Merged nuttx/apps into master

This commit is contained in:
Masayuki Ishikawa 2017-04-14 14:00:00 +09:00
commit 75e149c43d
31 changed files with 4708 additions and 40 deletions

View File

@ -71,19 +71,25 @@ 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

View File

@ -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,6 +216,18 @@ void sporadic_test(void);
void tls_test(void);
/* 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);

View File

@ -424,15 +424,31 @@ static int user_main(int argc, char *argv[])
cond_test();
check_test_memory_usage();
#endif
/* Verify pthreads rwlock interfaces */
printf("\nuser_main: pthread_rwlock test\n");
pthread_rwlock_test();
check_test_memory_usage();
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
#ifndef CONFIG_DISABLE_PTHREAD
/* 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 */

View File

@ -0,0 +1,170 @@
/****************************************************************************
* examples/ostest/pthread_cleanup.c
*
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
* Author: Juha Niskanen <juha.niskanen@haltian.com>
*
* 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 <pthread.h>
#include <stdio.h>
#include <errno.h>
/****************************************************************************
* 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;
/* 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;
}
#endif
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);
}
#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);
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);
}
#endif
}
/****************************************************************************
* Public Functions
****************************************************************************/
void pthread_cleanup_test(void)
{
printf("pthread_cleanup: Starting test\n");
test_cleanup();
}

View File

@ -0,0 +1,448 @@
/****************************************************************************
* examples/ostest/pthread_rwlock.c
*
* Copyright (C) 2017 Mark Schulte. All rights reserved.
* Author: Mark Schulte <mark@mjs.pw>
*
* 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 <pthread.h>
#include <stdio.h>
#include <errno.h>
/****************************************************************************
* Private Types
****************************************************************************/
struct race_cond_s
{
sem_t * sem1;
sem_t * sem2;
pthread_rwlock_t *rw_lock;
};
/****************************************************************************
* Private Data
****************************************************************************/
static int g_race_cond_thread_pos;
/****************************************************************************
* 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 */
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)
{
printf("pthread_rwlock: Failed to lock for writing\n");
}
sem_post(rc->sem2);
sem_wait(rc->sem1);
/* 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)
{
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 */
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;
}
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);
}
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)
{
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);
}
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)
{
printf("pthread_rwlock: Failed to unlock lock held for writing\n");
}
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;
}
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;
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
****************************************************************************/
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 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 write 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();
test_timeout();
}

View File

@ -0,0 +1,252 @@
/****************************************************************************
* examples/ostest/pthread_rwlock_cancel.c
*
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
* Author: Juha Niskanen <juha.niskanen@haltian.com>
*
* 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 <pthread.h>
#include <stdio.h>
#include <errno.h>
/****************************************************************************
* 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();
}

View File

@ -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;

View File

@ -114,10 +114,11 @@ 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);
bool netlib_nodeaddrconv(FAR const char *hwstr, FAR uint8_t *hw);
#endif
/* IP address support */

586
include/wireless/wapi.h Normal file
View File

@ -0,0 +1,586 @@
/****************************************************************************
* apps/include/wireless/wapi.h
*
* Copyright (C) 2011, 2017Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for Nuttx from WAPI:
*
* Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
* 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 <netinet/in.h>
#include <sys/socket.h>
#include <net/ethernet.h>
#include <nuttx/wireless/wireless.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Maximum allowed ESSID size. */
#define WAPI_ESSID_MAX_SIZE IW_ESSID_MAX_SIZE
/* 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_MESH = IW_MODE_MESH /* Mesh (IEEE 802.11s) network */
} 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_add_route_gw
*
* Description:
* Adds gateway for the given target network.
*
****************************************************************************/
#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
*
* Description:
* Deletes gateway for the given target network.
*
****************************************************************************/
#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_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, FAR const 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_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_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 */

View File

@ -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

View File

@ -0,0 +1,109 @@
/****************************************************************************
* netutils/netlib/netlib_nodeaddrconv.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <nuttx/net/sixlowpan.h>
#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;
}

View File

@ -49,6 +49,8 @@
#include <netinet/in.h>
#include <net/if.h>
#include <nuttx/net/sixlowpan.h>
#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 */

View File

@ -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.
*/

View File

