Skip to content

Commit fd1f28e

Browse files
GeorgeCGVcarlescufi
authored andcommitted
usb: device: class: rndis: correct packet reception
Allows receive packets that are bigger than CONFIG_RNDIS_BULK_EP_MPS. Considering: * MaxPacketsPerTransfer is 1 * MaxTransferSize is 1558 * PacketAlignmentFactor is 0 (20=1) The rndis_bulk_out shall be able to receive transfer up to 1558 bytes (inclusive). Signed-off-by: Georgij Cernysiov <[email protected]>
1 parent 3712094 commit fd1f28e

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

subsys/usb/device/class/netusb/function_rndis.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static struct __rndis {
197197
uint8_t media_status;
198198
} rndis = {
199199
.mac = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 },
200-
.mtu = 1500, /* Ethernet frame */
200+
.mtu = NET_ETH_MTU, /* Ethernet frame */
201201
.media_status = RNDIS_OBJECT_ID_MEDIA_DISCONNECTED,
202202
.state = UNINITIALIZED,
203203
.skip_bytes = 0,
@@ -207,8 +207,17 @@ static struct __rndis {
207207
static uint8_t manufacturer[] = CONFIG_USB_DEVICE_MANUFACTURER;
208208
static uint32_t drv_version = 1U;
209209

210-
static uint8_t tx_buf[NET_ETH_MAX_FRAME_SIZE +
211-
sizeof(struct rndis_payload_packet)];
210+
/**
211+
* Assumes MaxPacketsPerTransfer of 1 and 802.2 (ethernet) medium.
212+
*/
213+
#define RNDIS_BUF_SIZE (NET_ETH_MAX_FRAME_SIZE + sizeof(struct rndis_payload_packet))
214+
215+
static uint8_t tx_buf[RNDIS_BUF_SIZE];
216+
217+
/**
218+
* TODO: package reception can be optimized to avoid rx_buf usage.
219+
*/
220+
static uint8_t rx_buf[RNDIS_BUF_SIZE];
212221

213222
static uint32_t object_id_supported[] = {
214223
RNDIS_OBJECT_ID_GEN_SUPP_LIST,
@@ -318,21 +327,20 @@ void rndis_clean(void)
318327

319328
static void rndis_bulk_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
320329
{
321-
uint8_t buffer[CONFIG_RNDIS_BULK_EP_MPS];
322330
uint32_t hdr_offset = 0U;
323331
uint32_t len, read;
324332

325333
usb_read(ep, NULL, 0, &len);
326334

327335
LOG_DBG("EP 0x%x status %d len %u", ep, ep_status, len);
328336

329-
if (len > CONFIG_RNDIS_BULK_EP_MPS) {
330-
LOG_WRN("Limit read len %u to MPS %u", len,
331-
CONFIG_RNDIS_BULK_EP_MPS);
332-
len = CONFIG_RNDIS_BULK_EP_MPS;
337+
if (len > sizeof(rx_buf)) {
338+
LOG_WRN("Trying to receive too much data, drop");
339+
rndis_clean();
340+
return;
333341
}
334342

335-
usb_read(ep, buffer, len, &read);
343+
usb_read(ep, rx_buf, len, &read);
336344
if (len != read) {
337345
LOG_ERR("Read %u instead of expected %u, skip the rest",
338346
read, len);
@@ -343,7 +351,7 @@ static void rndis_bulk_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
343351
/* We already use frame keeping with len, warn here about
344352
* receiving frame delimiter
345353
*/
346-
if (len == 1U && !buffer[0]) {
354+
if (len == 1U && !rx_buf[0]) {
347355
LOG_DBG("Got frame delimiter, skip");
348356
return;
349357
}
@@ -371,7 +379,7 @@ static void rndis_bulk_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
371379
/* Append data only, skipping RNDIS header */
372380
hdr_offset = sizeof(struct rndis_payload_packet);
373381

374-
rndis.in_pkt_len = parse_rndis_header(buffer, len);
382+
rndis.in_pkt_len = parse_rndis_header(rx_buf, len);
375383
if (rndis.in_pkt_len < 0) {
376384
LOG_ERR("Error parsing RNDIS header");
377385

@@ -399,7 +407,7 @@ static void rndis_bulk_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
399407
}
400408

401409
if (net_pkt_write(rndis.in_pkt,
402-
buffer + hdr_offset, len - hdr_offset)) {
410+
rx_buf + hdr_offset, len - hdr_offset)) {
403411
LOG_ERR("Error writing data to pkt: %p", rndis.in_pkt);
404412
rndis_clean();
405413
rndis.rx_err++;
@@ -500,10 +508,7 @@ static int rndis_init_handle(uint8_t *data, uint32_t len)
500508
rsp->flags = sys_cpu_to_le32(RNDIS_FLAG_CONNECTIONLESS);
501509
rsp->medium = sys_cpu_to_le32(RNDIS_MEDIUM_WIRED_ETHERNET);
502510
rsp->max_packets = sys_cpu_to_le32(1);
503-
rsp->max_transfer_size = sys_cpu_to_le32(rndis.mtu +
504-
sizeof(struct net_eth_hdr) +
505-
sizeof(struct
506-
rndis_payload_packet));
511+
rsp->max_transfer_size = sys_cpu_to_le32(RNDIS_BUF_SIZE);
507512

508513
rsp->pkt_align_factor = sys_cpu_to_le32(0);
509514
(void)memset(rsp->__reserved, 0, sizeof(rsp->__reserved));

0 commit comments

Comments
 (0)