static int readResponse(int type, int timeoutSecs) { int len; JIF_t end; int wait; wait = timeoutSecs * HZ; end = jiffies + wait; do { if ((len = netSockRead(s.conn, &dhcp_msg_buf, sizeof(dhcp_msg_buf), wait)) > 0) { if(msg_for_me(len) == type) { parse_msg(len); return len; } } wait = end - jiffies; } while (wait > 0); return -1; }
/* #define DHCP_DISCOVER 1 #define DHCP_OFFER 2 #define DHCP_REQUEST 3 #define DHCP_DECLINE 4 #define DHCP_ACK 5 #define DHCP_NAK 6 #define DHCP_RELEASE 7 #define DHCP_INFORM 8 */ void dhcpc_appcall(void) { int8_t message; // PRINTF("dhcpc_appcall() %d\r\n", dhcpc_state.state); // just for debugging if ( uip_newdata() && (message = msg_for_me()) > 0 ) { handle_dhcp( (uint8_t) message ); } if(dhcpc_state.state == DHCP_STATE_INITIAL || dhcpc_state.state == DHCP_STATE_LEASED) { handle_dhcp(0); // no message if DHCP_STATE_INITIAL or DHCP_STATE_LEASED, but we need to handle timer and initialisation. } }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_dhcp(process_event_t ev, void *data)) { clock_time_t ticks; PT_BEGIN(&s.pt); // printf("handle_dhcp\n"); init: // printf("init\n"); xid++; s.state = STATE_SENDING; s.ticks = CLOCK_SECOND * 4; while(1) { while(ev != tcpip_event) { tcpip_poll_udp(s.conn); PT_YIELD(&s.pt); } send_discover(); etimer_set(&s.etimer, s.ticks); do { PT_YIELD(&s.pt); // printf("tcpip_event:%d ev:%d uip_newdata():%d msg_for_me():%d\n",tcpip_event, ev,uip_newdata(),msg_for_me()); if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPOFFER) { // printf("here2\n"); parse_msg(); s.state = STATE_OFFER_RECEIVED; goto selecting; } } while(!etimer_expired(&s.etimer)); if(s.ticks < CLOCK_SECOND * 60) { s.ticks *= 2; } } selecting: // printf("selecting\n"); xid++; s.ticks = CLOCK_SECOND; do { while(ev != tcpip_event) { tcpip_poll_udp(s.conn); PT_YIELD(&s.pt); } send_request(); etimer_set(&s.etimer, s.ticks); do { PT_YIELD(&s.pt); if(ev == tcpip_event && uip_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", 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 // printf("bound\n"); ip64_dhcpc_configured(&s); #define MAX_TICKS (~((clock_time_t)0) / 2) #define MAX_TICKS32 (~((uint32_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) { 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 { while(ev != tcpip_event) { tcpip_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 == tcpip_event && uip_newdata() && msg_for_me() == DHCPACK) { parse_msg(); goto bound; } } while(!etimer_expired(&s.etimer)); } while(s.ticks >= CLOCK_SECOND*3); /* rebinding: */ /* lease_expired: */ ip64_dhcpc_unconfigured(&s); goto init; PT_END(&s.pt); }