diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 26af9d79..7cd71abe 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -41,7 +41,19 @@ #include "lwip/memp.h" #if !NO_SYS +/** + ********************************** + * Netbuf functions + ********************************** + */ +/** + * Create (allocate) and initialize a new netbuf. + * The netbuf doesn't yet contain a packet buffer! + * + * @return a pointer to a new netbuf + * NULL on lack of memory + */ struct netbuf *netbuf_new(void) { @@ -58,6 +70,11 @@ netbuf *netbuf_new(void) } } +/** + * Deallocate a netbuf allocated by netbuf_new(). + * + * @param buf pointer to a netbuf allocated by netbuf_new() + */ void netbuf_delete(struct netbuf *buf) { @@ -70,9 +87,19 @@ netbuf_delete(struct netbuf *buf) } } +/** + * Allocate memory for a packet buffer for a given netbuf. + * + * @param buf the netbuf for which to allocate a packet buffer + * @param size the size of the packet buffer to allocate + * @return pointer to the allocated memory + * NULL if no memory could be allocated + */ void * netbuf_alloc(struct netbuf *buf, u16_t size) { + LWIP_ERROR("netbuf_alloc: invalid buf", (buf == NULL), return NULL;); + /* Deallocate any previously allocated memory. */ if (buf->p != NULL) { pbuf_free(buf->p); @@ -85,18 +112,34 @@ netbuf_alloc(struct netbuf *buf, u16_t size) return buf->p->payload; } +/** + * Free the packet buffer included in a netbuf + * + * @param buf pointer to the netbuf which contains the packet buffer to free + */ void netbuf_free(struct netbuf *buf) { + LWIP_ERROR("netbuf_free: invalid buf", (buf == NULL), return;); if (buf->p != NULL) { pbuf_free(buf->p); } buf->p = buf->ptr = NULL; } +/** + * Let a netbuf reference existing (non-volatile) data. + * + * @param buf netbuf which should reference the data + * @param dataptr pointer to the data to reference + * @param size size of the data + * @return ERR_OK if data is referenced + * ERR_MEM if data couldn't be referenced due to lack of memory + */ err_t netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) { + LWIP_ERROR("netbuf_ref: invalid buf", (buf == NULL), return ERR_ARG;); if (buf->p != NULL) { pbuf_free(buf->p); } @@ -111,17 +154,38 @@ netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) return ERR_OK; } +/** + * Chain one netbuf to another (@see pbuf_chain) + * + * @param head the first netbuf + * @param tail netbuf to chain after head + */ void netbuf_chain(struct netbuf *head, struct netbuf *tail) { + LWIP_ERROR("netbuf_ref: invalid head", (head == NULL), return;); + LWIP_ERROR("netbuf_chain: invalid tail", (tail == NULL), return;); pbuf_chain(head->p, tail->p); head->ptr = head->p; memp_free(MEMP_NETBUF, tail); } +/** + * Get the data pointer and length of the data inside a netbuf. + * + * @param buf netbuf to get the data from + * @param dataptr pointer to a void pointer where to store the data pointer + * @param len pointer to an u16_t where the length of the data is stored + * @return ERR_OK if the information was retreived, + * ERR_BUF on error. + */ err_t netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) { + LWIP_ERROR("netbuf_data: invalid buf", (buf == NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr == NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid len", (len == NULL), return ERR_ARG;); + if (buf->ptr == NULL) { return ERR_BUF; } @@ -130,9 +194,20 @@ netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) return ERR_OK; } +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the next part. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + * @return -1 if there is no next part + * 1 if moved to the next part but now there is no next part + * 0 if moved to the next part and there are still more parts + */ s8_t netbuf_next(struct netbuf *buf) { + LWIP_ERROR("netbuf_free: invalid buf", (buf == NULL), return -1;); if (buf->ptr->next == NULL) { return -1; } @@ -143,12 +218,29 @@ netbuf_next(struct netbuf *buf) return 0; } +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the beginning of the packet. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + */ void netbuf_first(struct netbuf *buf) { + LWIP_ERROR("netbuf_free: invalid buf", (buf == NULL), return;); buf->ptr = buf->p; } +/** + * Copy (part of) the contents of a packet buffer contained in a netbuf + * to an application supplied buffer. + * + * @param buf the netbuf from which to copy data + * @param dataptr the application supplied buffer + * @param len length of data to copy (dataptr must be big enough) + * @param offset offset into the packet buffer from where to begin copying len bytes + */ void netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset) { @@ -156,6 +248,9 @@ netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset) u16_t left; u16_t buf_copy_len; + LWIP_ERROR("netbuf_copy_partial: invalid buf", (buf == NULL), return;); + LWIP_ERROR("netbuf_copy_partial: invalid dataptr", (dataptr == NULL), return;); + left = 0; if(buf == NULL || dataptr == NULL) { @@ -164,7 +259,7 @@ netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset) /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ for(p = buf->p; len != 0 && p != NULL; p = p->next) { - if (offset != 0 && offset >= p->len) { + if ((offset != 0) && (offset >= p->len)) { /* don't copy from this buffer -> on to the next */ offset -= p->len; } else { @@ -181,6 +276,22 @@ netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset) } } +/** + ********************************** + * Netconn functions + ********************************** + */ + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is also created. + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, void (*callback)(struct netconn *, enum netconn_evt, u16_t len)) @@ -232,19 +343,14 @@ netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, return conn; } -struct -netconn *netconn_new(enum netconn_type t) -{ - return netconn_new_with_proto_and_callback(t,0,NULL); -} - -struct -netconn *netconn_new_with_callback(enum netconn_type t, - void (*callback)(struct netconn *, enum netconn_evt, u16_t len)) -{ - return netconn_new_with_proto_and_callback(t,0,callback); -} - +/** + * Close a netconn 'connection' and free its resources. + * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate + * after this returns. + * + * @param conn the netconn to delete + * @return ERR_OK if the connection was deleted + */ err_t netconn_delete(struct netconn *conn) { @@ -295,15 +401,35 @@ netconn_delete(struct netconn *conn) return ERR_OK; } +/** + * Get the type of a netconn (as enum netconn_type). + * + * @param conn the netconn of which to get the type + * @return the netconn_type of conn + */ enum netconn_type netconn_type(struct netconn *conn) { + LWIP_ERROR("netconn_type: invalid conn", (conn == NULL), return NETCONN_INVALID;); return conn->type; } +/** + * Get the current perr a netconn is connected to. + * This might only be temporary for UDP netconns, + * doesn't work for RAW netconns and returns garbage + * if called for a TCP listen netconn. + * + * @param conn the netconn to query + * @param addr a pointer to which to save the remote IP address + * @param port a pointer to which to save the remote port + * @return ERR_CONN for invalid connections + * ERR_OK if the information was retrieved + */ err_t netconn_peer(struct netconn *conn, struct ip_addr *addr, u16_t *port) { + LWIP_ERROR("netconn_peer: invalid conn", (conn == NULL), return ERR_ARG;); switch (NETCONNTYPE_GROUP(conn->type)) { case NETCONN_RAW: /* return an error as connecting is only a helper for upper layers */ @@ -325,9 +451,21 @@ netconn_peer(struct netconn *conn, struct ip_addr *addr, u16_t *port) return ERR_OK; } +/** + * Get the local IP address and port of a netconn. + * For RAW netconns, this returns the protocol instead of a port! + * + * @param conn the netconn to query + * @param addr a pointer to which to save the local IP address + * @param port a pointer to which to save the local port (or protocol for RAW) + * @return ERR_OK if the information was retrieved + */ err_t netconn_addr(struct netconn *conn, struct ip_addr **addr, u16_t *port) { + LWIP_ERROR("netconn_addr: invalid conn", (conn == NULL), return ERR_ARG;); + LWIP_ERROR("netconn_addr: invalid addr", (addr == NULL), return ERR_ARG;); + LWIP_ERROR("netconn_addr: invalid port", (port == NULL), return ERR_ARG;); switch (NETCONNTYPE_GROUP(conn->type)) { case NETCONN_RAW: *addr = &(conn->pcb.raw->local_ip); @@ -345,6 +483,16 @@ netconn_addr(struct netconn *conn, struct ip_addr **addr, u16_t *port) return ERR_OK; } +/** + * Bind a netconn to a specific local IP address and port. + * Binding one netconn twice might not always be checked correctly! + * + * @param conn the netconn to bind + * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY + * to bind to all addresses) + * @param port the local port to bind the netconn to (not used for RAW) + * @return ERR_OK if bound, any other err_t on failure + */ err_t netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port) { @@ -366,7 +514,14 @@ netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port) return conn->err; } - +/** + * Connect a netconn to a specific remote IP address and port. + * + * @param conn the netconn to connect + * @param addr the remote IP address to connect to + * @param port the remote port to connect to (no used for RAW) + * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise + */ err_t netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port) { @@ -389,6 +544,12 @@ netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port) return conn->err; } +/** + * Disconnect a netconn from its current peer (only valid for UDP netconns). + * + * @param conn the netconn to disconnect + * @return TODO: return value is not set here... + */ err_t netconn_disconnect(struct netconn *conn) { @@ -403,6 +564,13 @@ netconn_disconnect(struct netconn *conn) } +/** + * Set a TCP netconn into listen mode + * + * @param conn the tcp netconn to set to listen mode + * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns + * don't return any error (yet?)) + */ err_t netconn_listen(struct netconn *conn) { @@ -416,6 +584,12 @@ netconn_listen(struct netconn *conn) return conn->err; } +/** + * Accept a new connection on a TCP listening netconn. + * + * @param conn the TCP listen netconn + * @return the newly accepted netconn or NULL on timeout + */ struct netconn * netconn_accept(struct netconn *conn) { @@ -439,6 +613,12 @@ netconn_accept(struct netconn *conn) return newconn; } +/** + * Receive data (in form of a netbuf containing a packet buffer) from a netconn + * + * @param conn the netconn from which to receive data + * @return a new netbuf containing received data or NULL on memory error or timeout + */ struct netbuf * netconn_recv(struct netconn *conn) { @@ -538,16 +718,34 @@ netconn_recv(struct netconn *conn) return buf; } +/** + * Send data (in form of a netbuf) to a specific remote IP address and port. + * Only to be used for UDP and RAW netconns (not TCP). + * + * @param conn the netconn over which to send data + * @param buf a netbuf containing the data to send + * @param addr the remote IP address to which to send the data + * @param addr the remote port to which to send the data + * @return ERR_OK if data was sent, any other err_t on error + */ err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, struct ip_addr *addr, u16_t port) -{ if (buf!=NULL) { +{ + if (buf != NULL) { buf->addr = addr; buf->port = port; - return netconn_send( conn, buf); + return netconn_send(conn, buf); } return ERR_VAL; } +/** + * Send data over a UDP or RAW netconn (that is already connected). + * + * @param conn the UDP or RAW netconn over which to send data + * @param buf a netbuf containing the data to send + * @return ERR_OK if data was sent, any other err_t on error + */ err_t netconn_send(struct netconn *conn, struct netbuf *buf) { @@ -567,6 +765,15 @@ netconn_send(struct netconn *conn, struct netbuf *buf) return conn->err; } +/** + * Send data over a TCP netconn. + * + * @param conn the TCP netconn over which to send data + * @param dataptr pointer to the application buffer that contains the data to send + * @param size size of the application data to send + * @param copy flag: 1 = copy the data, 0 = data is non-volatile, can be sent by reference + * @return ERR_OK if data was sent, any other err_t on error + */ err_t netconn_write(struct netconn *conn, const void *dataptr, u16_t size, u8_t copy) { @@ -623,6 +830,12 @@ netconn_write(struct netconn *conn, const void *dataptr, u16_t size, u8_t copy) return conn->err; } +/** + * Close a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close + * @return ERR_OK if the netconn was closed, any other err_t on error + */ err_t netconn_close(struct netconn *conn) { @@ -645,11 +858,21 @@ netconn_close(struct netconn *conn) } #if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * + * @param conn the UDP netconn for which to change multicast addresses + * @param multiaddr IP address of the multicast group to join or leave + * @param interface the IP address of the network interface on which to send + * the igmp message + * @param join_or_leave flag whether to send a join- or leave-message + * @return ERR_OK if the action was taken, any err_t on error + */ err_t -netconn_join_leave_group (struct netconn *conn, - struct ip_addr *multiaddr, - struct ip_addr *interface, - enum netconn_igmp join_or_leave) +netconn_join_leave_group(struct netconn *conn, + struct ip_addr *multiaddr, + struct ip_addr *interface, + enum netconn_igmp join_or_leave) { struct api_msg msg; @@ -669,10 +892,4 @@ netconn_join_leave_group (struct netconn *conn, } #endif /* LWIP_IGMP */ -err_t -netconn_err(struct netconn *conn) -{ - return conn->err; -} - #endif /* !NO_SYS */