int main (int argc, char *argv[]) { FILE *fp; uint8_t tx_buf[128]; uint8_t rx_buf[128]; TRANSDUCER_PKT_T tran_pkt; TRANSDUCER_MSG_T tran_msg; int32_t v,cnt,i,len,j; uint8_t nav_time_secs, reply_time_secs; int32_t tmp; time_t reply_timeout,nav_timeout,t; uint8_t cmd,error; char buf[1024]; char mbuf[128]; uint8_t num_msgs,p2p_mode,echo; FF_POWER_ACTUATE_PKT ff_pwr_actuate[10]; uint8_t ff_pwr_actuate_mac[10]; uint8_t ff_pwr_actuate_ack[10]; debug_txt_flag=0; p2p_mode=0; if (argc < 6 ) { printf ("Usage: server port num-msgs [mac-addr socket state] [-m or p]\n"); printf (" ex: %s localhost 5000 1 0x000000f0 1 on\n",argv[0]); printf (" mac-addr MAC address of node to actuate\n"); printf (" socket 0 or 1\n"); printf (" state on or off\n"); printf (" -d debug mode\n"); printf (" -m multi-cast\n"); printf (" -p P2P packet mode\n"); exit (1); } for(i=0; i<argc; i++ ) { // Grab dash command line options if(strstr(argv[i],"-d")!=NULL ) debug_txt_flag=1; if(strcmp(argv[i],"-p")==0) p2p_mode=1; if(strcmp(argv[i],"-m")==0) p2p_mode=0; } sscanf( argv[3],"%d",&tmp); num_msgs=tmp; if(p2p_mode==1 && num_msgs!=1 ) { printf( "Error: Can't send multi-cast p2p message\n" ); return -1; } if(num_msgs>9 ) { printf( "Sorry, too many messages...\n" ); return 0; } if(debug_txt_flag==1) printf( "Composing %d actuation msgs\n", num_msgs ); for(i=0; i<num_msgs; i++ ) { sscanf( argv[(i*3)+4],"%x",&tmp ); subnet_3=(tmp&0xff000000) >> 24; subnet_2=(tmp&0xff0000) >> 16; subnet_1=(tmp&0xff00) >> 8; ff_pwr_actuate_mac[i]=(tmp & 0xff); ff_pwr_actuate_ack[i]=0; if(debug_txt_flag==1) printf( "MAC_ADDR: 0x%x ",ff_pwr_actuate_mac[i]); sscanf( argv[(i*3)+5],"%d",&tmp ); if(debug_txt_flag==1) printf( " socket 0 " ); ff_pwr_actuate[i].socket0_state=SOCKET_HOLD; ff_pwr_actuate[i].socket1_state=SOCKET_HOLD; if( strstr(argv[(i*3)+6],"on")!=NULL ) { if(tmp==0) ff_pwr_actuate[i].socket0_state=SOCKET_ON; else ff_pwr_actuate[i].socket1_state=SOCKET_ON; } else { if(tmp==0) ff_pwr_actuate[i].socket0_state=SOCKET_OFF; else ff_pwr_actuate[i].socket1_state=SOCKET_OFF; } if(debug_txt_flag==1) { printf( "Socket MAC %d\n",ff_pwr_actuate_mac[i] ); printf( " Socket 0: %d\n",ff_pwr_actuate[i].socket0_state ); printf( " Socket 1: %d\n",ff_pwr_actuate[i].socket1_state ); } } v=slipstream_open(argv[1],atoi(argv[2]),NONBLOCKING); nav_time_secs=25; cnt = 0; while (1) { error=0; cmd=0; retry: // Setup the packet to send out to the network if(!p2p_mode) { // These values setup the internal data structure and probably don't // need to be changed ds_pkt.payload_len=0; ds_pkt.buf=tx_buf; ds_pkt.buf_len=DS_PAYLOAD_START; ds_pkt.payload_start=DS_PAYLOAD_START; ds_pkt.payload=&(tx_buf[DS_PAYLOAD_START]); // These are parameters that can be adjusted for different packets //ds_pkt.pkt_type=PING_PKT; ds_pkt.pkt_type=TRANSDUCER_PKT; ds_pkt.ctrl_flags= DS_MASK | DEBUG_FLAG | ENCRYPT; //srand(time(NULL)); //ds_pkt.seq_num=rand()%255; // Use the gateway's spiffy auto-cnt when set to 0 ds_pkt.seq_num=0; // Use the gateway's spiffy auto-cnt when set to 0 if(debug_txt_flag==1) printf( "rand seq-num=%d\n",ds_pkt.seq_num ); ds_pkt.priority=0; ds_pkt.ack_retry=10; ds_pkt.subnet_mac[0]=subnet_1; ds_pkt.subnet_mac[1]=subnet_2; ds_pkt.subnet_mac[2]=subnet_3; ds_pkt.hop_cnt=0; // Starting depth, always keep at 0 ds_pkt.hop_max=5; // Max tree depth ds_pkt.delay_per_level=0; // Reply delay per level in seconds ds_pkt.nav=0; // Time in seconds until next message to be sent ds_pkt.mac_check_rate=100; // B-mac check rate in ms ds_pkt.rssi_threshold=-45; // Reply RSSI threshold ds_pkt.last_hop_mac=0; ds_pkt.mac_filter_num=0; // Increase if MAC_FILTER is active ds_pkt.aes_ctr[0]=0; // Encryption AES counter ds_pkt.aes_ctr[1]=0; ds_pkt.aes_ctr[2]=0; ds_pkt.aes_ctr[3]=0; } else { // These values setup the internal data structure and probably don't // need to be changed p2p_pkt.payload_len=0; p2p_pkt.buf=tx_buf; p2p_pkt.buf_len=P2P_PAYLOAD_START; p2p_pkt.payload_start=P2P_PAYLOAD_START; p2p_pkt.payload=&(tx_buf[P2P_PAYLOAD_START]); // These are parameters that can be adjusted for different packets //p2p_pkt.pkt_type=PING_PKT; p2p_pkt.pkt_type=TRANSDUCER_PKT; p2p_pkt.ctrl_flags= MOBILE_MASK | LINK_ACK | DEBUG_FLAG | ENCRYPT; p2p_pkt.seq_num=0; // Use the gateway's spiffy auto-cnt when set to 0 //p2p_pkt.seq_num=rand()%255; // Use the gateway's spiffy auto-cnt when set to 0 if(debug_txt_flag==1) printf( "rand seq-num=%d\n",p2p_pkt.seq_num ); p2p_pkt.priority=0; p2p_pkt.hop_cnt=0; p2p_pkt.ttl=5; p2p_pkt.ack_retry=10; 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=0; p2p_pkt.last_hop_mac=0; p2p_pkt.next_hop_mac=BROADCAST; p2p_pkt.dst_subnet_mac[0] = subnet_1; p2p_pkt.dst_subnet_mac[1] = subnet_2; p2p_pkt.dst_subnet_mac[2] = subnet_3; p2p_pkt.dst_mac = ff_pwr_actuate_mac[0]; p2p_pkt.check_rate=100; // B-mac check rate in ms } // At the top level you have a SAMPL packet (ds_pkt) // For transducers, this holds a single transducer pkt (tran_pkt) // Each transducer packet contains multiple transducer messages (tran_msg) // Transducers typically have helper functions used to pack the transducer messages. // Setup Transducer Packet tran_pkt.num_msgs=0; tran_pkt.checksum=0; tran_pkt.msgs_payload=buf; for(i=0; i<num_msgs; i++ ) { // Setup Transducer Message tran_msg.mac_addr = ff_pwr_actuate_mac[i]; tran_msg.type = TRAN_POWER_PKT; tran_msg.len = 0; tran_msg.payload = mbuf; // Pack application specifc message into transducer message tran_msg.len=ff_power_actuate_pack(mbuf, &(ff_pwr_actuate[i])); // Add the transducer message to the transducer packet len=transducer_msg_add( &tran_pkt, &tran_msg); // printf( "payload = " ); // for(j=0; j<len; j++ ) // printf( "%d ",ds_pkt.payload[j] ); // printf( "\n" ); } if(!p2p_mode) { // Add the packet to the payload ds_pkt.payload_len = transducer_pkt_pack(&tran_pkt, ds_pkt.payload); // This takes the structure and packs it into the raw // array that is sent using SLIP pack_downstream_packet( &ds_pkt); // Add MAC filter entries below // downstream_packet_add_mac_filter( &ds_pkt, 0x07 ); // downstream_packet_add_mac_filter( &ds_pkt, 3 ); // downstream_packet_add_mac_filter( &ds_pkt, 4 ); // downstream_packet_add_mac_filter( &ds_pkt, 5 ); // Print your packet on the screen if(debug_txt_flag==1) print_ds_packet(&ds_pkt ); if(error==0) v=slipstream_send(ds_pkt.buf,ds_pkt.buf_len); //nav_time_secs=ds_pkt.nav; nav_time_secs=5; reply_time_secs=ds_pkt.delay_per_level * ds_pkt.hop_max; } else { p2p_pkt.payload_len = transducer_pkt_pack(&tran_pkt,p2p_pkt.payload); // This takes the structure and packs it into the raw // array that is sent using SLIP pack_peer_2_peer_packet( &p2p_pkt); if(error==0) v=slipstream_send(p2p_pkt.buf,p2p_pkt.buf_len); if(debug_txt_flag==1) { if (v == 0) printf( "Error sending\n" ); else printf( "Sent request %d\n",p2p_pkt.seq_num); } nav_time_secs=10; reply_time_secs=10; } if(debug_txt_flag==1) { if (v == 0) printf( "Error sending\n" ); else printf( "Sent request %d\n",cnt); } t=time(NULL); reply_timeout=t+reply_time_secs+1; nav_timeout=t+nav_time_secs; echo=0; while (nav_timeout > time (NULL)) { v = slipstream_receive (rx_buf); if (v > 0) { if (check_for_ack(rx_buf,v, ff_pwr_actuate_mac[0], p2p_pkt.seq_num)==1 ) { printf( "ACK\n" ); return 1; } } usleep (1000); } cnt++; if(cnt>2) break; } printf( "NCK\n" ); return 0; }
// This task periodically sends and XMPP message through the gateway // to an arbitrary JID on the network. void tx_task () { uint8_t cnt ; int8_t val; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // 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; // 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 (15); //channel 15 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); cnt = 0; while (1) { // Build an XMPP p2p packet p2p_pkt.pkt_type = XMPP_PKT; p2p_pkt.ctrl_flags = LINK_ACK | MOBILE_MASK; p2p_pkt.ack_retry = 0xf0; p2p_pkt.ttl = 5; 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; // Set destination to be any nearby gateway 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 = 0; 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]); // Create XMPP lite message that includes: // 1) destination JID // 2) Your node's password // 3) timeout value in seconds // 4) Message as a string (only ascii text, no XML delimiters) // // The total size of the packet must be under 110 bytes // CHANGE THIS FIRST! // Setting binary_flag to 1 will convert message into ASCII HEX format // Setting binary_flag to 0 will send ASCII string xp.binary_flag=0; xp.pub_sub_flag=0; xp.explicit_src_jid_flag=0; xp.src_jid_size=0; sprintf (my_passwd, "firefly"); xp.passwd = my_passwd; // This is the mobile node JID's password sprintf (dst_jid, "vrajkuma3"); //sprintf (dst_jid, "*****@*****.**"); // JIDs without the @ symbol are set to the gateway's server xp.dst_jid = dst_jid; // This is the destination of the message sprintf (tst_msg, "omg, I'm trapped in an elevator, lol %d", cnt); xp.msg = tst_msg; // This is the message body xp.timeout = 30; // 30 second timeout for the connection // After 30 seconds, the gateway will log the node out // If you need to login as a different user xp.explicit_src_jid_flag=1; sprintf (src_jid, "vrajkuma2"); xp.src_jid = src_jid; xp.src_jid_size=strlen(src_jid)+1; xp.dst_jid_size=strlen(dst_jid)+1; xp.passwd_size=strlen(my_passwd)+1; xp.msg_size=strlen(tst_msg)+1; // Pack the XMPP data structure into a byte sequence for sending p2p_pkt.payload_len = xmpp_pkt_pack (&xp, p2p_pkt.payload, 0); // Make sure it isn't too long! if (p2p_pkt.payload_len == 0) { nrk_kprintf (PSTR ("XMPP packet too long!\r\n")); nrk_wait_until_next_period (); continue; } cnt++; // Lets print out what we are sending printf ("Msg to: %s\r\n", xp.src_jid); printf (" body: %s\r\n", xp.msg); nrk_led_set (BLUE_LED); // Make sure bmac checkrate is correct check_period.secs = 0; check_period.nano_secs = DEFAULT_CHECK_RATE * 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); nrk_led_clr (BLUE_LED); nrk_led_clr (GREEN_LED); nrk_wait_until_next_period (); } }
int main (int argc, char *argv[]) { FILE *fp; uint8_t tx_buf[128]; uint8_t rx_buf[128]; TRANSDUCER_PKT_T tran_pkt; TRANSDUCER_MSG_T tran_msg; int32_t v,cnt,i,len,j; uint8_t nav_time_secs, reply_time_secs; int32_t tmp; time_t reply_timeout,nav_timeout,t; uint8_t cmd,error; char buf[1024]; char mbuf[128]; uint8_t p2p_mode, retry_flag; uint8_t node_mac_addr; char* lcd_msg; // Message to send to LCD debug_txt_flag=0; p2p_mode=1; retry_flag=0; if(argc < 5 || argc > 7) { printf("Usage: %s server port mac-addr \'message\' [-p] [-d]\n", argv[0]); printf("Example: %s localhost 5000 0x00000001 \'Hello\\nWorld!\' -p\n", argv[0]); printf(" mac-addr MAC address of node to display LCD message\n"); printf(" -p Use P2P packet mode\n"); printf(" -m Multi-cast\n"); printf(" -d Display debugging output\n"); printf(" -r Local Retry, don't use with slip mirror gateway\n"); printf(" -l Use Link ACK routing\n"); exit(1); } // Grab dash command line options if(argc > 5) { for(i = 5; i < argc; i++) { if(strcmp(argv[i], "-p") == 0) { p2p_mode = 1; printf("*P2P Mode Enabled\n"); } if(strcmp(argv[i], "-m") == 0) { p2p_mode = 0; printf("*Multi-cast Mode Enabled\n"); } else if(strcmp(argv[i], "-d") == 0) { debug_txt_flag = 1; printf("*Debug Mode Enabled\n"); } else if(strcmp(argv[i], "-r") == 0) { retry_flag= 1; printf("*Retry Enabled\n"); } } } if (strlen (argv[3]) != 8 && strlen (argv[3]) != 10) { printf ("Invalid MAC address\n"); exit(1); } v = sscanf (argv[3], "%x", &tmp); if (v != 1) { printf ("Invalid MAC address\n"); exit(1); } subnet_3=(tmp&0xff000000) >> 24; subnet_2=(tmp&0xff0000) >> 16; subnet_1=(tmp&0xff00) >> 8; node_mac_addr = tmp & 0xff; v = slipstream_open (argv[1], atoi (argv[2]), NONBLOCKING); // Set pointer to message lcd_msg = (char*)argv[4]; nav_time_secs = 25; cnt = 0; while (1) { error=0; cmd=0; retry: // Setup the packet to send out to the network if(!p2p_mode) { // These values setup the internal data structure and probably don't // need to be changed ds_pkt.payload_len=0; ds_pkt.buf=tx_buf; ds_pkt.buf_len=DS_PAYLOAD_START; ds_pkt.payload_start=DS_PAYLOAD_START; ds_pkt.payload=&(tx_buf[DS_PAYLOAD_START]); // These are parameters that can be adjusted for different packets //ds_pkt.pkt_type=PING_PKT; ds_pkt.pkt_type=TRANSDUCER_PKT; ds_pkt.ctrl_flags= DS_MASK | DEBUG_FLAG | ENCRYPT; //srand(time(NULL)); //ds_pkt.seq_num=rand()%255; // Use the gateway's spiffy auto-cnt when set to 0 ds_pkt.seq_num=0; // Use the gateway's spiffy auto-cnt when set to 0 if(debug_txt_flag==1) printf( "rand seq-num=%d\n",ds_pkt.seq_num ); ds_pkt.priority=0; ds_pkt.ack_retry=10; ds_pkt.subnet_mac[0]=subnet_1; ds_pkt.subnet_mac[1]=subnet_2; ds_pkt.subnet_mac[2]=subnet_3; ds_pkt.hop_cnt=0; // Starting depth, always keep at 0 ds_pkt.hop_max=7; // Max tree depth ds_pkt.delay_per_level=0; // Reply delay per level in seconds ds_pkt.nav=0; // Time in seconds until next message to be sent ds_pkt.mac_check_rate=100; // B-mac check rate in ms ds_pkt.rssi_threshold=-35; // Reply RSSI threshold ds_pkt.last_hop_mac=0; ds_pkt.mac_filter_num=0; // Increase if MAC_FILTER is active ds_pkt.aes_ctr[0]=0; // Encryption AES counter ds_pkt.aes_ctr[1]=0; ds_pkt.aes_ctr[2]=0; ds_pkt.aes_ctr[3]=0; } else { // These values setup the internal data structure and probably don't // need to be changed p2p_pkt.payload_len=0; p2p_pkt.buf=tx_buf; p2p_pkt.buf_len=P2P_PAYLOAD_START; p2p_pkt.payload_start=P2P_PAYLOAD_START; p2p_pkt.payload=&(tx_buf[P2P_PAYLOAD_START]); // These are parameters that can be adjusted for different packets //p2p_pkt.pkt_type=PING_PKT; p2p_pkt.pkt_type=TRANSDUCER_PKT; // p2p_pkt.ctrl_flags= MOBILE_MASK | /*LINK_ACK |*/ DEBUG_FLAG | ENCRYPT; p2p_pkt.ctrl_flags= MOBILE_MASK | LINK_ACK | DEBUG_FLAG | ENCRYPT; //p2p_pkt.ctrl_flags= MOBILE_MASK | DEBUG_FLAG | ENCRYPT; p2p_pkt.seq_num=0; // Use the gateway's spiffy auto-cnt when set to 0 //p2p_pkt.seq_num=rand()%255; // Use the gateway's spiffy auto-cnt when set to 0 if(debug_txt_flag==1) printf( "rand seq-num=%d\n",p2p_pkt.seq_num ); p2p_pkt.priority=0; p2p_pkt.hop_cnt=0; p2p_pkt.ttl=7; p2p_pkt.ack_retry=10; 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=0; p2p_pkt.last_hop_mac=0; p2p_pkt.next_hop_mac=BROADCAST; p2p_pkt.dst_subnet_mac[0] = 0; p2p_pkt.dst_subnet_mac[1] = 0; p2p_pkt.dst_subnet_mac[2] = 0; p2p_pkt.dst_mac = node_mac_addr; p2p_pkt.check_rate=100; // B-mac check rate in ms } // At the top level you have a SAMPL packet (ds_pkt) // For transducers, this holds a single transducer pkt (tran_pkt) // Each transducer packet contains multiple transducer messages (tran_msg) // Transducers typically have helper functions used to pack the transducer messages. // Setup Transducer Packet tran_pkt.num_msgs=0; tran_pkt.checksum=0; tran_pkt.msgs_payload=buf; // Build message to send to LCD tran_msg.mac_addr = node_mac_addr; tran_msg.type = TRAN_LCD_MESSAGE; tran_msg.len = strlen(lcd_msg) + 1; for(i = 0; i < tran_msg.len; i++) mbuf[i] = (uint8_t)lcd_msg[i]; tran_msg.payload = mbuf; // Add the transducer message to the transducer packet transducer_msg_add( &tran_pkt, &tran_msg); if(!p2p_mode) { // Add the packet to the payload ds_pkt.payload_len = transducer_pkt_pack(&tran_pkt, ds_pkt.payload); // This takes the structure and packs it into the raw // array that is sent using SLIP pack_downstream_packet( &ds_pkt); // Add MAC filter entries below // downstream_packet_add_mac_filter( &ds_pkt, 0x07 ); // downstream_packet_add_mac_filter( &ds_pkt, 3 ); // downstream_packet_add_mac_filter( &ds_pkt, 4 ); // downstream_packet_add_mac_filter( &ds_pkt, 5 ); // Print your packet on the screen if(debug_txt_flag==1) print_ds_packet(&ds_pkt ); if(error==0) { v=slipstream_send(ds_pkt.buf,ds_pkt.buf_len); for(i=0; i<100; i++ ) { v = slipstream_receive (rx_buf); if(v==1 && rx_buf[0]=='A' ) { printf( "Serial Good\n" ); break;} if(v==1 && rx_buf[0]=='N') { printf( "Serial Error 1\n" ); } usleep(1000); } if(i==100) printf( "Serial Error 2\n" ); } //nav_time_secs=ds_pkt.nav; nav_time_secs=5; reply_time_secs=ds_pkt.delay_per_level * ds_pkt.hop_max; } else { p2p_pkt.payload_len = transducer_pkt_pack(&tran_pkt,p2p_pkt.payload); // This takes the structure and packs it into the raw // array that is sent using SLIP pack_peer_2_peer_packet( &p2p_pkt); if(error==0) { if(retry_flag) v=slipstream_acked_send(p2p_pkt.buf,p2p_pkt.buf_len,3); else v=slipstream_send(p2p_pkt.buf,p2p_pkt.buf_len); } if(debug_txt_flag==1) { if (v == 0) printf( "Serial Error\n" ); else printf( "Sent request %d\n",p2p_pkt.seq_num); } nav_time_secs=5; reply_time_secs=5; } if(debug_txt_flag==1) { if (v == 0) printf( "Error sending\n" ); else printf( "Sent request %d\n",cnt); } //LCD message sent if(v > 0) printf("[%i] Message \'%s\' sent to node 0x%x.\n", cnt, lcd_msg, node_mac_addr); t=time(NULL); reply_timeout=t+reply_time_secs+1; nav_timeout=t+nav_time_secs; while (nav_timeout > time (NULL)) { v = slipstream_receive (rx_buf); if (v > 0) { if (check_for_ack(rx_buf,v, node_mac_addr, p2p_pkt.seq_num)==1 ) { printf( "ACK\n" ); return 1; } } usleep (1000); } cnt++; if(cnt>2) break; } printf( "NCK\n" ); return 0; }
// Build TX pkt by txState void buildTxPkt() { uint32_t addr; uint8_t i,j; // TX protocol switch(txState) { case START: // Send wireless update pkt nrk_kprintf (PSTR ("Build Start Packet\r\n")); // Build a TX packet by hand... p2p_pkt.pkt_type = WIRELESS_UPDATE_PKT; p2p_pkt.ctrl_flags = ENCRYPT; // set as p2p packet (no US_MASK or DS_MASK) p2p_pkt.ack_retry= 0x00; p2p_pkt.ttl = 1; p2p_pkt.check_rate = DEFAULT_CHECK_RATE; // FIXME: add proper subnet later p2p_pkt.src_subnet_mac[0] = dest_mac[1]; p2p_pkt.src_subnet_mac[1] = dest_mac[2]; p2p_pkt.src_subnet_mac[2] = dest_mac[3]; p2p_pkt.src_mac = my_mac; p2p_pkt.last_hop_mac = my_mac; p2p_pkt.dst_mac = dest_mac[0]; p2p_pkt.buf=tx_buf; p2p_pkt.buf_len = P2P_PAYLOAD_START; p2p_pkt.seq_num = cnt; p2p_pkt.priority = 0; // p2p_pkt.payload[0]=my_mac; // p2p_pkt.payload_len=1; // ping_p2p_generate(&p2p_pkt); needReply = TRUE; // Pack data structure values in buffer before transmit pack_peer_2_peer_packet(&p2p_pkt); // Copy in tx buffers len = p2p_pkt.buf_len; for(i=0;i<len;i++) tx_buf[i] = p2p_pkt.buf[i]; break; case INIT: nrk_kprintf (PSTR ("Build Init Packet\r\n")); // Send update tx info, checks // PKT_TYPE = 0 tx_buf[PKT_TYPE] = UNKNOWN_PKT; tx_buf[MSG_TYPE] = INIT_MSG; tx_buf[UP_PAGES] = UpdatePages; tx_buf[UP_LESSB] = UpdateLessBytes; tx_buf[UP_MODE] = UpdateMode; tx_buf[UP_VER] = UpdateVersion; tx_buf[UP_CSUM] = UpdateChecksum; len = CMD_PAYLOAD; // Need a checksum success reply needReply = TRUE; break; case DATA: nrk_kprintf (PSTR ("Build Data Packet\r\n")); // Send image binary // PKT_TYPE = 0 tx_buf[PKT_TYPE] = UNKNOWN_PKT; tx_buf[MSG_TYPE] = DATA_MSG; tx_buf[PG_NUM] = pgNumber; tx_buf[PG_OFF] = pgOffset; // Read page from flash if(pgOffset == 0){ addr = ((uint32_t)pgNumber*(uint32_t)PAGESIZE) + (uint32_t)UPDATE_SECTION; ws_flash_read_page(addr,ph_buf); } // Add data to pkt for(i = 0, j = 0; i < DATA_PAYLOAD; i++, j++){ tx_buf[j + DATA_HEAD] = ph_buf[i + (pgOffset * DATA_PAYLOAD)]; } len = DATA_PAYLOAD + DATA_HEAD; needReply = FALSE; break; case STOP: // Send stop and reboot cmd nrk_kprintf(PSTR("Reboot\r\n")); tx_buf[PKT_TYPE] = UNKNOWN_PKT; tx_buf[MSG_TYPE] = NACK_MSG; len = CMD_PAYLOAD; needReply = FALSE; break; default: nrk_kprintf(PSTR("Error: Invalid Build Pkt State")); break; } }
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 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 (); } }
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 (); } }
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 (); } }