net: ieee802154: Add a shell module named 'ieee15_4'
This one exposes IEEE 802.15.4 net mgmt requests through the shell. User has then the ability to directly make relevant requests like raising a scan, associating, etc... For now, it assumes the 15.4 interface is the only one on the system and thus will rely on net_if_get_default(). Change-Id: I8eb20565b8231e6cfcba6c1479179cc85ff1d8e5 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
6b41aecd99
commit
336e3f8721
4 changed files with 309 additions and 0 deletions
|
@ -69,6 +69,15 @@ config NET_L2_IEEE802154_RFD
|
|||
thus it is not set as the default level
|
||||
endchoice
|
||||
|
||||
config NET_L2_IEEE802154_SHELL
|
||||
bool "Enable IEEE 802.15.4 shell module"
|
||||
default n
|
||||
select CONSOLE_SHELL
|
||||
depends on NET_L2_IEEE802154_RFD
|
||||
help
|
||||
This can be used for testing 15.4 through the console via exposing
|
||||
a shell module named "ieee15_4".
|
||||
|
||||
config NET_L2_IEEE802154_ACK_SET
|
||||
bool "Expose ACK request setting"
|
||||
default n
|
||||
|
|
|
@ -4,6 +4,7 @@ obj-$(CONFIG_NET_L2_IEEE802154) += ieee802154.o \
|
|||
ieee802154_frame.o
|
||||
|
||||
obj-$(CONFIG_NET_L2_IEEE802154_MGMT) += ieee802154_mgmt.o
|
||||
obj-$(CONFIG_NET_L2_IEEE802154_SHELL) += ieee802154_shell.o
|
||||
obj-$(CONFIG_NET_L2_IEEE802154_RADIO_ALOHA) += ieee802154_radio_aloha.o
|
||||
obj-$(CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA) += ieee802154_radio_csma_ca.o
|
||||
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
#ifndef __IEEE802154_MGMT_H__
|
||||
#define __IEEE802154_MGMT_H__
|
||||
|
||||
#include "ieee802154_frame.h"
|
||||
|
||||
#ifdef CONFIG_NET_L2_IEEE802154_SHELL
|
||||
void ieee802154_shell_init(void);
|
||||
#else
|
||||
#define ieee802154_shell_init(...)
|
||||
#endif /* CONFIG_NET_L2_IEEE802154_SHELL */
|
||||
|
||||
#ifdef CONFIG_NET_MGMT
|
||||
|
||||
static inline bool ieee802154_is_scanning(struct net_if *iface)
|
||||
|
@ -36,6 +44,8 @@ static inline void ieee802154_mgmt_init(struct net_if *iface)
|
|||
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
||||
|
||||
k_sem_init(&ctx->res_lock, 1, 1);
|
||||
|
||||
ieee802154_shell_init();
|
||||
}
|
||||
|
||||
enum net_verdict ieee802154_handle_beacon(struct net_if *iface,
|
||||
|
|
289
subsys/net/ip/l2/ieee802154/ieee802154_shell.c
Normal file
289
subsys/net/ip/l2/ieee802154/ieee802154_shell.c
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief IEEE 802.15.4 shell module
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <shell/shell.h>
|
||||
#include <misc/printk.h>
|
||||
|
||||
#include <net/net_if.h>
|
||||
#include <net/ieee802154.h>
|
||||
|
||||
#include "ieee802154_mgmt.h"
|
||||
#include "ieee802154_frame.h"
|
||||
|
||||
#define IEEE802154_SHELL_MODULE "ieee15_4"
|
||||
|
||||
struct ieee802154_req_params params;
|
||||
static struct net_mgmt_event_callback scan_cb;
|
||||
|
||||
static int shell_cmd_ack(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
|
||||
if (!strcmp(argv[1], "set") || !strcmp(argv[1], "1")) {
|
||||
net_mgmt(NET_REQUEST_IEEE802154_SET_ACK, iface, NULL, 0);
|
||||
printk("ACK flag set on outgoing packets\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "unset") || !strcmp(argv[1], "0")) {
|
||||
net_mgmt(NET_REQUEST_IEEE802154_SET_ACK, iface, NULL, 0);
|
||||
printk("ACK flag unset on outgoing packets\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline void parse_extended_address(char *addr, uint8_t *ext_addr)
|
||||
{
|
||||
char *p, *n;
|
||||
int i = 0;
|
||||
|
||||
p = addr;
|
||||
|
||||
do {
|
||||
n = strchr(p, ':');
|
||||
if (n) {
|
||||
*n = '\0';
|
||||
}
|
||||
|
||||
ext_addr[i] = strtol(p, NULL, 16);
|
||||
p = n ? n + 1 : n;
|
||||
} while (n);
|
||||
}
|
||||
|
||||
static int shell_cmd_associate(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
|
||||
params.pan_id = atoi(argv[1]);
|
||||
|
||||
if (strlen(argv[2]) == 23) {
|
||||
parse_extended_address(argv[2], params.addr);
|
||||
params.len = IEEE802154_EXT_ADDR_LENGTH;
|
||||
} else {
|
||||
params.short_addr = (uint16_t) atoi(argv[2]);
|
||||
params.len = IEEE802154_SHORT_ADDR_LENGTH;
|
||||
}
|
||||
|
||||
if (net_mgmt(NET_REQUEST_IEEE802154_ASSOCIATE, iface,
|
||||
¶ms, sizeof(struct ieee802154_req_params))) {
|
||||
printk("Could not associate to %s on PAN ID %u",
|
||||
argv[2], params.pan_id);
|
||||
} else {
|
||||
printk("Associated to PAN ID %u", params.pan_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_cmd_disassociate(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
int ret;
|
||||
|
||||
ret = net_mgmt(NET_REQUEST_IEEE802154_DISASSOCIATE, iface, NULL, 0);
|
||||
if (ret == -EALREADY) {
|
||||
printk("Interface is not associated\n");
|
||||
} else if (ret) {
|
||||
printk("Could not disassociate? (status: %i)\n", ret);
|
||||
} else {
|
||||
printk("Interface is now disassociated\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t parse_channel_set(char *str_set)
|
||||
{
|
||||
uint32_t channel_set = 0;
|
||||
char *p, *n;
|
||||
|
||||
p = str_set;
|
||||
|
||||
do {
|
||||
uint32_t chan;
|
||||
|
||||
n = strchr(p, ':');
|
||||
if (n) {
|
||||
*n = '\0';
|
||||
}
|
||||
|
||||
chan = atoi(p);
|
||||
channel_set |= BIT(chan - 1);
|
||||
p = n ? n + 1 : n;
|
||||
} while (n);
|
||||
|
||||
return channel_set;
|
||||
}
|
||||
|
||||
static inline void print_coordinator_address(void)
|
||||
{
|
||||
if (params.len == IEEE802154_EXT_ADDR_LENGTH) {
|
||||
int i;
|
||||
|
||||
printk("(extended) ");
|
||||
|
||||
for (i = 0; i < IEEE802154_EXT_ADDR_LENGTH; i++) {
|
||||
printk("%02X", params.addr[i]);
|
||||
|
||||
if (i < (IEEE802154_EXT_ADDR_LENGTH - 1)) {
|
||||
printk(":");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printk("(short) %u", params.short_addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void scan_result_cb(struct net_mgmt_event_callback *cb,
|
||||
uint32_t mgmt_event, struct net_if *iface)
|
||||
{
|
||||
printk("\nChannel: %u\tPAN ID: %u\tCoordinator Address: ",
|
||||
params.channel, params.pan_id);
|
||||
print_coordinator_address();
|
||||
printk("LQI: %u\n", params.lqi);
|
||||
}
|
||||
|
||||
static int shell_cmd_scan(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
uint32_t scan_type;
|
||||
int ret;
|
||||
|
||||
memset(¶ms, 0, sizeof(struct ieee802154_req_params));
|
||||
|
||||
net_mgmt_init_event_callback(&scan_cb, scan_result_cb,
|
||||
NET_EVENT_IEEE802154_SCAN_RESULT);
|
||||
|
||||
if (!strcmp(argv[1], "active")) {
|
||||
scan_type = NET_REQUEST_IEEE802154_ACTIVE_SCAN;
|
||||
} else if (!strcmp(argv[1], "passive")) {
|
||||
scan_type = NET_REQUEST_IEEE802154_PASSIVE_SCAN;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[2], "all")) {
|
||||
params.channel_set = IEEE802154_ALL_CHANNELS;
|
||||
} else {
|
||||
params.channel_set = parse_channel_set(argv[2]);
|
||||
}
|
||||
|
||||
if (!params.channel_set) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
params.duration = atoi(argv[3]);
|
||||
|
||||
printk("%s Scanning (channel set: 0x%08x, duration %u ms)...",
|
||||
scan_type == NET_REQUEST_IEEE802154_ACTIVE_SCAN ?
|
||||
"Active" : "Passive", params.channel_set, params.duration);
|
||||
|
||||
if (scan_type == NET_REQUEST_IEEE802154_ACTIVE_SCAN) {
|
||||
ret = net_mgmt(NET_REQUEST_IEEE802154_ACTIVE_SCAN, iface,
|
||||
¶ms, sizeof(struct ieee802154_req_params));
|
||||
} else {
|
||||
ret = net_mgmt(NET_REQUEST_IEEE802154_PASSIVE_SCAN, iface,
|
||||
¶ms, sizeof(struct ieee802154_req_params));
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
printk("Could not raise a scan (status: %i)\n", ret);
|
||||
} else {
|
||||
printk("Done\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_cmd_set_chan(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
uint16_t channel = (uint16_t) atoi(argv[1]);
|
||||
|
||||
if (net_mgmt(NET_REQUEST_IEEE802154_SET_CHAN, iface,
|
||||
&channel, sizeof(uint16_t))) {
|
||||
printk("Could not set channel %u\n", channel);
|
||||
} else {
|
||||
printk("Channel %u set\n", channel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_cmd_set_pan_id(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
uint16_t pan_id = (uint16_t) atoi(argv[1]);
|
||||
|
||||
if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, iface,
|
||||
&pan_id, sizeof(uint16_t))) {
|
||||
printk("Could not set PAN ID %u\n", pan_id);
|
||||
} else {
|
||||
printk("PAN ID %u set\n", pan_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_cmd_set_short_addr(int argc, char *argv[])
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
uint16_t short_addr = (uint16_t) atoi(argv[1]);
|
||||
|
||||
if (net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface,
|
||||
&short_addr, sizeof(uint16_t))) {
|
||||
printk("Could not set short address %u\n", short_addr);
|
||||
} else {
|
||||
printk("Short address %u set\n", short_addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shell_cmd ieee802154_commands[] = {
|
||||
{ "ack", shell_cmd_ack,
|
||||
"<set/1 | unset/0>" },
|
||||
{ "associate", shell_cmd_associate,
|
||||
"<pan_id> <PAN coordinator short or long address>" },
|
||||
{ "disassociate", shell_cmd_disassociate,
|
||||
NULL },
|
||||
{ "scan", shell_cmd_scan,
|
||||
"<passive|active> <channels set n[:m:...]:x|all>"
|
||||
" <per-channel duration in ms>" },
|
||||
{ "set_chan", shell_cmd_set_chan,
|
||||
"<channel>" },
|
||||
{ "set_pan_id", shell_cmd_set_pan_id,
|
||||
"<pan_id>" },
|
||||
{ "set_short_addr", shell_cmd_set_short_addr,
|
||||
"<short address>" },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
void ieee802154_shell_init(void)
|
||||
{
|
||||
SHELL_REGISTER(IEEE802154_SHELL_MODULE, ieee802154_commands);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue