From 92b435136d18373a17aa26cc89a13b4c6f6ccdfd Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 1/9] wireless/ieee802154/i8sak: fix nxstyle errors Add the missing blank lines after the declarations in i8sak_main.c and align a case label in i8sak_reset.c. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak_main.c | 4 ++++ wireless/ieee802154/i8sak/i8sak_reset.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 887be1b13a3..2b8017bf233 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -296,6 +296,7 @@ int i8sak_str2payload(FAR const char *str, FAR uint8_t *buf) while (str_len > 0) { int dat; + if (sscanf(str, "%2x", &dat) == 1) { buf[i++] = dat; @@ -353,6 +354,7 @@ long i8sak_str2long(FAR const char *str) uint8_t i8sak_str2luint8(FAR const char *str) { long value = i8sak_str2long(str); + if (value < 0 || value > UINT8_MAX) { fprintf(stderr, "ERROR: 8-bit value out of range\n"); @@ -373,6 +375,7 @@ uint8_t i8sak_str2luint8(FAR const char *str) uint16_t i8sak_str2luint16(FAR const char *str) { long value = i8sak_str2long(str); + if (value < 0 || value > UINT16_MAX) { fprintf(stderr, "ERROR: 16-bit value out of range\n"); @@ -934,6 +937,7 @@ int main(int argc, FAR char *argv[]) for (i = 0; i < nitems(g_i8sak_commands); i++) { FAR const struct i8sak_command_s *cmd = &g_i8sak_commands[i]; + if (strcmp(argv[argind], cmd->name) == 0) { i8sakcmd = cmd; diff --git a/wireless/ieee802154/i8sak/i8sak_reset.c b/wireless/ieee802154/i8sak/i8sak_reset.c index f9f30ae5718..d4279768e8d 100644 --- a/wireless/ieee802154/i8sak/i8sak_reset.c +++ b/wireless/ieee802154/i8sak/i8sak_reset.c @@ -70,7 +70,7 @@ void i8sak_reset_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) optind = -1; return; - case ':': + case ':': fprintf(stderr, "ERROR: missing argument\n"); /* Must manually reset optind if we are going to exit early */ From 76b8fc7c6aa12a689258bed7464e5d2923f8cb49 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 19:38:29 +0200 Subject: [PATCH 2/9] wireless/ieee802154/i8sak: fix the function banners Use the NuttX form, "Name:" with the name of the function that follows. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak_acceptassoc.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_assoc.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_blaster.c | 10 ++++++---- wireless/ieee802154/i8sak/i8sak_events.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_get.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_main.c | 18 ++++++++++-------- wireless/ieee802154/i8sak/i8sak_poll.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_regdump.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_reset.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_scan.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_set.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_sniffer.c | 10 ++++++---- wireless/ieee802154/i8sak/i8sak_startpan.c | 5 +++-- wireless/ieee802154/i8sak/i8sak_tx.c | 5 +++-- 14 files changed, 55 insertions(+), 38 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c index 69298d2682e..df054618402 100644 --- a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c +++ b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c @@ -54,10 +54,11 @@ static void acceptassoc_eventcb(FAR struct ieee802154_primitive_s *primitive, ****************************************************************************/ /**************************************************************************** - * Name : i8_acceptassoc + * Name: i8sak_acceptassoc_cmd * - * Description : + * Description: * Start accepting association requests. + * ****************************************************************************/ void i8sak_acceptassoc_cmd(FAR struct i8sak_s *i8sak, int argc, diff --git a/wireless/ieee802154/i8sak/i8sak_assoc.c b/wireless/ieee802154/i8sak/i8sak_assoc.c index 96d65986abb..a9abda2271a 100644 --- a/wireless/ieee802154/i8sak/i8sak_assoc.c +++ b/wireless/ieee802154/i8sak/i8sak_assoc.c @@ -52,10 +52,11 @@ static void assoc_eventcb(FAR struct ieee802154_primitive_s *primitive, ****************************************************************************/ /**************************************************************************** - * Name : i8sak_assoc + * Name: i8sak_assoc_cmd * - * Description : + * Description: * Request association with the Coordinator + * ****************************************************************************/ void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_blaster.c b/wireless/ieee802154/i8sak/i8sak_blaster.c index cbb403703cd..d1bd107d0a4 100644 --- a/wireless/ieee802154/i8sak/i8sak_blaster.c +++ b/wireless/ieee802154/i8sak/i8sak_blaster.c @@ -70,10 +70,11 @@ static inline void i8sak_blaster_start(FAR struct i8sak_s *i8sak) ****************************************************************************/ /**************************************************************************** - * Name : i8sak_blaster + * Name: i8sak_blaster_cmd * - * Description : + * Description: * Continuously transmit a packet + * ****************************************************************************/ void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) @@ -141,10 +142,11 @@ void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) } /**************************************************************************** - * Name : i8sak_blaster_thread + * Name: i8sak_blaster_thread * - * Description : + * Description: * Send frames periodically + * ****************************************************************************/ pthread_addr_t i8sak_blaster_thread(pthread_addr_t arg) diff --git a/wireless/ieee802154/i8sak/i8sak_events.c b/wireless/ieee802154/i8sak/i8sak_events.c index 143e7ae3e9c..33b49a768bb 100644 --- a/wireless/ieee802154/i8sak/i8sak_events.c +++ b/wireless/ieee802154/i8sak/i8sak_events.c @@ -51,10 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Name : i8sak_eventthread + * Name: i8sak_eventthread * - * Description : + * Description: * Listen for events from the MAC layer + * ****************************************************************************/ static pthread_addr_t i8sak_eventthread(pthread_addr_t arg) diff --git a/wireless/ieee802154/i8sak/i8sak_get.c b/wireless/ieee802154/i8sak/i8sak_get.c index 2b04fb769f9..ffb57e64f5b 100644 --- a/wireless/ieee802154/i8sak/i8sak_get.c +++ b/wireless/ieee802154/i8sak/i8sak_get.c @@ -54,11 +54,12 @@ union i8sak_get_u ****************************************************************************/ /**************************************************************************** - * Name : i8sak_get_cmd + * Name: i8sak_get_cmd * - * Description : + * Description: * Get various parameters. These can be either i8sak app level options * or attributes fetched via IOCTL to the network/MAC/or radio level. + * ****************************************************************************/ void i8sak_get_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 2b8017bf233..5ad7bdc6b96 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -162,9 +162,9 @@ FAR const char *g_ieee802154_status_string[] = ****************************************************************************/ /**************************************************************************** - * Name : i8sak_requestdaemon + * Name: i8sak_requestdaemon * - * Description : + * Description: * ****************************************************************************/ @@ -229,9 +229,9 @@ int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) } /**************************************************************************** - * Name : i8sak_releasedaemon + * Name: i8sak_releasedaemon * - * Description : + * Description: * ****************************************************************************/ @@ -259,14 +259,15 @@ int i8sak_releasedaemon(FAR struct i8sak_s *i8sak) } /**************************************************************************** - * Name : i8sak_str2payload + * Name: i8sak_str2payload * - * Description : + * Description: * Parse string to get buffer of data. Buf is expected to be of size * IEEE802154_MAX_MAC_PAYLOAD_SIZE or larger. * * Returns: * Positive length value of frame payload + * ****************************************************************************/ int i8sak_str2payload(FAR const char *str, FAR uint8_t *buf) @@ -747,10 +748,11 @@ static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) } /**************************************************************************** - * Name : i8sak_daemon + * Name: i8sak_daemon * - * Description : + * Description: * Runs command in separate task + * ****************************************************************************/ static int i8sak_daemon(int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_poll.c b/wireless/ieee802154/i8sak/i8sak_poll.c index c349708f0ca..832c98cca86 100644 --- a/wireless/ieee802154/i8sak/i8sak_poll.c +++ b/wireless/ieee802154/i8sak/i8sak_poll.c @@ -51,10 +51,11 @@ static void poll_eventcb(FAR struct ieee802154_primitive_s *primitive, ****************************************************************************/ /**************************************************************************** - * Name : i8sak_poll_cmd + * Name: i8sak_poll_cmd * - * Description : + * Description: * Try and extract data from the coordinator + * ****************************************************************************/ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_regdump.c b/wireless/ieee802154/i8sak/i8sak_regdump.c index aa32767c09f..22de716a61d 100644 --- a/wireless/ieee802154/i8sak/i8sak_regdump.c +++ b/wireless/ieee802154/i8sak/i8sak_regdump.c @@ -44,10 +44,11 @@ ****************************************************************************/ /**************************************************************************** - * Name : i8sak_regdump_cmd + * Name: i8sak_regdump_cmd * - * Description : + * Description: * Print register information of radio device + * ****************************************************************************/ void i8sak_regdump_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_reset.c b/wireless/ieee802154/i8sak/i8sak_reset.c index d4279768e8d..f7529ef3656 100644 --- a/wireless/ieee802154/i8sak/i8sak_reset.c +++ b/wireless/ieee802154/i8sak/i8sak_reset.c @@ -44,10 +44,11 @@ ****************************************************************************/ /**************************************************************************** - * Name : i8sak_reset_cmd + * Name: i8sak_reset_cmd * - * Description : + * Description: * Reset the MAC layer + * ****************************************************************************/ void i8sak_reset_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_scan.c b/wireless/ieee802154/i8sak/i8sak_scan.c index ab2093a3047..8064c3120aa 100644 --- a/wireless/ieee802154/i8sak/i8sak_scan.c +++ b/wireless/ieee802154/i8sak/i8sak_scan.c @@ -51,10 +51,11 @@ static void scan_eventcb(FAR struct ieee802154_primitive_s *primitive, ****************************************************************************/ /**************************************************************************** - * Name : i8sak_scan_cmd + * Name: i8sak_scan_cmd * - * Description : + * Description: * Request association with the Coordinator + * ****************************************************************************/ void i8sak_scan_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_set.c b/wireless/ieee802154/i8sak/i8sak_set.c index 2caf6b270ff..d60a0c456a1 100644 --- a/wireless/ieee802154/i8sak/i8sak_set.c +++ b/wireless/ieee802154/i8sak/i8sak_set.c @@ -53,11 +53,12 @@ union i8sak_set_u ****************************************************************************/ /**************************************************************************** - * Name : i8sak_set_cmd + * Name: i8sak_set_cmd * - * Description : + * Description: * Set various parameters. These can be either i8sak app level options * or attributes fetched via IOCTL to the network/MAC/or radio level. + * ****************************************************************************/ void i8sak_set_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) diff --git a/wireless/ieee802154/i8sak/i8sak_sniffer.c b/wireless/ieee802154/i8sak/i8sak_sniffer.c index 2fea25678f1..d8df056c823 100644 --- a/wireless/ieee802154/i8sak/i8sak_sniffer.c +++ b/wireless/ieee802154/i8sak/i8sak_sniffer.c @@ -50,10 +50,11 @@ ****************************************************************************/ /**************************************************************************** - * Name : i8sak_sniffer_cmd + * Name: i8sak_sniffer_cmd * - * Description : + * Description: * Sniff for frames (Promiscuous mode) + * ****************************************************************************/ void i8sak_sniffer_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) @@ -176,10 +177,11 @@ void i8sak_sniffer_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) } /**************************************************************************** - * Name : i8sak_sniffer_thread + * Name: i8sak_sniffer_thread * - * Description : + * Description: * Listen for frames. + * ****************************************************************************/ pthread_addr_t i8sak_sniffer_thread(pthread_addr_t arg) diff --git a/wireless/ieee802154/i8sak/i8sak_startpan.c b/wireless/ieee802154/i8sak/i8sak_startpan.c index 0954d49d968..3218541b36f 100644 --- a/wireless/ieee802154/i8sak/i8sak_startpan.c +++ b/wireless/ieee802154/i8sak/i8sak_startpan.c @@ -44,10 +44,11 @@ ****************************************************************************/ /**************************************************************************** - * Name : i8sak_startpan_cmd + * Name: i8sak_startpan_cmd * - * Description : + * Description: * Start PAN and accept association requests + * ****************************************************************************/ void i8sak_startpan_cmd(FAR struct i8sak_s *i8sak, diff --git a/wireless/ieee802154/i8sak/i8sak_tx.c b/wireless/ieee802154/i8sak/i8sak_tx.c index e0f2c19518e..58aef303caa 100644 --- a/wireless/ieee802154/i8sak/i8sak_tx.c +++ b/wireless/ieee802154/i8sak/i8sak_tx.c @@ -52,10 +52,11 @@ static void tx_eventcb(FAR struct ieee802154_primitive_s *primitive, ****************************************************************************/ /**************************************************************************** - * Name : i8_tx_cmd + * Name: i8sak_tx_cmd * - * Description : + * Description: * Transmit a data frame. + * ****************************************************************************/ void i8sak_tx_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) From 2f6acaa33534c3c415a56b646eb8456480ebedc1 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 3/9] wireless/ieee802154/i8sak: fix the tx command With -d or -m the option string was sent as the payload instead of the payload argument, and each tx confirm left a post on sigsem that ended the next poll or assoc early. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak_tx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak_tx.c b/wireless/ieee802154/i8sak/i8sak_tx.c index 58aef303caa..4f43559f973 100644 --- a/wireless/ieee802154/i8sak/i8sak_tx.c +++ b/wireless/ieee802154/i8sak/i8sak_tx.c @@ -115,7 +115,7 @@ void i8sak_tx_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) if (argc == argind + 1) { - i8sak->payload_len = i8sak_str2payload(argv[1], i8sak->payload); + i8sak->payload_len = i8sak_str2payload(argv[argind], i8sak->payload); } if (sendmax) @@ -282,7 +282,5 @@ static void tx_eventcb(FAR struct ieee802154_primitive_s *primitive, g_ieee802154_status_string[primitive->u.dataconf.status]); } - sem_post(&i8sak->sigsem); - i8sak_releasedaemon(i8sak); } From 940a07c0eedee319afa789d216482b1eacff2a82 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 4/9] wireless/ieee802154/i8sak: fix the event receivers Each acceptassoc added a receiver and a daemon user, the receivers ran out after three calls: replace the previous one. assoc and poll waited forever for a confirm when their receiver could not be registered. The event thread needs a SIGINT handler, an ignored signal does not break it out of MAC802154IOC_GET_EVENT. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak_acceptassoc.c | 7 ++++++ wireless/ieee802154/i8sak/i8sak_assoc.c | 9 ++++++- wireless/ieee802154/i8sak/i8sak_events.c | 24 ++++++++++++++++--- wireless/ieee802154/i8sak/i8sak_poll.c | 8 ++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c index df054618402..0f3d9c77b5e 100644 --- a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c +++ b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c @@ -147,6 +147,13 @@ void i8sak_acceptassoc_cmd(FAR struct i8sak_s *i8sak, int argc, i8sak_requestdaemon(i8sak); + /* Replace the receiver of a previous acceptassoc */ + + if (i8sak_eventlistener_removereceiver(i8sak, acceptassoc_eventcb) == OK) + { + i8sak_releasedaemon(i8sak); + } + /* Register new callback for receiving the association notifications */ memset(&filter, 0, sizeof(struct i8sak_eventfilter_s)); diff --git a/wireless/ieee802154/i8sak/i8sak_assoc.c b/wireless/ieee802154/i8sak/i8sak_assoc.c index a9abda2271a..ef59b406687 100644 --- a/wireless/ieee802154/i8sak/i8sak_assoc.c +++ b/wireless/ieee802154/i8sak/i8sak_assoc.c @@ -210,7 +210,14 @@ void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) memset(&filter, 0, sizeof(struct i8sak_eventfilter_s)); filter.confevents.assoc = true; - i8sak_eventlistener_addreceiver(i8sak, assoc_eventcb, &filter, false); + ret = i8sak_eventlistener_addreceiver(i8sak, assoc_eventcb, &filter, + false); + if (ret < 0) + { + i8sak_releasedaemon(i8sak); + close(fd); + return; + } /* Loop for the specified retry count if the association fails. */ diff --git a/wireless/ieee802154/i8sak/i8sak_events.c b/wireless/ieee802154/i8sak/i8sak_events.c index 33b49a768bb..cae0cc098c6 100644 --- a/wireless/ieee802154/i8sak/i8sak_events.c +++ b/wireless/ieee802154/i8sak/i8sak_events.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,22 @@ * Private Functions ****************************************************************************/ +#ifdef CONFIG_ENABLE_ALL_SIGNALS +/**************************************************************************** + * Name: i8sak_eventthread_wakeup + * + * Description: + * An empty handler for SIGINT. i8sak_eventlistener_stop() sends SIGINT + * to break the event thread out of MAC802154IOC_GET_EVENT; an ignored + * signal does not interrupt it. + * + ****************************************************************************/ + +static void i8sak_eventthread_wakeup(int signo) +{ +} +#endif + /**************************************************************************** * Name: i8sak_eventthread * @@ -72,6 +89,8 @@ static pthread_addr_t i8sak_eventthread(pthread_addr_t arg) #ifdef CONFIG_DISABLE_ALL_SIGNALS pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#elif defined(CONFIG_ENABLE_ALL_SIGNALS) + signal(SIGINT, i8sak_eventthread_wakeup); #endif if (i8sak->mode == I8SAK_MODE_CHAR) @@ -269,7 +288,7 @@ int i8sak_eventlistener_stop(FAR struct i8sak_s *i8sak) #ifdef CONFIG_DISABLE_ALL_SIGNALS pthread_cancel(i8sak->eventlistener_threadid); #else - pthread_kill(i8sak->eventlistener_threadid, 2); + pthread_kill(i8sak->eventlistener_threadid, SIGINT); #endif ret = pthread_join(i8sak->eventlistener_threadid, &value); @@ -409,6 +428,5 @@ int i8sak_eventlistener_removereceiver(FAR struct i8sak_s *i8sak, } sem_post(&i8sak->eventsem); - fprintf(stderr, "failed to remove receiver"); - return ERROR; + return -ENOENT; } diff --git a/wireless/ieee802154/i8sak/i8sak_poll.c b/wireless/ieee802154/i8sak/i8sak_poll.c index 832c98cca86..4161db7b852 100644 --- a/wireless/ieee802154/i8sak/i8sak_poll.c +++ b/wireless/ieee802154/i8sak/i8sak_poll.c @@ -105,7 +105,13 @@ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) memset(&eventfilter, 0, sizeof(struct i8sak_eventfilter_s)); eventfilter.confevents.poll = true; - i8sak_eventlistener_addreceiver(i8sak, poll_eventcb, &eventfilter, true); + ret = i8sak_eventlistener_addreceiver(i8sak, poll_eventcb, &eventfilter, + true); + if (ret < 0) + { + i8sak_releasedaemon(i8sak); + return; + } memcpy(&pollreq.coordaddr, &i8sak->ep_addr, sizeof(struct ieee802154_addr_s)); From 1ae1b2cec386e3011aa69d5353314705081a047a Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 5/9] wireless/ieee802154/i8sak: release the instance on an invalid argument The argument helpers exited with the instance locked, every later i8sak command then blocked. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak_main.c | 29 ++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 5ad7bdc6b96..44173fa820f 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -289,7 +289,7 @@ int i8sak_str2payload(FAR const char *str, FAR uint8_t *buf) if ((str_len & 1) || (ret > IEEE802154_MAX_MAC_PAYLOAD_SIZE)) { fprintf(stderr, "ERROR: Invalid payload\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } /* Decode hex packet */ @@ -307,7 +307,7 @@ int i8sak_str2payload(FAR const char *str, FAR uint8_t *buf) else { fprintf(stderr, "ERROR: Invalid payload\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } } @@ -331,14 +331,13 @@ long i8sak_str2long(FAR const char *str) if (*endptr != '\0') { fprintf(stderr, "ERROR: Garbage after numeric argument\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } if (value > INT_MAX || value < INT_MIN) { fprintf(stderr, "ERROR: Integer value out of range\n"); - return LONG_MAX; - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } return value; @@ -359,7 +358,7 @@ uint8_t i8sak_str2luint8(FAR const char *str) if (value < 0 || value > UINT8_MAX) { fprintf(stderr, "ERROR: 8-bit value out of range\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } return (uint8_t)value; @@ -380,7 +379,7 @@ uint16_t i8sak_str2luint16(FAR const char *str) if (value < 0 || value > UINT16_MAX) { fprintf(stderr, "ERROR: 16-bit value out of range\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } return (uint16_t)value; @@ -411,14 +410,16 @@ uint8_t i8sak_char2nibble(char ch) else if (ch == '\0') { fprintf(stderr, "ERROR: Unexpected end hex\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } else { fprintf(stderr, "ERROR: Unexpected character in hex value: %02x\n", ch); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } + + return 0; } /**************************************************************************** @@ -453,7 +454,7 @@ void i8sak_str2eaddr(FAR const char *str, FAR uint8_t *eaddr) { fprintf(stderr, "ERROR: Missing colon separator: %s\n", str); fprintf(stderr, " Expected xx:xx:xx:xx:xx:xx:xx:xx\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } } } @@ -491,7 +492,7 @@ void i8sak_str2saddr(FAR const char *str, FAR uint8_t *saddr) { fprintf(stderr, "ERROR: Missing colon separator: %s\n", str); fprintf(stderr, " Expected xx:xx\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } } } @@ -529,7 +530,7 @@ void i8sak_str2panid(FAR const char *str, FAR uint8_t *panid) { fprintf(stderr, "ERROR: Missing colon separator: %s\n", str); fprintf(stderr, " Expected xx:xx\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } } } @@ -557,8 +558,10 @@ bool i8sak_str2bool(FAR const char *str) { fprintf(stderr, "ERROR: Invalid boolean name: %s\n", str); fprintf(stderr, " Expected true or false\n"); - exit(EXIT_FAILURE); + i8sak_cmd_error(g_activei8sak); } + + return false; } /**************************************************************************** From 56def7c3bc345f29241e73428036a69fe56f57af Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 6/9] wireless/ieee802154/libmac: fix the disassociation and orphan requests sixlowpan_disassoc_req() was defined as sixlowpan_desassoc_req(), and the orphan response functions passed an uninitialized argument to the MAC. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/libmac/ieee802154_orphanresp.c | 2 ++ wireless/ieee802154/libmac/sixlowpan_disassocreq.c | 2 +- wireless/ieee802154/libmac/sixlowpan_orphanresp.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/wireless/ieee802154/libmac/ieee802154_orphanresp.c b/wireless/ieee802154/libmac/ieee802154_orphanresp.c index b997091d52e..80ac0f130fd 100644 --- a/wireless/ieee802154/libmac/ieee802154_orphanresp.c +++ b/wireless/ieee802154/libmac/ieee802154_orphanresp.c @@ -46,6 +46,8 @@ int ieee802154_orphan_resp(int fd, FAR struct ieee802154_orphan_resp_s *resp) union ieee802154_macarg_u arg; int ret; + memcpy(&arg.orphanresp, resp, sizeof(struct ieee802154_orphan_resp_s)); + ret = ioctl(fd, MAC802154IOC_MLME_ORPHAN_RESPONSE, (unsigned long)((uintptr_t)&arg)); if (ret < 0) diff --git a/wireless/ieee802154/libmac/sixlowpan_disassocreq.c b/wireless/ieee802154/libmac/sixlowpan_disassocreq.c index 8582379d3cf..b9dd97ffcb7 100644 --- a/wireless/ieee802154/libmac/sixlowpan_disassocreq.c +++ b/wireless/ieee802154/libmac/sixlowpan_disassocreq.c @@ -41,7 +41,7 @@ * Public Functions ****************************************************************************/ -int sixlowpan_desassoc_req(int sock, FAR const char *ifname, +int sixlowpan_disassoc_req(int sock, FAR const char *ifname, FAR const struct ieee802154_disassoc_req_s *req) { struct ieee802154_netmac_s arg; diff --git a/wireless/ieee802154/libmac/sixlowpan_orphanresp.c b/wireless/ieee802154/libmac/sixlowpan_orphanresp.c index decb4b58d7e..0f2d1b1a2c7 100644 --- a/wireless/ieee802154/libmac/sixlowpan_orphanresp.c +++ b/wireless/ieee802154/libmac/sixlowpan_orphanresp.c @@ -48,6 +48,7 @@ int sixlowpan_orphan_resp(int sock, FAR const char *ifname, int ret; strlcpy(arg.ifr_name, ifname, IFNAMSIZ); + memcpy(&arg.u.orphanresp, resp, sizeof(struct ieee802154_orphan_resp_s)); ret = ioctl(sock, MAC802154IOC_MLME_ORPHAN_RESPONSE, (unsigned long)((uintptr_t)&arg)); From 4d44140c09ad91307e2199672dc8ced70ed68544 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 7/9] wireless/ieee802154/i8sak: end the command when the daemon fails to start A daemon that failed to open the device never signalled its start, so the caller blocked forever, and a failed start left the daemon user counted. i8sak_requestdaemon() ends the command on any failure. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak.h | 3 ++- wireless/ieee802154/i8sak/i8sak_main.c | 25 ++++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak.h b/wireless/ieee802154/i8sak/i8sak.h index b5f826e0934..3467e9a1687 100644 --- a/wireless/ieee802154/i8sak/i8sak.h +++ b/wireless/ieee802154/i8sak/i8sak.h @@ -99,6 +99,7 @@ struct i8sak_s bool initialized : 1; bool daemon_shutdown : 1; + bool daemon_failed : 1; bool verbose : 1; bool acceptall : 1; bool assoc : 1; @@ -188,7 +189,7 @@ struct i8sak_s * Public Function Prototypes ****************************************************************************/ -int i8sak_requestdaemon(FAR struct i8sak_s *i8sak); +void i8sak_requestdaemon(FAR struct i8sak_s *i8sak); int i8sak_releasedaemon(FAR struct i8sak_s *i8sak); uint8_t i8sak_char2nibble (char ch); diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 44173fa820f..590932fa9f7 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -168,7 +168,7 @@ FAR const char *g_ieee802154_status_string[] = * ****************************************************************************/ -int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) +void i8sak_requestdaemon(FAR struct i8sak_s *i8sak) { char daemonname[I8SAK_MAX_DAEMONNAME]; int ret; @@ -178,7 +178,7 @@ int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) if (ret < 0) { DEBUGASSERT(ret == EINTR); - return ret; + i8sak_cmd_error(i8sak); } if (++i8sak->daemonusers == 1) @@ -201,6 +201,7 @@ int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) #endif i8sak->daemon_shutdown = false; + i8sak->daemon_failed = false; i8sak->daemon_pid = task_create(daemonname, CONFIG_IEEE802154_I8SAK_PRIORITY, CONFIG_IEEE802154_I8SAK_STACKSIZE, @@ -209,8 +210,9 @@ int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) if (i8sak->daemon_pid < 0) { fprintf(stderr, "failed to start daemon\n"); + i8sak->daemonusers = 0; sem_post(&i8sak->daemonlock); - return ERROR; + i8sak_cmd_error(i8sak); } /* Use the semaphore to wait for daemon to start before returning */ @@ -219,13 +221,22 @@ int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) if (ret < 0) { fprintf(stderr, "i8sak:interrupted while daemon starting\n"); + i8sak->daemonusers = 0; sem_post(&i8sak->daemonlock); - return ret; + i8sak_cmd_error(i8sak); + } + + /* The daemon signals a failed start too */ + + if (i8sak->daemon_failed) + { + i8sak->daemonusers = 0; + sem_post(&i8sak->daemonlock); + i8sak_cmd_error(i8sak); } } sem_post(&i8sak->daemonlock); - return 0; } /**************************************************************************** @@ -773,6 +784,8 @@ static int i8sak_daemon(int argc, FAR char *argv[]) fprintf(stderr, "ERROR: cannot open %s, errno=%d\n", i8sak->ifname, errno); ret = errno; + i8sak->daemon_failed = true; + sem_post(&i8sak->sigsem); return ret; } } @@ -784,6 +797,8 @@ static int i8sak_daemon(int argc, FAR char *argv[]) { fprintf(stderr, "ERROR: failed to open socket, errno=%d\n", errno); ret = errno; + i8sak->daemon_failed = true; + sem_post(&i8sak->sigsem); return ret; } } From 75e7caa7e9af14452b182d53a23233a88a9f57e5 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 8/9] wireless/ieee802154/i8sak: unwind the error exits A command that exited after requesting the daemon left its event receiver registered and the daemon running, and a failed instance setup exited with the instance on the active list. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak.h | 1 + wireless/ieee802154/i8sak/i8sak_assoc.c | 3 +-- wireless/ieee802154/i8sak/i8sak_main.c | 28 ++++++++++++++++++++++--- wireless/ieee802154/i8sak/i8sak_poll.c | 6 +++--- wireless/ieee802154/i8sak/i8sak_scan.c | 4 ++-- wireless/ieee802154/i8sak/i8sak_tx.c | 3 +-- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak.h b/wireless/ieee802154/i8sak/i8sak.h index 3467e9a1687..ca44f8faf62 100644 --- a/wireless/ieee802154/i8sak/i8sak.h +++ b/wireless/ieee802154/i8sak/i8sak.h @@ -191,6 +191,7 @@ struct i8sak_s void i8sak_requestdaemon(FAR struct i8sak_s *i8sak); int i8sak_releasedaemon(FAR struct i8sak_s *i8sak); +void i8sak_cmd_abort(FAR struct i8sak_s *i8sak, i8sak_eventcallback_t cb); uint8_t i8sak_char2nibble (char ch); long i8sak_str2long (FAR const char *str); diff --git a/wireless/ieee802154/i8sak/i8sak_assoc.c b/wireless/ieee802154/i8sak/i8sak_assoc.c index ef59b406687..07617a80920 100644 --- a/wireless/ieee802154/i8sak/i8sak_assoc.c +++ b/wireless/ieee802154/i8sak/i8sak_assoc.c @@ -261,8 +261,7 @@ void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) if (ret != OK) { i8sak->assoc = false; - i8sak_cmd_error(i8sak); - break; + i8sak_cmd_abort(i8sak, assoc_eventcb); } /* Check if the association was successful */ diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 590932fa9f7..a9792bf4580 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -239,6 +239,25 @@ void i8sak_requestdaemon(FAR struct i8sak_s *i8sak) sem_post(&i8sak->daemonlock); } +/**************************************************************************** + * Name: i8sak_cmd_abort + * + * Description: + * Remove the receiver of a pending request, release the daemon and exit. + * + ****************************************************************************/ + +void i8sak_cmd_abort(FAR struct i8sak_s *i8sak, i8sak_eventcallback_t cb) +{ + if (cb != NULL) + { + i8sak_eventlistener_removereceiver(i8sak, cb); + } + + i8sak_releasedaemon(i8sak); + i8sak_cmd_error(i8sak); +} + /**************************************************************************** * Name: i8sak_releasedaemon * @@ -581,6 +600,7 @@ bool i8sak_str2bool(FAR const char *str) static void i8sak_switch_instance(FAR char *ifname) { + FAR struct i8sak_s *prev = g_activei8sak; FAR struct i8sak_s *i8sak; /* Search list of i8sak instances for one associated with the provided @@ -620,6 +640,9 @@ static void i8sak_switch_instance(FAR char *ifname) if (i8sak_setup(i8sak, ifname) < 0) { + sq_rem((FAR sq_entry_t *)i8sak, &g_i8sak_instances); + sq_addlast((FAR sq_entry_t *)i8sak, &g_i8sak_free); + g_activei8sak = prev; exit(EXIT_FAILURE); } } @@ -712,7 +735,7 @@ static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) { fprintf(stderr, "ERROR: cannot open %s, errno=%d\n", i8sak->ifname, errno); - i8sak_cmd_error(i8sak); + return ERROR; } } #ifdef CONFIG_NET_6LOWPAN @@ -722,13 +745,12 @@ static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) if (fd < 0) { fprintf(stderr, "ERROR: failed to open socket, errno=%d\n", errno); - i8sak_cmd_error(i8sak); + return ERROR; } } #endif else { - close(fd); return ERROR; } diff --git a/wireless/ieee802154/i8sak/i8sak_poll.c b/wireless/ieee802154/i8sak/i8sak_poll.c index 4161db7b852..ebddad12514 100644 --- a/wireless/ieee802154/i8sak/i8sak_poll.c +++ b/wireless/ieee802154/i8sak/i8sak_poll.c @@ -132,7 +132,7 @@ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) { fprintf(stderr, "ERROR: cannot open %s, errno=%d\n", i8sak->ifname, errno); - i8sak_cmd_error(i8sak); + i8sak_cmd_abort(i8sak, poll_eventcb); } ieee802154_poll_req(fd, &pollreq); @@ -144,7 +144,7 @@ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) if (fd < 0) { fprintf(stderr, "ERROR: failed to open socket, errno=%d\n", errno); - i8sak_cmd_error(i8sak); + i8sak_cmd_abort(i8sak, poll_eventcb); } sixlowpan_poll_req(fd, i8sak->ifname, &pollreq); @@ -161,7 +161,7 @@ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) if (ret != OK) { printf("i8sak: poll cancelled\n"); - i8sak_cmd_error(i8sak); + i8sak_cmd_abort(i8sak, poll_eventcb); } i8sak_releasedaemon(i8sak); diff --git a/wireless/ieee802154/i8sak/i8sak_scan.c b/wireless/ieee802154/i8sak/i8sak_scan.c index 8064c3120aa..1d546d5c6a8 100644 --- a/wireless/ieee802154/i8sak/i8sak_scan.c +++ b/wireless/ieee802154/i8sak/i8sak_scan.c @@ -167,7 +167,7 @@ void i8sak_scan_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) { fprintf(stderr, "ERROR: cannot open %s, errno=%d\n", i8sak->ifname, errno); - i8sak_cmd_error(i8sak); + i8sak_cmd_abort(i8sak, scan_eventcb); } ieee802154_scan_req(fd, &scan); @@ -179,7 +179,7 @@ void i8sak_scan_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) if (fd < 0) { fprintf(stderr, "ERROR: failed to open socket, errno=%d\n", errno); - i8sak_cmd_error(i8sak); + i8sak_cmd_abort(i8sak, scan_eventcb); } sixlowpan_scan_req(fd, i8sak->ifname, &scan); diff --git a/wireless/ieee802154/i8sak/i8sak_tx.c b/wireless/ieee802154/i8sak/i8sak_tx.c index 4f43559f973..787b36d2043 100644 --- a/wireless/ieee802154/i8sak/i8sak_tx.c +++ b/wireless/ieee802154/i8sak/i8sak_tx.c @@ -260,8 +260,7 @@ void i8sak_tx_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) if (ret < 0) { fprintf(stderr, "ERROR: Failed to transmit packet: errno=%d\n", errno); - close(fd); - i8sak_cmd_error(i8sak); + i8sak_cmd_abort(i8sak, tx_eventcb); } close(fd); From f0d8da7f49fea45ebad68e2994f8b1757b8fc283 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 22 Oct 2026 17:47:04 +0200 Subject: [PATCH 9/9] wireless/ieee802154/i8sak: hold the daemon only while the blaster runs blaster requested the daemon before parsing its options and kept it on a help or error exit and on quit, and a failed socket bind exited the whole daemon from the blaster thread. Assisted-by: Claude Code Signed-off-by: raiden00pl --- wireless/ieee802154/i8sak/i8sak_blaster.c | 35 ++++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak_blaster.c b/wireless/ieee802154/i8sak/i8sak_blaster.c index d1bd107d0a4..c889e70a196 100644 --- a/wireless/ieee802154/i8sak/i8sak_blaster.c +++ b/wireless/ieee802154/i8sak/i8sak_blaster.c @@ -79,15 +79,10 @@ static inline void i8sak_blaster_start(FAR struct i8sak_s *i8sak) void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) { + bool start = argc < 2; + bool quit = false; int option; - i8sak_requestdaemon(i8sak); - - if (argc < 2) - { - i8sak_blaster_start(i8sak); - } - while ((option = getopt(argc, argv, "hqp:f:")) != ERROR) { switch (option) @@ -107,18 +102,18 @@ void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) optind = -1; return; case 'q': /* Quit blaster */ - i8sak->blasterenabled = false; + quit = true; break; case 'p': /* Inline change blaster period */ i8sak->blasterperiod = atoi(optarg); - i8sak_blaster_start(i8sak); + start = true; break; case 'f': /* Inline change blaster frame */ i8sak->payload_len = i8sak_str2payload(optarg, &i8sak->payload[0]); - i8sak_blaster_start(i8sak); + start = true; break; case ':': @@ -139,6 +134,22 @@ void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) i8sak_cmd_error(i8sak); /* This exits for us */ } } + + /* The blaster holds the daemon while it runs */ + + if (quit) + { + if (i8sak->blasterenabled) + { + i8sak->blasterenabled = false; + i8sak_releasedaemon(i8sak); + } + } + else if (start && !i8sak->blasterenabled) + { + i8sak_requestdaemon(i8sak); + i8sak_blaster_start(i8sak); + } } /**************************************************************************** @@ -161,7 +172,9 @@ pthread_addr_t i8sak_blaster_thread(pthread_addr_t arg) sizeof(struct sockaddr_in6)) < 0) { fprintf(stderr, "ERROR: failure to bind sock: %d\n", errno); - exit(1); + i8sak->blasterenabled = false; + i8sak_releasedaemon(i8sak); + return NULL; } } #endif