/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_dhcp(void)) { PT_BEGIN(&s.pt); /* try_again:*/ s.state = STATE_SENDING; s.ticks = CLOCK_SECOND; do { send_discover(); timer_set(&s.timer, s.ticks); PT_YIELD(&s.pt); PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); if(uip_newdata() && parse_msg() == DHCPOFFER) { s.state = STATE_OFFER_RECEIVED; break; } if(s.ticks < CLOCK_SECOND * 60) { s.ticks *= 2; } } while(s.state != STATE_OFFER_RECEIVED); s.ticks = CLOCK_SECOND; do { send_request(); timer_set(&s.timer, s.ticks); PT_YIELD(&s.pt); PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); if(uip_newdata() && parse_msg() == DHCPACK) { s.state = STATE_CONFIG_RECEIVED; break; } if(s.ticks <= CLOCK_SECOND * 10) { s.ticks += CLOCK_SECOND; } else { PT_RESTART(&s.pt); } } while(s.state != STATE_CONFIG_RECEIVED); #if 0 printf("Got IP address %d.%d.%d.%d\n", uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr), uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr)); printf("Got netmask %d.%d.%d.%d\n", uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask), uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask)); printf("Got DNS server %d.%d.%d.%d\n", uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr), uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr)); printf("Got default router %d.%d.%d.%d\n", uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router), uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router)); printf("Lease expires in %ld seconds\n", ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1])); #endif dhcpc_configured(&s); /* timer_stop(&s.timer);*/ /* * 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); }
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(void)) { PT_BEGIN(&s.pt); #if defined PORT_APP_MAPPER dhcpc_running = 1; #endif if (s.state == STATE_RENEW) goto send_request_section; /* try_again:*/ s.state = STATE_SENDING; s.ticks = CLOCK_SECOND; //sendString("\r\ndhcpc handle dhcp passed: STATE_SENDING"); do { send_discover(); timer_set(&s.timer, s.ticks); // NOTE: fixed as per http://www.mail-archive.com/[email protected]/msg00003.html PT_YIELD_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); //sendString("Just got something\n\r"); if(uip_newdata()) { //sendString("Data\n\r"); if (parse_msg() == DHCPOFFER) { s.state = STATE_OFFER_RECEIVED; break; } } else { //sendString("Timeout\n\r"); if(s.ticks < CLOCK_SECOND * 60) { s.ticks *= 2; } else { s.ticks = CLOCK_SECOND; } } } while(s.state != STATE_OFFER_RECEIVED); //sendString("\r\ndhcpc handle dhcp passed: STATE_OFFER_RECEIVED"); s.ticks = CLOCK_SECOND; send_request_section: do { send_request(); timer_set(&s.timer, s.ticks); // NOTE: fixed as per http://www.mail-archive.com/[email protected]/msg00003.html PT_YIELD_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); if(uip_newdata()) { msg_type = parse_msg(); if (msg_type == DHCPACK) { s.state = STATE_CONFIG_RECEIVED; break; } else if (msg_type == DHCPNAK) { s.state = STATE_FAIL; goto close_and_clean_up; } } else { if(s.ticks <= CLOCK_SECOND * 10) { s.ticks += CLOCK_SECOND; } else { PT_RESTART(&s.pt); //sendString("\r\ndhcpc handle RESTARTING!"); } } } while(s.state != STATE_CONFIG_RECEIVED); //sendString("\r\ndhcpc handle dhcp passed: STATE_CONFIG_RECEIVED"); #if DEBUG_SERIAL printf_P(PSTR("Got IP address %d.%d.%d.%d\r\n"), uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr), uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr)); printf_P(PSTR("Got netmask %d.%d.%d.%d\r\n"), uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask), uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask)); printf_P(PSTR("Got DNS server %d.%d.%d.%d\r\n"), uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr), uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr)); printf_P(PSTR("Got default router %d.%d.%d.%d\r\n"), uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router), uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router)); printf_P(PSTR("Lease expires in %ld seconds\r\n"), ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1])); #endif dhcpc_configured(&s); /* timer_stop(&s.timer);*/ /* * PT_END restarts the thread so we do this instead. Eventually we * should reacquire expired leases here. */ /* while(1) { PT_YIELD(&s.pt); } */ close_and_clean_up: #if defined PORT_APP_MAPPER dhcpc_running = 0; #endif // all done with the connection, clean up uip_udp_remove(s.conn); s.conn = NULL; //sendString("\r\ndhcpc handle dhcp passed: END"); PT_END(&s.pt); }
/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_dhcp(void)) { PT_BEGIN(&s.pt); /* try_again:*/ s.state = STATE_SENDING; s.ticks = CLOCK_SECOND; do { send_discover(); /* Sending does not clear the NEWDATA flag. The packet doesn't actually get sent until we yield at least once. If we don't clear the flag ourselves, we will enter an infinite loop here. This is arguably a bug in uip.c and the uip_send() function should probably clear the NEWDATA flag. */ uip_flags=uip_flags&(~UIP_NEWDATA); timer_set(&s.timer, s.ticks); PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); if(uip_newdata() && parse_msg() == DHCPOFFER) { s.state = STATE_OFFER_RECEIVED; break; } if(s.ticks < CLOCK_SECOND * 20) { s.ticks *= 2; } } while(s.state != STATE_OFFER_RECEIVED); s.ticks = CLOCK_SECOND; do { send_request(); uip_flags=uip_flags&(~UIP_NEWDATA); timer_set(&s.timer, s.ticks); PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); if(uip_newdata() && parse_msg() == DHCPACK) { s.state = STATE_CONFIG_RECEIVED; break; } if(s.ticks <= CLOCK_SECOND * 10) { s.ticks += CLOCK_SECOND; } else { PT_RESTART(&s.pt); } } while(s.state != STATE_CONFIG_RECEIVED); #if 0 printf("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr)); printf("Got netmask %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.netmask)); printf("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.dnsaddr)); printf("Got default router %d.%d.%d.%d\n", uip_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); /* timer_stop(&s.timer);*/ /* * 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); }
static PT_THREAD (handle_dhcp (void)) { PT_BEGIN (&dhcpcState->pt); dhcpcState->state = STATE_SENDING; dhcpcState->ticks = CLOCK_SECOND; do { send_discover (); timer_set (&dhcpcState->timer, dhcpcState->ticks); PT_WAIT_UNTIL (&dhcpcState->pt, uip_newdata () || timer_expired (&dhcpcState->timer)); if (uip_newdata () && (parse_msg () == DHCPOFFER)) { uip_flags &= ~UIP_NEWDATA; dhcpcState->state = STATE_OFFER_RECEIVED; break; } uip_flags &= ~UIP_NEWDATA; if (dhcpcState->ticks < CLOCK_SECOND * 60) dhcpcState->ticks *= 2; else { dhcpcState->ipaddr [0] = dhcpcState->ipaddr [1] = 0; goto dhcpcf; } } while (dhcpcState->state != STATE_OFFER_RECEIVED); dhcpcState->ticks = CLOCK_SECOND; do { send_request (); timer_set (&dhcpcState->timer, dhcpcState->ticks); PT_WAIT_UNTIL (&dhcpcState->pt, uip_newdata () || timer_expired (&dhcpcState->timer)); if (uip_newdata () && (parse_msg () == DHCPACK)) { uip_flags &= ~UIP_NEWDATA; dhcpcState->state = STATE_CONFIG_RECEIVED; break; } uip_flags &= ~UIP_NEWDATA; if (dhcpcState->ticks <= CLOCK_SECOND * 10) dhcpcState->ticks += CLOCK_SECOND; else PT_RESTART (&dhcpcState->pt); } while (dhcpcState->state != STATE_CONFIG_RECEIVED); dhcpcf: dhcpc_configured (dhcpcState); /* timer_stop (&dhcpcState->timer);*/ /* * PT_END restarts the thread so we do this instead. Eventually we * should reacquire expired leases here. */ while (1) PT_YIELD (&dhcpcState->pt); PT_END (&dhcpcState->pt); }
static void handle_dhcp(process_event_t message) { time_t seconds; switch( dhcpc_state.state ) { case DHCP_STATE_INITIAL: dhcpc_state.state = DHCP_STATE_DISCOVER; xid++; send_discover(); stimer_set(&dhcpc_state.stimer, (time_t)10 ); // normally set the timer for 60 seconds, // but because the ARP table is empty give DHCP server only 10 seconds. break; case DHCP_STATE_DISCOVER: if( !stimer_expired(&dhcpc_state.stimer) && message == DHCP_OFFER ) { parse_msg(); dhcpc_state.state = DHCP_STATE_REQUEST; xid++; send_request(); stimer_set(&dhcpc_state.stimer, (time_t)10 ); // set the timer for 10 seconds } else { dhcpc_state.state = DHCP_STATE_INITIAL; } break; case DHCP_STATE_REQUEST: if( !stimer_expired(&dhcpc_state.stimer) && message == DHCP_ACK ) { parse_msg(); dhcpc_state.state = DHCP_STATE_LEASED; PRINTF("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&dhcpc_state.ipaddr)); PRINTF("Got netmask %d.%d.%d.%d\n", uip_ipaddr_to_quad(&dhcpc_state.netmask)); PRINTF("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&dhcpc_state.dnsaddr)); PRINTF("Got default router %d.%d.%d.%d\n", uip_ipaddr_to_quad(&dhcpc_state.default_router)); PRINTF("Lease expires in %ld seconds\n", uip_ntohs(dhcpc_state.lease_time[0])*65536ul + uip_ntohs(dhcpc_state.lease_time[1])); dhcpc_configured(&dhcpc_state); #define MAX_TICKS (~((time_t)0) / 2) #define MAX_TICKS32 (~((time_t)0)) if((uip_ntohs(dhcpc_state.lease_time[0])*65536ul + uip_ntohs(dhcpc_state.lease_time[1]))/2 <= MAX_TICKS32) { seconds = ( uip_ntohs(dhcpc_state.lease_time[0])*65536ul + uip_ntohs(dhcpc_state.lease_time[1]) )/2; } else { seconds = MAX_TICKS32; } stimer_set(&dhcpc_state.stimer, seconds); // set the timer for half of lease_time seconds } else { dhcpc_state.state = DHCP_STATE_INITIAL; } break; case DHCP_STATE_LEASED: if( stimer_expired(&dhcpc_state.stimer) ) { dhcpc_state.state = DHCP_STATE_INITIAL; } break; case DHCP_STATE_REREQUEST: case DHCP_STATE_RELEASE: default: dhcpc_state.state = DHCP_STATE_INITIAL; break; } }