@ -316,15 +316,22 @@ 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;
int op;
#ifndef CONFIG_DISABLE_ENVIRON
/* Support set [{+|-}{e|x|xe|ex}] [<name> <value>] */
if (argc == 2 || argc == 4)
#else
/* Support set [{+|-}{e|x|xe|ex}] */
#endif
{
if (strlen(argv[1]) < 2)
{
@ -362,17 +369,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 */

View File

@ -79,6 +79,10 @@
#include <nuttx/net/icmp.h>
#include <nuttx/net/icmpv6.h>
#ifdef CONFIG_NET_6LOWPAN
#include <nuttx/net/sixlowpan.h>
#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];
}

View File

@ -72,6 +72,10 @@
# include "netutils/dhcpc.h"
#endif
#ifdef CONFIG_NET_6LOWPAN
# include <nuttx/net/sixlowpan.h>
#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 */

2
wireless/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/Kconfig

37
wireless/Make.defs Normal file
View File

@ -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 <gnutt@nuttx.org>
#
# 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)

38
wireless/Makefile Normal file
View File

@ -0,0 +1,38 @@
############################################################################
# apps/wireless/Makefile
#
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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

6
wireless/wapi/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/.built
/.depend
/Make.dep
/*.src
/*.obj
/*.lst

40
wireless/wapi/Kconfig Normal file
View File

@ -0,0 +1,40 @@
#
# 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 "IEEE802.11 Configuration Library"
default n
depends on NET && DRIVERS_WIRELESS && EXPERIMENTAL
---help---
Wapi is a tool by Volkan YAZICI <volkan.yazici@gmail.com> that can
be used to manage 802.11 network.
if WIRELESS_WAPI
config WIRELESS_WAPI_CMDTOOL
bool "IEEE802.11 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_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

23
wireless/wapi/LICENSE Normal file
View File

@ -0,0 +1,23 @@
Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
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.

40
wireless/wapi/Make.defs Normal file
View File

@ -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 <gnutt@nuttx.org>
#
# 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

149
wireless/wapi/Makefile Normal file
View File

@ -0,0 +1,149 @@
############################################################################
# apps/wireless/wapi/Makefile
#
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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
# IEEE802.11 Wapi Application
CONFIG_WIRELESS_WAPI_PRIORITY ?= 100
CONFIG_WIRELESS_WAPI_STACKSIZE ?= 2048
APPNAME = wapi
PRIORITY = $(CONFIG_WIRELESS_WAPI_PRIORITY)
STACKSIZE = $(CONFIG_WIRELESS_WAPI_STACKSIZE)
ASRCS =
CSRCS =
MAINSRC =
VPATH = .
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 ?= wapi$(EXEEXT)
PROGNAME = $(CONFIG_WAPI_PROGNAME)
ROOTDEPPATH = --dep-path .
# Common build
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),$(APPNAME)_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:

42
wireless/wapi/README Normal file
View File

@ -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 <volkan.yazici@gmail.com>
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.

View File

@ -0,0 +1,49 @@
############################################################################
# apps/wireless/src/Make.defs
#
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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)/wireless/wapi/src}
endif

329
wireless/wapi/src/network.c Normal file
View File

@ -0,0 +1,329 @@
/****************************************************************************
* apps/wireless/wapi/examples/network.c
*
* Copyright (C) 2011, 2017Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for Nuttx from WAPI:
*
* Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
* 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 <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/route.h>
#include <netinet/in.h>
#include "util.h"
#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, (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));
}
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, (unsigned long)((uintptr_t)&ifr))) < 0)
{
WAPI_IOCTL_STRERROR(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,
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, (unsigned long)((uintptr_t)&rt))) < 0)
{
WAPI_IOCTL_STRERROR(act);
}
return ret;
}
#endif
/****************************************************************************
* 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, (unsigned long)((uintptr_t)&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, (unsigned long)((uintptr_t)&ifr))) >= 0)
{
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
ret = ioctl(sock, SIOCSIFFLAGS, (unsigned long)((uintptr_t)&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, (unsigned long)((uintptr_t)&ifr))) >= 0)
{
ifr.ifr_flags &= ~IFF_UP;
ret = ioctl(sock, SIOCSIFFLAGS, (unsigned long)((uintptr_t)&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_add_route_gw
*
* Description:
* Adds gateway for the given target network.
*
****************************************************************************/
#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)
{
return wapi_act_route_gw(sock, SIOCADDRT, targettype, target, netmask, gw);
}
#endif
/****************************************************************************
* Name: wapi_del_route_gw
*
* Description:
* Deletes gateway for the given target network.
*
****************************************************************************/
#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)
{
return wapi_act_route_gw(sock, SIOCDELRT, targettype, target, netmask, gw);
}
#endif

182
wireless/wapi/src/util.c Normal file
View File

@ -0,0 +1,182 @@
/****************************************************************************
* apps/wireless/wapi/src/util.c
*
* Copyright (C) 2011, 2017Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for Nuttx from WAPI:
*
* Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
* 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 <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include "wireless/wapi.h"
#include "util.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* 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
****************************************************************************/
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(PF_INETX, SOCK_WAPI, 0);
}
/****************************************************************************
* Name: wapi_ioctl_command_name
*
* 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;
}
}

125
wireless/wapi/src/util.h Normal file
View File

@ -0,0 +1,125 @@
/****************************************************************************
* apps/wireless/wapi/src/util.h
*
* Copyright (C) 2011, 2017Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for Nuttx from WAPI:
*
* Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
* 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 <string.h>
#include <errno.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#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))
# 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_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 == NULL) \
{ \
WAPI_ERROR("Null pointer: %p\n", ptr); \
return -EINVAL; \
}
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR const char *wapi_ioctl_command_name(int cmd);
#endif /* __APPS_WIRELESS_WAPI_SRC_UTIL_H */

