/*---------------------------------------------------------------------------*/
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__);
}
示例#2
0
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;
}
示例#3
0
/*---------------------------------------------------------------------------*/
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();
    }
}
示例#4
0
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(&current_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 = &current_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(&current_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, &current_object);
    }
  }
}
示例#5
0
/*---------------------------------------------------------------------------*/
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
  }
}
示例#7
0
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 = &current_object.pages[packet.pagenum];
  if(packet.version == page->version && !(page->flags & PAGE_COMPLETE)) {
    memcpy(&current_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(&current_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, &current_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);
    }
  }
}
示例#8
0
文件: akes.c 项目: kkrentz/contiki
/*---------------------------------------------------------------------------*/
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);
      }
    }
  }