Ejemplo 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++);
  }
}
Ejemplo n.º 2
0
/*
 * active scan - will scan all 16 channels in the 802.15.4 network
 * NOTE: this assumes 16 channels, starting from 11. Needs to be changed
 * if running on other than 2.4 GHz
 */
int
handler_802154_active_scan(scan_callback_t cb)
{
  /* if no scan is active - start one */
  if(!scan) {
    callback = cb;
    current_channel = 0;
#if (DISABLE_NETSELECT_RANDOM_CHANNEL == 0)
    channel_index = 0;
#endif /* (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) */
    scan = 1;
    chseqno = framer_802154_next_seqno();
    NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0);
    ctimer_set(NULL, &scan_timer, (CLOCK_SECOND * 6) / 10, &handle_scan_timer, callback);
    return 1;
  }
  return 0;
}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static int
create_frame(struct net_buf *buf, int do_create)
{
  frame802154_t params;
  int hdr_len;

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

  /* Build the FCF. */
  params.fcf.frame_type = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_TYPE);
  params.fcf.frame_pending = packetbuf_attr(buf, PACKETBUF_ATTR_PENDING);
  if(packetbuf_holds_broadcast(buf)) {
    params.fcf.ack_required = 0;
  } else {
    params.fcf.ack_required = packetbuf_attr(buf, 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_LEVEL
  if(packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL)) {
    params.fcf.security_enabled = 1;
  }
  /* Setting security-related attributes */
  params.aux_hdr.security_control.security_level = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL);
  params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
  params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
#if LLSEC802154_USES_EXPLICIT_KEYS
  params.aux_hdr.security_control.key_id_mode = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE);
  params.aux_hdr.key_index = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_INDEX);
  params.aux_hdr.key_source.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY_LEVEL */

  /* 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(buf, PACKETBUF_ATTR_MAC_SEQNO)) {
    params.seq = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO);

  } else {
    params.seq = framer_802154_next_seqno();
    packetbuf_set_attr(buf, 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(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));
    /* 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, &linkaddr_node_addr);

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

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

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

    return hdr_len;
  } else {
    PRINTF("15.4-OUT: too large header: %u\n", hdr_len);
    return FRAMER_FAILED;
  }
}