void rx_task() { uint8_t i, len, rssi, *local_rx_buf; bmac_set_cca_thresh(DEFAULT_BMAC_CCA); bmac_rx_pkt_set_buffer ((char*)rx_buf, RF_MAX_PAYLOAD_SIZE); while (1) { if(cache[0]==MyOwnAddress) { nrk_led_set(RED_LED); } else { nrk_led_clr(RED_LED); } bmac_wait_until_rx_pkt(); nrk_led_set(ORANGE_LED); (char*)local_rx_buf = bmac_rx_pkt_get (&len, &rssi); for(i=0; i<len; i++) { putchar(local_rx_buf[i]); } RxPacketProcess(local_rx_buf,len); nrk_led_clr (ORANGE_LED); bmac_rx_pkt_release(); nrk_wait_until_next_period (); } }
void rx_task () { uint8_t i,len; int8_t rssi, v; nrk_status_t ret; uint8_t *local_rx_buf; // printf( "rx_task: PID=%d\r\n",nrk_get_pid()); bmac_rx_pkt_set_buffer(rx_buf,RF_MAX_PAYLOAD_SIZE); while(!bmac_started()) nrk_wait_until_next_period(); while(1) { if( bmac_rx_pkt_ready()==0) bmac_wait_until_rx_pkt(); v = nrk_sem_pend(lock); if( startCnt == 0 ) startCnt = 1; v = nrk_sem_post(lock); nrk_led_toggle(GREEN_LED); local_rx_buf = bmac_rx_pkt_get(&len,&rssi); printf( "rx_task: rssi=%d data=", rssi); for( i=0; i<len; i++ ) { printf( "%c", local_rx_buf[i]); } nrk_kprintf( PSTR("\r\n") ); bmac_rx_pkt_release(); } }
void rx_task () { uint8_t rssi,len,*local_rx_buf,mole, from, received_round;; int i,r; bmac_set_cca_thresh(DEFAULT_BMAC_CCA); bmac_rx_pkt_set_buffer (rx_buf,102); //cleaning up the target sector in the flash iap.erase(TARGET_SECTOR,TARGET_SECTOR); while(!bmac_started()); printf("Receiver node Bmac initialised\n"); while(1) { nrk_wait_until_next_period(); if( !bmac_rx_pkt_ready()) continue; printf("received packet\n\r"); nrk_led_toggle(ORANGE_LED); local_rx_buf = (uint8_t *)bmac_rx_pkt_get (&len, &rssi); for(i=0;i<2;i++) printf("%d", local_rx_buf[i]); printf("\r\n"); for(i = 2; i < len; i++) printf("0x%X ", local_rx_buf[i]); // getting function code for(i = 0; i < 200; i++){ code[i] = local_rx_buf[i+2]; } //getting function size functionSize=local_rx_buf[1]; iap.prepare(TARGET_SECTOR, TARGET_SECTOR); //alloting space and writing the cvode in the flash if(functionSize % 256 ==0) r = iap.write( code, sector_start_adress[TARGET_SECTOR], 256); else r = iap.write( code, sector_start_adress[TARGET_SECTOR], 256); printf("size: %d\n", functionSize + functionSize % 256); printf( "copied: SRAM(0x%08X)->Flash(0x%08X) for %d bytes. (result=0x%08X)\r\n", code, sector_start_adress[ TARGET_SECTOR ], 1024, r ); startAddress+=functionSize;//starting Address for next functtion to be added functionRecieved = 0; bmac_rx_pkt_release (); copied_function=(function) (0xE000 | 1); //calling the copi8ed function functionRecieved=1; } // pointing the function pointer to the copied code in the flash }
void rx_task () { uint8_t i, len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_time_t check_period; printf ("rx_task PID=%d\r\n", nrk_get_pid ()); // init bmac on channel 25 bmac_init (15); // Enable AES 128 bit encryption // When encryption is active, messages from plaintext // source will still be received. bmac_encryption_set_key(aes_key,16); bmac_encryption_enable(); // bmac_encryption_disable(); // By default the RX check rate is 100ms // below shows how to change that check_period.secs=0; check_period.nano_secs=25*NANOS_PER_MS; val=bmac_set_rx_check_rate(check_period); // The default Clear Channel Assement RSSI threshold is -45 // Setting this value higher means that you will only trigger // receive with a very strong signal. Setting this lower means // bmac will try to receive fainter packets. If the value is set // too high or too low performance will suffer greatly. // bmac_set_cca_thresh(-45); //if(val==NRK_ERROR) nrk_kprintf( PSTR("ERROR setting bmac rate\r\n" )); // This sets the next RX buffer. // This can be called at anytime before releaseing the packet // if you wish to do a zero-copy buffer switch bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); while (1) { // Wait until an RX packet is received val = bmac_wait_until_rx_pkt (); // Get the RX packet nrk_led_set (ORANGE_LED); local_rx_buf = bmac_rx_pkt_get (&len, &rssi); if( bmac_rx_pkt_is_encrypted()==1 ) nrk_kprintf( PSTR( "Packet Encrypted\r\n" )); printf ("Got RX packet len=%d RSSI=%d [", len, rssi); for (i = 0; i < len; i++) printf ("%c", local_rx_buf[i]); printf ("]\r\n"); nrk_led_clr (ORANGE_LED); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } }
void rx_task () { uint8_t i, len, rssi; int8_t val; //char *local_rx_buf; nrk_time_t check_period; printf ("rx_task PID=%d\r\n", nrk_get_pid ()); // init bmac on channel 24 bmac_init (5); bmac_set_cca_thresh(DEFAULT_BMAC_CCA); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); while (1) { // Wait until an RX packet is received val = bmac_wait_until_rx_pkt (); //printf("Hi..\n"); // Get the RX packet nrk_led_set (ORANGE_LED); local_rx_buf = bmac_rx_pkt_get (&len, &rssi); inter_flag=0; if(rssi<5){ dst_addr=0x0003; //inter_tx_buf=local_rx_buf; } else { dst_addr=0x0001; } if(local_rx_buf[0]=='n'){ dst_addr=0x0001; inter_tx_buf=local_rx_buf; inter_flag=1; } printf("inter_flag: %d",inter_flag); printf("\r\n"); printf("rx_buf:"); for(i=0;i<len;i++){ printf("%c",local_rx_buf[i]); } nrk_led_clr (ORANGE_LED); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); // this is necessary nrk_wait_until_next_period (); } }
void rx_task () { uint8_t i, len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_time_t check_period; // init bmac on channel 25 bmac_init (25); rx_data_ok=0; // This sets the next RX buffer. // This can be called at anytime before releaseing the packet // if you wish to do a zero-copy buffer switch bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); while (1) { // Wait until an RX packet is received val = bmac_wait_until_rx_pkt (); // Get the RX packet nrk_led_set(0); nrk_led_set(1); nrk_led_set(2); nrk_led_set(3); local_rx_buf = bmac_rx_pkt_get (&len, &rssi); printf("RX received: RSSI = %d\r\n", rssi); nrk_spin_wait_us(50000); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); nrk_led_clr(0); nrk_led_clr(1); nrk_led_clr(2); nrk_led_clr(3); } }
void rx_task () { uint8_t i, len, rssi; int8_t val; char *local_rx_buf; nrk_time_t check_period; printf ("rx_task PID=%d\r\n", nrk_get_pid ()); // init bmac on channel 24 bmac_init (12); bmac_set_cca_thresh(DEFAULT_BMAC_CCA); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); rx_count = 0; while (1) { // Wait until an RX packet is received if (tx_count >= 300) { printf("Total Packet received : %d \r\n", rx_count); } val = bmac_wait_until_rx_pkt (); // Get the RX packet nrk_led_set (ORANGE_LED); local_rx_buf = bmac_rx_pkt_get (&len, &rssi); //if( bmac_rx_pkt_is_encrypted()==1 ) nrk_kprintf( PSTR( "Packet Encrypted\r\n" )); if ((len > 0) && (rssi > 0)) { printf ("Got RX packet len=%d RSSI=%d \r\n", len, rssi); nrk_led_clr (ORANGE_LED); rx_count++; } // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); // this is necessary nrk_wait_until_next_period (); } }
void gateway_task () { uint8_t i, len; int8_t rssi, val; uint8_t *local_rx_tx_buf; uint16_t batt; nrk_time_t check_period, wait_time; uint16_t buf; int8_t fd; uint8_t j, cnt, level; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; nrk_time_t next_transmit_time; nrk_time_t current_time; nrk_time_t prev_time; char tmp[4]; printf ("gateway_task PID=%d\r\n", nrk_get_pid ()); next_transmit_time.secs = 0; next_transmit_time.nano_secs = 0; // init bmac on channel 25 bmac_init (26); // By default the RX check rate is 100ms // below shows how to change that check_period.secs=0; check_period.nano_secs=100*NANOS_PER_MS; val=bmac_set_rx_check_rate(check_period); // The default Clear Channel Assement RSSI threshold is -32 // Setting this value higher means that you will only trigger // receive with a very strong signal. Setting this lower means // bmac will try to receive fainter packets. If the value is set // too high or too low performance will suffer greatly. // bmac_set_cca_thresh(-36); if(val==NRK_ERROR) nrk_kprintf( PSTR("ERROR setting bmac rate\r\n" )); // This sets the next RX buffer. // This can be called at anytime before releaseing the packet // if you wish to do a zero-copy buffer switch bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); nrk_time_set(0, 0); cnt = 0; // Initially clear all the data buffers for(i=0; i<(MAX_NODES);i++) { for(j=0; j<(WORDS_PER_NODE); j++) { data_pkt.node_specific_data[i][j] = 0; } } while (1) { nrk_time_get(¤t_time); // If it is time to flood the network, send the control packets if(current_time.secs%FLOOD_RATE == 0 && prev_time.secs != current_time.secs || cnt == 0) { prev_time = current_time; cnt ++; SET_PACKET_COUNT(pkt_buf.pkt_type_cnt, cnt); #if MODE==DATA_MODE SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_CONTROL); #else SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_DIAG_CONTROL); #endif pkt_buf.hop_number = 0; pkt_buf.time_to_flood = TIME_TO_FLOOD_IN_SECS; pkt_buf.bmac_check_rate = BMAC_CHECK_RATE_IN_MS; pkt_buf.maximum_depth = MAXIMUM_DEPTH; pkt_buf.delay_at_each_level = DELAY_AT_EACH_LEVEL_IN_SECS; pkt_buf.next_control_time = NEXT_CONTROL_TIME; pkt_buf.data_push_rate = 0; for(i=0; i<(MAX_NODES);i++) { for(j=0; j<(WORDS_PER_NODE); j++) { #if MODE==DATA_MODE pkt_buf.node_specific_data[i][j] = SENSOR; #else pkt_buf.node_specific_data[i][j] = 0; #endif } } memcpy(tx_buf, &pkt_buf, sizeof(pkt_buf)); // Non-blocking send nrk_led_set (BLUE_LED); val = bmac_tx_pkt_nonblocking (tx_buf, sizeof(struct message_packet)); nrk_kprintf (PSTR ("Tx packet enqueued\r\n")); ret = nrk_event_wait (SIG(tx_done_signal)); if(ret & SIG(tx_done_signal) == 0 ) nrk_kprintf (PSTR ("TX done signal error\r\n")); nrk_led_clr (BLUE_LED); } // If a new packet has been received, then update the information if(bmac_rx_pkt_ready()) { // Wait until an RX packet is received nrk_led_set (ORANGE_LED); // Get the RX packet local_rx_tx_buf = bmac_rx_pkt_get (&len, &rssi); for (i = 0; i < len; i++) printf ("%d", rx_buf[i]); printf ("\r\n"); memcpy(&pkt_buf, rx_buf, sizeof(pkt_buf)); nrk_led_clr (ORANGE_LED); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); // If the received packet is a data packet then update the information, gateway just ignores the control packets if(GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DIAG_DATA || GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DATA) { printf("Type = %d\n\r", GET_PACKET_TYPE(pkt_buf.pkt_type_cnt)); printf("Count = %d\n\r", GET_PACKET_COUNT(pkt_buf.pkt_type_cnt)); printf("Hop # = %d\n\r", pkt_buf.hop_number); printf("TTF = %d\n\r", pkt_buf.time_to_flood); printf("BCR = %d\n\r", pkt_buf.bmac_check_rate); printf("Nmax = %d\n\r", pkt_buf.maximum_depth); printf("Dlev = %d\n\r", pkt_buf.delay_at_each_level); printf("Nxt = %d\n\r", pkt_buf.next_control_time); printf("Prate = %d\n\r", pkt_buf.data_push_rate); for(i=0; i<(MAX_NODES);i++) { for(j=0; j<(WORDS_PER_NODE); j++) { if(pkt_buf.node_specific_data[i][j] != 0) data_pkt.node_specific_data[i][j] = pkt_buf.node_specific_data[i][j]; } } for(i=0; i<(MAX_NODES);i++) { printf("Value @ Node %d is %d (cnt is %d)", i, ((int16_t)data_pkt.node_specific_data[i][1]<<4), (data_pkt.node_specific_data[i][0]&0x3F)); printf("\n\r"); } } } } }
// This task listens for messages and if it receives an XMPP // message addressed to broadcast or this node, it will print it out void rx_task () { uint8_t len; int8_t rssi, val; uint8_t *local_rx_buf; XMPP_PKT_T rxp; nrk_time_t check_period; printf ("rx_task PID=%d\r\n", nrk_get_pid ()); // Initialize FireFly LCD v1.2 board lcd_setup(); lcd_string_display_escape("Waiting\\nfor msg."); while (!bmac_started ()) nrk_wait_until_next_period (); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); while (1) { // Wait for new packet if one isn't already available if (bmac_rx_pkt_ready () == 0) { val = bmac_wait_until_rx_pkt (); } // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (MOBILE_MASK)) != 0) { // Set the buffer p2p_pkt.buf = local_rx_buf; p2p_pkt.buf_len = len; p2p_pkt.rssi = rssi; unpack_peer_2_peer_packet (&p2p_pkt); // just check the last part of the address because we are lazy // In the future you should check the whole address so that you // don't accidentally get someone elses messages if ((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) { nrk_led_set (GREEN_LED); // Packet arrived and is good to go #ifdef TXT_DEBUG printf ("full mac: %d %d %d %d ", p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2], p2p_pkt.src_mac); printf ("rssi: %d ", p2p_pkt.rssi); printf ("type: %d ", p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = p2p_pkt.payload_start; i < p2p_pkt.buf_len; i++) printf ("%d ", p2p_pkt.buf[i]); nrk_kprintf (PSTR ("]\r\n")); #endif // If it is an XMPP message if (p2p_pkt.pkt_type == XMPP_PKT) { nrk_kprintf (PSTR ("XMPP packet for me!\r\n")); // Unpack the message xmpp_pkt_unpack (&rxp, p2p_pkt.payload, 0); // Print it out printf ("XMPP msg:\r\n"); printf (" seq-num=%d\r\n", p2p_pkt.seq_num); printf (" from-jid=%s\r\n", rxp.src_jid); printf (" msg=%s\r\n", rxp.msg); // Load and display message lcd_string_array_load(rxp.msg); } } } // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } }
void rx_task () { uint8_t pos,len,i,version; int8_t rssi; uint8_t *local_rx_buf; int16_t recipient,sender,dataseq; char type; if(log_g) printf ("log:rx_task PID=%d\r\n", nrk_get_pid ()); // init bmac on channel 15 bmac_init (15); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); while (1) { // Wait until an RX packet is received bmac_wait_until_rx_pkt (); // Get the RX packet nrk_led_set (ORANGE_LED); local_rx_buf = bmac_rx_pkt_get (&len, &rssi); //if(log_g) printf ("log:Packet recv\n"); //if(log_g) printf ("log:"); //for (i = 0; i < len; i++) { // if(log_g) printf ("%c", rx_buf[i]); //} //if(log_g) printf ("\n"); pos = 0; recipient = get_next_int(local_rx_buf,&pos,len); pos+=1; sender = get_next_int(local_rx_buf,&pos,len); pos+=1; type = local_rx_buf[pos]; pos+=2; if((recipient != 0 && recipient != MAC_ADDR) || sender == MAC_ADDR) { if(log_g) printf("log:Ignore\r\n"); } else if(recipient == 0 && type == 'S') { version =get_next_int(local_rx_buf,&pos,len); on_discover_pkt(sender, version); } else if (recipient == 0 && type == 'B') { onBasketBallPkt(); } else if (type == 'C') { version =get_next_int(local_rx_buf,&pos,len); onConnectionReq(sender,version); } else if(type == 'D' ) { dataseq = get_next_int(local_rx_buf,&pos,len); onData(sender,dataseq,local_rx_buf,len); } else if(type == 'A') { dataseq = get_next_int(local_rx_buf,&pos,len); onAck(sender, dataseq); } else if(type == 'M') { onContactShare(local_rx_buf,len); }else { if(log_g) printf("log:Invalid MSG\r\n"); } // Release the RX buffer so future packets can arrive memset(local_rx_buf,0,len+1); bmac_rx_pkt_release (); nrk_led_clr(ORANGE_LED); nrk_wait_until_next_period(); } }
void rx_task () { uint8_t i, len; uint16_t j; int8_t rssi, val; int8_t data_ready, button_state; uint8_t *local_rx_buf; uint16_t seq_num; uint16_t pkt_cnt; nrk_time_t check_period; printf ("rx_task PID=%d\r\n", nrk_get_pid ()); // init bmac on channel 25 bmac_init (15); // Enable AES 128 bit encryption // When encryption is active, messages from plaintext // source will still be received. //bmac_encryption_set_key(aes_key,16); //bmac_encryption_enable(); // bmac_encryption_disable(); // By default the RX check rate is 100ms // below shows how to change that //check_period.secs=0; //check_period.nano_secs=200*NANOS_PER_MS; //val=bmac_set_rx_check_rate(check_period); // The default Clear Channel Assement RSSI threshold is -45 // Setting this value higher means that you will only trigger // receive with a very strong signal. Setting this lower means // bmac will try to receive fainter packets. If the value is set // too high or too low performance will suffer greatly. bmac_set_cca_thresh(-50); //if(val==NRK_ERROR) nrk_kprintf( PSTR("ERROR setting bmac rate\r\n" )); // This sets the next RX buffer. // This can be called at anytime before releaseing the packet // if you wish to do a zero-copy buffer switch bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); index=0; while (1) { nrk_led_clr(GREEN_LED); nrk_led_set(RED_LED); do { nrk_led_toggle(BLUE_LED); printf( "\r\nTest Data\r\n" ); for(j=0; j<index; j++ ) { printf( "run: %u pkts: %u rssi: %d\r\n",j, data[j],rssi_avg[j] ); } for(j=0; j<100; j++ ) nrk_wait_until_next_period (); }while( nrk_gpio_get(NRK_BUTTON)==1 ); nrk_led_clr(BLUE_LED); nrk_led_clr(RED_LED); for(j=0; j<100; j++ ) nrk_wait_until_next_period (); nrk_led_set(GREEN_LED); pkt_cnt=0; while(1) { // Wait until an RX packet is received do { data_ready=bmac_rx_pkt_ready(); button_state=nrk_gpio_get(NRK_BUTTON); nrk_wait_until_next_period(); } while(data_ready==0 && button_state==1 ); if(button_state==0) break; val = bmac_wait_until_rx_pkt (); // Get the RX packet nrk_led_set (ORANGE_LED); local_rx_buf = bmac_rx_pkt_get (&len, &rssi); //if( bmac_rx_pkt_is_encrypted()==1 ) nrk_kprintf( PSTR( "Packet Encrypted\r\n" )); //printf ("Got RX packet len=%d RSSI=%d [", len, rssi); rssi_acc+=rssi; seq_num=local_rx_buf[1]<<8 | local_rx_buf[0]; printf ("cnt: %u seq num: %u\r\n",pkt_cnt, seq_num); pkt_cnt++; nrk_led_clr (ORANGE_LED); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } rssi_avg[index]=rssi_acc/pkt_cnt; data[index]=pkt_cnt; index++; } }
void pingMode() { // Broadcast for ping val=bmac_addr_decode_set_my_mac(((uint16_t)my_subnet_mac<<8)|my_mac); val=bmac_addr_decode_dest_mac((uint16_t)0xffff); // broadcast by default bmac_addr_decode_enable(); uint8_t i; // Build a TX packet by hand... p2p_pkt.pkt_type = PING_PKT; // set as p2p packet (no US_MASK or DS_MASK) p2p_pkt.ctrl_flags = MOBILE_MASK ; // | DEBUG_FLAG ; p2p_pkt.ack_retry= 0x00; p2p_pkt.ttl = 1; p2p_pkt.src_subnet_mac[0] = 0; p2p_pkt.src_subnet_mac[1] = 0; p2p_pkt.src_subnet_mac[2] = 0; p2p_pkt.src_mac = my_mac; p2p_pkt.last_hop_mac = my_mac; p2p_pkt.dst_subnet_mac[0] = BROADCAST; p2p_pkt.dst_subnet_mac[1] = BROADCAST; p2p_pkt.dst_subnet_mac[2] = BROADCAST; p2p_pkt.dst_mac = BROADCAST; p2p_pkt.buf=tx_buf; p2p_pkt.buf_len = P2P_PAYLOAD_START; p2p_pkt.seq_num = cnt; p2p_pkt.priority = 0; cnt++; // p2p_pkt.payload[0]=my_mac; // p2p_pkt.payload_len=1; // ping_p2p_generate(&p2p_pkt); nrk_led_set (BLUE_LED); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet(&p2p_pkt); // For blocking transmits, use the following function call. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); check_period.secs = 0; check_period.nano_secs = FAST_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nPING Packet Sent. Waiting for Replies...\r\n\n")); #endif nrk_led_clr (BLUE_LED); nrk_led_clr(GREEN_LED); // Wait for packets or timeout nrk_time_get (&start); while (1) { timeout.secs = PING_WAIT_SECS; timeout.nano_secs = 0; // Wait until an RX packet is received //val = bmac_wait_until_rx_pkt (); nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Set the buffer p2p_pkt.buf=local_rx_buf; p2p_pkt.buf_len=len; p2p_pkt.rssi=rssi; unpack_peer_2_peer_packet(&p2p_pkt); if (p2p_pkt.dst_mac == my_mac || p2p_pkt.dst_mac == BROADCAST) { nrk_led_set(GREEN_LED); // Packet arrived and is good to go printf( "Mac: %x%x%x",p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2]); printf( "%x ",p2p_pkt.src_mac); printf( "| RSSI: %d ",p2p_pkt.rssi); printf( "| Type: %d \r\n",p2p_pkt.pkt_type); } } // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } nrk_time_get (¤t); if (start.secs + PING_WAIT_SECS < current.secs) break; } nrk_kprintf (PSTR ("\r\nDone Waiting for Response...\r\n")); nrk_led_clr(GREEN_LED); }
void whacky_task () { uint8_t i, len, fd; int8_t rssi, val; uint8_t *local_buf; uint16_t light, node_id, got_poll; uint8_t pos; printf ("whacky_task PID=%d\r\n", nrk_get_pid ()); // Open ADC device as read fd=nrk_open(FIREFLY_3_SENSOR_BASIC,READ); if(fd==NRK_ERROR) nrk_kprintf(PSTR("Failed to open sensor driver\r\n")); printf(PSTR("Sensor opened\r\n")); // init bmac on channel 15 bmac_init (15); printf(PSTR("bmac init\r\n")); srand(1); // This sets the next RX buffer. // This can be called at anytime before releasing the packet // if you wish to do a zero-copy buffer switch bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); printf(PSTR("RX buffer set\r\n")); while (1) { node_id = 0; got_poll = 0; printf(PSTR("Waiting for a Packet\r\n")); // Get the RX packet nrk_led_set (ORANGE_LED); // Wait until an RX packet is received if(!bmac_rx_pkt_ready()) { val = bmac_wait_until_rx_pkt (); } local_buf = bmac_rx_pkt_get (&len, &rssi); printf ("Got RX packet len=%d RSSI=%d [%s]\r\n", len, rssi, local_buf); // Check for a poll packet if(len>5 && local_buf[0] == 'P' && local_buf[1] == 'O' && local_buf[2] == 'L' && local_buf[3] == 'L' && local_buf[4] == ':') { // Assume that there is a space after POLL pos = 6; while(pos < len && local_buf[pos] != '\0' && local_buf[pos] >='0' && local_buf[pos]<='9') { node_id *= 10; node_id += (local_buf[pos]-'0'); pos++; } if(pos > 6) { got_poll = 1; } } nrk_led_clr (ORANGE_LED); // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); if(got_poll == 1 && node_id == MAC_ADDR) { val=nrk_set_status(fd,SENSOR_SELECT,LIGHT); val=nrk_read(fd,&light,2); sprintf (tx_buf, "Node %d Status %u", MAC_ADDR, light); nrk_led_set (BLUE_LED); val=bmac_tx_pkt(tx_buf, strlen(tx_buf)+1); if(val != NRK_OK) { nrk_kprintf(PSTR("Could not Transmit!\r\n")); } // Task gets control again after TX complete nrk_kprintf (PSTR ("Tx task sent data!\r\n")); printf("%s\r\n", tx_buf); nrk_led_clr (BLUE_LED); } } }
void tx_task () { uint8_t j, i, cnt, error; int8_t len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_sig_t tx_done_signal; nrk_sig_t rx_signal; nrk_sig_mask_t ret; nrk_time_t check_period; nrk_time_t timeout, start, current; nrk_sig_mask_t my_sigs; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); // Configure address for other packet handlers (my not be needed) my_mac= MY_MAC; my_subnet_mac[0]= MY_SUBNET_MAC_0; my_subnet_mac[1]= MY_SUBNET_MAC_1; my_subnet_mac[2]= MY_SUBNET_MAC_2; mac_address= (uint8_t)MY_SUBNET_MAC_2 << 24 | (uint8_t)MY_SUBNET_MAC_1 <<16 | (uint8_t)MY_SUBNET_MAC_0 << 8 | (uint8_t)MY_MAC; while (!bmac_started ()) nrk_wait_until_next_period (); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); val = bmac_addr_decode_set_my_mac (((uint16_t) MY_SUBNET_MAC_0 << 8) | MY_MAC); val = bmac_addr_decode_dest_mac (0xffff); // broadcast by default bmac_addr_decode_enable (); nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; while (1) { // Build a TX packet by hand... p2p_pkt.pkt_type = DATA_STORAGE_PKT; p2p_pkt.ctrl_flags = LINK_ACK | MOBILE_MASK; // | DEBUG_FLAG ; p2p_pkt.ack_retry = 0x0f; p2p_pkt.ttl = 1; p2p_pkt.src_subnet_mac[0] = MY_SUBNET_MAC_0; p2p_pkt.src_subnet_mac[1] = MY_SUBNET_MAC_1; p2p_pkt.src_subnet_mac[2] = MY_SUBNET_MAC_2; p2p_pkt.src_mac = MY_MAC; p2p_pkt.last_hop_mac = MY_MAC; // p2p_pkt.dst_subnet_mac[0] = BROADCAST; // p2p_pkt.dst_subnet_mac[1] = BROADCAST; // p2p_pkt.dst_subnet_mac[2] = BROADCAST; // p2p_pkt.dst_mac = BROADCAST; p2p_pkt.dst_subnet_mac[0] = BROADCAST; p2p_pkt.dst_subnet_mac[1] = BROADCAST; p2p_pkt.dst_subnet_mac[2] = BROADCAST; p2p_pkt.dst_mac = 0x1; p2p_pkt.buf = tx_buf; p2p_pkt.buf_len = P2P_PAYLOAD_START; p2p_pkt.seq_num = cnt; p2p_pkt.priority = 0; p2p_pkt.check_rate = 100; p2p_pkt.payload = &(tx_buf[P2P_PAYLOAD_START]); cnt++; #ifdef TEST_WRITE data_pkt.mode=EE_WRITE; data_pkt.addr=0x110; // Must be greater than 0x100 data_pkt.data_len=0x10; // point the eeprom data structure to our local data buffer data_pkt.eeprom_payload=eeprom_data; // copy over some data for(i=0; i<data_pkt.data_len; i++ ) data_pkt.eeprom_payload[i]=i; #endif #ifdef TEST_READ data_pkt.mode=EE_READ; data_pkt.addr=0x200; // Must be greater than 0x100 data_pkt.data_len=0x3d; #endif // add the eeprom pkt to the p2p pkt p2p_pkt.payload_len= eeprom_storage_pkt_pack(&data_pkt, p2p_pkt.payload); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet (&p2p_pkt); nrk_led_set (BLUE_LED); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); nrk_kprintf( PSTR("sending: " )); for(i=0; i<p2p_pkt.buf_len; i++ ) printf( "%u ",p2p_pkt.buf[i] ); printf( "\r\n" ); // For blocking transmits, use the following function call. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); check_period.secs = 0; check_period.nano_secs = FAST_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nSent Request:\r\n")); #endif nrk_led_clr (BLUE_LED); nrk_led_clr (GREEN_LED); // Wait for packets or timeout nrk_time_get (&start); while (1) { timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = 0; // Wait until an RX packet is received //val = bmac_wait_until_rx_pkt (); if(bmac_rx_pkt_ready()==0) { nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); } if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Set the buffer p2p_pkt.buf = local_rx_buf; p2p_pkt.buf_len = len; p2p_pkt.rssi = rssi; unpack_peer_2_peer_packet (&p2p_pkt); #ifdef TXT_DEBUG if ((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) { nrk_led_set (GREEN_LED); // Packet arrived and is good to go printf ("full mac: %d %d %d %d ", p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2], p2p_pkt.src_mac); printf ("rssi: %d ", p2p_pkt.rssi); printf ("type: %d ", p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = 0; i < p2p_pkt.payload_len; i++) printf ("%d ", p2p_pkt.payload[i]); nrk_kprintf (PSTR ("]\r\n")); if(p2p_pkt.pkt_type== DATA_STORAGE_PKT ) { eeprom_storage_pkt_unpack(&data_pkt, p2p_pkt.payload ); nrk_kprintf( PSTR("\r\n Storage Packet " )); nrk_kprintf( PSTR("\r\n Mode: " )); switch(data_pkt.mode) { case EE_REPLY: nrk_kprintf( PSTR( "Reply")); break; case EE_ERROR: nrk_kprintf( PSTR( "Error" )); break; case EE_READ: nrk_kprintf( PSTR( "Read" )); break; case EE_WRITE: nrk_kprintf( PSTR( "Write" )); break; default: nrk_kprintf( PSTR( "unknown" )); } nrk_kprintf( PSTR("\r\n From: " )); printf( "%u",data_pkt.mac ); nrk_kprintf( PSTR("\r\n Addr: " )); printf( "%u",data_pkt.addr); nrk_kprintf( PSTR("\r\n Len: " )); printf( "%u",data_pkt.data_len); nrk_kprintf( PSTR("\r\n Data: " )); for(i=0; i<data_pkt.data_len; i++ ) printf( "%u ",data_pkt.eeprom_payload[i]); nrk_kprintf( PSTR("\r\n" )); } } #endif } } nrk_time_get (¤t); if (start.secs + REPLY_WAIT_SECS < current.secs) break; // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } nrk_kprintf (PSTR ("Done Waiting for response...\r\n")); nrk_wait_until_next_period (); } }
// rx_msg_task() - receive messages from the network void rx_msg_task() { // local variable instantiation int8_t rssi; uint8_t len; packet rx_packet; uint8_t *local_rx_buf; volatile uint8_t local_network_joined = FALSE; volatile uint8_t rx_source_id = 0; volatile uint8_t node_id; volatile uint8_t rx_payload = 0; volatile msg_type rx_type; // print task PID printf("rx_msg PID: %d.\r\n", nrk_get_pid()); // initialize network receive buffer bmac_rx_pkt_set_buffer(g_net_rx_buf, RF_MAX_PAYLOAD_SIZE); // Wait until bmac has started. while (!bmac_started ()) { nrk_wait_until_next_period (); } // loop forever - run the task while(1) { // only execute if there is a packet available if(bmac_rx_pkt_ready()) { nrk_led_set(BLUE_LED); // get the packet, parse and release local_rx_buf = bmac_rx_pkt_get(&len, &rssi); parse_msg(&rx_packet, local_rx_buf, len); bmac_rx_pkt_release(); // print incoming packet if appropriate if(TRUE == g_verbose) { nrk_kprintf(PSTR("RX: ")); print_packet(&rx_packet); } // get message parameters rx_source_id = rx_packet.source_id; rx_type = rx_packet.type; // only receive the message if it's not from this node if((GATEWAY_MAC == rx_source_id) || (SERVER_MAC == rx_source_id)) { // determine if the network has been joined local_network_joined = atomic_network_joined(); // execute the normal sequence of events if the network has been joined if(TRUE == local_network_joined) { // put the message in the right queue based on the type switch(rx_type) { // command received -> actuate or ignore case MSG_CMD: // if command is for this node and add it to the action queue. node_id = rx_packet.payload[CMD_NODE_ID_INDEX]; if(MAC_ADDR == node_id) { atomic_push(&g_act_queue, &rx_packet, g_act_queue_mux); if (TRUE == g_verbose) { nrk_kprintf(PSTR("Received command ^^^\r\n")); } } case MSG_HANDACK: case MSG_HEARTBEAT: case MSG_RESET: atomic_kick_watchdog(); break; case MSG_HAND: case MSG_DATA: case MSG_CMDACK: case MSG_NO_MESSAGE: case MSG_GATEWAY: default: break; } } // if the local_network_joined flag hasn't been set yet, check status else { // if a handshake ack has been received, then set the network joined flag. Otherwise, ignore. rx_payload = rx_packet.payload[HANDACK_NODE_ID_INDEX]; if((MSG_HANDACK == rx_type) && (MAC_ADDR == rx_payload)) { atomic_update_network_joined(TRUE); atomic_kick_watchdog(); local_network_joined = atomic_network_joined(); } } } nrk_led_clr(BLUE_LED); } nrk_wait_until_next_period(); } nrk_kprintf(PSTR("Fallthrough: rx_msg_task\r\n")); }
void tx_task () { uint8_t j, i, error,unique; uint8_t samples; int8_t len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_sig_t tx_done_signal; nrk_sig_t rx_signal; nrk_sig_mask_t ret; nrk_time_t check_period; nrk_time_t timeout, start, current; nrk_sig_mask_t my_sigs; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); val=bmac_addr_decode_set_my_mac(((uint16_t)MY_SUBNET_MAC_0<<8)|MY_MAC); val=bmac_addr_decode_dest_mac(0xffff); // broadcast by default bmac_addr_decode_enable(); nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); while (1) { my_nlist_elements=0; for(samples=0; samples<10; samples++ ) { nrk_led_set (GREEN_LED); check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); build_ping_pkt( &p2p_pkt ); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet(&p2p_pkt); // For blocking transmits, use the following function call. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); check_period.secs = 0; check_period.nano_secs = p2p_pkt.check_rate * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nSent Request:\r\n")); #endif nrk_led_clr (GREEN_LED); // Wait for packets or timeout nrk_time_get (&start); while (1) { timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = 0; // Wait until an RX packet is received //val = bmac_wait_until_rx_pkt (); nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Set the buffer p2p_pkt.buf=local_rx_buf; p2p_pkt.buf_len=len; p2p_pkt.rssi=rssi; unpack_peer_2_peer_packet(&p2p_pkt); #ifdef TXT_DEBUG // Check if newly received packet is for this node if (((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) && p2p_pkt.pkt_type==PING_PKT) { // Packet arrived and is good to go printf( "src: %d ",p2p_pkt.src_mac); printf( "rssi: %d ",p2p_pkt.rssi); printf( "subnet: %d %d %d ",p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2]); printf( "type: %d ",p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = 0; i < p2p_pkt.payload_len; i++) printf ("%d ", p2p_pkt.payload[i]); nrk_kprintf (PSTR ("]\r\n")); unique=1; // Check if the MAC is unique for(i=0; i<my_nlist_elements; i++ ) { if(my_nlist[i*NLIST_SIZE]==p2p_pkt.src_subnet_mac[2] && my_nlist[i*NLIST_SIZE+1]==p2p_pkt.src_subnet_mac[1] && my_nlist[i*NLIST_SIZE+2]==p2p_pkt.src_subnet_mac[0] && my_nlist[i*NLIST_SIZE+3]==p2p_pkt.src_mac) { unique=0; break; } } // If MAC is unique, add it if(unique) { my_nlist[my_nlist_elements*NLIST_SIZE]=p2p_pkt.src_subnet_mac[2]; my_nlist[my_nlist_elements*NLIST_SIZE+1]=p2p_pkt.src_subnet_mac[1]; my_nlist[my_nlist_elements*NLIST_SIZE+2]=p2p_pkt.src_subnet_mac[0]; my_nlist[my_nlist_elements*NLIST_SIZE+3]=p2p_pkt.src_mac; my_nlist[my_nlist_elements*NLIST_SIZE+4]=p2p_pkt.rssi; my_nlist_elements++; } } #endif } // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); } nrk_time_get (¤t); if (start.secs + REPLY_WAIT_SECS < current.secs) break; } cnt++; } check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); nrk_kprintf (PSTR ("Done Waiting for response...\r\n")); nrk_kprintf (PSTR ("\r\n\r\nSurvey Says:\r\n")); nrk_kprintf( PSTR("LOC_DESC: \"location name\"\r\n" )); for(i=0; i<my_nlist_elements; i++ ) { nrk_kprintf( PSTR( "MAC: " )); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE] ); else printf( "%x", my_nlist[i*NLIST_SIZE] ); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE+1] ); else printf( "%x", my_nlist[i*NLIST_SIZE+1] ); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE+2] ); else printf( "%x", my_nlist[i*NLIST_SIZE+2] ); if(my_nlist[i*NLIST_SIZE]<0x10) printf( "0%x", my_nlist[i*NLIST_SIZE+3] ); else printf( "%x", my_nlist[i*NLIST_SIZE+3] ); printf( " RSSI: %d\r\n", (int8_t)my_nlist[i*NLIST_SIZE+4] ); } nrk_wait_until_next_period (); } }
/****************************************************************************************************** * * *Receive task execution * * * * ******************************************************************************************************/ void rx_task () { uint8_t rssi,len,*local_rx_buf,v; int receivedSeqNo=0,senderNode = 0; bmac_set_cca_thresh(DEFAULT_BMAC_CCA); bmac_rx_pkt_set_buffer (rx_buf,RF_MAX_PAYLOAD_SIZE); while(!bmac_started()); printf("Receiver node Bmac initialised\n"); while(1) { if( !bmac_rx_pkt_ready()) continue; //printf("received packet\n\r"); nrk_led_toggle(ORANGE_LED); local_rx_buf = (uint8_t *)bmac_rx_pkt_get (&len, &rssi); //If my own packet then dont receive if(local_rx_buf[SOURCE_ADDRESS_LOCATION]==MY_ID) { continue; } //Sample the data receivedSeqNo = local_rx_buf[SEQUENCE_NUM_LOCATION]; senderNode = local_rx_buf[SOURCE_ADDRESS_LOCATION]; //Check if the message is intended for me if(len!=0 && local_rx_buf[DESTINATION_ADDRESS_LOCATION]==MY_ID) { //Check the type of data switch(local_rx_buf[MESSAGE_TYPE_LOCATION]) { case DATA: if(receivedSeqNo>lastReceivedSequenceNo[senderNode]) { receiveComplete[senderNode] =0; printf("received new packet\n\r"); //Process and send the acknowledgement to the receiver lastReceivedSequenceNo[senderNode]=receivedSeqNo; extractPacket(local_rx_buf,&receiveData[DATA_LOCATION(senderNode)],len,senderNode); if(local_rx_buf[PACKET_NUM_LOCATION]==FIRST_PACKET) { receivedPacketSize[senderNode]=0; receivedPacketSize[senderNode] +=(len-HEADER_SIZE); } else { receivedPacketSize[senderNode] +=(len-HEADER_SIZE); } //Send the acknowledgement ack_buf[senderNode][DESTINATION_ADDRESS_LOCATION]=senderNode; ack_buf[senderNode][SOURCE_ADDRESS_LOCATION]= MY_ID; ack_buf[senderNode][SEQUENCE_NUM_LOCATION] = receivedSeqNo; ack_buf[senderNode][MESSAGE_TYPE_LOCATION] = DATA_PACKET_ACK; receiverNextPacket[senderNode]= SEND_ACK; if(local_rx_buf[PACKET_NUM_LOCATION]==LAST_PACKET) { receiveComplete[senderNode] =1; for(int i=0;i<receivedPacketSize[senderNode];i++) { printf("%d \t",receiveData[i]); } } sendAckFlag[senderNode]=1; } else { printf("received old packet\n\r"); ack_buf[senderNode][DESTINATION_ADDRESS_LOCATION]=senderNode; ack_buf[senderNode][SOURCE_ADDRESS_LOCATION]= MY_ID; ack_buf[senderNode][SEQUENCE_NUM_LOCATION] = lastReceivedSequenceNo[senderNode]; ack_buf[senderNode][MESSAGE_TYPE_LOCATION] = DATA_PACKET_ACK; //Send the acknowledgement to the sender receiverNextPacket[senderNode]= SEND_ACK; sendAckFlag[senderNode]=1; } //v=nrk_event_signal( signal_ack ); break; case DATA_PACKET_ACK: //If it is a new ACK packet then accept it. Else dont bother if(lastSentSequenceNo[senderNode]==receivedSeqNo) { printf("Received Ack\n"); switch(sendNextPacket[senderNode]) { case WAIT_ACK: sendNextPacket[senderNode]= IN_PROGRESS; printf("Sent IN_PROGRESS\n"); break; case LAST_PACKET_ACK: printf("Sent end_PROGRESS\n"); sendNextPacket[senderNode] = END; break; default: printf("Error shouldn't have entered here"); break; } } break; default: break; } } bmac_rx_pkt_release (); nrk_wait_until_next_period(); } // pointing the function pointer to the copied code in the flash }
// Run update Mode Protocol void updateMode() { // Set destination val=bmac_addr_decode_set_my_mac(((uint16_t)my_subnet_mac<<8)|my_mac); val=bmac_addr_decode_dest_mac(((uint16_t)dest_mac[1]<<8)|dest_mac[0]); bmac_addr_decode_enable(); while(programState == UPDATE) { // Build tx packet by txState buildTxPkt(); nrk_led_toggle (BLUE_LED); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Send with hardware acknowledgement. while(1) { val = bmac_tx_pkt (tx_buf, len); // Break if message ack recieved or is a broadcast if(val == NRK_OK){ nrk_kprintf(PSTR("Packet Sent\r\n")); break; } else{ nrk_kprintf(PSTR("Packet ReSent\r\n")); } // Resend if ack not recieved nrk_wait_until_next_period(); } #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nSent Request:\r\n")); #endif nrk_led_clr (BLUE_LED); nrk_led_clr(GREEN_LED); // Wait if reply expected / Change TX state if not //*********************************************************** if(needReply == FALSE) { // Change TX state, update page number changeState(); } else { // Wait for packets or timeout #ifdef TXT_DEBUG nrk_kprintf (PSTR ("\r\nExpecting Reply\r\n")); #endif timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = REPLY_WAIT_NANOSECS; nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); nrk_led_clr (ORANGE_LED); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("Recieved Reply\r\n")); #endif // Handle recieved packet updateReplyRecieved(); } else { #ifdef TXT_DEBUG nrk_kprintf (PSTR ("Timed Out Waiting for response...\r\n")); #endif } } nrk_wait_until_next_period(); } }
void nl_rx_task() { uint8_t len; // to hold the size of the received packet, always = sizeof(NW_Packet) int8_t rssi; // to hold rssi of received packet uint8_t *local_rx_buf; // pointer to receive buffer of link layer int8_t val; // status variable to hold the return type of function calls int8_t flag; nrk_time_t start, end, elapsed; // needed by nl_rx_task() // to decide when to send own NGB_LIST if(DEBUG_NL >= 1) { nrk_kprintf(PSTR("NL_RX_TASK PID = ")); printf("%d\r\n",nrk_get_pid()); } // initialise the timer nrk_time_get(&start); end.secs = start.secs; end.nano_secs = start.nano_secs; // initialise the link layer val = bmac_init(25); if(val == NRK_ERROR) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by bmac_init()\r\n")); } // give the link layer a rx buffer val = bmac_rx_pkt_set_buffer(rx_buf, RF_BUFFER_SIZE); if(val == NRK_ERROR) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by bmac_rx_pkt_set_buffer()\r\n")); } // start processing forever while(1) { // decide whether it is time to send your own Ngb_List message if(CONNECTED_TO_GATEWAY == TRUE) { nrk_time_get(&end); val = nrk_time_sub(&elapsed, end, start); nrk_time_compact_nanos(&elapsed); if(elapsed.secs >= NGB_LIST_PERIOD) { ntg_pkt.type = SERIAL_NGB_LIST; ntg_pkt.length = SIZE_MSG_NGB_LIST; enter_cr(nl_sem, 34); pack_Msg_NgbList(ntg_pkt.data, &nl); leave_cr(nl_sem, 34); pack_NodeToGatewaySerial_Packet_header(to_gw_buf, &ntg_pkt); memcpy(to_gw_buf + SIZE_NODETOGATEWAYSERIAL_PACKET_HEADER, ntg_pkt.data, MAX_SERIAL_PAYLOAD); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("Sending own NGB_LIST message to gateway\r\n")); } sendToSerial(to_gw_buf, SIZE_NODETOGATEWAYSERIAL_PACKET); // reset the timer start.secs = end.secs; start.nano_secs = end.nano_secs; } // end if } // end if if(DEBUG_NL >= 1) { nrk_kprintf(PSTR("Waiting for next pkt from link layer\r\n")); } flag = 0; // wait for the next packet while(bmac_rx_pkt_ready() == 0) { val = bmac_wait_until_rx_pkt(); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: bmac_wait_until_rx_packet() returned ")); printf("%d\n", val); } } // Get the packet do { local_rx_buf = bmac_rx_pkt_get(&len,&rssi); if(local_rx_buf == NULL) { nrk_kprintf(PSTR("NL: NULL returned by bmac_rx_pkt_get()\r\n")); } } while(local_rx_buf == NULL); // sanity check for debugging if(len != SIZE_NW_PACKET) // this should not happen { /* nrk_int_disable(); nrk_led_set(RED_LED); while(1) { nrk_kprintf(PSTR("NL: Wrong length of packet received: ")); printf("%d\r\n", len); } */ if(DEBUG_NL >= 1) { nrk_kprintf(PSTR("NL: nl_rx_task(): Wrong length of packet received: ")); printf("%d\r\n", len); } flag = 1; } nrk_led_set(GREEN_LED); if(DEBUG_NL == 2)// || flag == 1) { int8_t i; nrk_kprintf(PSTR("NL: Contents of received packet are\r\n")); printf("["); for(i = 0; i < len; i++) printf("%d ", local_rx_buf[i]); printf("]\r\n"); } if(flag == 1) { bmac_rx_pkt_release(); // drop the packet and go receive another nrk_led_clr(GREEN_LED); continue; } // unpack the packet header from the received buffer unpack_NW_Packet_header(&pkt_rx, local_rx_buf); // copy the packet payload to the data field of the local packet memcpy(pkt_rx.data, local_rx_buf + SIZE_NW_PACKET_HEADER, MAX_NETWORK_PAYLOAD); // Release the RX buffer quickly so future packets can arrive bmac_rx_pkt_release(); // begin processing this packet if(pkt_type(&pkt_rx) == APPLICATION) // its an application layer packet { // case 1: Destination is NODE_ADDR or BCAST_ADDR if(pkt_rx.dest == NODE_ADDR || pkt_rx.dest == BCAST_ADDR) process_app_pkt(&pkt_rx, rssi); // case 2: I am enroute to the destination else if(pkt_rx.nextHop == NODE_ADDR) { if(pkt_rx.src == NODE_ADDR) // routing table corrupted { nrk_int_disable(); nrk_led_set(RED_LED); while(1) { nrk_kprintf(PSTR("Routing table corrupted at ")); printf("%d\r\n", NODE_ADDR); } // end while } // end if else route_packet(&pkt_rx); } // end if // case 3: Routing tables still not made else if(pkt_rx.nextHop == BCAST_ADDR) route_packet(&pkt_rx); else ; // drop all other packets } // end if(type == APPLICATION) else { if(pkt_type(&pkt_rx) == NW_CONTROL) // its a network control packet { // case 1: Destination is NODE_ADDR or BCAST_ADDR if(pkt_rx.dest == NODE_ADDR || pkt_rx.dest == BCAST_ADDR) process_nw_ctrl_pkt(&pkt_rx, rssi); // case 2: I am enroute to a destination else if(pkt_rx.nextHop == NODE_ADDR) { if(pkt_rx.src == NODE_ADDR) // routing table corrupted { nrk_int_disable(); nrk_led_set(RED_LED); while(1) { nrk_kprintf(PSTR("Routing table corrupted at ")); printf("%d\r\n", NODE_ADDR); } // end while } // end if else route_packet(&pkt_rx); } // end if // case 3: Routing tables still not made else if(pkt_rx.nextHop == BCAST_ADDR) route_packet(&pkt_rx); else ; // drop all other packets } // end if(type == NW_CONTROL) else // unknown packet type { nrk_kprintf(PSTR("NL: Unknown pkt type received = ")); printf("%d\r\n", pkt_type(&pkt_rx)); } } nrk_led_clr(GREEN_LED); } // end while(1) return; } // end nl_rx_task
void tx_task () { uint8_t i, unique; uint8_t samples ; uint8_t len; int8_t rssi, val; uint8_t *local_rx_buf; nrk_sig_t tx_done_signal; nrk_sig_t rx_signal; nrk_time_t check_period; nrk_time_t timeout, start, current; nrk_sig_mask_t my_sigs; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... bmac_init (26); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); val = bmac_addr_decode_set_my_mac (((uint16_t) MY_SUBNET_MAC_0 << 8) | MY_MAC ); val = bmac_addr_decode_dest_mac (0xffff); // broadcast by default bmac_addr_decode_enable (); nrk_kprintf (PSTR ("bmac_started()\r\n")); bmac_set_cca_thresh (-45); check_period.secs = 0; check_period.nano_secs = 100 * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); rx_signal = bmac_get_rx_pkt_signal (); nrk_signal_register (rx_signal); cnt = 0; check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Main loop that does: // 1) Sends out ping message // 2) Collects replies, build neighbor list and then times out // 3) Repeat 1 and 2 for 3 times // 4) Build Extended Neighborlist packet // 5) Send Neighbor list packet // 6) Wait until next period and repeat 1-6 while (1) { nrk_led_clr (ORANGE_LED); // Set our local neighbor list to be empty my_nlist_elements = 0; for (samples = 0; samples < 3; samples++) { nrk_led_set (GREEN_LED); check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); // Construct a ping packet to send (this is being built into tx_buf) build_ping_pkt (&p2p_pkt); // Pack data structure values in buffer before transmit pack_peer_2_peer_packet (&p2p_pkt); // Send the Ping packet val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); // Set update rate based on p2p reply rate. // This is usually faster to limit congestion check_period.secs = 0; check_period.nano_secs = p2p_pkt.check_rate * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); #ifdef TXT_DEBUG nrk_kprintf (PSTR ("Pinging...\r\n")); #endif nrk_led_clr (GREEN_LED); // Grab start time for timeout nrk_time_get (&start); while (1) { // Set the amount of time to wait for timeout timeout.secs = REPLY_WAIT_SECS; timeout.nano_secs = 0; // Check if packet is already ready, or wait until one arrives // Also set timeout to break from function if no packets come my_sigs=0; if (bmac_rx_pkt_ready () == 0) { nrk_set_next_wakeup (timeout); my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal)); } if (my_sigs == 0) nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n")); if (my_sigs & SIG (rx_signal)) { // Get the RX packet local_rx_buf = bmac_rx_pkt_get (&len, &rssi); // Check the packet type from raw buffer before unpacking if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) { // Setup a p2p packet data structure with the newly received buffer p2p_pkt.buf = local_rx_buf; p2p_pkt.buf_len = len; p2p_pkt.rssi = rssi; // Unpack the data from the array into the p2p_pkt data struct unpack_peer_2_peer_packet (&p2p_pkt); // Check if newly received packet is for this node if (((p2p_pkt.dst_subnet_mac[2] == MY_SUBNET_MAC_2 && p2p_pkt.dst_subnet_mac[1] == MY_SUBNET_MAC_1 && p2p_pkt.dst_subnet_mac[0] == MY_SUBNET_MAC_0 && p2p_pkt.dst_mac == MY_MAC ) || p2p_pkt.dst_mac == BROADCAST) && (p2p_pkt.pkt_type == PING_PKT)) { // Packet arrived and is ping pkt! // Lets print some values out on the terminal printf ("full mac: %d %d %d %d ", p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2], p2p_pkt.src_mac); printf ("rssi: %d ", p2p_pkt.rssi); printf ("type: %d ", p2p_pkt.pkt_type); nrk_kprintf (PSTR ("payload: [")); for (i = 0; i < p2p_pkt.payload_len; i++) printf ("%d ", p2p_pkt.payload[i]); nrk_kprintf (PSTR ("]\r\n")); unique = 1; // Check if the MAC of this ping is unique or if it already // exists in our neighbor list for (i = 0; i < my_nlist_elements; i++) { if (my_nlist[i * NLIST_SIZE] == p2p_pkt.src_subnet_mac[2] && my_nlist[i * NLIST_SIZE + 1] == p2p_pkt.src_subnet_mac[1] && my_nlist[i * NLIST_SIZE + 2] == p2p_pkt.src_subnet_mac[0] && my_nlist[i * NLIST_SIZE + 3] == p2p_pkt.src_mac) { unique = 0; break; } } // If MAC is unique, add it to our neighbor list if (unique) { my_nlist[my_nlist_elements * NLIST_SIZE] = p2p_pkt.src_subnet_mac[2]; my_nlist[my_nlist_elements * NLIST_SIZE + 1] = p2p_pkt.src_subnet_mac[1]; my_nlist[my_nlist_elements * NLIST_SIZE + 2] = p2p_pkt.src_subnet_mac[0]; my_nlist[my_nlist_elements * NLIST_SIZE + 3] = p2p_pkt.src_mac; my_nlist[my_nlist_elements * NLIST_SIZE + 4] = p2p_pkt.rssi; my_nlist_elements++; } } } } // Check if we are done waiting for pings nrk_time_get (¤t); if (start.secs + REPLY_WAIT_SECS < current.secs) break; // exit loops waiting for pings // Release the RX buffer so future packets can arrive bmac_rx_pkt_release (); // Go back to top loop to wait for more pings } cnt++; // Repeat ping 3 times } // Now we are ready to build extended neighborlist packet and send it to gateway check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * NANOS_PER_MS; val = bmac_set_rx_check_rate (check_period); nrk_kprintf (PSTR ("Done Waiting for response...\r\n")); // If we have any neighbors, build the list if (my_nlist_elements > 0) { // Look in this function for format of extended neighborlist packet // This function also configures the parameters and destination address // of the p2p packet. The values are probably okay as defaults. build_extended_neighbor_list_pkt (&p2p_pkt, my_nlist, my_nlist_elements); // This function takes at p2p struct and packs it into an array for sending pack_peer_2_peer_packet (&p2p_pkt); nrk_led_set (BLUE_LED); // Send the list to the gateway. val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len); printf ("size of pkt: %d\r\n", p2p_pkt.buf_len); nrk_kprintf (PSTR ("sent neighbor list packet\r\n")); nrk_led_clr (BLUE_LED); } else { nrk_led_set (RED_LED); nrk_spin_wait_us (1000); nrk_led_clr (RED_LED); } // Wait a long time until we send out the pings again // This is in a loop so that period can be small for // other uses. for (i = 0; i < 10; i++) nrk_wait_until_next_period (); // Might as well release packets that arrived during long // break since they are not replies to your ping. bmac_rx_pkt_release (); } }