net: ieee802154: Add PAN association request

Such management request will enable association the 15.4 device to an
existing PAN.

Change-Id: I61ffd5e4d8192716e067c5225b3327f08944063b
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-10-19 13:18:44 +02:00
commit b53e48de1b
3 changed files with 109 additions and 3 deletions

View file

@ -30,15 +30,19 @@
struct ieee802154_context {
uint16_t pan_id;
uint16_t channel;
uint8_t sequence;
struct k_sem ack_lock;
#ifdef CONFIG_NET_L2_IEEE802154_MGMT
struct ieee802154_req_params *scan_ctx;
struct k_sem res_lock;
union {
struct k_sem res_lock;
struct k_sem req_lock;
};
#endif
uint8_t sequence;
uint8_t ack_received : 1;
uint8_t ack_requested : 1;
uint8_t _unused : 6;
uint8_t associated : 1;
uint8_t _unused : 5;
} __packed;
@ -56,6 +60,7 @@ enum net_request_ieee802154_cmd {
NET_REQUEST_IEEE802154_CMD_UNSET_ACK,
NET_REQUEST_IEEE802154_CMD_PASSIVE_SCAN,
NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN,
NET_REQUEST_IEEE802154_CMD_ASSOCIATE,
};
@ -79,6 +84,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_PASSIVE_SCAN);
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_CANCEL_SCAN);
#define NET_REQUEST_IEEE802154_ASSOCIATE \
(_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_ASSOCIATE)
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_ASSOCIATE);
enum net_event_ieee802154_cmd {
NET_EVENT_IEEE802154_CMD_SCAN_RESULT = 1,
};

View file

@ -132,6 +132,98 @@ static int ieee802154_scan(uint32_t mgmt_request, struct net_if *iface,
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_IEEE802154_PASSIVE_SCAN,
ieee802154_scan);
enum net_verdict ieee802154_handle_mac_command(struct net_if *iface,
struct ieee802154_mpdu *mpdu)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
if (mpdu->command->cfi != IEEE802154_CFI_ASSOCIATION_RESPONSE) {
return NET_DROP;
}
if (mpdu->command->assoc_res.status != IEEE802154_ASF_SUCCESSFUL) {
return NET_DROP;
}
ctx->associated = true;
k_sem_give(&ctx->req_lock);
return NET_OK;
}
static int ieee802154_associate(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
struct ieee802154_radio_api *radio =
(struct ieee802154_radio_api *)iface->dev->driver_api;
struct ieee802154_context *ctx = net_if_l2_data(iface);
struct ieee802154_req_params *req =
(struct ieee802154_req_params *)data;
struct ieee802154_frame_params params;
struct ieee802154_command *cmd;
struct net_buf *buf;
int ret = 0;
k_sem_take(&ctx->req_lock, K_FOREVER);
params.dst.len = req->len;
if (params.dst.len == IEEE802154_SHORT_ADDR_LENGTH) {
params.dst.short_addr = req->short_addr;
} else {
params.dst.ext_addr = req->addr;
}
params.dst.pan_id = req->pan_id;
params.pan_id = req->pan_id;
/* Set channel first */
if (radio->set_channel(iface->dev, req->channel)) {
ret = -EIO;
goto out;
}
buf = ieee802154_create_mac_cmd_frame(
iface, IEEE802154_CFI_ASSOCIATION_REQUEST, &params);
if (!buf) {
ret = -ENOBUFS;
goto out;
}
cmd = ieee802154_get_mac_command(buf);
cmd->assoc_req.ci.dev_type = 0; /* RFD */
cmd->assoc_req.ci.power_src = 0; /* ToDo: set right power source */
cmd->assoc_req.ci.rx_on = 1; /* ToDo: that will depends on PM */
cmd->assoc_req.ci.sec_capability = 0; /* ToDo: security support */
cmd->assoc_req.ci.alloc_addr = 0; /* ToDo: handle short addr */
ctx->associated = false;
if (net_if_send_data(iface, buf)) {
net_nbuf_unref(buf);
ret = -EIO;
goto out;
}
/* ToDo: current timeout is arbitrary */
k_sem_take(&ctx->req_lock, K_SECONDS(1));
if (ctx->associated) {
ctx->channel = req->channel;
ctx->pan_id = req->pan_id;
} else {
ret = -EACCES;
}
out:
k_sem_give(&ctx->req_lock);
return ret;
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_IEEE802154_ASSOCIATE,
ieee802154_associate);
static int ieee802154_set_ack(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{

View file

@ -41,11 +41,15 @@ static inline void ieee802154_mgmt_init(struct net_if *iface)
enum net_verdict ieee802154_handle_beacon(struct net_if *iface,
struct ieee802154_mpdu *mpdu);
enum net_verdict ieee802154_handle_mac_command(struct net_if *iface,
struct ieee802154_mpdu *mpdu);
#else /* CONFIG_NET_MGMT */
#define ieee802154_is_scanning(...) false
#define ieee802154_mgmt_init(...)
#define ieee802154_handle_beacon(...) NET_DROP
#define ieee802154_handle_mac_command(...) NET_DROP
#endif /* CONFIG_NET_MGMT */