static void periodic_task() { nrk_sig_mask_t wait_mask, func_wait_mask; nrk_time_t next_event, func_next_event; periodic_func_t **funcp; periodic_func_t *func; nrk_time_t now, sleep_time; int8_t rc; funcp = &functions[0]; while (*funcp) { func = *funcp; LOG("init: "); LOGF(func->name); LOGNL(); if (func->init) func->init(); funcp++; } rc = nrk_signal_register(func_signal); if (rc == NRK_ERROR) ABORT("reg sig: func\r\n"); while (1) { LOG("awake\r\n"); TIME_CLEAR(next_event); wait_mask = SIG(func_signal); funcp = &functions[0]; while (*funcp) { func = *funcp; TIME_CLEAR(func_next_event); func_wait_mask = 0; if (func->enabled || func->enabled != func->last_enabled) { LOG("proc: "); LOGF(func->name); LOGNL(); ASSERT(func->proc); func->proc(func->enabled, &func_next_event, &func_wait_mask); } func->last_enabled = func->enabled; wait_mask |= func_wait_mask; if (IS_VALID_TIME(func_next_event) && (!IS_VALID_TIME(next_event) || time_cmp(&func_next_event, &next_event) < 0)) { next_event = func_next_event; } funcp++; } if (IS_VALID_TIME(next_event)) { nrk_time_get(&now); rc = nrk_time_sub(&sleep_time, next_event, now); if (rc != NRK_OK) { LOG("next event in the past\r\n"); continue; } LOG("sleeping for: "); LOGP("%lu ms\r\n", TIME_TO_MS(sleep_time)); nrk_set_next_wakeup(sleep_time); wait_mask |= SIG(nrk_wakeup_signal); } LOG("waiting\r\n"); nrk_event_wait( wait_mask ); } ABORT("periodic task exited\r\n"); }
// 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_tx_task() { TransmitBuffer *ptr = NULL; // pointer to the buffer to be transmitted nrk_sig_t tx_done_signal; // to hold the tx_done signal from the link layer int8_t ret; // to hold the return value of various functions int8_t port_index; // to store the index of the corresponding port element int8_t sent; // to count the number of times the HELLO msg was sent int8_t isApplication; // flag to indicate whether the packet in the transmit // buffer is an APPLICATION / NW_CONTROL packet nrk_time_t timeout; nrk_time_t start; // used for sending network control messages nrk_time_t end; nrk_time_t elapsed; // wait for the nl_rx_task to start bmac while(!bmac_started()) nrk_wait_until_next_period(); // retrieve and register for the 'transmit done' signal from bmac tx_done_signal = bmac_get_tx_done_signal(); if( nrk_signal_register(tx_done_signal) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error while registering for the bmax_tx_done_signal\r\n")); } // initialise the timer nrk_time_get(&start); end.secs = start.secs; end.nano_secs = start.nano_secs; sent = 0; // set the radio power if( bmac_set_rf_power(10) == NRK_ERROR) { nrk_led_set(RED_LED); nrk_int_disable(); while(1) nrk_kprintf(PSTR("Error setting the transmit power\r\n")); } while(1) { isApplication = FALSE; // assume at the beginning that a nw_ctrl pkt will be transmitted ret = nrk_time_sub(&elapsed, end, start); if(ret == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_time_sub\r\n")); } nrk_time_compact_nanos(&elapsed); if(elapsed.secs >= HELLO_PERIOD) { sent++; build_Msg_Hello(&mhe); // build the 'HELLO' message if(DEBUG_NL == 2) { nrk_kprintf(PSTR("After building Msg_Hello, packet = ")); print_pkt(&pkt_tx); } enter_cr(bm_sem, 34); ret = insert_tx_aq(&pkt_tx); // insert it into the transmit queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("build_Msg_Hello() inserted packet.")); print_tx_buffer(); //print_pkt_header(&pkt_tx); } if(ret == NRK_ERROR && DEBUG_NL == 2) { nrk_kprintf(PSTR("HELLO msg was not inserted into the transmit queue\r\n")); } start.secs = end.secs; start.nano_secs = end.nano_secs; // reinitialise the timer } if(sent >= 3) //NGB_LIST_PERIOD / HELLO_PERIOD) // NGB_LIST period is always a multiple of HELLO_PERIOD { build_Msg_NgbList(&mn); // build the 'NGB_LIST' message enter_cr(bm_sem, 34); ret = insert_tx_aq(&pkt_tx); // insert it into the transmit queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("build_Msg_NgbList() inserted packet.")); print_tx_buffer(); //print_pkt_header(&pkt_tx); } if(ret == NRK_ERROR && DEBUG_NL == 2) { nrk_kprintf(PSTR("NGB_LIST msg was not inserted into the transmit queue\r\n")); } sent = 0; // reset the value of 'sent' } if(rand() % 2 == 0) // random number generator collect_queue_statistics(); enter_cr(bm_sem, 34); ptr = remove_tx_aq(); leave_cr(bm_sem, 34); if(ptr == NULL) // transmit queue is empty { if(DEBUG_NL == 2) nrk_kprintf(PSTR("NL:Transmit queue is empty\r\n")); // update the end time nrk_time_get(&end); nrk_wait_until_next_period(); // FIX ME continue; } if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Packet removed. Packet = ")); //print_pkt_header( &(ptr -> pkt) ); print_pkt( &(ptr -> pkt) ); //print_tx_buffer(); } // check to see the type of packet. It should be of type APPLICATION and be sent by this // node if( (pkt_type(&(ptr -> pkt)) == APPLICATION) && ((ptr -> pkt).src == NODE_ADDR) ) { // remove the encapsulated TL segment from the packet unpack_TL_UDP_header(&seg, (ptr -> pkt).data); memcpy(seg.data, (ptr -> pkt).data + SIZE_TRANSPORT_UDP_HEADER, MAX_APP_PAYLOAD); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Segment Removed = ")); print_seg(&seg); } isApplication = TRUE; } // pack the network packet header into the transmit buffer pack_NW_Packet_header(tx_buf, &(ptr -> pkt)); // append the network payload into the transmit buffer memcpy(tx_buf + SIZE_NW_PACKET_HEADER, (ptr -> pkt).data, MAX_NETWORK_PAYLOAD); enter_cr(bm_sem, 34); insert_tx_fq(ptr); // release the transmit buffer into the free queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Released transmit buffer back into queue\n")); print_tx_buffer(); } do { ret = bmac_tx_pkt_nonblocking(tx_buf, SIZE_NW_PACKET); // try to queue the buffer in link layer if(ret == NRK_ERROR) if(nrk_event_wait(SIG(tx_done_signal)) == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n")); } }while(ret == NRK_ERROR); // packet is queued at link layer timeout.secs = 10; // set a wait period of maximum 10 seconds timeout.nano_secs = 0; if( nrk_signal_register(nrk_wakeup_signal) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL:nl_tx(): Error registering for nrk_wakeup_signal\r\n")); } if( nrk_set_next_wakeup(timeout) == NRK_ERROR) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx(): Error returned by nrk_set_next_wakeup()\r\n")); } nrk_led_set(BLUE_LED); ret = nrk_event_wait (SIG(tx_done_signal) | SIG(nrk_wakeup_signal)); // wait for its transmission if(ret == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n")); } if(ret & SIG(tx_done_signal)) // bmac has successfully sent the packet over the radio { if(isApplication == TRUE) // it was an application layer packet { enter_cr(tl_sem, 34); port_index = port_to_port_index(seg.srcPort); if(port_index == NRK_ERROR) // sanity check { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in implementation of port element array\r\n")); } // signal 'send done' signal if(nrk_event_signal(ports[port_index].send_done_signal) == NRK_ERROR) { if(nrk_errno_get() == 1) // sanity check. This means signal was not created { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in creating signals in port element array\r\n")); } } leave_cr(tl_sem, 34); }// end if(isApplication == TRUE) else // a network control message was transmitted. Nothing to signal ; // do nothing } // end if(signal received = tx_done_signal) else if(ret & SIG(nrk_wakeup_signal)) { //nrk_led_set(RED_LED); //nrk_int_disable(); //while(1) //{ nrk_kprintf(PSTR("BMAC did not transmit the packet within specified time\r\n")); //} } else // unknown signal caught { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task(): Unknown signal caught\r\n")); } nrk_led_clr(BLUE_LED); // update the end time nrk_time_get(&end); } // end while(1) return; }
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 (); } }
inline PmReturn_t pymite() { PmReturn_t retval; bmac_init(14); bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE); bmac_addr_decode_enable(); //set MAC bmac_addr_decode_set_my_mac(MAC_ADDR); // sdp testing sdp_init(MAC_ADDR); uint8_t destId = 1; nrk_time_t wait; wait.secs = 1; wait.nano_secs = 0; int sel = 0; for (;; sel = (sel + 1) % 2) { uint8_t *script = slave_img; for (int i = 0; i < SLAVE_COUNT; i++) { destId = slaves[i]; printf("Sending a script to a node=%x\r\n", destId); /*for (i = 0; i < SDP_MAX_SCRIPT_SIZE; i++) { printf("%x ", script[i]); }*/ int8_t status = sdp_tx_send_script(script, destId, SDP_MAX_SCRIPT_SIZE); // see if script was delivered if(status == NRK_ERROR) nrk_kprintf(PSTR("Script not delivered.\r\n")); else nrk_kprintf(PSTR("Script delivered.\r\n")); // wait to send again nrk_set_next_wakeup(wait); nrk_event_wait(SIG(nrk_wakeup_signal)); } retval = pm_init(MEMSPACE_RAM, usrlib_img); retval = pm_run((uint8_t *)"main"); printf("exit code %x\r\n", retval); } printf("f**k MAC_ADDR=%x\r\n", MAC_ADDR); //PM_RETURN_IF_ERROR(retval); int i; for (i = 0; i < 100000; i++) { i++; i--; } }
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 (); } }