Esempio n. 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++);
  }
}
Esempio n. 2
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++);
  }
}
Esempio n. 3
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;
  }
}
Esempio n. 4
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;
  }
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
params.dest_pid = mac_dst_pan_id;

/*
 * 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_panCoord_addr);

/* Preparing the payload for ASSOC REQ */
// Filling the last two bytes, reserving the earlier bytes for hdr
payload[8] = MAC_ASSOC_REQ;
// Filling capability Info byte
// From Bit 7 to 0:
// PAN Coord, FFD, Pwr Src, Rx always on, Res, Sec, 16bit address
payload[9] |= 0x0;
params.payload = &payload[8];
params.payload_len = 2;
len = frame802154_hdrlen(&params);
if(len <= 8) {
    frame802154_create(&params, &payload[8-len], len);

    NETSTACK_RADIO.send(&payload[8-len], len+2);
    return(0); // success
} else {
    //PRINTF("6MAC-UT: too large header: %u\n", len);
}
return(1); // failure
#endif