mirror of
https://github.com/hak5/wifipineapple-openwrt.git
synced 2025-10-29 16:57:19 +00:00
move wificonf and nvram stuff back to package/, remove build_mipsel/root, run install part of package/ for every board/kernel - fixes dependency mess
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1540 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
@@ -8,14 +8,10 @@ package-$(BR2_PACKAGE_KMOD_OPENSWAN) += openswan
|
||||
package-y += openwrt
|
||||
|
||||
ifeq ($(BOARD),brcm)
|
||||
package-$(BR2_PACKAGE_WIFICONF) += wificonf
|
||||
package-y += nvram
|
||||
|
||||
ifeq ($(LINUX_VERSION),2.4.30)
|
||||
package-$(BR2_PACKAGE_KMOD_WLCOMPAT) += wlcompat
|
||||
wlcompat-compile: openwrt-compile
|
||||
endif
|
||||
|
||||
nvram-compile: openwrt-compile
|
||||
endif
|
||||
|
||||
all: compile install
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nvram
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(TOPDIR)/package/rules.mk
|
||||
|
||||
BR2_PACKAGE_NVRAM:=y # does not depend on menuconfig
|
||||
$(eval $(call PKG_template,NVRAM,nvram,$(PKG_RELEASE),$(ARCH)))
|
||||
|
||||
$(PKG_BUILD_DIR)/.prepared:
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
cp -a ./src/* $(PKG_BUILD_DIR)
|
||||
touch $@
|
||||
|
||||
$(PKG_BUILD_DIR)/.built:
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CFLAGS="$(TARGET_CFLAGS) -I $(STAGING_DIR)/usr/include"
|
||||
touch $@
|
||||
|
||||
$(IPKG_NVRAM):
|
||||
mkdir -p $(IDIR_NVRAM)/usr/lib
|
||||
cp $(PKG_BUILD_DIR)/*.so $(IDIR_NVRAM)/usr/lib
|
||||
mkdir -p $(IDIR_NVRAM)/usr/sbin
|
||||
cp $(PKG_BUILD_DIR)/nvram $(IDIR_NVRAM)/usr/sbin
|
||||
$(RSTRIP) $(IDIR_NVRAM)
|
||||
$(IPKG_BUILD) $(IDIR_NVRAM) $(PACKAGE_DIR)
|
||||
|
||||
|
||||
compile: install-dev
|
||||
install-dev:
|
||||
mkdir -p $(STAGING_DIR)/usr/lib
|
||||
cp $(PKG_BUILD_DIR)/*.so $(STAGING_DIR)/usr/lib
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
Package: nvram
|
||||
Priority: optional
|
||||
Section: sys
|
||||
Maintainer: Felix Fietkau <nbd@vd-s.ath.cx>
|
||||
Source: buildroot internal
|
||||
Description: NVRAM utility and libraries for Broadcom hardware
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
EXTRA_CFLAGS := -c -I. -I../include
|
||||
LIBSHARED_OBJS := shutils.o wl.o wl_linux.o defaults.o linux_timer.o
|
||||
LIBNVRAM_OBJS := nvram_linux.o nvram_convert.o
|
||||
|
||||
all: libshared.so libnvram.so nvram
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $^
|
||||
|
||||
libshared.so: $(LIBSHARED_OBJS)
|
||||
$(CC) -shared -o $@ $^
|
||||
|
||||
libnvram.so: $(LIBNVRAM_OBJS)
|
||||
$(CC) -shared -o $@ $^
|
||||
|
||||
nvram: main.o
|
||||
$(CC) -o $@ $^ -L. -lnvram
|
||||
|
||||
clean:
|
||||
rm -f *.o *.so nvram
|
||||
@@ -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__ */
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Router default NVRAM values
|
||||
*
|
||||
* 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 <epivers.h>
|
||||
#include <string.h>
|
||||
#include <bcmnvram.h>
|
||||
#include <typedefs.h>
|
||||
#include <wlioctl.h>
|
||||
|
||||
#define XSTR(s) STR(s)
|
||||
#define STR(s) #s
|
||||
|
||||
struct nvram_tuple router_defaults[] = {
|
||||
/* OS parameters */
|
||||
{ "os_name", "", 0 }, /* OS name string */
|
||||
{ "os_version", EPI_VERSION_STR, 0 }, /* OS revision */
|
||||
{ "os_date", __DATE__, 0 }, /* OS date */
|
||||
|
||||
/* Miscellaneous parameters */
|
||||
{ "timer_interval", "3600", 0 }, /* Timer interval in seconds */
|
||||
{ "ntp_server", "192.5.41.40 192.5.41.41 133.100.9.2", 0 }, /* NTP server */
|
||||
{ "time_zone", "PST8PDT", 0 }, /* Time zone (GNU TZ format) */
|
||||
{ "log_level", "0", 0 }, /* Bitmask 0:off 1:denied 2:accepted */
|
||||
{ "upnp_enable", "0", 0 }, /* Start UPnP */
|
||||
{ "ezc_enable", "1", 0 }, /* Enable EZConfig updates */
|
||||
{ "ezc_version", "1", 0 }, /* EZConfig version */
|
||||
{ "is_default", "1", 0 }, /* is it default setting: 1:yes 0:no*/
|
||||
{ "os_server", "", 0 }, /* URL for getting upgrades */
|
||||
{ "stats_server", "", 0 }, /* URL for posting stats */
|
||||
{ "console_loglevel", "1", 0 }, /* Kernel panics only */
|
||||
|
||||
/* Big switches */
|
||||
{ "router_disable", "0", 0 }, /* lan_proto=static lan_stp=0 wan_proto=disabled */
|
||||
{ "fw_disable", "0", 0 }, /* Disable firewall (allow new connections from the WAN) */
|
||||
|
||||
{ "log_ipaddr", "", 0 }, /* syslog recipient */
|
||||
|
||||
/* LAN H/W parameters */
|
||||
{ "lan_ifname", "", 0 }, /* LAN interface name */
|
||||
{ "lan_ifnames", "", 0 }, /* Enslaved LAN interfaces */
|
||||
{ "lan_hwnames", "", 0 }, /* LAN driver names (e.g. et0) */
|
||||
{ "lan_hwaddr", "", 0 }, /* LAN interface MAC address */
|
||||
|
||||
/* LAN TCP/IP parameters */
|
||||
{ "lan_proto", "dhcp", 0 }, /* [static|dhcp] */
|
||||
{ "lan_ipaddr", "192.168.1.1", 0 }, /* LAN IP address */
|
||||
{ "lan_netmask", "255.255.255.0", 0 }, /* LAN netmask */
|
||||
{ "lan_stp", "0", 0 }, /* LAN spanning tree protocol */
|
||||
{ "lan_wins", "", 0 }, /* x.x.x.x x.x.x.x ... */
|
||||
{ "lan_domain", "", 0 }, /* LAN domain name */
|
||||
{ "lan_lease", "86400", 0 }, /* LAN lease time in seconds */
|
||||
|
||||
/* WAN H/W parameters */
|
||||
{ "wan_ifname", "", 0 }, /* WAN interface name */
|
||||
{ "wan_ifnames", "", 0 }, /* WAN interface names */
|
||||
{ "wan_hwname", "", 0 }, /* WAN driver name (e.g. et1) */
|
||||
{ "wan_hwaddr", "", 0 }, /* WAN interface MAC address */
|
||||
|
||||
/* WAN TCP/IP parameters */
|
||||
{ "wan_proto", "dhcp", 0 }, /* [static|dhcp|pppoe|disabled] */
|
||||
{ "wan_ipaddr", "0.0.0.0", 0 }, /* WAN IP address */
|
||||
{ "wan_netmask", "0.0.0.0", 0 }, /* WAN netmask */
|
||||
{ "wan_gateway", "0.0.0.0", 0 }, /* WAN gateway */
|
||||
{ "wan_dns", "", 0 }, /* x.x.x.x x.x.x.x ... */
|
||||
{ "wan_wins", "", 0 }, /* x.x.x.x x.x.x.x ... */
|
||||
{ "wan_hostname", "", 0 }, /* WAN hostname */
|
||||
{ "wan_domain", "", 0 }, /* WAN domain name */
|
||||
{ "wan_lease", "86400", 0 }, /* WAN lease time in seconds */
|
||||
|
||||
/* PPPoE parameters */
|
||||
{ "wan_pppoe_ifname", "", 0 }, /* PPPoE enslaved interface */
|
||||
{ "wan_pppoe_username", "", 0 }, /* PPP username */
|
||||
{ "wan_pppoe_passwd", "", 0 }, /* PPP password */
|
||||
{ "wan_pppoe_idletime", "60", 0 }, /* Dial on demand max idle time (seconds) */
|
||||
{ "wan_pppoe_keepalive", "0", 0 }, /* Restore link automatically */
|
||||
{ "wan_pppoe_demand", "0", 0 }, /* Dial on demand */
|
||||
{ "wan_pppoe_mru", "1492", 0 }, /* Negotiate MRU to this value */
|
||||
{ "wan_pppoe_mtu", "1492", 0 }, /* Negotiate MTU to the smaller of this value or the peer MRU */
|
||||
{ "wan_pppoe_service", "", 0 }, /* PPPoE service name */
|
||||
{ "wan_pppoe_ac", "", 0 }, /* PPPoE access concentrator name */
|
||||
|
||||
/* Misc WAN parameters */
|
||||
{ "wan_desc", "", 0 }, /* WAN connection description */
|
||||
{ "wan_route", "", 0 }, /* Static routes (ipaddr:netmask:gateway:metric:ifname ...) */
|
||||
{ "wan_primary", "0", 0 }, /* Primary wan connection */
|
||||
|
||||
{ "wan_unit", "0", 0 }, /* Last configured connection */
|
||||
|
||||
/* Filters */
|
||||
{ "filter_maclist", "", 0 }, /* xx:xx:xx:xx:xx:xx ... */
|
||||
{ "filter_macmode", "deny", 0 }, /* "allow" only, "deny" only, or "disabled" (allow all) */
|
||||
{ "filter_client0", "", 0 }, /* [lan_ipaddr0-lan_ipaddr1|*]:lan_port0-lan_port1,proto,enable,day_start-day_end,sec_start-sec_end,desc */
|
||||
|
||||
/* Port forwards */
|
||||
{ "dmz_ipaddr", "", 0 }, /* x.x.x.x (equivalent to 0-60999>dmz_ipaddr:0-60999) */
|
||||
{ "forward_port0", "", 0 }, /* wan_port0-wan_port1>lan_ipaddr:lan_port0-lan_port1[:,]proto[:,]enable[:,]desc */
|
||||
{ "autofw_port0", "", 0 }, /* out_proto:out_port,in_proto:in_port0-in_port1>to_port0-to_port1,enable,desc */
|
||||
|
||||
/* DHCP server parameters */
|
||||
{ "dhcp_start", "192.168.1.100", 0 }, /* First assignable DHCP address */
|
||||
{ "dhcp_end", "192.168.1.150", 0 }, /* Last assignable DHCP address */
|
||||
{ "dhcp_domain", "wan", 0 }, /* Use WAN domain name first if available (wan|lan) */
|
||||
{ "dhcp_wins", "wan", 0 }, /* Use WAN WINS first if available (wan|lan) */
|
||||
|
||||
/* Web server parameters */
|
||||
{ "http_username", "", 0 }, /* Username */
|
||||
{ "http_passwd", "admin", 0 }, /* Password */
|
||||
{ "http_wanport", "", 0 }, /* WAN port to listen on */
|
||||
{ "http_lanport", "80", 0 }, /* LAN port to listen on */
|
||||
|
||||
/* Wireless parameters */
|
||||
{ "wl_ifname", "", 0 }, /* Interface name */
|
||||
{ "wl_hwaddr", "", 0 }, /* MAC address */
|
||||
{ "wl_phytype", "g", 0 }, /* Current wireless band ("a" (5 GHz), "b" (2.4 GHz), or "g" (2.4 GHz)) */
|
||||
{ "wl_corerev", "", 0 }, /* Current core revision */
|
||||
{ "wl_phytypes", "", 0 }, /* List of supported wireless bands (e.g. "ga") */
|
||||
{ "wl_radioids", "", 0 }, /* List of radio IDs */
|
||||
{ "wl_ssid", "OpenWrt", 0 }, /* Service set ID (network name) */
|
||||
{ "wl_country", "", 0 }, /* Country (default obtained from driver) */
|
||||
{ "wl_radio", "1", 0 }, /* Enable (1) or disable (0) radio */
|
||||
{ "wl_closed", "0", 0 }, /* Closed (hidden) network */
|
||||
{ "wl_ap_isolate", "0", 0 }, /* AP isolate mode */
|
||||
{ "wl_mode", "ap", 0 }, /* AP mode (ap|sta|wds) */
|
||||
{ "wl_lazywds", "0", 0 }, /* Enable "lazy" WDS mode (0|1) */
|
||||
{ "wl_wds", "", 0 }, /* xx:xx:xx:xx:xx:xx ... */
|
||||
{ "wl_wep", "disabled", 0 }, /* WEP data encryption (enabled|disabled) */
|
||||
{ "wl_auth", "0", 0 }, /* Shared key authentication optional (0) or required (1) */
|
||||
{ "wl_key", "1", 0 }, /* Current WEP key */
|
||||
{ "wl_key1", "", 0 }, /* 5/13 char ASCII or 10/26 char hex */
|
||||
{ "wl_key2", "", 0 }, /* 5/13 char ASCII or 10/26 char hex */
|
||||
{ "wl_key3", "", 0 }, /* 5/13 char ASCII or 10/26 char hex */
|
||||
{ "wl_key4", "", 0 }, /* 5/13 char ASCII or 10/26 char hex */
|
||||
{ "wl_maclist", "", 0 }, /* xx:xx:xx:xx:xx:xx ... */
|
||||
{ "wl_macmode", "disabled", 0 }, /* "allow" only, "deny" only, or "disabled" (allow all) */
|
||||
{ "wl_channel", "11", 0 }, /* Channel number */
|
||||
{ "wl_rate", "0", 0 }, /* Rate (bps, 0 for auto) */
|
||||
{ "wl_rateset", "default", 0 }, /* "default" or "all" or "12" */
|
||||
{ "wl_frag", "2346", 0 }, /* Fragmentation threshold */
|
||||
{ "wl_rts", "2347", 0 }, /* RTS threshold */
|
||||
{ "wl_dtim", "1", 0 }, /* DTIM period */
|
||||
{ "wl_bcn", "100", 0 }, /* Beacon interval */
|
||||
{ "wl_plcphdr", "long", 0 }, /* 802.11b PLCP preamble type */
|
||||
{ "wl_net_mode", "mixed", 0 }, /* 54g mode */
|
||||
{ "wl_gmode", "6", 0 }, /* 54g mode */
|
||||
{ "wl_gmode_protection", "auto", 0 }, /* 802.11g RTS/CTS protection (off|auto) */
|
||||
{ "wl_afterburner", "auto", 0 }, /* AfterBurner */
|
||||
{ "wl_frameburst", "off", 0 }, /* BRCM Frambursting mode (off|on) */
|
||||
{ "wl_antdiv", "-1", 0 }, /* Antenna Diversity (-1|0|1|3) */
|
||||
{ "wl_infra", "1", 0 }, /* Network Type (BSS/IBSS) */
|
||||
|
||||
/* WPA parameters */
|
||||
{ "security_mode", "open", 0 },
|
||||
{ "wl_auth_mode", "open", 0 }, /* Network authentication mode (open|shared|radius|wpa|psk) */
|
||||
{ "wl_wpa_psk", "", 0 }, /* WPA pre-shared key */
|
||||
{ "wl_wpa_gtk_rekey", "3600", 0 }, /* GTK rotation interval */
|
||||
{ "wl_radius_ipaddr", "", 0 }, /* RADIUS server IP address */
|
||||
{ "wl_radius_key", "", 0 }, /* RADIUS shared secret */
|
||||
{ "wl_radius_port", "1812", 0 }, /* RADIUS server UDP port */
|
||||
{ "wl_crypto", "tkip", 0 }, /* WPA data encryption */
|
||||
|
||||
|
||||
{ "wl_unit", "0", 0 }, /* Last configured interface */
|
||||
|
||||
/* Restore defaults */
|
||||
{ "restore_defaults", "0", 0 }, /* Set to 0 to not restore defaults on boot */
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Frontend command-line utility for Linux NVRAM layer
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmnvram.h>
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: nvram [get name] [set name=value] [unset name] [show]\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* NVRAM utility */
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *name, *value, buf[NVRAM_SPACE];
|
||||
int size;
|
||||
|
||||
/* Skip program name */
|
||||
--argc;
|
||||
++argv;
|
||||
|
||||
if (!*argv)
|
||||
usage();
|
||||
|
||||
/* Process the remaining arguments. */
|
||||
for (; *argv; argv++) {
|
||||
if (!strncmp(*argv, "get", 3)) {
|
||||
if (*++argv) {
|
||||
if ((value = nvram_get(*argv)))
|
||||
puts(value);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(*argv, "set", 3)) {
|
||||
if (*++argv) {
|
||||
strncpy(value = buf, *argv, sizeof(buf));
|
||||
name = strsep(&value, "=");
|
||||
nvram_set(name, value);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(*argv, "unset", 5)) {
|
||||
if (*++argv)
|
||||
nvram_unset(*argv);
|
||||
}
|
||||
else if (!strncmp(*argv, "commit", 5)) {
|
||||
nvram_commit();
|
||||
}
|
||||
else if (!strncmp(*argv, "show", 4) ||
|
||||
!strncmp(*argv, "getall", 6)) {
|
||||
nvram_getall(buf, sizeof(buf));
|
||||
for (name = buf; *name; name += strlen(name) + 1)
|
||||
puts(name);
|
||||
size = sizeof(struct nvram_header) + (int) name - (int) buf;
|
||||
fprintf(stderr, "size: %d bytes (%d left)\n", size, NVRAM_SPACE - size);
|
||||
}
|
||||
if (!*argv)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
|
||||
#define WL(a) "wl_"a
|
||||
#define WL0(a) "wl0_"a
|
||||
#define D11G(a) "d11g_"a
|
||||
|
||||
#define PPP(a) "ppp_"a
|
||||
#define PPPOE(a) "pppoe_"a
|
||||
|
||||
struct nvram_convert {
|
||||
char *name; // for WEB
|
||||
char *wl0_name; // for driver
|
||||
char *d11g_name; // for old nv name
|
||||
};
|
||||
|
||||
struct nvram_convert nvram_converts[] = {
|
||||
// Bellow change from 3.11.48.7
|
||||
{ WL("ssid"), WL0("ssid"), ""},
|
||||
{ WL("radio"), WL0("mode"), ""},
|
||||
{ WL("mode"), WL0("mode"), ""},
|
||||
{ WL("wds"), WL0("wds"), ""},
|
||||
{ WL("auth"), WL0("auth"), ""},
|
||||
{ WL("key"), WL0("key"), ""},
|
||||
{ WL("key1"), WL0("key1"), ""},
|
||||
{ WL("key2"), WL0("key2"), ""},
|
||||
{ WL("key3"), WL0("key3"), ""},
|
||||
{ WL("key4"), WL0("key4"), ""},
|
||||
{ WL("maclist"), WL0("maclist"), ""},
|
||||
{ WL("channel"), WL0("channel"), D11G("channel")},
|
||||
{ WL("rateset"), WL0("rateset"), D11G("rateset")},
|
||||
{ WL("rts"), WL0("rts"), D11G("rts")},
|
||||
{ WL("bcn"), WL0("bcn"), D11G("bcn")},
|
||||
{ WL("gmode"), WL0("gmode"), "d11g_mode"},
|
||||
{ WL("unit"), WL0("unit"), ""},
|
||||
{ WL("ifname"), WL0("ifname"), ""},
|
||||
{ WL("phytype"), WL0("phytype"), ""},
|
||||
{ WL("country"), WL0("country"), ""},
|
||||
{ WL("closed"), WL0("closed"), ""},
|
||||
{ WL("lazywds"), WL0("lazywds"), ""},
|
||||
{ WL("wep"), WL0("wep"), ""},
|
||||
{ WL("macmode"), WL0("macmode"), ""},
|
||||
{ WL("rate"), WL0("rate"), D11G("rate")},
|
||||
{ WL("frag"), WL0("frag"), D11G("frag")},
|
||||
{ WL("dtim"), WL0("dtim"), D11G("dtim")},
|
||||
{ WL("plcphdr"), WL0("plcphdr"), ""},
|
||||
{ WL("gmode_protection"), WL0("gmode_protection"), ""},
|
||||
{ WL("radio"), WL0("radio"), ""},
|
||||
// Bellow change from 3.21.9.0
|
||||
{ WL("auth_mode"), WL0("auth_mode"), ""},
|
||||
{ WL("radius_ipaddr"), WL0("radius_ipaddr"), ""},
|
||||
{ WL("radius_port"), WL0("radius_port"), ""},
|
||||
{ WL("radius_key"), WL0("radius_key"), ""},
|
||||
{ WL("wpa_psk"), WL0("wpa_psk"), ""},
|
||||
{ WL("wpa_gtk_rekey"), WL0("wpa_gtk_rekey"), ""},
|
||||
{ WL("frameburst"), WL0("frameburst"), ""},
|
||||
{ WL("crypto"), WL0("crypto"), ""},
|
||||
{ WL("ap_isolate"), WL0("ap_isolate"), ""},
|
||||
{ WL("afterburner"), WL0("afterburner"), ""},
|
||||
// for PPPoE
|
||||
{ PPP("username"), PPPOE("username"), ""},
|
||||
{ PPP("passwd"), PPPOE("passwd"), ""},
|
||||
{ PPP("idletime"), PPPOE("idletime"), ""},
|
||||
{ PPP("keepalive"), PPPOE("keepalive"), ""},
|
||||
{ PPP("demand"), PPPOE("demand"), ""},
|
||||
{ PPP("service"), PPPOE("service"), ""},
|
||||
{ PPP("ac"), PPPOE("ac"), ""},
|
||||
{ PPP("static"), PPPOE("static"), ""},
|
||||
{ PPP("static_ip"), PPPOE("static_ip"), ""},
|
||||
{ PPP("username_1"), PPPOE("username_1"), ""},
|
||||
{ PPP("passwd_1"), PPPOE("passwd_1"), ""},
|
||||
{ PPP("idletime_1"), PPPOE("idletime_1"), ""},
|
||||
{ PPP("keepalive_1"), PPPOE("keepalive_1"), ""},
|
||||
{ PPP("demand_1"), PPPOE("demand_1"), ""},
|
||||
{ PPP("service_1"), PPPOE("service_1"), ""},
|
||||
{ PPP("ac_1"), PPPOE("ac_1"), ""},
|
||||
|
||||
{ 0, 0, 0},
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
struct nvram_convert {
|
||||
char *name;
|
||||
char *wl0_name;
|
||||
char *d11g_name;
|
||||
};
|
||||
|
||||
@@ -1,320 +0,0 @@
|
||||
/*
|
||||
* NVRAM variable manipulation (Linux user mode half)
|
||||
*
|
||||
* 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 <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmnvram.h>
|
||||
#include <nvram_convert.h>
|
||||
#include <shutils.h>
|
||||
#include <utils.h>
|
||||
|
||||
#define PATH_DEV_NVRAM "/dev/nvram"
|
||||
|
||||
/* Globals */
|
||||
static int nvram_fd = -1;
|
||||
static char *nvram_buf = NULL;
|
||||
int check_action(void);
|
||||
int file_to_buf(char *path, char *buf, int len);
|
||||
|
||||
int
|
||||
nvram_init(void *unused)
|
||||
{
|
||||
if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
|
||||
goto err;
|
||||
|
||||
/* Map kernel string buffer into user space */
|
||||
if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) {
|
||||
close(nvram_fd);
|
||||
nvram_fd = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
perror(PATH_DEV_NVRAM);
|
||||
return errno;
|
||||
}
|
||||
|
||||
char *
|
||||
nvram_get(const char *name)
|
||||
{
|
||||
size_t count = strlen(name) + 1;
|
||||
char tmp[100], *value;
|
||||
unsigned long *off = (unsigned long *) tmp;
|
||||
|
||||
if (nvram_fd < 0)
|
||||
if (nvram_init(NULL))
|
||||
return NULL;
|
||||
|
||||
if (count > sizeof(tmp)) {
|
||||
if (!(off = malloc(count)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get offset into mmap() space */
|
||||
strcpy((char *) off, name);
|
||||
|
||||
count = read(nvram_fd, off, count);
|
||||
|
||||
if (count == sizeof(unsigned long))
|
||||
value = &nvram_buf[*off];
|
||||
else
|
||||
value = NULL;
|
||||
|
||||
if (count < 0)
|
||||
perror(PATH_DEV_NVRAM);
|
||||
|
||||
if (off != (unsigned long *) tmp)
|
||||
free(off);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int
|
||||
nvram_getall(char *buf, int count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (nvram_fd < 0)
|
||||
if ((ret = nvram_init(NULL)))
|
||||
return ret;
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
/* Get all variables */
|
||||
*buf = '\0';
|
||||
|
||||
ret = read(nvram_fd, buf, count);
|
||||
|
||||
if (ret < 0)
|
||||
perror(PATH_DEV_NVRAM);
|
||||
|
||||
return (ret == count) ? 0 : ret;
|
||||
}
|
||||
|
||||
static int
|
||||
_nvram_set(const char *name, const char *value)
|
||||
{
|
||||
size_t count = strlen(name) + 1;
|
||||
char tmp[100], *buf = tmp;
|
||||
int ret;
|
||||
|
||||
if (nvram_fd < 0)
|
||||
if ((ret = nvram_init(NULL)))
|
||||
return ret;
|
||||
|
||||
/* Unset if value is NULL */
|
||||
if (value)
|
||||
count += strlen(value) + 1;
|
||||
|
||||
if (count > sizeof(tmp)) {
|
||||
if (!(buf = malloc(count)))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (value)
|
||||
sprintf(buf, "%s=%s", name, value);
|
||||
else
|
||||
strcpy(buf, name);
|
||||
|
||||
ret = write(nvram_fd, buf, count);
|
||||
|
||||
if (ret < 0)
|
||||
perror(PATH_DEV_NVRAM);
|
||||
|
||||
if (buf != tmp)
|
||||
free(buf);
|
||||
|
||||
return (ret == count) ? 0 : ret;
|
||||
}
|
||||
|
||||
int
|
||||
nvram_set(const char *name, const char *value)
|
||||
{
|
||||
extern struct nvram_convert nvram_converts[];
|
||||
struct nvram_convert *v;
|
||||
int ret;
|
||||
|
||||
ret = _nvram_set(name, value);
|
||||
|
||||
for(v = nvram_converts ; v->name ; v++) {
|
||||
if(!strcmp(v->name, name)){
|
||||
if(strcmp(v->wl0_name,"")) _nvram_set(v->wl0_name, value);
|
||||
if(strcmp(v->d11g_name,"")) _nvram_set(v->d11g_name, value);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
nvram_unset(const char *name)
|
||||
{
|
||||
return _nvram_set(name, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
nvram_commit(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cprintf("nvram_commit(): start\n");
|
||||
|
||||
if((check_action() == ACT_IDLE) ||
|
||||
(check_action() == ACT_SW_RESTORE) ||
|
||||
(check_action() == ACT_HW_RESTORE)){
|
||||
if (nvram_fd < 0)
|
||||
if ((ret = nvram_init(NULL)))
|
||||
return ret;
|
||||
|
||||
ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
|
||||
|
||||
if (ret < 0)
|
||||
perror(PATH_DEV_NVRAM);
|
||||
|
||||
cprintf("nvram_commit(): end\n");
|
||||
}
|
||||
else
|
||||
cprintf("nvram_commit(): nothing to do...\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int file2nvram(char *filename, char *varname) {
|
||||
FILE *fp;
|
||||
int c,count;
|
||||
int i=0,j=0;
|
||||
char mem[10000],buf[30000];
|
||||
|
||||
if ( !(fp=fopen(filename,"rb") ))
|
||||
return 0;
|
||||
|
||||
count=fread(mem,1,sizeof(mem),fp);
|
||||
fclose(fp);
|
||||
for (j=0;j<count;j++) {
|
||||
if (i > sizeof(buf)-3 )
|
||||
break;
|
||||
c=mem[j];
|
||||
if (c >= 32 && c <= 126 && c != '\\' && c != '~') {
|
||||
buf[i++]=(unsigned char) c;
|
||||
} else if (c==0) {
|
||||
buf[i++]='~';
|
||||
} else {
|
||||
buf[i++]='\\';
|
||||
sprintf(buf+i,"%02X",c);
|
||||
i+=2;
|
||||
}
|
||||
}
|
||||
if (i==0) return 0;
|
||||
buf[i]=0;
|
||||
//fprintf(stderr,"================ > file2nvram %s = [%s] \n",varname,buf);
|
||||
nvram_set(varname,buf);
|
||||
//nvram_commit(); //Barry adds for test
|
||||
}
|
||||
|
||||
int nvram2file(char *varname, char *filename) {
|
||||
FILE *fp;
|
||||
int c,tmp;
|
||||
int i=0,j=0;
|
||||
char *buf;
|
||||
char mem[10000];
|
||||
|
||||
if ( !(fp=fopen(filename,"wb") ))
|
||||
return 0;
|
||||
|
||||
buf=strdup(nvram_safe_get(varname));
|
||||
//fprintf(stderr,"=================> nvram2file %s = [%s] \n",varname,buf);
|
||||
while ( buf[i] && j < sizeof(mem)-3 ) {
|
||||
if (buf[i] == '\\') {
|
||||
i++;
|
||||
tmp=buf[i+2];
|
||||
buf[i+2]=0;
|
||||
sscanf(buf+i,"%02X",&c);
|
||||
buf[i+2]=tmp;
|
||||
i+=2;
|
||||
mem[j]=c;j++;
|
||||
} else if (buf[i] == '~') {
|
||||
mem[j]=0;j++;
|
||||
i++;
|
||||
} else {
|
||||
mem[j]=buf[i];j++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (j<=0) return j;
|
||||
j=fwrite(mem,1,j,fp);
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
return j;
|
||||
}
|
||||
|
||||
int
|
||||
check_action(void)
|
||||
{
|
||||
char buf[80] = "";
|
||||
|
||||
if(file_to_buf(ACTION_FILE, buf, sizeof(buf))){
|
||||
if(!strcmp(buf, "ACT_TFTP_UPGRADE")){
|
||||
cprintf("Upgrading from tftp now, quiet exit....\n");
|
||||
return ACT_TFTP_UPGRADE;
|
||||
}
|
||||
else if(!strcmp(buf, "ACT_WEBS_UPGRADE")){
|
||||
cprintf("Upgrading from web (https) now, quiet exit....\n");
|
||||
return ACT_WEBS_UPGRADE;
|
||||
}
|
||||
else if(!strcmp(buf, "ACT_WEB_UPGRADE")){
|
||||
cprintf("Upgrading from web (http) now, quiet exit....\n");
|
||||
return ACT_WEB_UPGRADE;
|
||||
}
|
||||
else if(!strcmp(buf, "ACT_SW_RESTORE")){
|
||||
cprintf("Receive restore command from web, quiet exit....\n");
|
||||
return ACT_SW_RESTORE;
|
||||
}
|
||||
else if(!strcmp(buf, "ACT_HW_RESTORE")){
|
||||
cprintf("Receive restore commond from resetbutton, quiet exit....\n");
|
||||
return ACT_HW_RESTORE;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "Waiting for upgrading....\n");
|
||||
return ACT_IDLE;
|
||||
}
|
||||
|
||||
int
|
||||
file_to_buf(char *path, char *buf, int len)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
memset(buf, 0 , len);
|
||||
|
||||
if ((fp = fopen(path, "r"))) {
|
||||
fgets(buf, len, fp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,86 +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 <string.h>
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <wlutils.h>
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Wireless network adapter utilities (linux-specific)
|
||||
*
|
||||
* 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 <wlioctl.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;
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME := base-files-arch
|
||||
PKG_RELEASE := 1
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(BOARD)
|
||||
|
||||
include $(TOPDIR)/package/rules.mk
|
||||
|
||||
BR2_PACKAGE_OPENWRT:=y # ignore menuconfig
|
||||
$(eval $(call PKG_template,OPENWRT,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
|
||||
IDIR_OPENWRT:=$(PKG_BUILD_DIR)/ipkg
|
||||
IPKG_OPENWRT:=$(PACKAGE_DIR)/base-files-$(BOARD)_$(PKG_RELEASE)_$(ARCH).ipk
|
||||
|
||||
$(PKG_BUILD_DIR)/.prepared:
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
@@ -30,8 +30,12 @@ endif
|
||||
|
||||
$(PKG_BUILD_DIR)/.built:
|
||||
touch $@
|
||||
|
||||
$(IDIR_OPENWRT):
|
||||
$(SCRIPT_DIR)/make-ipkg-dir.sh $(IDIR_OPENWRT) ipkg/base-files-arch.control $(PKG_RELEASE) $(ARCH)
|
||||
$(SED) s,base-files-arch,base-files-$(BOARD),g $(IDIR_OPENWRT)/CONTROL/control
|
||||
|
||||
$(IPKG_OPENWRT):
|
||||
$(IPKG_OPENWRT):
|
||||
mkdir -p $(IDIR_OPENWRT)/etc
|
||||
cp files/network.overrides.$(BOARD) $(IDIR_OPENWRT)/etc/network.overrides
|
||||
$(RSTRIP) $(IDIR_OPENWRT)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
config BR2_PACKAGE_WIFICONF
|
||||
tristate "wificonf - replacement utility for wlconf"
|
||||
default y
|
||||
help
|
||||
Replacement utility for wlconf
|
||||
@@ -1,29 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wificonf
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/wificonf
|
||||
|
||||
include $(TOPDIR)/package/rules.mk
|
||||
|
||||
|
||||
|
||||
|
||||
$(eval $(call PKG_template,WIFICONF,$(PKG_NAME),$(PKG_RELEASE),$(ARCH)))
|
||||
|
||||
$(PKG_BUILD_DIR)/.prepared:
|
||||
mkdir -p $@
|
||||
touch $@
|
||||
|
||||
$(PKG_BUILD_DIR)/.built:
|
||||
$(TARGET_CC) $(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include -o $(PKG_BUILD_DIR)/wifi wificonf.c -L$(STAGING_DIR)/usr/lib -lnvram -lshared $(STAGING_DIR)/usr/lib/libiw.so
|
||||
touch $@
|
||||
|
||||
$(IPKG_WIFICONF):
|
||||
install -d -m0755 $(IDIR_WIFICONF)/sbin
|
||||
install -m0755 $(PKG_BUILD_DIR)/wifi $(IDIR_WIFICONF)/sbin/
|
||||
$(RSTRIP) $(IDIR_WIFICONF)
|
||||
$(IPKG_BUILD) $(IDIR_WIFICONF) $(PACKAGE_DIR)
|
||||
@@ -1,6 +0,0 @@
|
||||
Package: wificonf
|
||||
Priority: optional
|
||||
Section: net
|
||||
Maintainer: Felix Fietkau <nbd@vd-s.ath.cx>
|
||||
Source: buildroot internal
|
||||
Description: Replacement utility for wlconf
|
||||
@@ -1,495 +0,0 @@
|
||||
/*
|
||||
* Wireless Network Adapter configuration utility
|
||||
*
|
||||
* Copyright (C) 2005 Felix Fietkau <nbd@vd-s.ath.cx>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <iwlib.h>
|
||||
#include <bcmnvram.h>
|
||||
#include <shutils.h>
|
||||
#include <wlioctl.h>
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
* Macro to handle errors when setting WE
|
||||
* Print a nice error message and exit...
|
||||
* We define them as macro so that "return" do the right thing.
|
||||
* The "do {...} while(0)" is a standard trick
|
||||
*/
|
||||
#define ERR_SET_EXT(rname, request) \
|
||||
fprintf(stderr, "Error for wireless request \"%s\" (%X) :\n", \
|
||||
rname, request)
|
||||
|
||||
#define ABORT_ARG_NUM(rname, request) \
|
||||
do { \
|
||||
ERR_SET_EXT(rname, request); \
|
||||
fprintf(stderr, " too few arguments.\n"); \
|
||||
} while(0)
|
||||
|
||||
#define ABORT_ARG_TYPE(rname, request, arg) \
|
||||
do { \
|
||||
ERR_SET_EXT(rname, request); \
|
||||
fprintf(stderr, " invalid argument \"%s\".\n", arg); \
|
||||
} while(0)
|
||||
|
||||
#define ABORT_ARG_SIZE(rname, request, max) \
|
||||
do { \
|
||||
ERR_SET_EXT(rname, request); \
|
||||
fprintf(stderr, " argument too big (max %d)\n", max); \
|
||||
} while(0)
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
* Wrapper to push some Wireless Parameter in the driver
|
||||
* Use standard wrapper and add pretty error message if fail...
|
||||
*/
|
||||
#define IW_SET_EXT_ERR(skfd, ifname, request, wrq, rname) \
|
||||
do { \
|
||||
if(iw_set_ext(skfd, ifname, request, wrq) < 0) { \
|
||||
ERR_SET_EXT(rname, request); \
|
||||
fprintf(stderr, " SET failed on device %-1.16s ; %s.\n", \
|
||||
ifname, strerror(errno)); \
|
||||
} } while(0)
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
* Wrapper to extract some Wireless Parameter out of the driver
|
||||
* Use standard wrapper and add pretty error message if fail...
|
||||
*/
|
||||
#define IW_GET_EXT_ERR(skfd, ifname, request, wrq, rname) \
|
||||
do { \
|
||||
if(iw_get_ext(skfd, ifname, request, wrq) < 0) { \
|
||||
ERR_SET_EXT(rname, request); \
|
||||
fprintf(stderr, " GET failed on device %-1.16s ; %s.\n", \
|
||||
ifname, strerror(errno)); \
|
||||
} } while(0)
|
||||
|
||||
void set_wext_ssid(int skfd, char *ifname);
|
||||
|
||||
char *prefix;
|
||||
char buffer[128];
|
||||
|
||||
char *wl_var(char *name)
|
||||
{
|
||||
strcpy(buffer, prefix);
|
||||
strcat(buffer, name);
|
||||
}
|
||||
|
||||
int nvram_enabled(char *name)
|
||||
{
|
||||
return (nvram_match(name, "1") || nvram_match(name, "on") || nvram_match(name, "enabled") || nvram_match(name, "true") || nvram_match(name, "yes") ? 1 : 0);
|
||||
}
|
||||
|
||||
int nvram_disabled(char *name)
|
||||
{
|
||||
return (nvram_match(name, "0") || nvram_match(name, "off") || nvram_match(name, "disabled") || nvram_match(name, "false") || nvram_match(name, "no") ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int bcom_ioctl(int skfd, char *ifname, int cmd, void *buf, int len)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
wl_ioctl_t ioc;
|
||||
int ret;
|
||||
|
||||
ioc.cmd = cmd;
|
||||
ioc.buf = buf;
|
||||
ioc.len = len;
|
||||
|
||||
ifr.ifr_data = (caddr_t) &ioc;
|
||||
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
|
||||
ret = ioctl(skfd, SIOCDEVPRIVATE, &ifr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bcom_set_val(int skfd, char *ifname, char *var, void *val, int len)
|
||||
{
|
||||
char buf[8192];
|
||||
int ret;
|
||||
|
||||
if (strlen(var) + 1 > sizeof(buf) || len > sizeof(buf))
|
||||
return -1;
|
||||
|
||||
strcpy(buf, var);
|
||||
|
||||
if ((ret = bcom_ioctl(skfd, ifname, WLC_GET_VAR, buf, sizeof(buf))))
|
||||
return ret;
|
||||
|
||||
memcpy(val, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcom_set_int(int skfd, char *ifname, char *var, int val)
|
||||
{
|
||||
return bcom_set_val(skfd, ifname, var, &val, sizeof(val));
|
||||
}
|
||||
|
||||
void stop_bcom(int skfd, char *ifname)
|
||||
{
|
||||
int val = 0;
|
||||
wlc_ssid_t ssid;
|
||||
|
||||
if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0)
|
||||
return;
|
||||
|
||||
ssid.SSID_len = 0;
|
||||
ssid.SSID[0] = 0;
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_SSID, &ssid, sizeof(ssid));
|
||||
bcom_ioctl(skfd, ifname, WLC_DOWN, NULL, 0);
|
||||
|
||||
}
|
||||
|
||||
void start_bcom(int skfd, char *ifname)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0)
|
||||
return;
|
||||
|
||||
bcom_ioctl(skfd, ifname, WLC_UP, &val, sizeof(val));
|
||||
set_wext_ssid(skfd, ifname);
|
||||
}
|
||||
|
||||
|
||||
void setup_bcom(int skfd, char *ifname)
|
||||
{
|
||||
int val = 0;
|
||||
char buf[8192];
|
||||
char wbuf[80];
|
||||
char *v;
|
||||
|
||||
if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0)
|
||||
return;
|
||||
|
||||
stop_bcom(skfd, ifname);
|
||||
|
||||
/* Set Country */
|
||||
strncpy(buf, nvram_safe_get(wl_var("country_code")), 4);
|
||||
buf[3] = 0;
|
||||
bcom_ioctl(skfd, ifname, 273, buf, 4);
|
||||
|
||||
/* Set up afterburner */
|
||||
val = ABO_AUTO;
|
||||
if (nvram_enabled(wl_var("afterburner")))
|
||||
val = ABO_ON;
|
||||
if (nvram_disabled(wl_var("afterburner")))
|
||||
val = ABO_OFF;
|
||||
bcom_set_val(skfd, ifname, "afterburner_override", &val, sizeof(val));
|
||||
|
||||
/* Set other options */
|
||||
if (v = nvram_get(wl_var("lazywds"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_LAZYWDS, &val, sizeof(val));
|
||||
}
|
||||
if (v = nvram_get(wl_var("frag"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_FRAG, &val, sizeof(val));
|
||||
}
|
||||
if (v = nvram_get(wl_var("dtim"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_DTIMPRD, &val, sizeof(val));
|
||||
}
|
||||
if (v = nvram_get(wl_var("bcn"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_BCNPRD, &val, sizeof(val));
|
||||
}
|
||||
if (v = nvram_get(wl_var("rts"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_RTS, &val, sizeof(val));
|
||||
}
|
||||
if (v = nvram_get(wl_var("antdiv"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_ANTDIV, &val, sizeof(val));
|
||||
}
|
||||
if (v = nvram_get(wl_var("txant"))) {
|
||||
val = atoi(v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_TXANT, &val, sizeof(val));
|
||||
}
|
||||
|
||||
val = nvram_enabled(wl_var("closed"));
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_CLOSED, &val, sizeof(val));
|
||||
|
||||
val = nvram_enabled(wl_var("ap_isolate"));
|
||||
bcom_set_int(skfd, ifname, "ap_isolate", val);
|
||||
|
||||
val = nvram_enabled(wl_var("frameburst"));
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_FAKEFRAG, &val, sizeof(val));
|
||||
|
||||
/* Set up MAC list */
|
||||
if (nvram_match(wl_var("macmode"), "allow"))
|
||||
val = WLC_MACMODE_ALLOW;
|
||||
else if (nvram_match(wl_var("macmode"), "deny"))
|
||||
val = WLC_MACMODE_DENY;
|
||||
else
|
||||
val = WLC_MACMODE_DISABLED;
|
||||
|
||||
if ((val != WLC_MACMODE_DISABLED) && (v = nvram_get(wl_var("maclist")))) {
|
||||
struct maclist *mac_list;
|
||||
struct ether_addr *addr;
|
||||
char *next;
|
||||
|
||||
memset(buf, 0, 8192);
|
||||
mac_list = (struct maclist *) buf;
|
||||
addr = mac_list->ea;
|
||||
|
||||
foreach(wbuf, v, next) {
|
||||
if (ether_atoe(wbuf, addr->ether_addr_octet)) {
|
||||
mac_list->count++;
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_MACLIST, buf, sizeof(buf));
|
||||
} else {
|
||||
val = WLC_MACMODE_DISABLED;
|
||||
}
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_MACMODE, &val, sizeof(val));
|
||||
|
||||
if (v = nvram_get(wl_var("wds"))) {
|
||||
struct maclist *wdslist = (struct maclist *) buf;
|
||||
struct ether_addr *addr = wdslist->ea;
|
||||
char *next;
|
||||
|
||||
memset(buf, 0, 8192);
|
||||
foreach(wbuf, v, next) {
|
||||
if (ether_atoe(wbuf, addr->ether_addr_octet)) {
|
||||
wdslist->count++;
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_WDSLIST, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* Set up G mode */
|
||||
bcom_ioctl(skfd, ifname, WLC_GET_PHYTYPE, &val, sizeof(val));
|
||||
if (val == 2) {
|
||||
int override = WLC_G_PROTECTION_OFF;
|
||||
int control = WLC_G_PROTECTION_CTL_OFF;
|
||||
|
||||
if (v = nvram_get(wl_var("gmode")))
|
||||
val = atoi(v);
|
||||
else
|
||||
val = 1;
|
||||
|
||||
if (val > 5)
|
||||
val = 1;
|
||||
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_GMODE, &val, sizeof(val));
|
||||
|
||||
if (nvram_match(wl_var("gmode_protection"), "auto")) {
|
||||
override = WLC_G_PROTECTION_AUTO;
|
||||
control = WLC_G_PROTECTION_CTL_OVERLAP;
|
||||
}
|
||||
if (nvram_enabled(wl_var("gmode_protection"))) {
|
||||
override = WLC_G_PROTECTION_ON;
|
||||
control = WLC_G_PROTECTION_CTL_OVERLAP;
|
||||
}
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_GMODE_PROTECTION_CONTROL, &override, sizeof(control));
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_GMODE_PROTECTION_OVERRIDE, &override, sizeof(override));
|
||||
|
||||
if (val = 0) {
|
||||
if (nvram_match(wl_var("plcphdr"), "long"))
|
||||
val = WLC_PLCP_AUTO;
|
||||
else
|
||||
val = WLC_PLCP_SHORT;
|
||||
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_PLCPHDR, &val, sizeof(val));
|
||||
}
|
||||
}
|
||||
|
||||
start_bcom(skfd, ifname);
|
||||
|
||||
if (!(v = nvram_get(wl_var("akm"))))
|
||||
v = nvram_safe_get(wl_var("auth_mode"));
|
||||
|
||||
if (strstr(v, "wpa") || strstr(v, "psk")) {
|
||||
/* Set up WPA */
|
||||
if (nvram_match(wl_var("crypto"), "tkip"))
|
||||
val = TKIP_ENABLED;
|
||||
else if (nvram_match(wl_var("crypto"), "aes"))
|
||||
val = AES_ENABLED;
|
||||
else if (nvram_match(wl_var("crypto"), "tkip+aes"))
|
||||
val = TKIP_ENABLED | AES_ENABLED;
|
||||
else
|
||||
val = 0;
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_WSEC, &val, sizeof(val));
|
||||
|
||||
if (val && strstr(v, "psk")) {
|
||||
v = nvram_safe_get(wl_var("wpa_psk"));
|
||||
|
||||
if ((strlen(v) >= 8) && (strlen(v) < 63)) {
|
||||
val = 4;
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_WPA_AUTH, &val, sizeof(val));
|
||||
|
||||
bcom_ioctl(skfd, ifname, WLC_GET_AP, &val, sizeof(val));
|
||||
if (!val) {
|
||||
/* Enable in-driver WPA supplicant */
|
||||
wsec_pmk_t pmk;
|
||||
|
||||
pmk.key_len = (unsigned short) strlen(v);
|
||||
pmk.flags = WSEC_PASSPHRASE;
|
||||
strcpy(pmk.key, v);
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk));
|
||||
bcom_set_int(skfd, ifname, "sup_wpa", 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val = 1;
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_EAP_RESTRICT, &val, sizeof(val));
|
||||
}
|
||||
} else {
|
||||
val = 0;
|
||||
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_WSEC, &val, sizeof(val));
|
||||
bcom_ioctl(skfd, ifname, WLC_SET_WPA_AUTH, &val, sizeof(val));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void set_wext_ssid(int skfd, char *ifname)
|
||||
{
|
||||
char *buffer;
|
||||
struct iwreq wrq;
|
||||
|
||||
if (buffer = nvram_get(wl_var("ssid"))) {
|
||||
if (strlen(buffer) > IW_ESSID_MAX_SIZE) {
|
||||
ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
|
||||
} else {
|
||||
char essid[IW_ESSID_MAX_SIZE + 1];
|
||||
|
||||
wrq.u.essid.flags = 1;
|
||||
strcpy(essid, buffer);
|
||||
wrq.u.essid.pointer = (caddr_t) essid;
|
||||
wrq.u.essid.length = strlen(essid) + 1;
|
||||
IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq, "Set ESSID");
|
||||
}
|
||||
}
|
||||
}
|
||||
void setup_wext_wep(int skfd, char *ifname)
|
||||
{
|
||||
int i, keylen;
|
||||
struct iwreq wrq;
|
||||
char keystr[5];
|
||||
char *keyval;
|
||||
unsigned char key[IW_ENCODING_TOKEN_MAX];
|
||||
|
||||
strcpy(keystr, "key1");
|
||||
for (i = 1; i <= 4; i++) {
|
||||
if (keyval = nvram_get(wl_var(keystr))) {
|
||||
keylen = iw_in_key(keyval, key);
|
||||
|
||||
if (keylen > 0) {
|
||||
wrq.u.data.length = keylen;
|
||||
wrq.u.data.pointer = (caddr_t) key;
|
||||
wrq.u.data.flags = i;
|
||||
IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
|
||||
}
|
||||
}
|
||||
keystr[3]++;
|
||||
}
|
||||
|
||||
|
||||
i = atoi(nvram_safe_get(wl_var("key")));
|
||||
if (i > 0 && i < 4) {
|
||||
wrq.u.data.flags = i | IW_ENCODE_RESTRICTED;
|
||||
IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq, "Set Encode");
|
||||
}
|
||||
}
|
||||
|
||||
void set_wext_mode(skfd, ifname)
|
||||
{
|
||||
struct iwreq wrq;
|
||||
int ap = 0, infra = 0, wet = 0;
|
||||
|
||||
/* Set operation mode */
|
||||
ap = !nvram_match(wl_var("mode"), "sta");
|
||||
infra = !nvram_disabled(wl_var("infra"));
|
||||
wet = nvram_enabled(wl_var("wet"));
|
||||
|
||||
wrq.u.mode = (!infra ? IW_MODE_ADHOC : (ap ? IW_MODE_MASTER : (wet ? IW_MODE_REPEAT : IW_MODE_INFRA)));
|
||||
IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq, "Set Mode");
|
||||
}
|
||||
|
||||
void setup_wext(int skfd, char *ifname)
|
||||
{
|
||||
char *buffer;
|
||||
struct iwreq wrq;
|
||||
|
||||
/* Set channel */
|
||||
int channel = atoi(nvram_safe_get(wl_var("channel")));
|
||||
|
||||
wrq.u.freq.m = -1;
|
||||
wrq.u.freq.e = 0;
|
||||
wrq.u.freq.flags = 0;
|
||||
|
||||
if (channel > 0) {
|
||||
wrq.u.freq.flags = IW_FREQ_FIXED;
|
||||
wrq.u.freq.m = channel;
|
||||
IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq, "Set Frequency");
|
||||
}
|
||||
|
||||
|
||||
/* Disable radio if wlX_radio is set and not enabled */
|
||||
wrq.u.txpower.disabled = nvram_disabled(wl_var("radio"));
|
||||
|
||||
wrq.u.txpower.value = -1;
|
||||
wrq.u.txpower.fixed = 1;
|
||||
wrq.u.txpower.flags = IW_TXPOW_DBM;
|
||||
IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq, "Set Tx Power");
|
||||
|
||||
/* Set up WEP */
|
||||
if (nvram_enabled(wl_var("wep")))
|
||||
setup_wext_wep(skfd, ifname);
|
||||
|
||||
/* Set ESSID */
|
||||
set_wext_ssid(skfd, ifname);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int setup_interfaces(int skfd, char *ifname, char *args[], int count)
|
||||
{
|
||||
struct iwreq wrq;
|
||||
int rc;
|
||||
|
||||
/* Avoid "Unused parameter" warning */
|
||||
args = args; count = count;
|
||||
|
||||
if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
|
||||
return 0;
|
||||
|
||||
stop_bcom(skfd, ifname);
|
||||
set_wext_mode(skfd, ifname);
|
||||
setup_bcom(skfd, ifname);
|
||||
setup_wext(skfd, ifname);
|
||||
|
||||
prefix[2]++;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int skfd;
|
||||
if((skfd = iw_sockets_open()) < 0) {
|
||||
perror("socket");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
prefix = strdup("wl0_");
|
||||
iw_enum_devices(skfd, &setup_interfaces, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user