From c28cbf108cd5d0263af2aed44483856e61b272de Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Sat, 20 Sep 2008 15:14:05 +0000 Subject: [PATCH] added support for dynamic IP configuration (DHCP), enabled by default (so far) on LM3S --- SConstruct | 2 +- inc/elua_uip.h | 5 +- inc/validate.h | 7 + src/elua_uip.c | 60 ++++-- src/lua/ldump.c | 4 +- src/lua/luaconf.h | 8 +- src/platform/lm3s/build.h | 21 +- src/platform/lm3s/platform.c | 16 +- src/platform/lm3s/uip-conf.h | 22 ++- src/uip/dhcpc.c | 358 +++++++++++++++++++++++++++++++++++ src/uip/dhcpc.h | 61 ++++++ src/uip/psock.c | 3 +- src/uip/uip.h | 2 +- 13 files changed, 518 insertions(+), 51 deletions(-) create mode 100644 src/uip/dhcpc.c create mode 100644 src/uip/dhcpc.h diff --git a/SConstruct b/SConstruct index daa20825..8ffcd30c 100644 --- a/SConstruct +++ b/SConstruct @@ -123,7 +123,7 @@ app_files = " src/main.c src/romfs.c src/xmodem.c src/shell.c src/term.c src/dlm newlib_files = " src/newlib/devman.c src/newlib/stubs.c src/newlib/genstd.c src/newlib/stdtcp.c" # UIP files -uip_files = "uip_arp.c uip.c uiplib.c uip-split.c" +uip_files = "uip_arp.c uip.c uiplib.c uip-split.c dhcpc.c psock.c" uip_files = " src/elua_uip.c " + " ".join( [ "src/uip/%s" % name for name in uip_files.split() ] ) local_include = local_include + " -Isrc/uip" diff --git a/inc/elua_uip.h b/inc/elua_uip.h index 415062ab..1c35583e 100644 --- a/inc/elua_uip.h +++ b/inc/elua_uip.h @@ -14,7 +14,7 @@ enum ELUA_UIP_STATE_SEND, ELUA_UIP_STATE_RECV, ELUA_UIP_STATE_RECV_2, - ELUA_UIP_STATE_CLOSE, + ELUA_UIP_STATE_CLOSE }; // eLua UIP "error codes" @@ -35,9 +35,10 @@ struct elua_uip_state elua_net_size len; }; +struct uip_eth_addr; // Helper functions void elua_uip_appcall(); -void elua_uip_init(); +void elua_uip_init( const struct uip_eth_addr* paddr ); void elua_uip_mainloop(); #endif diff --git a/inc/validate.h b/inc/validate.h index d6e8f8b4..e28a9296 100644 --- a/inc/validate.h +++ b/inc/validate.h @@ -31,4 +31,11 @@ #endif // #ifdef BUILD_TERM #endif // #ifdef BUILD_CON_TCP +// For DHCP we need to have TCP/IP support +#ifdef BUILD_DHCPC + #ifndef BUILD_UIP + #error "DHCP client requires TCP/IP support (enable BUILD_UIP in build.h)" + #endif // #ifndef BUILD_UIP +#endif // #ifdef BUILD_DHCPC + #endif // #ifndef __VALIDATE_H__ diff --git a/src/elua_uip.c b/src/elua_uip.c index d2b090c2..8e3eedbf 100644 --- a/src/elua_uip.c +++ b/src/elua_uip.c @@ -12,21 +12,14 @@ #include "platform.h" #include "utils.h" #include "uip-split.h" +#include "dhcpc.h" #include -// [REMOVE] -// Also remove any printf()s here and MYLOGs -#include -#include "hw_types.h" -#include "hw_uart.h" -#include "hw_memmap.h" -#include "usart.h" -#define MYLOG( x ) UARTCharPut( UART0_BASE, x ) - // UIP send buffer extern void* uip_sappdata; - +// Global "configured" flag +static u8 elua_uip_configured; // ***************************************************************************** // Platform independenet eLua UIP "main loop" implementation @@ -152,6 +145,24 @@ void elua_uip_mainloop() } } +// ***************************************************************************** +// DHCP callback + +#ifdef BUILD_DHCPC + +void dhcpc_configured(const struct dhcpc_state *s) +{ + if(s->ipaddr[0] != 0) + { + uip_sethostaddr(s->ipaddr); + uip_setnetmask(s->netmask); + uip_setdraddr(s->default_router); + elua_uip_configured = 1; + } +} + +#endif + // ***************************************************************************** // Console over Ethernet support @@ -239,6 +250,10 @@ void elua_uip_appcall() struct elua_uip_state *s; elua_net_size temp; int sockno; + + // If uIP is not yet configured (DHCP response not received), do nothing + if( !elua_uip_configured ) + return; s = ( struct elua_uip_state* )&( uip_conn->appstate ); // Need to find the actual socket location, since UIP doesn't provide this ... @@ -356,8 +371,27 @@ void elua_uip_appcall() } // Init application -void elua_uip_init() +void elua_uip_init( const struct uip_eth_addr *paddr ) { + // Set hardware address + uip_setethaddr( (*paddr) ); + + // Initialize the uIP TCP/IP stack. + uip_init(); + uip_arp_init(); +#ifdef BUILD_DHCPC + dhcpc_init( paddr->addr, sizeof( *paddr ) ); + dhcpc_request(); +#else + uip_ipaddr_t ipaddr; + uip_ipaddr(ipaddr, ELUA_CONF_IPADDR0, ELUA_CONF_IPADDR1, ELUA_CONF_IPADDR2, ELUA_CONF_IPADDR3); + uip_sethostaddr(ipaddr); + uip_ipaddr(ipaddr, ELUA_CONF_NETMASK0, ELUA_CONF_NETMASK1, ELUA_CONF_NETMASK2, ELUA_CONF_NETMASK3); + uip_setnetmask(ipaddr); + uip_ipaddr(ipaddr, ELUA_CONF_DEFGW0, ELUA_CONF_DEFGW1, ELUA_CONF_DEFGW2, ELUA_CONF_DEFGW3); + uip_setdraddr(ipaddr); + elua_uip_configured = 1; +#endif #ifdef BUILD_CON_TCP uip_listen( HTONS( ELUA_NET_TELNET_PORT ) ); #endif @@ -366,7 +400,7 @@ void elua_uip_init() // ***************************************************************************** // eLua TCP/IP services (from elua_net.h) -#define ELUA_UIP_IS_SOCK_OK( sock ) ( sock >= 0 && sock < UIP_CONNS ) +#define ELUA_UIP_IS_SOCK_OK( sock ) ( elua_uip_configured && sock >= 0 && sock < UIP_CONNS ) int elua_net_socket( int type ) { @@ -469,6 +503,8 @@ int elua_net_get_last_err( int s ) // Accept a connection on the given port, return its socket id int elua_accept( u16 port ) { + if( !elua_uip_configured ) + return -1; #ifdef BUILD_CON_TCP if( port == ELUA_NET_TELNET_PORT ) return -1; diff --git a/src/lua/ldump.c b/src/lua/ldump.c index 3dd9d37a..387a9761 100644 --- a/src/lua/ldump.c +++ b/src/lua/ldump.c @@ -71,14 +71,14 @@ static void DumpIntWithSize(int x, int sizeof_int, DumpState* D) } break; case 2: { if (x>0x7FFF || x<(-0x8000)) D->status=LUA_ERR_CC_INTOVERFLOW; - int16_t y=x; + int16_t y=(int16_t)x; MaybeByteSwap((char*)&y,2,D); DumpVar(y,D); } break; case 4: { /* Need to reduce bounds by 1 to avoid messing 32-bit compilers up */ if (x>0x7FFFFFFE || x<(-0x7FFFFFFF)) D->status=LUA_ERR_CC_INTOVERFLOW; - int32_t y=x; + int32_t y=(int32_t)x; MaybeByteSwap((char*)&y,4,D); DumpVar(y,D); } break; diff --git a/src/lua/luaconf.h b/src/lua/luaconf.h index a3889c5b..0fd22a50 100644 --- a/src/lua/luaconf.h +++ b/src/lua/luaconf.h @@ -804,8 +804,6 @@ union luai_Cast { double l_d; long l_l; }; #endif - - /* =================================================================== */ /* @@ -813,7 +811,9 @@ union luai_Cast { double l_d; long l_l; }; ** without modifying the main part of the file. */ - - +#ifndef LUA_CROSS_COMPILER +typedef short int16_t; +typedef long int32_t; #endif +#endif diff --git a/src/platform/lm3s/build.h b/src/platform/lm3s/build.h index 7e5b6f1a..dc4e79ea 100644 --- a/src/platform/lm3s/build.h +++ b/src/platform/lm3s/build.h @@ -10,16 +10,21 @@ #define BUILD_TERM #define BUILD_UIP #define BUILD_CON_GENERIC +#define BUILD_DHCPC //#define BUILD_CON_TCP // Static TCP/IP configuration -#define ELUA_IPADDR0 192 -#define ELUA_IPADDR1 168 -#define ELUA_IPADDR2 1 -#define ELUA_IPADDR3 13 -#define ELUA_NETMASK0 255 -#define ELUA_NETMASK1 255 -#define ELUA_NETMASK2 255 -#define ELUA_NETMASK3 0 +#define ELUA_CONF_IPADDR0 192 +#define ELUA_CONF_IPADDR1 168 +#define ELUA_CONF_IPADDR2 1 +#define ELUA_CONF_IPADDR3 13 +#define ELUA_CONF_NETMASK0 255 +#define ELUA_CONF_NETMASK1 255 +#define ELUA_CONF_NETMASK2 255 +#define ELUA_CONF_NETMASK3 0 +#define ELUA_CONF_DEFGW0 192 +#define ELUA_CONF_DEFGW1 168 +#define ELUA_CONF_DEFGW2 1 +#define ELUA_CONF_DEFGW3 1 #endif diff --git a/src/platform/lm3s/platform.c b/src/platform/lm3s/platform.c index a676868c..1500d21d 100644 --- a/src/platform/lm3s/platform.c +++ b/src/platform/lm3s/platform.c @@ -9,7 +9,6 @@ #include #include #include -#include "uip.h" #include "uip_arp.h" #include "elua_uip.h" #include "uip-conf.h" @@ -35,6 +34,7 @@ #include "flash.h" #include "interrupt.h" #include "elua_net.h" +#include "dhcpc.h" // UIP sys tick data #define SYSTICKHZ 4 @@ -567,7 +567,6 @@ static void eth_init() { #ifdef BUILD_UIP u32 user0, user1, temp; - uip_ipaddr_t ipaddr; static struct uip_eth_addr sTempAddr; // Enable and reset the controller @@ -611,14 +610,6 @@ static void eth_init() // Enable all processor interrupts. IntMasterEnable(); - // Initialize the uIP TCP/IP stack. - uip_init(); - uip_arp_init(); - uip_ipaddr(ipaddr, ELUA_IPADDR0, ELUA_IPADDR1, ELUA_IPADDR2, ELUA_IPADDR3); - uip_sethostaddr(ipaddr); - uip_ipaddr(ipaddr, ELUA_NETMASK0, ELUA_NETMASK1, ELUA_NETMASK2, ELUA_NETMASK3); - uip_setnetmask(ipaddr); - // Configure the hardware MAC address for Ethernet Controller filtering of // incoming packets. // @@ -639,10 +630,9 @@ static void eth_init() // Program the hardware with it's MAC address (for filtering). EthernetMACAddrSet(ETH_BASE, (unsigned char *)&sTempAddr); - uip_setethaddr(sTempAddr); - // Initialize the TCP/IP Application - elua_uip_init(); + // Initialize the eLua uIP layer + elua_uip_init( &sTempAddr ); #endif } diff --git a/src/platform/lm3s/uip-conf.h b/src/platform/lm3s/uip-conf.h index bd338a16..b686b4b0 100644 --- a/src/platform/lm3s/uip-conf.h +++ b/src/platform/lm3s/uip-conf.h @@ -62,13 +62,13 @@ typedef unsigned short uip_stats_t; // // UDP support on or off // -#define UIP_CONF_UDP 0 +#define UIP_CONF_UDP 1 // // UDP checksums on or off // (not currently supported ... should be 0) // -#define UIP_CONF_UDP_CHECKSUMS 0 +#define UIP_CONF_UDP_CHECKSUMS 1 // // UDP Maximum Connections @@ -98,7 +98,7 @@ typedef unsigned short uip_stats_t; // // uIP buffer size. // -#define UIP_CONF_BUFFER_SIZE 1600 +#define UIP_CONF_BUFFER_SIZE 1024 // // uIP statistics on or off @@ -113,7 +113,7 @@ typedef unsigned short uip_stats_t; // // Broadcast Support // -#define UIP_CONF_BROADCAST 0 +#define UIP_CONF_BROADCAST 1 // // Link-Level Header length @@ -129,11 +129,13 @@ typedef unsigned short uip_stats_t; // Here we include the header file for the application we are using in // this example #include "elua_uip.h" +#include "dhcpc.h" // -// Define the uIP Application State type +// Define the uIP Application State type (both TCP and UDP) // typedef struct elua_uip_state uip_tcp_appstate_t; +typedef struct dhcpc_state uip_udp_appstate_t; // // UIP_APPCALL: the name of the application function. This function @@ -141,7 +143,15 @@ typedef struct elua_uip_state uip_tcp_appstate_t; // appfunc(void)"). // #ifndef UIP_APPCALL -#define UIP_APPCALL elua_uip_appcall +#define UIP_APPCALL elua_uip_appcall #endif +#ifndef UIP_ADP_APPCALL +#define UIP_UDP_APPCALL dhcpc_appcall +#endif + +// Added for eLua: DHCP TIMER ID +#define ELUA_DHCP_TIMER_ID 1 +#define CLOCK_SECOND 1000000UL + #endif // __UIP_CONF_H_ diff --git a/src/uip/dhcpc.c b/src/uip/dhcpc.c new file mode 100644 index 00000000..d3cf7df6 --- /dev/null +++ b/src/uip/dhcpc.c @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * 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 + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + */ + +#include +#include + +#include "uip.h" +#include "dhcpc.h" +#include "pt.h" +#include "platform.h" + +#define STATE_INITIAL 0 +#define STATE_SENDING 1 +#define STATE_OFFER_RECEIVED 2 +#define STATE_CONFIG_RECEIVED 3 + +#define HOSTNAME "elua" + +static struct dhcpc_state s; + +struct __attribute((packed)) dhcp_msg { + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; +#ifndef UIP_CONF_DHCP_LIGHT + u8_t sname[64]; + u8_t file[128]; +#endif + u8_t options[312]; +}; + +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPC_SERVER_PORT 67 +#define DHCPC_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOST_NAME 12 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +static const u8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; +static const u8_t magic_cookie[4] = {99, 130, 83, 99}; + +/*---------------------------------------------------------------------------*/ +static u8_t * +add_msg_type(u8_t *optptr, u8_t type) +{ + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_server_id(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + memcpy(optptr, s.serverid, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_ipaddr(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_IPADDR; + *optptr++ = 4; + memcpy(optptr, s.ipaddr, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_host_name(u8_t *optptr, const char* name) +{ + *optptr++ = DHCP_OPTION_HOST_NAME; + *optptr++ = (u8)strlen(name); + strcpy(optptr, name); + return optptr + strlen(name); +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_options(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_LIST; + *optptr++ = 3; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = DHCP_OPTION_DNS_SERVER; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_end(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static void +create_msg(register struct dhcp_msg *m) +{ + m->op = DHCP_REQUEST; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = s.mac_len; + m->hops = 0; + memcpy(m->xid, xid, sizeof(m->xid)); + 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)); + memset(m->yiaddr, 0, sizeof(m->yiaddr)); + memset(m->siaddr, 0, sizeof(m->siaddr)); + memset(m->giaddr, 0, sizeof(m->giaddr)); + memcpy(m->chaddr, s.mac_addr, s.mac_len); + memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); +#ifndef UIP_CONF_DHCP_LIGHT + memset(m->sname, 0, sizeof(m->sname)); + memset(m->file, 0, sizeof(m->file)); +#endif + + memcpy(m->options, magic_cookie, sizeof(magic_cookie)); +} +/*---------------------------------------------------------------------------*/ +static void +send_discover(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPDISCOVER); + end = add_req_options(end); + end = add_req_host_name(end, HOSTNAME); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static void +send_request(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPREQUEST); + end = add_server_id(end); + end = add_req_ipaddr(end); + end = add_req_host_name(end, HOSTNAME); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_options(u8_t *optptr, int len) +{ + u8_t *end = optptr + len; + u8_t type = 0; + + while(optptr < end) { + switch(*optptr) { + case DHCP_OPTION_SUBNET_MASK: + memcpy(s.netmask, optptr + 2, 4); + break; + case DHCP_OPTION_ROUTER: + memcpy(s.default_router, optptr + 2, 4); + break; + case DHCP_OPTION_DNS_SERVER: + memcpy(s.dnsaddr, optptr + 2, 4); + break; + case DHCP_OPTION_MSG_TYPE: + type = *(optptr + 2); + break; + case DHCP_OPTION_SERVER_ID: + memcpy(s.serverid, optptr + 2, 4); + break; + case DHCP_OPTION_LEASE_TIME: + memcpy(s.lease_time, optptr + 2, 4); + break; + case DHCP_OPTION_END: + return type; + } + + optptr += optptr[1] + 2; + } + return type; +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_msg(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + if(m->op == DHCP_REPLY && + memcmp(m->xid, xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + memcpy(s.ipaddr, m->yiaddr, 4); + return parse_options(&m->options[4], uip_datalen()); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_dhcp(void)) +{ + PT_BEGIN(&s.pt); + + /* try_again:*/ + s.state = STATE_SENDING; + s.ticks = CLOCK_SECOND; + + do { + send_discover(); + s.timer_init = platform_timer_op( ELUA_DHCP_TIMER_ID, PLATFORM_TIMER_OP_START, 0 ); + PT_WAIT_UNTIL(&s.pt, uip_newdata() || platform_timer_get_diff_us( ELUA_DHCP_TIMER_ID, s.timer_init, platform_timer_op( ELUA_DHCP_TIMER_ID, PLATFORM_TIMER_OP_READ, 0 ) ) >= s.ticks ); + if(uip_newdata() && parse_msg() == DHCPOFFER) { + uip_flags &= ~UIP_NEWDATA; + s.state = STATE_OFFER_RECEIVED; + break; + } + uip_flags &= ~UIP_NEWDATA; + if(s.ticks < CLOCK_SECOND * 60) { + s.ticks *= 2; + } else { + s.ipaddr[0] = 0; + goto dhcp_failed; + } + } while(s.state != STATE_OFFER_RECEIVED); + + s.ticks = CLOCK_SECOND; + + do { + send_request(); + s.timer_init = platform_timer_op( ELUA_DHCP_TIMER_ID, PLATFORM_TIMER_OP_START, 0 ); + PT_WAIT_UNTIL(&s.pt, uip_newdata() || platform_timer_get_diff_us( ELUA_DHCP_TIMER_ID, s.timer_init, platform_timer_op( ELUA_DHCP_TIMER_ID, PLATFORM_TIMER_OP_READ, 0 ) ) >= s.ticks ); + + if(uip_newdata() && parse_msg() == DHCPACK) { + uip_flags &= ~UIP_NEWDATA; + s.state = STATE_CONFIG_RECEIVED; + break; + } + uip_flags &= ~UIP_NEWDATA; + if(s.ticks <= CLOCK_SECOND * 10) { + s.ticks += CLOCK_SECOND; + } else { + PT_RESTART(&s.pt); + } + } while(s.state != STATE_CONFIG_RECEIVED); + +dhcp_failed: + dhcpc_configured(&s); + + /* + * PT_END restarts the thread so we do this instead. Eventually we + * should reacquire expired leases here. + */ + while(1) { + PT_YIELD(&s.pt); + } + + PT_END(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_init(const void *mac_addr, int mac_len) +{ + uip_ipaddr_t addr; + + s.mac_addr = mac_addr; + s.mac_len = mac_len; + + s.state = STATE_INITIAL; + uip_ipaddr(addr, 255,255,255,255); + s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT)); + if(s.conn != NULL) { + uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT)); + } + PT_INIT(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_appcall(void) +{ + handle_dhcp(); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_request(void) +{ + u16_t ipaddr[2]; + + if(s.state == STATE_INITIAL) { + uip_ipaddr(ipaddr, 0,0,0,0); + uip_sethostaddr(ipaddr); + /* handle_dhcp(PROCESS_EVENT_NONE, NULL);*/ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/src/uip/dhcpc.h b/src/uip/dhcpc.h new file mode 100644 index 00000000..aa8629f5 --- /dev/null +++ b/src/uip/dhcpc.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * 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 + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +#ifndef __DHCPC_H__ +#define __DHCPC_H__ + +#include "pt.h" +#include "type.h" + +struct dhcpc_state { + struct pt pt; + char state; + struct uip_udp_conn *conn; + u32 timer_init, ticks; + const void *mac_addr; + int mac_len; + + u8_t serverid[4]; + + u16_t lease_time[2]; + u16_t ipaddr[2]; + u16_t netmask[2]; + u16_t dnsaddr[2]; + u16_t default_router[2]; +}; + +void dhcpc_init(const void *mac_addr, int mac_len); +void dhcpc_request(void); +void dhcpc_appcall(void); +void dhcpc_configured(const struct dhcpc_state *s); + +#endif /* __DHCPC_H__ */ diff --git a/src/uip/psock.c b/src/uip/psock.c index 49f1f99f..962d5908 100644 --- a/src/uip/psock.c +++ b/src/uip/psock.c @@ -1,5 +1,4 @@ #include "build.h" - #ifdef BUILD_UIP /* @@ -341,4 +340,4 @@ psock_init(register struct psock *psock, char *buffer, unsigned int buffersize) } /*---------------------------------------------------------------------------*/ -#endif // #ifdef BUILD_UIP \ No newline at end of file +#endif // #ifdef BUILD_UIP diff --git a/src/uip/uip.h b/src/uip/uip.h index 08893bb3..fa5c780d 100644 --- a/src/uip/uip.h +++ b/src/uip/uip.h @@ -1560,7 +1560,7 @@ extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; /** * Representation of a 48-bit Ethernet address. */ -struct uip_eth_addr { +struct uip_eth_addr { u8_t addr[6]; } __attribute__ ((__packed__));