1 /*
2 * Copyright (c) 2016 Intel Corporation
3 * Copyright (c) 2023 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/logging/log.h>
9 LOG_MODULE_DECLARE(net_shell);
10
11 #include <zephyr/kernel.h>
12 #include <zephyr/shell/shell_uart.h>
13 #include <zephyr/net/net_mgmt.h>
14 #include <zephyr/net/net_event.h>
15 #include <zephyr/net/coap_mgmt.h>
16 #include <zephyr/net/ethernet_mgmt.h>
17
18 #include "net_shell_private.h"
19
20 #if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
21 #define THREAD_PRIORITY K_PRIO_COOP(2)
22 #define MAX_EVENT_INFO_SIZE NET_EVENT_INFO_MAX_SIZE
23 #define MONITOR_L2_MASK (_NET_EVENT_IF_BASE)
24 #define MONITOR_L3_IPV4_MASK (_NET_EVENT_IPV4_BASE | NET_MGMT_COMMAND_MASK)
25 #define MONITOR_L3_IPV6_MASK (_NET_EVENT_IPV6_BASE | NET_MGMT_COMMAND_MASK)
26 #define MONITOR_L4_MASK (_NET_EVENT_L4_BASE | NET_MGMT_COMMAND_MASK)
27
28 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
29 #define MONITOR_L2_ETHERNET_MASK (_NET_ETHERNET_BASE)
30 static struct net_mgmt_event_callback l2_ethernet_cb;
31 #endif
32
33 static bool net_event_monitoring;
34 static bool net_event_shutting_down;
35 static struct net_mgmt_event_callback l2_cb;
36 static struct net_mgmt_event_callback l3_ipv4_cb;
37 static struct net_mgmt_event_callback l3_ipv6_cb;
38 static struct net_mgmt_event_callback l4_cb;
39 static struct k_thread event_mon;
40 static K_THREAD_STACK_DEFINE(event_mon_stack, CONFIG_NET_MGMT_EVENT_MONITOR_STACK_SIZE);
41
42 static const char unknown_event_str[] = "<unknown event>";
43
44 struct event_msg {
45 struct net_if *iface;
46 size_t len;
47 uint32_t event;
48 uint8_t data[MAX_EVENT_INFO_SIZE];
49 };
50
51 K_MSGQ_DEFINE(event_mon_msgq, sizeof(struct event_msg),
52 CONFIG_NET_MGMT_EVENT_QUEUE_SIZE, sizeof(intptr_t));
53
event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)54 static void event_handler(struct net_mgmt_event_callback *cb,
55 uint32_t mgmt_event, struct net_if *iface)
56 {
57 struct event_msg msg;
58 int ret;
59
60 memset(&msg, 0, sizeof(msg));
61
62 msg.len = MIN(sizeof(msg.data), cb->info_length);
63 msg.event = mgmt_event;
64 msg.iface = iface;
65
66 if (cb->info_length > 0) {
67 memcpy(msg.data, cb->info, msg.len);
68 }
69
70 ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(10));
71 if (ret < 0) {
72 NET_ERR("Cannot write to msgq (%d)\n", ret);
73 }
74 }
75
get_l2_desc(struct event_msg * msg,const char ** desc,const char ** desc2,char * extra_info,size_t extra_info_len)76 static char *get_l2_desc(struct event_msg *msg,
77 const char **desc, const char **desc2,
78 char *extra_info, size_t extra_info_len)
79 {
80 static const char *desc_unknown = unknown_event_str;
81 char *info = NULL;
82
83 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
84 #define MAX_VLAN_TAG_INFO_STR_LEN sizeof("tag xxxx disabled")
85 static char vlan_buf[MAX_VLAN_TAG_INFO_STR_LEN + 1];
86 #endif
87
88 *desc = desc_unknown;
89
90 switch (msg->event) {
91 case NET_EVENT_IF_DOWN:
92 *desc = "interface";
93 *desc2 = "down";
94 break;
95 case NET_EVENT_IF_UP:
96 *desc = "interface";
97 *desc2 = "up";
98 break;
99 case NET_EVENT_IF_ADMIN_UP:
100 *desc = "interface";
101 *desc2 = "admin up";
102 break;
103 case NET_EVENT_IF_ADMIN_DOWN:
104 *desc = "interface";
105 *desc2 = "admin down";
106 break;
107 case NET_EVENT_ETHERNET_CARRIER_ON:
108 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
109 *desc = "Ethernet";
110 *desc2 = "carrier on";
111 #endif
112 break;
113 case NET_EVENT_ETHERNET_CARRIER_OFF:
114 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
115 *desc = "Ethernet";
116 *desc2 = "carrier off";
117 #endif
118 break;
119 case NET_EVENT_ETHERNET_VLAN_TAG_ENABLED: {
120 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
121 uint16_t tag = *((uint16_t *)msg->data);
122
123 *desc = "VLAN";
124 snprintk(vlan_buf, MAX_VLAN_TAG_INFO_STR_LEN,
125 "tag %u enabled", (uint16_t)tag);
126 *desc2 = vlan_buf;
127 #endif
128 break;
129 }
130 case NET_EVENT_ETHERNET_VLAN_TAG_DISABLED: {
131 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
132 uint16_t tag = *((uint16_t *)msg->data);
133
134 *desc = "VLAN";
135 snprintk(vlan_buf, MAX_VLAN_TAG_INFO_STR_LEN,
136 "tag %u enabled", (uint16_t)tag);
137 *desc2 = vlan_buf;
138 #endif
139 break;
140 }
141 }
142
143 return info;
144 }
145
get_l3_desc(struct event_msg * msg,const char ** desc,const char ** desc2,char * extra_info,size_t extra_info_len)146 static char *get_l3_desc(struct event_msg *msg,
147 const char **desc, const char **desc2,
148 char *extra_info, size_t extra_info_len)
149 {
150 static const char *desc_unknown = unknown_event_str;
151 char *info = NULL;
152
153 #if defined(CONFIG_NET_PMTU)
154 #define MAX_PMTU_INFO_STR_LEN sizeof("changed MTU xxxxx for")
155 static char pmtu_buf[MAX_PMTU_INFO_STR_LEN + 1];
156 #endif
157
158 *desc = desc_unknown;
159
160 switch (msg->event) {
161 case NET_EVENT_IPV6_ADDR_ADD:
162 *desc = "IPv6 address";
163 *desc2 = "add";
164 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
165 extra_info_len);
166 break;
167 case NET_EVENT_IPV6_ADDR_DEPRECATED:
168 *desc = "IPv6 address";
169 *desc2 = "deprecated";
170 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
171 extra_info_len);
172 break;
173 case NET_EVENT_IPV6_ADDR_DEL:
174 *desc = "IPv6 address";
175 *desc2 = "del";
176 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
177 extra_info_len);
178 break;
179 case NET_EVENT_IPV6_MADDR_ADD:
180 *desc = "IPv6 mcast address";
181 *desc2 = "add";
182 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
183 extra_info_len);
184 break;
185 case NET_EVENT_IPV6_MADDR_DEL:
186 *desc = "IPv6 mcast address";
187 *desc2 = "del";
188 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
189 extra_info_len);
190 break;
191 case NET_EVENT_IPV6_PREFIX_ADD:
192 *desc = "IPv6 prefix";
193 *desc2 = "add";
194 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
195 extra_info_len);
196 break;
197 case NET_EVENT_IPV6_PREFIX_DEL:
198 *desc = "IPv6 prefix";
199 *desc2 = "del";
200 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
201 extra_info_len);
202 break;
203 case NET_EVENT_IPV6_MCAST_JOIN:
204 *desc = "IPv6 mcast";
205 *desc2 = "join";
206 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
207 extra_info_len);
208 break;
209 case NET_EVENT_IPV6_MCAST_LEAVE:
210 *desc = "IPv6 mcast";
211 *desc2 = "leave";
212 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
213 extra_info_len);
214 break;
215 case NET_EVENT_IPV6_ROUTER_ADD:
216 *desc = "IPv6 router";
217 *desc2 = "add";
218 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
219 extra_info_len);
220 break;
221 case NET_EVENT_IPV6_ROUTER_DEL:
222 *desc = "IPv6 router";
223 *desc2 = "del";
224 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
225 extra_info_len);
226 break;
227 case NET_EVENT_IPV6_ROUTE_ADD:
228 *desc = "IPv6 route";
229 *desc2 = "add";
230 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
231 extra_info_len);
232 break;
233 case NET_EVENT_IPV6_ROUTE_DEL:
234 *desc = "IPv6 route";
235 *desc2 = "del";
236 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
237 extra_info_len);
238 break;
239 case NET_EVENT_IPV6_DAD_SUCCEED:
240 *desc = "IPv6 DAD";
241 *desc2 = "ok";
242 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
243 extra_info_len);
244 break;
245 case NET_EVENT_IPV6_DAD_FAILED:
246 *desc = "IPv6 DAD";
247 *desc2 = "fail";
248 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
249 extra_info_len);
250 break;
251 case NET_EVENT_IPV6_NBR_ADD:
252 *desc = "IPv6 neighbor";
253 *desc2 = "add";
254 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
255 extra_info_len);
256 break;
257 case NET_EVENT_IPV6_NBR_DEL:
258 *desc = "IPv6 neighbor";
259 *desc2 = "del";
260 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
261 extra_info_len);
262 break;
263 case NET_EVENT_IPV6_PE_ENABLED:
264 *desc = "IPv6 PE";
265 *desc2 = "enabled";
266 break;
267 case NET_EVENT_IPV6_PE_DISABLED:
268 *desc = "IPv6 PE";
269 *desc2 = "disabled";
270 break;
271 case NET_EVENT_IPV6_PE_FILTER_ADD:
272 *desc = "IPv6 PE filter";
273 *desc2 = "add";
274 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
275 extra_info_len);
276 break;
277 case NET_EVENT_IPV6_PE_FILTER_DEL:
278 *desc = "IPv6 PE filter";
279 *desc2 = "del";
280 info = net_addr_ntop(AF_INET6, msg->data, extra_info,
281 extra_info_len);
282 break;
283 case NET_EVENT_IPV4_ADDR_ADD:
284 *desc = "IPv4 address";
285 *desc2 = "add";
286 info = net_addr_ntop(AF_INET, msg->data, extra_info,
287 extra_info_len);
288 break;
289 case NET_EVENT_IPV4_ADDR_DEL:
290 *desc = "IPv4 address";
291 *desc2 = "del";
292 info = net_addr_ntop(AF_INET, msg->data, extra_info,
293 extra_info_len);
294 break;
295 case NET_EVENT_IPV4_MADDR_ADD:
296 *desc = "IPv4 mcast address";
297 *desc2 = "add";
298 info = net_addr_ntop(AF_INET, msg->data, extra_info,
299 extra_info_len);
300 break;
301 case NET_EVENT_IPV4_MADDR_DEL:
302 *desc = "IPv4 mcast address";
303 *desc2 = "del";
304 info = net_addr_ntop(AF_INET, msg->data, extra_info,
305 extra_info_len);
306 break;
307 case NET_EVENT_IPV4_ROUTER_ADD:
308 *desc = "IPv4 router";
309 *desc2 = "add";
310 info = net_addr_ntop(AF_INET, msg->data, extra_info,
311 extra_info_len);
312 break;
313 case NET_EVENT_IPV4_ROUTER_DEL:
314 *desc = "IPv4 router";
315 *desc2 = "del";
316 info = net_addr_ntop(AF_INET, msg->data, extra_info,
317 extra_info_len);
318 break;
319 case NET_EVENT_IPV4_DHCP_START:
320 *desc = "DHCPv4";
321 *desc2 = "start";
322 break;
323 case NET_EVENT_IPV4_DHCP_BOUND:
324 *desc = "DHCPv4";
325 *desc2 = "bound";
326 #if defined(CONFIG_NET_DHCPV4)
327 struct net_if_dhcpv4 *data = (struct net_if_dhcpv4 *)msg->data;
328
329 info = net_addr_ntop(AF_INET, &data->requested_ip, extra_info,
330 extra_info_len);
331 #endif
332 break;
333 case NET_EVENT_IPV4_DHCP_STOP:
334 *desc = "DHCPv4";
335 *desc2 = "stop";
336 break;
337 case NET_EVENT_IPV4_MCAST_JOIN:
338 *desc = "IPv4 mcast";
339 *desc2 = "join";
340 info = net_addr_ntop(AF_INET, msg->data, extra_info,
341 extra_info_len);
342 break;
343 case NET_EVENT_IPV4_MCAST_LEAVE:
344 *desc = "IPv4 mcast";
345 *desc2 = "leave";
346 info = net_addr_ntop(AF_INET, msg->data, extra_info,
347 extra_info_len);
348 break;
349 case NET_EVENT_IPV4_ACD_SUCCEED:
350 *desc = "IPv4 ACD";
351 *desc2 = "ok";
352 info = net_addr_ntop(AF_INET, msg->data, extra_info,
353 extra_info_len);
354 break;
355 case NET_EVENT_IPV4_ACD_FAILED:
356 *desc = "IPv4 ACD";
357 *desc2 = "fail";
358 info = net_addr_ntop(AF_INET, msg->data, extra_info,
359 extra_info_len);
360 break;
361 case NET_EVENT_IPV4_PMTU_CHANGED: {
362 #if defined(CONFIG_NET_IPV4_PMTU)
363 struct net_event_ipv4_pmtu_info *pmtu_info =
364 (struct net_event_ipv4_pmtu_info *)msg->data;
365
366 *desc = "IPV4 PMTU";
367 *desc2 = pmtu_buf;
368 snprintk(pmtu_buf, MAX_PMTU_INFO_STR_LEN,
369 "changed MTU %u for", (uint16_t)pmtu_info->mtu);
370 info = net_addr_ntop(AF_INET, &pmtu_info->dst, extra_info,
371 extra_info_len);
372 #endif
373 break;
374 }
375 case NET_EVENT_IPV6_PMTU_CHANGED: {
376 #if defined(CONFIG_NET_IPV6_PMTU)
377 struct net_event_ipv6_pmtu_info *pmtu_info =
378 (struct net_event_ipv6_pmtu_info *)msg->data;
379
380 *desc = "IPV6 PMTU";
381 *desc2 = pmtu_buf;
382 snprintk(pmtu_buf, MAX_PMTU_INFO_STR_LEN,
383 "changed MTU %u for", (uint16_t)pmtu_info->mtu);
384 info = net_addr_ntop(AF_INET6, &pmtu_info->dst, extra_info,
385 extra_info_len);
386 #endif
387 break;
388 }
389 }
390
391 return info;
392 }
393
sockaddr_ntop(const struct sockaddr * addr,char * dst,size_t size)394 static char *sockaddr_ntop(const struct sockaddr *addr, char *dst, size_t size)
395 {
396 if (addr->sa_family == AF_INET) {
397 return net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr, dst, size);
398 } else if (addr->sa_family == AF_INET6) {
399 return net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr, dst, size);
400 }
401
402 return NULL;
403 }
404
get_l4_desc(struct event_msg * msg,const char ** desc,const char ** desc2,char * extra_info,size_t extra_info_len)405 static char *get_l4_desc(struct event_msg *msg,
406 const char **desc, const char **desc2,
407 char *extra_info, size_t extra_info_len)
408 {
409 static const char *desc_unknown = unknown_event_str;
410 char *info = NULL;
411
412 *desc = desc_unknown;
413
414 switch (msg->event) {
415 case NET_EVENT_L4_CONNECTED:
416 *desc = "connected";
417 break;
418 case NET_EVENT_L4_DISCONNECTED:
419 *desc = "disconnected";
420 break;
421 case NET_EVENT_L4_IPV4_CONNECTED:
422 *desc = "IPv4 connectivity";
423 *desc2 = "available";
424 break;
425 case NET_EVENT_L4_IPV4_DISCONNECTED:
426 *desc = "IPv4 connectivity";
427 *desc2 = "lost";
428 break;
429 case NET_EVENT_L4_IPV6_CONNECTED:
430 *desc = "IPv6 connectivity";
431 *desc2 = "available";
432 break;
433 case NET_EVENT_L4_IPV6_DISCONNECTED:
434 *desc = "IPv6 connectivity";
435 *desc2 = "lost";
436 break;
437 case NET_EVENT_DNS_SERVER_ADD: {
438 struct sockaddr *addr = (struct sockaddr *)msg->data;
439
440 *desc = "DNS server";
441 *desc2 = "add";
442
443 info = sockaddr_ntop(addr, extra_info, extra_info_len);
444
445 break;
446 }
447 case NET_EVENT_DNS_SERVER_DEL: {
448 struct sockaddr *addr = (struct sockaddr *)msg->data;
449
450 *desc = "DNS server";
451 *desc2 = "del";
452
453 info = sockaddr_ntop(addr, extra_info, extra_info_len);
454
455 break;
456 }
457 case NET_EVENT_HOSTNAME_CHANGED:
458 *desc = "Hostname changed";
459 break;
460 case NET_EVENT_COAP_SERVICE_STARTED:
461 *desc = "CoAP service";
462 *desc2 = "started";
463 break;
464 case NET_EVENT_COAP_SERVICE_STOPPED:
465 *desc = "CoAP service";
466 *desc2 = "stopped";
467 break;
468 case NET_EVENT_COAP_OBSERVER_ADDED:
469 *desc = "CoAP observer";
470 *desc2 = "added";
471 break;
472 case NET_EVENT_COAP_OBSERVER_REMOVED:
473 *desc = "CoAP observer";
474 *desc2 = "removed";
475 break;
476 case NET_EVENT_CAPTURE_STARTED:
477 *desc = "Capture";
478 *desc2 = "started";
479 break;
480 case NET_EVENT_CAPTURE_STOPPED:
481 *desc = "Capture";
482 *desc2 = "stopped";
483 break;
484 }
485
486 return info;
487 }
488
489 /* We use a separate thread in order not to do any shell printing from
490 * event handler callback (to avoid stack size issues).
491 */
event_mon_handler(const struct shell * sh,void * p2,void * p3)492 static void event_mon_handler(const struct shell *sh, void *p2, void *p3)
493 {
494 char extra_info[NET_IPV6_ADDR_LEN];
495 struct event_msg msg;
496
497 ARG_UNUSED(p2);
498 ARG_UNUSED(p3);
499 net_mgmt_init_event_callback(&l2_cb, event_handler,
500 MONITOR_L2_MASK);
501 net_mgmt_add_event_callback(&l2_cb);
502
503 net_mgmt_init_event_callback(&l3_ipv4_cb, event_handler,
504 MONITOR_L3_IPV4_MASK);
505 net_mgmt_add_event_callback(&l3_ipv4_cb);
506
507 net_mgmt_init_event_callback(&l3_ipv6_cb, event_handler,
508 MONITOR_L3_IPV6_MASK);
509 net_mgmt_add_event_callback(&l3_ipv6_cb);
510
511 net_mgmt_init_event_callback(&l4_cb, event_handler,
512 MONITOR_L4_MASK);
513 net_mgmt_add_event_callback(&l4_cb);
514
515 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
516 net_mgmt_init_event_callback(&l2_ethernet_cb, event_handler,
517 MONITOR_L2_ETHERNET_MASK);
518 net_mgmt_add_event_callback(&l2_ethernet_cb);
519 #endif
520
521 while (net_event_shutting_down == false) {
522 const char *layer_str = "<unknown layer>";
523 const char *desc = "", *desc2 = "";
524 char *info = NULL;
525 uint32_t layer;
526
527 (void)k_msgq_get(&event_mon_msgq, &msg, K_FOREVER);
528
529 if (msg.iface == NULL && msg.event == 0 && msg.len == 0) {
530 /* This is the stop message */
531 continue;
532 }
533
534 layer = NET_MGMT_GET_LAYER(msg.event);
535 if (layer == NET_MGMT_LAYER_L2) {
536 layer_str = "L2";
537 info = get_l2_desc(&msg, &desc, &desc2,
538 extra_info, NET_IPV6_ADDR_LEN);
539 } else if (layer == NET_MGMT_LAYER_L3) {
540 layer_str = "L3";
541 info = get_l3_desc(&msg, &desc, &desc2,
542 extra_info, NET_IPV6_ADDR_LEN);
543 } else if (layer == NET_MGMT_LAYER_L4) {
544 layer_str = "L4";
545 info = get_l4_desc(&msg, &desc, &desc2,
546 extra_info, NET_IPV6_ADDR_LEN);
547 }
548
549 if (desc == unknown_event_str) {
550 PR_INFO("EVENT: %s [%d] %s%s%s%s%s (0x%08x)\n", layer_str,
551 net_if_get_by_iface(msg.iface), desc,
552 desc2 ? " " : "", desc2 ? desc2 : "",
553 info ? " " : "", info ? info : "", msg.event);
554 } else {
555 PR_INFO("EVENT: %s [%d] %s%s%s%s%s\n", layer_str,
556 net_if_get_by_iface(msg.iface), desc,
557 desc2 ? " " : "", desc2 ? desc2 : "",
558 info ? " " : "", info ? info : "");
559 }
560 }
561
562 net_mgmt_del_event_callback(&l2_cb);
563 net_mgmt_del_event_callback(&l3_ipv4_cb);
564 net_mgmt_del_event_callback(&l3_ipv6_cb);
565 net_mgmt_del_event_callback(&l4_cb);
566
567 #if defined(CONFIG_NET_L2_ETHERNET_MGMT)
568 net_mgmt_del_event_callback(&l2_ethernet_cb);
569 #endif
570
571 k_msgq_purge(&event_mon_msgq);
572
573 net_event_monitoring = false;
574 net_event_shutting_down = false;
575
576 PR_INFO("Network event monitoring %s.\n", "disabled");
577 }
578 #endif
579
cmd_net_events_on(const struct shell * sh,size_t argc,char * argv[])580 static int cmd_net_events_on(const struct shell *sh, size_t argc, char *argv[])
581 {
582 #if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
583 k_tid_t tid;
584
585 if (net_event_monitoring) {
586 PR_INFO("Network event monitoring is already %s.\n",
587 "enabled");
588 return -ENOEXEC;
589 }
590
591 tid = k_thread_create(&event_mon, event_mon_stack,
592 K_THREAD_STACK_SIZEOF(event_mon_stack),
593 (k_thread_entry_t)event_mon_handler,
594 (void *)sh, NULL, NULL, THREAD_PRIORITY, 0,
595 K_FOREVER);
596 if (!tid) {
597 PR_ERROR("Cannot create network event monitor thread!");
598 return -ENOEXEC;
599 }
600
601 k_thread_name_set(tid, "event_mon");
602
603 PR_INFO("Network event monitoring %s.\n", "enabled");
604
605 net_event_monitoring = true;
606 net_event_shutting_down = false;
607
608 k_thread_start(tid);
609 #else
610 PR_INFO("Network management events are not supported. "
611 "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n");
612 #endif
613
614 return 0;
615 }
616
cmd_net_events_off(const struct shell * sh,size_t argc,char * argv[])617 static int cmd_net_events_off(const struct shell *sh, size_t argc, char *argv[])
618 {
619 #if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
620 static const struct event_msg msg;
621 int ret;
622
623 if (!net_event_monitoring) {
624 PR_INFO("Network event monitoring is already %s.\n",
625 "disabled");
626 return -ENOEXEC;
627 }
628
629 net_event_shutting_down = true;
630
631 ret = k_msgq_put(&event_mon_msgq, (void *)&msg, K_MSEC(100));
632 if (ret < 0) {
633 PR_ERROR("Cannot write to msgq (%d)\n", ret);
634 return -ENOEXEC;
635 }
636 #else
637 PR_INFO("Network management events are not supported. "
638 "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n");
639 #endif
640
641 return 0;
642 }
643
cmd_net_events(const struct shell * sh,size_t argc,char * argv[])644 static int cmd_net_events(const struct shell *sh, size_t argc, char *argv[])
645 {
646 #if defined(CONFIG_NET_MGMT_EVENT_MONITOR)
647 PR("Network event monitoring is %s.\n",
648 net_event_monitoring ? "enabled" : "disabled");
649
650 if (!argv[1]) {
651 PR_INFO("Give 'on' to enable event monitoring and "
652 "'off' to disable it.\n");
653 }
654 #else
655 PR_INFO("Network management events are not supported. "
656 "Set CONFIG_NET_MGMT_EVENT_MONITOR to enable it.\n");
657 #endif
658
659 return 0;
660 }
661
events_enable(void)662 void events_enable(void)
663 {
664 static const char * const argv[] = {
665 "on",
666 NULL
667 };
668
669 (void)cmd_net_events_on(shell_backend_uart_get_ptr(), 1, (char **)argv);
670 }
671
672 SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_events,
673 SHELL_CMD(on, NULL, "Turn on network event monitoring.",
674 cmd_net_events_on),
675 SHELL_CMD(off, NULL, "Turn off network event monitoring.",
676 cmd_net_events_off),
677 SHELL_SUBCMD_SET_END
678 );
679
680 SHELL_SUBCMD_ADD((net), events, &net_cmd_events, "Monitor network management events.",
681 cmd_net_events, 1, 1);
682