/*---------------------------------------------------------------------------*/ void forwarderActivity() { pmesg(200, "%s :: %s :: Line #%d\n", __FILE__, __func__, __LINE__); //When the forwarder not initialized, do nothing if(!isRunningForwardingEngine) { return; } else if(rootControl_isRoot()) { //As soon as we are root, should have zero virtual queue virtualQueueSize = 0; //The root should always be beaconing if(ctimer_expired(&beacon_timer)) { // If this is the start of the beacon, be agressive! Beacon fast // so neighbors can re-direct rapidly. isBeaconTimerPeriodic = false; ctimer_set(&beacon_timer, FAST_BEACON_TIME, beacon_timer_fired, NULL); timer_reset(&beacon_timerTime); // Reset the tandem timer } // If there are packets sitting in the forwarding queue, get them to the reciever if(list_length(send_stack) == 0) { // Don't need sending set to true here? Not using radio? // NO_SNOOP: set beacon type beaconType = NORMAL_BEACON; process_post(&sendDataTask, NULL, NULL); } return; } else if (sending) { pmesg(100, "ForwardingEngine is already sending\n"); return; } else if (!(list_length(send_stack) == 0) || virtualQueueSize > 0 || sendQeOccupied ) { //Stop Beacon, not needed if we are sending data packets (snoop) #ifndef BEACON_ONLY ctimer_stop(&beacon_timer); // Stop the tandem timer here, but can't because API doesnt provide that functionality #endif // Start sending a data packet sending = true; //NO_SNOOP: set beacon type beaconType = NORMAL_BEACON; process_post(&sendDataTask, NULL, NULL); return; } else{ // Nothing to do but start the beacon! #ifndef BEACON_ONLY isBeaconTimerPeriodic = true; ctimer_set(&beacon_timer, BEACON_TIME, beacon_timer_fired, NULL); timer_reset(&beacon_timerTime); // Reset the tandem timer #endif } pmesg(200, "%s :: %s :: Line #%d\n", __FILE__, __func__, __LINE__); }
uint16_t mqtt_sn_send_publish(struct mqtt_sn_connection *mqc, uint16_t topic_id, uint8_t topic_type, const char* data, uint16_t data_len, int8_t qos, uint8_t retain) { publish_packet_t packet; if (data_len > sizeof(packet.data)) { printf("Error: payload is too big\n"); return 0; } packet.type = MQTT_SN_TYPE_PUBLISH; packet.flags = 0x00; if (retain) packet.flags += MQTT_SN_FLAG_RETAIN; packet.flags += mqtt_sn_get_qos_flag(qos); packet.flags += (topic_type & 0x3); packet.topic_id = uip_htons(topic_id); packet.message_id = uip_htons(mqc->next_message_id++); strncpy(packet.data, data, sizeof(packet.data)); packet.length = 0x07 + data_len; if (debug){ printf("Sending PUBLISH packet...\n"); if (ctimer_expired(&(mqc->receive_timer))){ printf("receive timer has already expired...\n"); } } send_packet(mqc, (char*)&packet, packet.length); return packet.message_id; }
/*---------------------------------------------------------------------------*/ void akes_trickle_on_new_nbr(void) { PRINTF("akes-trickle: New neighbor\n"); if((++new_nbrs_count == get_reset_threshold()) && ctimer_expired(&hello_timer)) { akes_trickle_reset(); } }
static void handle_summary(struct deluge_msg_summary *msg, const linkaddr_t *sender) { int highest_available, i; clock_time_t oldest_request, oldest_data, now; struct deluge_page *page; highest_available = highest_available_page(¤t_object); if(msg->version != current_object.version || msg->highest_available != highest_available) { neighbor_inconsistency = 1; } else { recv_adv++; } if(msg->version < current_object.version) { old_summary = 1; broadcast_profile = 1; } /* Deluge M.5 */ if(msg->version == current_object.update_version && msg->highest_available > highest_available) { if(msg->highest_available > OBJECT_PAGE_COUNT(current_object)) { PRINTF("Error: highest available is above object page count!\n"); return; } oldest_request = oldest_data = now = clock_time(); for(i = 0; i < msg->highest_available; i++) { page = ¤t_object.pages[i]; if(page->last_request < oldest_request) { oldest_request = page->last_request; } if(page->last_request < oldest_data) { oldest_data = page->last_data; } } if(((now - oldest_request) / CLOCK_SECOND) <= 2 * r_interval || ((now - oldest_data) / CLOCK_SECOND) <= r_interval) { return; } linkaddr_copy(¤t_object.summary_from, sender); transition(DELUGE_STATE_RX); if(ctimer_expired(&rx_timer)) { ctimer_set(&rx_timer, CONST_OMEGA * ESTIMATED_TX_TIME + ((unsigned)random_rand() % T_R), send_request, ¤t_object); } } }
/*---------------------------------------------------------------------------*/ static void start_transmission_timer(void) { PRINTF("csma: start_transmission_timer, queue len %d\n", list_length(queued_packet_list)); if(list_length(queued_packet_list) > 0) { if(ctimer_expired(&transmit_timer)) { ctimer_set(&transmit_timer, 0, transmit_queued_packet, NULL); } } }
/*---------------------------------------------------------------------------*/ void beacon_timer_fired(){ pmesg(200, "%s :: %s :: Line #%d\n", __FILE__, __func__, __LINE__); #ifdef BEACON_ONLY // check stack size timer if(ctimer_expired(&stack_check_timer)) { ctimer_set(&stack_check_timer, (clock_time_t)STACK_CHECK_INTERVAL, stack_check_timer_fired, NULL); } #endif if (isRunningForwardingEngine) { if (!tHasPassed) { beaconType = NORMAL_BEACON; process_post(&sendBeaconTask, NULL, NULL); remainingInterval(); } else { decayInterval(); } } if(isBeaconTimerPeriodic == true){ ctimer_set(&beacon_timer, BEACON_TIME, beacon_timer_fired, NULL); timer_reset(&beacon_timerTime); // Reset the tandem timer } }
static void handle_packet(struct deluge_msg_packet *msg) { struct deluge_page *page; uint16_t crc; struct deluge_msg_packet packet; memcpy(&packet, msg, sizeof(packet)); PRINTF("Incoming packet for object id %u, version %u, page %u, packet num %u!\n", (unsigned)packet.object_id, (unsigned)packet.version, (unsigned)packet.pagenum, (unsigned)packet.packetnum); if(packet.pagenum != current_object.current_rx_page) { return; } if(packet.version != current_object.version) { neighbor_inconsistency = 1; } page = ¤t_object.pages[packet.pagenum]; if(packet.version == page->version && !(page->flags & PAGE_COMPLETE)) { memcpy(¤t_object.current_page[S_PKT * packet.packetnum], packet.payload, S_PKT); crc = crc16_data(packet.payload, S_PKT, 0); if(packet.crc != crc) { PRINTF("packet crc: %hu, calculated crc: %hu\n", packet.crc, crc); return; } page->last_data = clock_time(); page->packet_set |= (1 << packet.packetnum); if(page->packet_set == ALL_PACKETS) { /* This is the last packet of the requested page; stop streaming. */ packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM_END); write_page(¤t_object, packet.pagenum, current_object.current_page); page->version = packet.version; page->flags = PAGE_COMPLETE; PRINTF("Page %u completed\n", packet.pagenum); current_object.current_rx_page++; if(packet.pagenum == OBJECT_PAGE_COUNT(current_object) - 1) { current_object.version = current_object.update_version; leds_on(LEDS_RED); PRINTF("Update completed for object %u, version %u\n", (unsigned)current_object.object_id, packet.version); } else if(current_object.current_rx_page < OBJECT_PAGE_COUNT(current_object)) { if(ctimer_expired(&rx_timer)) { ctimer_set(&rx_timer, CONST_OMEGA * ESTIMATED_TX_TIME + (random_rand() % T_R), send_request, ¤t_object); } } /* Deluge R.3 */ transition(DELUGE_STATE_MAINTAIN); } else { /* More packets to come. Put lower layers in streaming mode. */ packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM); } } }
/*---------------------------------------------------------------------------*/ static enum cmd_broker_result on_helloack(uint8_t *payload, int p_flag) { struct akes_nbr_entry *entry; uint8_t *secret; uint8_t key[AKES_NBR_CHALLENGE_LEN * 2]; int is_new; PRINTF("akes: Received HELLOACK\n"); if(!akes_is_acceptable_helloack()) { return CMD_BROKER_ERROR; } akes_nbr_delete_expired_tentatives(); entry = akes_nbr_get_sender_entry(); if(entry && entry->permanent && p_flag) { PRINTF("akes: No need to start a new session\n"); return CMD_BROKER_ERROR; } secret = AKES_SCHEME.get_secret_with_helloack_sender(packetbuf_addr(PACKETBUF_ADDR_SENDER)); if(!secret) { PRINTF("akes: No secret with HELLOACK sender\n"); return CMD_BROKER_ERROR; } /* copy challenges and generate key */ akes_nbr_copy_challenge(key, hello_challenge); akes_nbr_copy_challenge(key + AKES_NBR_CHALLENGE_LEN, payload); generate_pairwise_key(key, secret); #if ANTI_REPLAY_WITH_SUPPRESSION packetbuf_set_attr(PACKETBUF_ATTR_NEIGHBOR_INDEX, payload[AKES_NBR_CHALLENGE_LEN]); anti_replay_parse_counter(payload + AKES_NBR_CHALLENGE_LEN + 1); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ if(adaptivesec_verify(key)) { PRINTF("akes: Invalid HELLOACK\n"); return CMD_BROKER_ERROR; } is_new = 1; if(entry) { if(entry->permanent) { if( #if AKES_NBR_WITH_PAIRWISE_KEYS !memcmp(key, entry->permanent->pairwise_key, AES_128_KEY_LENGTH)) { #else /* AKES_NBR_WITH_PAIRWISE_KEYS */ !memcmp(payload, entry->permanent->helloack_challenge, AKES_NBR_CACHED_HELLOACK_CHALLENGE_LEN)) { #endif /* AKES_NBR_WITH_PAIRWISE_KEYS */ PRINTF("akes: Replayed HELLOACK\n"); return CMD_BROKER_ERROR; } else { akes_nbr_delete(entry, AKES_NBR_PERMANENT); is_new = 0; } } if(entry->tentative) { #if !AKES_NBR_WITH_PAIRWISE_KEYS if(!entry->tentative->meta->has_wait_timer) { PRINTF("akes: Awaiting acknowledgement of ACK\n"); return CMD_BROKER_ERROR; } #endif /* !AKES_NBR_WITH_PAIRWISE_KEYS */ if(ctimer_expired(&entry->tentative->meta->wait_timer)) { PRINTF("akes: Awaiting ACK\n"); return CMD_BROKER_ERROR; } else { PRINTF("akes: Skipping HELLOACK\n"); ctimer_stop(&entry->tentative->meta->wait_timer); akes_nbr_delete(entry, AKES_NBR_TENTATIVE); } } }