net: ieee802154: Add PAN disassociation request

If associated, this will request to disassociate from the PAN. That's
only client side, PAN coordinator can also disassociate a client, which
case is not handled here.

Change-Id: If308f51b62c5006b4a2db53d0c891e8192f3c198
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-10-20 09:44:42 +02:00
commit 820713239a
2 changed files with 64 additions and 0 deletions

View file

@ -37,6 +37,11 @@ struct ieee802154_context {
struct k_sem res_lock;
struct k_sem req_lock;
};
union {
uint8_t ext_addr[IEEE802154_MAX_ADDR_LENGTH];
uint16_t short_addr;
} coord;
uint8_t coord_addr_len;
#endif
uint8_t sequence;
uint8_t ack_received : 1;
@ -62,6 +67,7 @@ enum net_request_ieee802154_cmd {
NET_REQUEST_IEEE802154_CMD_ACTIVE_SCAN,
NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN,
NET_REQUEST_IEEE802154_CMD_ASSOCIATE,
NET_REQUEST_IEEE802154_CMD_DISASSOCIATE,
};
@ -95,6 +101,12 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_CANCEL_SCAN);
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_ASSOCIATE);
#define NET_REQUEST_IEEE802154_DISASSOCIATE \
(_NET_IEEE802154_BASE | NET_REQUEST_IEEE802154_CMD_DISASSOCIATE)
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_IEEE802154_DISASSOCIATE);
enum net_event_ieee802154_cmd {
NET_EVENT_IEEE802154_CMD_SCAN_RESULT = 1,
};

View file

@ -274,6 +274,14 @@ static int ieee802154_associate(uint32_t mgmt_request, struct net_if *iface,
if (ctx->associated) {
ctx->channel = req->channel;
ctx->pan_id = req->pan_id;
ctx->coord_addr_len = req->len;
if (ctx->coord_addr_len == IEEE802154_SHORT_ADDR_LENGTH) {
ctx->coord.short_addr = req->short_addr;
} else {
memcpy(ctx->coord.ext_addr,
req->addr, IEEE802154_EXT_ADDR_LENGTH);
}
} else {
ret = -EACCES;
}
@ -287,6 +295,50 @@ out:
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_IEEE802154_ASSOCIATE,
ieee802154_associate);
static int ieee802154_disassociate(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
struct ieee802154_frame_params params;
struct ieee802154_command *cmd;
struct net_buf *buf;
if (!ctx->associated) {
return -EALREADY;
}
params.dst.pan_id = ctx->pan_id;
params.dst.len = ctx->coord_addr_len;
if (params.dst.len == IEEE802154_SHORT_ADDR_LENGTH) {
params.dst.short_addr = ctx->coord.short_addr;
} else {
params.dst.ext_addr = ctx->coord.ext_addr;
}
params.pan_id = ctx->pan_id;
buf = ieee802154_create_mac_cmd_frame(
iface, IEEE802154_CFI_DISASSOCIATION_NOTIFICATION, &params);
if (!buf) {
return -ENOBUFS;
}
cmd = ieee802154_get_mac_command(buf);
cmd->disassoc_note.reason = IEEE802154_DRF_DEVICE_WISH;
if (net_if_send_data(iface, buf)) {
net_nbuf_unref(buf);
return -EIO;
}
ctx->associated = false;
return 0;
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_IEEE802154_DISASSOCIATE,
ieee802154_disassociate);
static int ieee802154_set_ack(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{