Пример #1
0
/*---------------------------------------------------------------------------*/
static void
handle_beacon_send_timer(struct net_buf *buf, void *p)
{
  struct net_buf *mbuf;
  frame802154_t params;
  uint8_t len;

  mbuf = l2_buf_get_reserve(0);
  if(!mbuf) {
    return;
  }

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  /* use packetbuf for sending ?? */
  packetbuf_clear(mbuf);
  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_BEACONFRAME;

  /* Insert IEEE 802.15.4 (2006) version bits. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2006;

  /* assume long for now */
  params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);

  /* Set the source PAN ID to the global variable. */
  params.src_pid = panid;

  params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
  params.dest_addr[0] = 0xFF;
  params.dest_addr[1] = 0xFF;

  params.dest_pid = 0xffff;

  params.seq = framer_802154_next_seqno();

  /* Calculate beacon length and copy it to packetbuf */
  beacon_payload_len = handler_802154_calculate_beacon_payload_length(beacon_payload, BEACON_PAYLOAD_BUFFER_SIZE);
  packetbuf_copyfrom(mbuf, beacon_payload, beacon_payload_len);

  /* Set payload and payload length */
  params.payload = packetbuf_dataptr(mbuf);
  params.payload_len = packetbuf_datalen(mbuf);

  len = frame802154_hdrlen(&params);
  if(packetbuf_hdralloc(mbuf, len)) {
    frame802154_create(&params, packetbuf_hdrptr(mbuf), len);
    if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf),
                  packetbuf_totlen(mbuf)) != RADIO_TX_OK) {
      l2_buf_unref(mbuf);
      return;
    }

    HANDLER_802154_STAT(handler_802154_stats.beacons_sent++);
  }
}
Пример #2
0
/* Construct enhanced ACK packet and return ACK length */
int
tsch_packet_create_eack(uint8_t *buf, int buf_size,
                        linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack)
{
    int ret;
    uint8_t curr_len = 0;
    frame802154_t p;
    struct ieee802154_ies ies;

    memset(&p, 0, sizeof(p));
    p.fcf.frame_type = FRAME802154_ACKFRAME;
    p.fcf.frame_version = FRAME802154_IEEE802154E_2012;
    p.fcf.ie_list_present = 1;
    /* Compression unset. According to IEEE802.15.4e-2012:
     * - if no address is present: elide PAN ID
     * - if at least one address is present: include exactly one PAN ID (dest by default) */
    p.fcf.panid_compression = 0;
    p.dest_pid = IEEE802154_PANID;
    p.seq = seqno;
#if TSCH_PACKET_EACK_WITH_DEST_ADDR
    if(dest_addr != NULL) {
        p.fcf.dest_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;;
        linkaddr_copy((linkaddr_t *)&p.dest_addr, dest_addr);
    }
#endif
#if TSCH_PACKET_EACK_WITH_SRC_ADDR
    p.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;;
    p.src_pid = IEEE802154_PANID;
    linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
#endif
#if LLSEC802154_ENABLED
    if(tsch_is_pan_secured) {
        p.fcf.security_enabled = 1;
        p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK;
        p.aux_hdr.security_control.key_id_mode = FRAME802154_1_BYTE_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 = TSCH_SECURITY_KEY_INDEX_ACK;
    }
#endif /* LLSEC802154_ENABLED */

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

    /* Append IE timesync */
    memset(&ies, 0, sizeof(ies));
    ies.ie_time_correction = drift;
    ies.ie_is_nack = nack;

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

    return curr_len;
}
Пример #3
0
/* called to send a beacon request */
void
handler_802154_send_beacon_request(void)
{
  struct net_buf *mbuf;
  frame802154_t params;
  uint8_t len;

  mbuf = l2_buf_get_reserve(0);
  if(!mbuf) {
    return;
  }

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  /* use packetbuf for sending ?? */
  packetbuf_clear(mbuf);
  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_CMDFRAME;

  /* Insert IEEE 802.15.4 (2006) version bits. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2006;

  params.fcf.src_addr_mode = FRAME802154_NOADDR;

  params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
  params.dest_addr[0] = 0xFF;
  params.dest_addr[1] = 0xFF;

  params.dest_pid = 0xffff;

  params.seq = chseqno;

  packetbuf_set_datalen(mbuf, 1);
  params.payload = packetbuf_dataptr(mbuf);
  /* set the type in the payload */
  params.payload[0] = FRAME802154_BEACONREQ;
  params.payload_len = packetbuf_datalen(mbuf);
  len = frame802154_hdrlen(&params);

  if(packetbuf_hdralloc(mbuf, len)) {
    frame802154_create(&params, packetbuf_hdrptr(mbuf), len);
    if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf),
             packetbuf_totlen(mbuf)) != RADIO_TX_OK) {
      l2_buf_unref(mbuf);
      return;
    }
    HANDLER_802154_STAT(handler_802154_stats.beacons_reqs_sent++);
  }
}
Пример #4
0
/*---------------------------------------------------------------------------*/
static int
create_frame(int type, int do_create)
{
  frame802154_t params;
  int hdr_len;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  if(!initialized) {
    initialized = 1;
    mac_dsn = random_rand() & 0xff;
  }

  /* Build the FCF. */
  params.fcf.frame_type = packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE);
  params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
  if(packetbuf_holds_broadcast()) {
    params.fcf.ack_required = 0;
  } else {
    params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK);
  }
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2006) version bits. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2006;
  
