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:
parent
82891d3d32
commit
dd5492b3ce
1 changed files with 12 additions and 11 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue