diff options
Diffstat (limited to 'package/nvram/src')
-rw-r--r-- | package/nvram/src/Makefile | 6 | ||||
-rw-r--r-- | package/nvram/src/bcmtimer.h | 42 | ||||
-rw-r--r-- | package/nvram/src/linux_timer.c | 738 | ||||
-rw-r--r-- | package/nvram/src/shutils.c | 329 | ||||
-rw-r--r-- | package/nvram/src/wl.c | 356 |
5 files changed, 1 insertions, 1470 deletions
diff --git a/package/nvram/src/Makefile b/package/nvram/src/Makefile index 54c089b44a..e882d58ea0 100644 --- a/package/nvram/src/Makefile +++ b/package/nvram/src/Makefile @@ -1,16 +1,12 @@ # $Id$ -LIBSHARED_OBJS := shutils.o wl.o linux_timer.o LIBNVRAM_OBJS := nvram.o -all: libshared.so libnvram.so nvram +all: libnvram.so nvram %.o: %.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -I. -Iinclude -o $@ $^ -libshared.so: $(LIBSHARED_OBJS) - $(CC) -shared -o $@ $^ - libnvram.so: $(LIBNVRAM_OBJS) $(CC) -shared -o $@ $^ diff --git a/package/nvram/src/bcmtimer.h b/package/nvram/src/bcmtimer.h deleted file mode 100644 index 3db9e624f9..0000000000 --- a/package/nvram/src/bcmtimer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * Low resolution timer interface. Timer handlers may be called - * in a deferred manner in a different task context after the - * timer expires or in the task context from which the timer - * was created, depending on the implementation. - * - * $Id$ - */ -#ifndef __bcmtimer_h__ -#define __bcmtimer_h__ - -/* ANSI headers */ -#include <time.h> - -/* timer ID */ -typedef unsigned int bcm_timer_module_id; -typedef unsigned int bcm_timer_id; - -/* timer callback */ -typedef void (*bcm_timer_cb)(bcm_timer_id id, int data); - -/* OS-independant interfaces, applications should call these functions only */ -int bcm_timer_module_init(int timer_entries, bcm_timer_module_id *module_id); -int bcm_timer_module_cleanup(bcm_timer_module_id module_id); -int bcm_timer_module_enable(bcm_timer_module_id module_id, int enable); -int bcm_timer_create(bcm_timer_module_id module_id, bcm_timer_id *timer_id); -int bcm_timer_delete(bcm_timer_id timer_id); -int bcm_timer_gettime(bcm_timer_id timer_id, struct itimerspec *value); -int bcm_timer_settime(bcm_timer_id timer_id, const struct itimerspec *value); -int bcm_timer_connect(bcm_timer_id timer_id, bcm_timer_cb func, int data); -int bcm_timer_cancel(bcm_timer_id timer_id); -int bcm_timer_change_expirytime(bcm_timer_id timer_id, const struct itimerspec *timer_spec); - -#endif /* #ifndef __bcmtimer_h__ */ diff --git a/package/nvram/src/linux_timer.c b/package/nvram/src/linux_timer.c deleted file mode 100644 index 0402e44378..0000000000 --- a/package/nvram/src/linux_timer.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * Low resolution timer interface linux specific implementation. - * - * $Id$ - */ - -/* -* debug facilities -*/ -#define TIMER_DEBUG 0 -#if TIMER_DEBUG -#define TIMERDBG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args) -#else -#define TIMERDBG(fmt, args...) -#endif - - -/* - * POSIX timer support for Linux. Taken from linux_timer.c in upnp - */ - -#define __USE_GNU - - -#include <stdlib.h> // for malloc, free, etc. -#include <string.h> // for memset, strncasecmp, etc. -#include <assert.h> // for assert, of course. -#include <signal.h> // for sigemptyset, etc. -#include <stdio.h> // for printf, etc. -#include <sys/time.h> -#include <time.h> - -/* define TIMER_PROFILE to enable code which guages how accurate the timer functions are. - For each expiring timer the code will print the expected time interval and the actual time interval. -#define TIMER_PROFILE -*/ -#undef TIMER_PROFILE - -/* -timer_cancel( ) - cancel a timer -timer_connect( ) - connect a user routine to the timer signal -timer_create( ) - allocate a timer using the specified clock for a timing base (POSIX) -timer_delete( ) - remove a previously created timer (POSIX) -timer_gettime( ) - get the remaining time before expiration and the reload value (POSIX) -timer_getoverrun( ) - return the timer expiration overrun (POSIX) -timer_settime( ) - set the time until the next expiration and arm timer (POSIX) -nanosleep( ) - suspend the current task until the time interval elapses (POSIX) -*/ - -#define MS_PER_SEC 1000 -#define US_PER_SEC 1000000 -#define US_PER_MS 1000 -#define UCLOCKS_PER_SEC 1000000 - -typedef void (*event_callback_t)(timer_t, int); - -#ifndef TIMESPEC_TO_TIMEVAL -# define TIMESPEC_TO_TIMEVAL(tv, ts) { \ - (tv)->tv_sec = (ts)->tv_sec; \ - (tv)->tv_usec = (ts)->tv_nsec / 1000; \ -} -#endif - -#ifndef TIMEVAL_TO_TIMESPEC -# define TIMEVAL_TO_TIMESPEC(tv, ts) { \ - (ts)->tv_sec = (tv)->tv_sec; \ - (ts)->tv_nsec = (tv)->tv_usec * 1000; \ -} -#endif - -#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) - -#define timerroundup(t,g) \ - do { \ - if (!timerisset(t)) (t)->tv_usec=1; \ - if ((t)->tv_sec == 0) (t)->tv_usec=ROUNDUP((t)->tv_usec, g); \ - } while (0) - -typedef long uclock_t; - -#define TFLAG_NONE 0 -#define TFLAG_CANCELLED (1<<0) -#define TFLAG_DELETED (1<<1) - -struct event { - struct timeval it_interval; - struct timeval it_value; - event_callback_t func; - int arg; - unsigned short flags; - struct event *next; -#ifdef TIMER_PROFILE - uint expected_ms; - uclock_t start; -#endif -}; - -void timer_cancel(timer_t timerid); - -static void alarm_handler(int i); -static void check_event_queue(); -static void print_event_queue(); -static void check_timer(); -#if THIS_FINDS_USE -static int count_queue(struct event *); -#endif -static int timer_change_settime(timer_t timer_id, const struct itimerspec *timer_spec); -void block_timer(); -void unblock_timer(); - -static struct event *event_queue = NULL; -static struct event *event_freelist; -static uint g_granularity; -static int g_maxevents = 0; - -uclock_t uclock() -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - return ((tv.tv_sec * US_PER_SEC) + tv.tv_usec); -} - - -void init_event_queue(int n) -{ - int i; - struct itimerval tv; - - g_maxevents = n; - event_freelist = (struct event *) malloc(n * sizeof(struct event)); - memset(event_freelist, 0, n * sizeof(struct event)); - - for (i = 0; i < (n-1); i++) - event_freelist[i].next = &event_freelist[i+1]; - - event_freelist[i].next = NULL; - - tv.it_interval.tv_sec = 0; - tv.it_interval.tv_usec = 1; - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = 0; - setitimer (ITIMER_REAL, &tv, 0); - setitimer (ITIMER_REAL, 0, &tv); - g_granularity = tv.it_interval.tv_usec; - - signal(SIGALRM, alarm_handler); -} - - -int clock_gettime( - clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */ - struct timespec * tp /* where to store current time */ -) -{ - struct timeval tv; - int n; - - - n = gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, tp); - - return n; -} - - -int timer_create( - clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */ - struct sigevent * evp, /* user event handler */ - timer_t * pTimer /* ptr to return value */ -) -{ - struct event *event; - - if (clock_id != CLOCK_REALTIME) { - TIMERDBG("timer_create can only support clock id CLOCK_REALTIME"); - exit(1); - } - - if (evp != NULL) { - if (evp->sigev_notify != SIGEV_SIGNAL || evp->sigev_signo != SIGALRM) { - TIMERDBG("timer_create can only support signalled alarms using SIGALRM"); - exit(1); - } - } - - event = event_freelist; - if (event == NULL) { - print_event_queue(); - } - assert(event != NULL); - - event->flags = TFLAG_NONE; - - event_freelist = event->next; - event->next = NULL; - - check_event_queue(); - - *pTimer = (timer_t) event; - - return 0; -} - -int timer_delete( - timer_t timerid /* timer ID */ -) -{ - struct event *event = (struct event *) timerid; - - if (event->flags & TFLAG_DELETED) { - TIMERDBG("Cannot delete a deleted event"); - return 1; - } - - timer_cancel(timerid); - - event->flags |= TFLAG_DELETED; - - event->next = event_freelist; - event_freelist = event; - - return 0; -} - -int timer_connect -( - timer_t timerid, /* timer ID */ - void (*routine)(timer_t, int), /* user routine */ - int arg /* user argument */ -) -{ - struct event *event = (struct event *) timerid; - - assert(routine != NULL); - event->func = routine; - event->arg = arg; - - return 0; -} - -/* - * Please Call this function only from the call back functions of the alarm_handler. - * This is just a hack -*/ -int timer_change_settime -( - timer_t timerid, /* timer ID */ - const struct itimerspec * value /* time to be set */ -) -{ - struct event *event = (struct event *) timerid; - - TIMESPEC_TO_TIMEVAL(&event->it_interval, &value->it_interval); - TIMESPEC_TO_TIMEVAL(&event->it_value, &value->it_value); - - return 1; -} - -int timer_settime -( - timer_t timerid, /* timer ID */ - int flags, /* absolute or relative */ - const struct itimerspec * value, /* time to be set */ - struct itimerspec * ovalue /* previous time set (NULL=no result) */ -) -{ - struct itimerval itimer; - struct event *event = (struct event *) timerid; - struct event **ppevent; - - TIMESPEC_TO_TIMEVAL(&event->it_interval, &value->it_interval); - TIMESPEC_TO_TIMEVAL(&event->it_value, &value->it_value); - - /* if .it_value is zero, the timer is disarmed */ - if (!timerisset(&event->it_value)) { - timer_cancel(timerid); - return 0; - } - - block_timer(); - -#ifdef TIMER_PROFILE - event->expected_ms = (event->it_value.tv_sec * MS_PER_SEC) + (event->it_value.tv_usec / US_PER_MS); - event->start = uclock(); -#endif - if (event->next) { - TIMERDBG("calling timer_settime with a timer that is already on the queue."); - } - - - /* We always want to make sure that the event at the head of the - queue has a timeout greater than the itimer granularity. - Otherwise we end up with the situation that the time remaining - on an itimer is greater than the time at the head of the queue - in the first place. */ - timerroundup(&event->it_value, g_granularity); - - timerclear(&itimer.it_value); - getitimer(ITIMER_REAL, &itimer); - if (timerisset(&itimer.it_value)) { - // reset the top timer to have an interval equal to the remaining interval - // when the timer was cancelled. - if (event_queue) { - if (timercmp(&(itimer.it_value), &(event_queue->it_value), >)) { - // it is an error if the amount of time remaining is more than the amount of time - // requested by the top event. - // - TIMERDBG("timer_settime: TIMER ERROR!"); - - } else { - // some portion of the top event has already expired. - // Reset the interval of the top event to remaining - // time left in that interval. - // - event_queue->it_value = itimer.it_value; - - // if we were the earliest timer before now, we are still the earliest timer now. - // we do not need to reorder the list. - } - } - } - - // Now, march down the list, decrementing the new timer by the - // current it_value of each event on the queue. - ppevent = &event_queue; - while (*ppevent) { - if ( timercmp(&(event->it_value), &((*ppevent)->it_value), <) ) { - // if the proposed event will trigger sooner than the next event - // in the queue, we will insert the new event just before the next one. - // - // we also need to adjust the delta value to the next event. - timersub(&((*ppevent)->it_value), &(event->it_value), &((*ppevent)->it_value)); - break; - } - // subtract the interval of the next event from the proposed interval. - timersub(&(event->it_value), &((*ppevent)->it_value), &(event->it_value)); - - ppevent = &((*ppevent)->next); - } - - // we have found our proper place in the queue, - // link our new event into the pending event queue. - event->next = *ppevent; - *ppevent = event; - - check_event_queue(); - - // if our new event ended up at the front of the queue, reissue the timer. - if (event == event_queue) { - timerroundup(&event_queue->it_value, g_granularity); - timerclear(&itimer.it_interval); - itimer.it_value = event_queue->it_value; - - // we want to be sure to never turn off the timer completely, - // so if the next interval is zero, set it to some small value. - if (!timerisset(&(itimer.it_value))) - itimer.it_value = (struct timeval) { 0, 1 }; - - assert(!timerisset(&itimer.it_interval)); - assert(itimer.it_value.tv_sec > 0 || itimer.it_value.tv_usec >= g_granularity); - assert(event_queue->it_value.tv_sec > 0 || event_queue->it_value.tv_usec >= g_granularity); - setitimer(ITIMER_REAL, &itimer, NULL); - check_timer(); - } - - event->flags &= ~TFLAG_CANCELLED; - - unblock_timer(); - - return 0; -} - -static void check_timer() -{ - struct itimerval itimer; - - getitimer(ITIMER_REAL, &itimer); - if (timerisset(&itimer.it_interval)) { - TIMERDBG("ERROR timer interval is set."); - } - if (timercmp(&(itimer.it_value), &(event_queue->it_value), >)) { - TIMERDBG("ERROR timer expires later than top event."); - } -} - - -static void check_event_queue() -{ - struct timeval sum; - struct event *event; - int i = 0; - -#ifdef notdef - int nfree = 0; - struct event *p; - for (p = event_freelist; p; p = p->next) - nfree++; - printf("%d free events\n", nfree); -#endif - - timerclear(&sum); - for (event = event_queue; event; event = event->next) { - if (i > g_maxevents) { - TIMERDBG("timer queue looks like it loops back on itself!"); - print_event_queue(); - exit(1); - } - i++; - } -} - -#if THIS_FINDS_USE -/* The original upnp version has this unused function, so I left it in - to maintain the resemblance. */ -static int count_queue(struct event *event_queue) -{ - struct event *event; - int i = 0; - for (event = event_queue; event; event = event->next) - i++; - return i; -} -#endif - -static void print_event_queue() -{ - struct event *event; - int i = 0; - - for (event = event_queue; event; event = event->next) { - printf("#%d (0x%x)->0x%x: \t%d sec %d usec\t%p\n", - i++, (unsigned int) event, (unsigned int) event->next, (int) event->it_value.tv_sec, (int) event->it_value.tv_usec, event->func); - if (i > g_maxevents) { - printf("...(giving up)\n"); - break; - } - } -} - -// The top element of the event queue must have expired. -// Remove that element, run its function, and reset the timer. -// if there is no interval, recycle the event structure. -static void alarm_handler(int i) -{ - struct event *event, **ppevent; - struct itimerval itimer; - struct timeval small_interval = { 0, g_granularity/2 }; -#ifdef TIMER_PROFILE - uint junk; - uclock_t end; - uint actual; -#endif - - block_timer(); - - // Loop through the event queue and remove the first event plus any - // subsequent events that will expire very soon thereafter (within 'small_interval'}. - // - do { - // remove the top event. - event = event_queue; - event_queue = event_queue->next; - event->next = NULL; - -#ifdef TIMER_PROFILE - end = uclock(); - actual = ((end-event->start)/((uclock_t)UCLOCKS_PER_SEC/1000)); - if (actual < 0) - junk = end; - TIMERDBG("expected %d ms actual %d ms", event->expected_ms, ((end-event->start)/((uclock_t)UCLOCKS_PER_SEC/1000))); -#endif - - // call the event callback function - (*(event->func))((timer_t) event, (int)event->arg); - - /* If the event has been cancelled, do NOT put it back on the queue. */ - if ( !(event->flags & TFLAG_CANCELLED) ) { - - // if the event is a recurring event, reset the timer and - // find its correct place in the sorted list of events. - // - if (timerisset(&event->it_interval)) { - // event is recurring... - // - event->it_value = event->it_interval; -#ifdef TIMER_PROFILE - event->expected_ms = (event->it_value.tv_sec * MS_PER_SEC) + (event->it_value.tv_usec / US_PER_MS); - event->start = uclock(); -#endif - timerroundup(&event->it_value, g_granularity); - - // Now, march down the list, decrementing the new timer by the - // current delta of each event on the queue. - ppevent = &event_queue; - while (*ppevent) { - if ( timercmp(&(event->it_value), &((*ppevent)->it_value), <) ) { - // if the proposed event will trigger sooner than the next event - // in the queue, we will insert the new event just before the next one. - // - // we also need to adjust the delta value to the next event. - timersub(&((*ppevent)->it_value), &(event->it_value), &((*ppevent)->it_value)); - break; - } - timersub(&(event->it_value), &((*ppevent)->it_value), &(event->it_value)); - ppevent = &((*ppevent)->next); - } - - // we have found our proper place in the queue, - // link our new event into the pending event queue. - event->next = *ppevent; - *ppevent = event; - } else { - // there is no interval, so recycle the event structure. - //timer_delete((timer_t) event); - } - } - - check_event_queue(); - - } while (event_queue && timercmp(&event_queue->it_value, &small_interval, <)); - - // re-issue the timer... - if (event_queue) { - timerroundup(&event_queue->it_value, g_granularity); - - timerclear(&itimer.it_interval); - itimer.it_value = event_queue->it_value; - // we want to be sure to never turn off the timer completely, - // so if the next interval is zero, set it to some small value. - if (!timerisset(&(itimer.it_value))) - itimer.it_value = (struct timeval) { 0, 1 }; - - setitimer(ITIMER_REAL, &itimer, NULL); - check_timer(); - } else { - TIMERDBG("There are no events in the queue - timer not reset."); - } - - unblock_timer(); -} - -static int block_count = 0; - -void block_timer() -{ - sigset_t set; - - if (block_count++ == 0) { - sigemptyset(&set); - sigaddset(&set, SIGALRM); - sigprocmask(SIG_BLOCK, &set, NULL); - } -} - -void unblock_timer() -{ - sigset_t set; - - if (--block_count == 0) { - sigemptyset(&set); - sigaddset(&set, SIGALRM); - sigprocmask(SIG_UNBLOCK, &set, NULL); - } -} - -void timer_cancel_all() -{ - struct itimerval timeroff = { { 0, 0 }, { 0, 0} }; - struct event *event; - struct event **ppevent; - - setitimer(ITIMER_REAL, &timeroff, NULL); - - ppevent = &event_queue; - while (*ppevent) { - event = *ppevent; - *ppevent = event->next; - event->next = NULL; - } -} - - - -void timer_cancel(timer_t timerid) -{ - struct itimerval itimer; - struct itimerval timeroff = { { 0, 0 }, { 0, 0} }; - struct event *event = (struct event *) timerid; - struct event **ppevent; - - if (event->flags & TFLAG_CANCELLED) { - TIMERDBG("Cannot cancel a cancelled event"); - return; - } - - block_timer(); - - ppevent = &event_queue; - while (*ppevent) { - if ( *ppevent == event ) { - - /* RACE CONDITION - if the alarm goes off while we are in - this loop, and if the timer we want to cancel is the - next to expire, the alarm will end up firing - after this routine is complete, causing it to go off early. */ - - /* If the cancelled timer is the next to expire, - we need to do something special to clean up correctly. */ - if (event == event_queue && event->next != NULL) { - timerclear(&itimer.it_value); - getitimer(ITIMER_REAL, &itimer); - - /* subtract the time that has already passed while waiting for this timer... */ - timersub(&(event->it_value), &(itimer.it_value), &(event->it_value)); - - /* and add any remainder to the next timer in the list */ - timeradd(&(event->next->it_value), &(event->it_value), &(event->next->it_value)); - } - - *ppevent = event->next; - event->next = NULL; - - if (event_queue) { - timerroundup(&event_queue->it_value, g_granularity); - timerclear(&itimer.it_interval); - itimer.it_value = event_queue->it_value; - - /* We want to be sure to never turn off the timer - completely if there are more events on the queue, - so if the next interval is zero, set it to some - small value. */ - - if (!timerisset(&(itimer.it_value))) - itimer.it_value = (struct timeval) { 0, 1 }; - - assert(itimer.it_value.tv_sec > 0 || itimer.it_value.tv_usec >= g_granularity); - assert(event_queue->it_value.tv_sec > 0 || event_queue->it_value.tv_usec >= g_granularity); - setitimer(ITIMER_REAL, &itimer, NULL); - check_timer(); - } else { - setitimer(ITIMER_REAL, &timeroff, NULL); - } - break; - } - ppevent = &((*ppevent)->next); - } - - event->flags |= TFLAG_CANCELLED; - - unblock_timer(); -} - -/* -* timer related headers -*/ -#include "bcmtimer.h" - -/* -* locally used global variables and constants -*/ - -/* -* Initialize internal resources used in the timer module. It must be called -* before any other timer function calls. The param 'timer_entries' is used -* to pre-allocate fixed number of timer entries. -*/ -int bcm_timer_module_init(int timer_entries, bcm_timer_module_id *module_id) -{ - init_event_queue(timer_entries); - *module_id = (bcm_timer_module_id)event_freelist; - return 0; -} - -/* -* Cleanup internal resources used by this timer module. It deletes all -* pending timer entries from the backend timer system as well. -*/ -int bcm_timer_module_cleanup(bcm_timer_module_id module_id) -{ - module_id = 0; - return 0; -} - -/* Enable/Disable timer module */ -int bcm_timer_module_enable(bcm_timer_module_id module_id, int enable) -{ - if (enable) - unblock_timer(); - else - block_timer(); - return 0; -} - -int bcm_timer_create(bcm_timer_module_id module_id, bcm_timer_id *timer_id) -{ - module_id = 0; - return timer_create(CLOCK_REALTIME, NULL, (timer_t *)timer_id); -} - -int bcm_timer_delete(bcm_timer_id timer_id) -{ - return timer_delete((timer_t)timer_id); -} - -int bcm_timer_gettime(bcm_timer_id timer_id, struct itimerspec *timer_spec) -{ - return -1; -} - -int bcm_timer_settime(bcm_timer_id timer_id, const struct itimerspec *timer_spec) -{ - return timer_settime((timer_t)timer_id, 0, timer_spec, NULL); -} - -int bcm_timer_connect(bcm_timer_id timer_id, bcm_timer_cb func, int data) -{ - return timer_connect((timer_t)timer_id, (void *)func, data); -} - -int bcm_timer_cancel(bcm_timer_id timer_id) -{ - timer_cancel((timer_t)timer_id); - return 0; -} -int bcm_timer_change_expirytime(bcm_timer_id timer_id, const struct itimerspec *timer_spec) -{ - timer_change_settime((timer_t)timer_id, timer_spec); - return 1; -} diff --git a/package/nvram/src/shutils.c b/package/nvram/src/shutils.c deleted file mode 100644 index 49ad41af81..0000000000 --- a/package/nvram/src/shutils.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Shell-like utility functions - * - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id$ - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <limits.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <termios.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <net/ethernet.h> - -#include <shutils.h> - -/* - * Reads file and returns contents - * @param fd file descriptor - * @return contents of file or NULL if an error occurred - */ -char * -fd2str(int fd) -{ - char *buf = NULL; - size_t count = 0, n; - - do { - buf = realloc(buf, count + 512); - n = read(fd, buf + count, 512); - if (n < 0) { - free(buf); - buf = NULL; - } - count += n; - } while (n == 512); - - close(fd); - if (buf) - buf[count] = '\0'; - return buf; -} - -/* - * Reads file and returns contents - * @param path path to file - * @return contents of file or NULL if an error occurred - */ -char * -file2str(const char *path) -{ - int fd; - - if ((fd = open(path, O_RDONLY)) == -1) { - perror(path); - return NULL; - } - - return fd2str(fd); -} - -/* - * Waits for a file descriptor to change status or unblocked signal - * @param fd file descriptor - * @param timeout seconds to wait before timing out or 0 for no timeout - * @return 1 if descriptor changed status or 0 if timed out or -1 on error - */ -int -waitfor(int fd, int timeout) -{ - fd_set rfds; - struct timeval tv = { timeout, 0 }; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - return select(fd + 1, &rfds, NULL, NULL, (timeout > 0) ? &tv : NULL); -} - -/* - * Concatenates NULL-terminated list of arguments into a single - * commmand and executes it - * @param argv argument list - * @param path NULL, ">output", or ">>output" - * @param timeout seconds to wait before timing out or 0 for no timeout - * @param ppid NULL to wait for child termination or pointer to pid - * @return return value of executed command or errno - */ -int -_eval(char *const argv[], char *path, int timeout, int *ppid) -{ - pid_t pid; - int status; - int fd; - int flags; - int sig; - char buf[254]=""; - int i; - - switch (pid = fork()) { - case -1: /* error */ - perror("fork"); - return errno; - case 0: /* child */ - /* Reset signal handlers set for parent process */ - for (sig = 0; sig < (_NSIG-1); sig++) - signal(sig, SIG_DFL); - - /* Clean up */ - ioctl(0, TIOCNOTTY, 0); - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - setsid(); - - /* We want to check the board if exist UART? , add by honor 2003-12-04 */ - if ((fd = open("/dev/console", O_RDWR)) < 0) { - (void) open("/dev/null", O_RDONLY); - (void) open("/dev/null", O_WRONLY); - (void) open("/dev/null", O_WRONLY); - } - else{ - close(fd); - (void) open("/dev/console", O_RDONLY); - (void) open("/dev/console", O_WRONLY); - (void) open("/dev/console", O_WRONLY); - } - - /* Redirect stdout to <path> */ - if (path) { - flags = O_WRONLY | O_CREAT; - if (!strncmp(path, ">>", 2)) { - /* append to <path> */ - flags |= O_APPEND; - path += 2; - } else if (!strncmp(path, ">", 1)) { - /* overwrite <path> */ - flags |= O_TRUNC; - path += 1; - } - if ((fd = open(path, flags, 0644)) < 0) - perror(path); - else { - dup2(fd, STDOUT_FILENO); - close(fd); - } - } - - /* execute command */ - for(i=0 ; argv[i] ; i++) - snprintf(buf+strlen(buf), sizeof(buf), "%s ", argv[i]); - dprintf("cmd=[%s]\n", buf); - setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1); - alarm(timeout); - execvp(argv[0], argv); - perror(argv[0]); - exit(errno); - default: /* parent */ - if (ppid) { - *ppid = pid; - return 0; - } else { - waitpid(pid, &status, 0); - if (WIFEXITED(status)) - return WEXITSTATUS(status); - else - return status; - } - } -} - -/* - * Concatenates NULL-terminated list of arguments into a single - * commmand and executes it - * @param argv argument list - * @return stdout of executed command or NULL if an error occurred - */ -char * -_backtick(char *const argv[]) -{ - int filedes[2]; - pid_t pid; - int status; - char *buf = NULL; - - /* create pipe */ - if (pipe(filedes) == -1) { - perror(argv[0]); - return NULL; - } - - switch (pid = fork()) { - case -1: /* error */ - return NULL; - case 0: /* child */ - close(filedes[0]); /* close read end of pipe */ - dup2(filedes[1], 1); /* redirect stdout to write end of pipe */ - close(filedes[1]); /* close write end of pipe */ - execvp(argv[0], argv); - exit(errno); - break; - default: /* parent */ - close(filedes[1]); /* close write end of pipe */ - buf = fd2str(filedes[0]); - waitpid(pid, &status, 0); - break; - } - - return buf; -} - -/* - * Kills process whose PID is stored in plaintext in pidfile - * @param pidfile PID file - * @return 0 on success and errno on failure - */ -int -kill_pidfile(char *pidfile) -{ - FILE *fp = fopen(pidfile, "r"); - char buf[256]; - - if (fp && fgets(buf, sizeof(buf), fp)) { - pid_t pid = strtoul(buf, NULL, 0); - fclose(fp); - return kill(pid, SIGTERM); - } else - return errno; -} - -/* - * fread() with automatic retry on syscall interrupt - * @param ptr location to store to - * @param size size of each element of data - * @param nmemb number of elements - * @param stream file stream - * @return number of items successfully read - */ -int -safe_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - size_t ret = 0; - - do { - clearerr(stream); - ret += fread((char *)ptr + (ret * size), size, nmemb - ret, stream); - } while (ret < nmemb && ferror(stream) && errno == EINTR); - - return ret; -} - -/* - * fwrite() with automatic retry on syscall interrupt - * @param ptr location to read from - * @param size size of each element of data - * @param nmemb number of elements - * @param stream file stream - * @return number of items successfully written - */ -int -safe_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - size_t ret = 0; - - do { - clearerr(stream); - ret += fwrite((char *)ptr + (ret * size), size, nmemb - ret, stream); - } while (ret < nmemb && ferror(stream) && errno == EINTR); - - return ret; -} - -/* - * Convert Ethernet address string representation to binary data - * @param a string in xx:xx:xx:xx:xx:xx notation - * @param e binary data - * @return TRUE if conversion was successful and FALSE otherwise - */ -int -ether_atoe(const char *a, unsigned char *e) -{ - char *c = (char *) a; - int i = 0; - - memset(e, 0, ETHER_ADDR_LEN); - for (;;) { - e[i++] = (unsigned char) strtoul(c, &c, 16); - if (!*c++ || i == ETHER_ADDR_LEN) - break; - } - return (i == ETHER_ADDR_LEN); -} - -/* - * Convert Ethernet address binary data to string representation - * @param e binary data - * @param a string in xx:xx:xx:xx:xx:xx notation - * @return a - */ -char * -ether_etoa(const unsigned char *e, char *a) -{ - char *c = a; - int i; - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - if (i) - *c++ = ':'; - c += sprintf(c, "%02X", e[i] & 0xff); - } - return a; -} diff --git a/package/nvram/src/wl.c b/package/nvram/src/wl.c deleted file mode 100644 index c33610310c..0000000000 --- a/package/nvram/src/wl.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Wireless network adapter utilities - * - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id$ - */ -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <net/if.h> - -#include <typedefs.h> -#include <wlutils.h> - -int -wl_ioctl(char *name, int cmd, void *buf, int len) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - int ret = 0; - int s; - - /* open socket to kernel */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - return errno; - } - - /* do it */ - ioc.cmd = cmd; - ioc.buf = buf; - ioc.len = len; - strncpy(ifr.ifr_name, name, IFNAMSIZ); - ifr.ifr_data = (caddr_t) &ioc; - if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0) - if (cmd != WLC_GET_MAGIC) - perror(ifr.ifr_name); - - /* cleanup */ - close(s); - return ret; -} - -int -wl_hwaddr(char *name, unsigned char *hwaddr) -{ - struct ifreq ifr; - int ret = 0; - int s; - - /* open socket to kernel */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - return errno; - } - - /* do it */ - strncpy(ifr.ifr_name, name, IFNAMSIZ); - if ((ret = ioctl(s, SIOCGIFHWADDR, &ifr)) == 0) - memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); - - /* cleanup */ - close(s); - return ret; -} - -int -wl_probe(char *name) -{ - int ret, val; - - /* Check interface */ - if ((ret = wl_ioctl(name, WLC_GET_MAGIC, &val, sizeof(val)))) - return ret; - if (val != WLC_IOCTL_MAGIC) - return -1; - if ((ret = wl_ioctl(name, WLC_GET_VERSION, &val, sizeof(val)))) - return ret; - if (val > WLC_IOCTL_VERSION) - return -1; - - return ret; -} - -int -wl_set_val(char *name, char *var, void *val, int len) -{ - char buf[128]; - int buf_len; - - /* check for overflow */ - if ((buf_len = strlen(var)) + 1 + len > sizeof(buf)) - return -1; - - strcpy(buf, var); - buf_len += 1; - - /* append int value onto the end of the name string */ - memcpy(&buf[buf_len], val, len); - buf_len += len; - - return wl_ioctl(name, WLC_SET_VAR, buf, buf_len); -} - -int -wl_get_val(char *name, char *var, void *val, int len) -{ - char buf[128]; - int ret; - - /* check for overflow */ - if (strlen(var) + 1 > sizeof(buf) || len > sizeof(buf)) - return -1; - - strcpy(buf, var); - if ((ret = wl_ioctl(name, WLC_GET_VAR, buf, sizeof(buf)))) - return ret; - - memcpy(val, buf, len); - return 0; -} - -int -wl_set_int(char *name, char *var, int val) -{ - return wl_set_val(name, var, &val, sizeof(val)); -} - -int -wl_get_int(char *name, char *var, int *val) -{ - return wl_get_val(name, var, val, sizeof(*val)); -} - -/************************************************************************** - * The following code is from Broadcom (wl.c) * - **************************************************************************/ - -int -wl_iovar_getbuf(char *ifname, char *iovar, void *param, - int paramlen, void *bufptr, int buflen) -{ - int err; - uint namelen; - uint iolen; - - namelen = strlen(iovar) + 1; /* length of iovar name plus null */ - iolen = namelen + paramlen; - - /* check for overflow */ - if (iolen > buflen) - return (-1); - - memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ - memcpy((int8*)bufptr + namelen, param, paramlen); - - err = wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); - - return (err); -} - -int -wl_iovar_setbuf(char *ifname, char *iovar, void *param, - int paramlen, void *bufptr, int buflen) -{ - uint namelen; - uint iolen; - - namelen = strlen(iovar) + 1; /* length of iovar name plus null */ - iolen = namelen + paramlen; - - /* check for overflow */ - if (iolen > buflen) - return (-1); - - memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ - memcpy((int8*)bufptr + namelen, param, paramlen); - - return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); -} - -int -wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen) -{ - char smbuf[WLC_IOCTL_SMLEN]; - - return wl_iovar_setbuf(ifname, iovar, param, paramlen, smbuf, sizeof(smbuf)); -} - -int -wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen) -{ - char smbuf[WLC_IOCTL_SMLEN]; - int ret; - - /* use the return buffer if it is bigger than what we have on the stack */ - if (buflen > sizeof(smbuf)) { - ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, bufptr, buflen); - } else { - ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, smbuf, sizeof(smbuf)); - if (ret == 0) - memcpy(bufptr, smbuf, buflen); - } - - return ret; -} - -/* - * set named driver variable to int value - * calling example: wl_iovar_setint(ifname, "arate", rate) -*/ -int -wl_iovar_setint(char *ifname, char *iovar, int val) -{ - return wl_iovar_set(ifname, iovar, &val, sizeof(val)); -} - -/* - * get named driver variable to int value and return error indication - * calling example: wl_iovar_getint(ifname, "arate", &rate) - */ -int -wl_iovar_getint(char *ifname, char *iovar, int *val) -{ - return wl_iovar_get(ifname, iovar, val, sizeof(int)); -} - -/* - * format a bsscfg indexed iovar buffer - */ -static int -wl_bssiovar_mkbuf(char *iovar, int bssidx, void *param, - int paramlen, void *bufptr, int buflen, int *plen) -{ - char *prefix = "bsscfg:"; - int8* p; - uint prefixlen; - uint namelen; - uint iolen; - - prefixlen = strlen(prefix); /* length of bsscfg prefix */ - namelen = strlen(iovar) + 1; /* length of iovar name + null */ - iolen = prefixlen + namelen + sizeof(int) + paramlen; - - /* check for overflow */ - if (buflen < 0 || iolen > (uint)buflen) { - *plen = 0; - return -1; - } - - p = (int8*)bufptr; - - /* copy prefix, no null */ - memcpy(p, prefix, prefixlen); - p += prefixlen; - - /* copy iovar name including null */ - memcpy(p, iovar, namelen); - p += namelen; - - /* bss config index as first param */ - memcpy(p, &bssidx, sizeof(int32)); - p += sizeof(int32); - - /* parameter buffer follows */ - if (paramlen) - memcpy(p, param, paramlen); - - *plen = iolen; - return 0; -} - -/* - * set named & bss indexed driver variable to buffer value - */ -int -wl_bssiovar_setbuf(char *ifname, char *iovar, int bssidx, void *param, - int paramlen, void *bufptr, int buflen) -{ - int err; - uint iolen; - - err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); - if (err) - return err; - - return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); -} - -/* - * get named & bss indexed driver variable buffer value - */ -int -wl_bssiovar_getbuf(char *ifname, char *iovar, int bssidx, void *param, - int paramlen, void *bufptr, int buflen) -{ - int err; - uint iolen; - - err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); - if (err) - return err; - - return wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); -} - -/* - * set named & bss indexed driver variable to buffer value - */ -int -wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen) -{ - char smbuf[WLC_IOCTL_SMLEN]; - - return wl_bssiovar_setbuf(ifname, iovar, bssidx, param, paramlen, smbuf, sizeof(smbuf)); -} - -/* - * get named & bss indexed driver variable buffer value - */ -int -wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len) -{ - char smbuf[WLC_IOCTL_SMLEN]; - int err; - - /* use the return buffer if it is bigger than what we have on the stack */ - if (len > (int)sizeof(smbuf)) { - err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, outbuf, len); - } else { - memset(smbuf, 0, sizeof(smbuf)); - err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, smbuf, sizeof(smbuf)); - if (err == 0) - memcpy(outbuf, smbuf, len); - } - - return err; -} - -/* - * set named & bss indexed driver variable to int value - */ -int -wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val) -{ - return wl_bssiovar_set(ifname, iovar, bssidx, &val, sizeof(int)); -} |