usb: device_next: rework wSequence check in CDC NCM implementation

The consequences of a wSequence mismatch are unspecified and are
primarily for debugging purposes. Our checks are a bit too strict, and
if the header check fails, the sequence is not updated, and the header
check subsequently fails. Rework the code to just log a warning on
mismatch and also reset OUT sequence counter the same way as the IN
sequence counter.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
Johann Fischer 2024-12-05 13:38:45 +01:00 committed by Benjamin Cabé
parent 82891d3d32
commit dd5492b3ce

View file

@ -340,7 +340,8 @@ static int cdc_ncm_out_start(struct usbd_class_data *const c_data)
return ret;
}
static int verify_nth16(const union recv_ntb *ntb, uint16_t len, uint16_t seq)
static int verify_nth16(struct cdc_ncm_eth_data *const data,
const union recv_ntb *const ntb, const uint16_t len)
{
const struct nth16 *nthdr16 = &ntb->nth;
const struct ndp16 *ndphdr16;
@ -362,6 +363,14 @@ static int verify_nth16(const union recv_ntb *ntb, uint16_t len, uint16_t seq)
return -EINVAL;
}
if (sys_le16_to_cpu(nthdr16->wSequence) != data->rx_seq) {
LOG_WRN("OUT NTH wSequence %u mismatch expected %u",
sys_le16_to_cpu(nthdr16->wSequence), data->rx_seq);
data->rx_seq = sys_le16_to_cpu(nthdr16->wSequence);
}
data->rx_seq++;
if (len < (sizeof(struct nth16) + sizeof(struct ndp16) +
2U * sizeof(struct ndp16_datagram))) {
LOG_DBG("DROP: %s len %d", "min", len);
@ -388,13 +397,6 @@ static int verify_nth16(const union recv_ntb *ntb, uint16_t len, uint16_t seq)
return -EINVAL;
}
if (sys_le16_to_cpu(nthdr16->wSequence) != 0 &&
sys_le16_to_cpu(nthdr16->wSequence) != (seq + 1)) {
LOG_DBG("DROP: seq %d %d",
seq, sys_le16_to_cpu(nthdr16->wSequence));
return -EINVAL;
}
ndphdr16 = (const struct ndp16 *)(ntb->data +
sys_le16_to_cpu(nthdr16->wNdpIndex));
@ -433,7 +435,7 @@ static int check_frame(struct cdc_ncm_eth_data *data, struct net_buf *const buf)
int ret;
/* TODO: support nth32 */
ret = verify_nth16(ntb, len, data->rx_seq);
ret = verify_nth16(data, ntb, len);
if (ret < 0) {
LOG_ERR("Failed to verify NTH16");
return ret;
@ -488,8 +490,6 @@ static int check_frame(struct cdc_ncm_eth_data *data, struct net_buf *const buf)
ndx++;
}
data->rx_seq = sys_le16_to_cpu(nthdr16->wSequence);
if (DUMP_PKT) {
LOG_HEXDUMP_DBG(ntb->data, len, "NTB");
}
@ -837,6 +837,7 @@ static void usbd_cdc_ncm_update(struct usbd_class_data *const c_data,
if (data_iface == iface && alternate == 0) {
atomic_clear_bit(&data->state, CDC_NCM_DATA_IFACE_ENABLED);
data->tx_seq = 0;
data->rx_seq = 0;
}
if (data_iface == iface && alternate == 1) {