void udp_apps_appcall(void) { #ifdef UIP_DHCP switch(uip_udp_conn->lport) { case UIP_HTONS(IP_PORT_DHCP_SERVER): case UIP_HTONS(IP_PORT_DHCP_CLIENT): dhcpc_appcall(); break; // case UIP_HTONS(IP_PORT_NTP): // ntpd_appcall(); break; default: break; } if( stimer_expired(&dhcpc_state.stimer) ) { dhcpc_state.state = DHCP_STATE_INITIAL; dhcpc_unconfigured(&dhcpc_state); dhcpc_appcall(); } #endif // UIP_DHCP }
static void dhcpTask(void* arg) { int wait; init: xid++; s.state = STATE_SENDING; wait = 1; while (1) { send_discover(); if (readResponse(DHCPOFFER, wait) != -1) { s.state = STATE_OFFER_RECEIVED; goto selecting; } if(wait < 60) wait = wait * 2; } selecting: xid++; wait = 1; do { send_request(); if (readResponse(DHCPACK, wait) != -1) { s.state = STATE_CONFIG_RECEIVED; goto bound; } if(wait < 10) { wait++; } else { goto init; } } while(s.state != STATE_CONFIG_RECEIVED); bound: #if 0 nosPrintf("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr)); nosPrintf("Got netmask %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.netmask)); nosPrintf("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.dnsaddr)); nosPrintf("Got default router %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.default_router)); nosPrintf("Lease expires in %ld seconds\n", uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])); #endif dhcpc_configured(&s); uint32_t leaseLeft = uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]); uint32_t sleepLeft = leaseLeft / 2; #define MAX_SECS ((INFINITE - 1) / HZ) while (sleepLeft > 0) { if (sleepLeft > MAX_SECS) { wait = MAX_SECS * HZ; sleepLeft -= MAX_SECS; } else { wait = sleepLeft * HZ; sleepLeft = 0; } posTaskSleep(wait); } leaseLeft = leaseLeft / 2; /* renewing: */ xid++; do { send_request(); if (leaseLeft / 2 > MAX_SECS) wait = MAX_SECS; else wait = (leaseLeft / 2); if (readResponse(DHCPACK, wait) != -1) { s.state = STATE_CONFIG_RECEIVED; goto bound; } leaseLeft -= wait; } while (leaseLeft > 3); /* rebinding: */ /* lease_expired: */ dhcpc_unconfigured(&s); goto init; }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_dhcp(process_event_t ev, void *data)) { PT_BEGIN(&s.pt); init: xid++; s.state = STATE_SENDING; s.ticks = CLOCK_SECOND; while (1) { while(ev != tcpipv4_event) { tcpipv4_poll_udp(s.conn); PT_YIELD(&s.pt); } send_discover(); etimer_set(&s.etimer, s.ticks); do { PT_YIELD(&s.pt); if(ev == tcpipv4_event && uipv4_newdata() && msg_for_me() == DHCPOFFER) { parse_msg(); s.state = STATE_OFFER_RECEIVED; goto selecting; } } while (!etimer_expired(&s.etimer)); if(s.ticks < CLOCK_SECOND * 60) { s.ticks *= 2; } } selecting: xid++; s.ticks = CLOCK_SECOND; do { while(ev != tcpipv4_event) { tcpipv4_poll_udp(s.conn); PT_YIELD(&s.pt); } send_request(); etimer_set(&s.etimer, s.ticks); do { PT_YIELD(&s.pt); if(ev == tcpipv4_event && uipv4_newdata() && msg_for_me() == DHCPACK) { parse_msg(); s.state = STATE_CONFIG_RECEIVED; goto bound; } } while (!etimer_expired(&s.etimer)); if(s.ticks <= CLOCK_SECOND * 10) { s.ticks += CLOCK_SECOND; } else { goto init; } } while(s.state != STATE_CONFIG_RECEIVED); bound: #if 0 printf("Got IP address %d.%d.%d.%d\n", uipv4_ipaddr_to_quad(&s.ipaddr)); printf("Got netmask %d.%d.%d.%d\n", uipv4_ipaddr_to_quad(&s.netmask)); printf("Got DNS server %d.%d.%d.%d\n", uipv4_ipaddr_to_quad(&s.dnsaddr)); printf("Got default router %d.%d.%d.%d\n", uipv4_ipaddr_to_quad(&s.default_router)); printf("Lease expires in %ld seconds\n", uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])); #endif dhcpc_configured(&s); #define MAX_TICKS (~((clock_time_t)0) / 2) #define MAX_TICKS32 (~((u32_t)0)) #define IMIN(a, b) ((a) < (b) ? (a) : (b)) if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2 <= MAX_TICKS32) { s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]) )*CLOCK_SECOND/2; } else { s.ticks = MAX_TICKS32; } while(s.ticks > 0) { clock_time_t ticks; ticks = IMIN(s.ticks, MAX_TICKS); s.ticks -= ticks; etimer_set(&s.etimer, ticks); PT_YIELD_UNTIL(&s.pt, etimer_expired(&s.etimer)); } if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2 <= MAX_TICKS32) { s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]) )*CLOCK_SECOND/2; } else { s.ticks = MAX_TICKS32; } /* renewing: */ xid++; do { clock_time_t ticks; while(ev != tcpipv4_event) { tcpipv4_poll_udp(s.conn); PT_YIELD(&s.pt); } send_request(); ticks = IMIN(s.ticks / 2, MAX_TICKS); s.ticks -= ticks; etimer_set(&s.etimer, ticks); do { PT_YIELD(&s.pt); if(ev == tcpipv4_event && uipv4_newdata() && msg_for_me() == DHCPACK) { parse_msg(); goto bound; } } while(!etimer_expired(&s.etimer)); } while(s.ticks >= CLOCK_SECOND*3); /* rebinding: */ /* lease_expired: */ dhcpc_unconfigured(&s); goto init; PT_END(&s.pt); }