static void schedule_powercycle(struct rtimer *t, rtimer_clock_t time) { int r; if(contikimac_is_on) { if(RTIMER_CLOCK_LT(RTIMER_TIME(t) + time, RTIMER_NOW() + 2)) { time = RTIMER_NOW() - RTIMER_TIME(t) + 2; } r = rtimer_set(t, RTIMER_TIME(t) + time, 1, (void (*)(struct rtimer *, void *))powercycle, NULL); if(r != RTIMER_OK) { PRINTF("schedule_powercycle: could not set rtimer\n"); } } }
static void schedule_powercycle(struct rtimer *t, rtimer_clock_t time) { int r; if(xmac_is_on) { r = rtimer_set(t, RTIMER_TIME(t) + time, 1, (void (*)(struct rtimer *, void *))powercycle, NULL); if(r) { PRINTF("schedule_powercycle: could not set rtimer\n"); } } }
/*---------------------------------------------------------------------------*/ #if GLOSSY static volatile int in_on_phase = 0; char powercycle(void) { PT_BEGIN(&pt); while(1) { if((xmac_config.off_time > 0) && (!was_timeout)) { if(we_are_sending == 0) { in_on_phase = 1; off(); } if(xmac_is_on) { TBCCR3 += xmac_config.off_time; } PT_YIELD(&pt); } last_on = TBCCR3; was_timeout = 0; if(we_are_sending == 0) { in_on_phase = 0; on(); } if(xmac_is_on) { TBCCR3 += xmac_config.on_time; in_on_phase = 0; } PT_YIELD(&pt); } PT_END(&pt); } #else /* GLOSSY */ static char powercycle(struct rtimer *t, void *ptr) { int r; PT_BEGIN(&pt); while(1) { if((xmac_config.off_time > 0) && (!was_timeout)) { if(we_are_sending == 0) { off(); } if(xmac_is_on) { r = rtimer_set(t, RTIMER_TIME(t) + xmac_config.off_time, 1, (void (*)(struct rtimer *, void *))powercycle, ptr); } PT_YIELD(&pt); } last_on = RTIMER_TIME(t); was_timeout = 0; if(we_are_sending == 0) { on(); } if(xmac_is_on) { r = rtimer_set(t, RTIMER_TIME(t) + xmac_config.on_time, 1, (void (*)(struct rtimer *, void *))powercycle, ptr); } PT_YIELD(&pt); } PT_END(&pt); }
/*---------------------------------------------------------------------------*/ static void schedule_powercycle(struct rtimer *t, rtimer_clock_t time) { int r; rtimer_clock_t now; if(contikimac_is_on) { time += RTIMER_TIME(t); now = RTIMER_NOW(); if(RTIMER_CLOCK_LT(time, now + RTIMER_GUARD_TIME)) { time = now + RTIMER_GUARD_TIME; } r = rtimer_set(t, time, 1, powercycle_wrapper, NULL); if(r != RTIMER_OK) { PRINTF("schedule_powercycle: could not set rtimer\n"); } } }
static void schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time) { int r; if(contikimac_is_on) { if(RTIMER_CLOCK_LT(fixed_time, RTIMER_NOW() + 1)) { fixed_time = RTIMER_NOW() + 1; } #if NURTIMER r = rtimer_reschedule(t, RTIMER_TIME(t) - time, 1); #else r = rtimer_set(t, fixed_time, 1, (void (*)(struct rtimer *, void *))powercycle, NULL); #endif if(r != RTIMER_OK) { printf("schedule_powercycle: could not set rtimer\n"); } } }
/*---------------------------------------------------------------------------*/ static void advanceSlot(struct rtimer *t, void *ptr, int status) { off(TURN_OFF); last = RTIMER_TIME(t); if(!(rtimer_set(t, last + REGULAR_SLOT, 1, (void (*)(struct rtimer *, void *))advanceSlot, NULL) == RTIMER_OK)) { printf("%s\n", "WPI-MAC: Could not schedule task!!!!!"); } if(current_slot == TOTAL_SLOTS + 1) { current_slot = BROADCAST_SLOT; } else { current_slot++; } if(current_slot > (TOTAL_SLOTS - 1)) { current_slot = BROADCAST_SLOT; } //printf("Slot is now %u\n", current_slot); unsigned char somethingToSend = check_buffers(current_slot); if(somethingToSend) { // grab the necessary info from our queue QueuedPacket *curr = QPQueue[current_slot]; real_send(curr->sent, curr->ptr, curr->packet); } else if(current_slot == BROADCAST_SLOT || current_slot == node_id) { // just need to be awake to listen // if(!(rtimer_set(t, last + CONTENTION_PREPARE + (CONTENTION_TICKS * (CONTENTION_SLOTS)), 1, (void (*)(struct rtimer *, void *))async_on, NULL) == RTIMER_OK)){ // printf("%s\n", "Could not schedule task!!!!!"); // } rtimer_clock_t stall = last + CONTENTION_PREPARE + (CONTENTION_TICKS * (CONTENTION_SLOTS)); // printf("STALLLLL: %u %u %u %u\n", RTIMER_NOW(), stall, REGULAR_SLOT, last); while(RTIMER_CLOCK_LT(RTIMER_NOW(), stall)); if(!radio_is_on) on(); } else { // we can snooze if(radio_is_on) off(TURN_OFF); } }
char glossy_scheduler(struct rtimer *t, void *ptr) { PT_BEGIN(&pt); if (IS_INITIATOR()) { // Glossy initiator. while (1) { printf("[SCHEDULER]: Get Data from queue\n"); // Increment sequence number. glossy_data.seq_no++; // Glossy phase. leds_on(LEDS_GREEN); rtimer_clock_t t_stop = RTIMER_TIME(t) + GLOSSY_DURATION; // Start Glossy. glossy_start((uint8_t *)&glossy_data, DATA_LEN, GLOSSY_INITIATOR, GLOSSY_SYNC, N_TX, APPLICATION_HEADER, t_stop, (rtimer_callback_t)glossy_scheduler, t, ptr); // Store time at which Glossy has started. t_start = RTIMER_TIME(t); // Yield the protothread. It will be resumed when Glossy terminates. PT_YIELD(&pt); // Off phase. leds_off(LEDS_GREEN); // Stop Glossy. glossy_stop(); if (!GLOSSY_IS_BOOTSTRAPPING()) { // Glossy has already successfully bootstrapped. if (!GLOSSY_IS_SYNCED()) { // The reference time was not updated: increment reference time by GLOSSY_PERIOD. set_t_ref_l(GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD); set_t_ref_l_updated(1); } } // Schedule begin of next Glossy phase based on GLOSSY_PERIOD. rtimer_set(t, t_start + GLOSSY_PERIOD, 1, (rtimer_callback_t)glossy_scheduler, ptr); // Estimate the clock skew over the last period. estimate_period_skew(); // Poll the process that prints statistics (will be activated later by Contiki). process_poll(&glossy_print_stats_process); // Yield the protothread. PT_YIELD(&pt); } } else { // Glossy receiver. while (1) { // Glossy phase. leds_on(LEDS_GREEN); rtimer_clock_t t_stop; if (GLOSSY_IS_BOOTSTRAPPING()) { // Glossy is still bootstrapping: // Schedule end of Glossy phase based on GLOSSY_INIT_DURATION. t_stop = RTIMER_TIME(t) + GLOSSY_INIT_DURATION; } else { // Glossy has already successfully bootstrapped: // Schedule end of Glossy phase based on GLOSSY_DURATION. t_stop = RTIMER_TIME(t) + GLOSSY_DURATION; } // Start Glossy. glossy_start((uint8_t *)&glossy_data, DATA_LEN, GLOSSY_RECEIVER, GLOSSY_SYNC, N_TX, APPLICATION_HEADER, t_stop, (rtimer_callback_t)glossy_scheduler, t, ptr); // Yield the protothread. It will be resumed when Glossy terminates. PT_YIELD(&pt); // Off phase. leds_off(LEDS_GREEN); // Stop Glossy. glossy_stop(); if (GLOSSY_IS_BOOTSTRAPPING()) { // Glossy is still bootstrapping. if (!GLOSSY_IS_SYNCED()) { // The reference time was not updated: reset skew_estimated to zero. skew_estimated = 0; } } else { // Glossy has already successfully bootstrapped. if (!GLOSSY_IS_SYNCED()) { // The reference time was not updated: // increment reference time by GLOSSY_PERIOD + period_skew. set_t_ref_l(GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD + period_skew); set_t_ref_l_updated(1); // Increment sync_missed. sync_missed++; } else { // The reference time was not updated: reset sync_missed to zero. sync_missed = 0; } } // Estimate the clock skew over the last period. estimate_period_skew(); if (GLOSSY_IS_BOOTSTRAPPING()) { // Glossy is still bootstrapping. if (skew_estimated == 0) { // The reference time was not updated: // Schedule begin of next Glossy phase based on last begin and GLOSSY_INIT_PERIOD. rtimer_set(t, RTIMER_TIME(t) + GLOSSY_INIT_PERIOD, 1, (rtimer_callback_t)glossy_scheduler, ptr); } else { // The reference time was updated: // Schedule begin of next Glossy phase based on reference time and GLOSSY_INIT_PERIOD. rtimer_set(t, GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD - GLOSSY_INIT_GUARD_TIME, 1, (rtimer_callback_t)glossy_scheduler, ptr); } } else { // Glossy has already successfully bootstrapped: // Schedule begin of next Glossy phase based on reference time and GLOSSY_PERIOD. rtimer_set(t, GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD + period_skew - GLOSSY_GUARD_TIME * (1 + sync_missed), 1, (rtimer_callback_t)glossy_scheduler, ptr); } // Poll the process that prints statistics (will be activated later by Contiki). process_poll(&glossy_print_stats_process); // Yield the protothread. PT_YIELD(&pt); } } PT_END(&pt); }
// TDMA_BS_send() -- called at a specific time static void TDMA_BS_send(void) { //printf("%05u,",RTIMER_NOW());//call time for BS_send // uint8_t bkn_len = 16; // uint8_t bkn_pkt[16]={0}; // bkn_pkt[14]=1; // bkn_pkt[15]=2; if (disable_sending == 1) return; // set timer for next BS send // right now, rtimer_timer does not consider drifting. For long time experiment, it may have problem rtimer_set(&BSTimer,RTIMER_TIME(&BSTimer)+segment_period,0,TDMA_BS_send,NULL); //update packet sequence number seq_num = seq_num + 1; if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_CMD) // has command to send { // Assume for BS, if the tdma_rdc_buf is not empty, then the payload should be command. // Should be changed if BS can send other types of data. /* packetbuf_copyfrom((void *)&tdma_rdc_buffer[0],sizeof(uint8_t)*tdma_rdc_buf_ptr); packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,PACKETBUF_ATTR_PACKET_TYPE_CMD); tdma_rdc_buf_full_flg = 0; tdma_rdc_buf_ptr = 0; tdma_rdc_buf_send_ptr = 0; */ PRINTF("send command %s %d\n",tdma_rdc_buffer,packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE)); } else { packetbuf_copyfrom((void *)&bkn_pkt,sizeof(uint8_t)*bkn_len); packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP); } BS_RX_start_time = radio_TX_time+BS_period; packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO,seq_num); uint8_t hdr_len = NETSTACK_FRAMER.create(); // fail to create framer if(hdr_len < 0) return; //send packet -- pushed to radio layer if(NETSTACK_RADIO.send(packetbuf_hdrptr(),packetbuf_totlen()) != RADIO_TX_OK) { printf("TDMA RDC: BS fails to send packet\n"); } else { printf("TDMA RDC: BS sends %u, %u bits\n",seq_num,packetbuf_datalen()); char* data_ptr = (char *)packetbuf_dataptr(); // PRINTF("%c%c%c\n",data_ptr[0],data_ptr[1],data_ptr[2]); } }
/*---------------------------------------------------------------------------*/ 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); }
// TDMA_BS_send() -- called at a specific time static void TDMA_BS_send(void) { //printf("%05u,",RTIMER_NOW());//call time for BS_send //uint8_t bkn_len = 16; //uint8_t bkn_pkt[16]={0}; //bkn_pkt[14]=1; //bkn_pkt[15]=2; char bkn_pkt[100]; // Lab 5 switch(beacon_msg_counter) { case 0: strncpy(bkn_pkt,"Welcome to CEE155/255 ",100); break; case 1: strncpy(bkn_pkt,"This msg is from the base station ",100); break; case 2: strncpy(bkn_pkt,"Answer following questions: ",100); break; case 3: strncpy(bkn_pkt,"1.fs of a 20Hz sine wave ",100); break; case 4: strncpy(bkn_pkt,"2.Data rate of a 16 bit ADC and fs = 5Hz ",100); break; case 5: strncpy(bkn_pkt,"3. list 6 blocks of sensor network ",100); break; } //Lab 5 uint8_t bkn_len = strlen(bkn_pkt)+1; beacon_msg_counter = (beacon_msg_counter+1)%6; // set timer for next BS send // right now, rtimer_timer does not consider drifting. For long time experiment, it may have problem rtimer_set(&BSTimer,RTIMER_TIME(&BSTimer)+segment_period,0,TDMA_BS_send,NULL); //update packet sequence number seq_num = seq_num + 1; if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_CMD) // has command to send { // Assume for BS, if the tdma_rdc_buf is not empty, then the payload should be command. // Should be changed if BS can send other types of data. /* packetbuf_copyfrom((void *)&tdma_rdc_buffer[0],sizeof(uint8_t)*tdma_rdc_buf_ptr); packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,PACKETBUF_ATTR_PACKET_TYPE_CMD); tdma_rdc_buf_full_flg = 0; tdma_rdc_buf_ptr = 0; tdma_rdc_buf_send_ptr = 0; */ PRINTF("send command %s %d\n",tdma_rdc_buffer,packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE)); } else { packetbuf_copyfrom((void *)&bkn_pkt,sizeof(uint8_t)*bkn_len); packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP); } BS_RX_start_time = radio_TX_time+BS_period; packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO,seq_num); uint8_t hdr_len = NETSTACK_FRAMER.create(); // fail to create framer if(hdr_len < 0) return; //send packet -- pushed to radio layer if(NETSTACK_RADIO.send(packetbuf_hdrptr(),packetbuf_totlen()) != RADIO_TX_OK) { printf("TDMA RDC: BS fails to send packet\n"); } else { printf("TDMA RDC: BS sends %u, %u bits\n",seq_num,packetbuf_datalen()); char* data_ptr = (char *)packetbuf_dataptr(); // PRINTF("%c%c%c\n",data_ptr[0],data_ptr[1],data_ptr[2]); } }
// TDMA_BS_send() -- called at a specific time static void TDMA_BS_send(void) { //printf("%05u,",RTIMER_NOW());//call time for BS_send /* uint8_t bkn_len = 16; uint8_t bkn_pkt[16]={0}; bkn_pkt[14]=1; bkn_pkt[15]=2; */ uint8_t bkn_len = 12; uint8_t bkn_pkt[12] = {72,73,72,74,72,75,72,76,72,77,72,78}; // set timer for next BS send // right now, rtimer_timer does not consider drifting. For long time experiment, it may have problem rtimer_set(&BSTimer,RTIMER_TIME(&BSTimer)+segment_period,0,TDMA_BS_send,NULL); if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_CMD) // has command to send { printf("Remote shell command %s -- sent\n",(char *)packetbuf_dataptr()); } else { packetbuf_copyfrom((void *)&bkn_pkt,sizeof(uint8_t)*bkn_len); packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP); } BS_RX_start_time = radio_TX_time+BS_period; //update packet sequence number seq_num = seq_num + 1; seq_num = ((seq_num == 10) ? 11: seq_num); //filter out 10 packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO,seq_num); uint8_t hdr_len = NETSTACK_FRAMER.create(); // fail to create framer if(hdr_len < 0) return; //send packet -- pushed to radio layer // uint8_t i = 0; // uint8_t * pkt = packetbuf_hdrptr(); // for(i = 0; i < packetbuf_totlen(); i++) // { // printf("%u,",pkt[i]); // } // printf("\n"); if(NETSTACK_RADIO.send(packetbuf_hdrptr(),packetbuf_totlen()) != RADIO_TX_OK) { printf("TDMA RDC: BS fails to send packet\n"); } else { PRINTF("TDMA RDC: BS sends %u\n",seq_num); } //clean flag packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP); }