#if LLSEC802154_SECURITY
  if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) {
    params.fcf.security_enabled = 1;
  }
  /* Setting security-related attributes */
  params.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
  params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
  params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
#if LLSEC802154_USES_EXPLICIT_KEYS
  params.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE);
  params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
  params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY */

  /* Increment and set the data sequence number. */
  if(!do_create) {
    /* Only length calculation - no sequence number is needed and
       should not be consumed. */

  } else if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) {
    params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);

  } else {
    /* Ensure that the sequence number 0 is not used as it would bypass the above check. */
    if(mac_dsn == 0) {
      mac_dsn++;
    }
    params.seq = mac_dsn++;
    packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq);
  }

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  if(LINKADDR_SIZE == 2) {
    /* Use short address mode if linkaddr size is short. */
    params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
  } else {
    params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  }
  params.dest_pid = mac_dst_pan_id;

  if(packetbuf_holds_broadcast()) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr[0] = 0xFF;
    params.dest_addr[1] = 0xFF;

  } else {
    linkaddr_copy((linkaddr_t *)&params.dest_addr,
                  packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
    /* Use short address mode if linkaddr size is small */
    if(LINKADDR_SIZE == 2) {
      params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    } else {
      params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
    }
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
  linkaddr_copy((linkaddr_t *)&params.src_addr,
                packetbuf_addr(PACKETBUF_ADDR_SENDER));

  params.payload = packetbuf_dataptr();
  params.payload_len = packetbuf_datalen();
  hdr_len = frame802154_hdrlen(&params);
  if(!do_create) {
    /* Only calculate header length */
    return hdr_len;

  } else if(packetbuf_hdralloc(hdr_len)) {
    frame802154_create(&params, packetbuf_hdrptr());

    PRINTF("15.4-OUT: %2X", params.fcf.frame_type);
    PRINTADDR(params.dest_addr);
    PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen());

    return hdr_len;
  } else {
    PRINTF("15.4-OUT: too large header: %u\n", hdr_len);
    return FRAMER_FAILED;
  }
}
Пример #5
0
/*---------------------------------------------------------------------------*/
static int
create(void)
{
  frame802154_t params;
  int len;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  if(!initialized) {
    initialized = 1;
    mac_dsn = random_rand() & 0xff;
  }

  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_DATAFRAME;
  params.fcf.security_enabled = 0;
  params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
  if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) {
    params.fcf.ack_required = 0;
  } else {
    params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK);
  }
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2003) version bit. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2003;

  /* Increment and set the data sequence number. */
  if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) {
    params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
  } else {
    params.seq = mac_dsn++;
    packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq);
  }
