From 162fb66ecfe28fa353a4eb68a99b904ddd86fc94 Mon Sep 17 00:00:00 2001 From: Anthony Merlino Date: Sun, 19 Aug 2018 18:47:40 +0000 Subject: [PATCH] Merged in antmerlino/apps/i8sak_daemon (pull request #151) i8sak: i8sak daemon now gets shutdown if not in use. Previously, once the i8sak daemon was started, by running any command, it would stay running. This means that if you want to use i8sak to setup your network, but then want exclusive access to the char device, or network device, you have to manually shutdown the i8sak daemon. Now the daemon stays active as long as required to finish any commands, or stays open if a new command keeps it on, but when all work is finished, it shuts down. Approved-by: GregoryN --- wireless/ieee802154/i8sak/i8sak.h | 18 ++- wireless/ieee802154/i8sak/i8sak_acceptassoc.c | 2 + wireless/ieee802154/i8sak/i8sak_assoc.c | 4 +- wireless/ieee802154/i8sak/i8sak_blaster.c | 2 + wireless/ieee802154/i8sak/i8sak_main.c | 150 ++++++++++++------ wireless/ieee802154/i8sak/i8sak_poll.c | 4 + wireless/ieee802154/i8sak/i8sak_scan.c | 4 + wireless/ieee802154/i8sak/i8sak_sniffer.c | 2 + wireless/ieee802154/i8sak/i8sak_tx.c | 4 + 9 files changed, 136 insertions(+), 54 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak.h b/wireless/ieee802154/i8sak/i8sak.h index ff5ffb79f..75de77a8f 100644 --- a/wireless/ieee802154/i8sak/i8sak.h +++ b/wireless/ieee802154/i8sak/i8sak.h @@ -124,13 +124,16 @@ struct i8sak_s pid_t daemon_pid; FAR char ifname[I8SAK_MAX_IFNAME]; int result; - int fd; /* File/Socket descriptor. Only to be used by operations - * occuring within the Daemon TCB - */ + int fd; /* File/Socket descriptor. Only to be used by operations + * occuring within the Daemon TCB + */ - sem_t exclsem; /* For synchronizing access to the signaling semaphore */ - sem_t sigsem; /* For signaling various tasks */ - sem_t updatesem; /* For signaling the daemon that it's settings have changed */ + sem_t exclsem; /* For synchronizing access to the signaling semaphore */ + sem_t sigsem; /* For signaling various tasks */ + sem_t updatesem; /* For signaling the daemon that it's settings have changed */ + sem_t daemonlock; /* For synchronizing access to managing the daemon */ + + int daemonusers; /* Fields related to event listener */ @@ -202,6 +205,9 @@ struct i8sak_s * Public Function Prototypes ****************************************************************************/ +int i8sak_requestdaemon(FAR struct i8sak_s *i8sak); +int i8sak_releasedaemon(FAR struct i8sak_s *i8sak); + uint8_t i8sak_char2nibble (char ch); long i8sak_str2long (FAR const char *str); uint8_t i8sak_str2luint8 (FAR const char *str); diff --git a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c index 7dc6c5648..3d7230e35 100644 --- a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c +++ b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c @@ -156,6 +156,8 @@ void i8sak_acceptassoc_cmd(FAR struct i8sak_s *i8sak, int argc, printf("i8sak: accepting all assoc requests\n"); } + i8sak_requestdaemon(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 e9106c326..3c754045d 100644 --- a/wireless/ieee802154/i8sak/i8sak_assoc.c +++ b/wireless/ieee802154/i8sak/i8sak_assoc.c @@ -214,6 +214,8 @@ void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) } #endif + i8sak_requestdaemon(i8sak); + /* Register new callback for receiving the association notifications. */ memset(&filter, 0, sizeof(struct i8sak_eventfilter_s)); @@ -260,7 +262,6 @@ void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) i8sak->result = -EBUSY; ret = sem_wait(&i8sak->sigsem); - sem_post(&i8sak->exclsem); if (ret != OK) { i8sak->assoc = false; @@ -311,6 +312,7 @@ void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) /* Clean up and return */ (void)i8sak_eventlistener_removereceiver(i8sak, assoc_eventcb); + i8sak_releasedaemon(i8sak); close(fd); } diff --git a/wireless/ieee802154/i8sak/i8sak_blaster.c b/wireless/ieee802154/i8sak/i8sak_blaster.c index ddce15050..cf1ac58f3 100644 --- a/wireless/ieee802154/i8sak/i8sak_blaster.c +++ b/wireless/ieee802154/i8sak/i8sak_blaster.c @@ -98,6 +98,8 @@ void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) { int option; + i8sak_requestdaemon(i8sak); + if (argc < 2) { i8sak_blaster_start(i8sak); diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 95ee643ec..82b7d4921 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -140,6 +140,100 @@ static void i8sak_switch_instance(FAR char *ifname); * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name : i8sak_requestdaemon + * + * Description : + * + ****************************************************************************/ + +int i8sak_requestdaemon(FAR struct i8sak_s *i8sak) +{ + char daemonname[I8SAK_MAX_DAEMONNAME]; + int ret; + int len; + + ret = sem_wait(&i8sak->daemonlock); + if (ret < 0) + { + DEBUGASSERT(ret == EINTR); + return ret; + } + + if (++i8sak->daemonusers == 1) + { + /* Create strings for task based on device. i.e. i8_ieee0 */ + + if (i8sak->mode == I8SAK_MODE_CHAR) + { + len = strlen(i8sak->ifname); + snprintf(daemonname, I8SAK_DAEMONNAME_PREFIX_LEN + (len - 5), + I8SAK_DAEMONNAME_FMT, &i8sak->ifname[5]); + } +#ifdef CONFIG_NET_6LOWPAN + else if (i8sak->mode == I8SAK_MODE_NETIF) + { + len = strlen(i8sak->ifname); + snprintf(daemonname, I8SAK_DAEMONNAME_PREFIX_LEN + len, + I8SAK_DAEMONNAME_FMT, i8sak->ifname); + } +#endif + + i8sak->daemon_started = true; + i8sak->daemon_pid = task_create(daemonname, CONFIG_IEEE802154_I8SAK_PRIORITY, + CONFIG_IEEE802154_I8SAK_STACKSIZE, i8sak_daemon, + NULL); + if (i8sak->daemon_pid < 0) + { + fprintf(stderr, "failed to start daemon\n"); + sem_post(&i8sak->daemonlock); + return ERROR; + } + + /* Use the signal semaphore to wait for daemon to start before returning */ + + ret = sem_wait(&i8sak->sigsem); + if (ret < 0) + { + fprintf(stderr, "i8sak:interrupted while daemon starting\n"); + sem_post(&i8sak->daemonlock); + return ret; + } + } + + sem_post(&i8sak->daemonlock); + return 0; +} + +/**************************************************************************** + * Name : i8sak_releasedaemon + * + * Description : + * + ****************************************************************************/ + +int i8sak_releasedaemon(FAR struct i8sak_s *i8sak) +{ + int ret; + + ret = sem_wait(&i8sak->daemonlock); + if (ret < 0) + { + DEBUGASSERT(ret == EINTR); + return ret; + } + + /* If this was the last user, signal the daemon to shutdown */ + + if (--i8sak->daemonusers == 0) + { + i8sak->daemon_shutdown = true; + sem_post(&i8sak->updatesem); + } + + return 0; +} + /**************************************************************************** * Name : i8sak_str2payload * @@ -496,10 +590,7 @@ static void i8sak_switch_instance(FAR char *ifname) static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) { - char daemonname[I8SAK_MAX_DAEMONNAME]; int i; - int ret; - int len; int fd = 0; if (i8sak->initialized) @@ -507,23 +598,21 @@ static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) return OK; } - i8sak->chan = 11; - i8sak->chpage = 0; - if (strlen(ifname) > I8SAK_MAX_IFNAME) { fprintf(stderr, "ERROR: ifname too long\n"); return ERROR; } - strcpy(&i8sak->ifname[0], ifname); + i8sak->chan = 11; + i8sak->chpage = 0; i8sak->addrmode = IEEE802154_ADDRMODE_SHORT; - /* Initialize the default remote endpoint address */ - i8sak->ep_addr.mode = IEEE802154_ADDRMODE_SHORT; + /* Initialize the default remote endpoint address */ + for (i = 0; i < IEEE802154_EADDRSIZE; i++) { i8sak->ep_addr.eaddr[i] = @@ -610,8 +699,11 @@ static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) sem_init(&i8sak->eventsem, 0, 1); + sem_init(&i8sak->daemonlock, 0, 1); + i8sak->daemon_started = false; i8sak->daemon_shutdown = false; + i8sak->daemonusers = 0; i8sak->eventlistener_run = false; sq_init(&i8sak->eventreceivers); @@ -623,41 +715,6 @@ static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *ifname) i8sak->blasterperiod = 1000; - /* Create strings for task based on device. i.e. i8_ieee0 */ - - if (i8sak->mode == I8SAK_MODE_CHAR) - { - len = strlen(ifname); - snprintf(daemonname, I8SAK_DAEMONNAME_PREFIX_LEN + (len - 5), - I8SAK_DAEMONNAME_FMT, &ifname[5]); - } -#ifdef CONFIG_NET_6LOWPAN - else if (i8sak->mode == I8SAK_MODE_NETIF) - { - len = strlen(ifname); - snprintf(daemonname, I8SAK_DAEMONNAME_PREFIX_LEN + len, - I8SAK_DAEMONNAME_FMT, ifname); - } -#endif - - i8sak->daemon_pid = task_create(daemonname, CONFIG_IEEE802154_I8SAK_PRIORITY, - CONFIG_IEEE802154_I8SAK_STACKSIZE, i8sak_daemon, - NULL); - if (i8sak->daemon_pid < 0) - { - fprintf(stderr, "failed to start daemon\n"); - return ERROR; - } - - /* Use the signal semaphore to wait for daemon to start before returning */ - - ret = sem_wait(&i8sak->sigsem); - if (ret < 0) - { - fprintf(stderr, "i8sak:interrupted while daemon starting\n"); - return ERROR; - } - i8sak->initialized = true; return OK; } @@ -675,7 +732,6 @@ static int i8sak_daemon(int argc, FAR char *argv[]) int ret; fprintf(stderr, "i8sak: daemon started\n"); - i8sak->daemon_started = true; if (i8sak->mode == I8SAK_MODE_CHAR) { @@ -766,12 +822,12 @@ static int i8sak_showusage(FAR const char *progname, int exitcode) " acceptassoc [-h|e]\n" " assoc [-h|p|e|s|w|r|t]\n" " blaster [-h|q|f|p]\n" - " get [-h] parameter" + " get [-h] parameter\n" " poll [-h]\n" " regdump [-h]\n" " reset [-h]\n" " scan [-h|p|a|e] minch-maxch\n" - " set [-h] param val" + " set [-h] param val\n" " sniffer [-h|d]\n" " startpan [-h|b|s] xx:xx\n" " tx [-h|d|m] \n" diff --git a/wireless/ieee802154/i8sak/i8sak_poll.c b/wireless/ieee802154/i8sak/i8sak_poll.c index 52b861393..1a63410ce 100644 --- a/wireless/ieee802154/i8sak/i8sak_poll.c +++ b/wireless/ieee802154/i8sak/i8sak_poll.c @@ -110,6 +110,8 @@ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) } } + i8sak_requestdaemon(i8sak); + /* Register new oneshot callback for receiving the association notifications */ memset(&eventfilter, 0, sizeof(struct i8sak_eventfilter_s)); @@ -163,6 +165,8 @@ void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) printf("i8sak: poll cancelled\n"); i8sak_cmd_error(i8sak); } + + i8sak_releasedaemon(i8sak); } /**************************************************************************** diff --git a/wireless/ieee802154/i8sak/i8sak_scan.c b/wireless/ieee802154/i8sak/i8sak_scan.c index 849c8d40d..f17d56fcb 100644 --- a/wireless/ieee802154/i8sak/i8sak_scan.c +++ b/wireless/ieee802154/i8sak/i8sak_scan.c @@ -161,6 +161,8 @@ void i8sak_scan_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) scan.channels[i] = minchannel + i; } + i8sak_requestdaemon(i8sak); + /* Register new callback for receiving the scan confirmation notification */ memset(&filter, 0, sizeof(struct i8sak_eventfilter_s)); @@ -257,4 +259,6 @@ static void scan_eventcb(FAR struct ieee802154_primitive_s *primitive, FAR void PRINTF_FORMAT_EADDR(scan->pandescs[i].coordaddr.eaddr)); } } + + i8sak_requestdaemon(i8sak); } diff --git a/wireless/ieee802154/i8sak/i8sak_sniffer.c b/wireless/ieee802154/i8sak/i8sak_sniffer.c index 6964eadd0..95891c3b5 100644 --- a/wireless/ieee802154/i8sak/i8sak_sniffer.c +++ b/wireless/ieee802154/i8sak/i8sak_sniffer.c @@ -171,6 +171,8 @@ void i8sak_sniffer_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) close(fd); + i8sak_requestdaemon(i8sak); + /* Start the sniffer thread. We use the existing daemon thread so that this * thread belongs to the daemon task group. */ diff --git a/wireless/ieee802154/i8sak/i8sak_tx.c b/wireless/ieee802154/i8sak/i8sak_tx.c index 0ff18e4bd..84082fb16 100644 --- a/wireless/ieee802154/i8sak/i8sak_tx.c +++ b/wireless/ieee802154/i8sak/i8sak_tx.c @@ -201,6 +201,8 @@ void i8sak_tx_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]) tx.meta.flags.indirect = false; } + i8sak_requestdaemon(i8sak); + /* Register new oneshot callback for receiving the association notifications */ memset(&eventfilter, 0, sizeof(struct i8sak_eventfilter_s)); @@ -296,4 +298,6 @@ static void tx_eventcb(FAR struct ieee802154_primitive_s *primitive, FAR void *a } sem_post(&i8sak->sigsem); + + i8sak_requestdaemon(i8sak); } \ No newline at end of file