summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/include/net/uip/dhcpc.h5
-rw-r--r--nuttx/include/net/uip/uip.h9
-rw-r--r--nuttx/net/recvfrom.c38
-rw-r--r--nuttx/net/uip/uip.c26
-rw-r--r--nuttx/netutils/dhcpc/dhcpc.c172
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);
}