static void recv_mesh(struct mesh_conn *c, const rimeaddr_t *from, uint8_t hops) { struct rime_ping_msg ping; char buf[64]; rtimer_clock_t pingrecvtime; memcpy(&ping, packetbuf_dataptr(), sizeof(struct rime_ping_msg)); if(waiting_for_pong == 0) { #if TIMESYNCH_CONF_ENABLED ping.pongtime = timesynch_time(); #else ping.pongtime = ping.pingtime; #endif memcpy(packetbuf_dataptr(), &ping, sizeof(struct rime_ping_msg)); mesh_send(&mesh, from); } else { #if TIMESYNCH_CONF_ENABLED pingrecvtime = timesynch_time(); #else pingrecvtime = rtimer_arch_now(); #endif snprintf(buf, sizeof(buf), "%lu ms (%lu + %lu), %d hops.", ((pingrecvtime - ping.pingtime) * 1000L) / RTIMER_ARCH_SECOND, ((ping.pongtime - ping.pingtime) * 1000L) / RTIMER_ARCH_SECOND, ((pingrecvtime - ping.pongtime) * 1000L) / RTIMER_ARCH_SECOND, hops); shell_output_str(&rime_ping_command, "Pong recived; rtt ", buf); waiting_for_pong = 0; process_post(&shell_rime_ping_process, PROCESS_EVENT_CONTINUE, NULL); } }
/*---------------------------------------------------------------------------*/ static void recv(const linkaddr_t *originator, uint8_t seqno, uint8_t hops) { struct sky_collect_msg *msg; msg = packetbuf_dataptr(); printf("%u %u %u %u %u %u %u %u %u %u %u %lu %lu %lu %lu %lu ", (originator->u8[1] << 8) + originator->u8[0], seqno, hops, msg->light1, msg->light2, msg->temperature, msg->humidity, msg->rssi, (msg->best_neighbor.u8[0] << 8) + msg->best_neighbor.u8[1], msg->best_neighbor_etx, msg->best_neighbor_rtmetric, msg->energy_lpm, msg->energy_cpu, msg->energy_rx, msg->energy_tx, msg->energy_rled ); printf("%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u ", msg->tx, msg->rx, msg->reliabletx, msg->reliablerx, msg->rexmit, msg->acktx, msg->noacktx, msg->ackrx, msg->timedout, msg->badackrx, msg->toolong, msg->tooshort, msg->badsynch, msg->badcrc, msg->contentiondrop, msg->sendingdrop, msg->lltx, msg->llrx); #if TIMESYNCH_CONF_ENABLED printf("%u", timesynch_time() - msg->timestamp); #else printf("%u", RTIMER_NOW() - msg->timestamp); #endif /* TIMESYNCH_CONF_ENABLED */ printf("\n"); }
static void recv_ruc(struct runicast_conn *c, const rimeaddr_t *from, uint8_t seqno) { struct collect_msg *msg; rtimer_clock_t latency; #if TIMESYNCH_CONF_ENABLED rtimer_clock_t timestamp; #endif /* TIMESYNCH_CONF_ENABLED */ msg = packetbuf_dataptr(); #if TIMESYNCH_CONF_ENABLED memcpy(×tamp, &msg->timestamp, sizeof(timestamp)); latency = timesynch_time() - timestamp; #else latency = 0; #endif printf("runicast message received from %d.%d, latency %lu ms, seqno %d, data '%.*s'\n", from->u8[0], from->u8[1], (latency * 1000L) / RTIMER_ARCH_SECOND, seqno, packetbuf_datalen() - COLLECT_MSG_HDRSIZE, msg->data); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_sense_process, ev, data) { struct sense_msg msg; PROCESS_BEGIN(); SENSORS_ACTIVATE(light_sensor); SENSORS_ACTIVATE(battery_sensor); SENSORS_ACTIVATE(sht11_sensor); msg.len = 7; msg.clock = clock_time(); #if TIMESYNCH_CONF_ENABLED msg.timesynch_time = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ msg.timesynch_time = 0; #endif /* TIMESYNCH_CONF_ENABLED */ msg.light1 = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); msg.light2 = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); msg.temp = sht11_sensor.value(SHT11_SENSOR_TEMP); msg.humidity = sht11_sensor.value(SHT11_SENSOR_HUMIDITY); msg.rssi = do_rssi(); msg.voltage = battery_sensor.value(0); msg.rssi = do_rssi(); SENSORS_DEACTIVATE(light_sensor); SENSORS_DEACTIVATE(battery_sensor); SENSORS_DEACTIVATE(sht11_sensor); shell_output(&sense_command, &msg, sizeof(msg), "", 0); PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_broadcast_process, ev, data) { struct shell_input *input; int len; struct collect_msg *msg; PROCESS_BEGIN(); while(1) { PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input); input = data; len = input->len1 + input->len2; if(len == 0) { PROCESS_EXIT(); } if(len < PACKETBUF_SIZE) { packetbuf_clear(); packetbuf_set_datalen(len + COLLECT_MSG_HDRSIZE); msg = packetbuf_dataptr(); memcpy(msg->data, input->data1, input->len1); memcpy(msg->data + input->len1, input->data2, input->len2); #if TIMESYNCH_CONF_ENABLED msg->timestamp = timesynch_time(); #else msg->timestamp = 0; #endif /* printf("Sending %d bytes\n", len);*/ broadcast_send(&broadcast); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ static int construct_reply(const rimeaddr_t *from) { struct datapath_msg *msg = packetbuf_dataptr(); #if TIMESYNCH_CONF_ENABLED rtimer_clock_t now = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ rtimer_clock_t now = 0; #endif /* TIMESYNCH_CONF_ENABLED */ memcpy_misaligned(&msg->rx, &now, sizeof(rtimer_clock_t)); switch(msg->datapath_command) { case DATAPATH_COMMAND_ECHO_REQUEST: msg->datapath_command = DATAPATH_COMMAND_ECHO_REPLY; break; case DATAPATH_COMMAND_STREAM_ECHO_REQUEST: msg->datapath_command = DATAPATH_COMMAND_ECHO_REPLY; packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM); break; } if(msg->datapath_command == DATAPATH_COMMAND_ECHO_REPLY) { packetbuf_set_datalen(sizeof(struct datapath_msg)); msg->received = stats.received; stats.sent++; return 1; } return 0; }
/*---------------------------------------------------------------------------*/ void collect_view_construct_message(struct collect_view_data_msg *msg, const linkaddr_t *parent, uint16_t parent_etx, uint16_t current_rtmetric, uint16_t num_neighbors, uint16_t beacon_interval) { static unsigned long last_cpu, last_lpm, last_transmit, last_listen; unsigned long cpu, lpm, transmit, listen; msg->len = sizeof(struct collect_view_data_msg) / sizeof(uint16_t); msg->clock = clock_time(); #if TIMESYNCH_CONF_ENABLED msg->timesynch_time = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ msg->timesynch_time = 0; #endif /* TIMESYNCH_CONF_ENABLED */ energest_flush(); cpu = energest_type_time(ENERGEST_TYPE_CPU) - last_cpu; lpm = energest_type_time(ENERGEST_TYPE_LPM) - last_lpm; transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT) - last_transmit; listen = energest_type_time(ENERGEST_TYPE_LISTEN) - last_listen; /* Make sure that the values are within 16 bits. If they are larger, we scale them down to fit into 16 bits. */ while(cpu >= 65536ul || lpm >= 65536ul || transmit >= 65536ul || listen >= 65536ul) { cpu /= 2; lpm /= 2; transmit /= 2; listen /= 2; } msg->cpu = cpu; msg->lpm = lpm; msg->transmit = transmit; msg->listen = listen; last_cpu = energest_type_time(ENERGEST_TYPE_CPU); last_lpm = energest_type_time(ENERGEST_TYPE_LPM); last_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT); last_listen = energest_type_time(ENERGEST_TYPE_LISTEN); memcpy(&msg->parent, &parent->u8[LINKADDR_SIZE - 2], 2); msg->parent_etx = parent_etx; msg->current_rtmetric = current_rtmetric; msg->num_neighbors = num_neighbors; msg->beacon_interval = beacon_interval; memset(msg->sensors, 0, sizeof(msg->sensors)); collect_view_arch_read_sensors(msg); }
/*---------------------------------------------------------------------------*/ static void send_collect(void *dummy) { struct collect_msg msg; #if TIMESYNCH_CONF_ENABLED msg.timestamp = timesynch_time(); #else msg.timestamp = 0; #endif packetbuf_copyfrom(&msg, COLLECT_MSG_HDRSIZE); collect_send(&collect, COLLECT_REXMITS); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_unicast_send_process, ev, data) { struct shell_input *input; static linkaddr_t receiver; int len; const char *nextptr; struct unicast_msg *msg; PROCESS_BEGIN(); receiver.u8[0] = shell_strtolong(data, &nextptr); if(nextptr == data || *nextptr != '.') { shell_output_str(&unicast_send_command, "unicast <receiver>: recevier must be specified", ""); PROCESS_EXIT(); } ++nextptr; receiver.u8[1] = shell_strtolong(nextptr, &nextptr); /* snprintf(buf, sizeof(buf), "%d.%d", receiver.u8[0], receiver.u8[1]); shell_output_str(&unicast_send_command, "Sending unicast packets to ", buf);*/ while(1) { PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input); input = data; len = input->len1 + input->len2; if(len == 0) { PROCESS_EXIT(); } if(len < MAX_DATALEN) { packetbuf_clear(); packetbuf_set_datalen(len + UNICAST_MSG_HDRSIZE); msg = packetbuf_dataptr(); memcpy(msg->data, input->data1, input->len1); memcpy(msg->data + input->len1, input->data2, input->len2); #if TIMESYNCH_CONF_ENABLED msg->timestamp = timesynch_time(); #else msg->timestamp = 0; #endif /* printf("Sending %d bytes\n", len);*/ unicast_send(&uc, &receiver); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ static void recv_collect(const rimeaddr_t *originator, u8_t seqno, u8_t hops) { struct collect_msg *collect_msg; rtimer_clock_t latency; int len; collect_msg = packetbuf_dataptr(); #if TIMESYNCH_CONF_ENABLED latency = timesynch_time() - collect_msg->timestamp; #else latency = 0; #endif if(waiting_for_collect) { struct { uint16_t len; uint16_t originator; uint16_t seqno; uint16_t hops; uint16_t latency; } msg; if(packetbuf_datalen() >= COLLECT_MSG_HDRSIZE) { len = packetbuf_datalen() - COLLECT_MSG_HDRSIZE; if(collect_msg->crc == crc16_data(collect_msg->data, len, 0)) { msg.len = 5 + (packetbuf_datalen() - COLLECT_MSG_HDRSIZE) / 2; rimeaddr_copy((rimeaddr_t *)&msg.originator, originator); msg.seqno = seqno; msg.hops = hops; msg.latency = latency; /* printf("recv_collect datalen %d\n", packetbuf_datalen());*/ shell_output(&collect_command, &msg, sizeof(msg), collect_msg->data, packetbuf_datalen() - COLLECT_MSG_HDRSIZE); } } } else if(waiting_for_nodes) { char buf[40]; snprintf(buf, sizeof(buf), "%d.%d, %d hops, latency %lu ms", originator->u8[0], originator->u8[1], hops, (1000L * latency) / RTIMER_ARCH_SECOND); shell_output_str(&nodes_command, "Message from node ", buf); messages_received++; } }
/* * Interrupt leaves frame intact in FIFO. */ static volatile rtimer_clock_t interrupt_time; static volatile int interrupt_time_set; #if CC2420_TIMETABLE_PROFILING #define cc2420_timetable_size 16 TIMETABLE(cc2420_timetable); TIMETABLE_AGGREGATE(aggregate_time, 10); #endif /* CC2420_TIMETABLE_PROFILING */ int cc2420_interrupt(void) { interrupt_time = timesynch_time(); interrupt_time_set = 1; CLEAR_FIFOP_INT(); process_poll(&cc2420_process); #if CC2420_TIMETABLE_PROFILING timetable_clear(&cc2420_timetable); TIMETABLE_TIMESTAMP(cc2420_timetable, "interrupt"); #endif /* CC2420_TIMETABLE_PROFILING */ return 1; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_rime_ping_process, ev, data) { static int i; static struct etimer timeout, periodic; static rimeaddr_t receiver; struct rime_ping_msg *ping; const char *nextptr; char buf[32]; PROCESS_BEGIN(); receiver.u8[0] = shell_strtolong(data, &nextptr); if(nextptr == data || *nextptr != '.') { shell_output_str(&rime_ping_command, "ping <receiver>: recevier must be specified", ""); PROCESS_EXIT(); } ++nextptr; receiver.u8[1] = shell_strtolong(nextptr, &nextptr); snprintf(buf, sizeof(buf), "%d.%d", receiver.u8[0], receiver.u8[1]); shell_output_str(&rime_ping_command, "Sending 4 pings to ", buf); for(i = 0; i < 4; ++i) { packetbuf_clear(); ping = packetbuf_dataptr(); packetbuf_set_datalen(sizeof(struct rime_ping_msg)); #if TIMESYNCH_CONF_ENABLED ping->pingtime = timesynch_time(); #else ping->pingtime = rtimer_arch_now(); #endif mesh_send(&mesh, &receiver); etimer_set(&timeout, CLOCK_SECOND * 8); etimer_set(&periodic, CLOCK_SECOND * 1); waiting_for_pong = 1; PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timeout) || waiting_for_pong == 0); if(waiting_for_pong == 0) { PROCESS_WAIT_UNTIL(etimer_expired(&periodic)); } else { shell_output_str(&rime_ping_command, "Timed out", ""); } waiting_for_pong = 0; } PROCESS_END(); }
void nrf24l01_interrupt(void) { #if RF230_CONF_TIMESTAMPS interrupt_time = timesynch_time(); interrupt_time_set = 1; #endif /* RF230_CONF_TIMESTAMPS */ isr_event_write.isr_type= ISR_RX_DR; process_poll(&nrf24l01_process); #if RF230_TIMETABLE_PROFILING timetable_clear(&rf230_timetable); TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt"); #endif /* RF230_TIMETABLE_PROFILING */ return; }
nRF24L01_ISR() { #if RF230_CONF_TIMESTAMPS interrupt_time = timesynch_time(); interrupt_time_set = 1; #endif /* RF230_CONF_TIMESTAMPS */ volatile uint8_t status; status = spi_register_read(NOP); //PRINTF("ISR: status=0x%x\r\n", status); //Rx FIFO data ready if(status & (1 << MASK_RX_DR)) { uint8_t rx_pipe_no = (status & 0x07); if(rx_pipe_no < 6) { status_rx_dr_handler(rx_pipe_no); } sbi(status, MASK_RX_DR); } //Tx FIFO data has been sent successfully else if(status & (1 << MASK_TX_DS)) { status_tx_ds_handler(); sbi(status, MASK_TX_DS); //clear intertupt } //Re transmit is up to the max counter, //Note: // 1. If you don't clear this interrupt, no data can be transmitted any more // 2. The package lost counter(PLOS_CNT) is incremented at each MAX_RT interrupt else if(status & (1 << MASK_MAX_RT)) { status_max_rt_handler(); sbi(status, MASK_MAX_RT); //clear the interrupt } else {} //clean interrupts SPI_WRITE_REG(WRITE_REG+STATUS, status); #if RF230_TIMETABLE_PROFILING timetable_clear(&rf230_timetable); TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt"); #endif /* RF230_TIMETABLE_PROFILING */ }
/*---------------------------------------------------------------------------*/ static void process_incoming_packet(void) { struct datapath_msg *msg = packetbuf_dataptr(); rtimer_clock_t now; struct datapath_msg msg_copy; #if TIMESYNCH_CONF_ENABLED now = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ now = 0; #endif /* TIMESYNCH_CONF_ENABLED */ memcpy_misaligned(&msg_copy, (uint8_t *)msg, sizeof(msg_copy)); stats.received++; stats.total_tx_latency += msg_copy.rx - msg_copy.tx; stats.total_rx_latency += now - msg_copy.rx; }
static void recv_uc(struct unicast_conn *c, const rimeaddr_t *from) { struct collect_msg *msg; rtimer_clock_t latency; msg = packetbuf_dataptr(); #if TIMESYNCH_CONF_ENABLED latency = timesynch_time() - msg->timestamp; #else latency = 0; #endif printf("unicast message received from %d.%d, latency %lu ms, data '%.*s'\n", from->u8[0], from->u8[1], (1000L * latency) / RTIMER_ARCH_SECOND, packetbuf_datalen() - COLLECT_MSG_HDRSIZE, msg->data); }
/*---------------------------------------------------------------------------*/ static int construct_next_packet(void) { struct datapath_msg *msg; packetbuf_clear(); if(left_to_send > 0) { packetbuf_set_datalen(DATALEN); msg = packetbuf_dataptr(); msg->datapath_command = DATAPATH_COMMAND_NONE; msg->received = 0; #if TIMESYNCH_CONF_ENABLED msg->tx = msg->rx = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ msg->tx = msg->rx = 0; #endif /* TIMESYNCH_CONF_ENABLED */ rimeaddr_copy(&msg->receiver, &receiver); left_to_send--; return 1; } return 0; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_time_process, ev, data) { struct { uint16_t len; uint16_t clock; uint16_t rtimer; uint16_t timesynch; uint16_t timesynch_authority; uint16_t time[2]; } msg; unsigned long newtime; const char *nextptr; PROCESS_BEGIN(); if(data != NULL) { newtime = shell_strtolong(data, &nextptr); if(data != nextptr) { shell_set_time(newtime); } } msg.clock = (uint16_t)clock_time(); msg.rtimer = (uint16_t)RTIMER_NOW(); #if TIMESYNCH_CONF_ENABLED msg.timesynch = timesynch_time(); msg.timesynch_authority = timesynch_authority_level(); #else msg.timesynch = 0; msg.timesynch_authority = -1; #endif msg.time[0] = (uint16_t)(shell_time() >> 16); msg.time[1] = (uint16_t)(shell_time()); msg.len = 6; shell_output(&time_command, &msg, sizeof(msg), "", 0); PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_timestamp_process, ev, data) { struct shell_input *input; struct msg { uint16_t len; uint16_t time[2]; uint16_t timesynch; uint8_t data[MAX_COMMANDLENGTH]; } msg; PROCESS_BEGIN(); while(1) { PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input); input = data; if(input->len1 + input->len2 == 0) { PROCESS_EXIT(); } msg.len = 3 + *(uint16_t *)input->data1; msg.time[0] = (uint16_t)(shell_time() >> 16); msg.time[1] = (uint16_t)(shell_time()); #if TIMESYNCH_CONF_ENABLED msg.timesynch = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ msg.timesynch = 0; #endif /* TIMESYNCH_CONF_ENABLED */ memcpy(msg.data, input->data1 + 2, input->len1 - 2 > MAX_COMMANDLENGTH? MAX_COMMANDLENGTH: input->len1 - 2); shell_output(×tamp_command, &msg, 6 + input->len1, input->data2, input->len2); } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ static void recv_uc(struct unicast_conn *c, const linkaddr_t *from) { struct unicast_msg *msg; #define OUTPUT_BLOB_HDRSIZE 6 struct { uint16_t len; uint16_t from; uint16_t latency; uint16_t data[MAX_DATALEN]; } output_blob; if(is_receiving == 0) { return; } msg = packetbuf_dataptr(); #if TIMESYNCH_CONF_ENABLED output_blob.latency = timesynch_time() - msg->timestamp; #else output_blob.latency = 0; #endif linkaddr_copy((linkaddr_t *)&output_blob.from, from); memcpy(output_blob.data, msg->data, packetbuf_datalen() - UNICAST_MSG_HDRSIZE); output_blob.len = 2 + (packetbuf_datalen() - UNICAST_MSG_HDRSIZE) / 2; shell_output(&unicast_recv_command, &output_blob, OUTPUT_BLOB_HDRSIZE + (packetbuf_datalen() - UNICAST_MSG_HDRSIZE), NULL, 0); /* printf("unicast message received from %d.%d, latency %lu ms, data '%.*s'\n", from->u8[0], from->u8[1], (1000L * latency) / RTIMER_ARCH_SECOND, packetbuf_datalen() - UNICAST_MSG_HDRSIZE, msg->data);*/ }
/*---------------------------------------------------------------------------*/ int nrf24l01_send(const void *payload, unsigned short payload_len) { uint8_t total_len,buffer[RF230_MAX_TX_FRAME_LENGTH],*pbuf; uint8_t tx_result = RADIO_TX_ERR; #if RF230_CONF_TIMESTAMPS struct timestamp timestamp; #endif /* RF230_CONF_TIMESTAMPS */ #if RF230_CONF_CHECKSUM uint16_t checksum; #endif /* RF230_CONF_CHECKSUM */ #if RADIOSTATS RF230_sendpackets++; #endif GET_LOCK(); RIMESTATS_ADD(lltx); #if RF230_CONF_CHECKSUM checksum = crc16_data(payload, payload_len, 0); #endif /* RF230_CONF_CHECKSUM */ total_len = payload_len + AUX_LEN; /*Check function parameters and current state.*/ if (total_len > RF230_MAX_TX_FRAME_LENGTH){ #if RADIOSTATS RF230_sendfail++; #endif return -1; } pbuf=&buffer[0]; memcpy(pbuf,payload,payload_len); pbuf+=payload_len; #if RF230_CONF_CHECKSUM memcpy(pbuf,&checksum,CHECKSUM_LEN); pbuf+=CHECKSUM_LEN; #endif /* RF230_CONF_CHECKSUM */ #if RF230_CONF_TIMESTAMPS timestamp.authority_level = timesynch_authority_level(); timestamp.time = timesynch_time(); memcpy(pbuf,×tamp,TIMESTAMP_LEN); pbuf+=TIMESTAMP_LEN; #endif /* RF230_CONF_TIMESTAMPS */ /* If radio is sleeping we have to turn it on first */ // /* if need radio calibrate, do it here */ // /* Wait for any previous transmission to finish. */ //nrf24l01_waitidle(); BUSYWAIT_UNTIL(nrf24l01_status(), RTIMER_SECOND / 100); /* set tx mode */ // /* set some features here like auto ack */ // /* get the current power and save, then adjust the power to send */ // if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { nrf24l01_set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } else { nrf24l01_set_txpower(TX_PWR_18DBM); //-18dbm } /* Now start transmitting... */ PRINTF("nrf24l01: sending %d bytes\n", payload_len); //send these data SPI_WRITE_BUF(WR_TX_PLOAD, buffer, total_len); if(1) { #if RF230_CONF_TIMESTAMPS rtimer_clock_t txtime = timesynch_time(); #endif /* RF230_CONF_TIMESTAMPS */ if(rf_radio_on) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); } ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ //nrf24l01_waitidle(); //radio_set_trx_state(RX_AACK_ON);//Re-enable receive mode BUSYWAIT_UNTIL(isr_event_write.isr_type, RTIMER_SECOND / 100); if(ISR_TX_DS == isr_event_write.isr_type) { tx_result = RADIO_TX_OK; } /*else if(ISR_MAX_RT == state) { tx_result = RADIO_TX_NOACK; }*/ else { tx_result = RADIO_TX_NOACK; } #if RF230_CONF_TIMESTAMPS setup_time_for_transmission = txtime - timestamp.time; if(num_transmissions < 10000) { total_time_for_transmission += timesynch_time() - txtime; total_transmission_len += total_len; num_transmissions++; } #endif /* RF230_CONF_TIMESTAMPS */ #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,rf230_get_txpower()); #endif ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); if(rf_radio_on) { ENERGEST_ON(ENERGEST_TYPE_LISTEN); } RELEASE_LOCK(); return tx_result; } }
/* * this function produce a string @buf in form of json data * example of buf: * * {'clk':%d,'syn':%d,'cpu':%d,'lpm':%d,'tras':%d,'lst':%d, * 'parent':%s,'etx':%d,'rt':%d,\'nbr':%d,'bea_itv':%d,'sen':%d} * */ void collectd_prepare_data() { uint16_t parent_etx; uint16_t rtmetric; uint16_t num_neighbors; uint16_t beacon_interval; rpl_parent_t *preferred_parent; uip_lladdr_t lladdr_parent; rpl_dag_t *dag; //copied from collect-view.c static unsigned long last_cpu, last_lpm, last_transmit, last_listen; unsigned long cpu, lpm, transmit, listen; u16_t clock, timesynch_time; clock = clock_time(); #if TIMESYNCH_CONF_ENABLED timesynch_time = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ timesynch_time = 0; #endif /* TIMESYNCH_CONF_ENABLED */ /*save to buf */ blen = 0; ADD("{'clk':%u,'syn':%u,", clock, timesynch_time); energest_flush(); cpu = energest_type_time(ENERGEST_TYPE_CPU) - last_cpu; lpm = energest_type_time(ENERGEST_TYPE_LPM) - last_lpm; transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT) - last_transmit; listen = energest_type_time(ENERGEST_TYPE_LISTEN) - last_listen; /* Make sure that the values are within 16 bits. If they are larger, we scale them down to fit into 16 bits. */ //TODO: why do i need to scale down to 16 bit? while(cpu >= 65536ul || lpm >= 65536ul || transmit >= 65536ul || listen >= 65536ul) { cpu /= 2; lpm /= 2; transmit /= 2; listen /= 2; } /* prepare for next calling */ last_cpu = energest_type_time(ENERGEST_TYPE_CPU); last_lpm = energest_type_time(ENERGEST_TYPE_LPM); last_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT); last_listen = energest_type_time(ENERGEST_TYPE_LISTEN); /* save to buf */ ADD("'cpu':%u,'lpm':%u,'tras':%u,'lst':%u,", (u16_t)cpu, (u16_t)lpm, (u16_t)transmit, (u16_t)listen); /* initial value, if there's not any dag */ parent_etx = 0; rtmetric = 0; beacon_interval = 0; num_neighbors = 0; /* Let's suppose we have only one instance */ dag = rpl_get_any_dag(); if(dag != NULL) { preferred_parent = dag->preferred_parent; if(preferred_parent != NULL) { uip_ds6_nbr_t *nbr; nbr = uip_ds6_nbr_lookup(&preferred_parent->addr); if(nbr != NULL) { //PRINT6ADDR(&nbr->lladdr); memcpy(&lladdr_parent, &nbr->lladdr, sizeof(uip_lladdr_t)); parent_etx = neighbor_info_get_metric((rimeaddr_t *) &nbr->lladdr) / 2; } } rtmetric = dag->rank; beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000); num_neighbors = RPL_PARENT_COUNT(dag); } char lladdr_parent_str[30]; u8_t lladdr_str_len; lladdr_str_len = lladdr_print(&lladdr_parent, lladdr_parent_str, 30); ADD("'parent':'%s',", lladdr_parent_str); ADD("'etx':%u,'rt':%u,'nbr':%u,'bea_itv':%u,", parent_etx, rtmetric, num_neighbors, beacon_interval); //collectd_arch_read_sensors(); #if CONTIKI_TARGET_SKY u8_t sensors[MAX_SENSORS_BUF_SIZE]; //PRINTF("oh,sky\n"); if (collect_view_arch_read_sensors(sensors, MAX_SENSORS_BUF_SIZE) >= 0) { ADD("'sen':'%s',", sensors); } #endif ADD("}"); }
/*---------------------------------------------------------------------------*/ int cc2420_send(const void *payload, unsigned short payload_len) { int i; uint8_t total_len; struct timestamp timestamp; uint16_t checksum; GET_LOCK(); PRINTF("cc2420: sending %d bytes\n", payload_len); RIMESTATS_ADD(lltx); /* Wait for any previous transmission to finish. */ while(status() & BV(CC2420_TX_ACTIVE)); /* Write packet to TX FIFO. */ strobe(CC2420_SFLUSHTX); checksum = crc16_data(payload, payload_len, 0); total_len = payload_len + AUX_LEN; FASTSPI_WRITE_FIFO(&total_len, 1); FASTSPI_WRITE_FIFO(payload, payload_len); FASTSPI_WRITE_FIFO(&checksum, CHECKSUM_LEN); #if CC2420_CONF_TIMESTAMPS timestamp.authority_level = timesynch_authority_level(); timestamp.time = timesynch_time(); FASTSPI_WRITE_FIFO(×tamp, TIMESTAMP_LEN); #endif /* CC2420_CONF_TIMESTAMPS */ /* The TX FIFO can only hold one packet. Make sure to not overrun * FIFO by waiting for transmission to start here and synchronizing * with the CC2420_TX_ACTIVE check in cc2420_send. * * Note that we may have to wait up to 320 us (20 symbols) before * transmission starts. */ #ifdef TMOTE_SKY #define LOOP_20_SYMBOLS 100 /* 326us (msp430 @ 2.4576MHz) */ #elif __AVR__ #define LOOP_20_SYMBOLS 500 /* XXX */ #endif #if WITH_SEND_CCA strobe(CC2420_SRXON); while(!(status() & BV(CC2420_RSSI_VALID))); strobe(CC2420_STXONCCA); #else /* WITH_SEND_CCA */ strobe(CC2420_STXON); #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(SFD_IS_1) { #if CC2420_CONF_TIMESTAMPS rtimer_clock_t txtime = timesynch_time(); #endif /* CC2420_CONF_TIMESTAMPS */ if(receive_on) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); } ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ while(status() & BV(CC2420_TX_ACTIVE)); #if CC2420_CONF_TIMESTAMPS setup_time_for_transmission = txtime - timestamp.time; if(num_transmissions < 10000) { total_time_for_transmission += timesynch_time() - txtime; total_transmission_len += total_len; num_transmissions++; } #endif /* CC2420_CONF_TIMESTAMPS */ #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower()); #endif ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); if(receive_on) { ENERGEST_ON(ENERGEST_TYPE_LISTEN); } RELEASE_LOCK(); return 0; } } /* If we are using WITH_SEND_CCA, we get here if the packet wasn't transmitted because of other channel activity. */ RIMESTATS_ADD(contentiondrop); PRINTF("cc2420: do_send() transmission never started\n"); RELEASE_LOCK(); return -3; /* Transmission never started! */ }