From b7e4d2a8ffe6f8accc19e438311389bc74d2389b Mon Sep 17 00:00:00 2001 From: goldsimon Date: Fri, 8 Jun 2007 17:10:05 +0000 Subject: [PATCH] Done some work on task #1549 (function documentation) and minor changes to meet coding standard + added some comments to make the code easier to read. --- src/netif/etharp.c | 30 ++++++++++---- src/netif/ethernetif.c | 90 +++++++++++++++++++++++++++++------------- src/netif/loopif.c | 41 ++++++++++++++----- src/netif/slipif.c | 67 +++++++++++++++++++++++++------ 4 files changed, 173 insertions(+), 55 deletions(-) diff --git a/src/netif/etharp.c b/src/netif/etharp.c index 6bf5c620..f510c768 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -114,6 +114,7 @@ static u8_t etharp_cached_entry = 0; static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags); static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags); + /** * Initializes ARP module. */ @@ -133,8 +134,13 @@ etharp_init(void) } #if ARP_QUEUEING -/** Free a complete queue of etharp entrys */ -static void free_etharp_q(struct etharp_q_entry *q) +/** + * Free a complete queue of etharp entries + * + * @param q a qeueue of etharp_q_entry's to free + */ +static void +free_etharp_q(struct etharp_q_entry *q) { struct etharp_q_entry *r; LWIP_ASSERT("q != NULL", q != NULL); @@ -222,7 +228,8 @@ etharp_tmr(void) * @return The ARP entry index that matched or is created, ERR_MEM if no * entry is found or could be recycled. */ -static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags) +static s8_t +find_entry(struct ip_addr *ipaddr, u8_t flags) { s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; s8_t empty = ARP_TABLE_SIZE; @@ -313,8 +320,7 @@ static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags) /* no empty entry found and not allowed to recycle? */ if ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0) /* or don't create new entry, only search? */ - || ((flags & ETHARP_FIND_ONLY) != 0)) - { + || ((flags & ETHARP_FIND_ONLY) != 0)) { return (s8_t)ERR_MEM; } @@ -781,7 +787,8 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. * */ -err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) +err_t +etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) { struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; err_t result = ERR_MEM; @@ -911,7 +918,16 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) return result; } -err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr) +/** + * Send an ARP request packet asking for ipaddr. + * + * @param netif the lwip network interface on which to send the request + * @param ipaddr the IP address for which to ask + * @return ERR_OK if the request has been sent + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, struct ip_addr *ipaddr) { struct pbuf *p; struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; diff --git a/src/netif/ethernetif.c b/src/netif/ethernetif.c index 4e79052c..e044dcf2 100644 --- a/src/netif/ethernetif.c +++ b/src/netif/ethernetif.c @@ -50,6 +50,12 @@ #define IFNAME0 'e' #define IFNAME1 'n' +/** + * Helper struct to hold private data used to operate your ethernet interface. + * Keeping the ethernet address of the MAC in this struct is not necessary + * as it is already kept in the struct netif. + * But this is only an example, anyway... + */ struct ethernetif { struct eth_addr *ethaddr; /* Add whatever per-interface state that is needed here. */ @@ -62,6 +68,13 @@ static void ethernetif_input(struct netif *netif); static err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr); +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ static void low_level_init(struct netif *netif) { @@ -85,13 +98,20 @@ low_level_init(struct netif *netif) /* Do whatever else is needed to initialize interface. */ } -/* - * low_level_output(): - * - * Should do the actual transmission of the packet. The packet is +/** + * This function should do the actual transmission of the packet. The packet is * contained in the pbuf that is passed to the function. This pbuf * might be chained. * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). */ static err_t @@ -126,14 +146,14 @@ low_level_output(struct netif *netif, struct pbuf *p) return ERR_OK; } -/* - * low_level_input(): - * +/** * Should allocate a pbuf and transfer the bytes of the incoming * packet from the interface into the pbuf. * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error */ - static struct pbuf * low_level_input(struct netif *netif) { @@ -186,35 +206,34 @@ low_level_input(struct netif *netif) return p; } -/* - * ethernetif_output(): - * +/** * This function is called by the TCP/IP stack when an IP packet * should be sent. It calls the function called low_level_output() to * do the actual transmission of the packet. * + * @param netif the lwip network interface structure for this ethernetif + * @param p the (IP) packet to send + * @param ipaddr the ip address to send the packet to + * @return ERR_OK if the packet has been sent + * an err_t on failure */ - static err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) { - - /* resolve hardware address, then send (or queue) packet */ + /* resolve hardware address, then send (or queue) packet */ return etharp_output(netif, ipaddr, p); - } -/* - * ethernetif_input(): - * +/** * This function should be called when a packet is ready to be read * from the interface. It uses the function low_level_input() that * should handle the actual reception of bytes from the network - * interface. + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. * + * @param netif the lwip network interface structure for this ethernetif */ - static void ethernetif_input(struct netif *netif) { @@ -252,6 +271,12 @@ ethernetif_input(struct netif *netif) case ETHTYPE_IP: #if ETHARP_TRUST_IP_MAC /* update ARP table */ + /* In multithreaded environments, watch out if using etharp_ip_input() + * in another thread than the main tcpip_thread, since the ARP table + * is not locked from concurrent access!!! + * Use ETHARP_TCPIP_ETHINPUT=1 instead so ARP processing is done inside + * the thread context of tcpip_thread. + */ etharp_ip_input(netif, p); #endif /* ETHARP_TRUST_IP_MAC */ /* skip Ethernet header */ @@ -267,6 +292,12 @@ ethernetif_input(struct netif *netif) /* ARP packet? */ case ETHTYPE_ARP: /* pass p to ARP module */ + /* In multithreaded environments, watch out if using etharp_ip_input() + * in another thread than the main tcpip_thread, since the ARP table + * is not locked from concurrent access!!! + * Use ETHARP_TCPIP_ETHINPUT=1 instead so ARP processing is done inside + * the thread context of tcpip_thread. + */ etharp_arp_input(netif, ethernetif->ethaddr, p); break; @@ -280,22 +311,26 @@ ethernetif_input(struct netif *netif) } } -/* - * ethernetif_init(): - * +/** * Should be called at the beginning of the program to set up the * network interface. It calls the function low_level_init() to do the * actual setup of the hardware. * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error */ - err_t ethernetif_init(struct netif *netif) { struct ethernetif *ethernetif; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); ethernetif = mem_malloc(sizeof(struct ethernetif)); - if (ethernetif == NULL) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); return ERR_MEM; @@ -307,6 +342,7 @@ ethernetif_init(struct netif *netif) #endif /* LWIP_NETIF_HOSTNAME */ #if LWIP_SNMP + /* initialize the snmp variables and counters inside the struct netif */ /* ifType ethernetCsmacd(6) @see RFC1213 */ netif->link_type = 6; /* your link speed here */ @@ -321,7 +357,7 @@ ethernetif_init(struct netif *netif) netif->ifoutnucastpkts = 0; netif->ifoutdiscards = 0; #endif /* LWIP_SNMP */ - + netif->state = ethernetif; netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; @@ -330,8 +366,8 @@ ethernetif_init(struct netif *netif) ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + /* initialize the hardware */ low_level_init(netif); return ERR_OK; } - diff --git a/src/netif/loopif.c b/src/netif/loopif.c index fbae0eb2..982404a5 100644 --- a/src/netif/loopif.c +++ b/src/netif/loopif.c @@ -49,10 +49,13 @@ struct loopif_private { struct pbuf *last; }; -/* Call loopif_poll() in the main loop of your application. This is to prevent +/** + * Call loopif_poll() in the main loop of your application. This is to prevent * reentering non-reentrant functions like tcp_input(). Packets passed to * loopif_output() are put on a list that is passed to netif->input() by * loopif_poll(). + * + * @param netif the lwip network interface structure for this loopif */ void loopif_poll(struct netif *netif) @@ -84,19 +87,36 @@ loopif_poll(struct netif *netif) if(in != NULL) { if(in->next != NULL) { + /* De-queue the pbuf from its successors on the 'priv' list. */ in->next = NULL; + /* This is built on the assumption that PBUF_RAM pbufs are in one piece! */ LWIP_ASSERT("packet must not consist of multiple pbufs!", in->len == in->tot_len); } if(netif->input(in, netif) != ERR_OK) { pbuf_free(in); - in = NULL; } + /* Don't reference the packet any more! */ + in = NULL; } /* go on while there is a packet on the list */ } while(priv->first != NULL); } #endif /* LWIP_LOOPIF_MULTITHREADING */ +/** + * Send an IP packet over the loopback interface. + * The pbuf is simply copied and handed back to netif->input. + * In multithreaded mode, this is done directly since netif->input must put + * the packet on a queue. + * In callback mode, the packet is put on an internal queue and is fed to + * netif->input by loopif_poll(). + * + * @param netif the lwip network interface structure for this loopif + * @param p the (IP) packet to 'send' + * @param ipaddr the ip address to send the packet to (not used for loopif) + * @return ERR_OK if the packet has been sent + * ERR_MEM if the pbuf used to copy the packet couldn't be allocated + */ static err_t loopif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) @@ -139,6 +159,9 @@ loopif_output(struct netif *netif, struct pbuf *p, through calling loopif_poll(). */ priv = (struct loopif_private*)netif->state; + /* This is built on the assumption that PBUF_RAM pbufs are in one piece! */ + LWIP_ASSERT("packet must not consist of multiple pbufs!", r->len == r->tot_len); + SYS_ARCH_PROTECT(lev); if(priv->first != NULL) { LWIP_ASSERT("if first!=NULL, last must also be != NULL", priv->last != NULL); @@ -153,6 +176,13 @@ loopif_output(struct netif *netif, struct pbuf *p, return ERR_OK; } +/** + * Initialize a lwip network interface structure for a loopback interface + * + * @param netif the lwip network interface structure for this loopif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + */ err_t loopif_init(struct netif *netif) { @@ -173,10 +203,3 @@ loopif_init(struct netif *netif) } #endif /* LWIP_HAVE_LOOPIF */ - - - - - - - diff --git a/src/netif/slipif.c b/src/netif/slipif.c index 844ed706..9d39cfe0 100644 --- a/src/netif/slipif.c +++ b/src/netif/slipif.c @@ -54,7 +54,12 @@ /** * Send a pbuf doing the necessary SLIP encapsulation * - * Uses the serial layer's sio_send() + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chaing packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values */ err_t slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) @@ -63,6 +68,12 @@ slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) u16_t i; u8_t c; + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + LWIP_ASSERT("p != NULL", (p != NULL)); + + LWIP_UNUSED_ARG(ipaddr); + /* Send pbuf out on the serial I/O device. */ sio_send(SLIP_END, netif->state); @@ -85,24 +96,29 @@ slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) } } sio_send(SLIP_END, netif->state); - return 0; + return ERR_OK; } /** * Handle the incoming SLIP stream character by character * * Poll the serial layer by calling sio_recv() - * + * + * @param netif the lwip network interface structure for this slipif * @return The IP packet when SLIP_END is received */ static struct pbuf * slipif_input(struct netif *netif) { u8_t c; + /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ struct pbuf *p, *q; u16_t recved; u16_t i; + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + q = p = NULL; recved = i = 0; c = 0; @@ -113,6 +129,7 @@ slipif_input(struct netif *netif) case SLIP_END: if (recved > 0) { /* Received whole packet. */ + /* Trim the pbuf to the size of the received packet. */ pbuf_realloc(q, recved); LINK_STATS_INC(link.recv); @@ -135,36 +152,47 @@ slipif_input(struct netif *netif) /* FALLTHROUGH */ default: + /* byte received, packet not yet completely received */ if (p == NULL) { + /* allocate a new pbuf */ LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL); if (p == NULL) { LINK_STATS_INC(link.drop); LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); + /* don't process any further since we got no pbuf to receive to */ + break; } if (q != NULL) { + /* 'chain' the pbuf to the existing chain */ pbuf_cat(q, p); } else { + /* p is the first pbuf in the chain */ q = p; } } - if (p != NULL && recved < MAX_SIZE) { + /* this automatically drops bytes if > MAX_SIZE */ + if ((p != NULL) && (recved <= MAX_SIZE)) { ((u8_t *)p->payload)[i] = c; recved++; i++; if (i >= p->len) { + /* on to the next pbuf */ i = 0; - if (p->next != NULL && p->next->len > 0) + if (p->next != NULL && p->next->len > 0) { + /* p is a chain, on to the next in the chain */ p = p->next; - else + } else { + /* p is a signle pbuf, set it to NULL so next time a new + * pbuf is allocated */ p = NULL; + } } } break; } - } return NULL; } @@ -173,6 +201,8 @@ slipif_input(struct netif *netif) * The SLIP input thread. * * Feed the IP layer with incoming packets + * + * @param nf the lwip network interface structure for this slipif */ static void slipif_loop(void *nf) @@ -182,9 +212,11 @@ slipif_loop(void *nf) while (1) { p = slipif_input(netif); - if(netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - p = NULL; + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + p = NULL; + } } } } @@ -194,6 +226,13 @@ slipif_loop(void *nf) * * Call the arch specific sio_open and remember * the opened device in the state field of the netif. + * + * @param nf the lwip network interface structure for this slipif + * @return ERR_OK if serial line could be opened, + * ERR_IF is serial line couldn't be opened + * + * @note netif->num must contain the number of the serial port to open + * (0 by default) */ err_t slipif_init(struct netif *netif) @@ -204,13 +243,17 @@ slipif_init(struct netif *netif) netif->name[0] = 's'; netif->name[1] = 'l'; netif->output = slipif_output; - netif->mtu = 1500; + netif->mtu = MAX_SIZE; netif->flags = NETIF_FLAG_POINTTOPOINT; + /* Try to open the serial port (netif->num contains the port number). */ netif->state = sio_open(netif->num); - if (!netif->state) + if (!netif->state) { + /* Opening the serial port failed. */ return ERR_IF; + } + /* Create a thread to poll the serial line. */ sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO); return ERR_OK; }