コード例 #1
0
/* Adds and returns a slotframe (NULL if failure) */
struct tsch_slotframe *
tsch_schedule_add_slotframe(uint16_t handle, uint16_t size)
{
  if(size == 0) {
    return NULL;
  }

  if(tsch_schedule_get_slotframe_by_handle(handle)) {
    /* A slotframe with this handle already exists */
    return NULL;
  }

  if(tsch_get_lock()) {
    struct tsch_slotframe *sf = memb_alloc(&slotframe_memb);
    if(sf != NULL) {
      /* Initialize the slotframe */
      sf->handle = handle;
      ASN_DIVISOR_INIT(sf->size, size);
      LIST_STRUCT_INIT(sf, links_list);
      /* Add the slotframe to the global list */
      list_add(slotframe_list, sf);
    }
    PRINTF("TSCH-schedule: add_slotframe %u %u\n",
           handle, size);
    tsch_release_lock();
    return sf;
  }
  return NULL;
}
コード例 #2
0
ファイル: tsch-packet.c プロジェクト: nkigen/contiki
/* Create an EB packet */
int
tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
                      uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset)
{
    int ret = 0;
    uint8_t curr_len = 0;
    uint8_t mlme_ie_offset;

    frame802154_t p;
    struct ieee802154_ies ies;

    if(buf_size < TSCH_PACKET_MAX_LEN) {
        return 0;
    }

    /* Create 802.15.4 header */
    memset(&p, 0, sizeof(p));
    p.fcf.frame_type = FRAME802154_BEACONFRAME;
    p.fcf.ie_list_present = 1;
    p.fcf.frame_version = FRAME802154_IEEE802154E_2012;
    p.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;
    p.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    p.seq = seqno;
    p.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
    /* It is important not to compress PAN ID, as this would result in not including either
     * source nor destination PAN ID, leaving potential joining devices unaware of the PAN ID. */
    p.fcf.panid_compression = 0;

    p.src_pid = frame802154_get_pan_id();
    p.dest_pid = frame802154_get_pan_id();
    linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
    p.dest_addr[0] = 0xff;
    p.dest_addr[1] = 0xff;

#if LLSEC802154_ENABLED
    if(tsch_is_pan_secured) {
        p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0;
        p.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
        p.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE);
        p.aux_hdr.security_control.frame_counter_suppression = 1;
        p.aux_hdr.security_control.frame_counter_size = 1;
        p.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
    }
#endif /* LLSEC802154_ENABLED */

    if((curr_len = frame802154_create(&p, buf)) == 0) {
        return 0;
    }

    /* Prepare Information Elements for inclusion in the EB */
    memset(&ies, 0, sizeof(ies));

    /* Add TSCH timeslot timing IE. */
#if TSCH_PACKET_EB_WITH_TIMESLOT_TIMING
    {
        int i;
        ies.ie_tsch_timeslot_id = 1;
        for(i = 0; i < tsch_ts_elements_count; i++) {
            ies.ie_tsch_timeslot[i] = RTIMERTICKS_TO_US(tsch_timing[i]);
        }
    }
#endif /* TSCH_PACKET_EB_WITH_TIMESLOT_TIMING */

    /* Add TSCH hopping sequence IE */
#if TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE
    if(tsch_hopping_sequence_length.val <= sizeof(ies.ie_hopping_sequence_list)) {
        ies.ie_channel_hopping_sequence_id = 1;
        ies.ie_hopping_sequence_len = tsch_hopping_sequence_length.val;
        memcpy(ies.ie_hopping_sequence_list, tsch_hopping_sequence, ies.ie_hopping_sequence_len);
    }
#endif /* TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE */

    /* Add Slotframe and Link IE */
#if TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK
    {
        /* Send slotframe 0 with link at timeslot 0 */
        struct tsch_slotframe *sf0 = tsch_schedule_get_slotframe_by_handle(0);
        struct tsch_link *link0 = tsch_schedule_get_link_by_timeslot(sf0, 0);
        if(sf0 && link0) {
            ies.ie_tsch_slotframe_and_link.num_slotframes = 1;
            ies.ie_tsch_slotframe_and_link.slotframe_handle = sf0->handle;
            ies.ie_tsch_slotframe_and_link.slotframe_size = sf0->size.val;
            ies.ie_tsch_slotframe_and_link.num_links = 1;
            ies.ie_tsch_slotframe_and_link.links[0].timeslot = link0->timeslot;
            ies.ie_tsch_slotframe_and_link.links[0].channel_offset = link0->channel_offset;
            ies.ie_tsch_slotframe_and_link.links[0].link_options = link0->link_options;
        }
    }
#endif /* TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK */

    /* First add header-IE termination IE to stipulate that next come payload IEs */
    if((ret = frame80215e_create_ie_header_list_termination_1(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
        return -1;
    }
    curr_len += ret;

    /* We start payload IEs, save offset */
    if(hdr_len != NULL) {
        *hdr_len = curr_len;
    }

    /* Save offset of the MLME IE descriptor, we need to know the total length
     * before writing it */
    mlme_ie_offset = curr_len;
    curr_len += 2; /* Space needed for MLME descriptor */

    /* Save the offset of the TSCH Synchronization IE, needed to update ASN and join priority before sending */
    if(tsch_sync_ie_offset != NULL) {
        *tsch_sync_ie_offset = curr_len;
    }
    if((ret = frame80215e_create_ie_tsch_synchronization(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
        return -1;
    }
    curr_len += ret;

    if((ret = frame80215e_create_ie_tsch_timeslot(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
        return -1;
    }
    curr_len += ret;

    if((ret = frame80215e_create_ie_tsch_channel_hopping_sequence(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
        return -1;
    }
    curr_len += ret;

    if((ret = frame80215e_create_ie_tsch_slotframe_and_link(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
        return -1;
    }
    curr_len += ret;

    ies.ie_mlme_len = curr_len - mlme_ie_offset - 2;
    if((ret = frame80215e_create_ie_mlme(buf + mlme_ie_offset, buf_size - mlme_ie_offset, &ies)) == -1) {
        return -1;
    }

    /* Payload IE list termination: optional */
    /*
    if((ret = frame80215e_create_ie_payload_list_termination(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
      return -1;
    }
    curr_len += ret;
    */

    return curr_len;
}