/*---------------------------------------------------------------------------*/ PROCESS_THREAD(demo_source, ev, data) { static struct etimer et; rimeaddr_t addr; //PROCESS_EXITHANDLER(unicast_close(&unicast);) PROCESS_BEGIN(); // unicast init // unicast_open(&unicast, 146, &unicast_callbacks); // UART init // slip_arch_init(115200); // DATA Storing // data_sensing=(uint8_t *) malloc(UART_Full+1 * sizeof(uint8_t)); //size+1 은 첫번째에 indicator 넣기 위함! data_sensing[0]='B'; //sensor 식별자 sensor A or sensor B //data_sensing[UART_Full]=90; while (1) { etimer_set(&et, CLOCK_SECOND/10); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); //printf("%d\t%c\n",data_sensing[0],data_sensing[0]); /* RAIDO_LISTEN : * Wait start signal from Sink Node */ if(CURRENT_STATE==RAIDO_LISTEN){ PRINTF("CURRENT_STATE: %d. RAIDO_LISTEN \n",CURRENT_STATE); leds_on(RAIDO_LISTEN); if (RADIO_Input=='S'){ UART_out('S'); CURRENT_STATE=UART_START; RADIO_Input=NULL; } } /* UART_SEND : * 1. Sensor Interface로 부터 Sensing Complete(C) 신호를 받은 경우 * 2. Sensor Interface로 부터 1회 UART 전송을 완료하고 SUCCESS신호를 받은경우 * -> NEXT(N) 신호를 전달하여 다음 데이터 요구 * 1. Sensor Interface로 부터 (!SUCCESS)를 받은 경우 * ->Retransmission(R) 신호 전달 */ else if(CURRENT_STATE==UART_SEND){ PRINTF("CURRENT_STATE: %d. UART_SEND \n",CURRENT_STATE); leds_on(UART_SEND); if(UART_Success==1) UART_out('N'); else if (UART_Success==0) UART_out('R'); CURRENT_STATE=UART_LISTEN; } /* UART_READY : * 1회 전송 가능 data 량을 Sensor interface 로 부터 받은 경우 * data를 packet화 하여 unicast 전송 */ else if(CURRENT_STATE==UART_READY){ PRINTF("CURRENT_STATE: %d. UART_READY \n",CURRENT_STATE); leds_on(UART_READY); //헤더 붙이고, 데이터 패킷화 하여 전송하기 packetbuf_copyfrom(data_sensing, UART_Full+1); addr.u8[0] = 4; addr.u8[1] = 0; //send to F2 unicast_send(&unicast, &addr); CURRENT_STATE=RADIO_SENT; } else if(CURRENT_STATE==RADIO_SENT){ RADIO_NumSend++; PRINTF("CURRENT_STATE: %d. RADIO_SNET \t RADIO_NumSend : %d\n",CURRENT_STATE,RADIO_NumSend); leds_on(RADIO_SENT); if(RADIO_NumSend>=END_SENSING)//End 인 경우 { UART_End=1; //이건 아마 필요없는 기능이 될듯 CURRENT_STATE=RAIDO_LISTEN; RADIO_NumSend=0; } else{ CURRENT_STATE=UART_SEND; } } else if(CURRENT_STATE==UART_START){ PRINTF("CURRENT_STATE: %d. UART_START \n",UART_START); leds_on(UART_START); } else if(CURRENT_STATE==UART_LISTEN){ PRINTF("CURRENT_STATE: %d. UART_LISTEN \n",UART_LISTEN); leds_on(UART_LISTEN); } else { PRINTF("NONE STATE \t%d\n",CURRENT_STATE); leds_on(0); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(example_abc_process, ev, data) { static struct channel *c; static struct etimer et; PROCESS_BEGIN(); char buffer[32]; //button_sensor.activate(); SENSORS_ACTIVATE(button_sensor); printf("ready to rock\n"); //ds2411_init(); static int i; //cc2420_init(); //cc2420_set_pan_addr(panId, 0 /*XXX*/, ds2411_id); //cc2420_set_channel(26); //abc_open(&abc, 128, &abc_call); // set_rime_addr(); // cc2420_init(); //cc2420_set_pan_addr(panId, 0 , ds2411_id); // cc2420_set_channel(RF_CHANNEL); //cc2420_set_txpower(31); //nullmac_init(&cc2420_driver); //rime_init(&nullmac_driver); //cc2420_set_txpower(31); //cc2420_on(); channel_init(); packetbuf_clear(); driver = nullmac_init(&cc2420_driver); //rime_init(driver); //driver = sicslowmac_init(&cc2420_driver); cc2420_set_channel(26); channel_open(c, 34); /*packetbuf_clear();*/ driver->set_receive_function(recv); //packetbuf_clear(); channel_set_attributes(34, attributes); //set_receive_function(driver); driver->on(); leds_toggle(LEDS_RED); packetbuf_clear(); etimer_set(&et, CLOCK_SECOND * 2 + random_rand() % (CLOCK_SECOND * 2)); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); leds_toggle(LEDS_RED); PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor); while(1) { if (i % 20 == 19) { PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor); } else { printf("wait!"); etimer_set(&et, CLOCK_SECOND * 0.5 + random_rand() % (CLOCK_SECOND) * 0.25); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } sprintf(buffer, "ping %d\0",i); printf("Attempting to send %s\n", buffer); // send the message straight to the radio //cc2420_send ( buffer, (int)strlen(buffer) ); packetbuf_clear(); packetbuf_copyfrom(&buffer, (int)strlen(buffer)); //driver->on(); //cc2420_driver.send(&buffer, (int)strlen(buffer)); //cc2420_send ( &buffer, (int)strlen(buffer) ); driver->send(); //rime_output(); //abc_send(&abc); //chameleon_output(c); //driver->off(1); printf("Message sent\n"); leds_toggle(LEDS_YELLOW); i = i + 1; } PROCESS_END(); }
// 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]); } }
// TDMA_SN_send() -- called at a assigned time slot static void TDMA_SN_send(void) { //set timer for open RADIO -- for opening earlier 2 ms //uint16_t time = RTIMER_TIME(&SNTimer)+RTIMER_MS*(segment_period-BS_period-my_slot*TS_period); uint16_t callBkTime = RTIMER_NOW(); radioontime = SN_RX_start_time+segment_period-GRD_PERIOD;//RTIMER_TIME(&SNTimer) + (total_slot_num-my_slot)*TS_period-GRD_PERIOD;//(segment_period-BS_period-(my_slot)*TS_period - GRD_PERIOD); rtimer_set(&SNTimer,radioontime,0,NETSTACK_RADIO.on,NULL); //update packet sequence number seq_num = seq_num + 1; //wait if the tdma_rdc_buffer is accessing by other functions while(tdma_rdc_buf_in_using_flg); // lock tdma_rdc_buffer and preventing access from other functions. tdma_rdc_buf_in_using_flg = 1; if (tdma_rdc_buf_full_flg == 0) { packetbuf_copyfrom((void *)&tdma_rdc_buffer[0],sizeof(uint8_t)*tdma_rdc_buf_ptr); packetbuf_set_datalen(tdma_rdc_buf_ptr); } else { uint8_t temp_len = MAX_PKT_PAYLOAD_SIZE - tdma_rdc_buf_send_ptr; memcpy(packetbuf_dataptr(),tdma_rdc_buffer+tdma_rdc_buf_send_ptr,sizeof(uint8_t)*temp_len); memcpy(packetbuf_dataptr()+temp_len,tdma_rdc_buffer,sizeof(uint8_t)*tdma_rdc_buf_send_ptr); packetbuf_set_datalen(MAX_PKT_PAYLOAD_SIZE); } // send packet -- pushed to radio layer if(NETSTACK_RADIO.on()) { packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO,seq_num); uint8_t hdr_len = NETSTACK_FRAMER.create(); if(NETSTACK_RADIO.send(packetbuf_hdrptr(),packetbuf_totlen()) != RADIO_TX_OK) { printf("TDMA RDC: SN fails to send packet\n"); } else { //lab 5 //printf("TDMA RDC: SN sends %d, %d bytes\n",seq_num,packetbuf_datalen()); } tdma_rdc_buf_full_flg = 0; tdma_rdc_buf_ptr = 0; tdma_rdc_buf_send_ptr = 0; memset(tdma_rdc_buffer,0,MAX_PKT_PAYLOAD_SIZE); } else { printf("TDMA RDC: SN fails to open radio\n"); } // turn off radio NETSTACK_RADIO.off(); // release tdma_rdc_buffer tdma_rdc_buf_in_using_flg = 0; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(zoul_demo_process, ev, data) { PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_BEGIN(); counter = 0; broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); /* Configure the user button */ button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, BUTTON_PRESS_EVENT_INTERVAL); /* Configure the ADC ports */ adc_sensors.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC_ALL); printf("Zoul test application\n"); etimer_set(&et, LOOP_INTERVAL); while(1) { PROCESS_YIELD(); if(ev == PROCESS_EVENT_TIMER) { leds_on(LEDS_PERIODIC); printf("-----------------------------------------\n" "Counter = 0x%08x\n", counter); printf("VDD = %d mV\n", vdd3_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); printf("Temperature = %d mC\n", cc2538_temp_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); printf("ADC1 = %d raw\n", adc_sensors.value(ZOUL_SENSORS_ADC1)); printf("ADC3 = %d raw\n", adc_sensors.value(ZOUL_SENSORS_ADC3)); etimer_set(&et, LOOP_INTERVAL); rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, rt_callback, NULL); counter++; } else if(ev == sensors_event) { if(data == &button_sensor) { if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) { printf("Button pressed\n"); packetbuf_copyfrom(&counter, sizeof(counter)); broadcast_send(&bc); } else { printf("...and released!\n"); } } } else if(ev == serial_line_event_message) { leds_toggle(LEDS_SERIAL_IN); } else if(ev == button_press_duration_exceeded) { printf("Button pressed for %d ticks [%u events]\n", (*((uint8_t *)data) * BUTTON_PRESS_EVENT_INTERVAL), button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION)); } } PROCESS_END(); }
void sicslowmac_unknownIndication(void) { if (sicslowmac_snifferhook) { packetbuf_clear(); /* Finally, get the stuff into the rime buffer.... */ packetbuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length); packetbuf_set_datalen(parsed_frame->payload_length); #if UIP_LLADDR_LEN == 8 memcpy(dest_reversed, (uint8_t *)parsed_frame->dest_addr, UIP_LLADDR_LEN); memcpy(src_reversed, (uint8_t *)parsed_frame->src_addr, UIP_LLADDR_LEN); /* Change addresses to expected byte order */ byte_reverse((uint8_t *)dest_reversed, UIP_LLADDR_LEN); byte_reverse((uint8_t *)src_reversed, UIP_LLADDR_LEN); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const linkaddr_t *)dest_reversed); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const linkaddr_t *)src_reversed); #elif UIP_CONF_USE_RUM dest_reversed[0] = MSB(parsed_frame->dest_pid); dest_reversed[1] = LSB(parsed_frame->dest_pid); dest_reversed[2] = 0; dest_reversed[3] = 0; dest_reversed[4] = MSB(parsed_frame->payload[0]); //FinalDestAddr dest_reversed[5] = LSB(parsed_frame->payload[1]); src_reversed[0] = MSB(parsed_frame->src_pid); src_reversed[1] = LSB(parsed_frame->src_pid); src_reversed[2] = 0; src_reversed[3] = 0; src_reversed[4] = MSB(parsed_frame->payload[2]); //originAddr src_reversed[5] = LSB(parsed_frame->payload[3]); #else dest_reversed[0] = MSB(parsed_frame->dest_pid); dest_reversed[1] = LSB(parsed_frame->dest_pid); dest_reversed[2] = 0; dest_reversed[3] = 0; dest_reversed[4] = MSB(parsed_frame->dest_addr->addr16); dest_reversed[5] = LSB(parsed_frame->dest_addr->addr16); src_reversed[0] = MSB(parsed_frame->src_pid); src_reversed[1] = LSB(parsed_frame->src_pid); src_reversed[2] = 0; src_reversed[3] = 0; src_reversed[4] = MSB(parsed_frame->src_addr->addr16); src_reversed[5] = LSB(parsed_frame->src_addr->addr16); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const linkaddr_t *)dest_reversed); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const linkaddr_t *)src_reversed); #endif PRINTF("sicslowmac: hand off frame to sniffer \n"); sicslowmac_snifferhook(pmac_driver); } }
//void sendDataTask() { PROCESS_THREAD(sendDataTask, ev, data) { PROCESS_BEGIN(); while(1) { PROCESS_WAIT_EVENT(); pmesg(200, "%s :: %s :: Line #%d\n", __FILE__, __func__, __LINE__); static fe_queue_entry_t* qe; static fe_queue_entry_t* nullQe; static message_wrapper_t* nullMsg; static bcp_data_header_t* nullHdr; static int subsendResult; static error_t retVal; static uint8_t payloadLen; static rimeaddr_t dest; static message_wrapper_t* hdr; static uint32_t sendTime; static uint32_t checksum; checksum = 0; // Specialty handling of loopback or sudden sink designation if(rootControl_isRoot()) { sending = false; // If we are sending we'll abort if(sendQeOccupied == true) { qe = sendQe; sendQeOccupied = false; // Guaranteed succcessful service } else { if(list_length(send_stack) == 0 && virtualQueueSize == 0) { //This shouldn't be possible pmesg(10, "FAILURE IN BCP_FORWARDING_ENGINE.c SENDDATATASK()"); continue; } qe = sendQe = list_pop(send_stack); } memcpy(loopbackMsgPtr, qe -> msg, sizeof(message_wrapper_t)); //Deallocate the message in qe list_remove(message_pool, qe -> msg); memb_free(&message_pool_mem, qe -> msg); //Deallocate the qe object list_remove(q_entry_pool, qe); memb_free(&q_entry_pool_mem, qe); //Signal the event if(ev_msg_receive != NULL) loopbackMsgPtr = ev_msg_receive(loopbackMsgPtr); //Maybe do it again, if we are sink and there are data packets forwarderActivity(); continue; } if(sendQeOccupied == true) { qe = sendQe; } else { if(list_length(send_stack) == 0 && virtualQueueSize == 0) { pmesg(10, "ERROR: BcpForwardingEngine sendDataTask()\n"); continue; } //Check to see whether there exists a neighbor to route to with positive weight. retVal = routerForwarder_updateRouting(list_length(send_stack) + sendQeOccupied + virtualQueueSize); //NO_SNOOP: add another retVal response type, //if there is no entry in our routing table //request a RR beacon if(retVal == ESIZE) { sending = false; pmesg(200, "DEBUG: RR Beacon Send\n"); beaconType = RR_BEACON; process_post(&sendBeaconTask, NULL, NULL); //Stop the timer, reset it. We have two, one for keeping time, // one for the function call back ctimer_stop(&txRetryTimer); ctimer_set(&txRetryTimer, REROUTE_TIME, tx_retry_timer_fired, NULL); timer_reset(&txRetryTimerTime); continue; } if(retVal == FAIL) { //No neighbor is a good option right now, wait on a recompute-time sending = false; ctimer_stop(&txRetryTimer); ctimer_set(&txRetryTimer, REROUTE_TIME, tx_retry_timer_fired, NULL); timer_reset(&txRetryTimerTime); continue; } if(list_length(send_stack) == 0) { // Create a null packet, place it on the stack (must be here by virtue of a virtual backlog) nullQe = memb_alloc(&q_entry_pool_mem); if(nullQe == NULL) { pmesg(10, "ERROR: BcpForwardingEngine - sendDataTask. Cannot enqueue nullQe\n"); continue; } list_add(q_entry_pool, nullQe); nullMsg = memb_alloc(&message_pool_mem); if(nullMsg == NULL) { pmesg(10, "ERROR: BcpForwardingEngine - sendDataTask. Cannot enqueue nullMsg\n"); //Deallocate list_remove(q_entry_pool, nullQe); memb_free(&q_entry_pool_mem, nullQe); continue; } list_add(message_pool, nullMsg); nullHdr = &(nullMsg -> bcp_data_header); nullHdr -> hopCount = 0; rimeaddr_copy(&(nullHdr -> origin), &rimeaddr_node_addr); nullHdr -> originSeqNo = nullSeqNo++; nullHdr -> bcpDelay = 0; nullHdr -> txCount = 0; nullHdr -> pktType = PKT_NULL; nullQe -> arrivalTime = 0; //call DelayPacketTimer.getNow(); nullQe -> firstTxTime = 0; nullQe -> bcpArrivalDelay = 0; nullQe -> msg = nullMsg; nullQe -> source = LOCAL_SEND; nullQe -> txCount = 0; list_push(send_stack, nullQe); virtualQueueSize--; } qe = sendQe = list_pop(send_stack); pmesg(10, "SENDING MESSAGE ORIGINATING FROM = %d.%d\n", qe -> msg -> bcp_data_header.origin.u8[0], qe -> msg -> bcp_data_header.origin.u8[1]); qe -> firstTxTime = timer_remaining(&txRetryTimerTime); //call txRetryTimer.getNow(); sendQeOccupied = true; } //End else // payloadLen = sizeof(qe -> msg); //call SubPacket.payloadLength(qe->msg); // Give up on a link after MAX_RETX_ATTEMPTS retransmit attempts, link is lousy! // Furthermore, penalize by double MAX_RETX_ATTEMPTS, due to cutoff. if(qe -> txCount >= MAX_RETX_ATTEMPTS) { static bool isBroadcast = 0; isBroadcast = rimeaddr_cmp(&(qe -> msg -> from), &rimeaddr_null); routerForwarder_updateLinkSuccess(&(qe -> msg -> from), isBroadcast, 2*MAX_RETX_ATTEMPTS); //call RouterForwarderIF.updateLinkSuccess(call AMDataPacket.destination(qe->msg), 2*MAX_RETX_ATTEMPTS); // call BcpDebugIF.reportValues( 0,0,0,0,0,MAX_RETX_ATTEMPTS, call AMDataPacket.destination(qe->msg),0x77 ); qe -> txCount = 0; // Place back on the Stack, discard element if necesary conditionalFQDiscard(); list_push(send_stack, qe); // retVal = call SendStack.pushTop( qe ); sendQeOccupied = false; // Try again after a REROUTE_TIME, this choice was bad. sending = false; ctimer_stop(&txRetryTimer); ctimer_set(&txRetryTimer, REROUTE_TIME, tx_retry_timer_fired, NULL); timer_reset(&txRetryTimerTime); continue; } qe -> txCount++; localTXCount++; rimeaddr_copy(&dest, &nextHopAddress_m); //Request an ack, not going to support DL without ack (for now) //Store the local backpressure level to the backpressure field hdr = qe -> msg; //getHeader(qe->msg); hdr -> bcp_data_header.bcpBackpressure = list_length(send_stack) + sendQeOccupied + virtualQueueSize; //Fill in the next hop Backpressure value hdr -> bcp_data_header.nhBackpressure = nextHopBackpressure_m; //Fill in the node tx count field (burst success detection by neighbors #ifndef BEACON_ONLY hdr -> bcp_data_header.nodeTxCount = localTXCount; // Fill in the burstNotifyAddr, then reset to TOS_NODE_ID immediately rimeaddr_copy(&(hdr->bcp_data_header.burstNotifyAddr), ¬ifyBurstyLinkNeighbor_m); rimeaddr_copy(¬ifyBurstyLinkNeighbor_m, &rimeaddr_node_addr); #endif //Update the txCount field hdr -> bcp_data_header.txCount = hdr -> bcp_data_header.txCount + 1; sendTime = 0; //This timer is never implemented in TinyOS: timer_remaining(&delayPacketTimer); //regardless of transmission history, lastTxTime and BcpDelay are re-comptued. hdr -> bcp_data_header.bcpDelay = qe -> bcpArrivalDelay + (sendTime - qe -> arrivalTime) + PER_HOP_MAC_DLY; //Calculate the checksum! checksum = calcHdrChecksum(qe -> msg); hdr -> bcp_data_header.hdrChecksum = checksum; // #ifdef LOW_POWER_LISTENING // // call LowPowerListening.setRxSleepInterval(qe->msg, LPL_SLEEP_INTERVAL_MS); // call LowPowerListening.setRemoteWakeupInterval(qe->msg, LPL_SLEEP_INTERVAL_MS); // #endif //Send thge packet!! rimeaddr_copy(&(qe -> msg -> to), &dest); rimeaddr_copy(&(qe -> msg -> from), &rimeaddr_node_addr); payloadLen = sizeof(message_wrapper_t); //call SubPacket.payloadLength(qe->msg); packetbuf_clear(); packetbuf_set_datalen(payloadLen); packetbuf_copyfrom(qe -> msg, payloadLen); pmesg(10, "Checksum from packet about to send: %u\n", ((message_wrapper_t*)packetbuf_dataptr()) -> bcp_data_header.hdrChecksum); //Non-zero if the packet could be sent, zero otherwise subsendResult = unicast_send(&unicast, &dest); //Success if(subsendResult != 0) { // Successfully submitted to the data-link layer. pmesg(100, "BcpForwardingEngine: Successfully Sent Unicast Message\n"); //Print out end-to-end message only if packet is originating from here if(rimeaddr_cmp(&(qe -> msg -> from), &(qe -> msg -> bcp_data_header.origin)) != 0) printf("Sent Packet from: %d.%d with SequenceNum = %lu\n", qe -> msg -> bcp_data_header.origin.u8[0], qe -> msg -> bcp_data_header.origin.u8[1], qe -> msg -> bcp_data_header.packetSeqNum); continue; } else { pmesg(100, "BcpForwardingEngine: Failed to Send Unicast Message. Trying again\n"); // radioOn = false; // NO_SNOOP: set beacon type beaconType = NORMAL_BEACON; process_post(&sendDataTask, NULL, NULL); } } //End while(1) PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(cc2538_demo_process, ev, data) { PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_BEGIN(); counter = 0; broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); /* Enable antenna */ antenna_sw_select(ANTENNA_SW_SELECT_INTERNAL); button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, BUTTON_PRESS_EVENT_INTERVAL); tmp102_init(); printf("Re-Mote test application, initial values:\n"); etimer_set(&et, LOOP_INTERVAL); while(1) { PROCESS_YIELD(); if(ev == PROCESS_EVENT_TIMER) { leds_on(LEDS_PERIODIC); printf("-----------------------------------------\n" "Counter = 0x%08x\n", counter); printf("VDD = %d mV\n", vdd3_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); printf("Temperature = %d mC\n", cc2538_temp_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); printf("Phidget ADC2 = %d raw\n", phidget_sensor.value(PHIDGET_SENSORS_ADC2)); printf("Phidget ADC3 = %d raw\n", phidget_sensor.value(PHIDGET_SENSORS_ADC3)); tmp102_read(&temperature); printf("TMP102 sensor = %u mC\n", temperature); etimer_set(&et, LOOP_INTERVAL); rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, rt_callback, NULL); counter++; } else if(ev == sensors_event) { if(data == &button_sensor) { if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) { printf("Press\n"); packetbuf_copyfrom(&counter, sizeof(counter)); broadcast_send(&bc); } else { printf("Release\n"); } } } else if(ev == serial_line_event_message) { leds_toggle(LEDS_SERIAL_IN); } else if(ev == button_press_duration_exceeded) { printf("Button pressed for %d ticks [%u events]\n", (*((uint8_t *)data) * BUTTON_PRESS_EVENT_INTERVAL), button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION)); } } PROCESS_END(); }
PROCESS_THREAD(main_process, ev, data) { static struct etimer et; int16_t out; int i, s; char str[5]; PROCESS_EXITHANDLER(broadcast_close(&broadcast)); PROCESS_BEGIN(); broadcast_open(&broadcast, SNIFFER_CHANNEL, &broadcast_call); SENSORS_ACTIVATE(button_sensor); // Don't start data collection until user button is pressed PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor); // Wait two seconds after activating light sensor to allow user to move away after // pressing the button SENSORS_ACTIVATE(light_sensor); etimer_set(&et, CLOCK_SECOND*2); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); //~ if( ADC12CTL0 & REFON ) //~ { //~ if( ADC12CTL0 & REF2_5V ) //~ { //~ packetbuf_copyfrom("Vref=2.5V", 10); //~ } //~ else //~ { //~ packetbuf_copyfrom("Vref=1.5V", 10); //~ } //~ } //~ else //~ { //~ packetbuf_copyfrom("Vref=off", 9); //~ } //~ //~ broadcast_send(&broadcast); while( 1 ) { etimer_set(&et, CLOCK_SECOND/FREQ); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); out = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); s = snprintf( str, 5, "%i", out ) + 1; //packetbuf_copyfrom( &out,sizeof(out) ); if( s ) { packetbuf_copyfrom( str, s ); } else { packetbuf_copyfrom( "I am alive.", 12 ); } broadcast_send(&broadcast); } PROCESS_END(); }
static int fragment(struct net_buf *buf, void *ptr) { struct queuebuf *q; int max_payload; int framer_hdrlen; uint16_t frag_tag; /* Number of bytes processed. */ uint16_t processed_ip_out_len; struct net_buf *mbuf; bool last_fragment = false; #define USE_FRAMER_HDRLEN 0 #if USE_FRAMER_HDRLEN framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ framer_hdrlen = 21; } #else /* USE_FRAMER_HDRLEN */ framer_hdrlen = 21; #endif /* USE_FRAMER_HDRLEN */ max_payload = MAC_MAX_PAYLOAD - framer_hdrlen - NETSTACK_LLSEC.get_overhead(); PRINTF("max_payload: %d, framer_hdrlen: %d \n",max_payload, framer_hdrlen); mbuf = l2_buf_get_reserve(0); if (!mbuf) { goto fail; } uip_last_tx_status(mbuf) = MAC_TX_OK; /* * The destination address will be tagged to each outbound * packet. If the argument localdest is NULL, we are sending a * broadcast packet. */ if((int)uip_len(buf) <= max_payload) { /* The packet does not need to be fragmented, send buf */ packetbuf_copyfrom(mbuf, uip_buf(buf), uip_len(buf)); send_packet(mbuf, &ip_buf_ll_dest(buf), true, ptr); ip_buf_unref(buf); return 1; } uip_uncomp_hdr_len(mbuf) = 0; uip_packetbuf_hdr_len(mbuf) = 0; packetbuf_clear(mbuf); uip_packetbuf_ptr(mbuf) = packetbuf_dataptr(mbuf); packetbuf_set_attr(mbuf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, SICSLOWPAN_MAX_MAC_TRANSMISSIONS); PRINTF("fragmentation: total packet len %d\n", uip_len(buf)); /* * The outbound IPv6 packet is too large to fit into a single 15.4 * packet, so we fragment it into multiple packets and send them. * The first fragment contains frag1 dispatch, then * IPv6/HC1/HC06/HC_UDP dispatchs/headers. * The following fragments contain only the fragn dispatch. */ int estimated_fragments = ((int)uip_len(buf)) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1; int freebuf = queuebuf_numfree(mbuf) - 1; PRINTF("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len(buf), estimated_fragments, freebuf); if(freebuf < estimated_fragments) { PRINTF("Dropping packet, not enough free bufs\n"); goto fail; } /* Create 1st Fragment */ SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len(buf))); frag_tag = my_tag++; SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_TAG, frag_tag); PRINTF("fragmentation: fragment %d \n", frag_tag); /* Copy payload and send */ uip_packetbuf_hdr_len(mbuf) += SICSLOWPAN_FRAG1_HDR_LEN; uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xfffffff8; PRINTF("(payload len %d, hdr len %d, tag %d)\n", uip_packetbuf_payload_len(mbuf), uip_packetbuf_hdr_len(mbuf), frag_tag); memcpy(uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf), uip_buf(buf), uip_packetbuf_payload_len(mbuf)); packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf)); q = queuebuf_new_from_packetbuf(mbuf); if(q == NULL) { PRINTF("could not allocate queuebuf for first fragment, dropping packet\n"); goto fail; } net_buf_ref(mbuf); send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr); queuebuf_to_packetbuf(mbuf, q); queuebuf_free(q); q = NULL; /* Check tx result. */ if((uip_last_tx_status(mbuf) == MAC_TX_COLLISION) || (uip_last_tx_status(mbuf) == MAC_TX_ERR) || (uip_last_tx_status(mbuf) == MAC_TX_ERR_FATAL)) { PRINTF("error in fragment tx, dropping subsequent fragments.\n"); goto fail; } /* set processed_ip_out_len to what we already sent from the IP payload*/ processed_ip_out_len = uip_packetbuf_payload_len(mbuf); /* * Create following fragments * Datagram tag is already in the buffer, we need to set the * FRAGN dispatch and for each fragment, the offset */ uip_packetbuf_hdr_len(mbuf) = SICSLOWPAN_FRAGN_HDR_LEN; SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len(buf))); uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xfffffff8; while(processed_ip_out_len < uip_len(buf)) { PRINTF("fragmentation: fragment:%d, processed_ip_out_len:%d \n", my_tag, processed_ip_out_len); uip_packetbuf_ptr(mbuf)[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3; /* Copy payload and send */ if(uip_len(buf) - processed_ip_out_len < uip_packetbuf_payload_len(mbuf)) { /* last fragment */ last_fragment = true; uip_packetbuf_payload_len(mbuf) = uip_len(buf) - processed_ip_out_len; } PRINTF("(offset %d, len %d, tag %d)\n", processed_ip_out_len >> 3, uip_packetbuf_payload_len(mbuf), my_tag); memcpy(uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf), (uint8_t *)UIP_IP_BUF(buf) + processed_ip_out_len, uip_packetbuf_payload_len(mbuf)); packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf)); q = queuebuf_new_from_packetbuf(mbuf); if(q == NULL) { PRINTF("could not allocate queuebuf, dropping fragment\n"); goto fail; } net_buf_ref(mbuf); send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr); queuebuf_to_packetbuf(mbuf, q); queuebuf_free(q); q = NULL; processed_ip_out_len += uip_packetbuf_payload_len(mbuf); /* Check tx result. */ if((uip_last_tx_status(mbuf) == MAC_TX_COLLISION) || (uip_last_tx_status(mbuf) == MAC_TX_ERR) || (uip_last_tx_status(mbuf) == MAC_TX_ERR_FATAL)) { PRINTF("error in fragment tx, dropping subsequent fragments.\n"); goto fail; } } ip_buf_unref(buf); l2_buf_unref(mbuf); return 1; fail: if (mbuf) { l2_buf_unref(mbuf); } return 0; }
// 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); }
/*---------------------------------------------------------------------------*/ uint8_t uip_over_mesh_send(void) { linkaddr_t receiver; struct route_entry *rt; /* This function is called by the uip-fw module to send out an IP packet. We try to send the IP packet to the next hop route, or we queue the packet and send out a route request for the final receiver of the packet. */ /* Packets destined to this network is sent using mesh, whereas packets destined to a network outside this network is sent towards the gateway node. */ if(uip_ipaddr_maskcmp(&BUF->destipaddr, &netaddr, &netmask)) { receiver.u8[0] = BUF->destipaddr.u8[2]; receiver.u8[1] = BUF->destipaddr.u8[3]; } else { if(linkaddr_cmp(&gateway, &linkaddr_node_addr)) { PRINTF("uip_over_mesh_send: I am gateway, packet to %d.%d.%d.%d to local interface\n", uip_ipaddr_to_quad(&BUF->destipaddr)); if(gw_netif != NULL) { return gw_netif->output(); } return UIP_FW_DROPPED; } else if(linkaddr_cmp(&gateway, &linkaddr_null)) { PRINTF("uip_over_mesh_send: No gateway setup, dropping packet\n"); return UIP_FW_OK; } else { PRINTF("uip_over_mesh_send: forwarding packet to %d.%d.%d.%d towards gateway %d.%d\n", uip_ipaddr_to_quad(&BUF->destipaddr), gateway.u8[0], gateway.u8[1]); linkaddr_copy(&receiver, &gateway); } } PRINTF("uIP over mesh send to %d.%d with len %d\n", receiver.u8[0], receiver.u8[1], uip_len); packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len); /* Send TCP data with the PACKETBUF_ATTR_ERELIABLE set so that an underlying power-saving MAC layer knows that it should be waiting for an ACK. */ if(BUF->proto == UIP_PROTO_TCP) { packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 1); packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1); /* packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM);*/ } rt = route_lookup(&receiver); if(rt == NULL) { PRINTF("uIP over mesh no route to %d.%d\n", receiver.u8[0], receiver.u8[1]); if(queued_packet == NULL) { queued_packet = queuebuf_new_from_packetbuf(); linkaddr_copy(&queued_receiver, &receiver); route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT); } else if(!linkaddr_cmp(&queued_receiver, &receiver)) { route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT); } } else { route_decay(rt); send_data(&rt->nexthop); } return UIP_FW_OK; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(example_abc_process, ev, data) { static struct etimer et; static struct channel *c; PROCESS_BEGIN(); char buffer[32]; //button_sensor.activate(); SENSORS_ACTIVATE(button_sensor); printf("ready to rock\n"); static int i, j, k; //cc2420_init(); //cc2420_set_pan_addr(panId, 0 /*XXX*/, ds2411_id); //cc2420_set_channel(26); //cc2420_set_txpower(31); cc2420_on(); driver = nullmac_init(&cc2420_driver); driver->on(); channel_open(c, 128);channel_set_attributes(128, attributes); packetbuf_clear(); driver->set_receive_function(recv); packetbuf_clear(); //set_receive_function(driver); while(1) { //PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor); for (j = 0; j < 10000; j++) k = j/23; sprintf(buffer, "ping %d, %d\0",i, k); printf("Attempting to send %s\n", buffer); // send the message straight to the radio //cc2420_send ( buffer, (int)strlen(buffer) ); packetbuf_clear(); packetbuf_copyfrom(&buffer, (int)strlen(buffer)); driver->send(); printf("Message sent\n"); leds_toggle(LEDS_RED); i = i + 1; } PROCESS_END(); }
PROCESS_THREAD(proc_epoch_syncer, ev, data) { static struct etimer send_timer; static struct etimer epoch_timer; static const struct broadcast_callbacks broadcast_cbs = {__broadcast_recv_cb, __broadcast_sent_cb}; static struct broadcast_conn conn; PROCESS_EXITHANDLER(broadcast_close(&conn)); PROCESS_BEGIN(); #ifdef TRACK_CONNECTIONS /* Log the node id */ printf("board-id64 0x%.16llx\n", board_get_id64()); #endif #ifdef XFER_CRC16 /* Log the node id */ printf("xfer crc16\n"); #endif printf("epoch interval %ld ticks\n", EPOCH_INTERVAL); /* * Alloc the two syncer events */ evt_epoch_synced = process_alloc_event(); evt_end_of_epoch = process_alloc_event(); /* * Open a `connection` on the syncer broadcasting channel */ broadcast_open(&conn, BROADCAST_CHANNEL_TIMESYNC, &broadcast_cbs); /* * init the epoch-syncer instance */ epoch_syncer_init(&__epoch_syncer); /* * This is the main syncer loop. Initially we try to sync the * epoch between nodes without concurrently running any other * algo. After a period, at which time the network is synced, * we start generating epoch events which can be * consumed by, e.g., the estimator process. */ etimer_set(&epoch_timer, __epoch_syncer.epoch_interval); __epoch_syncer.epoch_start_time = clock_time(); __epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer); while (1) { /* * The start of a new epoch ! */ epoch_syncer_at_epoch_start(&__epoch_syncer); clock_time_t now; clock_time_t time_to_epoch_end; now = clock_time(); assert(__epoch_syncer.epoch_end_time == etimer_expiration_time(&epoch_timer)); assert(__epoch_syncer.epoch_end_time > now); time_to_epoch_end = __epoch_syncer.epoch_end_time - now; /* * Setup a random wait time before sending the sync packet * * ! we cannot let send_timer delay the epoch_timer, especially * when the next `end-of-epoch-time` has been anticipated by a lot * (this can happen at startup) */ if (time_to_epoch_end > __epoch_syncer.epoch_sync_start) { long int send_wait; long int send_wait_rnd; long int rnd; rnd = rand(); send_wait_rnd = (unsigned)rnd % (unsigned) __epoch_syncer.epoch_sync_xfer_interval; send_wait = __epoch_syncer.epoch_sync_start + send_wait_rnd; assert(send_wait >= __epoch_syncer.epoch_sync_start); assert(send_wait <= __epoch_syncer.epoch_sync_start + __epoch_syncer.epoch_sync_xfer_interval); if (send_wait > time_to_epoch_end) send_wait = __epoch_syncer.epoch_sync_start; assert(send_wait < time_to_epoch_end); etimer_set(&send_timer, send_wait); PROCESS_WAIT_UNTIL(etimer_expired(&send_timer)); /* * Acquire the radio lock * * ! we don't use WAIT/YIELD_UNTIL() because * 1) we do not want to yield if we can acquire the lock on the first try * 2) no kernel signal is generated when the lock is released (we would `deadlock') */ do { if (!radio_trylock()) break; PROCESS_PAUSE(); } while (1); { clock_time_t now; struct epoch_sync_packet packet; /* * broadcast the sync packet * * ! We put this part into its own block since non static stack * variables/allocations in the parent block wouldn't get preserved trough * kernel calls (e.g. the PROCESS_PAUSE() a few lines above) */ #ifdef TRACK_CONNECTIONS packet.board_id16 = board_get_id16(); #endif packet.epoch = __epoch_syncer.epoch; now = clock_time(); assert(now > __epoch_syncer.epoch_start_time); assert(__epoch_syncer.epoch_end_time > now); packet.time_from_epoch_start = now - __epoch_syncer.epoch_start_time; packet.time_to_epoch_end = __epoch_syncer.epoch_end_time - now; #ifdef XFER_CRC16 /* * Compute the packet crc with the .crc16 field zeroed */ { uint16_t crc16; packet.crc16 = 0; crc16 = crc16_data((const unsigned char *)&packet, sizeof(struct epoch_sync_packet), 0); packet.crc16 = crc16; } #endif packetbuf_copyfrom(&packet, sizeof(struct epoch_sync_packet)); broadcast_send(&conn); } } else { printf("epoch-syncer: skipping sync send\n"); } /* * We cannot YIELD here: if epoch_timer has already expired there won't be * any event to wake us up. * * FIXME: if we get here and the epoch timer has fired * already print by how much we are late: this can be terribly useful * to trace bugs in the epoch sync code or the kernel. */ if (etimer_expired(&epoch_timer)) { long int now; now = clock_time(); assert(now > __epoch_syncer.epoch_end_time); } else { char do_wait; do_wait = 1; if (__epoch_syncer.sum_sync_offsets) { long int avg_offset = __epoch_syncer.sum_sync_offsets / __epoch_syncer.nr_offsets; const long int threshold = CLOCK_SECOND; if (avg_offset > threshold) { /* * if we are late don't wait until the timer expires * ! this migth give us the opportunity to re-enter the right sync_xfer_interval */ do_wait = 0; } else if (avg_offset < -threshold) { /* * we are too fast, delay end of epoch */ clock_time_t now; clock_time_t time_to_epoch_end; now = clock_time(); assert(__epoch_syncer.epoch_end_time == etimer_expiration_time(&epoch_timer)); assert(__epoch_syncer.epoch_end_time > now); time_to_epoch_end = __epoch_syncer.epoch_end_time - now; long int delay = time_to_epoch_end + (-avg_offset/2); static struct etimer delay_timer; trace("epoch-syncer: delaying end-of-epoch by %ld ticks\n", (-avg_offset/2)); etimer_set(&delay_timer, delay); __epoch_syncer.epoch_end_time += (-avg_offset/2); PROCESS_WAIT_UNTIL(etimer_expired(&delay_timer)); } } if (do_wait) { PROCESS_WAIT_UNTIL(etimer_expired(&epoch_timer)); } else { trace("epoch-syncer: not waiting for end-of-epoch\n"); } } trace("epoch-syncer: epoch %d ended\n", __epoch_syncer.epoch); #ifdef TRACK_CONNECTIONS connection_print_and_zero(CONNECTION_TRACK_SYNC, __epoch_syncer.epoch); #endif /* * Re-Set the end-of-epoch timer */ if (__epoch_syncer.epoch == EPOCHS_UNTIL_SYNCED) { /* * We have hopefully achieved sync at this point * * 1) update the epoch timings, and set the epoch timer * * 2) signal the size-estimator process that the epoch is now synced */ __epoch_syncer.epoch_interval = EPOCH_INTERVAL; __epoch_syncer.epoch_sync_start = EPOCH_SYNC_START; __epoch_syncer.epoch_sync_xfer_interval = EPOCH_SYNC_XFER_INTERVAL; etimer_stop(&epoch_timer); etimer_set(&epoch_timer, __epoch_syncer.epoch_interval); /* * The epoch timer has been re-set: update the time until the next epoch end * Increase the epoch count. * ! these operations must happen in a block which cannot block in kernel calls */ __epoch_syncer.epoch_start_time = clock_time(); __epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer); __epoch_syncer.epoch++; process_post(&proc_size_estimator, evt_epoch_synced, NULL); } else { /* * Re-set and adjust the epoch timer using the data received trough sync packets * (in this epoch) * * ! using re-set (instead of, e.g., restart) is important here in order to avoid * drifting */ etimer_reset(&epoch_timer); /* * The epoch timer has been re-set: update the time until the next epoch end * Increase the epoch count. * ! these operations must happen in a block which cannot block in kernel calls */ //__epoch_syncer.epoch_start_time = epoch_timer.timer.start; __epoch_syncer.epoch_start_time = clock_time(); __epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer); __epoch_syncer.epoch++; if (__epoch_syncer.sum_sync_offsets) { long int avg_offset = __epoch_syncer.sum_sync_offsets / __epoch_syncer.nr_offsets; const long int threshold = 1;//(CLOCK_SECOND/32);//*3; #if __CONTIKI_NETSTACK_RDC==__CONTIKI_NETSTACK_RDC_NULL const int tx_delay = 0; #elif __CONTIKI_NETSTACK_RDC==__CONTIKI_NETSTACK_RDC_CXMAC /* * When the cxmac RDC is used we must consider an added delay due to the fact that when * other nodes radios are turned off the sync packet must be re-sent. */ const int tx_delay = 8; #endif /* * estimate the avg tx delay */ avg_offset += tx_delay; trace("epoch-syncer: sync offsets %d ~ %ld < %ld < %ld\n", __epoch_syncer.nr_offsets, __epoch_syncer.min_offset + tx_delay, avg_offset, __epoch_syncer.max_offset+tx_delay); if ((avg_offset < -threshold) || (avg_offset > threshold)) { clock_time_t new_expiration_time; const long int adjust_threshold = CLOCK_SECOND/2; long int adjust; /* * feedback control the next expiration time */ adjust = -avg_offset/2; adjust = min(adjust, adjust_threshold); adjust = max(adjust, -adjust_threshold); if (adjust) etimer_adjust(&epoch_timer, adjust); new_expiration_time = etimer_expiration_time(&epoch_timer); __epoch_syncer.epoch_end_time = new_expiration_time; } } if (__epoch_syncer.epoch > EPOCHS_UNTIL_SYNCED) { /* * Signal the estimator-process that this epoch has ended */ process_post(&proc_size_estimator, evt_end_of_epoch, NULL); } } } PROCESS_END(); }
static void ieee_mcpspt(MAC_McpsDcfmInd_s *ev) /* packet input and output thread */ { rimeaddr_t rime; switch(ev->u8Type) { case MAC_MCPS_IND_DATA: GDB2_PUTS(","); /* new frame received */ packetbuf_clear(); packetbuf_copyfrom(asdataframe(ev).au8Sdu, asdataframe(ev).u8SduLength); packetbuf_set_datalen(asdataframe(ev).u8SduLength); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, asrimeaddr(&asdataframe(ev).sSrcAddr.uAddr.sExt, &rime)); if(asdataframe(ev).sDstAddr.u8AddrMode==LONG) { /* addressed frame */ packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, asrimeaddr(&asdataframe(ev).sDstAddr.uAddr.sExt, &rime)); } else if(asdataframe(ev).sDstAddr.u8AddrMode==SHORT && asdataframe(ev).sDstAddr.u16PanId==BROADCAST_PANID && asdataframe(ev).sDstAddr.uAddr.u16Short==BROADCAST_ADDR) { /* broadcast frame */ packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_null); } /* update lqi stuff and call lqi callback */ packetbuf_set_attr(PACKETBUF_ATTR_RSSI, asdataframe(ev).u8LinkQuality); if (asdataframe(ev).sSrcAddr.u8AddrMode == LONG && lqicb) lqicb(asrimeaddr(&asdataframe(ev).sSrcAddr.uAddr.sExt, &rime), asdataframe(ev).u8LinkQuality); else if (lqicb) lqicb(NULL, asdataframe(ev).u8LinkQuality); #if USE_TS current_timestamp = asdataframe(ev).timestamp; #endif //{ // static char buf[512]; // uint8_t i; // uint16_t j; // printf("delay:%d len:%d data:", (int32_t) (clock_hrtime()-asdataframe(ev).timestamp), asdataframe(ev).u8SduLength); // for (i=0,j=0; i<asdataframe(ev).u8SduLength; i++) // j+=snprintf(buf+j,sizeof(buf)-j,"0x%x ",asdataframe(ev).au8Sdu[i]); // buf[j]='\n'; // puts(buf); //} /* call upper layer */ NETSTACK_NETWORK.input(); break; case MAC_MCPS_DCFM_DATA: mac_call_sent_callback(mac_cb, mac_cb_ptr, tx_status(&asdataind(ev)), 1); break; case MAC_MCPS_DCFM_PURGE: default: HAL_BREAKPOINT(); break; } }
/*---------------------------------------------------------------------------*/ void slip_packet_input(unsigned char *data, int len) { packetbuf_copyfrom(data, len); NETSTACK_RDC.input(); }