/*   params.seq = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); */

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  if(sizeof(linkaddr_t) == 2) {
    /* Use short address mode if linkaddr size is short. */
    params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
  } else {
    params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  }
  params.dest_pid = mac_dst_pan_id;

  /*
   *  If the output address is NULL in the Rime buf, then it is broadcast
   *  on the 802.15.4 network.
   */
  if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr[0] = 0xFF;
    params.dest_addr[1] = 0xFF;

  } else {
    linkaddr_copy((linkaddr_t *)&params.dest_addr,
                  packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
    /* Use short address mode if linkaddr size is small */
    if(sizeof(linkaddr_t) == 2) {
      params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    } else {
      params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
    }
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
  linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);

  params.payload = packetbuf_dataptr();
  params.payload_len = packetbuf_datalen();
  len = frame802154_hdrlen(&params);
  if(packetbuf_hdralloc(len)) {
    frame802154_create(&params, packetbuf_hdrptr(), len);

    PRINTF("15.4-OUT: %2X", params.fcf.frame_type);
    PRINTADDR(params.dest_addr);
    PRINTF("%d %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen());

    return len;
  } else {
    PRINTF("15.4-OUT: too large header: %u\n", len);
    return FRAMER_FAILED;
  }
}
Пример #6
0
/*---------------------------------------------------------------------------*/
static int
send_packet(void)
{
  frame802154_t params;
  uint8_t len;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_DATAFRAME;
  params.fcf.security_enabled = 0;
  params.fcf.frame_pending = 0;
  params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_RELIABLE);
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2003) version bit. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2003;

  /* Increment and set the data sequence number. */
  params.seq = mac_dsn++;

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  params.dest_pid = mac_dst_pan_id;

  /*
   *  If the output address is NULL in the Rime buf, then it is broadcast
   *  on the 802.15.4 network.
   */
  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr.u8[0] = 0xFF;
    params.dest_addr.u8[1] = 0xFF;

  } else {
    rimeaddr_copy(&params.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
    params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
  rimeaddr_copy(&params.src_addr, &rimeaddr_node_addr);

  params.payload = packetbuf_dataptr();  
  params.payload_len = packetbuf_datalen();  
  len = frame802154_hdrlen(&params);
  PRINTF("payload=%s, len=%d, hdrlen=%d\n", params.payload, params.payload_len, len);
  if(packetbuf_hdralloc(len)) {
    frame802154_create(&params, packetbuf_hdrptr(), len);

    //PRINTF("6MAC-UT: %2X\n", params.fcf.frame_type);
    PRINTADDR(params.dest_addr.u8);
    //PRINTF("%u %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen());

    return radio->send(packetbuf_hdrptr(), packetbuf_totlen());
  } else {
    PRINTF("6MAC-UT: too large header: %u\n", len);
  }
  return 0;
}
Пример #7
0
/* 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;
}
Пример #8
0
/*---------------------------------------------------------------------------*/
static uint8_t
send_packet(struct net_buf *buf, mac_callback_t sent, void *ptr)
{
  frame802154_t params;
  uint8_t len;
  uint8_t ret = 0;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_DATAFRAME;
  params.fcf.security_enabled = 0;
  params.fcf.frame_pending = 0;
  params.fcf.ack_required = packetbuf_attr(buf, PACKETBUF_ATTR_RELIABLE);
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2003) version bit. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2003;

  /* Increment and set the data sequence number. */
  params.seq = mac_dsn++;

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  params.dest_pid = mac_dst_pan_id;

  if(packetbuf_holds_broadcast(buf)) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr[0] = 0xFF;
    params.dest_addr[1] = 0xFF;

  } else {
    linkaddr_copy((linkaddr_t *)&params.dest_addr,
                  packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
    params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
#if NETSTACK_CONF_BRIDGE_MODE
  linkaddr_copy((linkaddr_t *)&params.src_addr,packetbuf_addr(PACKETBUF_ADDR_SENDER));
#else
  linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);
#endif

  params.payload = packetbuf_dataptr(buf);
  params.payload_len = packetbuf_datalen(buf);
  len = frame802154_hdrlen(&params);
  if(packetbuf_hdralloc(buf, len)) {
    frame802154_create(&params, packetbuf_hdrptr(buf), len);

    PRINTF("6MAC-UT: type %X dest ", params.fcf.frame_type);
    PRINTLLADDR((uip_lladdr_t *)params.dest_addr);
    PRINTF(" len %u datalen %u (totlen %u)\n", len, packetbuf_datalen(buf),
	   packetbuf_totlen(buf));

    ret = NETSTACK_RADIO.send(buf, packetbuf_hdrptr(buf), packetbuf_totlen(buf));
    if(sent) {
      switch(ret) {
      case RADIO_TX_OK:
        sent(buf, ptr, MAC_TX_OK, 1);
        break;
      case RADIO_TX_ERR:
        sent(buf, ptr, MAC_TX_ERR, 1);
        break;
      case RADIO_TX_COLLISION:
        sent(buf, ptr, MAC_TX_COLLISION, 1);
        break;
      }
    }
  } else {
    PRINTF("6MAC-UT: too large header: %u\n", len);
  }

  return ret;
}
Пример #9
0
/* Function to send beacon */
extern void mac_send_beacon()
{
    static uint16_t macBSN = 0x00;
    uint8_t payload[10] = {0,0,0,0,0,0,0,0,0,0};
    frame802154_t params;
    static frame802154_beacon_t beaconData;
    uint8_t len;

    /* init to zeros */
    memset(&params, 0, sizeof(params));
    memset(&beaconData, 0, sizeof(frame802154_beacon_t));

    /* Build the FCF. */
    params.fcf.frame_type = FRAME802154_BEACONFRAME;
    params.fcf.security_enabled = 0;
    params.fcf.frame_pending = 0;
    params.fcf.ack_required = 0;
    params.fcf.panid_compression = 0;

    /* Insert IEEE 802.15.4 (2003) version bit. */
    params.fcf.frame_version = FRAME802154_IEEE802154_2003;

    /* Increment and set the beacon sequence number. */
    params.seq = macBSN++;

    /* Complete the addressing fields. */
    /**
      \todo For phase 1 the addresses are all long. We'll need a mechanism
      in the rime attributes to tell the mac to use long or short for phase 2.
     */
    params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
    /* Set the source PAN ID to the PAN ID as per spec. */
    params.src_pid = mac_dst_pan_id;

    params.fcf.dest_addr_mode = FRAME802154_NOADDR;
    params.dest_pid = 0;
    //    params.dest_addr[0] = 0xFF;
    // params.dest_addr[1] = 0xFF;

    //rimeaddr_copy((rimeaddr_t *)&params.dest_addr,\
    packetbuf_addr(PACKETBUF_ADDR_RECEIVER));


    /*
     * Set up the source address using only the long address mode for
     * phase 1.
     */
    rimeaddr_copy((rimeaddr_t *)&params.src_addr, &rimeaddr_node_addr);
    rimeaddr_copy((rimeaddr_t *)&params.dest_addr, &rimeaddr_null);

    /* Preparing the payload for beacon*/
    beaconData.superFrSpec |= 0x000F;  /* BO set to 15 */
    beaconData.superFrSpec |= 0x00F0;  /* SO set to 15 */
    beaconData.superFrSpec |= 0x0F00;  /* CAP lt:No relevance in beacon less */
    beaconData.superFrSpec |= BV(14);  /* PAN coordinator */
    beaconData.superFrSpec |= BV(15);  /* Association permitted */

    beaconData.gtsInfo.gtsSpec = 0;    /* If 0, direction and list are absent*/

    beaconData.pendAddrInfo.pendAddrSpec = 0; /* If 0, no list present*/

    packetbuf_clear();
    len = frame802154_packBeacon((uint8_t*)packetbuf_dataptr(),&beaconData);
    packetbuf_set_datalen(len);
    params.payload = packetbuf_dataptr();
    len = frame802154_hdrlen(&params);
    frame802154_create(&params, packetbuf_hdrptr(), len);
    NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen());
    return;
}