Instead of using 32 bit enum values for event numbers, convert the code to use 64 bit long bit fields. This means that the user API is changed to use 64 bit event values instead of 32 bit event values. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
698 lines
18 KiB
C
698 lines
18 KiB
C
/*
|
|
* Copyright (c) 2016 Intel Corporation
|
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(net_shell);
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/shell/shell_uart.h>
|
|
#include <zephyr/net/net_mgmt.h>
|
|
#include <zephyr/net/net_event.h>
|
|
#include <zephyr/net/coap_mgmt.h>
|
|
#include <zephyr/net/ethernet_mgmt.h>
|
|
|
|
#include "net_shell_private.h"
|
|
|
|
#if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
|
|
#define THREAD_PRIORITY K_PRIO_COOP(2)
|
|
#define MAX_EVENT_INFO_SIZE NET_EVENT_INFO_MAX_SIZE
|
|
#define MONITOR_L2_MASK (NET_EVENT_IF_BASE)
|
|
#define MONITOR_L3_IPV4_MASK (NET_EVENT_IPV4_BASE | NET_MGMT_COMMAND_MASK)
|
|
#define MONITOR_L3_IPV6_MASK (NET_EVENT_IPV6_BASE | NET_MGMT_COMMAND_MASK)
|
|
#define MONITOR_L4_MASK (NET_EVENT_L4_BASE | NET_MGMT_COMMAND_MASK)
|
|
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
#define MONITOR_L2_ETHERNET_MASK (NET_ETHERNET_BASE)
|
|
static struct net_mgmt_event_callback l2_ethernet_cb;
|
|
#endif
|
|
|
|
static bool net_event_monitoring;
|
|
static bool net_event_shutting_down;
|
|
static struct net_mgmt_event_callback l2_cb;
|
|
static struct net_mgmt_event_callback l3_ipv4_cb;
|
|
static struct net_mgmt_event_callback l3_ipv6_cb;
|
|
static struct net_mgmt_event_callback l4_cb;
|
|
static struct k_thread event_mon;
|
|
static K_THREAD_STACK_DEFINE(event_mon_stack, CONFIG_NET_MGMT_EVENT_MONITOR_STACK_SIZE);
|
|
|
|
static const char unknown_event_str[] = "<unknown event>";
|
|
|
|
struct event_msg {
|
|
struct net_if *iface;
|
|
size_t len;
|
|
uint64_t event;
|
|
uint8_t data[MAX_EVENT_INFO_SIZE];
|
|
};
|
|
|
|
K_MSGQ_DEFINE(event_mon_msgq, sizeof(struct event_msg),
|
|
CONFIG_NET_MGMT_EVENT_QUEUE_SIZE, sizeof(intptr_t));
|
|
|
|
static void event_handler(struct net_mgmt_event_callback *cb,
|
|
uint64_t mgmt_event, struct net_if *iface)
|
|
{
|
|
struct event_msg msg;
|
|
int ret;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
|
|
msg.len = MIN(sizeof(msg.data), cb->info_length);
|
|
msg.event = mgmt_event;
|
|
msg.iface = iface;
|
|
|
|
if (cb->info_length > 0) {
|
|
memcpy(msg.data, cb->info, msg.len);
|
|
}
|
|
|
|
ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(10));
|
|
if (ret < 0) {
|
|
NET_ERR("Cannot write to msgq (%d)\n", ret);
|
|
}
|
|
}
|
|
|
|
static char *get_l2_desc(struct event_msg *msg,
|
|
const char **desc, const char **desc2,
|
|
char *extra_info, size_t extra_info_len)
|
|
{
|
|
static const char *desc_unknown = unknown_event_str;
|
|
char *info = NULL;
|
|
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
#define MAX_VLAN_TAG_INFO_STR_LEN sizeof("tag xxxx disabled")
|
|
static char vlan_buf[MAX_VLAN_TAG_INFO_STR_LEN + 1];
|
|
#endif
|
|
|
|
*desc = desc_unknown;
|
|
|
|
switch (msg->event) {
|
|
case NET_EVENT_IF_DOWN:
|
|
*desc = "interface";
|
|
*desc2 = "down";
|
|
break;
|
|
case NET_EVENT_IF_UP:
|
|
*desc = "interface";
|
|
*desc2 = "up";
|
|
break;
|
|
case NET_EVENT_IF_ADMIN_UP:
|
|
*desc = "interface";
|
|
*desc2 = "admin up";
|
|
break;
|
|
case NET_EVENT_IF_ADMIN_DOWN:
|
|
*desc = "interface";
|
|
*desc2 = "admin down";
|
|
break;
|
|
case NET_EVENT_ETHERNET_CARRIER_ON:
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
*desc = "Ethernet";
|
|
*desc2 = "carrier on";
|
|
#endif
|
|
break;
|
|
case NET_EVENT_ETHERNET_CARRIER_OFF:
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
*desc = "Ethernet";
|
|
*desc2 = "carrier off";
|
|
#endif
|
|
break;
|
|
case NET_EVENT_ETHERNET_VLAN_TAG_ENABLED: {
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
uint16_t tag = *((uint16_t *)msg->data);
|
|
|
|
*desc = "VLAN";
|
|
snprintk(vlan_buf, MAX_VLAN_TAG_INFO_STR_LEN,
|
|
"tag %u enabled", (uint16_t)tag);
|
|
*desc2 = vlan_buf;
|
|
#endif
|
|
break;
|
|
}
|
|
case NET_EVENT_ETHERNET_VLAN_TAG_DISABLED: {
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
uint16_t tag = *((uint16_t *)msg->data);
|
|
|
|
*desc = "VLAN";
|
|
snprintk(vlan_buf, MAX_VLAN_TAG_INFO_STR_LEN,
|
|
"tag %u enabled", (uint16_t)tag);
|
|
*desc2 = vlan_buf;
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
static char *get_l3_desc(struct event_msg *msg,
|
|
const char **desc, const char **desc2,
|
|
char *extra_info, size_t extra_info_len)
|
|
{
|
|
static const char *desc_unknown = unknown_event_str;
|
|
char *info = NULL;
|
|
|
|
#if defined(CONFIG_NET_PMTU)
|
|
#define MAX_PMTU_INFO_STR_LEN sizeof("changed MTU xxxxx for")
|
|
static char pmtu_buf[MAX_PMTU_INFO_STR_LEN + 1];
|
|
#endif
|
|
|
|
*desc = desc_unknown;
|
|
|
|
switch (msg->event) {
|
|
case NET_EVENT_IPV6_ADDR_ADD:
|
|
*desc = "IPv6 address";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_ADDR_DEPRECATED:
|
|
*desc = "IPv6 address";
|
|
*desc2 = "deprecated";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_ADDR_DEL:
|
|
*desc = "IPv6 address";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_MADDR_ADD:
|
|
*desc = "IPv6 mcast address";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_MADDR_DEL:
|
|
*desc = "IPv6 mcast address";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_PREFIX_ADD:
|
|
*desc = "IPv6 prefix";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_PREFIX_DEL:
|
|
*desc = "IPv6 prefix";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_MCAST_JOIN:
|
|
*desc = "IPv6 mcast";
|
|
*desc2 = "join";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_MCAST_LEAVE:
|
|
*desc = "IPv6 mcast";
|
|
*desc2 = "leave";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_ROUTER_ADD:
|
|
*desc = "IPv6 router";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_ROUTER_DEL:
|
|
*desc = "IPv6 router";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_ROUTE_ADD:
|
|
*desc = "IPv6 route";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_ROUTE_DEL:
|
|
*desc = "IPv6 route";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_DAD_SUCCEED:
|
|
*desc = "IPv6 DAD";
|
|
*desc2 = "ok";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_DAD_FAILED:
|
|
*desc = "IPv6 DAD";
|
|
*desc2 = "fail";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_NBR_ADD:
|
|
*desc = "IPv6 neighbor";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_NBR_DEL:
|
|
*desc = "IPv6 neighbor";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_PE_ENABLED:
|
|
*desc = "IPv6 PE";
|
|
*desc2 = "enabled";
|
|
break;
|
|
case NET_EVENT_IPV6_PE_DISABLED:
|
|
*desc = "IPv6 PE";
|
|
*desc2 = "disabled";
|
|
break;
|
|
case NET_EVENT_IPV6_PE_FILTER_ADD:
|
|
*desc = "IPv6 PE filter";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV6_PE_FILTER_DEL:
|
|
*desc = "IPv6 PE filter";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET6, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_ADDR_ADD:
|
|
*desc = "IPv4 address";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_ADDR_DEL:
|
|
*desc = "IPv4 address";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_MADDR_ADD:
|
|
*desc = "IPv4 mcast address";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_MADDR_DEL:
|
|
*desc = "IPv4 mcast address";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_ROUTER_ADD:
|
|
*desc = "IPv4 router";
|
|
*desc2 = "add";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_ROUTER_DEL:
|
|
*desc = "IPv4 router";
|
|
*desc2 = "del";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_DHCP_START:
|
|
*desc = "DHCPv4";
|
|
*desc2 = "start";
|
|
break;
|
|
case NET_EVENT_IPV4_DHCP_BOUND:
|
|
*desc = "DHCPv4";
|
|
*desc2 = "bound";
|
|
#if defined(CONFIG_NET_DHCPV4)
|
|
struct net_if_dhcpv4 *data = (struct net_if_dhcpv4 *)msg->data;
|
|
|
|
info = net_addr_ntop(AF_INET, &data->requested_ip, extra_info,
|
|
extra_info_len);
|
|
#endif
|
|
break;
|
|
case NET_EVENT_IPV4_DHCP_STOP:
|
|
*desc = "DHCPv4";
|
|
*desc2 = "stop";
|
|
break;
|
|
case NET_EVENT_IPV4_MCAST_JOIN:
|
|
*desc = "IPv4 mcast";
|
|
*desc2 = "join";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_MCAST_LEAVE:
|
|
*desc = "IPv4 mcast";
|
|
*desc2 = "leave";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_ACD_SUCCEED:
|
|
*desc = "IPv4 ACD";
|
|
*desc2 = "ok";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_ACD_FAILED:
|
|
*desc = "IPv4 ACD";
|
|
*desc2 = "fail";
|
|
info = net_addr_ntop(AF_INET, msg->data, extra_info,
|
|
extra_info_len);
|
|
break;
|
|
case NET_EVENT_IPV4_PMTU_CHANGED: {
|
|
#if defined(CONFIG_NET_IPV4_PMTU)
|
|
struct net_event_ipv4_pmtu_info *pmtu_info =
|
|
(struct net_event_ipv4_pmtu_info *)msg->data;
|
|
|
|
*desc = "IPV4 PMTU";
|
|
*desc2 = pmtu_buf;
|
|
snprintk(pmtu_buf, MAX_PMTU_INFO_STR_LEN,
|
|
"changed MTU %u for", (uint16_t)pmtu_info->mtu);
|
|
info = net_addr_ntop(AF_INET, &pmtu_info->dst, extra_info,
|
|
extra_info_len);
|
|
#endif
|
|
break;
|
|
}
|
|
case NET_EVENT_IPV6_PMTU_CHANGED: {
|
|
#if defined(CONFIG_NET_IPV6_PMTU)
|
|
struct net_event_ipv6_pmtu_info *pmtu_info =
|
|
(struct net_event_ipv6_pmtu_info *)msg->data;
|
|
|
|
*desc = "IPV6 PMTU";
|
|
*desc2 = pmtu_buf;
|
|
snprintk(pmtu_buf, MAX_PMTU_INFO_STR_LEN,
|
|
"changed MTU %u for", (uint16_t)pmtu_info->mtu);
|
|
info = net_addr_ntop(AF_INET6, &pmtu_info->dst, extra_info,
|
|
extra_info_len);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
static char *sockaddr_ntop(const struct sockaddr *addr, char *dst, size_t size)
|
|
{
|
|
if (addr->sa_family == AF_INET) {
|
|
return net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr, dst, size);
|
|
} else if (addr->sa_family == AF_INET6) {
|
|
return net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr, dst, size);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static char *get_l4_desc(struct event_msg *msg,
|
|
const char **desc, const char **desc2,
|
|
char *extra_info, size_t extra_info_len)
|
|
{
|
|
static const char *desc_unknown = unknown_event_str;
|
|
char *info = NULL;
|
|
|
|
*desc = desc_unknown;
|
|
|
|
switch (msg->event) {
|
|
case NET_EVENT_L4_CONNECTED:
|
|
*desc = "connected";
|
|
break;
|
|
case NET_EVENT_L4_DISCONNECTED:
|
|
*desc = "disconnected";
|
|
break;
|
|
case NET_EVENT_L4_IPV4_CONNECTED:
|
|
*desc = "IPv4 connectivity";
|
|
*desc2 = "available";
|
|
break;
|
|
case NET_EVENT_L4_IPV4_DISCONNECTED:
|
|
*desc = "IPv4 connectivity";
|
|
*desc2 = "lost";
|
|
break;
|
|
case NET_EVENT_L4_IPV6_CONNECTED:
|
|
*desc = "IPv6 connectivity";
|
|
*desc2 = "available";
|
|
break;
|
|
case NET_EVENT_L4_IPV6_DISCONNECTED:
|
|
*desc = "IPv6 connectivity";
|
|
*desc2 = "lost";
|
|
break;
|
|
case NET_EVENT_DNS_SERVER_ADD: {
|
|
struct sockaddr *addr = (struct sockaddr *)msg->data;
|
|
|
|
*desc = "DNS server";
|
|
*desc2 = "add";
|
|
|
|
info = sockaddr_ntop(addr, extra_info, extra_info_len);
|
|
|
|
break;
|
|
}
|
|
case NET_EVENT_DNS_SERVER_DEL: {
|
|
struct sockaddr *addr = (struct sockaddr *)msg->data;
|
|
|
|
*desc = "DNS server";
|
|
*desc2 = "del";
|
|
|
|
info = sockaddr_ntop(addr, extra_info, extra_info_len);
|
|
|
|
break;
|
|
}
|
|
case NET_EVENT_HOSTNAME_CHANGED:
|
|
*desc = "Hostname changed";
|
|
break;
|
|
case NET_EVENT_COAP_SERVICE_STARTED:
|
|
*desc = "CoAP service";
|
|
*desc2 = "started";
|
|
break;
|
|
case NET_EVENT_COAP_SERVICE_STOPPED:
|
|
*desc = "CoAP service";
|
|
*desc2 = "stopped";
|
|
break;
|
|
case NET_EVENT_COAP_OBSERVER_ADDED:
|
|
*desc = "CoAP observer";
|
|
*desc2 = "added";
|
|
break;
|
|
case NET_EVENT_COAP_OBSERVER_REMOVED:
|
|
*desc = "CoAP observer";
|
|
*desc2 = "removed";
|
|
break;
|
|
case NET_EVENT_CAPTURE_STARTED:
|
|
*desc = "Capture";
|
|
*desc2 = "started";
|
|
break;
|
|
case NET_EVENT_CAPTURE_STOPPED:
|
|
*desc = "Capture";
|
|
*desc2 = "stopped";
|
|
break;
|
|
case NET_EVENT_VPN_PEER_ADD:
|
|
*desc = "VPN peer";
|
|
*desc2 = "add";
|
|
break;
|
|
case NET_EVENT_VPN_PEER_DEL:
|
|
*desc = "VPN peer";
|
|
*desc2 = "del";
|
|
break;
|
|
case NET_EVENT_VPN_CONNECTED:
|
|
*desc = "VPN";
|
|
*desc2 = "connected";
|
|
break;
|
|
case NET_EVENT_VPN_DISCONNECTED:
|
|
*desc = "VPN";
|
|
*desc2 = "disconnected";
|
|
break;
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
/* We use a separate thread in order not to do any shell printing from
|
|
* event handler callback (to avoid stack size issues).
|
|
*/
|
|
static void event_mon_handler(const struct shell *sh, void *p2, void *p3)
|
|
{
|
|
char extra_info[NET_IPV6_ADDR_LEN + sizeof("id 0123456789 ")];
|
|
struct event_msg msg;
|
|
|
|
ARG_UNUSED(p2);
|
|
ARG_UNUSED(p3);
|
|
net_mgmt_init_event_callback(&l2_cb, event_handler,
|
|
MONITOR_L2_MASK);
|
|
net_mgmt_add_event_callback(&l2_cb);
|
|
|
|
net_mgmt_init_event_callback(&l3_ipv4_cb, event_handler,
|
|
MONITOR_L3_IPV4_MASK);
|
|
net_mgmt_add_event_callback(&l3_ipv4_cb);
|
|
|
|
net_mgmt_init_event_callback(&l3_ipv6_cb, event_handler,
|
|
MONITOR_L3_IPV6_MASK);
|
|
net_mgmt_add_event_callback(&l3_ipv6_cb);
|
|
|
|
net_mgmt_init_event_callback(&l4_cb, event_handler,
|
|
MONITOR_L4_MASK);
|
|
net_mgmt_add_event_callback(&l4_cb);
|
|
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
net_mgmt_init_event_callback(&l2_ethernet_cb, event_handler,
|
|
MONITOR_L2_ETHERNET_MASK);
|
|
net_mgmt_add_event_callback(&l2_ethernet_cb);
|
|
#endif
|
|
|
|
while (net_event_shutting_down == false) {
|
|
const char *layer_str = "<unknown layer>";
|
|
const char *desc = "", *desc2 = "";
|
|
char *info = NULL;
|
|
uint32_t layer;
|
|
|
|
(void)k_msgq_get(&event_mon_msgq, &msg, K_FOREVER);
|
|
|
|
if (msg.iface == NULL && msg.event == 0 && msg.len == 0) {
|
|
/* This is the stop message */
|
|
continue;
|
|
}
|
|
|
|
layer = NET_MGMT_GET_LAYER(msg.event);
|
|
if (layer == NET_MGMT_LAYER_L2) {
|
|
layer_str = "L2";
|
|
info = get_l2_desc(&msg, &desc, &desc2,
|
|
extra_info, sizeof(extra_info));
|
|
} else if (layer == NET_MGMT_LAYER_L3) {
|
|
layer_str = "L3";
|
|
info = get_l3_desc(&msg, &desc, &desc2,
|
|
extra_info, sizeof(extra_info));
|
|
} else if (layer == NET_MGMT_LAYER_L4) {
|
|
layer_str = "L4";
|
|
info = get_l4_desc(&msg, &desc, &desc2,
|
|
extra_info, sizeof(extra_info));
|
|
}
|
|
|
|
if (desc == unknown_event_str) {
|
|
PR_INFO("EVENT: %s [%d] %s%s%s%s%s (0x%" PRIx64 ")\n", layer_str,
|
|
net_if_get_by_iface(msg.iface), desc,
|
|
desc2 ? " " : "", desc2 ? desc2 : "",
|
|
info ? " " : "", info ? info : "", msg.event);
|
|
} else {
|
|
PR_INFO("EVENT: %s [%d] %s%s%s%s%s\n", layer_str,
|
|
net_if_get_by_iface(msg.iface), desc,
|
|
desc2 ? " " : "", desc2 ? desc2 : "",
|
|
info ? " " : "", info ? info : "");
|
|
}
|
|
}
|
|
|
|
net_mgmt_del_event_callback(&l2_cb);
|
|
net_mgmt_del_event_callback(&l3_ipv4_cb);
|
|
net_mgmt_del_event_callback(&l3_ipv6_cb);
|
|
net_mgmt_del_event_callback(&l4_cb);
|
|
|
|
#if defined(CONFIG_NET_L2_ETHERNET_MGMT)
|
|
net_mgmt_del_event_callback(&l2_ethernet_cb);
|
|
#endif
|
|
|
|
k_msgq_purge(&event_mon_msgq);
|
|
|
|
net_event_monitoring = false;
|
|
net_event_shutting_down = false;
|
|
|
|
PR_INFO("Network event monitoring %s.\n", "disabled");
|
|
}
|
|
#endif
|
|
|
|
static int cmd_net_events_on(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
#if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
|
|
k_tid_t tid;
|
|
|
|
if (net_event_monitoring) {
|
|
PR_INFO("Network event monitoring is already %s.\n",
|
|
"enabled");
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
tid = k_thread_create(&event_mon, event_mon_stack,
|
|
K_THREAD_STACK_SIZEOF(event_mon_stack),
|
|
(k_thread_entry_t)event_mon_handler,
|
|
(void *)sh, NULL, NULL, THREAD_PRIORITY, 0,
|
|
K_FOREVER);
|
|
if (!tid) {
|
|
PR_ERROR("Cannot create network event monitor thread!");
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
k_thread_name_set(tid, "event_mon");
|
|
|
|
PR_INFO("Network event monitoring %s.\n", "enabled");
|
|
|
|
net_event_monitoring = true;
|
|
net_event_shutting_down = false;
|
|
|
|
k_thread_start(tid);
|
|
#else
|
|
PR_INFO("Network management events are not supported. "
|
|
"Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_events_off(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
#if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
|
|
static const struct event_msg msg;
|
|
int ret;
|
|
|
|
if (!net_event_monitoring) {
|
|
PR_INFO("Network event monitoring is already %s.\n",
|
|
"disabled");
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
net_event_shutting_down = true;
|
|
|
|
ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(100));
|
|
if (ret < 0) {
|
|
PR_ERROR("Cannot write to msgq (%d)\n", ret);
|
|
return -ENOEXEC;
|
|
}
|
|
#else
|
|
PR_INFO("Network management events are not supported. "
|
|
"Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_events(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
#if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
|
|
PR("Network event monitoring is %s.\n",
|
|
net_event_monitoring ? "enabled" : "disabled");
|
|
|
|
if (!argv[1]) {
|
|
PR_INFO("Give 'on' to enable event monitoring and "
|
|
"'off' to disable it.\n");
|
|
}
|
|
#else
|
|
PR_INFO("Network management events are not supported. "
|
|
"Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
void events_enable(void)
|
|
{
|
|
static const char * const argv[] = {
|
|
"on",
|
|
NULL
|
|
};
|
|
|
|
(void)cmd_net_events_on(shell_backend_uart_get_ptr(), 1, (char **)argv);
|
|
}
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_events,
|
|
SHELL_CMD(on, NULL, "Turn on network event monitoring.",
|
|
cmd_net_events_on),
|
|
SHELL_CMD(off, NULL, "Turn off network event monitoring.",
|
|
cmd_net_events_off),
|
|
SHELL_SUBCMD_SET_END
|
|
);
|
|
|
|
SHELL_SUBCMD_ADD((net), events, &net_cmd_events, "Monitor network management events.",
|
|
cmd_net_events, 1, 1);
|