diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 020f4e4d..27adce86 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -99,7 +99,7 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) /* if the network driver can accept another packet, we make it happen */ if (tud_network_can_xmit()) { - tud_network_xmit(p); + tud_network_xmit(p, 0 /* unused for this example */); return ERR_OK; } @@ -152,17 +152,49 @@ bool dns_query_proc(const char *name, ip_addr_t *addr) return false; } -bool tud_network_recv_cb(struct pbuf *p) +bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { /* this shouldn't happen, but if we get another packet before parsing the previous, we must signal our inability to accept it */ if (received_frame) return false; - /* store away the pointer for service_traffic() to later handle */ - received_frame = p; + if (size) + { + struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); + + if (p) + { + /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */ + memcpy(p->payload, src, size); + + /* store away the pointer for service_traffic() to later handle */ + received_frame = p; + } + } + return true; } +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) +{ + struct pbuf *p = (struct pbuf *)ref; + struct pbuf *q; + uint16_t len = 0; + + (void)arg; /* unused for this example */ + + /* traverse the "pbuf chain"; see ./lwip/src/core/pbuf.c for more info */ + for(q = p; q != NULL; q = q->next) + { + memcpy(dst, (char *)q->payload, q->len); + dst += q->len; + len += q->len; + if (q->len == q->tot_len) break; + } + + return len; +} + static void service_traffic(void) { /* handle any packet received by tud_network_recv_cb() */ diff --git a/src/class/net/net_device.c b/src/class/net/net_device.c index 238d64d8..65fd1ab5 100644 --- a/src/class/net/net_device.c +++ b/src/class/net/net_device.c @@ -366,23 +366,7 @@ static void handle_incoming_packet(uint32_t len) } } - bool accepted = false; - - if (size) - { - struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); - - if (p) - { - /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */ - memcpy(p->payload, pnt, size); - accepted = tud_network_recv_cb(p); - - if (!accepted) pbuf_free(p); - } - } - - if (!accepted) + if (!tud_network_recv_cb(pnt, size)) { /* if a buffer was never handled by user code, we must renew on the user's behalf */ tud_network_recv_renew(); @@ -429,9 +413,8 @@ bool tud_network_can_xmit(void) return can_xmit; } -void tud_network_xmit(struct pbuf *p) +void tud_network_xmit(void *ref, uint16_t arg) { - struct pbuf *q; uint8_t *data; uint16_t len; @@ -441,14 +424,7 @@ void tud_network_xmit(struct pbuf *p) len = (_netd_itf.ecm_mode) ? 0 : CFG_TUD_NET_PACKET_PREFIX_LEN; data = transmitted + len; - /* traverse the "pbuf chain"; see ./lwip/src/core/pbuf.c for more info */ - for(q = p; q != NULL; q = q->next) - { - memcpy(data, (char *)q->payload, q->len); - data += q->len; - len += q->len; - if (q->len == q->tot_len) break; - } + len += tud_network_xmit_cb(data, ref, arg); if (!_netd_itf.ecm_mode) { diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 0175ea56..795b2f9e 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -32,15 +32,13 @@ #include "device/usbd.h" #include "class/cdc/cdc.h" -// TODO should not include external files -#include "lwip/pbuf.h" -#include "netif/ethernet.h" - /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ #define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) /* Maximum Tranmission Unit (in bytes) of the network, including Ethernet header */ -#define CFG_TUD_NET_MTU (1500 + SIZEOF_ETH_HDR) +#ifndef CFG_TUD_NET_MTU +#define CFG_TUD_NET_MTU 1514 +#endif #ifdef __cplusplus extern "C" { @@ -54,7 +52,10 @@ void tud_network_init_cb(void); // client must provide this: return false if the packet buffer was not accepted -bool tud_network_recv_cb(struct pbuf *p); +bool tud_network_recv_cb(const uint8_t *src, uint16_t size); + +// client must provide this: copy from network stack packet pointer to dst +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); // client must provide this: 48-bit MAC address // TODO removed later since it is not part of tinyusb stack @@ -67,7 +68,7 @@ void tud_network_recv_renew(void); bool tud_network_can_xmit(void); // if network_can_xmit() returns true, network_xmit() can be called once -void tud_network_xmit(struct pbuf *p); +void tud_network_xmit(void *ref, uint16_t arg); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API