bool run() { static uint8_t led = 0; static uint8_t data; static uint16_t value = 0; PT_BEGIN(); while (true) { PT_WAIT_UNTIL(Uart::read(data)); if (data != 0xff) continue; PT_WAIT_UNTIL(Uart::read(data)); if (data != 0xaa) continue; PT_WAIT_UNTIL(Uart::read(data)); if (data != 0x55) continue; PT_WAIT_UNTIL(Uart::read(data)); if (data != 0x00) continue; // if we reach this point we read all four prefix bytes and can now // read led values for (led = 0; led < 30; led++) { value = 0; PT_WAIT_UNTIL(Uart::read(data)); value = data << 8; PT_WAIT_UNTIL(Uart::read(data)); value |= data; leds[led].red = value; value = 0; PT_WAIT_UNTIL(Uart::read(data)); value = data << 8; PT_WAIT_UNTIL(Uart::read(data)); value |= data; leds[led].green = value; value = 0; PT_WAIT_UNTIL(Uart::read(data)); value = data << 8; PT_WAIT_UNTIL(Uart::read(data)); value |= data; leds[led].blue = value; } } PT_END(); }
/*---------------------------------------------------------------------------*/ 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_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_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); }
/** * Duty cycle the radio and send probes. This function is called * repeatedly by a ctimer. The function restart_dutycycle() is used to * (re)start the duty cycling. */ static int dutycycle(void *ptr) { struct ctimer *t = ptr; #if WITH_PENDING_BROADCAST struct queue_list_item *p; #endif PT_BEGIN(&dutycycle_pt); while(1) { #if WITH_PENDING_BROADCAST { /* Before sending the probe, we mark all broadcast packets in our output queue to be pending. This means that they are ready to be sent, once we know that no neighbor is currently broadcasting. */ for(p = list_head(queued_packets_list); p != NULL; p = list_item_next(p)) { if(p->broadcast_flag == BROADCAST_FLAG_WAITING) { PRINTF("wait -> pending\n"); set_broadcast_flag(p, BROADCAST_FLAG_PENDING); } } } #endif /* WITH_PENDING_BROADCAST */ /* Turn on the radio for sending a probe packet and anticipating a data packet from a neighbor. */ turn_radio_on(); /* Send a probe packet. */ send_probe(); /* Set a timer so that we keep the radio on for LISTEN_TIME. */ ctimer_set(t, LISTEN_TIME, (void (*)(void *))dutycycle, t); PT_YIELD(&dutycycle_pt); #if WITH_PENDING_BROADCAST { struct queue_list_item *p; /* Go through the list of packets we are waiting to send, and check if there are any pending broadcasts in the list. If there are pending broadcasts, and we did not receive any broadcast packets from a neighbor in response to our probe, we mark the broadcasts as being ready to send. */ for(p = list_head(queued_packets_list); p != NULL; p = list_item_next(p)) { if(p->broadcast_flag == BROADCAST_FLAG_PENDING) { PRINTF("pending -> send\n"); set_broadcast_flag(p, BROADCAST_FLAG_SEND); turn_radio_on(); } } } #endif /* WITH_PENDING_BROADCAST */ /* If we have no packets to send (indicated by the list length of queued_packets_list being zero), we should turn the radio off. Othersize, we keep the radio on. */ if(num_packets_to_send() == 0) { /* If we are not listening for announcements, we turn the radio off and wait until we send the next probe. */ if(is_listening == 0) { int current_off_time; if(!NETSTACK_RADIO.receiving_packet()) { turn_radio_off(); compower_accumulate(&compower_idle_activity); } current_off_time = off_time - off_time_adjustment; if(current_off_time < LISTEN_TIME * 2) { current_off_time = LISTEN_TIME * 2; } off_time_adjustment = 0; ctimer_set(t, current_off_time, (void (*)(void *))dutycycle, t); PT_YIELD(&dutycycle_pt); #if WITH_ADAPTIVE_OFF_TIME off_time += LOWEST_OFF_TIME; if(off_time > OFF_TIME) { off_time = OFF_TIME; } #endif /* WITH_ADAPTIVE_OFF_TIME */ } else { /* We are listening for annonucements, so we count down the listen time, and keep the radio on. */ is_listening--; ctimer_set(t, OFF_TIME, (void (*)(void *))dutycycle, t); PT_YIELD(&dutycycle_pt); } } else { /* We had pending packets to send, so we do not turn the radio off. */ ctimer_set(t, off_time, (void (*)(void *))dutycycle, t); PT_YIELD(&dutycycle_pt); } } PT_END(&dutycycle_pt); }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_tcpthread(struct pt *pt)) { uint8_t *dataptr; struct codeprop_tcphdr *th; int datalen = uip_datalen(); PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, uip_connected()); s.state = STATE_RECEIVING_TCPDATA; s.addr = 0; s.count = 0; process_post(PROCESS_BROADCAST, codeprop_event_quit, (process_data_t)NULL); /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); dataptr = uip_appdata; if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); } th = (struct codeprop_tcphdr *)uip_appdata; s.len = uip_htons(th->len); s.addr = 0; uip_appdata += sizeof(struct codeprop_tcphdr); datalen = uip_datalen() - sizeof(struct codeprop_tcphdr); /* Read the rest of the data. */ do { if(datalen > 0) { /* printf("Got %d bytes\n", uip_len);*/ eeprom_write(EEPROMFS_ADDR_CODEPROP + s.addr, uip_appdata, datalen); s.addr += datalen; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); /* Print out the "ok" message. */ do { uip_send("ok\r\n", 4); PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); ++s.id; s.state = STATE_SENDING_UDPDATA; tcpip_poll_udp(udp_conn); codeprop_start_program(); PT_WAIT_UNTIL(pt, s.state != STATE_SENDING_UDPDATA); /* printf("recv_tcpthread: unblocked\n");*/ } PT_END(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); }
/** * @brief power_cycle * @param rt * @param ptr * @return */ static char power_cycle(struct rtimer *rt, void* ptr){ //start protothread function PT_BEGIN(&pt); //watchdog_stop(); //watchdog_periodic(); while(1){ if(rand_offset_wait_flag){ for(slot_counter = 0; slot_counter < node_slots_offset; slot_counter++){ rtimer_clock_t tnow_wait = RTIMER_NOW(); schedule_fixed(rt, tnow_wait + TS); PT_YIELD(&pt); } //random slots offset is over.. disable flag rand_offset_wait_flag = 0; COOJA_DEBUG_PRINTF("END oF RANDOM OFFSET:%u..%u\n", rounds_counter,node_slots_offset); }//else{} static rtimer_clock_t t0; //rtimer_clock_t tnow; watchdog_periodic(); //for(slot_counter = 0; slot_counter < slot_counter_upperB+2; slot_counter++){ for(slot_counter = 0; slot_counter <= slot_upperBound; slot_counter++){ //at this time, everyone receives new neighbors. //if(slot_counter!= 0 && (slot_counter % GROUP_MERGE_TIME) == 0){ //cc2420_set_channel(i3e154_channels[0]); /*if(rimeaddr_node_addr.u8[0] == 10){ cc2420_set_channel(i3e154_channels[0]); }*/ //}*/ //watchdog_periodic(); //watchdog_stop(); //this offset is transmitted probe_offset = slot_counter%period_length; if(slot_counter != 0 && (slot_counter % period_length) == 0){ anchor_time = slot_counter - probe_offset; //update j coeficient of neighbor nodes neighs_jfactor_update(); //reset extra slots counter.. a new period will commence here. extra_slots_k_counter = 0; } //txPacketFlag //this is an anchor slot.. if(slot_counter == 0 || (slot_counter%period_length) == 0){ isAnchorFlag = 1; //ANCHOR flag txPacketFlag = 1; //Set beacon Flag to TRUE //Compute next probe //probe_slot_counter = random_int(period_length/2+2); probe_slot_counter = 2*probe_jfact + 2; probe_time = slot_counter + probe_slot_counter; probe_jfact = (1+probe_jfact)%(period_length/4+1); energy_per_period++; //reset overflow_flag only used for indirect discovery overflow_flag = 0; /**COOJA_DEBUG_PRINTF("AnchorID:%u, ProbeID:%u\n", slot_counter, probe_slot_counter);*/ }else{//ELSE OF (slot_counter%period_length) //check it is a probe slot.. if(slot_counter == probe_time){ isAnchorFlag = 0; //RESET Anchor Flag txPacketFlag = 1; //Set beacon Flag to TRUE /**the probe offset on a probe slot is based on the probe slot counter.. bcz of strip-probbing.*/ probe_offset = probe_slot_counter; energy_per_period++; //reset overflow_flag only used for indirect discovery overflow_flag = 0; //COOJA_DEBUG_PRINTF("ProbeID:%u, time:%u\n", probe_slot_counter, probe_time); }else{//ELSE slot_counter == probe_time //probe also possible Hop 2 neighbors if(list_access_flag == 0){ list_access_flag = 1; if(isthere_anchor(extra_slots_k, slot_counter) && (extra_slots_k_counter < extra_slots_k)){ isAnchorFlag = 0; //RESET Anchor Flag txPacketFlag = 1; //Set beacon Flag to TRUE extra_slots_k_counter++; extra_probe_counter++; extra_probe_per_period++; //reset overflow_flag only used for indirect discovery overflow_flag = 1; //COOJA_DEBUG_PRINTF("TgT_ID:%u, time:%u\n", probe_offset, slot_counter + probe_offset); } //END of //reset flag.. list_access_flag = 0; } } //END OF slot_counter == probe_time }//END OF (slot_counter%period_length) if(txPacketFlag){ txPacketFlag = 0;//RESET txPacketFlag //total energy energy_counter++; //COOJA_DEBUG_PRINTF("PACKET_TX_INIT:%u,%u\n", slot_counter, RTIMER_NOW()); rtimer_clock_t tnow = RTIMER_NOW(); //cc2420_set_channel(i3e154_channels[0]); if(radio_is_on_flag == 0){ //COOJA_DEBUG_PRINTF("b17\n"); on(); } //send first beacon without offset beacon_2_flag = 0; //transmit beacon packet transmit_epidemic(); //wait for sometime to receive some packets schedule_fixed(rt, tnow + 3*TS_20P); PT_YIELD(&pt); //Once the cycle returns, it is time to send the second beacon //transmit Anchor Probe Here tnow = RTIMER_NOW(); //send second beacon with offset beacon_2_flag = 1; //trabsmit beacon packet if(list_access_flag == 0) transmit_epidemic(); //here we schedule to comence the next time slot. schedule_fixed(rt, tnow + 2*TS_20P +overflow_flag*TS_20P); PT_YIELD(&pt); //we need to switch the radio off.. if(radio_is_on_flag == 1){ //COOJA_DEBUG_PRINTF("b17\n"); /**if(node_id == 16) COOJA_DEBUG_PRINTF("b17\n");*/ off(); } //RESET txPacketFlag txPacketFlag = 0;//RESET txPacketFlag }else{ //END if(txPacketFlag) //turn radio off if(radio_is_on_flag == 1){ //COOJA_DEBUG_PRINTF("b17\n"); off(); } if(sort_gains_flag){ sort_gains_flag = 0; /*get current number of neighbors.. ACC: compute updates here..*/ uint8_t tmp_num_neighs = 0; //if(list_access_flag == 0){ //list_access_flag = 1; //tmp_num_neighs = compute_slot_gain(probe_offset); //sort slot gains here.. sort_slot_gains(); //list_access_flag = 0; tmp_num_neighs = neighs_num_nodes(); if(curr_frac_nodes < tmp_num_neighs){ ///set current number of neighbors curr_frac_nodes = tmp_num_neighs; process_post(&output_process,PROCESS_EVENT_CONTINUE, NULL); } //} //end of list_access_flag == 0 } //here we schedule to comence the next time slot. schedule_fixed(rt, RTIMER_NOW() + TS); PT_YIELD(&pt); } //END if(txPacketFlag) //print energy consumption if(slot_counter != 0 && (slot_counter % period_length) == 0){ //print energy consumption values ////print_nodes(1); //process_post(&output_process,PROCESS_EVENT_CONTINUE, energyPrint); //energy_per_period = 0; //extra_probe_per_period = 0; } } //END for LOOP COOJA_DEBUG_PRINTF("END oF DISCOVERY CYCLE:%u\n", rounds_counter); //AN UPPER_BOUND HAVE BEEN REACHED.. Exit the discovery_is_on = 0; restart_discovery(); //cycle is over, YIELD waiting for another call.. PT_YIELD(&pt); }//end of WHILE(1) //end protothread function:AG PT_END(&pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD( handle_script ( struct httpd_state *s ) ) { char *ptr; PT_BEGIN( &s->scriptpt ); ( void ) PT_YIELD_FLAG; while( s->file.len > 0 ) { /* Check if we should start executing a script. */ if( *s->file.data == ISO_percent && *(s->file.data + 1) == ISO_bang ) { s->scriptptr = s->file.data + 3; s->scriptlen = s->file.len - 3; if( *(s->scriptptr - 1) == ISO_colon ) { httpd_fs_open( s->scriptptr + 1, &s->file ); PT_WAIT_THREAD( &s->scriptpt, send_file(s) ); } else { PT_WAIT_THREAD( &s->scriptpt, httpd_cgi(s->scriptptr) (s, s->scriptptr) ); } next_scriptstate( s ); /* The script is over, so we reset the pointers and continue sending the rest of the file. */ s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { /* See if we find the start of script marker in the block of HTML to be sent. */ if( s->file.len > uip_mss() ) { s->len = uip_mss(); } else { s->len = s->file.len; } if( *s->file.data == ISO_percent ) { ptr = strchr( s->file.data + 1, ISO_percent ); } else { ptr = strchr( s->file.data, ISO_percent ); } if( ptr != NULL && ptr != s->file.data ) { s->len = ( int ) ( ptr - s->file.data ); if( s->len >= uip_mss() ) { s->len = uip_mss(); } } PT_WAIT_THREAD( &s->scriptpt, send_part_of_file(s) ); s->file.data += s->len; s->file.len -= s->len; } } PT_END( &s->scriptpt ); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_script(struct httpd_state *s)) { PGM_P ptr; PT_BEGIN(&s->scriptpt); while(s->file.len > 0) { /* Check if we should start executing a script. */ if(pgm_read_byte_near(s->file.data) == ISO_percent && pgm_read_byte_near(s->file.data + 1) == ISO_bang) { s->scriptptr = s->file.data + 3; s->scriptlen = s->file.len - 3; if(pgm_read_byte_near(s->scriptptr - 1) == ISO_colon) { strncpy_P(s->tmp_str, s->scriptptr + 1, sizeof(s->tmp_str) -1); if(httpd_fs_open(s->tmp_str, &s->file) || httpd_fs_open(s->tmp_str + 1 , &s->file)) { PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } else { // could not open the file. } } else { strncpy_P(s->tmp_str, s->scriptptr, sizeof(s->tmp_str) -1); ((s->tmp_str)[sizeof(s->tmp_str) - 1]) = '\0'; PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(s->tmp_str)(s, s->tmp_str)); } next_scriptstate(s); /* The script is over, so we reset the pointers and continue sending the rest of the file. */ s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { /* See if we find the start of script marker in the block of HTML to be sent. */ if(s->file.len > uip_mss()) { s->len = uip_mss(); } else { s->len = s->file.len; } if(pgm_read_byte_near(s->file.data) == ISO_percent) { ptr = strchr_P(s->file.data + 1, ISO_percent); } else { ptr = strchr_P(s->file.data, ISO_percent); } if(ptr != NULL && ptr != s->file.data) { s->len = (int)(ptr - s->file.data); if(s->len >= uip_mss()) { s->len = uip_mss(); } } PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); s->file.data += s->len; s->file.len -= s->len; } } PT_END(&s->scriptpt); /* PGM_P ptr; PT_BEGIN(&s->scriptpt); while(s->file.len > 0) { // Check if we should start executing a script. if( (pgm_read_byte(s->file.data) == ISO_percent) && (pgm_read_byte(s->file.data + 1) == ISO_bang)) { s->scriptptr = s->file.data + 3; s->scriptlen = s->file.len - 3; if(pgm_read_byte(s->scriptptr - 1) == ISO_colon) { strncpy_P(s->tmp_str, s->scriptptr + 1, sizeof(s->tmp_str) -1); if (httpd_fs_open(s->tmp_str, &s->file)) { PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } } else { PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(s->scriptptr)(s, s->scriptptr)); } next_scriptstate(s); // The script is over, so we reset the pointers and continue // sending the rest of the file. s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { // See if we find the start of script marker in the block of HTML // to be sent. if(s->file.len > uip_mss()) { s->len = uip_mss(); } else { s->len = s->file.len; } if(pgm_read_byte(s->file.data) == ISO_percent) { ptr = strchr_P(s->file.data + 1, ISO_percent); } else { ptr = strchr_P(s->file.data, ISO_percent); } if(ptr != NULL && ptr != s->file.data) { s->len = (int)(ptr - s->file.data); if(s->len >= uip_mss()) { s->len = uip_mss(); } } PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); s->file.data += s->len; s->file.len -= s->len; } } PT_END(&s->scriptpt); */ }
static PT_THREAD(data_activate_thread(struct pt *pt)) { PT_BEGIN(pt); char pdu[PDU_LENGTH]; char dataBuf[PDU_LENGTH]; int bufLen; int status; int sock; exosite_timer_t waitTimer; do { if(exosite_pal_load_cik(exoHttpContextQueue.cik, CIK_LENGTH)) break; build_msg_activate( pdu, sizeof(pdu), exoHttpContextQueue.vendor, exoHttpContextQueue.model, exoHttpContextQueue.sn); if(!exosite_pal_sock_connect(&sock)) { exosite_pal_sock_close(&sock); break; } if(!exosite_pal_sock_write( &sock, pdu, strlen(pdu))) { exosite_pal_sock_close(&sock); break; } exosite_pal_timer_init(&waitTimer); exosite_pal_timer_countdown_ms(&waitTimer, WAIT_TIME_MS); while(1) { if(exosite_pal_timer_expired(&waitTimer)) { exosite_pal_sock_close(&sock); break; } bufLen = sizeof(pdu); if(exosite_pal_sock_read( &sock, dataBuf, &bufLen) > 0) break; } if(!parse_rsp_status( dataBuf, bufLen, &status)) { exosite_pal_sock_close(&sock); break; } if(status != 200) { exosite_pal_sock_close(&sock); break; } if(!parse_cik_info( dataBuf, bufLen, exoHttpContextQueue.cik)) { exosite_pal_sock_close(&sock); break; } exosite_pal_save_cik( exoHttpContextQueue.cik, CIK_LENGTH); exosite_pal_sock_close(&sock); } while(false); PT_END(pt); }
static PT_THREAD(thread_process_msg(struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, radio_rx_flag == 1); //dump_message(radio_rx_buffer); /*if(radio_rx_buffer[MSG_BYTE_TYPE] == MSG_TYPE_ID_REQUEST) { prompt_node_id(); } else if(radio_rx_buffer[MSG_BYTE_TYPE] == MSG_TYPE_ID_REPLY && !timer_reached(TIMER_ID_INPUT, ID_INPUT_TIMEOUT_TICKS)) { set_node_id(radio_rx_buffer[MSG_BYTE_CONTENT]); } forward packet as it hasn't been processed on this node else if(radio_rx_buffer[MSG_BYTE_HOPS] < MAX_HOPS) { /* prevent loops by not forwarding a packet * if we are among the last hops int loop = 0; unsigned int i; for(i = MSG_BYTE_SRC_ROUTE; i < MSG_BYTE_SRC_ROUTE + radio_tx_buffer[MSG_BYTE_HOPS]; i++) { if(radio_tx_buffer[i] == node_id) { loop = 1; } } if(loop == 0) { memcpy(radio_tx_buffer, radio_rx_buffer, PKTLEN); radio_tx_buffer[MSG_BYTE_SRC_ROUTE + radio_tx_buffer[MSG_BYTE_HOPS]] = node_id; radio_tx_buffer[MSG_BYTE_HOPS]++; /* this is probably the ugliest MAC protocol ever made * (a packet send takes about 30 ms to complete, therefore * we wait 40 ms * node_id before forwarding a packet * to avoid collisions) TIMER_RADIO_FORWARD = 0; PT_WAIT_UNTIL(pt, timer_reached(TIMER_RADIO_FORWARD, 4 * node_id)); radio_send_message(); } }*/ if(radio_rx_buffer[MSG_BYTE_TYPE] == MSG_TYPE_TEMPERATURE) { unsigned int temperature; char *pt = (char *) &temperature; pt[0] = radio_rx_buffer[MSG_BYTE_CONTENT + 1]; pt[1] = radio_rx_buffer[MSG_BYTE_CONTENT]; printf("node_id,%d,temperature,%d.%d,rssi,%d,help,%d\r\n", (unsigned char) radio_rx_buffer[MSG_BYTE_SRC_ROUTE], temperature / 10, temperature % 10, last_rssi, radio_rx_buffer[MSG_BYTE_HOPS]); } radio_rx_flag = 0; } PT_END(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 int input_byte(uint8_t byte) { int crc; if(timer_expired(&rxstate.timer)) { restart_input(); } PT_BEGIN(&rxstate.pt); /* The first incoming byte is the length of the packet. */ rxstate.receiving = 1; rxstate.len = byte; if(byte == 0) { #if DEBUG printf("Bad len 0, state %d rxbytes %d\n", state(), read_rxbytes()); #endif /* DEBUG */ flushrx(); PT_EXIT(&rxstate.pt); } timer_set(&rxstate.timer, PACKET_LIFETIME); for(rxstate.ptr = 0; rxstate.ptr < rxstate.len; rxstate.ptr++) { /* Wait for the next data byte to be received. */ PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; } /* Receive two more bytes from the FIFO: the RSSI value and the LQI/CRC */ PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; rxstate.ptr++; PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; crc = (byte & 0x80); rxstate.ptr++; if(crc == 0) { #if DEBUG printf("bad crc\n"); #endif /* DEBUG */ flushrx(); } else if(packet_rx_len > 0) { #if DEBUG printf("Packet in the buffer (%d), dropping %d bytes\n", packet_rx_len, rxstate.len); #endif /* DEBUG */ flushrx(); process_poll(&cc1101_process); } else if(rxstate.len < ACK_LEN) { /* Drop packets that are way too small: less than ACK_LEN (3) bytes long. */ #if DEBUG printf("!"); #endif /* DEBUG */ } else { /* Read out the first three bytes to determine if we should send an ACK or not. */ /* Send a link-layer ACK before reading the full packet. */ if(rxstate.len >= ACK_LEN) { /* Try to parse the incoming frame as a 802.15.4 header. */ frame802154_t info154; if(frame802154_parse(rxstate.buf, rxstate.len, &info154) != 0) { /* XXX Potential optimization here: we could check if the frame is destined for us, or for the broadcast address and discard the packet if it isn't for us. */ if(1) { /* For dataframes that has the ACK request bit set and that is destined for us, we send an ack. */ if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && rimeaddr_cmp((rimeaddr_t *)&info154.dest_addr, &rimeaddr_node_addr)) { send_ack(info154.seq); /* Make sure that we don't put the radio in the IDLE state before the ACK has been fully transmitted. */ BUSYWAIT_UNTIL((state() != CC1101_STATE_TX), RTIMER_SECOND / 10); ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); if(state() == CC1101_STATE_TX) { #if DEBUG printf("didn't end ack tx (in %d, txbytes %d)\n", state(), txbytes()); #endif /* DEBUG */ check_txfifo(); flushrx(); } } memcpy((void *)packet_rx, rxstate.buf, rxstate.len + AUX_LEN); packet_rx_len = rxstate.len + AUX_LEN; /* including AUX */ process_poll(&cc1101_process); #if DEBUG printf("#"); #endif /* DEBUG */ } } } } rxstate.receiving = 0; PT_END(&rxstate.pt); }
/*---------------------------------------------------------------------------*/ static char powercycle(struct rtimer *t, void *ptr) { int r; #if WITH_TIMESYNCH rtimer_clock_t should_be, adjust; #endif /* WITH_TIMESYNCH */ CPRINTF("*"); PT_BEGIN(&pt); while(1) { /* Only wait for some cycles to pass for someone to start sending */ if(someone_is_sending > 0) { someone_is_sending--; } if(xmac_config.off_time > 0) { if(waiting_for_packet == 0) { if(we_are_sending == 0) { off(); } } else { waiting_for_packet++; if(waiting_for_packet > 2) { /* We should not be awake for more than two consecutive power cycles without having heard a packet, so we turn off the radio. */ waiting_for_packet = 0; #if WITH_TIMETABLE TIMETABLE_TIMESTAMP(xmac_timetable, "off waiting"); #endif off(); } } #if WITH_TIMESYNCH #define NUM_SLOTS 8 should_be = ((timesynch_rtimer_to_time(RTIMER_TIME(t)) + xmac_config.off_time) & ~(xmac_config.off_time + xmac_config.on_time - 1)) + (rimeaddr_node_addr.u8[0] % NUM_SLOTS * ((xmac_config.off_time + xmac_config.on_time) / NUM_SLOTS)); should_be = timesynch_time_to_rtimer(should_be); if(should_be - RTIMER_TIME(t) > xmac_config.off_time) { adjust = xmac_config.off_time / 2; } else { adjust = should_be - RTIMER_TIME(t); } r = rtimer_set(t, RTIMER_TIME(t) + adjust, 1, (void (*)(struct rtimer *, void *))powercycle, ptr); #else /* WITH_TIMESYNCH */ r = rtimer_set(t, RTIMER_TIME(t) + xmac_config.off_time, 1, TC(powercycle), ptr); #endif /* WITH_TIMESYNCH */ if(r) { PRINTF("xmac: 1 could not set rtimer %d\n", r); } PT_YIELD(&pt); } if(we_are_sending == 0 && waiting_for_packet == 0) { on(); } r = rtimer_set(t, RTIMER_TIME(t) + xmac_config.on_time, 1, TC(powercycle), ptr); if(r) { PRINTF("xmac: 3 could not set rtimer %d\n", r); } PT_YIELD(&pt); } PT_END(&pt); }
bool DWM1000_Tag::dispatch(Msg& msg) { PT_BEGIN() PT_WAIT_UNTIL(msg.is(0, SIG_INIT)); init(); POLL_SEND: { while (true) { timeout(1000); // delay between POLL PT_YIELD_UNTIL(timeout()); /* Write frame data to DW1000 and prepare transmission. See NOTE 7 below. */ tx_poll_msg[ALL_MSG_SN_IDX] = frame_seq_nb; dwt_writetxdata(sizeof(tx_poll_msg), tx_poll_msg, 0); dwt_writetxfctrl(sizeof(tx_poll_msg), 0); /* Start transmission, indicating that a response is expected so that reception is enabled automatically after the frame is sent and the delay * set by dwt_setrxaftertxdelay() has elapsed. */ LOG<< " Start TXF " << FLUSH; dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);// SEND POLL MSG dwt_setinterrupt(DWT_INT_TFRS, 0); dwt_setinterrupt(DWT_INT_RFCG, 1); // enable clearInterrupt(); _timeoutCounter = 0; /* We assume that the transmission is achieved correctly, poll for reception of a frame or error/timeout. See NOTE 8 below. */ timeout(10); PT_YIELD_UNTIL(timeout() || isInterruptDetected()); // WAIT RESP MSG if (isInterruptDetected()) LOG<< " INTERRUPT DETECTED " << FLUSH; status_reg = dwt_read32bitreg(SYS_STATUS_ID); LOG<< HEX <<" SYS_STATUS " << status_reg << FLUSH; if (status_reg == 0xDEADDEAD) { init(); } else if (status_reg & SYS_STATUS_RXFCG) goto RESP_RECEIVED; else if (status_reg & SYS_STATUS_ALL_RX_ERR) { if (status_reg & SYS_STATUS_RXRFTO) INFO(" RX Timeout"); else INFO(" RX error "); dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR); /* Clear RX error events in the DW1000 status register. */ } } } RESP_RECEIVED: { LOG<< " Received " <<FLUSH; frame_seq_nb++; /* Increment frame sequence number after transmission of the poll message (modulo 256). */ uint32 frame_len; /* Clear good RX frame event and TX frame sent in the DW1000 status register. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS); /* A frame has been received, read iCHANGEt into the local buffer. */ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK; if (frame_len <= RX_BUF_LEN) { dwt_readrxdata(rx_buffer, frame_len, 0); } /* Check that the frame is the expected response from the companion "DS TWR responder" example. * As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */ rx_buffer[ALL_MSG_SN_IDX] = 0; if (memcmp(rx_buffer, rx_resp_msg, ALL_MSG_COMMON_LEN) == 0) { // CHECK RESP MSG uint32 final_tx_time; /* Retrieve poll transmission and response reception timestamp. */ poll_tx_ts = get_tx_timestamp_u64(); resp_rx_ts = get_rx_timestamp_u64(); /* Compute final message transmission time. See NOTE 9 below. */ final_tx_time = (resp_rx_ts + (RESP_RX_TO_FINAL_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8; dwt_setdelayedtrxtime(final_tx_time); /* Final TX timestamp is the transmission time we programmed plus the TX antenna delay. */ final_tx_ts = (((uint64) (final_tx_time & 0xFFFFFFFE)) << 8) + TX_ANT_DLY; /* Write all timestamps in the final message. See NOTE 10 below. */ final_msg_set_ts(&tx_final_msg[FINAL_MSG_POLL_TX_TS_IDX], poll_tx_ts); final_msg_set_ts(&tx_final_msg[FINAL_MSG_RESP_RX_TS_IDX], resp_rx_ts); final_msg_set_ts(&tx_final_msg[FINAL_MSG_FINAL_TX_TS_IDX], final_tx_ts); /* Write and send final message. See NOTE 7 below. */ tx_final_msg[ALL_MSG_SN_IDX] = frame_seq_nb; dwt_writetxdata(sizeof(tx_final_msg), tx_final_msg, 0); dwt_writetxfctrl(sizeof(tx_final_msg), 0); dwt_starttx(DWT_START_TX_DELAYED); // SEND FINAL MSG /* Poll DW1000 until TX frame sent event set. See NOTE 8 below. */ timeout(10); PT_YIELD_UNTIL((dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS) || timeout());; /* Clear TXFRS event. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS); /* Increment frame sequence number after transmission of the final message (modulo 256). */ frame_seq_nb++; } else {
/*---------------------------------------------------------------------------*/ static PT_THREAD(connect_pt(struct pt* pt, struct mqtt_connection* conn)) { PT_BEGIN(pt); DBG("MQTT - Sending CONNECT message...\r\n"); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_CONNECT; conn->out_packet.remaining_length = 0; conn->out_packet.remaining_length += MQTT_connect_vhdr_flags_SIZE; conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->client_id); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.username); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.password); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.topic); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.message); encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); printf("MQTT - Error, remaining length > 4 bytes\r\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); PT_MQTT_WRITE_BYTE(conn, 0); PT_MQTT_WRITE_BYTE(conn, 6); PT_MQTT_WRITE_BYTES(conn, (uint8_t*)MQTT_PROTOCOL_NAME, 6); PT_MQTT_WRITE_BYTE(conn, MQTT_PROTOCOL_VERSION); PT_MQTT_WRITE_BYTE(conn, conn->connect_vhdr_flags); PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive & 0x00FF)); PT_MQTT_WRITE_BYTE(conn, conn->client_id.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->client_id.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->client_id.string, conn->client_id.length); if(conn->connect_vhdr_flags & MQTT_VHDR_WILL_FLAG) { PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->will.topic.string, conn->will.topic.length); PT_MQTT_WRITE_BYTE(conn, conn->will.message.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->will.message.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->will.message.string, conn->will.message.length); DBG("MQTT - Setting will topic to '%s' %i bytes and message to '%s' %i bytes\r\n", conn->will.topic.string, conn->will.topic.length, conn->will.message.string, conn->will.message.length); } if(conn->connect_vhdr_flags & MQTT_VHDR_USERNAME_FLAG) { DBG("MQTT - Setting username\r\n"); PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->credentials.username.string, conn->credentials.username.length); } if(conn->connect_vhdr_flags & MQTT_VHDR_PASSWORD_FLAG) { DBG("MQTT - Setting password\r\n"); PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->credentials.password.string, conn->credentials.password.length); } /* Send out buffer */ send_out_buffer(conn); conn->state = MQTT_CONN_STATE_CONNECTING_TO_BROKER; /* Wait for CONNACK */ reset_packet(&conn->in_packet); do { PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK); } while(conn->out_packet.qos_state != MQTT_QOS_STATE_GOT_ACK); reset_packet(&conn->in_packet); DBG("MQTT - Done sending CONNECT since we got CONNACK!\r\n"); #if DEBUG_MQTT == 1 DBG("MQTT - Sending CONNECT message: \r\n"); uint16_t i; for( i = 0; i < (conn->out_buffer_ptr - conn->out_buffer); i++ ) { DBG( "%02X ", conn->out_buffer[i] ); } DBG("\r\n"); #endif PT_END(pt); }
static PT_THREAD(data_write_thread(struct pt *pt)) { PT_BEGIN(pt); char dataBuf[4096]; static exosite_http_context_t *opContext; int status; do { printf("data_write_thread():\r\n"); if(!is_http_op_context_existed(EXO_OP_MODE_WRITE)) break; opContext = get_http_op_context(EXO_OP_MODE_WRITE); if(exoHttpContextQueue.deviceStatus != EXO_DEVICE_STATE_INITIALIZED) { struct pt actPt; PT_SPAWN(pt, &actPt, data_activate_thread(&actPt)); exoHttpContextQueue.deviceStatus = EXO_DEVICE_STATE_INITIALIZED; } if(!build_http_msg(opContext)) { release_op(opContext); break; } if(!exosite_pal_sock_write( &opContext->sock, opContext->pdu, strlen(opContext->pdu))) { opContext->opStatus = -1; opContext->resultCallback( NULL, opContext->opStatus); close_socket(&opContext->sock); release_op(opContext); break; } PT_YIELD(pt); memset(dataBuf, 0, sizeof(dataBuf)); size_t bufLen = sizeof(dataBuf); exosite_pal_timer_init(&opContext->waitTimer); exosite_pal_timer_countdown_ms(&opContext->waitTimer, WAIT_TIME_MS); bool isReadData = true; while(exosite_pal_sock_read( &opContext->sock, dataBuf, &bufLen) == 0) { PT_YIELD(pt); if(exosite_pal_timer_expired(&opContext->waitTimer)) { opContext->opStatus = -1; opContext->resultCallback( NULL, opContext->opStatus); close_socket(&opContext->sock); release_op(opContext); isReadData = false; break; } } if(!isReadData) break; printf("data_write_thread(): got rsp\r\n"); if(parse_rsp_status(dataBuf, bufLen, &status)) { opContext->opStatus = status; opContext->resultCallback( NULL, opContext->opStatus); release_op(opContext); check_http_error_status_to_determine_if_reset_cik(status); } printf("rsp status = %d\r\n", status); if(status == 401 || status == 403) { struct pt actPt; PT_SPAWN(pt, &actPt, data_activate_thread(&actPt)); } } while(false); PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(publish_pt(struct pt* pt, struct mqtt_connection* conn)) { PT_BEGIN(pt); DBG("MQTT - Sending publish message! topic %s topic_length %i\r\n", conn->out_packet.topic, conn->out_packet.topic_length); DBG("MQTT - Buffer space is %i \r\n", &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_PUBLISH | conn->out_packet.qos << 1; if(conn->out_packet.retain == MQTT_RETAIN_ON) { conn->out_packet.fhdr |= MQTT_FHDR_RETAIN_FLAG; } conn->out_packet.remaining_length = MQTT_STRING_LEN_SIZE + conn->out_packet.topic_length + conn->out_packet.payload_size; if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) { conn->out_packet.remaining_length += MQTT_MID_SIZE; } encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); printf("MQTT - Error, remaining length > 4 bytes\r\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); /* Write Variable Header */ PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.topic, conn->out_packet.topic_length); if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) { PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); } /* Write Payload */ PT_MQTT_WRITE_BYTES(conn, conn->out_packet.payload, conn->out_packet.payload_size); send_out_buffer(conn); /* If QoS is zero then wait until the message has been sent, since there is * no ACK to wait for. * * Also notify the app will not be notified via PUBACK or PUBCOMP */ if(conn->out_packet.qos == 0) { PT_WAIT_UNTIL(pt, conn->out_buffer_sent); process_post(conn->app_process, mqtt_update_event, NULL); } if(conn->out_packet.qos == 1) { /* Wait for PUBACK */ reset_packet(&conn->in_packet); do { PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK); } while(conn->out_packet.qos_state != MQTT_QOS_STATE_GOT_ACK); if(conn->in_packet.mid != conn->out_packet.mid) { DBG("MQTT - Warning, got PUBACK with none matching MID. Currently there is" "no support for several concurrent PUBLISH messages.\r\n"); } } if(conn->out_packet.qos == 2) { DBG("MQTT - QoS not implemented yet.\r\n"); /* Should wait for PUBREC, send PUBREL and then wait for PUBCOMP */ } reset_packet(&conn->in_packet); /* This is clear after the entire transaction is complete */ conn->out_queue_full = 0; DBG("MQTT - Done writing publish message to out buffer!\r\n"); PT_END(pt); }
static PT_THREAD (protothread_cmd(struct pt *pt)) { PT_BEGIN(pt); while(1) { // send the prompt via DMA to serial sprintf(PT_send_buffer,"cmd>"); // by spawning a print thread PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); //spawn a thread to handle terminal input // the input thread waits for input // -- BUT does NOT block other threads // string is returned in "PT_term_buffer" PT_SPAWN(pt, &pt_input, PT_GetSerialBuffer(&pt_input) ); // returns when the thread dies // in this case, when <enter> is pushed // now parse the string sscanf(PT_term_buffer, "%s %d", cmd, &value); if (cmd[0]=='d' ) { //set mux to DSP chip mPORTAClearBits(BIT_4); mPORTBClearBits(BIT_13); mPORTASetBits(BIT_4); mPORTBClearBits(BIT_3 | BIT_7 | BIT_8 | BIT_9); if(((value << 6) & (0x0040))){ mPORTBSetBits(BIT_3); } //select sound effect mPORTBSetBits(value << 6); } if (cmd[0] == 's'){ //distortion //set mux to Distortion mPORTAClearBits(BIT_4); mPORTBClearBits(BIT_13); } if (cmd[0] == 'n'){ //normal: only tone stack //set mux to channel 0 mPORTAClearBits(BIT_4); mPORTBClearBits(BIT_13); mPORTBSetBits(BIT_13); } //pots if (cmd[0] == 't'){ //treble // CS low to start transaction mPORTBClearBits(BIT_4); // start transaction deliverSPICh1Datum(value); // CS high mPORTBSetBits(BIT_4); // end transaction } if (cmd[0] == 'b'){ //bass // CS low to start transaction mPORTAClearBits(BIT_0); // start transaction deliverSPICh1Datum(value); // CS high mPORTASetBits(BIT_0); // end transaction } if (cmd[0] == 'v'){ //level // CS low to start transaction mPORTAClearBits(BIT_2); // start transaction deliverSPICh1Datum(value); // CS high mPORTASetBits(BIT_2); // end transaction } if (cmd[0] == 'm'){ //mid // CS low to start transaction mPORTAClearBits(BIT_3); // start transaction deliverSPICh1Datum(value); // CS high mPORTASetBits(BIT_3); // end transaction } // never exit while } // END WHILE(1) PT_END(pt); } // thread 3
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_tcpthread(struct pt *pt)) { register int ret; PT_BEGIN(pt); /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); goto thread_done; } s.len = htons(((struct codeprop_tcphdr *)uip_appdata)->len); s.addr = 0; uip_appdata += sizeof(struct codeprop_tcphdr); uip_len -= sizeof(struct codeprop_tcphdr); ret = xmem_erase(XMEM_ERASE_UNIT_SIZE, EEPROMFS_ADDR_CODEPROP); assert(ret == 0); /* Read the rest of the data. */ do { if(uip_len > 0) { ret = xmem_pwrite(uip_appdata, uip_len, EEPROMFS_ADDR_CODEPROP + s.addr); assert(ret = uip_len); s.addr += uip_len; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); /* Kill old program. */ cmod_unload(0); /* Link, load, and start new program. */ int s; static char msg[30 + 10]; cle_scratch elfloader_unknown; s = cmod_load(0, elfloader_unknown, xmem_pread, EEPROMFS_ADDR_CODEPROP); if (s == CMOD_OK) sprintf(msg, "ok\n"); else sprintf(msg, "err %d %s\n", s, elfloader_unknown); /* Return "ok" message. */ do { s = strlen(msg); uip_send(msg, s); PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); thread_done:; PT_END(pt); }
static PT_THREAD(handle_script(struct httpd_state *s)) { /* Note script includes will attach a leading : to the filename and a trailing zero */ static char scriptname[MAX_SCRIPT_NAME_LENGTH+1],*pptr; static uint16_t filelength; PT_BEGIN(&s->scriptpt); filelength=s->file.len; while(s->file.len > 0) { /* Sanity check */ if (s->file.len > filelength) break; /* Check if we should start executing a script, flagged by %! */ if(httpd_fs_getchar(s->file.data) == ISO_percent && httpd_fs_getchar(s->file.data + 1) == ISO_bang) { /* Extract name, if starts with colon include file else call cgi */ s->scriptptr=get_scriptname(scriptname,s->file.data+2); s->scriptlen=s->file.len-(s->scriptptr-s->file.data); PRINTF("httpd: Handle script named %s\n",scriptname); if(scriptname[0] == ISO_colon) { if (httpd_fs_open(&scriptname[1], &s->file)) { PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } } else { PT_WAIT_THREAD(&s->scriptpt,httpd_cgi(scriptname)(s, s->scriptptr)); } next_scriptstate(s); /* Reset the pointers and continue sending the current file. */ s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { /* Send file up to the next potential script */ if(s->file.len > uip_mss()) { s->len = uip_mss(); } else { s->len = s->file.len; } if(httpd_fs_getchar(s->file.data) == ISO_percent) { pptr = (char *) httpd_fs_strchr(s->file.data + 1, ISO_percent); } else { pptr = (char *) httpd_fs_strchr(s->file.data, ISO_percent); } if(pptr != NULL && pptr != s->file.data) { s->len = (int)(pptr - s->file.data); if(s->len >= uip_mss()) { s->len = uip_mss(); } } PRINTF("httpd: Sending %u bytes from 0x%04x\n",s->file.len,(unsigned int)s->file.data); PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); s->file.data += s->len; s->file.len -= s->len; } } PT_END(&s->scriptpt); }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_udpthread(struct pt *pt)) { int len; struct codeprop_udphdr *uh = (struct codeprop_udphdr *)uip_appdata; /* if(uip_newdata()) { PRINTF(("recv_udpthread: id %d uh->id %d\n", s.id, uip_htons(uh->id))); }*/ PT_BEGIN(pt); while(1) { do { PT_WAIT_UNTIL(pt, uip_newdata() && uh->type == UIP_HTONS(TYPE_DATA) && uip_htons(uh->id) > s.id); if(uip_htons(uh->addr) != 0) { s.addr = 0; send_nack(uh, 0); } } while(uip_htons(uh->addr) != 0); leds_on(LEDS_YELLOW); s.addr = 0; s.id = uip_htons(uh->id); s.len = uip_htons(uh->len); timer_set(&s.timer, CONNECTION_TIMEOUT); process_post(PROCESS_BROADCAST, codeprop_event_quit, (process_data_t)NULL); while(s.addr < s.len) { if(uip_htons(uh->addr) == s.addr) { leds_blink(); len = uip_datalen() - UDPHEADERSIZE; if(len > 0) { eeprom_write(EEPROMFS_ADDR_CODEPROP + s.addr, &uh->data[0], len); PRINTF(("Saved %d bytes at address %d, %d bytes left\n", uip_datalen() - UDPHEADERSIZE, s.addr, s.len - s.addr)); s.addr += len; } } else if(uip_htons(uh->addr) > s.addr) { PRINTF(("sending nack since 0x%x != 0x%x\n", uip_htons(uh->addr), s.addr)); send_nack(uh, s.addr); } if(s.addr < s.len) { /* timer_set(&s.nacktimer, NACK_TIMEOUT);*/ do { timer_set(&s.nacktimer, HIT_NACK_TIMEOUT); PT_YIELD_UNTIL(pt, timer_expired(&s.nacktimer) || (uip_newdata() && uh->type == UIP_HTONS(TYPE_DATA) && uip_htons(uh->id) == s.id)); if(timer_expired(&s.nacktimer)) { send_nack(uh, s.addr); } } while(timer_expired(&s.nacktimer)); } } leds_off(LEDS_YELLOW); /* printf("Received entire bunary over udr\n");*/ process_post(PROCESS_BROADCAST, codeprop_event_quit, (process_data_t)NULL); process_post(&codeprop_process, EVENT_START_PROGRAM, NULL); PT_EXIT(pt); } PT_END(pt); }
static PT_THREAD(recv_tcpthread(struct pt *pt)) { struct codeprop_tcphdr *th; int datalen = uip_datalen(); PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, uip_connected()); codeprop_exit_program(); s.state = STATE_RECEIVING_TCPDATA; s.addr = 0; s.count = 0; /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); if(uip_datalen() < CODEPROP_TCPHDR_SIZE) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); } th = (struct codeprop_tcphdr *)uip_appdata; s.len = uip_htons(th->len); s.addr = 0; uip_appdata += CODEPROP_TCPHDR_SIZE; datalen -= CODEPROP_TCPHDR_SIZE; /* Read the rest of the data. */ do { if(datalen > 0) { /* printf("Got %d bytes\n", datalen); */ if (cfs_seek(fd, s.addr, CFS_SEEK_SET) != s.addr) { PRINTF(("codeprop: seek in buffer file failed\n")); uip_abort(); } if (cfs_write(fd, uip_appdata, datalen) != datalen) { PRINTF(("codeprop: write to buffer file failed\n")); uip_abort(); } s.addr += datalen; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); #if 1 { static int err; err = codeprop_start_program(); /* Print out the "OK"/error message. */ do { if (err >= 0 && err < sizeof(err_msgs)/sizeof(char*)) { uip_send(err_msgs[err], strlen(err_msgs[err])); } else { uip_send("Unknown error\r\n", 15); } PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); } #endif ++s.id; s.state = STATE_SENDING_UDPDATA; tcpip_poll_udp(udp_conn); PT_WAIT_UNTIL(pt, s.state != STATE_SENDING_UDPDATA); /* printf("recv_tcpthread: unblocked\n");*/ } PT_END(pt); }
/*---------------------------------------------------------------------------*/ static char powercycle(struct rtimer *t, void *ptr) { PT_BEGIN(&pt); cycle_start = RTIMER_NOW(); while(1) { static uint8_t packet_seen; static rtimer_clock_t t0; static uint8_t count; cycle_start += CYCLE_TIME; if(WITH_STREAMING && is_streaming) { if(!RTIMER_CLOCK_LT(RTIMER_NOW(), stream_until)) { is_streaming = 0; rimeaddr_copy(&is_streaming_to, &rimeaddr_null); rimeaddr_copy(&is_streaming_to_too, &rimeaddr_null); } } packet_seen = 0; do { for(count = 0; count < CCA_COUNT_MAX; ++count) { t0 = RTIMER_NOW(); if(we_are_sending == 0) { powercycle_turn_radio_on(); /* Check if a packet is seen in the air. If so, we keep the radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to be able to receive the packet. We also continuously check the radio medium to make sure that we wasn't woken up by a false positive: a spurious radio interference that was not caused by an incoming packet. */ if(NETSTACK_RADIO.channel_clear() == 0) { packet_seen = 1; break; } powercycle_turn_radio_off(); } schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME); PT_YIELD(&pt); } if(packet_seen) { static rtimer_clock_t start; static uint8_t silence_periods, periods; start = RTIMER_NOW(); periods = silence_periods = 0; while(we_are_sending == 0 && radio_is_on && RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { /* Check for a number of consecutive periods of non-activity. If we see two such periods, we turn the radio off. Also, if a packet has been successfully received (as indicated by the NETSTACK_RADIO.pending_packet() function), we stop snooping. */ if(NETSTACK_RADIO.channel_clear()) { ++silence_periods; } else { silence_periods = 0; } ++periods; if(NETSTACK_RADIO.receiving_packet()) { silence_periods = 0; } if(silence_periods > MAX_SILENCE_PERIODS) { powercycle_turn_radio_off(); break; } if(WITH_FAST_SLEEP && periods > MAX_NONACTIVITY_PERIODS && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) { powercycle_turn_radio_off(); break; } if(NETSTACK_RADIO.pending_packet()) { break; } schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME); PT_YIELD(&pt); } if(radio_is_on) { if(!(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) || !RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { powercycle_turn_radio_off(); } } } } while((is_snooping || is_streaming) && RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 8)); if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) { schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); PT_YIELD(&pt); } } PT_END(&pt); }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_tcpthread(struct pt *pt)) { PT_BEGIN(pt); /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); goto thread_done; } /* Kill old program. */ rudolph0_stop(&rudolph0); /* elfloader_unload();*/ s.len = htons(((struct codeprop_tcphdr *)uip_appdata)->len); s.addr = 0; uip_appdata += sizeof(struct codeprop_tcphdr); uip_len -= sizeof(struct codeprop_tcphdr); s.fd = cfs_open("codeprop.out", CFS_WRITE); cfs_close(s.fd); /* xmem_erase(XMEM_ERASE_UNIT_SIZE, EEPROMFS_ADDR_CODEPROP);*/ /* Read the rest of the data. */ do { leds_toggle(LEDS_RED); if(uip_len > 0) { s.fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); cfs_seek(s.fd, s.addr, CFS_SEEK_SET); /* xmem_pwrite(uip_appdata, uip_len, EEPROMFS_ADDR_CODEPROP + s.addr);*/ cfs_write(s.fd, uip_appdata, uip_len); cfs_close(s.fd); PRINTF("Wrote %d bytes to file\n", uip_len); s.addr += uip_len; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); leds_off(LEDS_RED); #if DEBUG { int i, fd, j; printf("Contents of file:\n"); fd = cfs_open("codeprop.out", CFS_READ); j = 0; printf("\n0x%04x: ", 0); for(i = 0; i < s.len; ++i) { unsigned char byte; cfs_read(fd, &byte, 1); printf("0x%02x, ", byte); ++j; if(j == 8) { printf("\n0x%04x: ", i + 1); j = 0; } clock_delay(400); } cfs_close(fd); } #endif int ret; ret = start_program(); #if CONTIKI_TARGET_NETSIM rudolph0_send(&rudolph0, CLOCK_SECOND / 4); #else /* CONTIKI_TARGET_NETSIM */ if(ret == ELFLOADER_OK) { /* Propagate program. */ rudolph0_send(&rudolph0, CLOCK_SECOND / 4); } #endif /* CONTIKI_TARGET_NETSIM */ /* Return "ok" message. */ do { ret = strlen(msg); uip_send(msg, ret); PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); thread_done:; PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_dhcp(process_event_t ev, void *data)) { clock_time_t ticks; PT_BEGIN(&s.pt); init: 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); if(ev == tcpip_event && uip_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: 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 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: */ 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); }
static PT_THREAD(handle_bl(void)) { PT_BEGIN(&s.pt); s.retries = 3; do { flash_init(); tftpc_init(); tftpc_get(FIRMWARE_FILENAME); PT_WAIT_UNTIL(&s.pt, !tftpc_busy()); uint8_t rc = tftpc_result(); if(rc == TFTPC_FLASH_ERROR) { // any flash write errors, make sure the code doesn't run invalidate_code(); } // valid app code in place? if(!check_valid_code()) { // figure out what happened // and set indicator switch(rc) { case TFTPC_SUCCESS: diag_set(1); s.retries--; break; case TFTPC_SERVER_DOWN: diag_set(2); break; case TFTPC_FILE_NOT_FOUND: diag_set(3); break; case TFTPC_ERROR: diag_set(4); s.retries--; break; case TFTPC_FLASH_ERROR: diag_set(5); s.retries--; break; } } else { run_app(); } timer_set(&s.timer, RETRY_TIME); PT_WAIT_UNTIL(&s.pt, timer_expired(&s.timer)); } while (s.retries > 0); while(1) { PT_YIELD(&s.pt); } PT_END(&s.pt); }
/*---------------------------------------------------------------------------*/ static char powercycle(struct rtimer *t, void *ptr) { #if SYNC_CYCLE_STARTS static volatile rtimer_clock_t sync_cycle_start; static volatile uint8_t sync_cycle_phase; #endif PT_BEGIN(&pt); #if SYNC_CYCLE_STARTS sync_cycle_start = RTIMER_NOW(); #else cycle_start = RTIMER_NOW(); #endif while(1) { static uint8_t packet_seen; static rtimer_clock_t t0; static uint8_t count; #if SYNC_CYCLE_STARTS /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple of CHANNEL_CHECK_RATE */ if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { sync_cycle_phase = 0; sync_cycle_start += RTIMER_ARCH_SECOND; cycle_start = sync_cycle_start; } else { #if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535 cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE; #else cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE; #endif } #else cycle_start += CYCLE_TIME; #endif packet_seen = 0; for(count = 0; count < CCA_COUNT_MAX; ++count) { t0 = RTIMER_NOW(); if(we_are_sending == 0 && we_are_receiving_burst == 0) { powercycle_turn_radio_on(); /* Check if a packet is seen in the air. If so, we keep the radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to be able to receive the packet. We also continuously check the radio medium to make sure that we wasn't woken up by a false positive: a spurious radio interference that was not caused by an incoming packet. */ if(NETSTACK_RADIO.channel_clear() == 0) { packet_seen = 1; break; } powercycle_turn_radio_off(); } schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME); PT_YIELD(&pt); } if(packet_seen) { static rtimer_clock_t start; static uint8_t silence_periods, periods; start = RTIMER_NOW(); periods = silence_periods = 0; while(we_are_sending == 0 && radio_is_on && RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { /* Check for a number of consecutive periods of non-activity. If we see two such periods, we turn the radio off. Also, if a packet has been successfully received (as indicated by the NETSTACK_RADIO.pending_packet() function), we stop snooping. */ #if !RDC_CONF_HARDWARE_CSMA /* A cca cycle will disrupt rx on some radios, e.g. mc1322x, rf230 */ /*TODO: Modify those drivers to just return the internal RSSI when already in rx mode */ if(NETSTACK_RADIO.channel_clear()) { ++silence_periods; } else { silence_periods = 0; } #endif ++periods; if(NETSTACK_RADIO.receiving_packet()) { silence_periods = 0; } if(silence_periods > MAX_SILENCE_PERIODS) { powercycle_turn_radio_off(); break; } if(WITH_FAST_SLEEP && periods > MAX_NONACTIVITY_PERIODS && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) { powercycle_turn_radio_off(); break; } if(NETSTACK_RADIO.pending_packet()) { break; } schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME); PT_YIELD(&pt); } if(radio_is_on) { if(!(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) || !RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { powercycle_turn_radio_off(); } } } if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) { /* Schedule the next powercycle interrupt, or sleep the mcu until then. Sleeping will not exit from this interrupt, so ensure an occasional wake cycle or foreground processing will be blocked until a packet is detected */ #if RDC_CONF_MCU_SLEEP static uint8_t sleepcycle; if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start)); } else { sleepcycle = 0; schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); PT_YIELD(&pt); } #else schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); PT_YIELD(&pt); #endif } } PT_END(&pt); }
static char powercycle(struct rtimer *t, void *ptr) { PT_BEGIN(&pt); while(1) { static uint8_t packet_seen; static rtimer_clock_t t0; static uint8_t count; cycle_start = RTIMER_NOW(); if(WITH_STREAMING && is_streaming) { #if NURTIMER if(!RTIMER_CLOCK_LT(cycle_start, RTIMER_NOW(), stream_until)) #else if(!RTIMER_CLOCK_LT(RTIMER_NOW(), stream_until)) #endif { is_streaming = 0; rimeaddr_copy(&is_streaming_to, &rimeaddr_null); rimeaddr_copy(&is_streaming_to_too, &rimeaddr_null); } } packet_seen = 0; do { for(count = 0; count < CCA_COUNT_MAX; ++count) { t0 = RTIMER_NOW(); if(we_are_sending == 0) { powercycle_turn_radio_on(); #if 0 #if NURTIMER while(RTIMER_CLOCK_LT(t0, RTIMER_NOW(), t0 + CCA_CHECK_TIME)); #else while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)); #endif #endif /* 0 */ /* Check if a packet is seen in the air. If so, we keep the radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to be able to receive the packet. We also continuously check the radio medium to make sure that we wasn't woken up by a false positive: a spurious radio interference that was not caused by an incoming packet. */ if(NETSTACK_RADIO.channel_clear() == 0) { packet_seen = 1; break; } powercycle_turn_radio_off(); } schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME); /* COOJA_DEBUG_STR("yield\n");*/ PT_YIELD(&pt); } if(packet_seen) { static rtimer_clock_t start; static uint8_t silence_periods, periods; start = RTIMER_NOW(); periods = silence_periods = 0; while(we_are_sending == 0 && radio_is_on && RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { /* Check for a number of consecutive periods of non-activity. If we see two such periods, we turn the radio off. Also, if a packet has been successfully received (as indicated by the NETSTACK_RADIO.pending_packet() function), we stop snooping. */ if(NETSTACK_RADIO.channel_clear()) { ++silence_periods; } else { silence_periods = 0; } ++periods; if(NETSTACK_RADIO.receiving_packet()) { silence_periods = 0; } if(silence_periods > MAX_SILENCE_PERIODS) { LEDS_ON(LEDS_RED); powercycle_turn_radio_off(); #if CONTIKIMAC_CONF_COMPOWER compower_accumulate(&compower_idle_activity); #endif /* CONTIKIMAC_CONF_COMPOWER */ LEDS_OFF(LEDS_RED); break; } #if 1 if(periods > MAX_NONACTIVITY_PERIODIC && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) { LEDS_ON(LEDS_GREEN); powercycle_turn_radio_off(); #if CONTIKIMAC_CONF_COMPOWER compower_accumulate(&compower_idle_activity); #endif /* CONTIKIMAC_CONF_COMPOWER */ LEDS_OFF(LEDS_GREEN); break; } #endif /* 0 */ if(NETSTACK_RADIO.pending_packet()) { break; } schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME); LEDS_ON(LEDS_BLUE); PT_YIELD(&pt); LEDS_OFF(LEDS_BLUE); } if(radio_is_on && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) { LEDS_ON(LEDS_RED + LEDS_GREEN); powercycle_turn_radio_off(); #if CONTIKIMAC_CONF_COMPOWER compower_accumulate(&compower_idle_activity); #endif /* CONTIKIMAC_CONF_COMPOWER */ LEDS_OFF(LEDS_RED + LEDS_GREEN); } } else { #if CONTIKIMAC_CONF_COMPOWER compower_accumulate(&compower_idle_activity); #endif /* CONTIKIMAC_CONF_COMPOWER */ } } while(is_snooping && RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME)); if(is_snooping) { LEDS_ON(LEDS_RED); } if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME)) { /* schedule_powercycle(t, CYCLE_TIME - (RTIMER_NOW() - cycle_start));*/ schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); /* printf("cycle_start 0x%02x now 0x%02x wait 0x%02x\n", cycle_start, RTIMER_NOW(), CYCLE_TIME - (RTIMER_NOW() - cycle_start));*/ PT_YIELD(&pt); } LEDS_OFF(LEDS_RED); } PT_END(&pt); }
bool Wifi::dispatch(Msg& msg) { // INFO("line : %d ",_ptLine); // INFO("msg : %d:%d",msg.src(),msg.signal()); PT_BEGIN(); INIT : { PT_WAIT_UNTIL(msg.is(0,SIG_INIT)); struct station_config stationConf; INFO("WIFI_INIT"); if ( wifi_set_opmode(STATION_MODE) ){ ; // STATIONAP_MODE was STATION_MODE INFO("line : %d",__LINE__); if ( wifi_set_phy_mode(PHY_MODE_11B)) { os_memset(&stationConf, 0, sizeof(struct station_config)); ets_strncpy((char*)stationConf.ssid,_ssid,sizeof(stationConf.ssid)); ets_strncpy((char*)stationConf.password,_pswd,sizeof(stationConf.password)); stationConf.bssid_set=0; INFO("line : %d",__LINE__); if ( wifi_station_set_config(&stationConf) ){ if ( wifi_station_connect() ){ INFO("line : %d",__LINE__); goto DISCONNECTED;// wifi_station_set_auto_connect(TRUE); } } } } // wifi_station_set_auto_connect(FALSE); INFO(" WIFI INIT failed , retrying... "); goto INIT; }; DISCONNECTED: { while(true) { timeout(1000); PT_YIELD_UNTIL(timeout()); struct ip_info ipConfig; wifi_get_ip_info(STATION_IF, &ipConfig); wifiStatus = wifi_station_get_connect_status(); if ( wifi_station_get_connect_status()== STATION_NO_AP_FOUND || wifi_station_get_connect_status()==STATION_WRONG_PASSWORD || wifi_station_get_connect_status()==STATION_CONNECT_FAIL) { INFO(" NOT CONNECTED "); wifi_station_connect(); } else if (wifiStatus == STATION_GOT_IP && ipConfig.ip.addr != 0) { _connections++; union { uint32_t addr; uint8_t ip[4]; } v; v.addr = ipConfig.ip.addr; INFO(" IP Address : %d.%d.%d.%d ",v.ip[0],v.ip[1],v.ip[2],v.ip[3]); INFO(" CONNECTED "); Msg::publish(this,SIG_CONNECTED); _connected=true; timeout(2000); goto CONNECTED; } else { INFO(" STATION_IDLE "); } timeout(500); } }; CONNECTED : { while(true) { PT_YIELD_UNTIL(timeout()); struct ip_info ipConfig; wifi_get_ip_info(STATION_IF, &ipConfig); wifiStatus = wifi_station_get_connect_status(); if (wifiStatus != STATION_GOT_IP ) { Msg::publish(this,SIG_DISCONNECTED); timeout(500); _connected=false; goto DISCONNECTED; } timeout(2000); } }; PT_END(); }
/*---------------------------------------------------------------------------*/ static int parse_header_byte(struct http_socket *s, char c) { PT_BEGIN(&s->headerpt); memset(&s->header, -1, sizeof(s->header)); /* Skip the HTTP response */ while(c != ' ') { PT_YIELD(&s->headerpt); } /* Skip the space */ PT_YIELD(&s->headerpt); /* Read three characters of HTTP status and convert to BCD */ s->header.status_code = 0; for(s->header_chars = 0; s->header_chars < 3; s->header_chars++) { s->header.status_code = s->header.status_code << 4 | (c - '0'); PT_YIELD(&s->headerpt); } if(s->header.status_code == 0x200 || s->header.status_code == 0x206) { /* Read headers until data */ while(1) { /* Skip characters until end of line */ do { while(c != '\r') { s->header_chars++; PT_YIELD(&s->headerpt); } s->header_chars++; PT_YIELD(&s->headerpt); } while(c != '\n'); s->header_chars--; PT_YIELD(&s->headerpt); if(s->header_chars == 0) { /* This was an empty line, i.e. the end of headers */ break; } /* Start of line */ s->header_chars = 0; /* Read header field */ while(c != ' ' && c != '\t' && c != ':' && c != '\r' && s->header_chars < sizeof(s->header_field) - 1) { s->header_field[s->header_chars++] = c; PT_YIELD(&s->headerpt); } s->header_field[s->header_chars] = '\0'; /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c == ':') { /* Skip the colon */ s->header_chars++; PT_YIELD(&s->headerpt); /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(!strcmp(s->header_field, "Content-Length")) { s->header.content_length = 0; while(isdigit((int)c)) { s->header.content_length = s->header.content_length * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } } else if(!strcmp(s->header_field, "Content-Range")) { /* Skip the bytes-unit token */ while(c != ' ' && c != '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } s->header.content_range.first_byte_pos = 0; while(isdigit((int)c)) { s->header.content_range.first_byte_pos = s->header.content_range.first_byte_pos * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c == '-') { /* Skip the dash */ s->header_chars++; PT_YIELD(&s->headerpt); /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } s->header.content_range.last_byte_pos = 0; while(isdigit((int)c)) { s->header.content_range.last_byte_pos = s->header.content_range.last_byte_pos * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c == '/') { /* Skip the slash */ s->header_chars++; PT_YIELD(&s->headerpt); /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c != '*') { s->header.content_range.instance_length = 0; while(isdigit((int)c)) { s->header.content_range.instance_length = s->header.content_range.instance_length * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } } } } } } } /* All headers read, now read data */ call_callback(s, HTTP_SOCKET_HEADER, (void *)&s->header, sizeof(s->header)); /* Should exit the pt here to indicate that all headers have been read */ PT_EXIT(&s->headerpt); } else { if(s->header.status_code == 0x404) { printf("File not found\n"); } else if(s->header.status_code == 0x301 || s->header.status_code == 0x302) { printf("File moved (not handled)\n"); } call_callback(s, HTTP_SOCKET_ERR, (void *)&s->header, sizeof(s->header)); tcp_socket_close(&s->s); removesocket(s); PT_EXIT(&s->headerpt); } PT_END(&s->headerpt); }