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:
parent
792c29a376
commit
b53e48de1b
3 changed files with 109 additions and 3 deletions
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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, ¶ms);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue