/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_txpower_process, ev, data) { struct { uint16_t len; uint16_t txpower; } msg; const char *newptr; PROCESS_BEGIN(); msg.txpower = shell_strtolong(data, &newptr); /* If no transmission power was given on the command line, we print out the current txpower. */ if(newptr == data) { msg.txpower = cc2420_get_txpower(); } else { cc2420_set_txpower(msg.txpower); } msg.len = 1; shell_output(&txpower_command, &msg, sizeof(msg), "", 0); PROCESS_END(); }
/*-----------------------------------------------------------*/ void set_ETX_th(void) { int tx= cc2420_get_txpower(); if(tx==3 || tx==7) {ETX_THERESHOLD=8*RPL_DAG_MC_ETX_DIVISOR;} else if(tx>10)// && tx<20) {ETX_THERESHOLD = 2 *RPL_DAG_MC_ETX_DIVISOR;} //else if(tx>20 && tx<32) //{ETX_THERESHOLD = 1.5;} printf("set ETX_th=%d\n",ETX_THERESHOLD); }
PROCESS_THREAD(simple_process, ev, data) { PROCESS_BEGIN(); cc2420_set_txpower(12); init_router(&message_received); static struct ctimer ct; ctimer_set(&ct, CLOCK_SECOND * 60 * 5, send_message_after_5_minutes, NULL); process_start(&neighbor_discovery_process, NULL); printf("K = %d, MAX_NODES = %d, MAX_EDGES = %d, LINKADDR = %d.%d\n", (int) K, (int) MAX_NODES, (int) MAX_EDGES, linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); printf("NODE_MEM = %dB, EDGE_MEM = %dB\n", (int)(sizeof(p_node_t) * MAX_NODES), (int)(sizeof(p_edge_t) * MAX_EDGES)); printf("PACKETBUF_SIZE = %d, TXPOWER = %d, INTERVAL = %d - %d\n", PACKETBUF_SIZE, cc2420_get_txpower(), DISCOVERY_INTERVAL_MIN, DISCOVERY_INTERVAL_MAX); PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(udp_client_process, ev, data) { static struct etimer periodic; static struct ctimer backoff_timer; #if WITH_COMPOWER static int print = 0; #endif PROCESS_BEGIN(); powertrace_start(CLOCK_SECOND * 30); //elnaz cc2420_set_txpower(31); printf(" Tx=%d\n", cc2420_get_txpower()); PROCESS_PAUSE(); set_global_address(); PRINTF("UDP client process started\n"); print_local_addresses(); /* new connection with remote host */ client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL); if(client_conn == NULL) { PRINTF("No UDP connection available, exiting the process!\n"); PROCESS_EXIT(); } udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT)); PRINTF("Created a connection with the server "); PRINT6ADDR(&client_conn->ripaddr); PRINTF(" local/remote port %u/%u\n", UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); #if WITH_COMPOWER powertrace_sniff(POWERTRACE_ON); #endif etimer_set(&periodic, SEND_INTERVAL); while(1) { PROCESS_YIELD(); if(ev == tcpip_event) { tcpip_handler(); } if(etimer_expired(&periodic)) { etimer_reset(&periodic); ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL); #if WITH_COMPOWER if (print == 0) { powertrace_print("#P"); } if (++print == 3) { print = 0; } #endif } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(udp_client_process, ev, data) { static struct etimer periodic; static struct ctimer backoff_timer; //static struct etimer wait; //static int tx[] = { 31, 27, 23, 19, 15, 11, 7, 3}; #if WITH_COMPOWER static int print = 0; #endif PROCESS_BEGIN(); powertrace_start(CLOCK_SECOND * 1); //elnaz cc2420_set_txpower(23); printf(" Probe v\n Tx=%d\n", cc2420_get_txpower()); PROCESS_PAUSE(); set_global_address(); PRINTF("UDP client process started\n"); print_local_addresses(); /* new connection with remote host */ client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL); if(client_conn == NULL) { PRINTF("No UDP connection available, exiting the process!\n"); PROCESS_EXIT(); } udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT)); PRINTF("Created a connection with the server "); PRINT6ADDR(&client_conn->ripaddr); PRINTF(" local/remote port %u/%u\n", UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); #if WITH_COMPOWER powertrace_sniff(POWERTRACE_ON); #endif // etimer_set(&temp, 60*CLOCK_SECOND); // PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); etimer_set(&periodic, SEND_INTERVAL); while(1)//seq<150) { PROCESS_YIELD(); if(ev == tcpip_event) { tcpip_handler(); } if(etimer_expired(&periodic)) { etimer_reset(&periodic); ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL); } //end etimer_expired } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ static int cc2420_transmit(unsigned short payload_len) { int i, txpower; uint8_t total_len; #if CC2420_CONF_CHECKSUM uint16_t checksum; #endif /* CC2420_CONF_CHECKSUM */ GET_LOCK(); txpower = 0; if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Remember the current transmission power */ txpower = cc2420_get_txpower(); /* Set the specified transmission power */ set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } total_len = payload_len + AUX_LEN; /* 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. */ #ifndef CC2420_CONF_SYMBOL_LOOP_COUNT #error CC2420_CONF_SYMBOL_LOOP_COUNT needs to be set!!! #else #define LOOP_20_SYMBOLS CC2420_CONF_SYMBOL_LOOP_COUNT #endif #if WITH_SEND_CCA strobe(CC2420_SRXON); BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 10); strobe(CC2420_STXONCCA); #else /* WITH_SEND_CCA */ strobe(CC2420_STXON); #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(CC2420_SFD_IS_1) { { rtimer_clock_t sfd_timestamp; sfd_timestamp = cc2420_sfd_start_time; if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) { /* Write timestamp to last two bytes of packet in TXFIFO. */ CC2420_WRITE_RAM(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2); } } if(!(status() & BV(CC2420_TX_ACTIVE))) { /* SFD went high but we are not transmitting. This means that we just started receiving a packet, so we drop the transmission. */ RELEASE_LOCK(); return RADIO_TX_COLLISION; } 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.*/ BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10); #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); } else { /* We need to explicitly turn off the radio, * since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */ off(); } if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_OK; } } /* 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"); if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_COLLISION; }
/*---------------------------------------------------------------------------*/ 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! */ }
/*---------------------------------------------------------------------------*/ static int cc2420_transmit(unsigned short payload_len) { int i, txpower; uint8_t total_len; #if CC2420_CONF_CHECKSUM uint16_t checksum; #endif /* CC2420_CONF_CHECKSUM */ GET_LOCK(); txpower = 0; if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Remember the current transmission power */ txpower = cc2420_get_txpower(); /* Set the specified transmission power */ set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } total_len = payload_len + AUX_LEN; /* 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 400 /* 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(!(status() & BV(CC2420_TX_ACTIVE))) { /* SFD went high but we are not transmitting. This means that we just started receiving a packet, so we drop the transmission. */ return RADIO_TX_ERR; } 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)); #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); } else { /* We need to explicitly turn off the radio, * since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */ off(); } if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_OK; } } /* 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"); if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_ERR; /* Transmission never started! */ }
static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) { if (netdev == NULL) { return -ENODEV; } cc2420_t *dev = (cc2420_t *)netdev; int ext = netdev_ieee802154_get(&dev->netdev, opt, val, max_len); if (ext > 0) { return ext; } switch (opt) { case NETOPT_ADDRESS: assert(max_len >= sizeof(uint16_t)); cc2420_get_addr_short(dev, val); return sizeof(uint16_t); case NETOPT_ADDRESS_LONG: assert(max_len >= 8); cc2420_get_addr_long(dev, val); return 8; case NETOPT_NID: assert(max_len >= sizeof(uint16_t)); return w_u16(val, cc2420_get_pan(dev)); case NETOPT_CHANNEL: assert(max_len >= sizeof(uint16_t)); return w_u16(val, cc2420_get_chan(dev)); case NETOPT_TX_POWER: assert(max_len >= sizeof(int16_t)); return w_i16(val, cc2420_get_txpower(dev)); case NETOPT_STATE: assert(max_len >= sizeof(netopt_state_t)); *((netopt_state_t *)val) = cc2420_get_state(dev); return sizeof(netopt_state_t); case NETOPT_IS_CHANNEL_CLR: return opt_state(val, cc2420_cca(dev)); case NETOPT_AUTOACK: return opt_state(val, (dev->options & CC2420_OPT_AUTOACK)); case NETOPT_CSMA: return opt_state(val, (dev->options & CC2420_OPT_CSMA)); case NETOPT_PRELOADING: return opt_state(val, (dev->options & CC2420_OPT_PRELOADING)); case NETOPT_PROMISCUOUSMODE: return opt_state(val, (dev->options & CC2420_OPT_PROMISCUOUS)); case NETOPT_RX_START_IRQ: return opt_state(val, (dev->options & CC2420_OPT_TELL_RX_START)); case NETOPT_RX_END_IRQ: return opt_state(val, (dev->options & CC2420_OPT_TELL_TX_END)); case NETOPT_TX_START_IRQ: return opt_state(val, (dev->options & CC2420_OPT_TELL_RX_START)); case NETOPT_TX_END_IRQ: return opt_state(val, (dev->options & CC2420_OPT_TELL_RX_END)); default: return -ENOTSUP; } }
/*---------------------------------------------------------------------------*/ void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) { rpl_instance_t *instance; rpl_dag_t *dag; rpl_parent_t *p; rpl_of_t *of; int tx;//elnaz dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); if(dag == NULL) { // PRINTF("RPL: Failed to allocate a DAG object!\n"); return; } instance = dag->instance; p = rpl_add_parent(dag, dio, from); // PRINTF("RPL: Adding "); // PRINT6ADDR(from); // PRINTF(" as a parent: "); if(p == NULL) { // PRINTF("failed\n"); instance->used = 0; return; } p->dtsn = dio->dtsn; // PRINTF("succeeded\n"); /* Determine the objective function by using the objective code point of the DIO. */ of = rpl_find_of(dio->ocp); if(of == NULL) { // PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",dio->instance_id); rpl_remove_parent(p); instance->used = 0; return; } /* Autoconfigure an address if this node does not already have an address with this prefix. */ if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { check_prefix(NULL, &dio->prefix_info); } //-----------------elnaz tx =cc2420_get_txpower(); printf("Power=%d \n",tx); switch(tx) { case 3: dag->Tx = 0.003; break; case 7: dag->Tx = 0.03; break; case 11: dag->Tx = 0.1; break; case 15: dag->Tx = 0.2; break; case 19: dag->Tx = 0.3; break; case 23: dag->Tx = 0.5; break; case 27: dag->Tx = 0.8; break; case 31: dag->Tx = 1; } /* float mv = (bateria * 2.500 * 2) / 4096; printf("Battery: (%ld.%03d mV)\n", (long) mv, (unsigned) ((mv - floor(mv)) * 1000)); */ //printf("Test tx=%ld ",(long) (dag->Tx*1000)); //----------------------elnaz dag->joined = 1; dag->preference = dio->preference; dag->grounded = dio->grounded; dag->version = dio->version; instance->of = of; instance->mop = dio->mop; instance->current_dag = dag; instance->dtsn_out = RPL_LOLLIPOP_INIT; instance->max_rankinc = dio->dag_max_rankinc; instance->min_hoprankinc = dio->dag_min_hoprankinc; instance->dio_intdoubl = dio->dag_intdoubl; instance->dio_intmin = dio->dag_intmin; instance->dio_intcurrent = instance->dio_intmin + instance->dio_intdoubl; instance->dio_redundancy = dio->dag_redund; instance->default_lifetime = dio->default_lifetime; instance->lifetime_unit = dio->lifetime_unit; memcpy(&dag->dag_id, &dio->dag_id, sizeof(dio->dag_id)); /* Copy prefix information from the DIO into the DAG object. */ memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); rpl_set_preferred_parent(dag, p); instance->of->update_metric_container(instance); dag->rank = instance->of->calculate_rank(p, 0); /* So far this is the lowest rank we are aware of. */ dag->min_rank = dag->rank; if(default_instance == NULL) { default_instance = instance; } // PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ", dio->instance_id, dag->rank); // PRINT6ADDR(&dag->dag_id); // PRINTF("\n"); ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); rpl_reset_dio_timer(instance); rpl_set_default_route(instance, from); if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { rpl_schedule_dao(instance); } else { // PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n"); } }