2016-06-16 16:00:11 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation.
|
|
|
|
*
|
2017-01-18 17:01:01 -08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-06-16 16:00:11 +02:00
|
|
|
*/
|
|
|
|
|
2018-11-30 12:54:56 +02:00
|
|
|
#include <logging/log.h>
|
|
|
|
LOG_MODULE_REGISTER(net_ieee802154, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);
|
2016-06-16 16:00:11 +02:00
|
|
|
|
|
|
|
#include <net/net_core.h>
|
|
|
|
#include <net/net_l2.h>
|
|
|
|
#include <net/net_if.h>
|
|
|
|
|
2016-11-08 12:33:53 +01:00
|
|
|
#include "ipv6.h"
|
|
|
|
|
2016-06-16 16:00:11 +02:00
|
|
|
#include <errno.h>
|
|
|
|
|
2016-11-16 09:39:31 +01:00
|
|
|
#include "ieee802154_fragment.h"
|
2016-07-07 14:11:06 +02:00
|
|
|
#include <6lo.h>
|
|
|
|
|
2016-06-16 16:00:11 +02:00
|
|
|
#include <net/ieee802154_radio.h>
|
|
|
|
|
|
|
|
#include "ieee802154_frame.h"
|
2017-12-06 09:59:18 +01:00
|
|
|
#include "ieee802154_mgmt_priv.h"
|
2017-03-10 15:22:21 +01:00
|
|
|
#include "ieee802154_security.h"
|
2017-09-05 13:52:29 +02:00
|
|
|
#include "ieee802154_utils.h"
|
2018-10-09 11:50:47 +02:00
|
|
|
#include "ieee802154_radio_utils.h"
|
2016-06-16 16:00:11 +02:00
|
|
|
|
2018-07-26 14:38:42 +03:00
|
|
|
#define BUF_TIMEOUT K_MSEC(50)
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
/* No need to hold space for the FCS */
|
|
|
|
static u8_t frame_buffer_data[IEEE802154_MTU - 2];
|
|
|
|
|
|
|
|
static struct net_buf frame_buf = {
|
|
|
|
.data = frame_buffer_data,
|
|
|
|
.size = IEEE802154_MTU - 2,
|
|
|
|
.frags = NULL,
|
|
|
|
.__buf = frame_buffer_data,
|
|
|
|
};
|
|
|
|
|
2017-10-18 17:41:04 +03:00
|
|
|
#define PKT_TITLE "IEEE 802.15.4 packet content:"
|
|
|
|
#define TX_PKT_TITLE "> " PKT_TITLE
|
|
|
|
#define RX_PKT_TITLE "< " PKT_TITLE
|
|
|
|
|
2017-09-29 09:40:15 +02:00
|
|
|
#ifdef CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET
|
2016-07-12 16:09:29 +02:00
|
|
|
|
2017-08-17 15:54:00 +02:00
|
|
|
#include "net_private.h"
|
2016-07-12 16:09:29 +02:00
|
|
|
|
2017-10-18 17:41:04 +03:00
|
|
|
static inline void pkt_hexdump(const char *title, struct net_pkt *pkt,
|
2018-10-24 15:08:50 +02:00
|
|
|
bool in)
|
2016-07-12 16:09:29 +02:00
|
|
|
{
|
2018-10-24 15:08:50 +02:00
|
|
|
if (IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_RX) &&
|
2017-11-06 15:16:24 +01:00
|
|
|
in) {
|
2019-02-04 21:21:39 +01:00
|
|
|
net_pkt_hexdump(pkt, title);
|
2017-11-06 15:16:24 +01:00
|
|
|
}
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
if (IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_TX) &&
|
2017-11-06 15:16:24 +01:00
|
|
|
!in) {
|
2019-02-04 21:21:39 +01:00
|
|
|
net_pkt_hexdump(pkt, title);
|
2017-11-06 15:16:24 +01:00
|
|
|
}
|
2016-07-12 16:09:29 +02:00
|
|
|
}
|
2016-10-26 15:37:05 +02:00
|
|
|
|
2016-07-12 16:09:29 +02:00
|
|
|
#else
|
|
|
|
#define pkt_hexdump(...)
|
2017-09-29 09:40:15 +02:00
|
|
|
#endif /* CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET */
|
2016-07-12 16:09:29 +02:00
|
|
|
|
2016-06-28 15:05:07 +02:00
|
|
|
#ifdef CONFIG_NET_L2_IEEE802154_ACK_REPLY
|
|
|
|
static inline void ieee802154_acknowledge(struct net_if *iface,
|
|
|
|
struct ieee802154_mpdu *mpdu)
|
|
|
|
{
|
2017-04-05 08:37:44 +02:00
|
|
|
struct net_pkt *pkt;
|
2016-06-28 15:05:07 +02:00
|
|
|
|
|
|
|
if (!mpdu->mhr.fs->fc.ar) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-20 13:43:24 +01:00
|
|
|
pkt = net_pkt_alloc_with_buffer(iface, IEEE802154_ACK_PKT_LENGTH,
|
|
|
|
AF_UNSPEC, 0, BUF_TIMEOUT);
|
2017-04-05 08:37:44 +02:00
|
|
|
if (!pkt) {
|
2016-06-28 15:05:07 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
if (ieee802154_create_ack_frame(iface, pkt, mpdu->mhr.fs->sequence)) {
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 13:57:49 +01:00
|
|
|
ieee802154_tx(iface, IEEE802154_TX_MODE_DIRECT,
|
|
|
|
pkt, pkt->buffer);
|
2016-06-28 15:05:07 +02:00
|
|
|
}
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
net_pkt_unref(pkt);
|
2016-06-28 15:05:07 +02:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define ieee802154_acknowledge(...)
|
|
|
|
#endif /* CONFIG_NET_L2_IEEE802154_ACK_REPLY */
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
static inline void set_pkt_ll_addr(struct net_linkaddr *addr, bool comp,
|
2016-08-10 15:39:01 +02:00
|
|
|
enum ieee802154_addressing_mode mode,
|
|
|
|
struct ieee802154_address_field *ll)
|
|
|
|
{
|
|
|
|
if (mode == IEEE802154_ADDR_MODE_NONE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == IEEE802154_ADDR_MODE_EXTENDED) {
|
|
|
|
addr->len = IEEE802154_EXT_ADDR_LENGTH;
|
|
|
|
|
|
|
|
if (comp) {
|
|
|
|
addr->addr = ll->comp.addr.ext_addr;
|
|
|
|
} else {
|
|
|
|
addr->addr = ll->plain.addr.ext_addr;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* ToDo: Handle short address (lookup known nbr, ...) */
|
2019-03-26 19:57:45 -06:00
|
|
|
addr->len = 0U;
|
2016-08-10 15:39:01 +02:00
|
|
|
addr->addr = NULL;
|
|
|
|
}
|
2017-02-15 13:20:31 +02:00
|
|
|
|
|
|
|
addr->type = NET_LINK_IEEE802154;
|
2016-08-10 15:39:01 +02:00
|
|
|
}
|
|
|
|
|
2016-07-07 14:11:06 +02:00
|
|
|
#ifdef CONFIG_NET_6LO
|
2016-10-25 09:59:33 +02:00
|
|
|
static inline
|
2017-04-05 08:37:44 +02:00
|
|
|
enum net_verdict ieee802154_manage_recv_packet(struct net_if *iface,
|
2018-12-06 14:23:20 +01:00
|
|
|
struct net_pkt *pkt,
|
|
|
|
size_t hdr_len)
|
2016-10-25 09:59:33 +02:00
|
|
|
{
|
|
|
|
enum net_verdict verdict = NET_CONTINUE;
|
2017-04-21 09:27:50 -05:00
|
|
|
u32_t src;
|
|
|
|
u32_t dst;
|
2016-10-25 09:59:33 +02:00
|
|
|
|
2016-10-31 15:02:47 +02:00
|
|
|
/* Upper IP stack expects the link layer address to be in
|
|
|
|
* big endian format so we must swap it here.
|
|
|
|
*/
|
2018-09-11 09:16:03 +02:00
|
|
|
if (net_pkt_lladdr_src(pkt)->addr &&
|
|
|
|
net_pkt_lladdr_src(pkt)->len == IEEE802154_EXT_ADDR_LENGTH) {
|
|
|
|
sys_mem_swap(net_pkt_lladdr_src(pkt)->addr,
|
|
|
|
net_pkt_lladdr_src(pkt)->len);
|
2016-10-31 15:02:47 +02:00
|
|
|
}
|
|
|
|
|
2018-09-11 09:16:03 +02:00
|
|
|
if (net_pkt_lladdr_dst(pkt)->addr &&
|
|
|
|
net_pkt_lladdr_dst(pkt)->len == IEEE802154_EXT_ADDR_LENGTH) {
|
|
|
|
sys_mem_swap(net_pkt_lladdr_dst(pkt)->addr,
|
|
|
|
net_pkt_lladdr_dst(pkt)->len);
|
2016-10-31 15:02:47 +02:00
|
|
|
}
|
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
/** Uncompress will drop the current fragment. Pkt ll src/dst address
|
2016-10-25 09:59:33 +02:00
|
|
|
* will then be wrong and must be updated according to the new fragment.
|
|
|
|
*/
|
2018-09-11 09:16:03 +02:00
|
|
|
src = net_pkt_lladdr_src(pkt)->addr ?
|
2018-12-06 14:23:20 +01:00
|
|
|
net_pkt_lladdr_src(pkt)->addr -
|
|
|
|
(net_pkt_data(pkt) - hdr_len) : 0;
|
2018-09-11 09:16:03 +02:00
|
|
|
dst = net_pkt_lladdr_dst(pkt)->addr ?
|
2018-12-06 14:23:20 +01:00
|
|
|
net_pkt_lladdr_dst(pkt)->addr -
|
|
|
|
(net_pkt_data(pkt) - hdr_len) : 0;
|
2016-10-25 09:59:33 +02:00
|
|
|
|
2016-11-16 09:39:31 +01:00
|
|
|
#ifdef CONFIG_NET_L2_IEEE802154_FRAGMENT
|
2017-04-05 08:37:44 +02:00
|
|
|
verdict = ieee802154_reassemble(pkt);
|
2017-10-19 15:04:09 +03:00
|
|
|
if (verdict != NET_CONTINUE) {
|
2016-10-25 09:59:33 +02:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
#else
|
2017-04-05 08:37:44 +02:00
|
|
|
if (!net_6lo_uncompress(pkt)) {
|
2016-10-25 09:59:33 +02:00
|
|
|
NET_DBG("Packet decompression failed");
|
|
|
|
verdict = NET_DROP;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
#endif
|
2018-12-06 14:23:20 +01:00
|
|
|
net_pkt_lladdr_src(pkt)->addr = src ?
|
|
|
|
(net_pkt_data(pkt) - hdr_len) + src : NULL;
|
|
|
|
net_pkt_lladdr_dst(pkt)->addr = dst ?
|
|
|
|
(net_pkt_data(pkt) - hdr_len) + dst : NULL;
|
2016-10-25 09:59:33 +02:00
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
pkt_hexdump(RX_PKT_TITLE, pkt, true);
|
2016-10-25 09:59:33 +02:00
|
|
|
out:
|
|
|
|
return verdict;
|
|
|
|
}
|
|
|
|
#else /* CONFIG_NET_6LO */
|
2017-04-05 08:37:44 +02:00
|
|
|
#define ieee802154_manage_recv_packet(...) NET_CONTINUE
|
2016-07-07 14:11:06 +02:00
|
|
|
#endif /* CONFIG_NET_6LO */
|
2016-06-16 16:00:11 +02:00
|
|
|
|
2016-10-25 09:59:33 +02:00
|
|
|
static enum net_verdict ieee802154_recv(struct net_if *iface,
|
2017-04-05 08:37:44 +02:00
|
|
|
struct net_pkt *pkt)
|
2016-10-25 09:59:33 +02:00
|
|
|
{
|
|
|
|
struct ieee802154_mpdu mpdu;
|
2018-12-06 14:23:20 +01:00
|
|
|
size_t hdr_len;
|
2016-10-25 09:59:33 +02:00
|
|
|
|
2018-12-06 14:23:20 +01:00
|
|
|
if (!ieee802154_validate_frame(net_pkt_data(pkt),
|
2017-04-05 08:37:44 +02:00
|
|
|
net_pkt_get_len(pkt), &mpdu)) {
|
2016-06-16 16:00:11 +02:00
|
|
|
return NET_DROP;
|
|
|
|
}
|
|
|
|
|
2016-10-07 10:53:22 +02:00
|
|
|
if (mpdu.mhr.fs->fc.frame_type == IEEE802154_FRAME_TYPE_BEACON) {
|
2017-10-03 10:03:37 +02:00
|
|
|
return ieee802154_handle_beacon(iface, &mpdu,
|
|
|
|
net_pkt_ieee802154_lqi(pkt));
|
2016-10-07 10:53:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ieee802154_is_scanning(iface)) {
|
|
|
|
return NET_DROP;
|
|
|
|
}
|
|
|
|
|
2016-10-19 17:08:09 +02:00
|
|
|
if (mpdu.mhr.fs->fc.frame_type == IEEE802154_FRAME_TYPE_MAC_COMMAND) {
|
|
|
|
return ieee802154_handle_mac_command(iface, &mpdu);
|
2016-06-16 16:00:11 +02:00
|
|
|
}
|
|
|
|
|
2016-10-19 17:08:09 +02:00
|
|
|
/* At this point the frame has to be a DATA one */
|
|
|
|
|
2016-08-10 15:39:01 +02:00
|
|
|
ieee802154_acknowledge(iface, &mpdu);
|
|
|
|
|
2018-09-11 09:16:03 +02:00
|
|
|
set_pkt_ll_addr(net_pkt_lladdr_src(pkt), mpdu.mhr.fs->fc.pan_id_comp,
|
2016-08-10 15:39:01 +02:00
|
|
|
mpdu.mhr.fs->fc.src_addr_mode, mpdu.mhr.src_addr);
|
2016-06-16 16:00:11 +02:00
|
|
|
|
2018-09-11 09:16:03 +02:00
|
|
|
set_pkt_ll_addr(net_pkt_lladdr_dst(pkt), false,
|
2016-08-10 15:39:01 +02:00
|
|
|
mpdu.mhr.fs->fc.dst_addr_mode, mpdu.mhr.dst_addr);
|
2016-06-16 16:00:11 +02:00
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
if (!ieee802154_decipher_data_frame(iface, pkt, &mpdu)) {
|
2017-03-10 15:22:21 +01:00
|
|
|
return NET_DROP;
|
|
|
|
}
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
pkt_hexdump(RX_PKT_TITLE " (with ll)", pkt, true);
|
|
|
|
|
2018-12-06 14:23:20 +01:00
|
|
|
hdr_len = (u8_t *)mpdu.payload - net_pkt_data(pkt);
|
2019-02-20 13:43:24 +01:00
|
|
|
net_buf_pull(pkt->buffer, hdr_len);
|
2018-12-06 14:23:20 +01:00
|
|
|
|
|
|
|
return ieee802154_manage_recv_packet(iface, pkt, hdr_len);
|
2016-07-12 16:09:29 +02:00
|
|
|
|
2016-06-16 16:00:11 +02:00
|
|
|
}
|
|
|
|
|
2018-10-09 11:50:47 +02:00
|
|
|
static int ieee802154_send(struct net_if *iface, struct net_pkt *pkt)
|
2016-06-16 16:00:11 +02:00
|
|
|
{
|
2017-03-28 08:33:43 +02:00
|
|
|
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
2018-10-24 15:08:50 +02:00
|
|
|
struct ieee802154_fragment_ctx f_ctx;
|
2019-02-20 14:57:58 +01:00
|
|
|
struct net_buf *buf;
|
2018-10-24 15:08:50 +02:00
|
|
|
u8_t ll_hdr_size;
|
|
|
|
bool fragment;
|
2018-10-09 11:50:47 +02:00
|
|
|
int len;
|
2016-10-26 10:58:45 +02:00
|
|
|
|
2017-04-05 08:37:44 +02:00
|
|
|
if (net_pkt_family(pkt) != AF_INET6) {
|
2018-10-09 11:50:47 +02:00
|
|
|
return -EINVAL;
|
2016-06-16 16:00:11 +02:00
|
|
|
}
|
|
|
|
|
2019-01-08 11:43:11 +01:00
|
|
|
ll_hdr_size = ieee802154_compute_header_size(iface,
|
|
|
|
&NET_IPV6_HDR(pkt)->dst);
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
/* len will hold the hdr size difference on success */
|
|
|
|
len = net_6lo_compress(pkt, true);
|
|
|
|
if (len < 0) {
|
|
|
|
return len;
|
2016-11-08 19:27:04 +01:00
|
|
|
}
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
fragment = ieee802154_fragment_is_needed(pkt, ll_hdr_size);
|
|
|
|
ieee802154_fragment_ctx_init(&f_ctx, pkt, len, true);
|
2018-10-09 11:50:47 +02:00
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
len = 0;
|
2019-03-26 19:57:45 -06:00
|
|
|
frame_buf.len = 0U;
|
2019-02-20 14:57:58 +01:00
|
|
|
buf = pkt->buffer;
|
2018-10-24 15:08:50 +02:00
|
|
|
|
2019-02-20 14:57:58 +01:00
|
|
|
while (buf) {
|
2018-10-09 11:50:47 +02:00
|
|
|
int ret;
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
net_buf_add(&frame_buf, ll_hdr_size);
|
|
|
|
|
|
|
|
if (fragment) {
|
|
|
|
ieee802154_fragment(&f_ctx, &frame_buf, true);
|
2019-02-20 14:57:58 +01:00
|
|
|
buf = f_ctx.buf;
|
2018-10-24 15:08:50 +02:00
|
|
|
} else {
|
|
|
|
memcpy(frame_buf.data + frame_buf.len,
|
2019-02-20 14:57:58 +01:00
|
|
|
buf->data, buf->len);
|
|
|
|
net_buf_add(&frame_buf, buf->len);
|
|
|
|
buf = buf->frags;
|
2016-11-08 17:22:03 +01:00
|
|
|
}
|
|
|
|
|
2018-09-11 09:16:03 +02:00
|
|
|
if (!ieee802154_create_data_frame(ctx, net_pkt_lladdr_dst(pkt),
|
2018-10-24 15:08:50 +02:00
|
|
|
&frame_buf, ll_hdr_size)) {
|
2018-10-09 11:50:47 +02:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA) &&
|
|
|
|
ieee802154_get_hw_capabilities(iface) &
|
|
|
|
IEEE802154_HW_CSMA) {
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 13:57:49 +01:00
|
|
|
ret = ieee802154_tx(iface, IEEE802154_TX_MODE_CSMA_CA,
|
|
|
|
pkt, &frame_buf);
|
2018-10-09 11:50:47 +02:00
|
|
|
} else {
|
2018-10-24 15:08:50 +02:00
|
|
|
ret = ieee802154_radio_send(iface, pkt, &frame_buf);
|
2018-10-09 11:50:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
return ret;
|
2016-10-26 10:58:45 +02:00
|
|
|
}
|
|
|
|
|
2018-10-24 15:08:50 +02:00
|
|
|
len += frame_buf.len;
|
|
|
|
|
|
|
|
/* Reinitializing frame_buf */
|
2019-03-26 19:57:45 -06:00
|
|
|
frame_buf.len = 0U;
|
2016-10-26 10:58:45 +02:00
|
|
|
}
|
|
|
|
|
2018-10-09 11:50:47 +02:00
|
|
|
net_pkt_unref(pkt);
|
2016-06-16 16:00:11 +02:00
|
|
|
|
2018-10-09 11:50:47 +02:00
|
|
|
return len;
|
2016-06-16 16:00:11 +02:00
|
|
|
}
|
|
|
|
|
2017-11-22 17:29:31 +01:00
|
|
|
static int ieee802154_enable(struct net_if *iface, bool state)
|
|
|
|
{
|
|
|
|
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
|
|
|
|
|
|
|
NET_DBG("iface %p %s", iface, state ? "up" : "down");
|
|
|
|
|
|
|
|
if (ctx->channel == IEEE802154_NO_CHANNEL) {
|
|
|
|
return -ENETDOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state) {
|
2017-11-22 20:50:53 +01:00
|
|
|
return ieee802154_start(iface);
|
2017-11-22 17:29:31 +01:00
|
|
|
}
|
|
|
|
|
2017-11-22 20:50:53 +01:00
|
|
|
return ieee802154_stop(iface);
|
2017-11-22 17:29:31 +01:00
|
|
|
}
|
|
|
|
|
2018-08-06 16:59:33 +03:00
|
|
|
enum net_l2_flags ieee802154_flags(struct net_if *iface)
|
|
|
|
{
|
|
|
|
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
|
|
|
|
|
|
|
return ctx->flags;
|
|
|
|
}
|
|
|
|
|
2016-06-16 16:00:11 +02:00
|
|
|
NET_L2_INIT(IEEE802154_L2,
|
2017-11-22 17:29:31 +01:00
|
|
|
ieee802154_recv, ieee802154_send,
|
2018-06-28 09:58:50 +02:00
|
|
|
ieee802154_enable, ieee802154_flags);
|
2016-06-16 16:00:11 +02:00
|
|
|
|
|
|
|
void ieee802154_init(struct net_if *iface)
|
|
|
|
{
|
2017-02-01 14:34:44 +01:00
|
|
|
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
2018-01-11 16:06:53 +02:00
|
|
|
const u8_t *mac = net_if_get_link_addr(iface)->addr;
|
2017-11-22 20:50:53 +01:00
|
|
|
s16_t tx_power = CONFIG_NET_L2_IEEE802154_RADIO_DFLT_TX_POWER;
|
2017-04-21 09:27:50 -05:00
|
|
|
u8_t long_addr[8];
|
2016-06-16 16:00:11 +02:00
|
|
|
|
|
|
|
NET_DBG("Initializing IEEE 802.15.4 stack on iface %p", iface);
|
|
|
|
|
2017-11-22 17:29:31 +01:00
|
|
|
ctx->channel = IEEE802154_NO_CHANNEL;
|
2018-08-06 16:59:33 +03:00
|
|
|
ctx->flags = NET_L2_MULTICAST;
|
2017-11-22 17:29:31 +01:00
|
|
|
|
2016-10-07 10:53:22 +02:00
|
|
|
ieee802154_mgmt_init(iface);
|
|
|
|
|
2017-03-10 15:22:21 +01:00
|
|
|
#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
|
|
|
|
if (ieee802154_security_init(&ctx->sec_ctx)) {
|
|
|
|
NET_ERR("Initializing link-layer security failed");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-02-01 14:34:44 +01:00
|
|
|
sys_memcpy_swap(long_addr, mac, 8);
|
|
|
|
memcpy(ctx->ext_addr, long_addr, 8);
|
2017-09-05 13:52:29 +02:00
|
|
|
ieee802154_filter_ieee_addr(iface, ctx->ext_addr);
|
2017-02-01 14:34:44 +01:00
|
|
|
|
2017-11-22 20:50:53 +01:00
|
|
|
if (!ieee802154_set_tx_power(iface, tx_power)) {
|
|
|
|
ctx->tx_power = tx_power;
|
2017-04-12 13:34:44 +02:00
|
|
|
}
|
2016-06-16 16:00:11 +02:00
|
|
|
}
|