863
wireless/wapi/src/wapi.c Normal file
View File

@ -0,0 +1,863 @@
/****************************************************************************
* apps/wireless/wapi/src/wapi.c
*
* Copyright (C) 2011, 2017Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Largely and original work, but highly influenced by sampled code provided
* with WAPI:
*
* Copyright (c) 2010, Volkan YAZICI <volkan.yazici@gmail.com>
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "wireless/wapi.h"
#include "util.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 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,
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", 3, (CODE void *)wapi_txpower_cmd},
};
#define NCOMMANDS (sizeof(g_wapi_commands) / sizeof(struct wapi_command_s))
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* 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')
{
WAPI_ERROR("ERROR: Garbage after numeric argument\n");
exit(EXIT_FAILURE);
}
if (value > INT_MAX || value < INT_MIN)
{
WAPI_ERROR("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')
{
WAPI_ERROR("ERROR: Garbage after numeric argument\n");
exit(EXIT_FAILURE);
}
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 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);
}
/****************************************************************************
* Name: wapi_show_cmd
*
* 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 wapi_show_cmd(int sock, FAR const char *ifname)
{
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);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_ip() failed: %d\n", ret);
}
else
{
printf(" IP: %s\n", inet_ntoa(addr));
}
/* Get netmask */
bzero(&addr, sizeof(struct in_addr));
ret = wapi_get_netmask(sock, ifname, &addr);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_netmask() failed: %d\n", ret);
}
else
{
printf(" NetMask: %s", inet_ntoa(addr));
}
/* Get frequency */
ret = wapi_get_freq(sock, ifname, &freq, &freq_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_freq() failed: %d\n", ret);
}
else
{
double tmpfreq;
int chan;
printf("Frequency: %g\n", freq);
printf(" Flag: %s\n", g_wapi_freq_flags[freq_flag]);
ret = wapi_freq2chan(sock, ifname, freq, &chan);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_freq2chan() failed: %d\n", ret);
}
else
{
printf(" Channel: %d\n", chan);
}
ret = wapi_chan2freq(sock, ifname, chan, &tmpfreq);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_chan2freq() failed: %d\n", ret);
}
else
{
printf("Frequency: %g\n", tmpfreq);
}
}
/* Get the ESSID */
ret = wapi_get_essid(sock, ifname, essid, &essid_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_essid() failed: %d\n", ret);
}
else
{
printf(" ESSID: %s\n", essid);
printf(" Flag: %s\n", g_wapi_essid_flags[essid_flag]);
}
/* Get operating mode */
ret = wapi_get_mode(sock, ifname, &mode);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_mode() failed: %d\n", ret);
}
else
{
printf(" Mode: %s", g_wapi_modes[mode]);
}
/* Get AP */
ret = wapi_get_ap(sock, ifname, &ap);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_ap() failed: %d\n", ret);
}
else
{
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]);
}
/* Get bitrate */
ret = wapi_get_bitrate(sock, ifname, &bitrate, &bitrate_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_bitrate() failed: %d\n", ret);
}
else
{
printf(" BitRate: %d\n", bitrate);
printf(" Flag: %s\n", g_wapi_bitrate_flags[bitrate_flag]);
}
/* Get txpower */
ret = wapi_get_txpower(sock, ifname, &txpower, &txpower_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_get_txpower() failed: %d\n", ret);
}
else
{
printf(" TxPower: %d\n", txpower);
printf(" Flag: %s\n", g_wapi_txpower_flags[txpower_flag]);
}
}
/****************************************************************************
* Name: wapi_ip_cmd
*
* Description:
* Set the IP address.
*
* Returned Value:
* None
*
****************************************************************************/
static void wapi_ip_cmd(int sock, FAR const char *ifname,
FAR const char *addrstr)
{
struct in_addr addr;
int ret;
/* Format the request */
addr.s_addr = inet_addr(addrstr);
/* Set the IP address */
ret = wapi_set_ip(sock, ifname, &addr);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_set_ip() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_mask_cmd
*
* Description:
* Set the network mask
*
* Returned Value:
* None
*
****************************************************************************/
static void wapi_mask_cmd(int sock, FAR const char *ifname,
FAR const char *maskstr)
{
struct in_addr addr;
int ret;
/* Format the request */
addr.s_addr = inet_addr(maskstr);
/* Set the network mask */
ret = wapi_set_netmask(sock, ifname, &addr);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_set_netmask() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_freq_cmd
*
* Description:
* Set the frequency
*
* Returned Value:
* None
*
****************************************************************************/
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;
int ret;
/* Convert input strings to values */
frequency = wapi_str2double(freqstr);
freq_flag = (wapi_freq_flag_t)wapi_str2ndx(flagstr, g_wapi_freq_flags,
IW_FREQ_NFLAGS);
/* Set the frequency */
ret = wapi_set_freq(sock, ifname, frequency, freq_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: \nwapi_set_freq() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_essid_cmd
*
* Description:
* Set the ESSID
*
* Returned Value:
* None
*
****************************************************************************/
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;
int ret;
/* Convert input strings to values */
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);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_set_essid() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_mode_cmd
*
* Description:
* Set the operating mode
*
* Returned Value:
* None
*
****************************************************************************/
static void wapi_mode_cmd(int sock, FAR const char *ifname,
FAR const char *modestr)
{
wapi_mode_t mode;
int ret;
/* Convert input strings to values */
mode = (wapi_mode_t)wapi_str2ndx(modestr, g_wapi_modes, IW_MODE_NFLAGS);
/* Set operating mode */
ret = wapi_set_mode(sock, ifname, mode);
if (ret < 0)
{
WAPI_ERROR("ERROR: \nwapi_set_mode() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_ap_cmd
*
* Description:
* Set the AP
*
* Returned Value:
* None
*
****************************************************************************/
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);
if (ret < 0)
{
WAPI_ERROR("ERROR: \nwapi_set_ap() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_bitrate_cmd
*
* Description:
* Set the bit rate
*
* Returned Value:
* None
*
****************************************************************************/
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;
int bitrate;
int ret;
/* Convert input strings to values */
bitrate = wapi_str2int(ratestr);
bitrate_flag = (wapi_bitrate_flag_t)
wapi_str2ndx(flagstr, g_wapi_bitrate_flags, 2);
/* Set bitrate */
ret = wapi_set_bitrate(sock, ifname, bitrate, bitrate_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: \nwapi_set_bitrate() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_txpower_cmd
*
* Description:
* Set the TX power
*
* Returned Value:
* None
*
****************************************************************************/
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;
int txpower;
int ret;
/* Convert input strings to values */
txpower = wapi_str2int(pwrstr);
txpower_flag = (wapi_txpower_flag_t)
wapi_str2ndx(flagstr, g_wapi_txpower_flags, IW_TXPOW_NFLAGS);
/* Set txpower */
ret = wapi_set_txpower(sock, ifname, txpower, txpower_flag);
if (ret < 0)
{
WAPI_ERROR("ERROR: \nwapi_set_txpower() failed: %d\n", ret);
}
}
/****************************************************************************
* Name: wapi_scan_cmd
*
* Description:
* Scans available APs in the range using given ifname interface.
*
* Returned Value:
* None
*
****************************************************************************/
static void wapi_scan_cmd(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);
WAPI_ERROR("ERROR: wapi_scan_init() failed: %d\n", ret);
/* Wait for completion */
do
{
sleep(sleepdur);
ret = wapi_scan_stat(sock, ifname);
WAPI_ERROR("ERROR: wapi_scan_stat() failed: %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);
if (ret < 0)
{
WAPI_ERROR("ERROR: wapi_scan_coll() failed: %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;
}
}
/****************************************************************************
* Name: wapi_showusage
*
* Description:
* Show program usage.
*
* Returned Value:
* None
*
****************************************************************************/
static void wapi_showusage(FAR const char *progname, int exitcode)
{
int i;
fprintf(stderr, "Usage: %s show <ifname>\n", progname);
fprintf(stderr, " %s scan <ifname>\n", progname);
fprintf(stderr, " %s ip <ifname> <IP address>\n", progname);
fprintf(stderr, " %s mask <ifname> <mask>\n", progname);
fprintf(stderr, " %s freq <ifname> <frequency> <flag>\n", progname);
fprintf(stderr, " %s essid <ifname> <essid> <flag>\n", progname);
fprintf(stderr, " %s mode <ifname> <ifname> <mode>\n", progname);
fprintf(stderr, " %s ap <ifname> <ifname> <MAC address>\n", progname);
fprintf(stderr, " %s bitrate <ifname> <bitrate> <flag>\n", progname);
fprintf(stderr, " %s txpower <ifname> <txpower> <flag>\n", progname);
fprintf(stderr, " %s help\n", progname);
fprintf(stderr, "\nFrequency Flags:\n");
for (i = 0; i < IW_FREQ_NFLAGS; i++)
{
fprintf(stderr, " %s\n", g_wapi_freq_flags[i]);
}
fprintf(stderr, "\nESSID Flags:\n");
for (i = 0; i < 2; 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\n", g_wapi_modes[i]);
}
fprintf(stderr, "\nBitrate Flags:\n");
for (i = 0; i < 2; i++)
{
fprintf(stderr, " %s\n", g_wapi_bitrate_flags[i]);
}
fprintf(stderr, "\nTX power Flags:\n");
for (i = 0; i < IW_TXPOW_NFLAGS; i++)
{
fprintf(stderr, " %s\n", g_wapi_txpower_flags[i]);
}
exit(exitcode);
}
/****************************************************************************
* 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 *cmdname;
FAR const struct wapi_command_s *wapicmd;
int sock;
int i;
/* Get the command */
if (argc < 2)
{
WAPI_ERROR("ERROR: Missing command\n");
wapi_showusage(argv[0], EXIT_FAILURE);
}
cmdname = argv[1];
/* 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)
{
WAPI_ERROR("ERROR: Unsupported command: %s\n", cmdname);
wapi_showusage(argv[0], EXIT_FAILURE);
}
if (wapicmd->noptions + 2 < argc)
{
WAPI_ERROR("ERROR: Garbage at end of command ignored\n");
}
else if (wapicmd->noptions + 2 > argc)
{
WAPI_ERROR("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)
{
WAPI_ERROR("ERROR: wapi_make_socket() failed: %d\n", sock);
return EXIT_FAILURE;
}
/* Dispatch the command handling */
switch (wapicmd->noptions)
{
default:
case 0:
WAPI_ERROR("ERROR: Internal craziness\n");
wapi_showusage(argv[0], EXIT_FAILURE);
case 1:
((cmd1_t)wapicmd->handler)(sock, argv[2]);
break;
case 2:
((cmd2_t)wapicmd->handler)(sock, argv[2], argv[3]);
break;
case 3:
((cmd3_t)wapicmd->handler)(sock, argv[2], argv[3], argv[4]);
break;
}
/* Close communication socket */
close(sock);
return EXIT_SUCCESS;
}

1109
wireless/wapi/src/wireless.c Normal file

File diff suppressed because it is too large Load Diff