From 1fde89e2d94929a210f9bdc4f66afcf71717a561 Mon Sep 17 00:00:00 2001 From: Mark Schulte Date: Fri, 7 Apr 2017 07:23:14 -0600 Subject: [PATCH 01/23] examples/ostest: Add tests for pthread_rwlock. Adding tests to be used to verify the pthread_rwlock lock works --- examples/ostest/Makefile | 4 + examples/ostest/ostest.h | 4 + examples/ostest/ostest_main.c | 8 + examples/ostest/pthread_rwlock.c | 250 +++++++++++++++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 examples/ostest/pthread_rwlock.c diff --git a/examples/ostest/Makefile b/examples/ostest/Makefile index 99d4d3adf..6d7df2923 100644 --- a/examples/ostest/Makefile +++ b/examples/ostest/Makefile @@ -93,6 +93,10 @@ CSRCS += sporadic.c endif endif # CONFIG_DISABLE_PTHREAD +ifeq ($(CONFIG_PTHREAD_RWLOCK),y) +CSRCS += pthread_rwlock.c +endif + ifneq ($(CONFIG_DISABLE_MQUEUE),y) ifneq ($(CONFIG_DISABLE_PTHREAD),y) CSRCS += mqueue.c timedmqueue.c diff --git a/examples/ostest/ostest.h b/examples/ostest/ostest.h index 17ee5b85d..7cd9458ed 100644 --- a/examples/ostest/ostest.h +++ b/examples/ostest/ostest.h @@ -216,6 +216,10 @@ void sporadic_test(void); void tls_test(void); +/* pthread_rwlock.c ****************************************************************/ + +void pthread_rwlock_test(void); + /* barrier.c ****************************************************************/ void barrier_test(void); diff --git a/examples/ostest/ostest_main.c b/examples/ostest/ostest_main.c index 7d1734c97..dda6579d7 100644 --- a/examples/ostest/ostest_main.c +++ b/examples/ostest/ostest_main.c @@ -426,6 +426,14 @@ static int user_main(int argc, char *argv[]) #endif #endif +#ifdef CONFIG_PTHREAD_RWLOCK + /* Verify pthreads and pthread mutex */ + + printf("\nuser_main: pthread_rwlock test\n"); + pthread_rwlock_test(); + check_test_memory_usage(); +#endif /* CONFIG_PTHREAD_RWLOCK */ + #ifndef CONFIG_DISABLE_PTHREAD /* Verify pthreads and condition variable timed waits */ diff --git a/examples/ostest/pthread_rwlock.c b/examples/ostest/pthread_rwlock.c new file mode 100644 index 000000000..9d3f7216d --- /dev/null +++ b/examples/ostest/pthread_rwlock.c @@ -0,0 +1,250 @@ +/**************************************************************************** + * apps/examples/pthread_rwlock.c + * + * Copyright (C) 2017 Mark Schulte. All rights reserved. + * Author: Mark Schulte + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct race_cond_s +{ + sem_t * sem1; + sem_t * sem2; + pthread_rwlock_t *rw_lock; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static FAR void *race_cond_thread1(FAR void *data) +{ + FAR struct race_cond_s *rc = (FAR struct race_cond_s *) data; + int status; + + /* Runs 1st */ + + status = pthread_rwlock_wrlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to lock for writing\n"); + } + + sem_post(rc->sem2); + sem_wait(rc->sem1); + + /* Context Switch -> Runs 3rd */ + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to unlock lock held for writing\n"); + } + + status = pthread_rwlock_rdlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to open rwlock for reading. Status: %d\n", status); + } + + sem_wait(rc->sem1); + + /* Context Switch - Runs 5th */ + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to unlock lock held for writing\n"); + } + + return NULL; +} + +static FAR void *race_cond_thread2(FAR void *data) +{ + FAR struct race_cond_s *rc = (FAR struct race_cond_s *) data; + int status; + + status = sem_wait(rc->sem2); + + /* Runs 2nd */ + + if (status != 0) + { + printf("pthread_rwlock: Failed to wait on semaphore. Status: %d\n", status); + } + + status = pthread_rwlock_tryrdlock(rc->rw_lock); + if (status != EBUSY) + { + printf("pthread_rwlock: Opened rw_lock for rd when locked for writing: %d\n", status); + } + + status = pthread_rwlock_trywrlock(rc->rw_lock); + if (status != EBUSY) + { + printf("pthread_rwlock: Opened rw_lock for wr when locked for writing: %d\n", status); + } + sem_post(rc->sem1); + status = pthread_rwlock_rdlock(rc->rw_lock); + + /* Context - Switch Runs 4th */ + + if (status != 0) + { + printf("pthread_rwlock: Failed to open rwlock for reading. Status: %d\n", status); + } + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to unlock lock held for writing\n"); + } + + sem_post(rc->sem1); + return NULL; +} + +static void test_two_threads(void) +{ + pthread_rwlock_t rw_lock; + struct race_cond_s rc; + pthread_t thread1; + pthread_t thread2; + sem_t sem1; + sem_t sem2; + int status; + + status = pthread_rwlock_init(&rw_lock, NULL); + if (status != 0) + { + printf("pthread_rwlock: ERROR pthread_rwlock_init failed, status=%d\n", status); + } + + status = sem_init(&sem1, 0, 0); + if (status != 0) + { + printf("pthread_rwlock: ERROR sem_init failed, status=%d\n", status); + } + + status = sem_init(&sem2, 0, 0); + if (status != 0) + { + printf("pthread_rwlock: ERROR sem_init failed, status=%d\n", status); + } + + rc.sem1 = &sem1; + rc.sem2 = &sem2; + rc.rw_lock = &rw_lock; + + status = pthread_create(&thread1, NULL, race_cond_thread1, &rc); + status = pthread_create(&thread2, NULL, race_cond_thread2, &rc); + (void) pthread_join(thread1, NULL); + (void) pthread_join(thread2, NULL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void pthread_rwlock_test(void) +{ + pthread_rwlock_t rw_lock; + int status; + + printf("pthread_rwlock: Initializing rwlock\n"); + + status = pthread_rwlock_init(&rw_lock, NULL); + if (status != 0) + { + printf("pthread_rwlock: " + "ERROR pthread_rwlock_init failed, status=%d\n", + status); + } + + status = pthread_rwlock_trywrlock(&rw_lock); + if (status != 0) + { + printf("pthread_rwlock: " + "ERROR pthread_rwlock_trywrlock failed, status=%d\n", + status); + } + + status = pthread_rwlock_unlock(&rw_lock); + if (status != 0) + { + printf("pthread_rwlock: " + "ERROR pthread_rwlock_unlock failed, status=%d\n", + status); + } + + status = pthread_rwlock_trywrlock(&rw_lock); + if (status != 0) + { + printf("pthread_rwlock: " + "ERROR pthread_rwlock_trywrlock failed, status=%d\n", + status); + } + + status = pthread_rwlock_trywrlock(&rw_lock); + if (status != EBUSY) + { + printf("pthread_rwlock: ""ERROR able to acquire to write locks\n"); + } + + status = pthread_rwlock_tryrdlock(&rw_lock); + if (status != EBUSY) + { + printf("pthread_rwlock: " + "ERROR able to acquire read lock when read lock already acquired\n"); + } + + status = pthread_rwlock_unlock(&rw_lock); + if (status != 0) + { + printf("pthread_rwlock: " + "ERROR pthread_rwlock_unlock failed, status=%d\n", + status); + } + + test_two_threads(); +} From 4c56a28016c92b0e9996a91a391be204e5582ef4 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 7 Apr 2017 07:24:09 -0600 Subject: [PATCH 02/23] 6loWPAN: Fix some conditional compilation --- include/netutils/netlib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 697d973c2..f096e7baf 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -114,7 +114,7 @@ int netlib_setmacaddr(FAR const char *ifname, FAR const uint8_t *macaddr); int netlib_getmacaddr(FAR const char *ifname, FAR uint8_t *macaddr); #endif -#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_NET_6LOWPAN /* Get IEEE802.15.4 MAC driver node address */ int netlib_setnodeaddr(FAR const char *ifname, FAR const uint8_t *nodeaddr); From acb60779883f4f11280985a8cd286a27d4bee922 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 7 Apr 2017 07:30:52 -0600 Subject: [PATCH 03/23] Remove CONFIG_PTHREAD_RWLOCK. Rwlock interfaces built unconditionally. --- examples/ostest/Makefile | 5 +---- examples/ostest/ostest_main.c | 6 ++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/examples/ostest/Makefile b/examples/ostest/Makefile index 6d7df2923..5006623fd 100644 --- a/examples/ostest/Makefile +++ b/examples/ostest/Makefile @@ -71,6 +71,7 @@ endif ifneq ($(CONFIG_DISABLE_PTHREAD),y) CSRCS += cancel.c cond.c mutex.c sem.c semtimed.c barrier.c timedwait.c +CSRCS += pthread_rwlock.c ifneq ($(CONFIG_PTHREAD_MUTEX_UNSAFE),y) CSRCS += robust.c @@ -93,10 +94,6 @@ CSRCS += sporadic.c endif endif # CONFIG_DISABLE_PTHREAD -ifeq ($(CONFIG_PTHREAD_RWLOCK),y) -CSRCS += pthread_rwlock.c -endif - ifneq ($(CONFIG_DISABLE_MQUEUE),y) ifneq ($(CONFIG_DISABLE_PTHREAD),y) CSRCS += mqueue.c timedmqueue.c diff --git a/examples/ostest/ostest_main.c b/examples/ostest/ostest_main.c index dda6579d7..d623d8482 100644 --- a/examples/ostest/ostest_main.c +++ b/examples/ostest/ostest_main.c @@ -424,15 +424,13 @@ static int user_main(int argc, char *argv[]) cond_test(); check_test_memory_usage(); #endif -#endif -#ifdef CONFIG_PTHREAD_RWLOCK - /* Verify pthreads and pthread mutex */ + /* Verify pthreads rwlock interfaces */ printf("\nuser_main: pthread_rwlock test\n"); pthread_rwlock_test(); check_test_memory_usage(); -#endif /* CONFIG_PTHREAD_RWLOCK */ +#endif /* !CONFIG_DISABLE_PTHREAD */ #ifndef CONFIG_DISABLE_PTHREAD /* Verify pthreads and condition variable timed waits */ From d7932d55dffb973d6f4ab81fc3c4a6a3e5dd15ea Mon Sep 17 00:00:00 2001 From: Mark Schulte Date: Fri, 7 Apr 2017 15:47:16 -0600 Subject: [PATCH 04/23] examples/ostest: pthread rwlock additional tests and bugfixes --- examples/ostest/pthread_rwlock.c | 197 +++++++++++++++++++++++++++++++ examples/ostest/roundrobin.c | 2 +- 2 files changed, 198 insertions(+), 1 deletion(-) diff --git a/examples/ostest/pthread_rwlock.c b/examples/ostest/pthread_rwlock.c index 9d3f7216d..a53242899 100644 --- a/examples/ostest/pthread_rwlock.c +++ b/examples/ostest/pthread_rwlock.c @@ -52,6 +52,11 @@ struct race_cond_s pthread_rwlock_t *rw_lock; }; +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int g_race_cond_thread_pos; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -63,6 +68,12 @@ static FAR void *race_cond_thread1(FAR void *data) /* Runs 1st */ + if (g_race_cond_thread_pos++ != 0) + { + printf("pthread_rwlock: Thread order unexpected. Expected 0, got %d", + g_race_cond_thread_pos); + } + status = pthread_rwlock_wrlock(rc->rw_lock); if (status != 0) { @@ -74,6 +85,12 @@ static FAR void *race_cond_thread1(FAR void *data) /* Context Switch -> Runs 3rd */ + if (g_race_cond_thread_pos++ != 2) + { + printf("pthread_rwlock: Thread order unexpected. Expected 2, got %d", + g_race_cond_thread_pos); + } + status = pthread_rwlock_unlock(rc->rw_lock); if (status != 0) { @@ -90,12 +107,41 @@ static FAR void *race_cond_thread1(FAR void *data) /* Context Switch - Runs 5th */ + if (g_race_cond_thread_pos++ != 4) + { + printf("pthread_rwlock: Thread order unexpected. Expected 4, got %d", + g_race_cond_thread_pos); + } + status = pthread_rwlock_unlock(rc->rw_lock); if (status != 0) { printf("pthread_rwlock: Failed to unlock lock held for writing\n"); } + status = pthread_rwlock_rdlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to open rwlock for reading. Status: %d\n", status); + } + + sem_post(rc->sem2); + sem_wait(rc->sem1); + + /* Context switch - Runs 7th */ + + if (g_race_cond_thread_pos++ != 6) + { + printf("pthread_rwlock: Thread order unexpected. Expected 6, got %d", + g_race_cond_thread_pos); + } + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to unlock lock held for reading. Status: %d\n", status); + } + return NULL; } @@ -113,6 +159,11 @@ static FAR void *race_cond_thread2(FAR void *data) printf("pthread_rwlock: Failed to wait on semaphore. Status: %d\n", status); } + if (g_race_cond_thread_pos++ != 1) + { + printf("pthread_rwlock: Thread order unexpected. Expected 1, got %d", g_race_cond_thread_pos); + } + status = pthread_rwlock_tryrdlock(rc->rw_lock); if (status != EBUSY) { @@ -134,6 +185,12 @@ static FAR void *race_cond_thread2(FAR void *data) printf("pthread_rwlock: Failed to open rwlock for reading. Status: %d\n", status); } + if (g_race_cond_thread_pos++ != 3) + { + printf("pthread_rwlock: Thread order unexpected. Expected 3, got %d", + g_race_cond_thread_pos); + } + status = pthread_rwlock_unlock(rc->rw_lock); if (status != 0) { @@ -141,6 +198,38 @@ static FAR void *race_cond_thread2(FAR void *data) } sem_post(rc->sem1); + sem_wait(rc->sem2); + + /* Context switch Runs 6th */ + + if (g_race_cond_thread_pos++ != 5) + { + printf("pthread_rwlock: Thread order unexpected. Expected 5, got %d", + g_race_cond_thread_pos); + } + + sem_post(rc->sem1); + status = pthread_rwlock_wrlock(rc->rw_lock); + + /* Context switch runs 8th */ + + if (status != 0) + { + printf("pthread_rwlock: Failed to open rwlock for reading. Status: %d\n", status); + } + + if (g_race_cond_thread_pos++ != 7) + { + printf("pthread_rwlock: Thread order unexpected. Expected 7, got %d", + g_race_cond_thread_pos); + } + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to unlock lock held for writing. Status: %d\n", status); + } + return NULL; } @@ -176,12 +265,118 @@ static void test_two_threads(void) rc.sem2 = &sem2; rc.rw_lock = &rw_lock; + g_race_cond_thread_pos = 0; status = pthread_create(&thread1, NULL, race_cond_thread1, &rc); status = pthread_create(&thread2, NULL, race_cond_thread2, &rc); (void) pthread_join(thread1, NULL); (void) pthread_join(thread2, NULL); } +static void * timeout_thread1(FAR void * data) +{ + FAR struct race_cond_s * rc = (FAR struct race_cond_s *) data; + int status; + + status = pthread_rwlock_wrlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to acquire rw_lock. Status: %d\n", status); + } + + sem_wait(rc->sem1); + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to unlock rw_lock. Status: %d\n", status); + } + + return NULL; +} + +static void * timeout_thread2(FAR void * data) +{ + FAR struct race_cond_s * rc = (FAR struct race_cond_s *) data; + struct timespec time; + int status; + + status = clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 2; + + status = pthread_rwlock_timedwrlock(rc->rw_lock, &time); + if (status != ETIMEDOUT) + { + printf("pthread_rwlock: Failed to properly timeout write lock\n"); + } + + status = clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 2; + + status = pthread_rwlock_timedrdlock(rc->rw_lock, &time); + if (status != ETIMEDOUT) + { + printf("pthread_rwlock: Failed to properly timeout rd lock\n"); + } + + status = clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 2; + + sem_post(rc->sem1); + status = pthread_rwlock_timedrdlock(rc->rw_lock, &time); + if (status != 0) + { + printf("pthread_rwlock: Failed to properly acquire rdlock\n"); + } + + status = pthread_rwlock_unlock(rc->rw_lock); + if (status != 0) + { + printf("pthread_rwlock: Failed to release rdlock\n"); + } + + return NULL; +} + +static void test_timeout(void) +{ + pthread_rwlock_t rw_lock; + struct race_cond_s rc; + pthread_t thread1; + pthread_t thread2; + int status; + sem_t sem1; + sem_t sem2; + + status = pthread_rwlock_init(&rw_lock, NULL); + if (status != 0) + { + printf("pthread_rwlock: ERROR pthread_rwlock_init failed, status=%d\n", + status); + } + + status = sem_init(&sem1, 0, 0); + if (status != 0) + { + printf("pthread_rwlock: ERROR sem_init failed, status=%d\n", status); + } + + status = sem_init(&sem2, 0, 0); + if (status != 0) + { + printf("pthread_rwlock: ERROR sem_init failed, status=%d\n", status); + } + + rc.sem1 = &sem1; + rc.sem2 = &sem2; + rc.rw_lock = &rw_lock; + + status = pthread_create(&thread1, NULL, timeout_thread1, &rc); + status = pthread_create(&thread2, NULL, timeout_thread2, &rc); + + (void) pthread_join(thread1, NULL); + (void) pthread_join(thread2, NULL); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -247,4 +442,6 @@ void pthread_rwlock_test(void) } test_two_threads(); + + test_timeout(); } diff --git a/examples/ostest/roundrobin.c b/examples/ostest/roundrobin.c index 5a807cf5f..4bd2d9ed4 100644 --- a/examples/ostest/roundrobin.c +++ b/examples/ostest/roundrobin.c @@ -127,7 +127,7 @@ static void get_primes(int *count, int *last) static FAR void *get_primes_thread(FAR void *parameter) { - int id = (int)parameter; + int id = (int)((intptr_t)parameter); int count; int last; int i; From ec6ff2791a31403954b81e4de2b6cf188f79c49c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 8 Apr 2017 12:19:35 -0600 Subject: [PATCH 05/23] netutils: Add a helper function to convert a string to a 6loWPAN node address --- include/netutils/netlib.h | 1 + netutils/netlib/Makefile | 2 +- netutils/netlib/netlib_nodeaddrconv.c | 109 ++++++++++++++++++++++++++ netutils/netlib/netlib_setnodeaddr.c | 6 +- 4 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 netutils/netlib/netlib_nodeaddrconv.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index f096e7baf..4e1ff9fa6 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -118,6 +118,7 @@ int netlib_getmacaddr(FAR const char *ifname, FAR uint8_t *macaddr); /* Get IEEE802.15.4 MAC driver node address */ int netlib_setnodeaddr(FAR const char *ifname, FAR const uint8_t *nodeaddr); +bool netlib_nodeaddrconv(FAR const char *hwstr, FAR uint8_t *hw); #endif /* IP address support */ diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 35030cab5..01c1e73ab 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -87,7 +87,7 @@ CSRCS += netlib_setmacaddr.c netlib_getmacaddr.c endif ifeq ($(CONFIG_NET_6LOWPAN),y) -CSRCS += netlib_setnodeaddr.c +CSRCS += netlib_setnodeaddr.c netlib_nodeaddrconv.c endif # IGMP support diff --git a/netutils/netlib/netlib_nodeaddrconv.c b/netutils/netlib/netlib_nodeaddrconv.c new file mode 100644 index 000000000..02854c516 --- /dev/null +++ b/netutils/netlib/netlib_nodeaddrconv.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * netutils/netlib/netlib_nodeaddrconv.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +#include "netutils/netlib.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_nodeaddrconv + ****************************************************************************/ + +bool netlib_nodeaddrconv(FAR const char *hwstr, FAR uint8_t *hw) +{ + unsigned char tmp; + unsigned char i; + unsigned char j; + char ch; + + /* Form xx:xx or xx:xx:xx:xx:xx:xx:xx:xx for extended Rime address */ + + if (strlen(hwstr) != 3 * NET_6LOWPAN_RIMEADDR_SIZE - 1) + { + return false; + } + + tmp = 0; + + for (i = 0; i < NET_6LOWPAN_RIMEADDR_SIZE; ++i) + { + j = 0; + do + { + ch = *hwstr++; + if (++j > 3) + { + return false; + } + + if (ch == ':' || ch == '\0') + { + *hw++ = tmp; + tmp = 0; + } + else if (ch >= '0' && ch <= '9') + { + tmp = (tmp << 4) + (ch - '0'); + } + else if (ch >= 'a' && ch <= 'f') + { + tmp = (tmp << 4) + (ch - 'a' + 10); + } + else if (ch >= 'A' && ch <= 'F') + { + tmp = (tmp << 4) + (ch - 'A' + 10); + } + else + { + return false; + } + } + while (ch != ':' && ch != 0); + } + + return true; +} diff --git a/netutils/netlib/netlib_setnodeaddr.c b/netutils/netlib/netlib_setnodeaddr.c index 942186070..436591eb9 100644 --- a/netutils/netlib/netlib_setnodeaddr.c +++ b/netutils/netlib/netlib_setnodeaddr.c @@ -49,6 +49,8 @@ #include #include +#include + #include "netutils/netlib.h" #if defined(CONFIG_NET_6LOWPAN) && CONFIG_NSOCKET_DESCRIPTORS > 0 @@ -65,7 +67,7 @@ * * Parameters: * ifname The name of the interface to use - * nodeaddr Node address to set, size must be CONFIG_NET_6LOWPAN_RIMEADDR_SIZE + * nodeaddr Node address to set, size must be NET_6LOWPAN_RIMEADDR_SIZE * * Return: * 0 on success; -1 on failure @@ -92,7 +94,7 @@ int netlib_setnodeaddr(FAR const char *ifname, FAR const uint8_t *nodeaddr) /* Put the new MAC address into the request */ req.ifr_hwaddr.sa_family = AF_INET6; - memcpy(&req.ifr_hwaddr.sa_data, nodeaddr, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE); + memcpy(&req.ifr_hwaddr.sa_data, nodeaddr, NET_6LOWPAN_RIMEADDR_SIZE); /* Perform the ioctl to set the MAC address */ From 8369052a2212555cfe29d46314c14e15ad6b4cbb Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 8 Apr 2017 12:21:40 -0600 Subject: [PATCH 06/23] NSH library: Extend ifconfig to support 6loWPAN. Adapt to some changes in configuration variable usage. --- netutils/netlib/Makefile | 2 +- nshlib/nsh.h | 5 +++-- nshlib/nsh_netcmds.c | 47 +++++++++++++++++++++++++++------------- nshlib/nsh_netinit.c | 18 +++++++++------ 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 01c1e73ab..b5a8f96d2 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -87,7 +87,7 @@ CSRCS += netlib_setmacaddr.c netlib_getmacaddr.c endif ifeq ($(CONFIG_NET_6LOWPAN),y) -CSRCS += netlib_setnodeaddr.c netlib_nodeaddrconv.c +CSRCS += netlib_setnodeaddr.c netlib_nodeaddrconv.c endif # IGMP support diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 94e7e55d8..0231ef510 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -155,8 +155,9 @@ * domain sockets were enable. */ -#if !defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_LOOPBACK) && \ - !defined(CONFIG_NET_SLIP) && !defined(CONFIG_NET_TUN) +#if !defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_6LOWPAN) && \ + !defined(CONFIG_NET_LOOPBACK) && !defined(CONFIG_NET_SLIP) && \ + !defined(CONFIG_NET_TUN) /* No link layer protocol is a good indication that there is no network * device. */ diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 592f02b3f..35f19354e 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -79,6 +79,10 @@ #include #include +#ifdef CONFIG_NET_6LOWPAN +#include +#endif + #if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \ !defined(CONFIG_DISABLE_SIGNALS) # include "netutils/netlib.h" @@ -252,7 +256,7 @@ static int ping_options(FAR struct nsh_vtbl_s *vtbl, /* There should be exactly on parameter left on the command-line */ - if (optind == argc-1) + if (optind == argc - 1) { *staddr = argv[optind]; } @@ -371,7 +375,7 @@ int tftpc_parseargs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv, /* There should be exactly one parameter left on the command-line */ - if (optind == argc-1) + if (optind == argc - 1) { args->srcpath = argv[optind]; } @@ -384,7 +388,7 @@ int tftpc_parseargs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv, goto errout; } - /* optind < argc-1 means that there are too many arguments on the + /* optind < argc - 1 means that there are too many arguments on the * command-line */ @@ -744,7 +748,7 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) FAR char *gwip = NULL; FAR char *mask = NULL; FAR char *tmp = NULL; -#ifdef CONFIG_NET_ETHERNET +#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN) FAR char *hw = NULL; #endif #if defined(CONFIG_NSH_DHCPC) || defined(CONFIG_NSH_DNS) @@ -754,7 +758,12 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) bool inet6 = false; #endif bool badarg = false; +#ifdef CONFIG_NET_ETHERNET uint8_t mac[IFHWADDRLEN]; +#endif +#ifdef CONFIG_NET_6LOWPAN + uint8_t nodeaddr[NET_6LOWPAN_RIMEADDR_SIZE]; +#endif #if defined(CONFIG_NSH_DHCPC) FAR void *handle; #endif @@ -802,9 +811,9 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) tmp = argv[i]; if (!strcmp(tmp, "dr") || !strcmp(tmp, "gw") || !strcmp(tmp, "gateway")) { - if (argc-1 >= i+1) + if (argc - 1 >= i + 1) { - gwip = argv[i+1]; + gwip = argv[i + 1]; i++; } else @@ -814,9 +823,9 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } else if (!strcmp(tmp, "netmask")) { - if (argc-1 >= i+1) + if (argc - 1 >= i + 1) { - mask = argv[i+1]; + mask = argv[i + 1]; i++; } else @@ -841,16 +850,20 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) #endif } -#ifdef CONFIG_NET_ETHERNET +#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN) /* REVISIT: How will we handle Ethernet and SLIP networks together? */ else if (!strcmp(tmp, "hw")) { - if (argc-1>=i+1) + if (argc - 1 >= i + 1) { - hw = argv[i+1]; + hw = argv[i + 1]; i++; +#ifdef CONFIG_NET_ETHERNET badarg = !netlib_ethaddrconv(hw, mac); +#else + badarg = !netlib_nodeaddrconv(hw, nodeaddr); +#endif } else { @@ -862,9 +875,9 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) #if defined(CONFIG_NSH_DHCPC) || defined(CONFIG_NSH_DNS) else if (!strcmp(tmp, "dns")) { - if (argc-1 >= i+1) + if (argc - 1 >= i + 1) { - dns = argv[i+1]; + dns = argv[i + 1]; i++; } else @@ -883,14 +896,18 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) return ERROR; } -#ifdef CONFIG_NET_ETHERNET +#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN) /* Set Hardware Ethernet MAC address */ /* REVISIT: How will we handle Ethernet and SLIP networks together? */ if (hw) { ninfo("HW MAC: %s\n", hw); +#ifdef CONFIG_NET_ETHERNET netlib_setmacaddr(intf, mac); +#else + netlib_setnodeaddr(intf, nodeaddr); +#endif } #endif @@ -1620,7 +1637,7 @@ int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* There should be exactly on parameter left on the command-line */ - if (optind == argc-1) + if (optind == argc - 1) { url = argv[optind]; } diff --git a/nshlib/nsh_netinit.c b/nshlib/nsh_netinit.c index 38c862a30..f1f1f557f 100644 --- a/nshlib/nsh_netinit.c +++ b/nshlib/nsh_netinit.c @@ -72,6 +72,10 @@ # include "netutils/dhcpc.h" #endif +#ifdef CONFIG_NET_6LOWPAN +# include +#endif + #ifdef CONFIG_NETUTILS_NTPCLIENT # include "netutils/ntpclient.h" #endif @@ -90,9 +94,9 @@ #if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN) # define HAVE_MAC 1 # if defined(CONFIG_NET_6LOWPAN) -# if (CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2) && CONFIG_NSH_MACADDR > 0xffff +# if !defined(CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED) && CONFIG_NSH_MACADDR > 0xffff # error Invalid 6loWPAN node address for SIZE == 2 -# elif (CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8) && CONFIG_NSH_MACADDR > 0xffffffffffffffffull +# elif defined(CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED) && CONFIG_NSH_MACADDR > 0xffffffffffffffffull # error Invalid 6loWPAN node address for SIZE == 8 # endif # endif @@ -249,7 +253,7 @@ static void nsh_netinit_configure(void) #if defined(CONFIG_NET_ETHERNET) uint8_t mac[IFHWADDRLEN]; #elif defined(CONFIG_NET_6LOWPAN) - uint8_t nodeaddr[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE]; + uint8_t nodeaddr[NET_6LOWPAN_RIMEADDR_SIZE]; #endif #endif @@ -275,10 +279,7 @@ static void nsh_netinit_configure(void) #elif defined(CONFIG_NET_6LOWPAN) /* Use the configured, fixed MAC address */ -#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2 - nodeaddr[0] = (CONFIG_NSH_MACADDR >> (8 * 1)) & 0xff; - nodeaddr[1] = (CONFIG_NSH_MACADDR >> (8 * 0)) & 0xff; -#elif CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8 +#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED nodeaddr[0] = (CONFIG_NSH_MACADDR >> (8 * 7)) & 0xff; nodeaddr[1] = (CONFIG_NSH_MACADDR >> (8 * 6)) & 0xff; nodeaddr[2] = (CONFIG_NSH_MACADDR >> (8 * 5)) & 0xff; @@ -287,6 +288,9 @@ static void nsh_netinit_configure(void) nodeaddr[5] = (CONFIG_NSH_MACADDR >> (8 * 2)) & 0xff; nodeaddr[6] = (CONFIG_NSH_MACADDR >> (8 * 1)) & 0xff; nodeaddr[7] = (CONFIG_NSH_MACADDR >> (8 * 0)) & 0xff; +#else + nodeaddr[0] = (CONFIG_NSH_MACADDR >> (8 * 1)) & 0xff; + nodeaddr[1] = (CONFIG_NSH_MACADDR >> (8 * 0)) & 0xff; #endif /* Set the 6loWPAN node address */ From 169bcab3311e712a08e2d5656acd8e110823dad6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 9 Apr 2017 11:54:59 -0600 Subject: [PATCH 07/23] NSH: Eliminate warning about unused variable. --- nshlib/nsh_envcmds.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nshlib/nsh_envcmds.c b/nshlib/nsh_envcmds.c index b323d9538..23e2eb95e 100644 --- a/nshlib/nsh_envcmds.c +++ b/nshlib/nsh_envcmds.c @@ -316,7 +316,9 @@ int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { FAR char *value; int ret = OK; +#ifndef CONFIG_DISABLE_ENVIRON int ndx = 1; +#endif #ifndef CONFIG_NSH_DISABLESCRIPT FAR char *popt; const char opts[] = NSH_NP_SET_OPTIONS; @@ -362,17 +364,20 @@ int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } } +#ifndef CONFIG_DISABLE_ENVIRON if (ret == OK) { ndx = 2; } +#endif } } } -# ifndef CONFIG_DISABLE_ENVIRON + +#ifndef CONFIG_DISABLE_ENVIRON if (ret == OK && (argc == 3 || argc == 4)) -# endif #endif +#endif /* CONFIG_NSH_DISABLESCRIPT */ #ifndef CONFIG_DISABLE_ENVIRON { /* Trim whitespace from the value */ From 775d1052a56fda2b8169db82c317cd5cb50f4ce5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 9 Apr 2017 12:03:18 -0600 Subject: [PATCH 08/23] NSH set command: Eliminate useless argc check of SCRIPTS are enabled but ENVIRONMENT is disabled --- nshlib/nsh_envcmds.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nshlib/nsh_envcmds.c b/nshlib/nsh_envcmds.c index 23e2eb95e..4d80e465c 100644 --- a/nshlib/nsh_envcmds.c +++ b/nshlib/nsh_envcmds.c @@ -324,9 +324,14 @@ int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) const char opts[] = NSH_NP_SET_OPTIONS; int op; +#ifndef CONFIG_DISABLE_ENVIRON /* Support set [{+|-}{e|x|xe|ex}] [ ] */ if (argc == 2 || argc == 4) +#else + /* Support set [{+|-}{e|x|xe|ex}] */ + +#endif { if (strlen(argv[1]) < 2) { From 64ad0684e7c6221881545b28fc3c3b9293ec0431 Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Mon, 10 Apr 2017 07:20:48 -0600 Subject: [PATCH 09/23] examples/ostest: additional test for rwlock and one for cancel cleanup handlers --- examples/ostest/Makefile | 13 +- examples/ostest/ostest.h | 16 +- examples/ostest/ostest_main.c | 16 +- examples/ostest/pthread_cleanup.c | 156 +++++++++++++++ examples/ostest/pthread_rwlock.c | 7 +- examples/ostest/pthread_rwlock_cancel.c | 252 ++++++++++++++++++++++++ 6 files changed, 446 insertions(+), 14 deletions(-) create mode 100644 examples/ostest/pthread_cleanup.c create mode 100644 examples/ostest/pthread_rwlock_cancel.c diff --git a/examples/ostest/Makefile b/examples/ostest/Makefile index 5006623fd..f533364c6 100644 --- a/examples/ostest/Makefile +++ b/examples/ostest/Makefile @@ -72,19 +72,24 @@ endif ifneq ($(CONFIG_DISABLE_PTHREAD),y) CSRCS += cancel.c cond.c mutex.c sem.c semtimed.c barrier.c timedwait.c CSRCS += pthread_rwlock.c +CSRCS += pthread_rwlock_cancel.c + +ifeq ($(CONFIG_PTHREAD_CLEANUP),y) +CSRCS += pthread_cleanup.c +endif ifneq ($(CONFIG_PTHREAD_MUTEX_UNSAFE),y) CSRCS += robust.c endif -ifeq ($(CONFIG_FS_NAMED_SEMAPHORES),y) -CSRCS += nsem.c -endif - ifeq ($(CONFIG_PTHREAD_MUTEX_TYPES),y) CSRCS += rmutex.c endif +ifeq ($(CONFIG_FS_NAMED_SEMAPHORES),y) +CSRCS += nsem.c +endif + ifneq ($(CONFIG_RR_INTERVAL),0) CSRCS += roundrobin.c endif diff --git a/examples/ostest/ostest.h b/examples/ostest/ostest.h index 7cd9458ed..b271d3f79 100644 --- a/examples/ostest/ostest.h +++ b/examples/ostest/ostest.h @@ -145,7 +145,7 @@ int waitpid_test(void); void mutex_test(void); -/* rmutex.c ******************************************************************/ +/* rmutex.c *****************************************************************/ void recursive_mutex_test(void); @@ -187,7 +187,7 @@ void robust_test(void); void timedwait_test(void); -/* sigprocmask.c ****************************************************************/ +/* sigprocmask.c ************************************************************/ void sigprocmask_test(void); @@ -208,7 +208,7 @@ void sigev_thread_test(void); void rr_test(void); -/* sporadic.c *************************************************************/ +/* sporadic.c ***************************************************************/ void sporadic_test(void); @@ -216,10 +216,18 @@ void sporadic_test(void); void tls_test(void); -/* pthread_rwlock.c ****************************************************************/ +/* pthread_rwlock.c *********************************************************/ void pthread_rwlock_test(void); +/* pthread_rwlock_cancel.c **************************************************/ + +void pthread_rwlock_cancel_test(void); + +/* pthread_cleanup.c ********************************************************/ + +void pthread_cleanup_test(void); + /* barrier.c ****************************************************************/ void barrier_test(void); diff --git a/examples/ostest/ostest_main.c b/examples/ostest/ostest_main.c index d623d8482..4cfe61cd7 100644 --- a/examples/ostest/ostest_main.c +++ b/examples/ostest/ostest_main.c @@ -430,15 +430,25 @@ static int user_main(int argc, char *argv[]) printf("\nuser_main: pthread_rwlock test\n"); pthread_rwlock_test(); check_test_memory_usage(); -#endif /* !CONFIG_DISABLE_PTHREAD */ -#ifndef CONFIG_DISABLE_PTHREAD + printf("\nuser_main: pthread_rwlock_cancel test\n"); + pthread_rwlock_cancel_test(); + check_test_memory_usage(); + +#ifdef CONFIG_PTHREAD_CLEANUP + /* Verify pthread cancellation cleanup handlers */ + + printf("\nuser_main: pthread_cleanup test\n"); + pthread_cleanup_test(); + check_test_memory_usage(); +#endif + /* Verify pthreads and condition variable timed waits */ printf("\nuser_main: timed wait test\n"); timedwait_test(); check_test_memory_usage(); -#endif +#endif /* !CONFIG_DISABLE_PTHREAD */ #if !defined(CONFIG_DISABLE_MQUEUE) && !defined(CONFIG_DISABLE_PTHREAD) /* Verify pthreads and message queues */ diff --git a/examples/ostest/pthread_cleanup.c b/examples/ostest/pthread_cleanup.c new file mode 100644 index 000000000..0bddf7e55 --- /dev/null +++ b/examples/ostest/pthread_cleanup.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * examples/ostest/pthread_cleanup.c + * + * Copyright (C) 2017 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sync_s +{ + pthread_cond_t cond; + pthread_mutex_t lock; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void cleanup(FAR void * data) +{ + FAR struct sync_s *sync = (FAR struct sync_s *) data; + int status; + + status = pthread_mutex_unlock(&sync->lock); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_mutex_unlock in cleanup handler. " + "Status: %d\n", status); + } +} + +static void *cleanup_thread(FAR void * data) +{ + FAR struct sync_s *sync = (FAR struct sync_s *) data; + int status; + + status = pthread_mutex_lock(&sync->lock); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_mutex_lock, status=%d\n", status); + return NULL; + } + + pthread_cleanup_push(&cleanup, sync); + + while(1) + { + status = pthread_cond_wait(&sync->cond, &sync->lock); + if (status != 0) + { + printf("pthread_cleanup: ERROR wait returned. Status: %d\n", status); + } + } + + pthread_cleanup_pop(1); + return NULL; +} + +static void test_cleanup(void) +{ + pthread_t thread1; + int status; + void *result; + struct sync_s sync = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER + }; + + status = pthread_create(&thread1, NULL, cleanup_thread, &sync); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_create, status=%d\n", status); + return; + } + + usleep(500 * 1000); + + status = pthread_cancel(thread1); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_cancel, status=%d\n", status); + } + + status = pthread_join(thread1, &result); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_join, status=%d\n", status); + } + else if (result != PTHREAD_CANCELED) + { + printf("pthread_cleanup: ERROR pthread_join returned wrong result: %p\n", result); + } + + /* Do some operations on lock in order to check if it is in usable state. */ + + status = pthread_mutex_trylock(&sync.lock); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_mutex_trylock, status=%d\n", status); + } + + status = pthread_mutex_unlock(&sync.lock); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_mutex_unlock, status=%d\n", status); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void pthread_cleanup_test(void) +{ + printf("pthread_cleanup: Starting test\n"); + test_cleanup(); +} diff --git a/examples/ostest/pthread_rwlock.c b/examples/ostest/pthread_rwlock.c index a53242899..22ad446e8 100644 --- a/examples/ostest/pthread_rwlock.c +++ b/examples/ostest/pthread_rwlock.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/examples/pthread_rwlock.c + * examples/ostest/pthread_rwlock.c * * Copyright (C) 2017 Mark Schulte. All rights reserved. * Author: Mark Schulte @@ -423,14 +423,15 @@ void pthread_rwlock_test(void) status = pthread_rwlock_trywrlock(&rw_lock); if (status != EBUSY) { - printf("pthread_rwlock: ""ERROR able to acquire to write locks\n"); + printf("pthread_rwlock: " + "ERROR able to acquire write lock when write lock already acquired\n"); } status = pthread_rwlock_tryrdlock(&rw_lock); if (status != EBUSY) { printf("pthread_rwlock: " - "ERROR able to acquire read lock when read lock already acquired\n"); + "ERROR able to acquire read lock when write lock already acquired\n"); } status = pthread_rwlock_unlock(&rw_lock); diff --git a/examples/ostest/pthread_rwlock_cancel.c b/examples/ostest/pthread_rwlock_cancel.c new file mode 100644 index 000000000..ced4075d9 --- /dev/null +++ b/examples/ostest/pthread_rwlock_cancel.c @@ -0,0 +1,252 @@ +/**************************************************************************** + * examples/ostest/pthread_rwlock_cancel.c + * + * Copyright (C) 2017 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sync_s +{ + pthread_rwlock_t *read_lock; + pthread_rwlock_t *write_lock; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void * timeout_thread1(FAR void * data) +{ + FAR struct sync_s * sync = (FAR struct sync_s *) data; + struct timespec time; + int status; + + while(1) + { + (void)clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 1; + + status = pthread_rwlock_timedrdlock(sync->write_lock, &time); + if (status != ETIMEDOUT) + { + printf("pthread_rwlock_cancel: ERROR Acquired held write_lock. Status: %d\n", status); + } + } + + return NULL; +} + +static void * timeout_thread2(FAR void * data) +{ + FAR struct sync_s * sync = (FAR struct sync_s *) data; + struct timespec time; + int status; + + while (1) + { + (void)clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 1; + + status = pthread_rwlock_timedrdlock(sync->read_lock, &time); + if (status != 0) + { + printf("pthread_rwlock_cancel: Failed to acquire read_lock. Status: %d\n", status); + } + + sched_yield(); /* Not a cancellation point. */ + + if (status == 0) + { + status = pthread_rwlock_unlock(sync->read_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: Failed to release read_lock. Status: %d\n", status); + } + } + + (void)clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 1; + + status = pthread_rwlock_timedwrlock(sync->read_lock, &time); + if (status != ETIMEDOUT) + { + printf("pthread_rwlock_cancel: " + "ERROR Acquired held read_lock for writing. Status: %d\n", status); + } + } + + return NULL; +} + +static void test_timeout(void) +{ + pthread_rwlock_t read_lock; + pthread_rwlock_t write_lock; + struct sync_s sync; + pthread_t thread1, thread2; + int status, i; + + status = pthread_rwlock_init(&read_lock, NULL); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_rwlock_init(read_lock), status=%d\n", + status); + } + + status = pthread_rwlock_init(&write_lock, NULL); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_rwlock_init(write_lock), status=%d\n", + status); + } + + status = pthread_rwlock_rdlock(&read_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_rwlock_rdlock, status=%d\n", + status); + } + + status = pthread_rwlock_wrlock(&write_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_rwlock_wrlock, status=%d\n", + status); + } + + sync.read_lock = &read_lock; + sync.write_lock = &write_lock; + + status = pthread_create(&thread1, NULL, timeout_thread1, &sync); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_create, status=%d\n", status); + } + + status = pthread_create(&thread2, NULL, timeout_thread2, &sync); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_create, status=%d\n", status); + } + + for (i = 0; i < 10; i++) + { + usleep(300 * 1000); /* Give threads few seconds to run */ + } + + status = pthread_cancel(thread1); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_cancel, status=%d\n", status); + } + + status = pthread_cancel(thread2); + if (status != 0) + { + printf("pthread_rwlock_cancel: ERROR pthread_cancel, status=%d\n", status); + } + + (void) pthread_join(thread1, NULL); + (void) pthread_join(thread2, NULL); + + /* Do some operations on locks in order to check if they are still in + * usable state after deferred cancellation. */ + +#ifdef CONFIG_PTHREAD_CLEANUP +#ifdef CONFIG_CANCELLATION_POINTS + status = pthread_rwlock_trywrlock(&write_lock); + if (status != EBUSY) + { + printf("pthread_rwlock_cancel: " + "ERROR able to acquire write lock when write lock already acquired, " + "status=%d\n", status); + } + + status = pthread_rwlock_tryrdlock(&write_lock); + if (status != EBUSY) + { + printf("pthread_rwlock_cancel: " + "ERROR able to acquire read lock when write lock already acquired, " + "status=%d\n", status); + } + + status = pthread_rwlock_unlock(&read_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: " + "ERROR pthread_rwlock_unlock, status=%d\n", status); + } + + status = pthread_rwlock_unlock(&write_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: " + "ERROR pthread_rwlock_unlock, status=%d\n", status); + } + + status = pthread_rwlock_rdlock(&read_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: " + "ERROR pthread_rwlock_rdlock, status=%d\n", status); + } + + status = pthread_rwlock_wrlock(&write_lock); + if (status != 0) + { + printf("pthread_rwlock_cancel: " + "ERROR pthread_rwlock_wrlock, status=%d\n", status); + } +#endif /* CONFIG_CANCELLATION_POINTS */ +#endif /* CONFIG_PTHREAD_CLEANUP */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void pthread_rwlock_cancel_test(void) +{ + printf("pthread_rwlock_cancel: Starting test\n"); + test_timeout(); +} From b580d494e8106161197ee002d58f92b8bc0399f0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 08:13:06 -0600 Subject: [PATCH 10/23] examples/ostest: pthread clean-up test must call pthread_consistent, not pthread_mutex_unlock() on cancellation if robust mutexes are enabled. --- examples/ostest/pthread_cleanup.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/ostest/pthread_cleanup.c b/examples/ostest/pthread_cleanup.c index 0bddf7e55..b6f018c05 100644 --- a/examples/ostest/pthread_cleanup.c +++ b/examples/ostest/pthread_cleanup.c @@ -60,12 +60,21 @@ static void cleanup(FAR void * data) FAR struct sync_s *sync = (FAR struct sync_s *) data; int status; +#ifdef CONFIG_PTHREAD_MUTEX_UNSAFE status = pthread_mutex_unlock(&sync->lock); if (status != 0) { printf("pthread_cleanup: ERROR pthread_mutex_unlock in cleanup handler. " "Status: %d\n", status); } +#else + status = pthread_mutex_consistent(&sync->lock); + if (status != 0) + { + printf("pthread_cleanup: ERROR pthread_mutex_consistent in cleanup handler. " + "Status: %d\n", status); + } +#endif } static void *cleanup_thread(FAR void * data) From cfc71db80c3baac5fe76db1bdcf0c266391eba9e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 09:51:44 -0600 Subject: [PATCH 11/23] pthreads: Backed most of last pthread changes. Found the 'real' root poblem. A one like error in pthread_mutex.c. --- examples/ostest/pthread_cleanup.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/ostest/pthread_cleanup.c b/examples/ostest/pthread_cleanup.c index b6f018c05..54650823f 100644 --- a/examples/ostest/pthread_cleanup.c +++ b/examples/ostest/pthread_cleanup.c @@ -60,21 +60,20 @@ static void cleanup(FAR void * data) FAR struct sync_s *sync = (FAR struct sync_s *) data; int status; -#ifdef CONFIG_PTHREAD_MUTEX_UNSAFE + /* Note: pthread_cond_wait() will release the mutex while it waits on + * condition value. So a EPERM error is not a failure. + */ + status = pthread_mutex_unlock(&sync->lock); - if (status != 0) + if (status == EPERM) + { + printf("pthread_cleanup: thread did not have mutex locked: %d\n", status); + } + else if (status != 0) { printf("pthread_cleanup: ERROR pthread_mutex_unlock in cleanup handler. " "Status: %d\n", status); } -#else - status = pthread_mutex_consistent(&sync->lock); - if (status != 0) - { - printf("pthread_cleanup: ERROR pthread_mutex_consistent in cleanup handler. " - "Status: %d\n", status); - } -#endif } static void *cleanup_thread(FAR void * data) From eeb143415a507aa7ce723f8964f1ac0aef6f392a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 13:28:32 -0600 Subject: [PATCH 12/23] wireless/wapi: Quick port of Wapi wireless services. No build support yet. This also depends on features not supported by NuttX. This is a work in progress. --- include/wireless/wapi.h | 647 ++++++++++++ wireless/wapi/.gitignore | 6 + wireless/wapi/LICENSE | 23 + wireless/wapi/README | 42 + wireless/wapi/examples/ifadd.c | 118 +++ wireless/wapi/examples/ifdel.c | 62 ++ wireless/wapi/examples/sample-get.c | 35 + wireless/wapi/examples/sample-set.c | 36 + wireless/wapi/examples/sample.c | 410 ++++++++ wireless/wapi/src/network.c | 425 ++++++++ wireless/wapi/src/util.c | 235 +++++ wireless/wapi/src/util.h | 75 ++ wireless/wapi/src/wireless.c | 1498 +++++++++++++++++++++++++++ 13 files changed, 3612 insertions(+) create mode 100644 include/wireless/wapi.h create mode 100644 wireless/wapi/.gitignore create mode 100644 wireless/wapi/LICENSE create mode 100644 wireless/wapi/README create mode 100644 wireless/wapi/examples/ifadd.c create mode 100644 wireless/wapi/examples/ifdel.c create mode 100644 wireless/wapi/examples/sample-get.c create mode 100644 wireless/wapi/examples/sample-set.c create mode 100644 wireless/wapi/examples/sample.c create mode 100644 wireless/wapi/src/network.c create mode 100644 wireless/wapi/src/util.c create mode 100644 wireless/wapi/src/util.h create mode 100644 wireless/wapi/src/wireless.c diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h new file mode 100644 index 000000000..c808f1883 --- /dev/null +++ b/include/wireless/wapi.h @@ -0,0 +1,647 @@ +/**************************************************************************** + * apps/include/wireless/wapi.h + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_WIRELESS_WAPI_H +#define __APPS_INCLUDE_WIRELESS_WAPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Maximum allowed ESSID size. */ + +#define WAPI_ESSID_MAX_SIZE IW_ESSID_MAX_SIZE + +/* Path to /proc/net/wireless. (Requires procfs mounted.) */ + +#define WAPI_PROC_NET_WIRELESS "/proc/net/wireless" + +/* Path to /proc/net/route. (Requires procfs mounted.) */ + +#define WAPI_PROC_NET_ROUTE "/proc/net/route" + +/* Buffer size while reading lines from PROC_NET_ files. */ + +#define WAPI_PROC_LINE_SIZE 1024 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Generic linked list (dummy) decleration. (No definition!) */ + +typedef struct wapi_list_t wapi_list_t; + +/* Frequency flags. */ + +typedef enum +{ + WAPI_FREQ_AUTO = IW_FREQ_AUTO, + WAPI_FREQ_FIXED = IW_FREQ_FIXED +} wapi_freq_flag_t; + +/* Route target types. */ + +typedef enum +{ + WAPI_ROUTE_TARGET_NET, /* The target is a network. */ + WAPI_ROUTE_TARGET_HOST /* The target is a host. */ +} wapi_route_target_t; + +/* ESSID flags. */ + +typedef enum +{ + WAPI_ESSID_ON, + WAPI_ESSID_OFF +} wapi_essid_flag_t; + +/* Supported operation modes. */ + +typedef enum +{ + WAPI_MODE_AUTO = IW_MODE_AUTO, /* Driver decides. */ + WAPI_MODE_ADHOC = IW_MODE_ADHOC, /* Single cell network. */ + WAPI_MODE_MANAGED = IW_MODE_INFRA, /* Multi cell network, roaming, ... */ + WAPI_MODE_MASTER = IW_MODE_MASTER, /* Synchronisation master or access point. */ + WAPI_MODE_REPEAT = IW_MODE_REPEAT, /* Wireless repeater, forwarder. */ + WAPI_MODE_SECOND = IW_MODE_SECOND, /* Secondary master/repeater, backup. */ + WAPI_MODE_MONITOR = IW_MODE_MONITOR /* Passive monitor, listen only. */ +} wapi_mode_t; + +/* Bitrate flags. + * + * At the moment, unicast (IW_BITRATE_UNICAST) and broadcast + * (IW_BITRATE_BROADCAST) bitrate flags are not supported. + */ + +typedef enum +{ + WAPI_BITRATE_AUTO, + WAPI_BITRATE_FIXED +} wapi_bitrate_flag_t; + +/* Transmit power (txpower) flags. */ + +typedef enum +{ + WAPI_TXPOWER_DBM, /* Value is in dBm. */ + WAPI_TXPOWER_MWATT, /* Value is in mW. */ + WAPI_TXPOWER_RELATIVE /* Value is in arbitrary units. */ +} wapi_txpower_flag_t; + +/* Linked list container for strings. */ + +typedef struct wapi_string_t +{ + FAR struct wapi_string_t *next; + FAR char *data; +} wapi_string_t; + +/* Linked list container for scan results. */ + +typedef struct wapi_scan_info_t +{ + FAR struct wapi_scan_info_t *next; + struct ether_addr ap; + int has_essid; + char essid[WAPI_ESSID_MAX_SIZE + 1]; + wapi_essid_flag_t essid_flag; + int has_freq; + double freq; + int has_mode; + wapi_mode_t mode; + int has_bitrate; + int bitrate; +} wapi_scan_info_t; + +/* Linked list container for routing table rows. */ + +typedef struct wapi_route_info_t +{ + FAR struct wapi_route_info_t *next; + FAR char *ifname; + struct in_addr dest; + struct in_addr gw; + + unsigned int flags;/* See RTF_* in net/route.h for available values. */ + unsigned int refcnt; + unsigned int use; + unsigned int metric; + struct in_addr netmask; + unsigned int mtu; + unsigned int window; + unsigned int irtt; +} wapi_route_info_t; + +/* A generic linked list container. For functions taking wapi_list_t type of + * argument, caller is resposible for releasing allocated memory. + */ + +struct wapi_list_t +{ + union wapi_list_head_t + { + FAR wapi_string_t *string; + FAR wapi_scan_info_t *scan; + FAR wapi_route_info_t *route; + } head; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + + #ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Frequency flag names. */ + +EXTERN FAR const char *g_wapi_freq_flags[]; + +/* ESSID flag names. */ + +EXTERN FAR const char *g_wapi_essid_flags[]; + +/* Supported operation mode names. */ + +EXTERN FAR const char *g_wapi_modes[]; + +/* Bitrate flag names. */ + +EXTERN FAR const char *g_wapi_bitrate_flags[]; + +/* Transmit power flag names. */ + +EXTERN FAR const char *g_wapi_txpower_flags[]; + +/**************************************************************************** + * Public Function Prototyppes + ****************************************************************************/ + +/**************************************************************************** + * Name: wapi_get_ifup + * + * Description: + * Gets the interface up status. + * + * Input Parameters: + * is_up Set to 0, if up; 1, otherwise. + * + ****************************************************************************/ + +int wapi_get_ifup(int sock, const char *ifname, int *is_up); + +/**************************************************************************** + * Name: wapi_set_ifup + * + * Description: + * Activates the interface. + * + ****************************************************************************/ + +int wapi_set_ifup(int sock, const char *ifname); + +/**************************************************************************** + * Name: wapi_set_ifdown + * + * Description: + * Shuts down the interface. + * + ****************************************************************************/ + +int wapi_set_ifdown(int sock, const char *ifname); + +/**************************************************************************** + * Name: wapi_get_ip + * + * Description: + * Gets IP address of the given network interface. + * + ****************************************************************************/ + +int wapi_get_ip(int sock, const char *ifname, struct in_addr *addr); + +/**************************************************************************** + * Name: wapi_set_ip + * + * Description: + * Sets IP adress of the given network interface. + * + ****************************************************************************/ + +int wapi_set_ip(int sock, const char *ifname, const struct in_addr *addr); + +/**************************************************************************** + * Name: wapi_get_netmask + * + * Description: + * Gets netmask of the given network interface. + * + ****************************************************************************/ + +int wapi_get_netmask(int sock, const char *ifname, struct in_addr *addr); + +/**************************************************************************** + * Name: wapi_set_netmask + * + * Description: + * Sets netmask of the given network interface. + * + ****************************************************************************/ + +int wapi_set_netmask(int sock, const char *ifname, const struct in_addr *addr); + +/**************************************************************************** + * Name: wapi_get_routes + * + * Description: + * Parses routing table rows from WAPI_PROC_NET_ROUTE. + * + * Input Parameters: + * list - Pushes collected wapi_route_info_t into this list. + * + ****************************************************************************/ + +int wapi_get_routes(wapi_list_t * list); + +/**************************************************************************** + * Name: wapi_add_route_gw + * + * Description: + * Adds gateway for the given target network. + * + ****************************************************************************/ + +int wapi_add_route_gw(int sock, wapi_route_target_t targettype, + FAR const struct in_addr *target, + FAR const struct in_addr *netmask, + FAR const struct in_addr *gw); + +/**************************************************************************** + * Name: wapi_del_route_gw + * + * Description: + * Deletes gateway for the given target network. + * + ****************************************************************************/ + +int wapi_del_route_gw(int sock, wapi_route_target_t targettype, + FAR const struct in_addr *target, + FAR const struct in_addr *netmask, + FAR const struct in_addr *gw); + +/**************************************************************************** + * Name: wapi_get_we_version + * + * Description: + * Gets kernel WE (Wireless Extensions) version. + * + * Input Parameters: + * we_version Set to we_version_compiled of range information. + * + * Returned Value: + * Zero on success. + * + ****************************************************************************/ + +int wapi_get_we_version(int sock, const char *ifname, FAR int *we_version); + +/**************************************************************************** + * Name: wapi_get_freq + * + * Description: + * Gets the operating frequency of the device. + * + ****************************************************************************/ + +int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, + FAR wapi_freq_flag_t *flag); + +/**************************************************************************** + * Name: wapi_set_freq + * + * Description: + * Sets the operating frequency of the device. + * + ****************************************************************************/ + +int wapi_set_freq(int sock, FARconst char *ifname, double freq, + wapi_freq_flag_t flag); + +/**************************************************************************** + * Name: wapi_freq2chan + * + * Description: + * Finds corresponding channel for the supplied freq. + * + * Returned Value: + * 0, on success; -2, if not found; otherwise, ioctl() return value. + * + ****************************************************************************/ + +int wapi_freq2chan(int sock, FAR const char *ifname, double freq, + FAR int *chan); + +/**************************************************************************** + * Name: wapi_chan2freq + * + * Description: + * Finds corresponding frequency for the supplied chan. + * + * Returned Value: + * 0, on success; -2, if not found; otherwise, ioctl() return value. + * + ****************************************************************************/ + +int wapi_chan2freq(int sock, FAR const char *ifname, int chan, + FAR double *freq); + +/**************************************************************************** + * Name: wapi_get_essid + * + * Description: + * Gets ESSID of the device. + * + * Input Parameters: + * essid - Used to store the ESSID of the device. Buffer must have + * enough space to store WAPI_ESSID_MAX_SIZE+1 characters. + * + ****************************************************************************/ + +int wapi_get_essid(int sock, FAR const char *ifname, FAR char *essid, + FAR wapi_essid_flag_t *flag); + +/**************************************************************************** + * Name: wapi_set_essid + * + * Description: + * Sets ESSID of the device. + * + * essid At most WAPI_ESSID_MAX_SIZE characters are read. + * + ****************************************************************************/ + +int wapi_set_essid(int sock, FAR const char *ifname, FAR const char *essid, + wapi_essid_flag_t flag); + +/**************************************************************************** + * Name: wapi_get_mode + * + * Description: + * Gets the operating mode of the device. + * + ****************************************************************************/ + +int wapi_get_mode(int sock, FAR const char *ifname, FAR wapi_mode_t *mode); + +/**************************************************************************** + * Name: wapi_set_mode + * + * Description: + * Sets the operating mode of the device. + * + ****************************************************************************/ + +int wapi_set_mode(int sock, FAR const char *ifname, wapi_mode_t mode); + +/**************************************************************************** + * Name: wapi_make_broad_ether + * + * Description: + * Creates an ethernet broadcast address. + * + ****************************************************************************/ + +int wapi_make_broad_ether(FAR struct ether_addr *sa); + +/**************************************************************************** + * Name: wapi_make_null_ether + * + * Description: + * Creates an ethernet NULL address. + * + ****************************************************************************/ + +int wapi_make_null_ether(FAR struct ether_addr *sa); + +/**************************************************************************** + * Name: wapi_get_ap + * + * Description: + * Gets access point address of the device. + * + * Input Parameters: + * ap - Set the to MAC address of the device. (For "any", a broadcast + * ethernet address; for "off", a null ethernet address is used.) + * + ****************************************************************************/ + +int wapi_get_ap(int sock, FAR const char *ifname, FAR struct ether_addr *ap); + +/**************************************************************************** + * Name: wapi_set_ap + * + * Description: + * Sets access point address of the device. + * + ****************************************************************************/ + +int wapi_set_ap(int sock, FAR const char *ifname, + FAR const struct ether_addr *ap); + +/**************************************************************************** + * Name: wapi_get_bitrate + * + * Description: + * Gets bitrate of the device. + * + ****************************************************************************/ + +int wapi_get_bitrate(int sock, FAR const char *ifname, + FAR int *bitrate, FAR wapi_bitrate_flag_t *flag); + +/**************************************************************************** + * Name: wapi_set_bitrate + * + * Description: + * Sets bitrate of the device. + * + ****************************************************************************/ + +int wapi_set_bitrate(int sock, FAR const char *ifname, int bitrate, + wapi_bitrate_flag_t flag); + +/**************************************************************************** + * Name: wapi_dbm2mwatt + * + * Description: + * Converts a value in dBm to a value in milliWatt. + * + ****************************************************************************/ + +int wapi_dbm2mwatt(int dbm); + +/**************************************************************************** + * Name: wapi_mwatt2dbm + * + * Description: + * Converts a value in milliWatt to a value in dBm. + * + ****************************************************************************/ + +int wapi_mwatt2dbm(int mwatt); + +/**************************************************************************** + * Name: wapi_get_txpower + * + * Description: + * Gets txpower of the device. + * + ****************************************************************************/ + +int wapi_get_txpower(int sock, FAR const char *ifname, FAR int *power, + FAR wapi_txpower_flag_t *flag); + +/**************************************************************************** + * Name: wapi_set_txpower + * + * Description: + * Sets txpower of the device. + * + ****************************************************************************/ + +int wapi_set_txpower(int sock, FAR const char *ifname, int power, + wapi_txpower_flag_t flag); + +/**************************************************************************** + * Name: wapi_if_add + * + * Description: + * Creates a virtual interface with name for interface ifname. + * + ****************************************************************************/ + +int wapi_if_add(int sock, FAR const char *ifname, FAR const char *name, + wapi_mode_t mode); + +/**************************************************************************** + * Name: wapi_if_del + * + * Description: + * Deletes a virtual interface with name. + * + ****************************************************************************/ + +int wapi_if_del(int sock, FAR const char *ifname); + +/**************************************************************************** + * Name: wapi_make_socket + * + * Description: + * Creates an AF_INET socket to be used in ioctl() calls. + * + * Returned Value: + * Non-negative on success. + * + ****************************************************************************/ + +int wapi_make_socket(void); + +/**************************************************************************** + * Name: wapi_get_ifnames + * + * Description: + * Parses WAPI_PROC_NET_WIRELESS. + * + * Returned Value: + * list Pushes collected wapi_string_t into this list. + * + ****************************************************************************/ + +int wapi_get_ifnames(FAR wapi_list_t *list); + +/**************************************************************************** + * Name: wapi_scan_init + * + * Description: + * Starts a scan on the given interface. Root privileges are required to start a + * scan. + * + ****************************************************************************/ + +int wapi_scan_init(int sock, const char *ifname); + +/**************************************************************************** + * Name: wapi_scan_stat + * + * Description: + * Checks the status of the scan process. + * + * Returned Value: + * Zero, if data is ready; 1, if data is not ready; negative on failure. + * + ****************************************************************************/ + +int wapi_scan_stat(int sock, FAR const char *ifname); + +/**************************************************************************** + * Name: wapi_scan_coll + * + * Description: + * Collects the results of a scan process. + * + * Input Parameters: + * aps - Pushes collected wapi_scan_info_t into this list. + * + ****************************************************************************/ + +int wapi_scan_coll(int sock, FAR const char *ifname, FAR wapi_list_t *aps); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_WIRELESS_WAPI_H */ diff --git a/wireless/wapi/.gitignore b/wireless/wapi/.gitignore new file mode 100644 index 000000000..f21c854d1 --- /dev/null +++ b/wireless/wapi/.gitignore @@ -0,0 +1,6 @@ +/.built +/.depend +/Make.dep +/*.src +/*.obj +/*.lst diff --git a/wireless/wapi/LICENSE b/wireless/wapi/LICENSE new file mode 100644 index 000000000..eeb3ddaae --- /dev/null +++ b/wireless/wapi/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2010, Volkan YAZICI +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/wireless/wapi/README b/wireless/wapi/README new file mode 100644 index 000000000..41cafb9c2 --- /dev/null +++ b/wireless/wapi/README @@ -0,0 +1,42 @@ + + `_`_`_`_____`_____`__` + |`|`|`|``_``|``_``|``| + |`|`|`|`````|```__|``| + |_____|__|__|__|``|__| + +WAPI (Wireless API) provides an easy-to-use function set to configure wireless +network interfaces on a GNU/Linux system. One can think WAPI as a lightweight C +API for iwconfig, wlanconfig, ifconfig, and route commands. (But it is not a +thin wrapper for these command line tools.) It is designed to be used in +wireless heteregenous network research projects and supported by BWRC (Berkeley +Wireless Research Center) and WISERLAB (Wireless Information Systems Engineering +Research Laboratory at Özyeğin University). + +For source codes, see http://github.com/vy/wapi. The most recent version of the +documentation is (hopefully) always available at http://vy.github.com/wapi. + +--- L I C E N S E -------------------------------------------------------------- + +Copyright (c) 2010, Volkan YAZICI +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/wireless/wapi/examples/ifadd.c b/wireless/wapi/examples/ifadd.c new file mode 100644 index 000000000..2885949ba --- /dev/null +++ b/wireless/wapi/examples/ifadd.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * apps/wireless/wapi/examples/ifadd.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "include/wireless/wapi.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int parse_wapi_mode(FAR const char *s, FAR wapi_mode_t * mode) +{ + int ret = 0; + + if (!strcmp(s, "auto")) + { + *mode = WAPI_MODE_AUTO; + else if (!strcmp(s, "adhoc")) + { + *mode = WAPI_MODE_ADHOC; + } + else if (!strcmp(s, "managed")) + { + *mode = WAPI_MODE_MANAGED; + } + else if (!strcmp(s, "master")) + { + *mode = WAPI_MODE_MASTER; + } + else if (!strcmp(s, "repeat")) + { + *mode = WAPI_MODE_REPEAT; + } + else if (!strcmp(s, "second")) + { + *mode = WAPI_MODE_SECOND; + } + else if (!strcmp(s, "monitor")) + { + *mode = WAPI_MODE_MONITOR; + } + else + { + ret = 1; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int ifadd_main(int argc, char *argv[]) +#endif +{ + wapi_mode_t mode; + FAR const char *ifname; + FAR const char *name; + int ret; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + ifname = argv[1]; + name = argv[2]; + + if (parse_wapi_mode(argv[3], &mode)) + { + fprintf(stderr, "Unknown mode: %s!\n", argv[3]); + return EXIT_FAILURE; + } + + ret = wapi_if_add(-1, ifname, name, mode); + fprintf(stderr, "wapi_if_add(): ret: %d\n", ret); + + return ret; +} diff --git a/wireless/wapi/examples/ifdel.c b/wireless/wapi/examples/ifdel.c new file mode 100644 index 000000000..bc32eb9e0 --- /dev/null +++ b/wireless/wapi/examples/ifdel.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * apps/wireless/wapi/examples/ifdel.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "include/wireless/wapi.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int ifdel_main(int argc, char *argv[]) +#endif +{ + int ret; + + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + ret = wapi_if_del(-1, argv[1]); + fprintf(stderr, "wapi_if_del(): ret: %d\n", ret); + + return ret; +} diff --git a/wireless/wapi/examples/sample-get.c b/wireless/wapi/examples/sample-get.c new file mode 100644 index 000000000..7508d551e --- /dev/null +++ b/wireless/wapi/examples/sample-get.c @@ -0,0 +1,35 @@ +/**************************************************************************** + * apps/wireless/wapi/examples/sample.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "sample.c" diff --git a/wireless/wapi/examples/sample-set.c b/wireless/wapi/examples/sample-set.c new file mode 100644 index 000000000..f7c6bb600 --- /dev/null +++ b/wireless/wapi/examples/sample-set.c @@ -0,0 +1,36 @@ +/**************************************************************************** + * apps/wireless/wapi/examples/sample.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define ENABLE_SET +#include "sample.c" diff --git a/wireless/wapi/examples/sample.c b/wireless/wapi/examples/sample.c new file mode 100644 index 000000000..04b288e6b --- /dev/null +++ b/wireless/wapi/examples/sample.c @@ -0,0 +1,410 @@ +/**************************************************************************** + * apps/wireless/wapi/examples/sample.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "include/wireless/wapi.h" + + +/* Gets current configuration of the @a ifname using WAPI accessors and prints + * them in a pretty fashion with their corresponding return values. If a getter + * succeeds, we try to set that property with the same value to test the setters + * as well. + */ + +static void conf(int sock, FAR const char *ifname) +{ + int ret; + struct in_addr addr; + double freq; + wapi_freq_flag_t freq_flag; + char essid[WAPI_ESSID_MAX_SIZE + 1]; + wapi_essid_flag_t essid_flag; + wapi_mode_t mode; + struct ether_addr ap; + int bitrate; + wapi_bitrate_flag_t bitrate_flag; + int txpower; + wapi_txpower_flag_t txpower_flag; + + /* Get ip */ + + bzero(&addr, sizeof(struct in_addr)); + ret = wapi_get_ip(sock, ifname, &addr); + printf("wapi_get_ip(): ret: %d", ret); + if (ret >= 0) + { + printf(", ip: %s", inet_ntoa(addr)); + +#ifdef ENABLE_SET + /* set ip (Make sure sin.sin_family is set to AF_INET.) */ + + ret = wapi_set_ip(sock, ifname, &addr); + printf("\nwapi_set_ip(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get netmask */ + + bzero(&addr, sizeof(struct in_addr)); + ret = wapi_get_netmask(sock, ifname, &addr); + printf("wapi_get_netmask(): ret: %d", ret); + if (ret >= 0) + { + printf(", netmask: %s", inet_ntoa(addr)); + +#ifdef ENABLE_SET + /* set netmask (Make sure sin.sin_family is set to AF_INET.) */ + + ret = wapi_set_netmask(sock, ifname, &addr); + printf("\nwapi_set_netmask(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get freq */ + + ret = wapi_get_freq(sock, ifname, &freq, &freq_flag); + printf("wapi_get_freq(): ret: %d", ret); + if (ret >= 0) + { + int chan; + double tmpfreq; + + printf(", freq: %g, freq_flag: %s", freq, g_wapi_freq_flags[freq_flag]); + + ret = wapi_freq2chan(sock, ifname, freq, &chan); + printf("\nwapi_freq2chan(): ret: %d", ret); + if (ret >= 0) + { + printf(", chan: %d", chan); + } + + ret = wapi_chan2freq(sock, ifname, chan, &tmpfreq); + printf("\nwapi_chan2freq(): ret: %d", ret); + if (ret >= 0) + { + printf(", freq: %g", tmpfreq); + } + +#ifdef ENABLE_SET + /* Set freq */ + + ret = wapi_set_freq(sock, ifname, freq, freq_flag); + printf("\nwapi_set_freq(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get essid */ + + ret = wapi_get_essid(sock, ifname, essid, &essid_flag); + printf("wapi_get_essid(): ret: %d", ret); + if (ret >= 0) + { + printf(", essid: %s, essid_flag: %s", + essid, g_wapi_essid_flags[essid_flag]); + +#ifdef ENABLE_SET + /* Set essid */ + + ret = wapi_set_essid(sock, ifname, essid, essid_flag); + printf("\nwapi_set_essid(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get operating mode */ + + ret = wapi_get_mode(sock, ifname, &mode); + printf("wapi_get_mode(): ret: %d", ret); + if (ret >= 0) + { + printf(", mode: %s", g_wapi_modes[mode]); + +#ifdef ENABLE_SET + /* Set operating mode */ + + ret = wapi_set_mode(sock, ifname, mode); + printf("\nwapi_set_mode(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get ap */ + + ret = wapi_get_ap(sock, ifname, &ap); + printf("wapi_get_ap(): ret: %d", ret); + if (ret >= 0) + { + printf(", ap: %02X:%02X:%02X:%02X:%02X:%02X", + ap.ether_addr_octet[0], ap.ether_addr_octet[1], + ap.ether_addr_octet[2], ap.ether_addr_octet[3], + ap.ether_addr_octet[4], ap.ether_addr_octet[5]); + +#ifdef ENABLE_SET + /* Set ap */ + + ret = wapi_set_ap(sock, ifname, &ap); + printf("\nwapi_set_ap(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get bitrate */ + + ret = wapi_get_bitrate(sock, ifname, &bitrate, &bitrate_flag); + printf("wapi_get_bitrate(): ret: %d", ret); + if (ret >= 0) + { + printf(", bitrate: %d, bitrate_flag: %s", bitrate, + g_wapi_bitrate_flags[bitrate_flag]); + +#ifdef ENABLE_SET + /* Set bitrate */ + + ret = wapi_set_bitrate(sock, ifname, bitrate, bitrate_flag); + printf("\nwapi_set_bitrate(): ret: %d", ret); +#endif + } + + putchar('\n'); + + /* Get txpower */ + + ret = wapi_get_txpower(sock, ifname, &txpower, &txpower_flag); + printf("wapi_get_txpower(): ret: %d", ret); + if (ret >= 0) + { + printf(", txpower: %d, txpower_flag: %s", + txpower, g_wapi_txpower_flags[txpower_flag]); + +#ifdef ENABLE_SET + /* Set txpower */ + + ret = wapi_set_txpower(sock, ifname, txpower, txpower_flag); + printf("\nwapi_set_txpower(): ret: %d", ret); +#endif + } + + putchar('\n'); +} + +/* Scans available APs in the range using given @a ifname interface. (Requires + * root privileges to start a scan.) + */ + +static void scan(int sock, FAR const char *ifname) +{ + int sleepdur = 1; + int sleeptries = 5; + wapi_list_t list; + FAR wapi_scan_info_t *info; + int ret; + + /* Start scan */ + + ret = wapi_scan_init(sock, ifname); + printf("wapi_scan_init(): ret: %d\n", ret); + + /* Wait for completion */ + + do + { + sleep(sleepdur); + ret = wapi_scan_stat(sock, ifname); + printf("wapi_scan_stat(): ret: %d, sleeptries: %d\n", ret, sleeptries); + } + while (--sleeptries > 0 && ret > 0); + + if (ret < 0) + { + return; + } + + /* Collect results */ + + bzero(&list, sizeof(wapi_list_t)); + ret = wapi_scan_coll(sock, ifname, &list); + printf("wapi_scan_coll(): ret: %d\n", ret); + + /* Print found aps */ + + for (info = list.head.scan; info; info = info->next) + { + printf(">> %02x:%02x:%02x:%02x:%02x:%02x %s\n", + info->ap.ether_addr_octet[0], info->ap.ether_addr_octet[1], + info->ap.ether_addr_octet[2], info->ap.ether_addr_octet[3], + info->ap.ether_addr_octet[4], info->ap.ether_addr_octet[5], + (info->has_essid ? info->essid : "")); + } + + /* Free ap list */ + + info = list.head.scan; + while (info) + { + FAR wapi_scan_info_t *temp; + + temp = info->next; + free(info); + info = temp; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int wapi_main(int argc, char *argv[]) +#endif +{ + FAR const char *ifname; + wapi_list_t list; + int ret; + int sock; + + /* Check command line args */ + + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + ifname = argv[1]; + + /* Get ifnames */ + + bzero(&list, sizeof(wapi_list_t)); + ret = wapi_get_ifnames(&list); + printf("wapi_get_ifnames(): ret: %d", ret); + if (ret >= 0) + { + FAR wapi_string_t *str; + + /* Print ifnames */ + + printf(", ifnames:"); + for (str = list.head.string; str; str = str->next) + { + printf(" %s", str->data); + } + + /* Free ifnames */ + + str = list.head.string; + while (str) + { + FAR wapi_string_t *tmp; + + tmp = str->next; + free(str->data); + free(str); + str = tmp; + } + } + + putchar('\n'); + + /* Get routes */ + + bzero(&list, sizeof(wapi_list_t)); + ret = wapi_get_routes(&list); + printf("wapi_get_routes(): ret: %d\n", ret); + if (ret >= 0) + { + wapi_route_info_t *ri; + + /* Print route */ + + for (ri = list.head.route; ri; ri = ri->next) + { + printf(">> dest: %s, gw: %s, netmask: %s\n", + inet_ntoa(ri->dest), inet_ntoa(ri->gw), + inet_ntoa(ri->netmask)); + } + + /* Free routes */ + + ri = list.head.route; + while (ri) + { + FAR wapi_route_info_t *tmpri; + + tmpri = ri->next; + free(ri->ifname); + free(ri); + ri = tmpri; + } + } + + /* Make a comm. sock. */ + + sock = wapi_make_socket(); + printf("wapi_make_socket(): sock: %d\n", sock); + + /* List conf */ + + printf("\nconf\n"); + printf("------------\n"); + conf(sock, ifname); + + /* Scan aps */ + + printf("\nscan\n"); + printf("----\n"); + scan(sock, ifname); + + /* Close comm. sock. */ + + close(sock); + return EXIT_SUCCESS; +} diff --git a/wireless/wapi/src/network.c b/wireless/wapi/src/network.c new file mode 100644 index 000000000..893bf434d --- /dev/null +++ b/wireless/wapi/src/network.c @@ -0,0 +1,425 @@ +/**************************************************************************** + * apps/wireless/wapi/examples/network.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "include/wireless/wapi.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int wapi_get_addr(int sock, FAR const char *ifname, int cmd, + FAR struct in_addr *addr) +{ + struct ifreq ifr; + int ret; + + WAPI_VALIDATE_PTR(addr); + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, cmd, &ifr)) >= 0) + { + struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; + memcpy(addr, &sin->sin_addr, sizeof(struct in_addr)); + } + else + { + WAPI_IOCTL_STRERROR(cmd); + } + + return ret; +} + +static int wapi_set_addr(int sock, FAR const char *ifname, int cmd, + FAR const struct in_addr *addr) +{ + struct sockaddr_in sin; + struct ifreq ifr; + int ret; + + WAPI_VALIDATE_PTR(addr); + + sin.sin_family = AF_INET; + memcpy(&sin.sin_addr, addr, sizeof(struct in_addr)); + memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in)); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, cmd, &ifr)) < 0) + { + WAPI_IOCTL_STRERROR(cmd); + } + + return ret; +} + +static int wapi_act_route_gw(int sock, int act, + wapi_route_target_t targettype, + FAR const struct in_addr *target, + FAR const struct in_addr *netmask, + FAR const struct in_addr *gw) +{ + int ret; + struct rtentry rt; + FAR struct sockaddr_in *sin; + + /* Clean out rtentry. */ + + bzero(&rt, sizeof(struct rtentry)); + + /* Set target. */ + + sin = (struct sockaddr_in *)&rt.rt_dst; + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, target, sizeof(struct in_addr)); + + /* Set netmask. */ + + sin = (struct sockaddr_in *)&rt.rt_genmask; + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, netmask, sizeof(struct in_addr)); + + /* Set gateway. */ + + sin = (struct sockaddr_in *)&rt.rt_gateway; + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, gw, sizeof(struct in_addr)); + + /* Set rt_flags. */ + + rt.rt_flags = RTF_UP | RTF_GATEWAY; + if (targettype == WAPI_ROUTE_TARGET_HOST) + { + rt.rt_flags |= RTF_HOST; + } + + if ((ret = ioctl(sock, act, &rt)) < 0) + { + WAPI_IOCTL_STRERROR(act); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wapi_get_ifup + * + * Description: + * Gets the interface up status. + * + * Input Parameters: + * is_up Set to 0, if up; 1, otherwise. + * + ****************************************************************************/ + +int wapi_get_ifup(int sock, FAR const char *ifname, FAR int *is_up) +{ + struct ifreq ifr; + int ret; + + WAPI_VALIDATE_PTR(is_up); + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIFFLAGS, &ifr)) >= 0) + { + *is_up = (ifr.ifr_flags & IFF_UP) == IFF_UP; + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIFFLAGS); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_ifup + * + * Description: + * Activates the interface. + * + ****************************************************************************/ + +int wapi_set_ifup(int sock, FAR const char *ifname) +{ + struct ifreq ifr; + int ret; + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIFFLAGS, &ifr)) >= 0) + { + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + ret = ioctl(sock, SIOCSIFFLAGS, &ifr); + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIFFLAGS); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_ifdown + * + * Description: + * Shuts down the interface. + * + ****************************************************************************/ + +int wapi_set_ifdown(int sock, FAR const char *ifname) +{ + struct ifreq ifr; + int ret; + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIFFLAGS, &ifr)) >= 0) + { + ifr.ifr_flags &= ~IFF_UP; + ret = ioctl(sock, SIOCSIFFLAGS, &ifr); + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIFFLAGS); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_get_ip + * + * Description: + * Gets IP address of the given network interface. + * + ****************************************************************************/ + +int wapi_get_ip(int sock, FAR const char *ifname, FAR struct in_addr *addr) +{ + return wapi_get_addr(sock, ifname, SIOCGIFADDR, addr); +} + +/**************************************************************************** + * Name: wapi_set_ip + * + * Description: + * Sets IP adress of the given network interface. + * + ****************************************************************************/ + +int wapi_set_ip(int sock, FAR const char *ifname, + FAR const struct in_addr *addr) +{ + return wapi_set_addr(sock, ifname, SIOCSIFADDR, addr); +} + +/**************************************************************************** + * Name: wapi_set_netmask + * + * Description: + * Sets netmask of the given network interface. + * + ****************************************************************************/ + +int wapi_get_netmask(int sock, FAR const char *ifname, + FAR struct in_addr *addr) +{ + return wapi_get_addr(sock, ifname, SIOCGIFNETMASK, addr); +} + +/**************************************************************************** + * Name: wapi_set_netmask + * + * Description: + * Sets netmask of the given network interface. + * + ****************************************************************************/ + +int wapi_set_netmask(int sock, FAR const char *ifname, + FAR const struct in_addr *addr) +{ + return wapi_set_addr(sock, ifname, SIOCSIFNETMASK, addr); +} + +/**************************************************************************** + * Name: wapi_get_routes + * + * Description: + * Parses routing table rows from WAPI_PROC_NET_ROUTE. + * + * Input Parameters: + * list - Pushes collected wapi_route_info_t into this list. + * + ****************************************************************************/ + +int wapi_get_routes(FAR wapi_list_t *list) +{ + FAR FILE *fp; + int ret; + size_t bufsiz = WAPI_PROC_LINE_SIZE * sizeof(char); + char buf[WAPI_PROC_LINE_SIZE]; + + WAPI_VALIDATE_PTR(list); + + /* Open file for reading. */ + + fp = fopen(WAPI_PROC_NET_ROUTE, "r"); + if (!fp) + { + WAPI_STRERROR("fopen(\"%s\", \"r\")", WAPI_PROC_NET_ROUTE); + return -1; + } + + /* Skip header line. */ + + if (!fgets(buf, bufsiz, fp)) + { + WAPI_ERROR("Invalid \"%s\" content!\n", WAPI_PROC_NET_ROUTE); + return -1; + } + + /* Read lines. */ + + ret = 0; + while (fgets(buf, bufsiz, fp)) + { + wapi_route_info_t *ri; + char ifname[WAPI_PROC_LINE_SIZE]; + int refcnt, use, metric, mtu, window, irtt; + unsigned int dest, gw, flags, netmask; + + /* Allocate route row buffer. */ + + ri = malloc(sizeof(wapi_route_info_t)); + if (!ri) + { + WAPI_STRERROR("malloc()"); + ret = -1; + break; + } + + /* Read and tokenize fields. */ + + sscanf(buf, "%s\t" /* ifname */ + "%x\t" /* dest */ + "%x\t" /* gw */ + "%x\t" /* flags */ + "%d\t" /* refcnt */ + "%d\t" /* use */ + "%d\t" /* metric */ + "%x\t" /* mask */ + "%d\t" /* mtu */ + "%d\t" /* window */ + "%d\t", /* irtt */ + ifname, &dest, &gw, &flags, &refcnt, &use, &metric, &netmask, &mtu, + &window, &irtt); + + /* Allocate "ifname". */ + + ri->ifname = malloc((strlen(ifname) + 1) * sizeof(char)); + if (!ri->ifname) + { + WAPI_STRERROR("malloc()"); + free(ri); + ret = -1; + break; + } + + /* Copy fields. */ + + sprintf(ri->ifname, "%s", ifname); + ri->dest.s_addr = dest; + ri->gw.s_addr = gw; + ri->flags = flags; + ri->refcnt = refcnt; + ri->use = use; + ri->metric = metric; + ri->netmask.s_addr = netmask; + ri->mtu = mtu; + ri->window = window; + ri->irtt = irtt; + + /* Push parsed node to the list. */ + + ri->next = list->head.route; + list->head.route = ri; + } + + /* Close file. */ + + fclose(fp); + return 0; +} + +/**************************************************************************** + * Name: wapi_add_route_gw + * + * Description: + * Adds gateway for the given target network. + * + ****************************************************************************/ + +int wapi_add_route_gw(int sock, wapi_route_target_t targettype, + FAR const struct in_addr *target, + FAR const struct in_addr *netmask, + FAR const struct in_addr *gw) +{ + return wapi_act_route_gw(sock, SIOCADDRT, targettype, target, netmask, gw); +} + +/**************************************************************************** + * Name: wapi_del_route_gw + * + * Description: + * Deletes gateway for the given target network. + * + ****************************************************************************/ + +int wapi_del_route_gw(int sock, wapi_route_target_t targettype, + FAR const struct in_addr *target, + FAR const struct in_addr *netmask, + FAR const struct in_addr *gw) +{ + return wapi_act_route_gw(sock, SIOCDELRT, targettype, target, netmask, gw); +} diff --git a/wireless/wapi/src/util.c b/wireless/wapi/src/util.c new file mode 100644 index 000000000..4f8729721 --- /dev/null +++ b/wireless/wapi/src/util.c @@ -0,0 +1,235 @@ +/**************************************************************************** + * apps/wireless/wapi/src/util.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "include/wireless/wapi.h" +#include "util.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define WAPI_IOCTL_COMMAND_NAMEBUFSIZ 128 /* Is fairly enough to print an + * integer. */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static char g_ioctl_command_namebuf[WAPI_IOCTL_COMMAND_NAMEBUFSIZ]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wapi_make_socket + * + * Description: + * Creates an AF_INET socket to be used in ioctl() calls. + * + * Returned Value: + * Non-negative on success. + * + ****************************************************************************/ + +int wapi_make_socket(void) +{ + return socket(AF_INET, SOCK_DGRAM, 0); +} + +/**************************************************************************** + * Name: wapi_get_ifnames + * + * Description: + * Parses WAPI_PROC_NET_WIRELESS. + * + * Returned Value: + * list Pushes collected wapi_string_t into this list. + * + ****************************************************************************/ + +int wapi_get_ifnames(FAR wapi_list_t *list) +{ + FILE *fp; + int ret; + size_t tmpsize = WAPI_PROC_LINE_SIZE * sizeof(char); + char tmp[WAPI_PROC_LINE_SIZE]; + + WAPI_VALIDATE_PTR(list); + + /* Open file for reading. */ + + fp = fopen(WAPI_PROC_NET_WIRELESS, "r"); + if (!fp) + { + WAPI_STRERROR("fopen(\"%s\", \"r\")", WAPI_PROC_NET_WIRELESS); + return -1; + } + + /* Skip first two lines. */ + + if (!fgets(tmp, tmpsize, fp) || !fgets(tmp, tmpsize, fp)) + { + WAPI_ERROR("Invalid \"%s\" content!\n", WAPI_PROC_NET_WIRELESS); + return -1; + } + + /* Iterate over available lines. */ + + ret = 0; + while (fgets(tmp, tmpsize, fp)) + { + char *beg; + char *end; + wapi_string_t *string; + + /* Locate the interface name region. */ + + for (beg = tmp; *beg && isspace(*beg); beg++); + for (end = beg; *end && *end != ':'; end++); + + /* Allocate both wapi_string_t and char vector. */ + + string = malloc(sizeof(wapi_string_t)); + if (string) + { + string->data = malloc(end - beg + sizeof(char)); + } + + if (!string || !string->data) + { + WAPI_STRERROR("malloc()"); + ret = -1; + break; + } + + /* Copy region into the buffer. */ + + snprintf(string->data, (end - beg + sizeof(char)), "%s", beg); + + /* Push string into the list. */ + + string->next = list->head.string; + list->head.string = string; + } + + fclose(fp); + return ret; +} + +/**************************************************************************** + * Name: wapi_get_ifnames + * + * Description: + * Return name string for IOCTL command + * + * Returned Value: + * Name string for IOCTL command + * + ****************************************************************************/ + +FAR const char *wapi_ioctl_command_name(int cmd) +{ + switch (cmd) + { + case SIOCADDRT: + return "SIOCADDRT"; + + case SIOCDELRT: + return "SIOCDELRT"; + + case SIOCGIFADDR: + return "SIOCGIFADDR"; + + case SIOCGIWAP: + return "SIOCGIWAP"; + + case SIOCGIWESSID: + return "SIOCGIWESSID"; + + case SIOCGIWFREQ: + return "SIOCGIWFREQ"; + + case SIOCGIWMODE: + return "SIOCGIWMODE"; + + case SIOCGIWRANGE: + return "SIOCGIWRANGE"; + + case SIOCGIWRATE: + return "SIOCGIWRATE"; + + case SIOCGIWSCAN: + return "SIOCGIWSCAN"; + + case SIOCGIWTXPOW: + return "SIOCGIWTXPOW"; + + case SIOCSIFADDR: + return "SIOCSIFADDR"; + + case SIOCSIWAP: + return "SIOCSIWAP"; + + case SIOCSIWESSID: + return "SIOCSIWESSID"; + + case SIOCSIWFREQ: + return "SIOCSIWFREQ"; + + case SIOCSIWMODE: + return "SIOCSIWMODE"; + + case SIOCSIWRATE: + return "SIOCSIWRATE"; + + case SIOCSIWSCAN: + return "SIOCSIWSCAN"; + + case SIOCSIWTXPOW: + return "SIOCSIWTXPOW"; + + default: + snprintf(g_ioctl_command_namebuf, WAPI_IOCTL_COMMAND_NAMEBUFSIZ, + "0x%x", cmd); + return g_ioctl_command_namebuf; + } +} diff --git a/wireless/wapi/src/util.h b/wireless/wapi/src/util.h new file mode 100644 index 000000000..4982e3155 --- /dev/null +++ b/wireless/wapi/src/util.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * apps/wireless/wapi/src/util.h + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __APPS_WIRELESS_WAPI_SRC_UTIL_H +#define __APPS_WIRELESS_WAPI_SRC_UTIL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define WAPI_IOCTL_STRERROR(cmd) \ + fprintf( \ + stderr, "%s:%d:%s():ioctl(%s): %s\n", \ + __FILE__, __LINE__, __func__, \ + wapi_ioctl_command_name(cmd), strerror(errno)) + +#define WAPI_STRERROR(fmt, ...) \ + fprintf( \ + stderr, "%s:%d:%s():" fmt ": %s\n", \ + __FILE__, __LINE__, __func__, \ + ## __VA_ARGS__, strerror(errno)) + +#define WAPI_ERROR(fmt, ...) \ + fprintf( \ + stderr, "%s:%d:%s(): " fmt , \ + __FILE__, __LINE__, __func__, ## __VA_ARGS__) + +#define WAPI_VALIDATE_PTR(ptr) \ + if (!ptr) \ + { \ + WAPI_ERROR("Null pointer: %s.\n", #ptr); \ + return -1; \ + } + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +FAR const char *wapi_ioctl_command_name(int cmd); + +#endif /* __APPS_WIRELESS_WAPI_SRC_UTIL_H */ diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c new file mode 100644 index 000000000..d2a137c67 --- /dev/null +++ b/wireless/wapi/src/wireless.c @@ -0,0 +1,1498 @@ +/**************************************************************************** + * apps/wireless/wapi/src/wireless.c + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "include/wireless/wapi.h" +#include "util.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef LIBNL1 +# define nl_sock nl_handle +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Events & Streams */ + +struct iw_event_stream_s +{ + FAR char *end; /* End of the stream */ + FAR char *current; /* Current event in stream of events */ + FAR char *value; /* Current value in event */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Frequency */ + +FAR const char *g_wapi_freq_flags[] = +{ + "WAPI_FREQ_AUTO", + "WAPI_FREQ_FIXED" +}; + +/* ESSID */ + +FAR const char *g_wapi_essid_flags[] = +{ + "WAPI_ESSID_ON", + "WAPI_ESSID_OFF" +}; + +/* Operating Mode */ + +FAR const char *g_wapi_modes[] = +{ + "WAPI_MODE_AUTO", + "WAPI_MODE_ADHOC", + "WAPI_MODE_MANAGED", + "WAPI_MODE_MASTER", + "WAPI_MODE_REPEAT", + "WAPI_MODE_SECOND", + "WAPI_MODE_MONITOR" +}; + +/* Bit Rate */ + +FAR const char *g_wapi_bitrate_flags[] = +{ + "WAPI_BITRATE_AUTO", + "WAPI_BITRATE_FIXED" +}; + +/* Transmit Power */ + +FAR const char *g_wapi_txpower_flags[] = +{ + "WAPI_TXPOWER_DBM", + "WAPI_TXPOWER_MWATT", + "WAPI_TXPOWER_RELATIVE" +}; + +/* Add/Delete */ + +typedef enum +{ + WAPI_NL80211_CMD_IFADD, + WAPI_NL80211_CMD_IFDEL +} wapi_nl80211_cmd_t; + +typedef struct wapi_nl80211_ifadd_ctx_t +{ + FAR const char *name; + wapi_mode_t mode; +} wapi_nl80211_ifadd_ctx_t; + +typedef struct wapi_nl80211_ifdel_ctx_t +{ +} wapi_nl80211_ifdel_ctx_t; + +typedef struct wapi_nl80211_ctx_t +{ + FAR const char *ifname; + wapi_nl80211_cmd_t cmd; + union + { + wapi_nl80211_ifadd_ctx_t ifadd; + wapi_nl80211_ifdel_ctx_t ifdel; + } u; +} wapi_nl80211_ctx_t; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wapi_freq2float + * + * Description: + * Converts internal representation of frequencies to a floating point. + * + ****************************************************************************/ + +static inline double wapi_freq2float(const struct iw_freq *freq) +{ + return ((double)freq->m) * pow(10, freq->e); +} + +/**************************************************************************** + * Name: wapi_float2freq + * + * Description: + * Converts a floating point the our internal representation of frequencies. + * + ****************************************************************************/ + +static inline void wapi_float2freq(double floatfreq, struct iw_freq *freq) +{ + freq->e = (short)floor(log10(floatfreq)); + if (freq->e > 8) + { + freq->m = ((long)(floor(floatfreq / pow(10, freq->e - 6)))) * 100; + freq->e -= 8; + } + else + { + freq->m = (long)floatfreq; + freq->e = 0; + } +} + +/**************************************************************************** + * Name: wapi_parse_mode + * + * Description: + * + ****************************************************************************/ + +static int wapi_parse_mode(int iw_mode, FAR wapi_mode_t *wapi_mode) +{ + switch (iw_mode) + { + case WAPI_MODE_AUTO: + case WAPI_MODE_ADHOC: + case WAPI_MODE_MANAGED: + case WAPI_MODE_MASTER: + case WAPI_MODE_REPEAT: + case WAPI_MODE_SECOND: + case WAPI_MODE_MONITOR: + *wapi_mode = iw_mode; + return 0; + + default: + WAPI_ERROR("Unknown mode: %d.\n", iw_mode); + return -1; + } +} + +/**************************************************************************** + * Name: wapi_make_ether + * + * Description: + * + ****************************************************************************/ + +static int wapi_make_ether(FAR struct ether_addr *addr, int byte) +{ + WAPI_VALIDATE_PTR(addr); + memset(addr, byte, sizeof(struct ether_addr)); + return 0; +} + +/**************************************************************************** + * Name: iw_event_stream_init + * + * Description: + * + ****************************************************************************/ + +static void iw_event_stream_init(FAR struct iw_event_stream_s *stream, + FAR char *data, size_t len) +{ + memset(stream, 0, sizeof(struct iw_event_stream_s)); + stream->current = data; + stream->end = &data[len]; +} + +/**************************************************************************** + * Name: iw_event_stream_pop + * + * Description: + * + ****************************************************************************/ + +static int iw_event_stream_pop(FAR struct iw_event_stream_s *stream, + FAR struct iw_event *iwe, int we_version) +{ + return iw_extract_event_stream((struct stream_descr *)stream, iwe, + we_version); +} + +/**************************************************************************** + * Name: wapi_scan_event + * + * Description: + * + ****************************************************************************/ + +static int wapi_scan_event(FAR struct iw_event *event, FAR wapi_list_t *list) +{ + FAR wapi_scan_info_t *info; + + /* Get current "wapi_info_t". */ + + info = list->head.scan; + + /* Decode the event. */ + + switch (event->cmd) + { + case SIOCGIWAP: + { + wapi_scan_info_t *temp; + + /* Allocate a new cell. */ + + temp = malloc(sizeof(wapi_scan_info_t)); + if (!temp) + { + WAPI_STRERROR("malloc()"); + return -1; + } + + /* Reset it. */ + + bzero(temp, sizeof(wapi_scan_info_t)); + + /* Save cell identifier. */ + + memcpy(&temp->ap, &event->u.ap_addr.sa_data, sizeof(struct ether_addr)); + + /* Push it to the head of the list. */ + + temp->next = info; + list->head.scan = temp; + + break; + } + + case SIOCGIWFREQ: + info->has_freq = 1; + info->freq = wapi_freq2float(&(event->u.freq)); + break; + + case SIOCGIWMODE: + { + int ret = wapi_parse_mode(event->u.mode, &info->mode); + if (ret >= 0) + { + info->has_mode = 1; + break; + } + else + { + return ret; + } + } + + case SIOCGIWESSID: + info->has_essid = 1; + info->essid_flag = (event->u.data.flags) ? WAPI_ESSID_ON : WAPI_ESSID_OFF; + memset(info->essid, 0, (WAPI_ESSID_MAX_SIZE + 1)); + if ((event->u.essid.pointer) && (event->u.essid.length)) + { + memcpy(info->essid, event->u.essid.pointer, event->u.essid.length); + } + break; + + case SIOCGIWRATE: + /* Scan may return a list of bitrates. As we have space for only a single + * bitrate, we only keep the largest one. + */ + + if (!info->has_bitrate || event->u.bitrate.value > info->bitrate) + { + info->has_bitrate = 1; + info->bitrate = event->u.bitrate.value; + } + break; + } + + return 0; +} + +/**************************************************************************** + * Name: nl_socket_alloc + * + * Description: + * + ****************************************************************************/ + +#ifdef LIBNL1 +static FAR struct nl_handle *nl_socket_alloc(void) +{ + return nl_handle_alloc(); +} +#endif /* LIBNL1 */ + +/**************************************************************************** + * Name: nl_socket_free + * + * Description: + * + ****************************************************************************/ + +#ifdef LIBNL1 +static void nl_socket_free(FAR struct nl_sock *h) +{ + nl_handle_destroy(h); +} +#endif /* LIBNL1 */ + +/**************************************************************************** + * Name: wapi_mode_to_iftype + * + * Description: + * + ****************************************************************************/ + +static int wapi_mode_to_iftype(wapi_mode_t mode, FAR enum nl80211_iftype *type) +{ + int ret = 0; + + switch (mode) + { + case WAPI_MODE_AUTO: + *type = NL80211_IFTYPE_UNSPECIFIED; + break; + + case WAPI_MODE_ADHOC: + *type = NL80211_IFTYPE_ADHOC; + break; + + case WAPI_MODE_MANAGED: + *type = NL80211_IFTYPE_STATION; + break; + + case WAPI_MODE_MASTER: + *type = NL80211_IFTYPE_AP; + break; + + case WAPI_MODE_MONITOR: + *type = NL80211_IFTYPE_MONITOR; + break; + + default: + WAPI_ERROR("No supported nl80211 iftype for mode: %s!\n", + g_wapi_modes[mode]); + ret = -1; + } + + return ret; +} + +/**************************************************************************** + * Name: nl80211_err_handler + * + * Description: + * + ****************************************************************************/ + +static int nl80211_err_handler(FAR struct sockaddr_nl *nla, + FAR struct nlmsgerr *err, FAR void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +/**************************************************************************** + * Name: nl80211_fin_handler + * + * Description: + * + ****************************************************************************/ + +static int nl80211_fin_handler(FAR struct nl_msg *msg, FAR void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_SKIP; +} + +/**************************************************************************** + * Name: nl80211_ack_handler + * + * Description: + * + ****************************************************************************/ + +static int nl80211_ack_handler(FAR struct nl_msg *msg, FAR void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +/**************************************************************************** + * Name: nl80211_cmd_handler + * + * Description: + * + ****************************************************************************/ + +static int nl80211_cmd_handler(FAR const wapi_nl80211_ctx_t *ctx) +{ + FAR struct nl_sock *sock; + FAR struct nl_msg *msg; + FAR struct nl_cb *cb; + int family; + int ifidx; + int ret; + + /* Allocate netlink socket. */ + + sock = nl_socket_alloc(); + if (!sock) + { + WAPI_ERROR("Failed to allocate netlink socket!\n"); + return -ENOMEM; + } + + /* Reset "msg" and "cb". */ + + msg = NULL; + cb = NULL; + + /* Connect to generic netlink socket on kernel side. */ + + if (genl_connect(sock)) + { + WAPI_ERROR("Failed to connect to generic netlink!\n"); + ret = -ENOLINK; + goto exit; + } + + /* Ask kernel to resolve family name to family id. */ + + ret = family = genl_ctrl_resolve(sock, "nl80211"); + if (ret < 0) + { + WAPI_ERROR("genl_ctrl_resolve() failed!\n"); + goto exit; + } + + /* Map given network interface name (ifname) to its corresponding index. */ + + ifidx = if_nametoindex(ctx->ifname); + if (!ifidx) + { + WAPI_STRERROR("if_nametoindex(\"%s\")", ctx->ifname); + ret = -errno; + goto exit; + } + + /* Construct a generic netlink by allocating a new message. */ + + msg = nlmsg_alloc(); + if (!msg) + { + WAPI_ERROR("nlmsg_alloc() failed!\n"); + ret = -ENOMEM; + goto exit; + } + + /* Append the requested command to the message. */ + + switch (ctx->cmd) + { + case WAPI_NL80211_CMD_IFADD: + { + enum nl80211_iftype iftype; + + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, 0, + NL80211_CMD_NEW_INTERFACE, 0); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx); + + /* Get NL80211_IFTYPE_* for the given WAPI mode. */ + + ret = wapi_mode_to_iftype(ctx->u.ifadd.mode, &iftype); + if (ret < 0) + { + goto exit; + } + + NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ctx->u.ifadd.name); + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype); + break; + } + + case WAPI_NL80211_CMD_IFDEL: + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, 0, + NL80211_CMD_DEL_INTERFACE, 0); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx); + break; + } + + /* Finalize (send) the message. */ + + ret = nl_send_auto_complete(sock, msg); + if (ret < 0) + { + WAPI_ERROR("nl_send_auto_complete() failed!\n"); + goto exit; + } + + /* Allocate a new callback handle. */ + + cb = nl_cb_alloc(NL_CB_VERBOSE); + if (!cb) + { + WAPI_ERROR("nl_cb_alloc() failed\n"); + ret = -1; + goto exit; + } + + /* Configure callback handlers. */ + + nl_cb_err(cb, NL_CB_CUSTOM, nl80211_err_handler, &ret); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_fin_handler, &ret); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_ack_handler, &ret); + + /* Consume netlink replies. */ + + for (ret = 1; ret > 0;) + { + nl_recvmsgs(sock, cb); + } + + if (ret) + { + WAPI_ERROR("nl_recvmsgs() failed!\n"); + } + +exit: + /* Release resources and exit with "ret". */ + + nl_socket_free(sock); + if (msg) + { + nlmsg_free(msg); + } + + if (cb) + { + free(cb); + } + + return ret; + +nla_put_failure: + WAPI_ERROR("nla_put_failure!\n"); + ret = -1; + goto exit; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wapi_get_we_version + * + * Description: + * Gets kernel WE (Wireless Extensions) version. + * + * Input Parameters: + * we_version Set to we_version_compiled of range information. + * + * Returned Value: + * Zero on success. + * + ****************************************************************************/ + +int wapi_get_we_version(int sock, const char *ifname, FAR int *we_version) +{ + struct iwreq wrq; + char buf[sizeof(struct iw_range) * 2]; + int ret; + + WAPI_VALIDATE_PTR(we_version); + + /* Prepare request. */ + + bzero(buf, sizeof(buf)); + wrq.u.data.pointer = buf; + wrq.u.data.length = sizeof(buf); + wrq.u.data.flags = 0; + + /* Get WE version. */ + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWRANGE, &wrq)) >= 0) + { + struct iw_range *range = (struct iw_range *)buf; + *we_version = (int)range->we_version_compiled; + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWRANGE); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_get_freq + * + * Description: + * Gets the operating frequency of the device. + * + ****************************************************************************/ + +int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, + FAR wapi_freq_flag_t *flag); +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(freq); + WAPI_VALIDATE_PTR(flag); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWFREQ, &wrq)) >= 0) + { + /* Set flag. */ + + if (IW_FREQ_AUTO == (wrq.u.freq.flags & IW_FREQ_AUTO)) + { + *flag = WAPI_FREQ_AUTO; + } + else if (IW_FREQ_FIXED == (wrq.u.freq.flags & IW_FREQ_FIXED)) + { + *flag = WAPI_FREQ_FIXED; + } + else + { + WAPI_ERROR("Unknown flag: %d.\n", wrq.u.freq.flags); + return -1; + } + + /* Set freq. */ + + *freq = wapi_freq2float(&(wrq.u.freq)); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_freq + * + * Description: + * Sets the operating frequency of the device. + * + ****************************************************************************/ + +int wapi_set_freq(int sock, FARconst char *ifname, double freq, + wapi_freq_flag_t flag); +{ + struct iwreq wrq; + int ret; + + /* Set freq. */ + + wapi_float2freq(freq, &(wrq.u.freq)); + + /* Set flag. */ + + switch (flag) + { + case WAPI_FREQ_AUTO: + wrq.u.freq.flags = IW_FREQ_AUTO; + break; + + case WAPI_FREQ_FIXED: + wrq.u.freq.flags = IW_FREQ_FIXED; + break; + } + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCSIWFREQ, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWFREQ); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_freq2chan + * + * Description: + * Finds corresponding channel for the supplied freq. + * + * Returned Value: + * 0, on success; -2, if not found; otherwise, ioctl() return value. + * + ****************************************************************************/ + +int wapi_freq2chan(int sock, FAR const char *ifname, double freq, + FAR int *chan) +{ + struct iwreq wrq; + char buf[sizeof(struct iw_range) * 2]; + int ret; + + WAPI_VALIDATE_PTR(chan); + + /* Prepare request. */ + + bzero(buf, sizeof(buf)); + wrq.u.data.pointer = buf; + wrq.u.data.length = sizeof(buf); + wrq.u.data.flags = 0; + + /* Get range. */ + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWRANGE, &wrq)) >= 0) + { + struct iw_range *range = (struct iw_range *)buf; + int k; + + /* Compare the frequencies as double to ignore differences in encoding. + * Slower, but safer... + */ + + for (k = 0; k < range->num_frequency; k++) + { + if (freq == wapi_freq2float(&(range->freq[k]))) + { + *chan = range->freq[k].i; + return 0; + } + } + + /* Oops! Nothing found. */ + + ret = -2; + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWRANGE); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_chan2freq + * + * Description: + * Finds corresponding frequency for the supplied chan. + * + * Returned Value: + * 0, on success; -2, if not found; otherwise, ioctl() return value. + * + ****************************************************************************/ + +int wapi_chan2freq(int sock, FAR const char *ifname, int chan, + FAR double *freq) +{ + struct iwreq wrq; + char buf[sizeof(struct iw_range) * 2]; + int ret; + + WAPI_VALIDATE_PTR(freq); + + /* Prepare request. */ + + bzero(buf, sizeof(buf)); + wrq.u.data.pointer = buf; + wrq.u.data.length = sizeof(buf); + wrq.u.data.flags = 0; + + /* Get range. */ + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWRANGE, &wrq)) >= 0) + { + struct iw_range *range = (struct iw_range *)buf; + int k; + + for (k = 0; k < range->num_frequency; k++) + { + if (chan == range->freq[k].i) + { + *freq = wapi_freq2float(&(range->freq[k])); + return 0; + } + } + + /* Oops! Nothing found. */ + + ret = -2; + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWRANGE); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_get_essid + * + * Description: + * Gets ESSID of the device. + * + * Input Parameters: + * essid - Used to store the ESSID of the device. Buffer must have + * enough space to store WAPI_ESSID_MAX_SIZE+1 characters. + * + ****************************************************************************/ + +int wapi_get_essid(int sock, FAR const char *ifname, FAR char *essid, + FAR wapi_essid_flag_t *flag) +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(essid); + WAPI_VALIDATE_PTR(flag); + + wrq.u.essid.pointer = essid; + wrq.u.essid.length = WAPI_ESSID_MAX_SIZE + 1; + wrq.u.essid.flags = 0; + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCGIWESSID, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCGIWESSID); + } + else + { + *flag = (wrq.u.essid.flags) ? WAPI_ESSID_ON : WAPI_ESSID_OFF; + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_essid + * + * Description: + * Sets ESSID of the device. + * + * essid At most WAPI_ESSID_MAX_SIZE characters are read. + * + ****************************************************************************/ + +int wapi_set_essid(int sock, FAR const char *ifname, FAR const char *essid, + wapi_essid_flag_t flag) +{ + char buf[WAPI_ESSID_MAX_SIZE + 1]; + struct iwreq wrq; + int ret; + + /* Prepare request. */ + + wrq.u.essid.pointer = buf; + wrq.u.essid.length = + snprintf(buf, ((WAPI_ESSID_MAX_SIZE + 1) * sizeof(char)), "%s", essid); + wrq.u.essid.flags = (flag == WAPI_ESSID_ON); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCSIWESSID, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWESSID); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_get_mode + * + * Description: + * Gets the operating mode of the device. + * + ****************************************************************************/ + +int wapi_get_mode(int sock, FAR const char *ifname, FAR wapi_mode_t *mode) +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(mode); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWMODE, &wrq)) >= 0) + { + ret = wapi_parse_mode(wrq.u.mode, mode); + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWMODE); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_mode + * + * Description: + * Sets the operating mode of the device. + * + ****************************************************************************/ + +int wapi_set_mode(int sock, FAR const char *ifname, wapi_mode_t mode) +{ + struct iwreq wrq; + int ret; + + wrq.u.mode = mode; + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCSIWMODE, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWMODE); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_make_broad_ether + * + * Description: + * Creates an ethernet broadcast address. + * + ****************************************************************************/ + +int wapi_make_broad_ether(FAR struct ether_addr *sa) +{ + return wapi_make_ether(sa, 0xFF); +} + +/**************************************************************************** + * Name: wapi_make_null_ether + * + * Description: + * Creates an ethernet NULL address. + * + ****************************************************************************/ + +int wapi_make_null_ether(FAR struct ether_addr *sa) +{ + return wapi_make_ether(sa, 0x00); +} + +/**************************************************************************** + * Name: wapi_get_ap + * + * Description: + * Gets access point address of the device. + * + * Input Parameters: + * ap - Set the to MAC address of the device. (For "any", a broadcast + * ethernet address; for "off", a null ethernet address is used.) + * + ****************************************************************************/ + +int wapi_get_ap(int sock, FAR const char *ifname, FAR struct ether_addr *ap) +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(ap); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWAP, &wrq)) >= 0) + { + memcpy(ap, wrq.u.ap_addr.sa_data, sizeof(struct ether_addr)); + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWAP); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_ap + * + * Description: + * Sets access point address of the device. + * + ****************************************************************************/ + +int wapi_set_ap(int sock, FAR const char *ifname, + FAR const struct ether_addr *ap) +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(ap); + + wrq.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(wrq.u.ap_addr.sa_data, ap, sizeof(struct ether_addr)); + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(sock, SIOCSIWAP, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWAP); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_get_bitrate + * + * Description: + * Gets bitrate of the device. + * + ****************************************************************************/ + +int wapi_get_bitrate(int sock, FAR const char *ifname, + FAR int *bitrate, FAR wapi_bitrate_flag_t *flag) +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(bitrate); + WAPI_VALIDATE_PTR(flag); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWRATE, &wrq)) >= 0) + { + /* Check if enabled. */ + if (wrq.u.bitrate.disabled) + { + WAPI_ERROR("Bitrate is disabled.\n"); + return -1; + } + + /* Get bitrate. */ + *bitrate = wrq.u.bitrate.value; + *flag = wrq.u.bitrate.fixed ? WAPI_BITRATE_FIXED : WAPI_BITRATE_AUTO; + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWRATE); + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_bitrate + * + * Description: + * Sets bitrate of the device. + * + ****************************************************************************/ + +int wapi_set_bitrate(int sock, FAR const char *ifname, int bitrate, + wapi_bitrate_flag_t flag) +{ + struct iwreq wrq; + int ret; + + wrq.u.bitrate.value = bitrate; + wrq.u.bitrate.fixed = (flag == WAPI_BITRATE_FIXED); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCSIWRATE, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWRATE); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_dbm2mwatt + * + * Description: + * Converts a value in dBm to a value in milliWatt. + * + ****************************************************************************/ + +int wapi_dbm2mwatt(int dbm) +{ + return floor(pow(10, (((double)dbm) / 10))); +} + +/**************************************************************************** + * Name: wapi_mwatt2dbm + * + * Description: + * Converts a value in milliWatt to a value in dBm. + * + ****************************************************************************/ + +int wapi_mwatt2dbm(int mwatt) +{ + return ceil(10 * log10(mwatt)); +} + +/**************************************************************************** + * Name: wapi_get_txpower + * + * Description: + * Gets txpower of the device. + * + ****************************************************************************/ + +int wapi_get_txpower(int sock, FAR const char *ifname, FAR int *power, + FAR wapi_txpower_flag_t *flag) +{ + struct iwreq wrq; + int ret; + + WAPI_VALIDATE_PTR(power); + WAPI_VALIDATE_PTR(flag); + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWTXPOW, &wrq)) >= 0) + { + /* Check if enabled. */ + + if (wrq.u.txpower.disabled) + { + return -1; + } + + /* Get flag. */ + + if (IW_TXPOW_DBM == (wrq.u.txpower.flags & IW_TXPOW_DBM)) + { + *flag = WAPI_TXPOWER_DBM; + } + else if (IW_TXPOW_MWATT == (wrq.u.txpower.flags & IW_TXPOW_MWATT)) + { + *flag = WAPI_TXPOWER_MWATT; + } + else if (IW_TXPOW_RELATIVE == (wrq.u.txpower.flags & IW_TXPOW_RELATIVE)) + { + *flag = WAPI_TXPOWER_RELATIVE; + } + else + { + WAPI_ERROR("Unknown flag: %d.\n", wrq.u.txpower.flags); + return -1; + } + + /* Get power. */ + + *power = wrq.u.txpower.value; + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWTXPOW); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_set_txpower + * + * Description: + * Sets txpower of the device. + * + ****************************************************************************/ + +int wapi_set_txpower(int sock, FAR const char *ifname, int power, + wapi_txpower_flag_t flag); +{ + struct iwreq wrq; + int ret; + + /* Construct the request. */ + + wrq.u.txpower.value = power; + switch (flag) + { + case WAPI_TXPOWER_DBM: + wrq.u.txpower.flags = IW_TXPOW_DBM; + break; + + case WAPI_TXPOWER_MWATT: + wrq.u.txpower.flags = IW_TXPOW_MWATT; + break; + + case WAPI_TXPOWER_RELATIVE: + wrq.u.txpower.flags = IW_TXPOW_RELATIVE; + break; + } + + /* Issue the set command. */ + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCSIWTXPOW, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWTXPOW); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_scan_init + * + * Description: + * Starts a scan on the given interface. Root privileges are required to start a + * scan. + * + ****************************************************************************/ + +int wapi_scan_init(int sock, const char *ifname) +{ + struct iwreq wrq; + int ret; + + wrq.u.data.pointer = NULL; + wrq.u.data.flags = 0; + wrq.u.data.length = 0; + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sock, SIOCSIWSCAN, &wrq); + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCSIWSCAN); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_scan_stat + * + * Description: + * Checks the status of the scan process. + * + * Returned Value: + * Zero, if data is ready; 1, if data is not ready; negative on failure. + * + ****************************************************************************/ + +int wapi_scan_stat(int sock, FAR const char *ifname) +{ + struct iwreq wrq; + int ret; + char buf; + + wrq.u.data.pointer = &buf; + wrq.u.data.flags = 0; + wrq.u.data.length = 0; + + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWSCAN, &wrq)) < 0) + { + if (errno == E2BIG) + { + /* Data is ready, but not enough space, which is expected. */ + + return 0; + } + else if (errno == EAGAIN) + { + /* Data is not ready. */ + + return 1; + } + + printf("err[%d]: %s\n", errno, strerror(errno)); + } + else + { + WAPI_IOCTL_STRERROR(SIOCGIWSCAN); + } + + return ret; +} + +/**************************************************************************** + * Name: wapi_scan_coll + * + * Description: + * Collects the results of a scan process. + * + * Input Parameters: + * aps - Pushes collected wapi_scan_info_t into this list. + * + ****************************************************************************/ + +int wapi_scan_coll(int sock, FAR const char *ifname, FAR wapi_list_t *aps) +{ + FAR char *buf; + int buflen; + struct iwreq wrq; + int we_version; + int ret; + + WAPI_VALIDATE_PTR(aps); + + /* Get WE version. (Required for event extraction via libiw.) */ + + if ((ret = wapi_get_we_version(sock, ifname, &we_version)) < 0) + { + return ret; + } + + buflen = IW_SCAN_MAX_DATA; + buf = malloc(buflen * sizeof(char)); + if (!buf) + { + WAPI_STRERROR("malloc()"); + return -1; + } + +alloc: + /* Collect results. */ + + wrq.u.data.pointer = buf; + wrq.u.data.length = buflen; + wrq.u.data.flags = 0; + strncpy(wrq.ifr_name, ifname, IFNAMSIZ); + if ((ret = ioctl(sock, SIOCGIWSCAN, &wrq)) < 0 && errno == E2BIG) + { + char *tmp; + + buflen *= 2; + tmp = realloc(buf, buflen); + if (!tmp) + { + WAPI_STRERROR("realloc()"); + free(buf); + return -1; + } + + buf = tmp; + goto alloc; + } + + /* There is still something wrong. It's either EAGAIN or some other ioctl() + * failure. We don't bother, let the user deal with it. + */ + + if (ret < 0) + { + WAPI_IOCTL_STRERROR(SIOCGIWSCAN); + free(buf); + return ret; + } + + /* We have the results, process them. */ + + if (wrq.u.data.length) + { + struct iw_event iwe; + struct iw_event_stream_s stream; + + iw_event_stream_init(&stream, buf, wrq.u.data.length); + do + { + if ((ret = iw_event_stream_pop(&stream, &iwe, we_version)) >= 0) + { + int eventret = wapi_scan_event(&iwe, aps); + if (eventret < 0) + { + ret = eventret; + } + } + else + { + WAPI_ERROR("iw_event_stream_pop() failed!\n"); + } + } + while (ret > 0); + } + + /* Free request buffer. */ + + free(buf); + return ret; +} + +/**************************************************************************** + * Name: wapi_if_add + * + * Description: + * Creates a virtual interface with name for interface ifname. + * + ****************************************************************************/ + +int wapi_if_add(int sock, FAR const char *ifname, FAR const char *name, + wapi_mode_t mode) +{ + wapi_nl80211_ctx_t ctx; + + ctx.ifname = ifname; + ctx.cmd = WAPI_NL80211_CMD_IFADD; + ctx.u.ifadd.name = name; + ctx.u.ifadd.mode = mode; + + return nl80211_cmd_handler(&ctx); +} + +/**************************************************************************** + * Name: wapi_if_del + * + * Description: + * Deletes a virtual interface with name. + * + ****************************************************************************/ + +int wapi_if_del(int sock, FAR const char *ifname) +{ + wapi_nl80211_ctx_t ctx; + + ctx.ifname = ifname; + ctx.cmd = WAPI_NL80211_CMD_IFDEL; + + return nl80211_cmd_handler(&ctx); +} From 806d2c731a017ba3fe1b3e418e9c491ad370d328 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 14:00:21 -0600 Subject: [PATCH 13/23] wireless/wapi: Remove logic that depnds on Linux netlink. Add (untested) build support. --- include/wireless/wapi.h | 21 -- wireless/wapi/Kconfig | 44 +++ wireless/wapi/Make.defs | 40 ++ wireless/wapi/Makefile | 149 ++++++++ wireless/wapi/examples/ifadd.c | 118 ------ wireless/wapi/examples/ifdel.c | 62 ---- wireless/wapi/examples/sample-get.c | 35 -- wireless/wapi/examples/sample-set.c | 36 -- wireless/wapi/src/Make.defs | 49 +++ .../wapi/{examples/sample.c => src/wapi.c} | 20 +- wireless/wapi/src/wireless.c | 349 +----------------- 11 files changed, 293 insertions(+), 630 deletions(-) create mode 100644 wireless/wapi/Kconfig create mode 100644 wireless/wapi/Make.defs create mode 100644 wireless/wapi/Makefile delete mode 100644 wireless/wapi/examples/ifadd.c delete mode 100644 wireless/wapi/examples/ifdel.c delete mode 100644 wireless/wapi/examples/sample-get.c delete mode 100644 wireless/wapi/examples/sample-set.c create mode 100644 wireless/wapi/src/Make.defs rename wireless/wapi/{examples/sample.c => src/wapi.c} (95%) diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h index c808f1883..80eb4553c 100644 --- a/include/wireless/wapi.h +++ b/include/wireless/wapi.h @@ -555,27 +555,6 @@ int wapi_get_txpower(int sock, FAR const char *ifname, FAR int *power, int wapi_set_txpower(int sock, FAR const char *ifname, int power, wapi_txpower_flag_t flag); -/**************************************************************************** - * Name: wapi_if_add - * - * Description: - * Creates a virtual interface with name for interface ifname. - * - ****************************************************************************/ - -int wapi_if_add(int sock, FAR const char *ifname, FAR const char *name, - wapi_mode_t mode); - -/**************************************************************************** - * Name: wapi_if_del - * - * Description: - * Deletes a virtual interface with name. - * - ****************************************************************************/ - -int wapi_if_del(int sock, FAR const char *ifname); - /**************************************************************************** * Name: wapi_make_socket * diff --git a/wireless/wapi/Kconfig b/wireless/wapi/Kconfig new file mode 100644 index 000000000..f493bd74d --- /dev/null +++ b/wireless/wapi/Kconfig @@ -0,0 +1,44 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig WIRELESS_WAPI + bool "Temperature" + default n + depends on EXPERIMENTAL + ---help--- + Wapi is a tool by Volkan YAZICI that can + be used to manage 802.11 network. + +if WIRELESS_WAPI + +config WIRELESS_WAPI_CMDTOOL + bool "Build command line tool" + default n + ---help--- + By default, Wapi is build as only a library. If this option is + selected than a simple command line tool that can be ran from NSH + will also be generated. + +config WIRELESS_WAPI_ENABLE_SET + bool "Enable setting options" + default n + +config WIRELESS_WAPI_PROGNAME + string "Program name" + default "wapi" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config WIRELESS_WAPI_STACKSIZE + int "Stack size (bytes)" + default 2048 + +config WIRELESS_WAPI_PRIORITY + int "Command priority" + default 100 + +endif diff --git a/wireless/wapi/Make.defs b/wireless/wapi/Make.defs new file mode 100644 index 000000000..f8cf01b20 --- /dev/null +++ b/wireless/wapi/Make.defs @@ -0,0 +1,40 @@ +############################################################################ +# apps/wireless/wapi/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_WIRELESS_WAPI),y) +CONFIGURED_APPS += wireless/wapi +endif + diff --git a/wireless/wapi/Makefile b/wireless/wapi/Makefile new file mode 100644 index 000000000..ec335af09 --- /dev/null +++ b/wireless/wapi/Makefile @@ -0,0 +1,149 @@ +############################################################################ +# apps/wireless/wapi/Makefile +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# TODO, this makefile should run make under the app dirs, instead of +# sourcing the Make.defs! + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# LM-75 Temperature Sensor Application + +CONFIG_WIRELESS_WAPI_PRIORITY ?= 100 +CONFIG_WIRELESS_WAPI_STACKSIZE ?= 2048 + +APPNAME = temp +PRIORITY = $(CONFIG_WIRELESS_WAPI_PRIORITY) +STACKSIZE = $(CONFIG_WIRELESS_WAPI_STACKSIZE) + +ASRCS = +CSRCS = +MAINSRC = + +include $(APPDIR)/wireless/wapi/src/Make.defs + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) +OBJS = $(AOBJS) $(COBJS) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +CONFIG_WAPI_PROGNAME ?= lm75$(EXEEXT) +PROGNAME = $(CONFIG_WAPI_PROGNAME) + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: context depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + $(Q) touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +# Register application + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),lm75_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +# Create dependencies + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep +.PHONY: preconfig +preconfig: diff --git a/wireless/wapi/examples/ifadd.c b/wireless/wapi/examples/ifadd.c deleted file mode 100644 index 2885949ba..000000000 --- a/wireless/wapi/examples/ifadd.c +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** - * apps/wireless/wapi/examples/ifadd.c - * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include - -#include "include/wireless/wapi.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int parse_wapi_mode(FAR const char *s, FAR wapi_mode_t * mode) -{ - int ret = 0; - - if (!strcmp(s, "auto")) - { - *mode = WAPI_MODE_AUTO; - else if (!strcmp(s, "adhoc")) - { - *mode = WAPI_MODE_ADHOC; - } - else if (!strcmp(s, "managed")) - { - *mode = WAPI_MODE_MANAGED; - } - else if (!strcmp(s, "master")) - { - *mode = WAPI_MODE_MASTER; - } - else if (!strcmp(s, "repeat")) - { - *mode = WAPI_MODE_REPEAT; - } - else if (!strcmp(s, "second")) - { - *mode = WAPI_MODE_SECOND; - } - else if (!strcmp(s, "monitor")) - { - *mode = WAPI_MODE_MONITOR; - } - else - { - ret = 1; - } - - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#ifdef CONFIG_BUILD_KERNEL -int main(int argc, FAR char *argv[]) -#else -int ifadd_main(int argc, char *argv[]) -#endif -{ - wapi_mode_t mode; - FAR const char *ifname; - FAR const char *name; - int ret; - - if (argc != 4) - { - fprintf(stderr, "Usage: %s \n", argv[0]); - return EXIT_FAILURE; - } - - ifname = argv[1]; - name = argv[2]; - - if (parse_wapi_mode(argv[3], &mode)) - { - fprintf(stderr, "Unknown mode: %s!\n", argv[3]); - return EXIT_FAILURE; - } - - ret = wapi_if_add(-1, ifname, name, mode); - fprintf(stderr, "wapi_if_add(): ret: %d\n", ret); - - return ret; -} diff --git a/wireless/wapi/examples/ifdel.c b/wireless/wapi/examples/ifdel.c deleted file mode 100644 index bc32eb9e0..000000000 --- a/wireless/wapi/examples/ifdel.c +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** - * apps/wireless/wapi/examples/ifdel.c - * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -#include "include/wireless/wapi.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#ifdef CONFIG_BUILD_KERNEL -int main(int argc, FAR char *argv[]) -#else -int ifdel_main(int argc, char *argv[]) -#endif -{ - int ret; - - if (argc != 2) - { - fprintf(stderr, "Usage: %s \n", argv[0]); - return EXIT_FAILURE; - } - - ret = wapi_if_del(-1, argv[1]); - fprintf(stderr, "wapi_if_del(): ret: %d\n", ret); - - return ret; -} diff --git a/wireless/wapi/examples/sample-get.c b/wireless/wapi/examples/sample-get.c deleted file mode 100644 index 7508d551e..000000000 --- a/wireless/wapi/examples/sample-get.c +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************** - * apps/wireless/wapi/examples/sample.c - * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include "sample.c" diff --git a/wireless/wapi/examples/sample-set.c b/wireless/wapi/examples/sample-set.c deleted file mode 100644 index f7c6bb600..000000000 --- a/wireless/wapi/examples/sample-set.c +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** - * apps/wireless/wapi/examples/sample.c - * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#define ENABLE_SET -#include "sample.c" diff --git a/wireless/wapi/src/Make.defs b/wireless/wapi/src/Make.defs new file mode 100644 index 000000000..726ac06c9 --- /dev/null +++ b/wireless/wapi/src/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# apps/wireless/src/Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_WIRELESS_WAPI),y) + +CSRCS = network.c util.c wireless.c + +ifeq ($(CONFIG_WIRELESS_WAPI_CMDTOOL),y) +MAINSRC = wapi.c +endif + +DEPPATH += --dep-path src +VPATH += :src +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/wirelss/wapi/src} + +endif + diff --git a/wireless/wapi/examples/sample.c b/wireless/wapi/src/wapi.c similarity index 95% rename from wireless/wapi/examples/sample.c rename to wireless/wapi/src/wapi.c index 04b288e6b..0a029e2ee 100644 --- a/wireless/wapi/examples/sample.c +++ b/wireless/wapi/src/wapi.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/wireless/wapi/examples/sample.c + * apps/wireless/wapi/src/wapi.c * * Copyright (c) 2010, Volkan YAZICI * All rights reserved. @@ -73,8 +73,8 @@ static void conf(int sock, FAR const char *ifname) { printf(", ip: %s", inet_ntoa(addr)); -#ifdef ENABLE_SET - /* set ip (Make sure sin.sin_family is set to AF_INET.) */ +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET + /* Set ip (Make sure sin.sin_family is set to AF_INET.) */ ret = wapi_set_ip(sock, ifname, &addr); printf("\nwapi_set_ip(): ret: %d", ret); @@ -92,7 +92,7 @@ static void conf(int sock, FAR const char *ifname) { printf(", netmask: %s", inet_ntoa(addr)); -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* set netmask (Make sure sin.sin_family is set to AF_INET.) */ ret = wapi_set_netmask(sock, ifname, &addr); @@ -127,7 +127,7 @@ static void conf(int sock, FAR const char *ifname) printf(", freq: %g", tmpfreq); } -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* Set freq */ ret = wapi_set_freq(sock, ifname, freq, freq_flag); @@ -146,7 +146,7 @@ static void conf(int sock, FAR const char *ifname) printf(", essid: %s, essid_flag: %s", essid, g_wapi_essid_flags[essid_flag]); -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* Set essid */ ret = wapi_set_essid(sock, ifname, essid, essid_flag); @@ -164,7 +164,7 @@ static void conf(int sock, FAR const char *ifname) { printf(", mode: %s", g_wapi_modes[mode]); -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* Set operating mode */ ret = wapi_set_mode(sock, ifname, mode); @@ -185,7 +185,7 @@ static void conf(int sock, FAR const char *ifname) ap.ether_addr_octet[2], ap.ether_addr_octet[3], ap.ether_addr_octet[4], ap.ether_addr_octet[5]); -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* Set ap */ ret = wapi_set_ap(sock, ifname, &ap); @@ -204,7 +204,7 @@ static void conf(int sock, FAR const char *ifname) printf(", bitrate: %d, bitrate_flag: %s", bitrate, g_wapi_bitrate_flags[bitrate_flag]); -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* Set bitrate */ ret = wapi_set_bitrate(sock, ifname, bitrate, bitrate_flag); @@ -223,7 +223,7 @@ static void conf(int sock, FAR const char *ifname) printf(", txpower: %d, txpower_flag: %s", txpower, g_wapi_txpower_flags[txpower_flag]); -#ifdef ENABLE_SET +#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET /* Set txpower */ ret = wapi_set_txpower(sock, ifname, txpower, txpower_flag); diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c index d2a137c67..194d1b29a 100644 --- a/wireless/wapi/src/wireless.c +++ b/wireless/wapi/src/wireless.c @@ -36,14 +36,7 @@ #include #include -#include -#include -#include -#include -#include -#include - -#include +#include #include "include/wireless/wapi.h" #include "util.h" @@ -119,35 +112,6 @@ FAR const char *g_wapi_txpower_flags[] = "WAPI_TXPOWER_RELATIVE" }; -/* Add/Delete */ - -typedef enum -{ - WAPI_NL80211_CMD_IFADD, - WAPI_NL80211_CMD_IFDEL -} wapi_nl80211_cmd_t; - -typedef struct wapi_nl80211_ifadd_ctx_t -{ - FAR const char *name; - wapi_mode_t mode; -} wapi_nl80211_ifadd_ctx_t; - -typedef struct wapi_nl80211_ifdel_ctx_t -{ -} wapi_nl80211_ifdel_ctx_t; - -typedef struct wapi_nl80211_ctx_t -{ - FAR const char *ifname; - wapi_nl80211_cmd_t cmd; - union - { - wapi_nl80211_ifadd_ctx_t ifadd; - wapi_nl80211_ifdel_ctx_t ifdel; - } u; -} wapi_nl80211_ctx_t; - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -351,278 +315,6 @@ static int wapi_scan_event(FAR struct iw_event *event, FAR wapi_list_t *list) return 0; } -/**************************************************************************** - * Name: nl_socket_alloc - * - * Description: - * - ****************************************************************************/ - -#ifdef LIBNL1 -static FAR struct nl_handle *nl_socket_alloc(void) -{ - return nl_handle_alloc(); -} -#endif /* LIBNL1 */ - -/**************************************************************************** - * Name: nl_socket_free - * - * Description: - * - ****************************************************************************/ - -#ifdef LIBNL1 -static void nl_socket_free(FAR struct nl_sock *h) -{ - nl_handle_destroy(h); -} -#endif /* LIBNL1 */ - -/**************************************************************************** - * Name: wapi_mode_to_iftype - * - * Description: - * - ****************************************************************************/ - -static int wapi_mode_to_iftype(wapi_mode_t mode, FAR enum nl80211_iftype *type) -{ - int ret = 0; - - switch (mode) - { - case WAPI_MODE_AUTO: - *type = NL80211_IFTYPE_UNSPECIFIED; - break; - - case WAPI_MODE_ADHOC: - *type = NL80211_IFTYPE_ADHOC; - break; - - case WAPI_MODE_MANAGED: - *type = NL80211_IFTYPE_STATION; - break; - - case WAPI_MODE_MASTER: - *type = NL80211_IFTYPE_AP; - break; - - case WAPI_MODE_MONITOR: - *type = NL80211_IFTYPE_MONITOR; - break; - - default: - WAPI_ERROR("No supported nl80211 iftype for mode: %s!\n", - g_wapi_modes[mode]); - ret = -1; - } - - return ret; -} - -/**************************************************************************** - * Name: nl80211_err_handler - * - * Description: - * - ****************************************************************************/ - -static int nl80211_err_handler(FAR struct sockaddr_nl *nla, - FAR struct nlmsgerr *err, FAR void *arg) -{ - int *ret = arg; - *ret = err->error; - return NL_STOP; -} - -/**************************************************************************** - * Name: nl80211_fin_handler - * - * Description: - * - ****************************************************************************/ - -static int nl80211_fin_handler(FAR struct nl_msg *msg, FAR void *arg) -{ - int *ret = arg; - *ret = 0; - return NL_SKIP; -} - -/**************************************************************************** - * Name: nl80211_ack_handler - * - * Description: - * - ****************************************************************************/ - -static int nl80211_ack_handler(FAR struct nl_msg *msg, FAR void *arg) -{ - int *ret = arg; - *ret = 0; - return NL_STOP; -} - -/**************************************************************************** - * Name: nl80211_cmd_handler - * - * Description: - * - ****************************************************************************/ - -static int nl80211_cmd_handler(FAR const wapi_nl80211_ctx_t *ctx) -{ - FAR struct nl_sock *sock; - FAR struct nl_msg *msg; - FAR struct nl_cb *cb; - int family; - int ifidx; - int ret; - - /* Allocate netlink socket. */ - - sock = nl_socket_alloc(); - if (!sock) - { - WAPI_ERROR("Failed to allocate netlink socket!\n"); - return -ENOMEM; - } - - /* Reset "msg" and "cb". */ - - msg = NULL; - cb = NULL; - - /* Connect to generic netlink socket on kernel side. */ - - if (genl_connect(sock)) - { - WAPI_ERROR("Failed to connect to generic netlink!\n"); - ret = -ENOLINK; - goto exit; - } - - /* Ask kernel to resolve family name to family id. */ - - ret = family = genl_ctrl_resolve(sock, "nl80211"); - if (ret < 0) - { - WAPI_ERROR("genl_ctrl_resolve() failed!\n"); - goto exit; - } - - /* Map given network interface name (ifname) to its corresponding index. */ - - ifidx = if_nametoindex(ctx->ifname); - if (!ifidx) - { - WAPI_STRERROR("if_nametoindex(\"%s\")", ctx->ifname); - ret = -errno; - goto exit; - } - - /* Construct a generic netlink by allocating a new message. */ - - msg = nlmsg_alloc(); - if (!msg) - { - WAPI_ERROR("nlmsg_alloc() failed!\n"); - ret = -ENOMEM; - goto exit; - } - - /* Append the requested command to the message. */ - - switch (ctx->cmd) - { - case WAPI_NL80211_CMD_IFADD: - { - enum nl80211_iftype iftype; - - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, 0, - NL80211_CMD_NEW_INTERFACE, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx); - - /* Get NL80211_IFTYPE_* for the given WAPI mode. */ - - ret = wapi_mode_to_iftype(ctx->u.ifadd.mode, &iftype); - if (ret < 0) - { - goto exit; - } - - NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ctx->u.ifadd.name); - NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype); - break; - } - - case WAPI_NL80211_CMD_IFDEL: - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, 0, - NL80211_CMD_DEL_INTERFACE, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx); - break; - } - - /* Finalize (send) the message. */ - - ret = nl_send_auto_complete(sock, msg); - if (ret < 0) - { - WAPI_ERROR("nl_send_auto_complete() failed!\n"); - goto exit; - } - - /* Allocate a new callback handle. */ - - cb = nl_cb_alloc(NL_CB_VERBOSE); - if (!cb) - { - WAPI_ERROR("nl_cb_alloc() failed\n"); - ret = -1; - goto exit; - } - - /* Configure callback handlers. */ - - nl_cb_err(cb, NL_CB_CUSTOM, nl80211_err_handler, &ret); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_fin_handler, &ret); - nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_ack_handler, &ret); - - /* Consume netlink replies. */ - - for (ret = 1; ret > 0;) - { - nl_recvmsgs(sock, cb); - } - - if (ret) - { - WAPI_ERROR("nl_recvmsgs() failed!\n"); - } - -exit: - /* Release resources and exit with "ret". */ - - nl_socket_free(sock); - if (msg) - { - nlmsg_free(msg); - } - - if (cb) - { - free(cb); - } - - return ret; - -nla_put_failure: - WAPI_ERROR("nla_put_failure!\n"); - ret = -1; - goto exit; -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1457,42 +1149,3 @@ alloc: free(buf); return ret; } - -/**************************************************************************** - * Name: wapi_if_add - * - * Description: - * Creates a virtual interface with name for interface ifname. - * - ****************************************************************************/ - -int wapi_if_add(int sock, FAR const char *ifname, FAR const char *name, - wapi_mode_t mode) -{ - wapi_nl80211_ctx_t ctx; - - ctx.ifname = ifname; - ctx.cmd = WAPI_NL80211_CMD_IFADD; - ctx.u.ifadd.name = name; - ctx.u.ifadd.mode = mode; - - return nl80211_cmd_handler(&ctx); -} - -/**************************************************************************** - * Name: wapi_if_del - * - * Description: - * Deletes a virtual interface with name. - * - ****************************************************************************/ - -int wapi_if_del(int sock, FAR const char *ifname) -{ - wapi_nl80211_ctx_t ctx; - - ctx.ifname = ifname; - ctx.cmd = WAPI_NL80211_CMD_IFDEL; - - return nl80211_cmd_handler(&ctx); -} From aeb37c12b2f7825542d0e21d16ec822ff8d6cbad Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 14:57:33 -0600 Subject: [PATCH 14/23] apps/wireless/wapi: Fix problems in build support. Fix some initial compile isses (still does not compile). --- include/wireless/wapi.h | 10 ++++++--- wireless/.gitignore | 2 ++ wireless/Make.defs | 37 ++++++++++++++++++++++++++++++++++ wireless/Makefile | 38 +++++++++++++++++++++++++++++++++++ wireless/wapi/Kconfig | 14 ++++++------- wireless/wapi/Makefile | 4 ++-- wireless/wapi/src/Make.defs | 2 +- wireless/wapi/src/network.c | 39 ++++++++++++++++++++++-------------- wireless/wapi/src/util.c | 2 +- wireless/wapi/src/wapi.c | 2 +- wireless/wapi/src/wireless.c | 39 ++++++++++++++++++------------------ 11 files changed, 140 insertions(+), 49 deletions(-) create mode 100644 wireless/.gitignore create mode 100644 wireless/Make.defs create mode 100644 wireless/Makefile diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h index 80eb4553c..d97bb58fc 100644 --- a/include/wireless/wapi.h +++ b/include/wireless/wapi.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions @@ -72,7 +72,7 @@ typedef struct wapi_list_t wapi_list_t; typedef enum { - WAPI_FREQ_AUTO = IW_FREQ_AUTO, + WAPI_FREQ_AUTO = IW_FREQ_AUTO, WAPI_FREQ_FIXED = IW_FREQ_FIXED } wapi_freq_flag_t; @@ -314,10 +314,12 @@ int wapi_get_routes(wapi_list_t * list); * ****************************************************************************/ +#ifdef CONFIG_NET_ROUTE int wapi_add_route_gw(int sock, wapi_route_target_t targettype, FAR const struct in_addr *target, FAR const struct in_addr *netmask, FAR const struct in_addr *gw); +#endif /**************************************************************************** * Name: wapi_del_route_gw @@ -327,10 +329,12 @@ int wapi_add_route_gw(int sock, wapi_route_target_t targettype, * ****************************************************************************/ +#ifdef CONFIG_NET_ROUTE int wapi_del_route_gw(int sock, wapi_route_target_t targettype, FAR const struct in_addr *target, FAR const struct in_addr *netmask, FAR const struct in_addr *gw); +#endif /**************************************************************************** * Name: wapi_get_we_version @@ -367,7 +371,7 @@ int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, * ****************************************************************************/ -int wapi_set_freq(int sock, FARconst char *ifname, double freq, +int wapi_set_freq(int sock, FAR const char *ifname, double freq, wapi_freq_flag_t flag); /**************************************************************************** diff --git a/wireless/.gitignore b/wireless/.gitignore new file mode 100644 index 000000000..99f41601f --- /dev/null +++ b/wireless/.gitignore @@ -0,0 +1,2 @@ +/Kconfig + diff --git a/wireless/Make.defs b/wireless/Make.defs new file mode 100644 index 000000000..6f5bcf9f7 --- /dev/null +++ b/wireless/Make.defs @@ -0,0 +1,37 @@ +############################################################################ +# apps/wireless/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +include $(wildcard wireless/*/Make.defs) diff --git a/wireless/Makefile b/wireless/Makefile new file mode 100644 index 000000000..363f15cd6 --- /dev/null +++ b/wireless/Makefile @@ -0,0 +1,38 @@ +############################################################################ +# apps/wireless/Makefile +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +MENUDESC = "Wireless Libraries and NSH Add-Ons" + +include $(APPDIR)/Directory.mk diff --git a/wireless/wapi/Kconfig b/wireless/wapi/Kconfig index f493bd74d..4e8b7edcc 100644 --- a/wireless/wapi/Kconfig +++ b/wireless/wapi/Kconfig @@ -4,9 +4,9 @@ # menuconfig WIRELESS_WAPI - bool "Temperature" + bool "IEEE802.11 Configuration Library" default n - depends on EXPERIMENTAL + depends on NET && DRIVERS_WIRELESS && EXPERIMENTAL ---help--- Wapi is a tool by Volkan YAZICI that can be used to manage 802.11 network. @@ -14,7 +14,7 @@ menuconfig WIRELESS_WAPI if WIRELESS_WAPI config WIRELESS_WAPI_CMDTOOL - bool "Build command line tool" + bool "IEEE802.11 Command Line Tool" default n ---help--- By default, Wapi is build as only a library. If this option is @@ -22,11 +22,11 @@ config WIRELESS_WAPI_CMDTOOL will also be generated. config WIRELESS_WAPI_ENABLE_SET - bool "Enable setting options" + bool "Enable Setting Options" default n config WIRELESS_WAPI_PROGNAME - string "Program name" + string "Program Name" default "wapi" depends on BUILD_KERNEL ---help--- @@ -34,11 +34,11 @@ config WIRELESS_WAPI_PROGNAME program is installed. config WIRELESS_WAPI_STACKSIZE - int "Stack size (bytes)" + int "Stack Size (bytes)" default 2048 config WIRELESS_WAPI_PRIORITY - int "Command priority" + int "Command Priority" default 100 endif diff --git a/wireless/wapi/Makefile b/wireless/wapi/Makefile index ec335af09..02297248f 100644 --- a/wireless/wapi/Makefile +++ b/wireless/wapi/Makefile @@ -53,6 +53,8 @@ ASRCS = CSRCS = MAINSRC = +VPATH = . + include $(APPDIR)/wireless/wapi/src/Make.defs AOBJS = $(ASRCS:.S=$(OBJEXT)) @@ -89,8 +91,6 @@ ROOTDEPPATH = --dep-path . # Common build -VPATH = - all: .built .PHONY: context depend clean distclean diff --git a/wireless/wapi/src/Make.defs b/wireless/wapi/src/Make.defs index 726ac06c9..95100bb1c 100644 --- a/wireless/wapi/src/Make.defs +++ b/wireless/wapi/src/Make.defs @@ -43,7 +43,7 @@ endif DEPPATH += --dep-path src VPATH += :src -CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/wirelss/wapi/src} +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/wireless/wapi/src} endif diff --git a/wireless/wapi/src/network.c b/wireless/wapi/src/network.c index 893bf434d..170510ade 100644 --- a/wireless/wapi/src/network.c +++ b/wireless/wapi/src/network.c @@ -32,16 +32,19 @@ * Included Files ****************************************************************************/ -#include -#include -#include -#include #include #include #include +#include +#include +#include + +#include +#include + #include "util.h" -#include "include/wireless/wapi.h" +#include "wireless/wapi.h" /**************************************************************************** * Private Functions @@ -56,7 +59,7 @@ static int wapi_get_addr(int sock, FAR const char *ifname, int cmd, WAPI_VALIDATE_PTR(addr); strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, cmd, &ifr)) >= 0) + if ((ret = ioctl(sock, cmd, (unsigned long)((uintptr_t)&ifr))) >= 0) { struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; memcpy(addr, &sin->sin_addr, sizeof(struct in_addr)); @@ -82,7 +85,7 @@ static int wapi_set_addr(int sock, FAR const char *ifname, int cmd, memcpy(&sin.sin_addr, addr, sizeof(struct in_addr)); memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in)); strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, cmd, &ifr)) < 0) + if ((ret = ioctl(sock, cmd, (unsigned long)((uintptr_t)&ifr))) < 0) { WAPI_IOCTL_STRERROR(cmd); } @@ -90,6 +93,7 @@ static int wapi_set_addr(int sock, FAR const char *ifname, int cmd, return ret; } +#ifdef CONFIG_NET_ROUTE static int wapi_act_route_gw(int sock, int act, wapi_route_target_t targettype, FAR const struct in_addr *target, @@ -130,13 +134,14 @@ static int wapi_act_route_gw(int sock, int act, rt.rt_flags |= RTF_HOST; } - if ((ret = ioctl(sock, act, &rt)) < 0) + if ((ret = ioctl(sock, act, (unsigned long)((uintptr_t)&rt))) < 0) { WAPI_IOCTL_STRERROR(act); } return ret; } +#endif /**************************************************************************** * Public Functions @@ -161,7 +166,7 @@ int wapi_get_ifup(int sock, FAR const char *ifname, FAR int *is_up) WAPI_VALIDATE_PTR(is_up); strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIFFLAGS, &ifr)) >= 0) + if ((ret = ioctl(sock, SIOCGIFFLAGS, (unsigned long)((uintptr_t)&ifr))) >= 0) { *is_up = (ifr.ifr_flags & IFF_UP) == IFF_UP; } @@ -187,10 +192,10 @@ int wapi_set_ifup(int sock, FAR const char *ifname) int ret; strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIFFLAGS, &ifr)) >= 0) + if ((ret = ioctl(sock, SIOCGIFFLAGS, (unsigned long)((uintptr_t)&ifr))) >= 0) { ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - ret = ioctl(sock, SIOCSIFFLAGS, &ifr); + ret = ioctl(sock, SIOCSIFFLAGS, (unsigned long)((uintptr_t)&ifr)); } else { @@ -214,10 +219,10 @@ int wapi_set_ifdown(int sock, FAR const char *ifname) int ret; strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIFFLAGS, &ifr)) >= 0) + if ((ret = ioctl(sock, SIOCGIFFLAGS, (unsigned long)((uintptr_t)&ifr))) >= 0) { ifr.ifr_flags &= ~IFF_UP; - ret = ioctl(sock, SIOCSIFFLAGS, &ifr); + ret = ioctl(sock, SIOCSIFFLAGS, (unsigned long)((uintptr_t)&ifr)); } else { @@ -296,9 +301,9 @@ int wapi_set_netmask(int sock, FAR const char *ifname, int wapi_get_routes(FAR wapi_list_t *list) { FAR FILE *fp; - int ret; size_t bufsiz = WAPI_PROC_LINE_SIZE * sizeof(char); char buf[WAPI_PROC_LINE_SIZE]; + int ret; WAPI_VALIDATE_PTR(list); @@ -389,7 +394,7 @@ int wapi_get_routes(FAR wapi_list_t *list) /* Close file. */ fclose(fp); - return 0; + return ret; } /**************************************************************************** @@ -400,6 +405,7 @@ int wapi_get_routes(FAR wapi_list_t *list) * ****************************************************************************/ +#ifdef CONFIG_NET_ROUTE int wapi_add_route_gw(int sock, wapi_route_target_t targettype, FAR const struct in_addr *target, FAR const struct in_addr *netmask, @@ -407,6 +413,7 @@ int wapi_add_route_gw(int sock, wapi_route_target_t targettype, { return wapi_act_route_gw(sock, SIOCADDRT, targettype, target, netmask, gw); } +#endif /**************************************************************************** * Name: wapi_del_route_gw @@ -416,6 +423,7 @@ int wapi_add_route_gw(int sock, wapi_route_target_t targettype, * ****************************************************************************/ +#ifdef CONFIG_NET_ROUTE int wapi_del_route_gw(int sock, wapi_route_target_t targettype, FAR const struct in_addr *target, FAR const struct in_addr *netmask, @@ -423,3 +431,4 @@ int wapi_del_route_gw(int sock, wapi_route_target_t targettype, { return wapi_act_route_gw(sock, SIOCDELRT, targettype, target, netmask, gw); } +#endif diff --git a/wireless/wapi/src/util.c b/wireless/wapi/src/util.c index 4f8729721..8b9379e46 100644 --- a/wireless/wapi/src/util.c +++ b/wireless/wapi/src/util.c @@ -39,7 +39,7 @@ #include #include -#include "include/wireless/wapi.h" +#include "wireless/wapi.h" #include "util.h" /**************************************************************************** diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index 0a029e2ee..c7a13ee3f 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -40,7 +40,7 @@ #include #include -#include "include/wireless/wapi.h" +#include "wireless/wapi.h" /* Gets current configuration of the @a ifname using WAPI accessors and prints diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c index 194d1b29a..8ee1bdc83 100644 --- a/wireless/wapi/src/wireless.c +++ b/wireless/wapi/src/wireless.c @@ -38,7 +38,7 @@ #include -#include "include/wireless/wapi.h" +#include "wireless/wapi.h" #include "util.h" /**************************************************************************** @@ -351,7 +351,7 @@ int wapi_get_we_version(int sock, const char *ifname, FAR int *we_version) /* Get WE version. */ strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWRANGE, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWRANGE, (unsigned long)((uintptr_t)&wrq))) >= 0) { struct iw_range *range = (struct iw_range *)buf; *we_version = (int)range->we_version_compiled; @@ -382,7 +382,7 @@ int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, WAPI_VALIDATE_PTR(flag); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWFREQ, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWFREQ, (unsigned long)((uintptr_t)&wrq))) >= 0) { /* Set flag. */ @@ -440,7 +440,7 @@ int wapi_set_freq(int sock, FARconst char *ifname, double freq, } strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWFREQ, &wrq); + ret = ioctl(sock, SIOCSIWFREQ, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWFREQ); @@ -479,7 +479,7 @@ int wapi_freq2chan(int sock, FAR const char *ifname, double freq, /* Get range. */ strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWRANGE, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWRANGE, (unsigned long)((uintptr_t)&wrq))) >= 0) { struct iw_range *range = (struct iw_range *)buf; int k; @@ -539,7 +539,7 @@ int wapi_chan2freq(int sock, FAR const char *ifname, int chan, /* Get range. */ strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWRANGE, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWRANGE, (unsigned long)((uintptr_t)&wrq))) >= 0) { struct iw_range *range = (struct iw_range *)buf; int k; @@ -591,7 +591,7 @@ int wapi_get_essid(int sock, FAR const char *ifname, FAR char *essid, wrq.u.essid.flags = 0; strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCGIWESSID, &wrq); + ret = ioctl(sock, SIOCGIWESSID, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCGIWESSID); @@ -629,7 +629,7 @@ int wapi_set_essid(int sock, FAR const char *ifname, FAR const char *essid, wrq.u.essid.flags = (flag == WAPI_ESSID_ON); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWESSID, &wrq); + ret = ioctl(sock, SIOCSIWESSID, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWESSID); @@ -654,7 +654,7 @@ int wapi_get_mode(int sock, FAR const char *ifname, FAR wapi_mode_t *mode) WAPI_VALIDATE_PTR(mode); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWMODE, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWMODE, (unsigned long)((uintptr_t)&wrq))) >= 0) { ret = wapi_parse_mode(wrq.u.mode, mode); } @@ -682,7 +682,7 @@ int wapi_set_mode(int sock, FAR const char *ifname, wapi_mode_t mode) wrq.u.mode = mode; strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWMODE, &wrq); + ret = ioctl(sock, SIOCSIWMODE, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWMODE); @@ -737,7 +737,7 @@ int wapi_get_ap(int sock, FAR const char *ifname, FAR struct ether_addr *ap) WAPI_VALIDATE_PTR(ap); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWAP, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWAP, (unsigned long)((uintptr_t)&wrq))) >= 0) { memcpy(ap, wrq.u.ap_addr.sa_data, sizeof(struct ether_addr)); } @@ -769,7 +769,7 @@ int wapi_set_ap(int sock, FAR const char *ifname, memcpy(wrq.u.ap_addr.sa_data, ap, sizeof(struct ether_addr)); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWAP, &wrq); + ret = ioctl(sock, SIOCSIWAP, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWAP); @@ -796,7 +796,7 @@ int wapi_get_bitrate(int sock, FAR const char *ifname, WAPI_VALIDATE_PTR(flag); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWRATE, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWRATE, (unsigned long)((uintptr_t)&wrq))) >= 0) { /* Check if enabled. */ if (wrq.u.bitrate.disabled) @@ -834,7 +834,7 @@ int wapi_set_bitrate(int sock, FAR const char *ifname, int bitrate, wrq.u.bitrate.fixed = (flag == WAPI_BITRATE_FIXED); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWRATE, &wrq); + ret = ioctl(sock, SIOCSIWRATE, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWRATE); @@ -887,7 +887,7 @@ int wapi_get_txpower(int sock, FAR const char *ifname, FAR int *power, WAPI_VALIDATE_PTR(flag); strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWTXPOW, &wrq)) >= 0) + if ((ret = ioctl(sock, SIOCGIWTXPOW, (unsigned long)((uintptr_t)&wrq))) >= 0) { /* Check if enabled. */ @@ -963,7 +963,7 @@ int wapi_set_txpower(int sock, FAR const char *ifname, int power, /* Issue the set command. */ strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWTXPOW, &wrq); + ret = ioctl(sock, SIOCSIWTXPOW, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWTXPOW); @@ -991,7 +991,7 @@ int wapi_scan_init(int sock, const char *ifname) wrq.u.data.length = 0; strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - ret = ioctl(sock, SIOCSIWSCAN, &wrq); + ret = ioctl(sock, SIOCSIWSCAN, (unsigned long)((uintptr_t)&wrq)); if (ret < 0) { WAPI_IOCTL_STRERROR(SIOCSIWSCAN); @@ -1022,7 +1022,7 @@ int wapi_scan_stat(int sock, FAR const char *ifname) wrq.u.data.length = 0; strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWSCAN, &wrq)) < 0) + if ((ret = ioctl(sock, SIOCGIWSCAN, (unsigned long)((uintptr_t)&wrq))) < 0) { if (errno == E2BIG) { @@ -1090,7 +1090,8 @@ alloc: wrq.u.data.length = buflen; wrq.u.data.flags = 0; strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWSCAN, &wrq)) < 0 && errno == E2BIG) + if ((ret = ioctl(sock, SIOCGIWSCAN, (unsigned long)((uintptr_t)&wrq))) < 0 && + errno == E2BIG) { char *tmp; From 2d73f735fe87360aa4ac28083387adf03e390c2a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 15:34:56 -0600 Subject: [PATCH 15/23] Fix a little kruft left in ported wireless/wapi/Makefile --- wireless/wapi/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wireless/wapi/Makefile b/wireless/wapi/Makefile index 02297248f..03de538c9 100644 --- a/wireless/wapi/Makefile +++ b/wireless/wapi/Makefile @@ -40,12 +40,12 @@ -include $(TOPDIR)/Make.defs include $(APPDIR)/Make.defs -# LM-75 Temperature Sensor Application +# IEEE802.11 Wapi Application CONFIG_WIRELESS_WAPI_PRIORITY ?= 100 CONFIG_WIRELESS_WAPI_STACKSIZE ?= 2048 -APPNAME = temp +APPNAME = wapi PRIORITY = $(CONFIG_WIRELESS_WAPI_PRIORITY) STACKSIZE = $(CONFIG_WIRELESS_WAPI_STACKSIZE) @@ -84,7 +84,7 @@ else INSTALL_DIR = $(BIN_DIR) endif -CONFIG_WAPI_PROGNAME ?= lm75$(EXEEXT) +CONFIG_WAPI_PROGNAME ?= wapi$(EXEEXT) PROGNAME = $(CONFIG_WAPI_PROGNAME) ROOTDEPPATH = --dep-path . @@ -121,7 +121,7 @@ endif ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile - $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),lm75_main) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat else From 322ffe193b45fef0646b0d48a20d2d1bfd245d83 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 16:02:17 -0600 Subject: [PATCH 16/23] wireless/wapi: Remove functionality that depends on the Linux procfs: This includes only 1) listing of available interfaces and 2) listing of all routes. --- include/wireless/wapi.h | 43 +++---------- wireless/wapi/src/network.c | 119 +++-------------------------------- wireless/wapi/src/util.c | 91 +++------------------------ wireless/wapi/src/util.h | 9 ++- wireless/wapi/src/wapi.c | 74 +++------------------- wireless/wapi/src/wireless.c | 9 ++- 6 files changed, 43 insertions(+), 302 deletions(-) diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h index d97bb58fc..9bbc7d6f7 100644 --- a/include/wireless/wapi.h +++ b/include/wireless/wapi.h @@ -1,8 +1,13 @@ /**************************************************************************** * apps/include/wireless/wapi.h * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. + * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Adapted for Nuttx from WAPI: + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -48,14 +53,6 @@ #define WAPI_ESSID_MAX_SIZE IW_ESSID_MAX_SIZE -/* Path to /proc/net/wireless. (Requires procfs mounted.) */ - -#define WAPI_PROC_NET_WIRELESS "/proc/net/wireless" - -/* Path to /proc/net/route. (Requires procfs mounted.) */ - -#define WAPI_PROC_NET_ROUTE "/proc/net/route" - /* Buffer size while reading lines from PROC_NET_ files. */ #define WAPI_PROC_LINE_SIZE 1024 @@ -293,19 +290,6 @@ int wapi_get_netmask(int sock, const char *ifname, struct in_addr *addr); int wapi_set_netmask(int sock, const char *ifname, const struct in_addr *addr); -/**************************************************************************** - * Name: wapi_get_routes - * - * Description: - * Parses routing table rows from WAPI_PROC_NET_ROUTE. - * - * Input Parameters: - * list - Pushes collected wapi_route_info_t into this list. - * - ****************************************************************************/ - -int wapi_get_routes(wapi_list_t * list); - /**************************************************************************** * Name: wapi_add_route_gw * @@ -572,19 +556,6 @@ int wapi_set_txpower(int sock, FAR const char *ifname, int power, int wapi_make_socket(void); -/**************************************************************************** - * Name: wapi_get_ifnames - * - * Description: - * Parses WAPI_PROC_NET_WIRELESS. - * - * Returned Value: - * list Pushes collected wapi_string_t into this list. - * - ****************************************************************************/ - -int wapi_get_ifnames(FAR wapi_list_t *list); - /**************************************************************************** * Name: wapi_scan_init * diff --git a/wireless/wapi/src/network.c b/wireless/wapi/src/network.c index 170510ade..a2e2a1b9a 100644 --- a/wireless/wapi/src/network.c +++ b/wireless/wapi/src/network.c @@ -1,8 +1,13 @@ /**************************************************************************** * apps/wireless/wapi/examples/network.c * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. + * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Adapted for Nuttx from WAPI: + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -287,116 +292,6 @@ int wapi_set_netmask(int sock, FAR const char *ifname, return wapi_set_addr(sock, ifname, SIOCSIFNETMASK, addr); } -/**************************************************************************** - * Name: wapi_get_routes - * - * Description: - * Parses routing table rows from WAPI_PROC_NET_ROUTE. - * - * Input Parameters: - * list - Pushes collected wapi_route_info_t into this list. - * - ****************************************************************************/ - -int wapi_get_routes(FAR wapi_list_t *list) -{ - FAR FILE *fp; - size_t bufsiz = WAPI_PROC_LINE_SIZE * sizeof(char); - char buf[WAPI_PROC_LINE_SIZE]; - int ret; - - WAPI_VALIDATE_PTR(list); - - /* Open file for reading. */ - - fp = fopen(WAPI_PROC_NET_ROUTE, "r"); - if (!fp) - { - WAPI_STRERROR("fopen(\"%s\", \"r\")", WAPI_PROC_NET_ROUTE); - return -1; - } - - /* Skip header line. */ - - if (!fgets(buf, bufsiz, fp)) - { - WAPI_ERROR("Invalid \"%s\" content!\n", WAPI_PROC_NET_ROUTE); - return -1; - } - - /* Read lines. */ - - ret = 0; - while (fgets(buf, bufsiz, fp)) - { - wapi_route_info_t *ri; - char ifname[WAPI_PROC_LINE_SIZE]; - int refcnt, use, metric, mtu, window, irtt; - unsigned int dest, gw, flags, netmask; - - /* Allocate route row buffer. */ - - ri = malloc(sizeof(wapi_route_info_t)); - if (!ri) - { - WAPI_STRERROR("malloc()"); - ret = -1; - break; - } - - /* Read and tokenize fields. */ - - sscanf(buf, "%s\t" /* ifname */ - "%x\t" /* dest */ - "%x\t" /* gw */ - "%x\t" /* flags */ - "%d\t" /* refcnt */ - "%d\t" /* use */ - "%d\t" /* metric */ - "%x\t" /* mask */ - "%d\t" /* mtu */ - "%d\t" /* window */ - "%d\t", /* irtt */ - ifname, &dest, &gw, &flags, &refcnt, &use, &metric, &netmask, &mtu, - &window, &irtt); - - /* Allocate "ifname". */ - - ri->ifname = malloc((strlen(ifname) + 1) * sizeof(char)); - if (!ri->ifname) - { - WAPI_STRERROR("malloc()"); - free(ri); - ret = -1; - break; - } - - /* Copy fields. */ - - sprintf(ri->ifname, "%s", ifname); - ri->dest.s_addr = dest; - ri->gw.s_addr = gw; - ri->flags = flags; - ri->refcnt = refcnt; - ri->use = use; - ri->metric = metric; - ri->netmask.s_addr = netmask; - ri->mtu = mtu; - ri->window = window; - ri->irtt = irtt; - - /* Push parsed node to the list. */ - - ri->next = list->head.route; - list->head.route = ri; - } - - /* Close file. */ - - fclose(fp); - return ret; -} - /**************************************************************************** * Name: wapi_add_route_gw * diff --git a/wireless/wapi/src/util.c b/wireless/wapi/src/util.c index 8b9379e46..6e379c1e2 100644 --- a/wireless/wapi/src/util.c +++ b/wireless/wapi/src/util.c @@ -1,8 +1,13 @@ /**************************************************************************** * apps/wireless/wapi/src/util.c * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. + * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Adapted for Nuttx from WAPI: + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -76,87 +81,7 @@ int wapi_make_socket(void) } /**************************************************************************** - * Name: wapi_get_ifnames - * - * Description: - * Parses WAPI_PROC_NET_WIRELESS. - * - * Returned Value: - * list Pushes collected wapi_string_t into this list. - * - ****************************************************************************/ - -int wapi_get_ifnames(FAR wapi_list_t *list) -{ - FILE *fp; - int ret; - size_t tmpsize = WAPI_PROC_LINE_SIZE * sizeof(char); - char tmp[WAPI_PROC_LINE_SIZE]; - - WAPI_VALIDATE_PTR(list); - - /* Open file for reading. */ - - fp = fopen(WAPI_PROC_NET_WIRELESS, "r"); - if (!fp) - { - WAPI_STRERROR("fopen(\"%s\", \"r\")", WAPI_PROC_NET_WIRELESS); - return -1; - } - - /* Skip first two lines. */ - - if (!fgets(tmp, tmpsize, fp) || !fgets(tmp, tmpsize, fp)) - { - WAPI_ERROR("Invalid \"%s\" content!\n", WAPI_PROC_NET_WIRELESS); - return -1; - } - - /* Iterate over available lines. */ - - ret = 0; - while (fgets(tmp, tmpsize, fp)) - { - char *beg; - char *end; - wapi_string_t *string; - - /* Locate the interface name region. */ - - for (beg = tmp; *beg && isspace(*beg); beg++); - for (end = beg; *end && *end != ':'; end++); - - /* Allocate both wapi_string_t and char vector. */ - - string = malloc(sizeof(wapi_string_t)); - if (string) - { - string->data = malloc(end - beg + sizeof(char)); - } - - if (!string || !string->data) - { - WAPI_STRERROR("malloc()"); - ret = -1; - break; - } - - /* Copy region into the buffer. */ - - snprintf(string->data, (end - beg + sizeof(char)), "%s", beg); - - /* Push string into the list. */ - - string->next = list->head.string; - list->head.string = string; - } - - fclose(fp); - return ret; -} - -/**************************************************************************** - * Name: wapi_get_ifnames + * Name: wapi_ioctl_command_name * * Description: * Return name string for IOCTL command diff --git a/wireless/wapi/src/util.h b/wireless/wapi/src/util.h index 4982e3155..50de0b6eb 100644 --- a/wireless/wapi/src/util.h +++ b/wireless/wapi/src/util.h @@ -1,8 +1,13 @@ /**************************************************************************** * apps/wireless/wapi/src/util.h * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. + * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Adapted for Nuttx from WAPI: + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index c7a13ee3f..5b1aa6f70 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -1,8 +1,13 @@ /**************************************************************************** * apps/wireless/wapi/src/wapi.c * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. + * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Adapted for Nuttx from WAPI: + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -321,71 +326,6 @@ int wapi_main(int argc, char *argv[]) ifname = argv[1]; - /* Get ifnames */ - - bzero(&list, sizeof(wapi_list_t)); - ret = wapi_get_ifnames(&list); - printf("wapi_get_ifnames(): ret: %d", ret); - if (ret >= 0) - { - FAR wapi_string_t *str; - - /* Print ifnames */ - - printf(", ifnames:"); - for (str = list.head.string; str; str = str->next) - { - printf(" %s", str->data); - } - - /* Free ifnames */ - - str = list.head.string; - while (str) - { - FAR wapi_string_t *tmp; - - tmp = str->next; - free(str->data); - free(str); - str = tmp; - } - } - - putchar('\n'); - - /* Get routes */ - - bzero(&list, sizeof(wapi_list_t)); - ret = wapi_get_routes(&list); - printf("wapi_get_routes(): ret: %d\n", ret); - if (ret >= 0) - { - wapi_route_info_t *ri; - - /* Print route */ - - for (ri = list.head.route; ri; ri = ri->next) - { - printf(">> dest: %s, gw: %s, netmask: %s\n", - inet_ntoa(ri->dest), inet_ntoa(ri->gw), - inet_ntoa(ri->netmask)); - } - - /* Free routes */ - - ri = list.head.route; - while (ri) - { - FAR wapi_route_info_t *tmpri; - - tmpri = ri->next; - free(ri->ifname); - free(ri); - ri = tmpri; - } - } - /* Make a comm. sock. */ sock = wapi_make_socket(); diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c index 8ee1bdc83..a1bf9a666 100644 --- a/wireless/wapi/src/wireless.c +++ b/wireless/wapi/src/wireless.c @@ -1,8 +1,13 @@ /**************************************************************************** * apps/wireless/wapi/src/wireless.c * - * Copyright (c) 2010, Volkan YAZICI - * All rights reserved. + * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Adapted for Nuttx from WAPI: + * + * Copyright (c) 2010, Volkan YAZICI + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: From 2c53872a42a5fb762d81dcaeef57b5f07b527b4b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 16:14:49 -0600 Subject: [PATCH 17/23] wireless/wapi: Fix a few more compilation problems. --- wireless/wapi/src/wireless.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c index a1bf9a666..acd2eebd4 100644 --- a/wireless/wapi/src/wireless.c +++ b/wireless/wapi/src/wireless.c @@ -38,8 +38,9 @@ ****************************************************************************/ #include -#include #include +#include +#include #include @@ -378,7 +379,7 @@ int wapi_get_we_version(int sock, const char *ifname, FAR int *we_version) ****************************************************************************/ int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, - FAR wapi_freq_flag_t *flag); + FAR wapi_freq_flag_t *flag) { struct iwreq wrq; int ret; @@ -421,8 +422,8 @@ int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, * ****************************************************************************/ -int wapi_set_freq(int sock, FARconst char *ifname, double freq, - wapi_freq_flag_t flag); +int wapi_set_freq(int sock, FAR const char *ifname, double freq, + wapi_freq_flag_t flag) { struct iwreq wrq; int ret; @@ -804,6 +805,7 @@ int wapi_get_bitrate(int sock, FAR const char *ifname, if ((ret = ioctl(sock, SIOCGIWRATE, (unsigned long)((uintptr_t)&wrq))) >= 0) { /* Check if enabled. */ + if (wrq.u.bitrate.disabled) { WAPI_ERROR("Bitrate is disabled.\n"); @@ -811,12 +813,14 @@ int wapi_get_bitrate(int sock, FAR const char *ifname, } /* Get bitrate. */ + *bitrate = wrq.u.bitrate.value; *flag = wrq.u.bitrate.fixed ? WAPI_BITRATE_FIXED : WAPI_BITRATE_AUTO; } else { - WAPI_IOCTL_STRERROR(SIOCGIWRATE); + WAPI_IOCTL_STRERROR(SIOCGIWRATE); + } return ret; } @@ -942,7 +946,7 @@ int wapi_get_txpower(int sock, FAR const char *ifname, FAR int *power, ****************************************************************************/ int wapi_set_txpower(int sock, FAR const char *ifname, int power, - wapi_txpower_flag_t flag); + wapi_txpower_flag_t flag) { struct iwreq wrq; int ret; From dae395cb8e8d98c1d98e4351aa809b147b78d2b1 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 18:50:50 -0600 Subject: [PATCH 18/23] Beginning real design of wapi application based on Wapi sample code. --- wireless/wapi/src/wapi.c | 576 +++++++++++++++++++++++++++++---------- 1 file changed, 437 insertions(+), 139 deletions(-) diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index 5b1aa6f70..12239aff9 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -4,7 +4,8 @@ * Copyright (C) 2011, 2017Gregory Nutt. All rights reserved. * Author: Gregory Nutt * - * Adapted for Nuttx from WAPI: + * Largely and original work, but highly influenced by sampled code provided + * with WAPI: * * Copyright (c) 2010, Volkan YAZICI * All rights reserved. @@ -47,203 +48,395 @@ #include "wireless/wapi.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ -/* Gets current configuration of the @a ifname using WAPI accessors and prints - * them in a pretty fashion with their corresponding return values. If a getter - * succeeds, we try to set that property with the same value to test the setters - * as well. - */ +/**************************************************************************** + * Name: wapi_show_command + * + * Description: + * Gets current configuration of the ifname using WAPI accessors and prints + * them in a pretty fashion with their corresponding return values. If a + * getter succeeds, we try to set that property with the same value to test + * the setters as well. + * + * Returned Value: + * None + * + ****************************************************************************/ -static void conf(int sock, FAR const char *ifname) +static void wapi_show_command(int sock, FAR const char *ifname) { - int ret; struct in_addr addr; + double freq; wapi_freq_flag_t freq_flag; + char essid[WAPI_ESSID_MAX_SIZE + 1]; wapi_essid_flag_t essid_flag; + wapi_mode_t mode; + struct ether_addr ap; + int bitrate; wapi_bitrate_flag_t bitrate_flag; + int txpower; wapi_txpower_flag_t txpower_flag; + int ret; + + printf("%s Configuration:\n", ifname); + /* Get ip */ bzero(&addr, sizeof(struct in_addr)); ret = wapi_get_ip(sock, ifname, &addr); - printf("wapi_get_ip(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", ip: %s", inet_ntoa(addr)); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set ip (Make sure sin.sin_family is set to AF_INET.) */ - - ret = wapi_set_ip(sock, ifname, &addr); - printf("\nwapi_set_ip(): ret: %d", ret); -#endif + fprintf(stderr, "ERROR: wapi_get_ip() failed: %d", ret); + } + else + { + printf(" IP: %s\n", inet_ntoa(addr)); } - - putchar('\n'); /* Get netmask */ bzero(&addr, sizeof(struct in_addr)); ret = wapi_get_netmask(sock, ifname, &addr); - printf("wapi_get_netmask(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", netmask: %s", inet_ntoa(addr)); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* set netmask (Make sure sin.sin_family is set to AF_INET.) */ - - ret = wapi_set_netmask(sock, ifname, &addr); - printf("\nwapi_set_netmask(): ret: %d", ret); -#endif + fprintf(stderr, "ERROR: wapi_get_netmask() failed: %d", ret); + } + else + { + printf(" NetMask: %s", inet_ntoa(addr)); } - putchar('\n'); - - /* Get freq */ + /* Get frequency */ ret = wapi_get_freq(sock, ifname, &freq, &freq_flag); - printf("wapi_get_freq(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) + { + fprintf(stderr, "ERROR: wapi_get_freq() failed: %d", ret); + } + else { - int chan; double tmpfreq; + int chan; - printf(", freq: %g, freq_flag: %s", freq, g_wapi_freq_flags[freq_flag]); + printf("Frequency: %g\n", freq; + printf(" Flag: %s\n", g_wapi_freq_flags[freq_flag]); ret = wapi_freq2chan(sock, ifname, freq, &chan); - printf("\nwapi_freq2chan(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", chan: %d", chan); + fprintf(stderr, "ERROR: wapi_freq2chan() failed: %d", ret); + } + else + { + printf(" Channel: %d\n", chan); } ret = wapi_chan2freq(sock, ifname, chan, &tmpfreq); - printf("\nwapi_chan2freq(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", freq: %g", tmpfreq); + fprintf(stderr, "ERROR: wapi_chan2freq() failed: %d", ret); + } + else + { + printf("Frequency: %g\n", tmpfreq); } - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set freq */ - - ret = wapi_set_freq(sock, ifname, freq, freq_flag); - printf("\nwapi_set_freq(): ret: %d", ret); -#endif } - putchar('\n'); - - /* Get essid */ + /* Get the ESSID */ ret = wapi_get_essid(sock, ifname, essid, &essid_flag); - printf("wapi_get_essid(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", essid: %s, essid_flag: %s", - essid, g_wapi_essid_flags[essid_flag]); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set essid */ - - ret = wapi_set_essid(sock, ifname, essid, essid_flag); - printf("\nwapi_set_essid(): ret: %d", ret); -#endif + fprintf(stderr, "ERROR: wapi_get_essid() failed: %d", ret); + } + else + { + printf(" ESSID: %s\n", essid); + printf(" Flag: %s\n", g_wapi_essid_flags[essid_flag]); } - - putchar('\n'); /* Get operating mode */ ret = wapi_get_mode(sock, ifname, &mode); - printf("wapi_get_mode(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", mode: %s", g_wapi_modes[mode]); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set operating mode */ - - ret = wapi_set_mode(sock, ifname, mode); - printf("\nwapi_set_mode(): ret: %d", ret); -#endif + fprintf(stderr, "ERROR: wapi_get_mode() failed: %d", ret); + } + else + { + printf(" Mode: %s", g_wapi_modes[mode]); } - putchar('\n'); - - /* Get ap */ + /* Get AP */ ret = wapi_get_ap(sock, ifname, &ap); - printf("wapi_get_ap(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", ap: %02X:%02X:%02X:%02X:%02X:%02X", + fprintf(stderr, "ERROR: wapi_get_ap() failed: %d", ret); + } + else + { + printf(" AP: %02x:%02x:%02x:%02x:%02x:%02x", ap.ether_addr_octet[0], ap.ether_addr_octet[1], ap.ether_addr_octet[2], ap.ether_addr_octet[3], ap.ether_addr_octet[4], ap.ether_addr_octet[5]); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set ap */ - - ret = wapi_set_ap(sock, ifname, &ap); - printf("\nwapi_set_ap(): ret: %d", ret); -#endif } - putchar('\n'); - /* Get bitrate */ ret = wapi_get_bitrate(sock, ifname, &bitrate, &bitrate_flag); - printf("wapi_get_bitrate(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", bitrate: %d, bitrate_flag: %s", bitrate, - g_wapi_bitrate_flags[bitrate_flag]); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set bitrate */ - - ret = wapi_set_bitrate(sock, ifname, bitrate, bitrate_flag); - printf("\nwapi_set_bitrate(): ret: %d", ret); -#endif + fprintf(stderr, "ERROR: wapi_get_bitrate() failed: %d", ret); + } + else + { + printf(" BitRate: %d\n", bitrate); + printf(" Flag: %s\n", g_wapi_bitrate_flags[bitrate_flag]); } - - putchar('\n'); /* Get txpower */ ret = wapi_get_txpower(sock, ifname, &txpower, &txpower_flag); - printf("wapi_get_txpower(): ret: %d", ret); - if (ret >= 0) + if (ret < 0) { - printf(", txpower: %d, txpower_flag: %s", - txpower, g_wapi_txpower_flags[txpower_flag]); - -#ifdef CONFIG_WIRELESS_WAPI_ENABLE_SET - /* Set txpower */ - - ret = wapi_set_txpower(sock, ifname, txpower, txpower_flag); - printf("\nwapi_set_txpower(): ret: %d", ret); -#endif + fprintf(stderr, "ERROR: wapi_get_txpower() failed: %d", ret); + } + else + { + printf(" TxPower: %d\n", txpower); + printf(" Flag: %s\n", g_wapi_txpower_flags[txpower_flag]); } - - putchar('\n'); } -/* Scans available APs in the range using given @a ifname interface. (Requires - * root privileges to start a scan.) - */ +/**************************************************************************** + * Name: wapi_setip_cmd + * + * Description: + * Set the IP address. + * + * Returned Value: + * None + * + ****************************************************************************/ -static void scan(int sock, FAR const char *ifname) +static void wapi_setip_cmd(int sock, FAR const char *addrstr) +{ + struct in_addr addr; + int ret; + + /* Format the request */ +#warning Missing logic + + /* Set the IP address */ + + ret = wapi_set_ip(sock, ifname, &addr); + if (ret < 0) + { + fprintf(stderr, "ERROR: wapi_set_ip() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_setmask_cmd + * + * Description: + * Set the network mask + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_setmask_cmd(int sock, FAR const char *maskstr) +{ + struct in_addr addr; + int ret; + + /* Format the request */ +#warning Missing logic + + /* Set the network mask */ + + ret = wapi_set_netmask(sock, ifname, &addr); + if (ret < 0) + { + fprintf(stderr, "ERROR: wapi_set_netmask() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_setfreq_cmd + * + * Description: + * Set the frequency + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_setfreq_cmd(int sock, double frequency, + wapi_freq_flag_t freq_flag) +{ + int ret; + + /* Set the network mask */ + + ret = wapi_set_freq(sock, ifname, freq, freq_flag); + if (ret < 0) + { + fprintf(stderr, "ERROR: \nwapi_set_freq() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_setessid_cmd + * + * Description: + * Set the frequency + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_setessid_cmd(int sock, FAR char *essid, + wapi_essid_flag_t essid_flag) +{ + int ret; + + /* Set essid */ + + ret = wapi_set_essid(sock, ifname, essid, essid_flag); + if (ret < 0) + { + fprintf(stderr, "ERROR: wapi_set_essid() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_setmode_cmd + * + * Description: + * Set the operating mode + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_setmode_cmd(int sock, FAR char *ifname, wapi_mode_t mode) +{ + int ret; + + /* Set operating mode */ + + ret = wapi_set_mode(sock, ifname, mode); + if (ret < 0) + { + fprintf(stderr, "ERROR: \nwapi_set_mode() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_setap_cmd + * + * Description: + * Set the AP + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_setap_cmd(int sock, FAR char *ifname, + FAR struct ether_addr *ap) +{ + int ret; + + /* Set ap */ + + ret = wapi_set_ap(sock, ifname, ap); + if (ret < 0) + { + fprintf(stderr, "ERROR: \nwapi_set_ap() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_setbitrate_cmd + * + * Description: + * Set the bit rate + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_setbitrate_cmd(int sock, int bitrate, + wapi_bitrate_flag_t bitrate_flag) +{ + int ret; + + /* Set bitrate */ + + ret = wapi_set_bitrate(sock, ifname, bitrate, bitrate_flag); + if (ret < 0) + { + fprintf(stderr, "ERROR: \nwapi_set_bitrate() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_txpower_cmd + * + * Description: + * Set the TX power + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_txpower_cmd(int sock, int txpower, + wapi_txpower_flag_t txpower_flag) +{ + + int ret; + + /* Set txpower */ + + ret = wapi_set_txpower(sock, ifname, txpower, txpower_flag); + if (ret < 0) + { + fprintf(stderr, "ERROR: \nwapi_set_txpower() failed: %d", ret); + } +} + +/**************************************************************************** + * Name: wapi_scan + * + * Description: + * Scans available APs in the range using given ifname interface. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_scan(int sock, FAR const char *ifname) { int sleepdur = 1; int sleeptries = 5; @@ -254,7 +447,7 @@ static void scan(int sock, FAR const char *ifname) /* Start scan */ ret = wapi_scan_init(sock, ifname); - printf("wapi_scan_init(): ret: %d\n", ret); + fprintf(stderr, "ERROR: wapi_scan_init() failed: %d\n", ret); /* Wait for completion */ @@ -262,7 +455,7 @@ static void scan(int sock, FAR const char *ifname) { sleep(sleepdur); ret = wapi_scan_stat(sock, ifname); - printf("wapi_scan_stat(): ret: %d, sleeptries: %d\n", ret, sleeptries); + fprintf(stderr, "ERROR: wapi_scan_stat() failed: %d, sleeptries: %d\n", ret, sleeptries); } while (--sleeptries > 0 && ret > 0); @@ -275,7 +468,10 @@ static void scan(int sock, FAR const char *ifname) bzero(&list, sizeof(wapi_list_t)); ret = wapi_scan_coll(sock, ifname, &list); - printf("wapi_scan_coll(): ret: %d\n", ret); + if (ret < 0) + { + fprintf(stderr, "ERROR: wapi_scan_coll() failed: %d\n", ret); + } /* Print found aps */ @@ -301,6 +497,34 @@ static void scan(int sock, FAR const char *ifname) } } +/**************************************************************************** + * Name: wapi_showusage + * + * Description: + * Show program usage. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wapi_showusage(FAR const char *progname, int exitcode) +{ + fprintf(stderr, "Usage: %s show \n", progname); + fprintf(stderr, " %s setip OPTIONS\n", progname); + fprintf(stderr, " %s setmask OPTIONS\n", progname); + fprintf(stderr, " %s setfreq OPTIONS\n", progname); + fprintf(stderr, " %s setessid OPTIONS\n", progname); + fprintf(stderr, " %s setmode OPTIONS\n", progname); + fprintf(stderr, " %s setap OPTIONS\n", progname); + fprintf(stderr, " %s setbitrate OPTIONS\n", progname); + fprintf(stderr, " %s txpower OPTIONS\n", progname); + fprintf(stderr, " %s scan \n", progname); + fprintf(stderr, " %s help\n", progname); + + exit(exitcode); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -311,6 +535,7 @@ int main(int argc, FAR char *argv[]) int wapi_main(int argc, char *argv[]) #endif { + FAR const char *cmd; FAR const char *ifname; wapi_list_t list; int ret; @@ -318,32 +543,105 @@ int wapi_main(int argc, char *argv[]) /* Check command line args */ - if (argc != 2) + if (argc == 1 && strcmp(argv[1], "help") == 0) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return EXIT_FAILURE; + wapi_showusage(argv[0], EXIT_SUCCESS); + } + else if (argc < 3) + { + fprintf(stderr, "ERROR: Too few command line arguments\n"); + wapi_showusage(argv[0], EXIT_FAILURE); } - ifname = argv[1]; + cmd = argv[1]; + ifname = argv[2]; - /* Make a comm. sock. */ + /* Create a communication sock. */ sock = wapi_make_socket(); - printf("wapi_make_socket(): sock: %d\n", sock); + if (sock < 0) + { + fprintf(stderr, "ERROR: wapi_make_socket() failed: %d\n", sock); + } - /* List conf */ + /* Execute command */ - printf("\nconf\n"); - printf("------------\n"); - conf(sock, ifname); + if (strcmp(cmd, "show") + { + wapi_show_command(sock, ifname); + } + else if (strcmp(cmd, "setip") + { + /* Parse command specific options */ +#warning Missing logic * - /* Scan aps */ + /* Execute the command */ + //wapi_setip_cmd(sock, addrstr); + } + else if (strcmp(cmd, "setmask") + { + /* Parse command specific options */ +#warning Missing logic * - printf("\nscan\n"); - printf("----\n"); - scan(sock, ifname); + /* Execute the command */ + //wapi_setmask_cmd(sock, maskstr); + } + else if (strcmp(cmd, "setfreq") + { + /* Parse command specific options */ +#warning Missing logic * - /* Close comm. sock. */ + /* Execute the command */ + //wapi_setfreq_cmd(sock, frequency, freq_flag); + } + else if (strcmp(cmd, "setessid") + { + /* Parse command specific options */ +#warning Missing logic * + + /* Execute the command */ + //wapi_setessid_cmd(sock, essid, essid_flag); + } + else if (strcmp(cmd, "setmode") + { + /* Parse command specific options */ +#warning Missing logic * + + /* Execute the command */ + //wapi_setmode_cmd(sock, ifname, mode); + } + else if (strcmp(cmd, "setbitrate") + { + /* Parse command specific options */ +#warning Missing logic * + + /* Execute the command */ + //wapi_setap_cmd(sock, ifname, ap); + } + else if (strcmp(cmd, "txpower") + { + /* Parse command specific options */ +#warning Missing logic * + + /* Execute the command */ + //wapi_setbitrate_cmd(sock, bitrate, bitrate_flag); + } + else if (strcmp(cmd, "scan") + { + wapi_scan(sock, ifname); + } + else if (strcmp(cmd, "help") + { + fprintf(stderr, "WARNING: Garbage after help common ignored.\n"); + wapi_showusage(argv[0], EXIT_SUCCESS); + } + else + { + fprintf(stderr, "WARNING: Unrecognized command: %s\n", cmd); + wapi_showusage(argv[0], EXIT_FAILURE); + } + + /* Close communication socket */ close(sock); return EXIT_SUCCESS; From 1a470c6480caa83365a0d623524052af4f67ac6c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 11 Apr 2017 10:22:47 -0600 Subject: [PATCH 19/23] wireless/wapi: Re-write of wapi tool UI. --- include/wireless/wapi.h | 15 +- wireless/wapi/Kconfig | 4 - wireless/wapi/src/wapi.c | 513 ++++++++++++++++++++++++++--------- wireless/wapi/src/wireless.c | 2 + 4 files changed, 397 insertions(+), 137 deletions(-) diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h index 9bbc7d6f7..8713d1acb 100644 --- a/include/wireless/wapi.h +++ b/include/wireless/wapi.h @@ -93,13 +93,14 @@ typedef enum typedef enum { - WAPI_MODE_AUTO = IW_MODE_AUTO, /* Driver decides. */ - WAPI_MODE_ADHOC = IW_MODE_ADHOC, /* Single cell network. */ - WAPI_MODE_MANAGED = IW_MODE_INFRA, /* Multi cell network, roaming, ... */ - WAPI_MODE_MASTER = IW_MODE_MASTER, /* Synchronisation master or access point. */ - WAPI_MODE_REPEAT = IW_MODE_REPEAT, /* Wireless repeater, forwarder. */ - WAPI_MODE_SECOND = IW_MODE_SECOND, /* Secondary master/repeater, backup. */ - WAPI_MODE_MONITOR = IW_MODE_MONITOR /* Passive monitor, listen only. */ + WAPI_MODE_AUTO = IW_MODE_AUTO, /* Driver decides. */ + WAPI_MODE_ADHOC = IW_MODE_ADHOC, /* Single cell network. */ + WAPI_MODE_MANAGED = IW_MODE_INFRA, /* Multi cell network, roaming, ... */ + WAPI_MODE_MASTER = IW_MODE_MASTER, /* Synchronisation master or access point. */ + WAPI_MODE_REPEAT = IW_MODE_REPEAT, /* Wireless repeater, forwarder. */ + WAPI_MODE_SECOND = IW_MODE_SECOND, /* Secondary master/repeater, backup. */ + WAPI_MODE_MONITOR = IW_MODE_MONITOR, /* Passive monitor, listen only. */ + WAPI_MODE_MESH = IW_MODE_MESH /* Mesh (IEEE 802.11s) network */ } wapi_mode_t; /* Bitrate flags. diff --git a/wireless/wapi/Kconfig b/wireless/wapi/Kconfig index 4e8b7edcc..249a1593d 100644 --- a/wireless/wapi/Kconfig +++ b/wireless/wapi/Kconfig @@ -21,10 +21,6 @@ config WIRELESS_WAPI_CMDTOOL selected than a simple command line tool that can be ran from NSH will also be generated. -config WIRELESS_WAPI_ENABLE_SET - bool "Enable Setting Options" - default n - config WIRELESS_WAPI_PROGNAME string "Program Name" default "wapi" diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index 12239aff9..03fa6ba71 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -41,19 +41,141 @@ #include #include #include -#include +#include #include #include #include #include "wireless/wapi.h" +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Describes one command */ + +struct wapi_command_s +{ + FAR const char *name; + uint8_t noptions; + CODE void *handler; +}; + +/* Generic form of a commnd handler */ + +typedef void (*cmd1_t)(int sock, FAR const char *arg1); +typedef void (*cmd2_t)(int sock, FAR const char *arg1, + FAR const char *arg2); +typedef void (*cmd3_t)(int sock, FAR const char *arg1, + FAR const char *arg2, FAR const char *arg3); + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int wapi_str2int(FAR const char *str); +static double wapi_str2double(FAR const char *str); + +static void wapi_show_cmd(int sock, FAR const char *ifname); +static void wapi_ip_cmd(int sock, FAR const char *ifname, + FAR const char *addrstr); +static void wapi_mask_cmd(int sock, FAR const char *ifname, + FAR const char *maskstr); +static void wapi_freq_cmd(int sock, FAR const char *ifname, + FAR const char *freqstr, FAR const char *flagstr); +static void wapi_essid_cmd(int sock, FAR const char *ifname, + FAR const char *essid, FAR const char *flagstr); +static void wapi_mode_cmd(int sock, FAR const char *ifname, + FAR const char *modestr); +static void wapi_ap_cmd(int sock, FAR const char *ifname, + FAR const char *macstr); +static void wapi_bitrate_cmd(int sock, FAR const char *ifname, + FAR const char *ratestr, FAR const char *flagstr); +static void wapi_txpower_cmd(int sock, FAR const char *ifname, + FAR const char *pwrstr, FAR const char *flagstr); +static void wapi_scan_cmd(int sock, FAR const char *ifname); + +static void wapi_showusage(FAR const char *progname, int exitcode); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct wapi_command_s g_wapi_commands[] = +{ + {"help", 0, (CODE void *)NULL}, + {"show", 1, (CODE void *)wapi_show_cmd}, + {"scan", 1, (CODE void *)wapi_scan_cmd}, + {"ip", 2, (CODE void *)wapi_ip_cmd}, + {"mask", 2, (CODE void *)wapi_mask_cmd}, + {"freq", 3, (CODE void *)wapi_freq_cmd}, + {"essid", 3, (CODE void *)wapi_essid_cmd}, + {"mode", 2, (CODE void *)wapi_mode_cmd}, + {"ap", 2, (CODE void *)wapi_ap_cmd}, + {"bitrate", 3, (CODE void *)wapi_bitrate_cmd}, + {"txpower", 2, (CODE void *)wapi_txpower_cmd}, +}; + +#define NCOMMANDS (sizeof(g_wapi_commands) / sizeof(struct wapi_command_s)) + /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: wapi_show_command + * Name: wapi_str2int + * + * Description: + * Convert a string to an integer value + * + ****************************************************************************/ + +static int wapi_str2int(FAR const char *str) +{ + FAR char *endptr; + long value; + + value = strtol(str, &endptr, 0); + if (*endptr != '\0') + { + fprintf(stderr, "ERROR: Garbage after numeric argument\n"); + exit(EXIT_FAILURE); + } + + if (value > INT_MAX || value < INT_MIN) + { + fprintf(stderr, "ERROR: Integer value out of range\n"); + exit(EXIT_FAILURE); + } + + return (int)value; +} + +/**************************************************************************** + * Name: wapi_str2double + * + * Description: + * Convert a string to a double value + * + ****************************************************************************/ + +static double wapi_str2double(FAR const char *str) +{ + FAR char *endptr; + double value; + + value = strtod(str, &endptr); + if (*endptr != '\0') + { + fprintf(stderr, "ERROR: Garbage after numeric argument\n"); + exit(EXIT_FAILURE); + } + + return value; +} + +/**************************************************************************** + * Name: wapi_show_cmd * * Description: * Gets current configuration of the ifname using WAPI accessors and prints @@ -66,7 +188,7 @@ * ****************************************************************************/ -static void wapi_show_command(int sock, FAR const char *ifname) +static void wapi_show_cmd(int sock, FAR const char *ifname) { struct in_addr addr; @@ -128,7 +250,7 @@ static void wapi_show_command(int sock, FAR const char *ifname) double tmpfreq; int chan; - printf("Frequency: %g\n", freq; + printf("Frequency: %g\n", freq); printf(" Flag: %s\n", g_wapi_freq_flags[freq_flag]); ret = wapi_freq2chan(sock, ifname, freq, &chan); @@ -220,7 +342,7 @@ static void wapi_show_command(int sock, FAR const char *ifname) } /**************************************************************************** - * Name: wapi_setip_cmd + * Name: wapi_ip_cmd * * Description: * Set the IP address. @@ -230,13 +352,15 @@ static void wapi_show_command(int sock, FAR const char *ifname) * ****************************************************************************/ -static void wapi_setip_cmd(int sock, FAR const char *addrstr) +static void wapi_ip_cmd(int sock, FAR const char *ifname, + FAR const char *addrstr) { struct in_addr addr; int ret; /* Format the request */ -#warning Missing logic + + addr.s_addr = inet_addr(addrstr); /* Set the IP address */ @@ -248,7 +372,7 @@ static void wapi_setip_cmd(int sock, FAR const char *addrstr) } /**************************************************************************** - * Name: wapi_setmask_cmd + * Name: wapi_mask_cmd * * Description: * Set the network mask @@ -258,13 +382,15 @@ static void wapi_setip_cmd(int sock, FAR const char *addrstr) * ****************************************************************************/ -static void wapi_setmask_cmd(int sock, FAR const char *maskstr) +static void wapi_mask_cmd(int sock, FAR const char *ifname, + FAR const char *maskstr) { struct in_addr addr; int ret; /* Format the request */ -#warning Missing logic + + addr.s_addr = inet_addr(maskstr); /* Set the network mask */ @@ -276,7 +402,7 @@ static void wapi_setmask_cmd(int sock, FAR const char *maskstr) } /**************************************************************************** - * Name: wapi_setfreq_cmd + * Name: wapi_freq_cmd * * Description: * Set the frequency @@ -286,14 +412,38 @@ static void wapi_setmask_cmd(int sock, FAR const char *maskstr) * ****************************************************************************/ -static void wapi_setfreq_cmd(int sock, double frequency, - wapi_freq_flag_t freq_flag) +static void wapi_freq_cmd(int sock, FAR const char *ifname, + FAR const char *freqstr, FAR const char *flagstr) { + double frequency; + wapi_freq_flag_t freq_flag; + bool found = false; int ret; + int i; - /* Set the network mask */ + /* Convert input strings to values */ - ret = wapi_set_freq(sock, ifname, freq, freq_flag); + frequency = wapi_str2double(freqstr); + + for (i = 0; i < IW_FREQ_NFLAGS; i++) + { + if (strcmp(flagstr, g_wapi_freq_flags[i]) == 0) + { + freq_flag = (wapi_freq_flag_t)i; + found = true; + break; + } + } + + if (!found) + { + fprintf(stderr, "ERROR: Invalid frequency flag: %s\n", flagstr); + exit(EXIT_FAILURE); + } + + /* Set the frequency */ + + ret = wapi_set_freq(sock, ifname, frequency, freq_flag); if (ret < 0) { fprintf(stderr, "ERROR: \nwapi_set_freq() failed: %d", ret); @@ -301,22 +451,43 @@ static void wapi_setfreq_cmd(int sock, double frequency, } /**************************************************************************** - * Name: wapi_setessid_cmd + * Name: wapi_essid_cmd * * Description: - * Set the frequency + * Set the ESSID * * Returned Value: * None * ****************************************************************************/ -static void wapi_setessid_cmd(int sock, FAR char *essid, - wapi_essid_flag_t essid_flag) +static void wapi_essid_cmd(int sock, FAR const char *ifname, + FAR const char *essid, FAR const char *flagstr) { + wapi_essid_flag_t essid_flag; + bool found = false; int ret; + int i; - /* Set essid */ + /* Convert input strings to values */ + + for (i = 0; i < 2; i++) + { + if (strcmp(flagstr, g_wapi_essid_flags[i]) == 0) + { + essid_flag = (wapi_essid_flag_t)i; + found = true; + break; + } + } + + if (!found) + { + fprintf(stderr, "ERROR: Invalid ESSID flag: %s\n", flagstr); + exit(EXIT_FAILURE); + } + + /* Set the ESSID */ ret = wapi_set_essid(sock, ifname, essid, essid_flag); if (ret < 0) @@ -326,7 +497,7 @@ static void wapi_setessid_cmd(int sock, FAR char *essid, } /**************************************************************************** - * Name: wapi_setmode_cmd + * Name: wapi_mode_cmd * * Description: * Set the operating mode @@ -336,9 +507,31 @@ static void wapi_setessid_cmd(int sock, FAR char *essid, * ****************************************************************************/ -static void wapi_setmode_cmd(int sock, FAR char *ifname, wapi_mode_t mode) +static void wapi_mode_cmd(int sock, FAR const char *ifname, + FAR const char *modestr) { + wapi_mode_t mode; + bool found = false; int ret; + int i; + + /* Convert input strings to values */ + + for (i = 0; i < IW_MODE_NFLAGS; i++) + { + if (strcmp(modestr, g_wapi_modes[i]) == 0) + { + mode = (wapi_mode_t)i; + found = true; + break; + } + } + + if (!found) + { + fprintf(stderr, "ERROR: Invalid operating mode: %s\n", modestr); + exit(EXIT_FAILURE); + } /* Set operating mode */ @@ -350,7 +543,7 @@ static void wapi_setmode_cmd(int sock, FAR char *ifname, wapi_mode_t mode) } /**************************************************************************** - * Name: wapi_setap_cmd + * Name: wapi_ap_cmd * * Description: * Set the AP @@ -360,14 +553,22 @@ static void wapi_setmode_cmd(int sock, FAR char *ifname, wapi_mode_t mode) * ****************************************************************************/ -static void wapi_setap_cmd(int sock, FAR char *ifname, - FAR struct ether_addr *ap) +static void wapi_ap_cmd(int sock, FAR const char *ifname, + FAR const char *macstr) { + struct ether_addr ap; int ret; + /* Convert input strings to values */ + + sscanf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", + &ap.ether_addr_octet[0], &ap.ether_addr_octet[1], + &ap.ether_addr_octet[2], &ap.ether_addr_octet[3], + &ap.ether_addr_octet[4], &ap.ether_addr_octet[5]); + /* Set ap */ - ret = wapi_set_ap(sock, ifname, ap); + ret = wapi_set_ap(sock, ifname, &ap); if (ret < 0) { fprintf(stderr, "ERROR: \nwapi_set_ap() failed: %d", ret); @@ -375,7 +576,7 @@ static void wapi_setap_cmd(int sock, FAR char *ifname, } /**************************************************************************** - * Name: wapi_setbitrate_cmd + * Name: wapi_bitrate_cmd * * Description: * Set the bit rate @@ -385,10 +586,35 @@ static void wapi_setap_cmd(int sock, FAR char *ifname, * ****************************************************************************/ -static void wapi_setbitrate_cmd(int sock, int bitrate, - wapi_bitrate_flag_t bitrate_flag) +static void wapi_bitrate_cmd(int sock, FAR const char *ifname, + FAR const char *ratestr, FAR const char *flagstr) + { + wapi_bitrate_flag_t bitrate_flag; + bool found = false; + int bitrate; int ret; + int i; + + /* Convert input strings to values */ + + bitrate = wapi_str2int(ratestr); + + for (i = 0; i < 2; i++) + { + if (strcmp(flagstr, g_wapi_bitrate_flags[i]) == 0) + { + bitrate_flag = (wapi_bitrate_flag_t)i; + found = true; + break; + } + } + + if (!found) + { + fprintf(stderr, "ERROR: Invalid bitrate flag: %s\n", flagstr); + exit(EXIT_FAILURE); + } /* Set bitrate */ @@ -410,11 +636,34 @@ static void wapi_setbitrate_cmd(int sock, int bitrate, * ****************************************************************************/ -static void wapi_txpower_cmd(int sock, int txpower, - wapi_txpower_flag_t txpower_flag) +static void wapi_txpower_cmd(int sock, FAR const char *ifname, + FAR const char *pwrstr, FAR const char *flagstr) { - + wapi_txpower_flag_t txpower_flag; + bool found = false; + int txpower; int ret; + int i; + + /* Convert input strings to values */ + + txpower = wapi_str2int(pwrstr); + + for (i = 0; i < 3; i++) + { + if (strcmp(flagstr, g_wapi_txpower_flags[i]) == 0) + { + txpower_flag = (wapi_txpower_flag_t)i; + found = true; + break; + } + } + + if (!found) + { + fprintf(stderr, "ERROR: Invalid TX power flag: %s\n", flagstr); + exit(EXIT_FAILURE); + } /* Set txpower */ @@ -426,7 +675,7 @@ static void wapi_txpower_cmd(int sock, int txpower, } /**************************************************************************** - * Name: wapi_scan + * Name: wapi_scan_cmd * * Description: * Scans available APs in the range using given ifname interface. @@ -436,7 +685,7 @@ static void wapi_txpower_cmd(int sock, int txpower, * ****************************************************************************/ -static void wapi_scan(int sock, FAR const char *ifname) +static void wapi_scan_cmd(int sock, FAR const char *ifname) { int sleepdur = 1; int sleeptries = 5; @@ -510,18 +759,52 @@ static void wapi_scan(int sock, FAR const char *ifname) static void wapi_showusage(FAR const char *progname, int exitcode) { + int i; + fprintf(stderr, "Usage: %s show \n", progname); - fprintf(stderr, " %s setip OPTIONS\n", progname); - fprintf(stderr, " %s setmask OPTIONS\n", progname); - fprintf(stderr, " %s setfreq OPTIONS\n", progname); - fprintf(stderr, " %s setessid OPTIONS\n", progname); - fprintf(stderr, " %s setmode OPTIONS\n", progname); - fprintf(stderr, " %s setap OPTIONS\n", progname); - fprintf(stderr, " %s setbitrate OPTIONS\n", progname); - fprintf(stderr, " %s txpower OPTIONS\n", progname); fprintf(stderr, " %s scan \n", progname); + fprintf(stderr, " %s ip \n", progname); + fprintf(stderr, " %s mask \n", progname); + fprintf(stderr, " %s freq \n", progname); + fprintf(stderr, " %s essid \n", progname); + fprintf(stderr, " %s mode \n", progname); + fprintf(stderr, " %s ap \n", progname); + fprintf(stderr, " %s bitrate \n", progname); + fprintf(stderr, " %s txpower \n", progname); fprintf(stderr, " %s help\n", progname); + fprintf(stderr, "\nFrequency Flags:\n"); + for (i = 0; i < IW_FREQ_NFLAGS; i++) + { + fprintf(stderr, " %s", g_wapi_freq_flags[i]); + } + + fprintf(stderr, "\nESSID Flags:\n"); + for (i = 0; i < 2; i++) + { + fprintf(stderr, " %s", g_wapi_essid_flags[i]); + } + + fprintf(stderr, "\nOperating Modes:\n"); + for (i = 0; i < IW_MODE_NFLAGS; i++) + { + fprintf(stderr, " %s", g_wapi_modes[i]); + } + + fprintf(stderr, "\nBitrate Flags:\n"); + for (i = 0; i < 6; i++) + { + fprintf(stderr, " %s", g_wapi_bitrate_flags[i]); + } + + fprintf(stderr, "\nTX power Flags:\n"); + for (i = 0; i < 3; i++) + { + fprintf(stderr, " %s", g_wapi_txpower_flags[i]); + } + + putchar('\n'); + exit(exitcode); } @@ -535,28 +818,61 @@ int main(int argc, FAR char *argv[]) int wapi_main(int argc, char *argv[]) #endif { - FAR const char *cmd; - FAR const char *ifname; - wapi_list_t list; - int ret; + FAR const char *cmdname; + FAR const struct wapi_command_s *wapicmd; int sock; + int i; - /* Check command line args */ + /* Get the command */ - if (argc == 1 && strcmp(argv[1], "help") == 0) + if (argc < 2) { - wapi_showusage(argv[0], EXIT_SUCCESS); - } - else if (argc < 3) - { - fprintf(stderr, "ERROR: Too few command line arguments\n"); + fprintf(stderr, "ERROR: Missing command\n"); wapi_showusage(argv[0], EXIT_FAILURE); } - cmd = argv[1]; - ifname = argv[2]; + cmdname = argv[1]; - /* Create a communication sock. */ + /* Find the command in the g_wapi_command[] list */ + + wapicmd = NULL; + for (i = 0; i < NCOMMANDS; i++) + { + FAR const struct wapi_command_s *cmd = &g_wapi_commands[i]; + if (strcmp(cmdname, cmd->name) == 0) + { + wapicmd = cmd; + break; + } + } + + if (wapicmd == NULL) + { + fprintf(stderr, "ERROR: Unsupported command: %s\n", cmdname); + wapi_showusage(argv[0], EXIT_FAILURE); + } + + if (wapicmd->noptions + 2 < argc) + { + fprintf(stderr, "ERROR: Garbage at end of command ignored\n"); + } + else if (wapicmd->noptions + 2 > argc) + { + fprintf(stderr, "ERROR: Missing required command options: %s\n", + cmdname); + wapi_showusage(argv[0], EXIT_FAILURE); + } + + /* Special case the help command which has no arguments, no handler, + * and does not need a socket. + */ + + if (wapicmd->handler == NULL) + { + wapi_showusage(argv[0], EXIT_SUCCESS); + } + + /* Create a communication socket */ sock = wapi_make_socket(); if (sock < 0) @@ -564,81 +880,26 @@ int wapi_main(int argc, char *argv[]) fprintf(stderr, "ERROR: wapi_make_socket() failed: %d\n", sock); } - /* Execute command */ + /* Dispatch the command handling */ - if (strcmp(cmd, "show") + switch (wapicmd->noptions) { - wapi_show_command(sock, ifname); - } - else if (strcmp(cmd, "setip") - { - /* Parse command specific options */ -#warning Missing logic * + default: + case 0: + fprintf(stderr, "ERROR: Internal craziness\n"); + wapi_showusage(argv[0], EXIT_FAILURE); - /* Execute the command */ - //wapi_setip_cmd(sock, addrstr); - } - else if (strcmp(cmd, "setmask") - { - /* Parse command specific options */ -#warning Missing logic * + case 1: + ((cmd1_t)wapicmd->handler)(sock, argv[2]); + break; - /* Execute the command */ - //wapi_setmask_cmd(sock, maskstr); - } - else if (strcmp(cmd, "setfreq") - { - /* Parse command specific options */ -#warning Missing logic * + case 2: + ((cmd2_t)wapicmd->handler)(sock, argv[2], argv[3]); + break; - /* Execute the command */ - //wapi_setfreq_cmd(sock, frequency, freq_flag); - } - else if (strcmp(cmd, "setessid") - { - /* Parse command specific options */ -#warning Missing logic * - - /* Execute the command */ - //wapi_setessid_cmd(sock, essid, essid_flag); - } - else if (strcmp(cmd, "setmode") - { - /* Parse command specific options */ -#warning Missing logic * - - /* Execute the command */ - //wapi_setmode_cmd(sock, ifname, mode); - } - else if (strcmp(cmd, "setbitrate") - { - /* Parse command specific options */ -#warning Missing logic * - - /* Execute the command */ - //wapi_setap_cmd(sock, ifname, ap); - } - else if (strcmp(cmd, "txpower") - { - /* Parse command specific options */ -#warning Missing logic * - - /* Execute the command */ - //wapi_setbitrate_cmd(sock, bitrate, bitrate_flag); - } - else if (strcmp(cmd, "scan") - { - wapi_scan(sock, ifname); - } - else if (strcmp(cmd, "help") - { - fprintf(stderr, "WARNING: Garbage after help common ignored.\n"); - wapi_showusage(argv[0], EXIT_SUCCESS); - } - else - { - fprintf(stderr, "WARNING: Unrecognized command: %s\n", cmd); - wapi_showusage(argv[0], EXIT_FAILURE); + case 3: + ((cmd3_t)wapicmd->handler)(sock, argv[2], argv[3], argv[4]); + break; } /* Close communication socket */ diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c index acd2eebd4..12f9451a1 100644 --- a/wireless/wapi/src/wireless.c +++ b/wireless/wapi/src/wireless.c @@ -37,6 +37,7 @@ * Included Files ****************************************************************************/ +#include #include #include #include @@ -99,6 +100,7 @@ FAR const char *g_wapi_modes[] = "WAPI_MODE_REPEAT", "WAPI_MODE_SECOND", "WAPI_MODE_MONITOR" + "WAPI_MODE_MESH" }; /* Bit Rate */ From 568e932e809f987c3160281df5fcde038add36d5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 11 Apr 2017 12:42:15 -0600 Subject: [PATCH 20/23] apps/wireless/wapi: Some changes from initial debug. --- include/wireless/wapi.h | 16 ----- wireless/wapi/src/util.c | 28 ++++++++- wireless/wapi/src/wapi.c | 95 ++++++++++++++-------------- wireless/wapi/src/wireless.c | 116 ++++++++++------------------------- 4 files changed, 104 insertions(+), 151 deletions(-) diff --git a/include/wireless/wapi.h b/include/wireless/wapi.h index 8713d1acb..69ea3e38f 100644 --- a/include/wireless/wapi.h +++ b/include/wireless/wapi.h @@ -321,22 +321,6 @@ int wapi_del_route_gw(int sock, wapi_route_target_t targettype, FAR const struct in_addr *gw); #endif -/**************************************************************************** - * Name: wapi_get_we_version - * - * Description: - * Gets kernel WE (Wireless Extensions) version. - * - * Input Parameters: - * we_version Set to we_version_compiled of range information. - * - * Returned Value: - * Zero on success. - * - ****************************************************************************/ - -int wapi_get_we_version(int sock, const char *ifname, FAR int *we_version); - /**************************************************************************** * Name: wapi_get_freq * diff --git a/wireless/wapi/src/util.c b/wireless/wapi/src/util.c index 6e379c1e2..28dd7b600 100644 --- a/wireless/wapi/src/util.c +++ b/wireless/wapi/src/util.c @@ -51,8 +51,30 @@ * Pre-processor Definitions ****************************************************************************/ -#define WAPI_IOCTL_COMMAND_NAMEBUFSIZ 128 /* Is fairly enough to print an - * integer. */ +/* The address family that we used to create the socket really does not + * matter. It should, however, be valid in the current configuration. + */ + +#if defined(CONFIG_NET_IPv4) +# define PF_INETX PF_INET +#elif defined(CONFIG_NET_IPv6) +# define PF_INETX PF_INET6 +#endif + +/* SOCK_DGRAM is the preferred socket type to use when we just want a + * socket for performing driver ioctls. However, we can't use SOCK_DRAM + * if UDP is disabled. + */ + +#ifdef CONFIG_NET_UDP +# define SOCK_WAPI SOCK_DGRAM +#else +# define SOCK_WAPI SOCK_STREAM +#endif + +/* Size of the command buffer */ + +#define WAPI_IOCTL_COMMAND_NAMEBUFSIZ 24 /**************************************************************************** * Public Functions @@ -77,7 +99,7 @@ static char g_ioctl_command_namebuf[WAPI_IOCTL_COMMAND_NAMEBUFSIZ]; int wapi_make_socket(void) { - return socket(AF_INET, SOCK_DGRAM, 0); + return socket(PF_INETX, SOCK_WAPI, 0); } /**************************************************************************** diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index 03fa6ba71..09f6538ef 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -47,6 +47,7 @@ #include #include "wireless/wapi.h" +#include "util.h" /**************************************************************************** * Private Types @@ -138,13 +139,13 @@ static int wapi_str2int(FAR const char *str) value = strtol(str, &endptr, 0); if (*endptr != '\0') { - fprintf(stderr, "ERROR: Garbage after numeric argument\n"); + WAPI_ERROR("ERROR: Garbage after numeric argument\n"); exit(EXIT_FAILURE); } if (value > INT_MAX || value < INT_MIN) { - fprintf(stderr, "ERROR: Integer value out of range\n"); + WAPI_ERROR("ERROR: Integer value out of range\n"); exit(EXIT_FAILURE); } @@ -167,7 +168,7 @@ static double wapi_str2double(FAR const char *str) value = strtod(str, &endptr); if (*endptr != '\0') { - fprintf(stderr, "ERROR: Garbage after numeric argument\n"); + WAPI_ERROR("ERROR: Garbage after numeric argument\n"); exit(EXIT_FAILURE); } @@ -218,7 +219,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_ip(sock, ifname, &addr); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_ip() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_ip() failed: %d\n", ret); } else { @@ -231,7 +232,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_netmask(sock, ifname, &addr); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_netmask() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_netmask() failed: %d\n", ret); } else { @@ -243,7 +244,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_freq(sock, ifname, &freq, &freq_flag); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_freq() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_freq() failed: %d\n", ret); } else { @@ -256,7 +257,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_freq2chan(sock, ifname, freq, &chan); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_freq2chan() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_freq2chan() failed: %d\n", ret); } else { @@ -266,7 +267,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_chan2freq(sock, ifname, chan, &tmpfreq); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_chan2freq() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_chan2freq() failed: %d\n", ret); } else { @@ -279,7 +280,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_essid(sock, ifname, essid, &essid_flag); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_essid() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_essid() failed: %d\n", ret); } else { @@ -292,7 +293,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_mode(sock, ifname, &mode); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_mode() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_mode() failed: %d\n", ret); } else { @@ -304,11 +305,11 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_ap(sock, ifname, &ap); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_ap() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_ap() failed: %d\n", ret); } else { - printf(" AP: %02x:%02x:%02x:%02x:%02x:%02x", + printf(" AP: %02x:%02x:%02x:%02x:%02x:%02x\n", ap.ether_addr_octet[0], ap.ether_addr_octet[1], ap.ether_addr_octet[2], ap.ether_addr_octet[3], ap.ether_addr_octet[4], ap.ether_addr_octet[5]); @@ -319,7 +320,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_bitrate(sock, ifname, &bitrate, &bitrate_flag); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_bitrate() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_bitrate() failed: %d\n", ret); } else { @@ -332,7 +333,7 @@ static void wapi_show_cmd(int sock, FAR const char *ifname) ret = wapi_get_txpower(sock, ifname, &txpower, &txpower_flag); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_get_txpower() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_get_txpower() failed: %d\n", ret); } else { @@ -367,7 +368,7 @@ static void wapi_ip_cmd(int sock, FAR const char *ifname, ret = wapi_set_ip(sock, ifname, &addr); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_set_ip() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_set_ip() failed: %d\n", ret); } } @@ -397,7 +398,7 @@ static void wapi_mask_cmd(int sock, FAR const char *ifname, ret = wapi_set_netmask(sock, ifname, &addr); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_set_netmask() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_set_netmask() failed: %d\n", ret); } } @@ -437,7 +438,7 @@ static void wapi_freq_cmd(int sock, FAR const char *ifname, if (!found) { - fprintf(stderr, "ERROR: Invalid frequency flag: %s\n", flagstr); + WAPI_ERROR("ERROR: Invalid frequency flag: %s\n", flagstr); exit(EXIT_FAILURE); } @@ -446,7 +447,7 @@ static void wapi_freq_cmd(int sock, FAR const char *ifname, ret = wapi_set_freq(sock, ifname, frequency, freq_flag); if (ret < 0) { - fprintf(stderr, "ERROR: \nwapi_set_freq() failed: %d", ret); + WAPI_ERROR("ERROR: \nwapi_set_freq() failed: %d\n", ret); } } @@ -483,7 +484,7 @@ static void wapi_essid_cmd(int sock, FAR const char *ifname, if (!found) { - fprintf(stderr, "ERROR: Invalid ESSID flag: %s\n", flagstr); + WAPI_ERROR("ERROR: Invalid ESSID flag: %s\n", flagstr); exit(EXIT_FAILURE); } @@ -492,7 +493,7 @@ static void wapi_essid_cmd(int sock, FAR const char *ifname, ret = wapi_set_essid(sock, ifname, essid, essid_flag); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_set_essid() failed: %d", ret); + WAPI_ERROR("ERROR: wapi_set_essid() failed: %d\n", ret); } } @@ -529,7 +530,7 @@ static void wapi_mode_cmd(int sock, FAR const char *ifname, if (!found) { - fprintf(stderr, "ERROR: Invalid operating mode: %s\n", modestr); + WAPI_ERROR("ERROR: Invalid operating mode: %s\n", modestr); exit(EXIT_FAILURE); } @@ -538,7 +539,7 @@ static void wapi_mode_cmd(int sock, FAR const char *ifname, ret = wapi_set_mode(sock, ifname, mode); if (ret < 0) { - fprintf(stderr, "ERROR: \nwapi_set_mode() failed: %d", ret); + WAPI_ERROR("ERROR: \nwapi_set_mode() failed: %d\n", ret); } } @@ -571,7 +572,7 @@ static void wapi_ap_cmd(int sock, FAR const char *ifname, ret = wapi_set_ap(sock, ifname, &ap); if (ret < 0) { - fprintf(stderr, "ERROR: \nwapi_set_ap() failed: %d", ret); + WAPI_ERROR("ERROR: \nwapi_set_ap() failed: %d\n", ret); } } @@ -612,7 +613,7 @@ static void wapi_bitrate_cmd(int sock, FAR const char *ifname, if (!found) { - fprintf(stderr, "ERROR: Invalid bitrate flag: %s\n", flagstr); + WAPI_ERROR("ERROR: Invalid bitrate flag: %s\n", flagstr); exit(EXIT_FAILURE); } @@ -621,7 +622,7 @@ static void wapi_bitrate_cmd(int sock, FAR const char *ifname, ret = wapi_set_bitrate(sock, ifname, bitrate, bitrate_flag); if (ret < 0) { - fprintf(stderr, "ERROR: \nwapi_set_bitrate() failed: %d", ret); + WAPI_ERROR("ERROR: \nwapi_set_bitrate() failed: %d\n", ret); } } @@ -649,7 +650,7 @@ static void wapi_txpower_cmd(int sock, FAR const char *ifname, txpower = wapi_str2int(pwrstr); - for (i = 0; i < 3; i++) + for (i = 0; i < IW_TXPOW_NFLAGS; i++) { if (strcmp(flagstr, g_wapi_txpower_flags[i]) == 0) { @@ -661,7 +662,7 @@ static void wapi_txpower_cmd(int sock, FAR const char *ifname, if (!found) { - fprintf(stderr, "ERROR: Invalid TX power flag: %s\n", flagstr); + WAPI_ERROR("ERROR: Invalid TX power flag: %s\n", flagstr); exit(EXIT_FAILURE); } @@ -670,7 +671,7 @@ static void wapi_txpower_cmd(int sock, FAR const char *ifname, ret = wapi_set_txpower(sock, ifname, txpower, txpower_flag); if (ret < 0) { - fprintf(stderr, "ERROR: \nwapi_set_txpower() failed: %d", ret); + WAPI_ERROR("ERROR: \nwapi_set_txpower() failed: %d\n", ret); } } @@ -696,7 +697,7 @@ static void wapi_scan_cmd(int sock, FAR const char *ifname) /* Start scan */ ret = wapi_scan_init(sock, ifname); - fprintf(stderr, "ERROR: wapi_scan_init() failed: %d\n", ret); + WAPI_ERROR("ERROR: wapi_scan_init() failed: %d\n", ret); /* Wait for completion */ @@ -704,7 +705,8 @@ static void wapi_scan_cmd(int sock, FAR const char *ifname) { sleep(sleepdur); ret = wapi_scan_stat(sock, ifname); - fprintf(stderr, "ERROR: wapi_scan_stat() failed: %d, sleeptries: %d\n", ret, sleeptries); + WAPI_ERROR("ERROR: wapi_scan_stat() failed: %d, sleeptries: %d\n", + ret, sleeptries); } while (--sleeptries > 0 && ret > 0); @@ -719,7 +721,7 @@ static void wapi_scan_cmd(int sock, FAR const char *ifname) ret = wapi_scan_coll(sock, ifname, &list); if (ret < 0) { - fprintf(stderr, "ERROR: wapi_scan_coll() failed: %d\n", ret); + WAPI_ERROR("ERROR: wapi_scan_coll() failed: %d\n", ret); } /* Print found aps */ @@ -776,35 +778,33 @@ static void wapi_showusage(FAR const char *progname, int exitcode) fprintf(stderr, "\nFrequency Flags:\n"); for (i = 0; i < IW_FREQ_NFLAGS; i++) { - fprintf(stderr, " %s", g_wapi_freq_flags[i]); + fprintf(stderr, " %s\n", g_wapi_freq_flags[i]); } fprintf(stderr, "\nESSID Flags:\n"); for (i = 0; i < 2; i++) { - fprintf(stderr, " %s", g_wapi_essid_flags[i]); + fprintf(stderr, " %s\n", g_wapi_essid_flags[i]); } fprintf(stderr, "\nOperating Modes:\n"); for (i = 0; i < IW_MODE_NFLAGS; i++) { - fprintf(stderr, " %s", g_wapi_modes[i]); + fprintf(stderr, " %s\n", g_wapi_modes[i]); } fprintf(stderr, "\nBitrate Flags:\n"); - for (i = 0; i < 6; i++) + for (i = 0; i < 2; i++) { - fprintf(stderr, " %s", g_wapi_bitrate_flags[i]); + fprintf(stderr, " %s\n", g_wapi_bitrate_flags[i]); } fprintf(stderr, "\nTX power Flags:\n"); - for (i = 0; i < 3; i++) + for (i = 0; i < IW_TXPOW_NFLAGS; i++) { - fprintf(stderr, " %s", g_wapi_txpower_flags[i]); + fprintf(stderr, " %s\n", g_wapi_txpower_flags[i]); } - putchar('\n'); - exit(exitcode); } @@ -827,7 +827,7 @@ int wapi_main(int argc, char *argv[]) if (argc < 2) { - fprintf(stderr, "ERROR: Missing command\n"); + WAPI_ERROR("ERROR: Missing command\n"); wapi_showusage(argv[0], EXIT_FAILURE); } @@ -848,18 +848,18 @@ int wapi_main(int argc, char *argv[]) if (wapicmd == NULL) { - fprintf(stderr, "ERROR: Unsupported command: %s\n", cmdname); + WAPI_ERROR("ERROR: Unsupported command: %s\n", cmdname); wapi_showusage(argv[0], EXIT_FAILURE); } if (wapicmd->noptions + 2 < argc) { - fprintf(stderr, "ERROR: Garbage at end of command ignored\n"); + WAPI_ERROR("ERROR: Garbage at end of command ignored\n"); } else if (wapicmd->noptions + 2 > argc) { - fprintf(stderr, "ERROR: Missing required command options: %s\n", - cmdname); + WAPI_ERROR("ERROR: Missing required command options: %s\n", + cmdname); wapi_showusage(argv[0], EXIT_FAILURE); } @@ -877,7 +877,8 @@ int wapi_main(int argc, char *argv[]) sock = wapi_make_socket(); if (sock < 0) { - fprintf(stderr, "ERROR: wapi_make_socket() failed: %d\n", sock); + WAPI_ERROR("ERROR: wapi_make_socket() failed: %d\n", sock); + return EXIT_FAILURE; } /* Dispatch the command handling */ @@ -886,7 +887,7 @@ int wapi_main(int argc, char *argv[]) { default: case 0: - fprintf(stderr, "ERROR: Internal craziness\n"); + WAPI_ERROR("ERROR: Internal craziness\n"); wapi_showusage(argv[0], EXIT_FAILURE); case 1: diff --git a/wireless/wapi/src/wireless.c b/wireless/wapi/src/wireless.c index 12f9451a1..36bac9600 100644 --- a/wireless/wapi/src/wireless.c +++ b/wireless/wapi/src/wireless.c @@ -43,26 +43,19 @@ #include #include +#include #include #include "wireless/wapi.h" #include "util.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef LIBNL1 -# define nl_sock nl_handle -#endif - /**************************************************************************** * Private Types ****************************************************************************/ /* Events & Streams */ -struct iw_event_stream_s +struct wapi_event_stream_s { FAR char *end; /* End of the stream */ FAR char *current; /* Current event in stream of events */ @@ -99,7 +92,7 @@ FAR const char *g_wapi_modes[] = "WAPI_MODE_MASTER", "WAPI_MODE_REPEAT", "WAPI_MODE_SECOND", - "WAPI_MODE_MONITOR" + "WAPI_MODE_MONITOR", "WAPI_MODE_MESH" }; @@ -182,7 +175,7 @@ static int wapi_parse_mode(int iw_mode, FAR wapi_mode_t *wapi_mode) return 0; default: - WAPI_ERROR("Unknown mode: %d.\n", iw_mode); + WAPI_ERROR("ERROR: Unknown mode: %d\n", iw_mode); return -1; } } @@ -202,32 +195,35 @@ static int wapi_make_ether(FAR struct ether_addr *addr, int byte) } /**************************************************************************** - * Name: iw_event_stream_init + * Name: wapi_event_stream_init * * Description: + * Initialize a stream to access the events. * ****************************************************************************/ -static void iw_event_stream_init(FAR struct iw_event_stream_s *stream, - FAR char *data, size_t len) +static void wapi_event_stream_init(FAR struct wapi_event_stream_s *stream, + FAR char *data, size_t len) { - memset(stream, 0, sizeof(struct iw_event_stream_s)); + memset(stream, 0, sizeof(struct wapi_event_stream_s)); stream->current = data; stream->end = &data[len]; } /**************************************************************************** - * Name: iw_event_stream_pop + * Name: wapi_event_stream_extract * * Description: + * Extract the next event from the stream. * ****************************************************************************/ -static int iw_event_stream_pop(FAR struct iw_event_stream_s *stream, - FAR struct iw_event *iwe, int we_version) +static int wapi_event_stream_extract(FAR struct wapi_event_stream_s *stream, + FAR struct iw_event *iwe) { - return iw_extract_event_stream((struct stream_descr *)stream, iwe, - we_version); +#warning Missing logic +// return iw_extract_event_stream((struct stream_descr *)stream, iwe, 0); +return -ENOSYS; } /**************************************************************************** @@ -327,51 +323,6 @@ static int wapi_scan_event(FAR struct iw_event *event, FAR wapi_list_t *list) * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: wapi_get_we_version - * - * Description: - * Gets kernel WE (Wireless Extensions) version. - * - * Input Parameters: - * we_version Set to we_version_compiled of range information. - * - * Returned Value: - * Zero on success. - * - ****************************************************************************/ - -int wapi_get_we_version(int sock, const char *ifname, FAR int *we_version) -{ - struct iwreq wrq; - char buf[sizeof(struct iw_range) * 2]; - int ret; - - WAPI_VALIDATE_PTR(we_version); - - /* Prepare request. */ - - bzero(buf, sizeof(buf)); - wrq.u.data.pointer = buf; - wrq.u.data.length = sizeof(buf); - wrq.u.data.flags = 0; - - /* Get WE version. */ - - strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWRANGE, (unsigned long)((uintptr_t)&wrq))) >= 0) - { - struct iw_range *range = (struct iw_range *)buf; - *we_version = (int)range->we_version_compiled; - } - else - { - WAPI_IOCTL_STRERROR(SIOCGIWRANGE); - } - - return ret; -} - /**************************************************************************** * Name: wapi_get_freq * @@ -404,7 +355,7 @@ int wapi_get_freq(int sock, FAR const char *ifname, FAR double *freq, } else { - WAPI_ERROR("Unknown flag: %d.\n", wrq.u.freq.flags); + WAPI_ERROR("ERROR: Unknown flag: %d\n", wrq.u.freq.flags); return -1; } @@ -810,7 +761,7 @@ int wapi_get_bitrate(int sock, FAR const char *ifname, if (wrq.u.bitrate.disabled) { - WAPI_ERROR("Bitrate is disabled.\n"); + WAPI_ERROR("ERROR: Bitrate is disabled\n"); return -1; } @@ -923,7 +874,7 @@ int wapi_get_txpower(int sock, FAR const char *ifname, FAR int *power, } else { - WAPI_ERROR("Unknown flag: %d.\n", wrq.u.txpower.flags); + WAPI_ERROR("ERROR: Unknown flag: %d\n", wrq.u.txpower.flags); return -1; } @@ -1074,18 +1025,10 @@ int wapi_scan_coll(int sock, FAR const char *ifname, FAR wapi_list_t *aps) FAR char *buf; int buflen; struct iwreq wrq; - int we_version; int ret; WAPI_VALIDATE_PTR(aps); - /* Get WE version. (Required for event extraction via libiw.) */ - - if ((ret = wapi_get_we_version(sock, ifname, &we_version)) < 0) - { - return ret; - } - buflen = IW_SCAN_MAX_DATA; buf = malloc(buflen * sizeof(char)); if (!buf) @@ -1098,13 +1041,14 @@ alloc: /* Collect results. */ wrq.u.data.pointer = buf; - wrq.u.data.length = buflen; - wrq.u.data.flags = 0; + wrq.u.data.length = buflen; + wrq.u.data.flags = 0; strncpy(wrq.ifr_name, ifname, IFNAMSIZ); - if ((ret = ioctl(sock, SIOCGIWSCAN, (unsigned long)((uintptr_t)&wrq))) < 0 && - errno == E2BIG) + + ret = ioctl(sock, SIOCGIWSCAN, (unsigned long)((uintptr_t)&wrq)); + if (ret < 0 && errno == E2BIG) { - char *tmp; + FAR char *tmp; buflen *= 2; tmp = realloc(buf, buflen); @@ -1135,12 +1079,14 @@ alloc: if (wrq.u.data.length) { struct iw_event iwe; - struct iw_event_stream_s stream; + struct wapi_event_stream_s stream; - iw_event_stream_init(&stream, buf, wrq.u.data.length); + wapi_event_stream_init(&stream, buf, wrq.u.data.length); do { - if ((ret = iw_event_stream_pop(&stream, &iwe, we_version)) >= 0) + /* Get the next event from the stream */ + + if ((ret = wapi_event_stream_extract(&stream, &iwe)) >= 0) { int eventret = wapi_scan_event(&iwe, aps); if (eventret < 0) @@ -1150,7 +1096,7 @@ alloc: } else { - WAPI_ERROR("iw_event_stream_pop() failed!\n"); + WAPI_ERROR("ERROR: wapi_event_stream_extract() failed!\n"); } } while (ret > 0); From d9a02dd742705c1fe1fc5283d64b44819ccbeaaf Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 11 Apr 2017 16:34:50 -0600 Subject: [PATCH 21/23] apps/wireless/wapi: Consolidate some duplicate logic. --- wireless/wapi/src/wapi.c | 131 ++++++++++++--------------------------- 1 file changed, 38 insertions(+), 93 deletions(-) diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index 09f6538ef..60f00a3b9 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -114,7 +114,7 @@ static const struct wapi_command_s g_wapi_commands[] = {"mode", 2, (CODE void *)wapi_mode_cmd}, {"ap", 2, (CODE void *)wapi_ap_cmd}, {"bitrate", 3, (CODE void *)wapi_bitrate_cmd}, - {"txpower", 2, (CODE void *)wapi_txpower_cmd}, + {"txpower", 3, (CODE void *)wapi_txpower_cmd}, }; #define NCOMMANDS (sizeof(g_wapi_commands) / sizeof(struct wapi_command_s)) @@ -175,6 +175,31 @@ static double wapi_str2double(FAR const char *str) return value; } +/**************************************************************************** + * Name: wapi_str2ndx + * + * Description: + * Return the index of a string in a list of strings + * + ****************************************************************************/ + +static unsigned int wapi_str2ndx(FAR const char *name, FAR const char **list, + unsigned int listlen) +{ + unsigned int ndx; + + for (ndx = 0; ndx < listlen; ndx++) + { + if (strcmp(name, list[ndx]) == 0) + { + return ndx; + } + } + + WAPI_ERROR("ERROR: Invalid string: %s\n", name); + exit(EXIT_FAILURE); +} + /**************************************************************************** * Name: wapi_show_cmd * @@ -418,29 +443,13 @@ static void wapi_freq_cmd(int sock, FAR const char *ifname, { double frequency; wapi_freq_flag_t freq_flag; - bool found = false; int ret; - int i; /* Convert input strings to values */ frequency = wapi_str2double(freqstr); - - for (i = 0; i < IW_FREQ_NFLAGS; i++) - { - if (strcmp(flagstr, g_wapi_freq_flags[i]) == 0) - { - freq_flag = (wapi_freq_flag_t)i; - found = true; - break; - } - } - - if (!found) - { - WAPI_ERROR("ERROR: Invalid frequency flag: %s\n", flagstr); - exit(EXIT_FAILURE); - } + freq_flag = (wapi_freq_flag_t)wapi_str2ndx(flagstr, g_wapi_freq_flags, + IW_FREQ_NFLAGS); /* Set the frequency */ @@ -466,28 +475,12 @@ static void wapi_essid_cmd(int sock, FAR const char *ifname, FAR const char *essid, FAR const char *flagstr) { wapi_essid_flag_t essid_flag; - bool found = false; int ret; - int i; /* Convert input strings to values */ - for (i = 0; i < 2; i++) - { - if (strcmp(flagstr, g_wapi_essid_flags[i]) == 0) - { - essid_flag = (wapi_essid_flag_t)i; - found = true; - break; - } - } - - if (!found) - { - WAPI_ERROR("ERROR: Invalid ESSID flag: %s\n", flagstr); - exit(EXIT_FAILURE); - } - + essid_flag = (wapi_essid_flag_t)wapi_str2ndx(flagstr, g_wapi_essid_flags, 2); + /* Set the ESSID */ ret = wapi_set_essid(sock, ifname, essid, essid_flag); @@ -512,27 +505,11 @@ static void wapi_mode_cmd(int sock, FAR const char *ifname, FAR const char *modestr) { wapi_mode_t mode; - bool found = false; int ret; - int i; /* Convert input strings to values */ - for (i = 0; i < IW_MODE_NFLAGS; i++) - { - if (strcmp(modestr, g_wapi_modes[i]) == 0) - { - mode = (wapi_mode_t)i; - found = true; - break; - } - } - - if (!found) - { - WAPI_ERROR("ERROR: Invalid operating mode: %s\n", modestr); - exit(EXIT_FAILURE); - } + mode = (wapi_mode_t)wapi_str2ndx(modestr, g_wapi_modes, IW_MODE_NFLAGS); /* Set operating mode */ @@ -592,30 +569,14 @@ static void wapi_bitrate_cmd(int sock, FAR const char *ifname, { wapi_bitrate_flag_t bitrate_flag; - bool found = false; int bitrate; int ret; - int i; /* Convert input strings to values */ - bitrate = wapi_str2int(ratestr); - - for (i = 0; i < 2; i++) - { - if (strcmp(flagstr, g_wapi_bitrate_flags[i]) == 0) - { - bitrate_flag = (wapi_bitrate_flag_t)i; - found = true; - break; - } - } - - if (!found) - { - WAPI_ERROR("ERROR: Invalid bitrate flag: %s\n", flagstr); - exit(EXIT_FAILURE); - } + bitrate = wapi_str2int(ratestr); + bitrate_flag = (wapi_bitrate_flag_t) + wapi_str2ndx(flagstr, g_wapi_bitrate_flags, 2); /* Set bitrate */ @@ -641,30 +602,14 @@ static void wapi_txpower_cmd(int sock, FAR const char *ifname, FAR const char *pwrstr, FAR const char *flagstr) { wapi_txpower_flag_t txpower_flag; - bool found = false; int txpower; int ret; - int i; /* Convert input strings to values */ - txpower = wapi_str2int(pwrstr); - - for (i = 0; i < IW_TXPOW_NFLAGS; i++) - { - if (strcmp(flagstr, g_wapi_txpower_flags[i]) == 0) - { - txpower_flag = (wapi_txpower_flag_t)i; - found = true; - break; - } - } - - if (!found) - { - WAPI_ERROR("ERROR: Invalid TX power flag: %s\n", flagstr); - exit(EXIT_FAILURE); - } + txpower = wapi_str2int(pwrstr); + txpower_flag = (wapi_txpower_flag_t) + wapi_str2ndx(flagstr, g_wapi_txpower_flags, IW_TXPOW_NFLAGS); /* Set txpower */ @@ -728,7 +673,7 @@ static void wapi_scan_cmd(int sock, FAR const char *ifname) for (info = list.head.scan; info; info = info->next) { - printf(">> %02x:%02x:%02x:%02x:%02x:%02x %s\n", + printf(" %02x:%02x:%02x:%02x:%02x:%02x %s\n", info->ap.ether_addr_octet[0], info->ap.ether_addr_octet[1], info->ap.ether_addr_octet[2], info->ap.ether_addr_octet[3], info->ap.ether_addr_octet[4], info->ap.ether_addr_octet[5], From 65d59f84582a002d862b879bd7f7286cc2bfcdf0 Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Wed, 12 Apr 2017 06:47:07 -0600 Subject: [PATCH 22/23] examples/ostest: clarify when pthread clean-up test mutex need to remain usable --- examples/ostest/pthread_cleanup.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/ostest/pthread_cleanup.c b/examples/ostest/pthread_cleanup.c index 54650823f..61c11f0f8 100644 --- a/examples/ostest/pthread_cleanup.c +++ b/examples/ostest/pthread_cleanup.c @@ -60,16 +60,20 @@ static void cleanup(FAR void * data) FAR struct sync_s *sync = (FAR struct sync_s *) data; int status; - /* Note: pthread_cond_wait() will release the mutex while it waits on - * condition value. So a EPERM error is not a failure. + /* Note: The behavior of canceling pthread_cond_wait() with asynchronous + * cancellation is not defined. On NuttX we get EPERM here, but application + * code must not rely on this. */ status = pthread_mutex_unlock(&sync->lock); +#ifndef CONFIG_CANCELLATION_POINTS if (status == EPERM) { printf("pthread_cleanup: thread did not have mutex locked: %d\n", status); + return; } - else if (status != 0) +#endif + if (status != 0) { printf("pthread_cleanup: ERROR pthread_mutex_unlock in cleanup handler. " "Status: %d\n", status); @@ -138,6 +142,7 @@ static void test_cleanup(void) printf("pthread_cleanup: ERROR pthread_join returned wrong result: %p\n", result); } +#ifdef CONFIG_CANCELLATION_POINTS /* Do some operations on lock in order to check if it is in usable state. */ status = pthread_mutex_trylock(&sync.lock); @@ -151,6 +156,7 @@ static void test_cleanup(void) { printf("pthread_cleanup: ERROR pthread_mutex_unlock, status=%d\n", status); } +#endif } /**************************************************************************** From 58da85523dcc3aa005400283fcd18db379a7d5cc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 12 Apr 2017 07:09:37 -0600 Subject: [PATCH 23/23] wireless/wapi: Improve some output. --- wireless/wapi/src/util.h | 83 +++++++++++++++++++++++++++++++--------- wireless/wapi/src/wapi.c | 10 ++++- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/wireless/wapi/src/util.h b/wireless/wapi/src/util.h index 50de0b6eb..e7c304f7f 100644 --- a/wireless/wapi/src/util.h +++ b/wireless/wapi/src/util.h @@ -47,29 +47,74 @@ * Pre-processor Definitions ****************************************************************************/ -#define WAPI_IOCTL_STRERROR(cmd) \ - fprintf( \ - stderr, "%s:%d:%s():ioctl(%s): %s\n", \ - __FILE__, __LINE__, __func__, \ - wapi_ioctl_command_name(cmd), strerror(errno)) +#ifdef DEBUG_WIRELESS_ERROR +# ifdef CONFIG_LIBC_STRERROR +# define WAPI_IOCTL_STRERROR(cmd) \ + fprintf( \ + stderr, "%s:%d:%s():ioctl(%s): %s\n", \ + __FILE__, __LINE__, __func__, \ + wapi_ioctl_command_name(cmd), strerror(errno)) -#define WAPI_STRERROR(fmt, ...) \ - fprintf( \ - stderr, "%s:%d:%s():" fmt ": %s\n", \ - __FILE__, __LINE__, __func__, \ - ## __VA_ARGS__, strerror(errno)) +# define WAPI_STRERROR(fmt, ...) \ + fprintf( \ + stderr, "%s:%d:%s():" fmt ": %s\n", \ + __FILE__, __LINE__, __func__, \ + ## __VA_ARGS__, strerror(errno)) +# else +# define WAPI_IOCTL_STRERROR(cmd) \ + fprintf( \ + stderr, "%s:%d:%s():ioctl(%s): %d\n", \ + __FILE__, __LINE__, __func__, \ + wapi_ioctl_command_name(cmd), errno) -#define WAPI_ERROR(fmt, ...) \ - fprintf( \ - stderr, "%s:%d:%s(): " fmt , \ - __FILE__, __LINE__, __func__, ## __VA_ARGS__) +# define WAPI_STRERROR(fmt, ...) \ + fprintf( \ + stderr, "%s:%d:%s():" fmt ": %d\n", \ + __FILE__, __LINE__, __func__, \ + ## __VA_ARGS__, errno) +# endif + +# define WAPI_ERROR(fmt, ...) \ + fprintf( \ + stderr, "%s:%d:%s(): " fmt , \ + __FILE__, __LINE__, __func__, ## __VA_ARGS__) + +#else +# ifdef CONFIG_LIBC_STRERROR +# define WAPI_IOCTL_STRERROR(cmd) \ + fprintf( \ + stderr, "ioctl(%s): %s\n", \ + wapi_ioctl_command_name(cmd), strerror(errno)) + +# define WAPI_STRERROR(fmt, ...) \ + fprintf( \ + stderr, fmt ": %s\n", \ + ## __VA_ARGS__, strerror(errno)) +# else +# define WAPI_IOCTL_STRERROR(cmd) \ + fprintf( \ + stderr, "ioctl(%s): %d\n", \ + wapi_ioctl_command_name(cmd), errno) + +# define WAPI_STRERROR(fmt, ...) \ + fprintf( \ + stderr, fmt ": %d\n", \ + ## __VA_ARGS__, errno) +# endif + +# define WAPI_ERROR(fmt, ...) \ + fprintf( \ + stderr, fmt , \ + ## __VA_ARGS__) + +#endif #define WAPI_VALIDATE_PTR(ptr) \ - if (!ptr) \ - { \ - WAPI_ERROR("Null pointer: %s.\n", #ptr); \ - return -1; \ - } + if (ptr == NULL) \ + { \ + WAPI_ERROR("Null pointer: %p\n", ptr); \ + return -EINVAL; \ + } /**************************************************************************** * Public Function Prototypes diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c index 60f00a3b9..a5f53c2d2 100644 --- a/wireless/wapi/src/wapi.c +++ b/wireless/wapi/src/wapi.c @@ -76,6 +76,8 @@ typedef void (*cmd3_t)(int sock, FAR const char *arg1, static int wapi_str2int(FAR const char *str); static double wapi_str2double(FAR const char *str); +static unsigned int wapi_str2ndx(FAR const char *name, FAR const char **list, + unsigned int listlen); static void wapi_show_cmd(int sock, FAR const char *ifname); static void wapi_ip_cmd(int sock, FAR const char *ifname, @@ -196,7 +198,13 @@ static unsigned int wapi_str2ndx(FAR const char *name, FAR const char **list, } } - WAPI_ERROR("ERROR: Invalid string: %s\n", name); + WAPI_ERROR("ERROR: Invalid option string: %s\n", name); + WAPI_ERROR(" Valid options include:\n"); + for (ndx = 0; ndx < listlen; ndx++) + { + WAPI_ERROR(" - %s\n", list[ndx]); + } + exit(EXIT_FAILURE); }