diff options
-rw-r--r-- | nuttx/include/net/uip/dhcpc.h | 5 | ||||
-rw-r--r-- | nuttx/include/net/uip/uip.h | 9 | ||||
-rw-r--r-- | nuttx/net/recvfrom.c | 38 | ||||
-rw-r--r-- | nuttx/net/uip/uip.c | 26 | ||||
-rw-r--r-- | nuttx/netutils/dhcpc/dhcpc.c | 172 |
5 files changed, 160 insertions, 90 deletions
diff --git a/nuttx/include/net/uip/dhcpc.h b/nuttx/include/net/uip/dhcpc.h index f598c00ad..d1950c9b8 100644 --- a/nuttx/include/net/uip/dhcpc.h +++ b/nuttx/include/net/uip/dhcpc.h @@ -12,6 +12,7 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright @@ -66,7 +67,7 @@ struct dhcpc_state ****************************************************************************/ void *dhcpc_open(const void *mac_addr, int mac_len); -int dhcpc_request(void *handle, struct dhcpc_state *ds); -void dhcpc_close(void *handle); +int dhcpc_request(void *handle, struct dhcpc_state *ds); +void dhcpc_close(void *handle); #endif /* NET_UIP_DHCP_H__ */ diff --git a/nuttx/include/net/uip/uip.h b/nuttx/include/net/uip/uip.h index 0aceb8603..004c0ec6e 100644 --- a/nuttx/include/net/uip/uip.h +++ b/nuttx/include/net/uip/uip.h @@ -932,10 +932,11 @@ extern int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *a * addr3 The forth octet of the IP address. */ -#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ - ((uint16 *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ - ((uint16 *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ - } while(0) +#define uip_ipaddr(addr, addr0, addr1, addr2, addr3) \ + do { \ + ((uint16 *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ + ((uint16 *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ + } while(0) /* Construct an IPv6 address from eight 16-bit words. * diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 9632b5ca0..ac1f5f2bb 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -72,6 +72,11 @@ void recvfrom_interrupt(void *private) struct recvfrom_s *pstate = (struct recvfrom_s *)private; size_t recvlen; + /* If new data is available and we are correctly intialized, then complete + * the read action. We could also check for POLL events here in order to + * implement SO_RECVTIMEO. + */ + if (uip_newdata() && private) { /* Get the length of the data to return */ @@ -88,12 +93,14 @@ void recvfrom_interrupt(void *private) memcpy(pstate->rf_buffer, uip_appdata, recvlen); - /* Don't allow any furhter call backs. */ + /* Don't allow any further call backs. */ uip_conn->private = NULL; uip_conn->callback = NULL; - /* Wake up the waiting thread */ + /* Wake up the waiting thread, returning the number of bytes + * actually read. + */ pstate->rf_buflen = recvlen; sem_post(&pstate-> rf_sem); @@ -202,7 +209,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * save = irqsave(); memset(&state, 0, sizeof(struct recvfrom_s)); - sem_init(&state. rf_sem, 0, 0); + (void)sem_init(&state. rf_sem, 0, 0); /* Doesn't really fail */ state. rf_buflen = len; state. rf_buffer = buf; @@ -221,10 +228,31 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn->private = (void*)&state; udp_conn->callback = recvfrom_interrupt; - irqrestore(save); - sem_wait(&state. rf_sem); + /* Wait for either the read to complete: NOTES: (1) sem_wait will also + * terminate if a signal is received, (2) interrupts are disabled! They + * will be re-enabled while the task sleeps and automatically re-enabled + * when the task restarts. + */ + + ret = sem_wait(&state. rf_sem); + + /* Make sure that no further interrupts are processed */ + + uip_conn->private = NULL; + uip_conn->callback = NULL; sem_destroy(&state. rf_sem); + irqrestore(save); + + /* If sem_wait failed, then we were probably reawakened by a signal. In + * this case, sem_wait will have set errno appropriately. + */ + + if (ret < 0) + { + return ERROR; + } + return state.rf_buflen; #warning "Needs to return server address" #else diff --git a/nuttx/net/uip/uip.c b/nuttx/net/uip/uip.c index a8a149be2..2175ebc05 100644 --- a/nuttx/net/uip/uip.c +++ b/nuttx/net/uip/uip.c @@ -154,7 +154,9 @@ const uip_ipaddr_t uip_netmask = {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; #else -uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; +uip_ipaddr_t uip_hostaddr; +uip_ipaddr_t uip_draddr; +uip_ipaddr_t uip_netmask; #endif /* UIP_FIXEDADDR */ #ifndef CONFIG_NET_EXTERNAL_BUFFER @@ -179,12 +181,13 @@ uint16 uip_flags; /* The uip_flags variable is used for communica struct uip_conn *uip_conn; /* uip_conn always points to the current connection. */ uint16 uip_listenports[UIP_LISTENPORTS]; - /* The uip_listenports list all currently listning ports. */ + /* The uip_listenports list all currently listening ports. */ #ifdef CONFIG_NET_UDP struct uip_udp_conn *uip_udp_conn; #endif /* CONFIG_NET_UDP */ /* Temporary variables. */ + uint8 uip_acc32[4]; #if UIP_STATISTICS == 1 @@ -223,7 +226,9 @@ static uint16 ipid; /* Ths ipid variable is an increasing number th * used for the IP ID field. */ /* Temporary variables. */ -static uint8 c, opt; + +static uint8 c; +static uint8 opt; static uint16 tmp16; /**************************************************************************** @@ -1472,14 +1477,16 @@ tcp_send_synack: if (uip_flags & UIP_ACKDATA) { uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags = UIP_CONNECTED; - uip_connr->len = 0; + uip_flags = UIP_CONNECTED; + uip_connr->len = 0; + if (uip_len > 0) { - uip_flags |= UIP_NEWDATA; + uip_flags |= UIP_NEWDATA; uip_add_rcv_nxt(uip_len); } - uip_slen = 0; + + uip_slen = 0; uip_tcp_callback(); goto appsend; } @@ -1535,6 +1542,7 @@ tcp_send_synack: } } } + uip_connr->tcpstateflags = UIP_ESTABLISHED; uip_connr->rcv_nxt[0] = BUF->seqno[0]; uip_connr->rcv_nxt[1] = BUF->seqno[1]; @@ -1575,12 +1583,15 @@ tcp_send_synack: { goto drop; } + uip_add_rcv_nxt(1 + uip_len); uip_flags |= UIP_CLOSE; + if (uip_len > 0) { uip_flags |= UIP_NEWDATA; } + uip_tcp_callback(); uip_connr->len = 1; uip_connr->tcpstateflags = UIP_LAST_ACK; @@ -1781,6 +1792,7 @@ tcp_send_synack: { uip_connr->tcpstateflags = UIP_CLOSING; } + uip_add_rcv_nxt(1); uip_flags = UIP_CLOSE; uip_tcp_callback(); diff --git a/nuttx/netutils/dhcpc/dhcpc.c b/nuttx/netutils/dhcpc/dhcpc.c index 30172cef5..1e11ae079 100644 --- a/nuttx/netutils/dhcpc/dhcpc.c +++ b/nuttx/netutils/dhcpc/dhcpc.c @@ -49,6 +49,7 @@ #include <semaphore.h> #include <time.h> #include <debug.h> +#include <sys/socket.h> #include <net/uip/uip.h> #include <net/uip/dhcpc.h> @@ -101,39 +102,42 @@ struct dhcpc_state_internal { - char state; - sem_t sem; struct uip_udp_conn *conn; - uint16 ticks; - const void *mac_addr; - int mac_len; - struct dhcpc_state *result; + struct dhcpc_state *result; + const void *mac_addr; + int mac_len; + int sockfd; + uint16 ticks; + char state; }; struct dhcp_msg { - uint8 op, htype, hlen, hops; - uint8 xid[4]; - uint16 secs, flags; - uint8 ciaddr[4]; - uint8 yiaddr[4]; - uint8 siaddr[4]; - uint8 giaddr[4]; - uint8 chaddr[16]; + uint8 op; + uint8 htype; + uint8 hlen; + uint8 hops; + uint8 xid[4]; + uint16 secs; + uint16 flags; + uint8 ciaddr[4]; + uint8 yiaddr[4]; + uint8 siaddr[4]; + uint8 giaddr[4]; + uint8 chaddr[16]; #ifndef CONFIG_NET_DHCP_LIGHT - uint8 sname[64]; - uint8 file[128]; + uint8 sname[64]; + uint8 file[128]; #endif - uint8 options[312]; + uint8 options[312]; }; /**************************************************************************** * Private Data ****************************************************************************/ -static const uint8 xid[4] = {0xad, 0xde, 0x12, 0x23}; +static const uint8 xid[4] = {0xad, 0xde, 0x12, 0x23}; static const uint8 magic_cookie[4] = {99, 130, 83, 99}; -static volatile struct dhcpc_state_internal *gpdhcpc; /**************************************************************************** * Private Functions @@ -181,12 +185,12 @@ static uint8 *add_end(uint8 *optptr) static void create_msg(struct dhcpc_state_internal *pdhcpc, struct dhcp_msg *m) { - m->op = DHCP_REQUEST; + m->op = DHCP_REQUEST; m->htype = DHCP_HTYPE_ETHERNET; - m->hlen = pdhcpc->mac_len; - m->hops = 0; + m->hlen = pdhcpc->mac_len; + m->hops = 0; memcpy(m->xid, xid, sizeof(m->xid)); - m->secs = 0; + m->secs = 0; m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr)); @@ -203,33 +207,47 @@ static void create_msg(struct dhcpc_state_internal *pdhcpc, struct dhcp_msg *m) memcpy(m->options, magic_cookie, sizeof(magic_cookie)); } -static void send_discover(struct dhcpc_state_internal *pdhcpc) +static int send_discover(struct dhcpc_state_internal *pdhcpc) { - uint8 *end; - struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; - - create_msg(pdhcpc, m); - - end = add_msg_type(&m->options[4], DHCPDISCOVER); - end = add_req_options(end); - end = add_end(end); - - uip_send(uip_appdata, end - (uint8 *)uip_appdata); + struct dhcp_msg msg; + struct sockaddr_in addr; + uint8 *pend; + int len; + + create_msg(pdhcpc, &msg); + pend = add_msg_type(&msg.options[4], DHCPDISCOVER); + pend = add_req_options(pend); + pend = add_end(pend); + len = pend - (uint8*)&msg; + + addr.sin_family = AF_INET; + addr.sin_port = HTONS(DHCPC_SERVER_PORT); + addr.sin_addr.s_addr = INADDR_BROADCAST; + + return sendto(pdhcpc->sockfd, &msg, len, 0, + (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); } -static void send_request(struct dhcpc_state_internal *pdhcpc) +static int send_request(struct dhcpc_state_internal *pdhcpc) { - uint8 *end; - struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; - - create_msg(pdhcpc, m); - - end = add_msg_type(&m->options[4], DHCPREQUEST); - end = add_server_id(pdhcpc->result, end); - end = add_req_ipaddr(pdhcpc->result, end); - end = add_end(end); - - uip_send(uip_appdata, end - (uint8 *)uip_appdata); + struct dhcp_msg msg; + struct sockaddr_in addr; + uint8 *pend; + int len; + + create_msg(pdhcpc, &msg); + pend = add_msg_type(&msg.options[4], DHCPREQUEST); + pend = add_server_id(pdhcpc->result, pend); + pend = add_req_ipaddr(pdhcpc->result, pend); + pend = add_end(pend); + len = pend - (uint8*)&msg; + + addr.sin_family = AF_INET; + addr.sin_port = HTONS(DHCPC_SERVER_PORT); + addr.sin_addr.s_addr = INADDR_BROADCAST; + + return sendto(pdhcpc->sockfd, &msg, len, 0, + (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); } static uint8 parse_options(struct dhcpc_state *presult, uint8 *optptr, int len) @@ -283,7 +301,7 @@ static uint8 parse_msg(struct dhcpc_state_internal *pdhcpc) return 0; } -static void handle_dhcp(struct dhcpc_state_internal *pdhcpc) +static int handle_dhcp(struct dhcpc_state_internal *pdhcpc) { struct dhcpc_state *presult = pdhcpc->result; @@ -297,8 +315,11 @@ restart: send_discover(pdhcpc); - /* Wait for the response */ + /* Set up a watchdog to timeout the recvfrom */ +#warning need to implement timeout; + /* Wait for the response */ +#warning need to use recvfrom uip_event_timedwait(UIP_NEWDATA, CLOCK_SECOND); if (uip_newdata() && parse_msg(pdhcpc) == DHCPOFFER) @@ -322,7 +343,11 @@ restart: send_request(pdhcpc); + /* Set up a watchdog to timeout the recvfrom */ +#warning need to implement timeout; + /* Then wait to received the response */ +#warning need to use recvfrom uip_event_timedwait(UIP_NEWDATA, CLOCK_SECOND); @@ -357,6 +382,7 @@ restart: uip_ipaddr3(presult->default_router), uip_ipaddr4(presult->default_router)); dbg("Lease expires in %ld seconds\n", ntohs(presult->lease_time[0])*65536ul + ntohs(presult->lease_time[1])); + return OK; } /**************************************************************************** @@ -365,23 +391,42 @@ restart: void *dhcpc_open(const void *mac_addr, int mac_len) { - uip_ipaddr_t addr; struct dhcpc_state_internal *pdhcpc; + struct sockaddr_in addr; + + /* Allocate an internal DHCP structure */ pdhcpc = (struct dhcpc_state_internal *)malloc(sizeof(struct dhcpc_state_internal)); if (pdhcpc) { + /* Initialize the allocated structure */ + memset(pdhcpc, 0, sizeof(struct dhcpc_state_internal)); pdhcpc->mac_addr = mac_addr; pdhcpc->mac_len = mac_len; pdhcpc->state = STATE_INITIAL; - sem_init(&pdhcpc->sem, 0, 0); - uip_ipaddr(addr, 255,255,255,255); - pdhcpc->conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT)); - if (pdhcpc->conn != NULL) + /* Create a UDP socket */ + + pdhcpc->sockfd = socket(PF_INET, SOCK_DGRAM, 0); + if (pdhcpc->sockfd < 0) { - uip_udp_bind(pdhcpc->conn, HTONS(DHCPC_CLIENT_PORT)); + free(pdhcpc); + pdhcpc = NULL; + } + else + { + /* bind the socket */ + + addr.sin_family = AF_INET; + addr.sin_port = HTONS(DHCPC_CLIENT_PORT); + addr.sin_addr.s_addr = INADDR_ANY; + + if (bind(pdhcpc->sockfd, &addr, sizeof(struct sockaddr_in)) < 0) + { + free(pdhcpc); + pdhcpc = NULL; + } } } return (void*)pdhcpc; @@ -396,19 +441,6 @@ void dhcpc_close(void *handle) } } -/* This function is called by the UIP interrupt handling logic whenevent an - * event of interest occurs. - */ - -void uip_interrupt_udp_event(void) -{ -#warning OBSOLETE - if (gpdhcpc) - { - sem_post(&gpdhcpc->sem); - } -} - int dhcpc_request(void *handle, struct dhcpc_state *ds) { struct dhcpc_state_internal *pdhcpc = (struct dhcpc_state_internal *)handle; @@ -421,9 +453,5 @@ int dhcpc_request(void *handle, struct dhcpc_state *ds) } pdhcpc->result = ds; - gpdhcpc = pdhcpc; - sem_wait(&pdhcpc->sem); - gpdhcpc = NULL; - handle_dhcp(pdhcpc); - return OK; + return handle_dhcp(pdhcpc); } |