1/*
2 * Router rc control script
3 *
4 * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: rc.c 407542 2013-06-13 08:36:09Z $
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <limits.h>
24#include <time.h>
25#include <unistd.h>
26#include <errno.h>
27#include <syslog.h>
28#include <signal.h>
29#include <fcntl.h> /* for open */
30#include <string.h>
31#include <sys/klog.h>
32#include <sys/types.h>
33#include <sys/mount.h>
34#include <sys/reboot.h>
35#include <sys/stat.h>
36#include <sys/sysmacros.h>
37#include <sys/time.h>
38#include <sys/utsname.h>
39#include <sys/wait.h>
40#include <sys/socket.h>
41#include <sys/utsname.h> /* for uname */
42#include <net/if_arp.h>
43#include <dirent.h>
44
45#include <epivers.h>
46#include <router_version.h>
47#include <mtd.h>
48#include <shutils.h>
49#include <rc.h>
50#include <netconf.h>
51#include <nvparse.h>
52#include <bcmdevs.h>
53#include <bcmparams.h>
54#include <bcmnvram.h>
55#include <wlutils.h>
56#include <ezc.h>
57#include <pmon.h>
58#undef HAVE_CONFMTD
59#if defined(__CONFIG_WAPI__) || defined(__CONFIG_WAPI_IAS__) || \
60	defined(__CONFIG_CIFS__)
61#define HAVE_CONFMTD
62#include <confmtd_utils.h>
63#if defined(__CONFIG_WAPI__) || defined(__CONFIG_WAPI_IAS__)
64#include <wapi_path.h>
65#endif
66#if defined(__CONFIG_CIFS__)
67#include <cifs_path.h>
68#endif
69#endif /* __CONFIG_WAPI__ || __CONFIG_WAPI_IAS__ || __CONFIG_CIFS__ */
70
71/* foxconn added start, zacker, 09/17/2009, @wps_led */
72#include <fcntl.h>
73#include <wps_led.h>
74/* foxconn added end, zacker, 09/17/2009, @wps_led */
75
76/*fxcn added by dennis start,05/03/2012, fixed guest network can't reconnect issue*/
77#define MAX_BSSID_NUM       4
78#define MIN_BSSID_NUM       2
79/*fxcn added by dennis end,05/03/2012, fixed guest network can't reconnect issue*/
80
81
82#ifdef __CONFIG_NAT__
83static void auto_bridge(void);
84#endif	/* __CONFIG_NAT__ */
85
86#include <sys/sysinfo.h> /* foxconn wklin added */
87#ifdef __CONFIG_EMF__
88extern void load_emf(void);
89#endif /* __CONFIG_EMF__ */
90
91static void restore_defaults(void);
92static void sysinit(void);
93static void rc_signal(int sig);
94/* Foxconn added start, Wins, 05/16/2011, @RU_IPTV */
95#if defined(CONFIG_RUSSIA_IPTV)
96static int is_russia_specific_support (void);
97#endif /* CONFIG_RUSSIA_IPTV */
98/* Foxconn added end, Wins, 05/16/2011, @RU_IPTV */
99
100extern struct nvram_tuple router_defaults[];
101
102#define RESTORE_DEFAULTS() \
103	(!nvram_match("restore_defaults", "0") || nvram_invmatch("os_name", "linux"))
104
105#ifdef LINUX_2_6_36
106static int
107coma_uevent(void)
108{
109	char *modalias = NULL;
110	char lan_ifname[32], *lan_ifnames, *next;
111
112	modalias = getenv("MODALIAS");
113	if (!strcmp(modalias, "platform:coma_dev")) {
114
115		/* down WiFi adapter */
116		lan_ifnames = nvram_safe_get("lan_ifnames");
117		foreach(lan_ifname, lan_ifnames, next) {
118			if (!strncmp(lan_ifname, "eth", 3)) {
119				eval("wl", "-i", lan_ifname, "down");
120			}
121		}
122
123		system("echo \"2\" > /proc/bcm947xx/coma");
124	}
125	return 0;
126}
127#endif /* LINUX_2_6_36 */
128
129#define RESTORE_DEFAULTS() (!nvram_match("restore_defaults", "0") || nvram_invmatch("os_name", "linux"))
130
131/* for WCN support, Foxconn added start by EricHuang, 12/13/2006 */
132static void convert_wlan_params(void)
133{
134    int config_flag = 0; /* Foxconn add, Tony W.Y. Wang, 01/06/2010 */
135
136    /* Foxconn added start pling 03/05/2010 */
137    /* Added for dual band WPS req. for WNDR3400 */
138#define MAX_SSID_LEN    32
139    char wl0_ssid[64], wl1_ssid[64];
140
141    /* first check how we arrived here?
142     * 1. or by "add WPS client" in unconfigured state.
143     * 2. by external register configure us,
144     */
145    strcpy(wl0_ssid, nvram_safe_get("wl0_ssid"));
146    strcpy(wl1_ssid, nvram_safe_get("wl1_ssid"));
147    /* Foxconn modified, Tony W.Y. Wang, 03/24/2010 @WPS random ssid setting */
148    if (!nvram_match("wps_start", "none") || nvram_match("wps_pbc_conn_success", "1"))
149    {
150        /* case 1 above, either via pbc, or gui */
151        /* In this case, the WPS set both SSID to be
152         *  either "NTRG-2.4G_xxx" or "NTRG-5G_xxx".
153         * We need to set proper SSID for each radio.
154         */
155#define RANDOM_SSID_2G  "NTGR-2.4G_"
156#define RANDOM_SSID_5G  "NTGR-5G_"
157
158        if (strncmp(wl0_ssid, RANDOM_SSID_2G, strlen(RANDOM_SSID_2G)) == 0 && !nvram_match("wl0_radio","0"))
159        {
160            printf("Random ssid 2.4G\n");
161            /* Set correct ssid for 5G */
162            sprintf(wl1_ssid, "%s%s", RANDOM_SSID_5G,
163                    &wl0_ssid[strlen(RANDOM_SSID_2G)]);
164            nvram_set("wl1_ssid", wl1_ssid);
165        }
166        else
167        if (strncmp(wl1_ssid, RANDOM_SSID_5G, strlen(RANDOM_SSID_5G)) == 0 && !nvram_match("wl1_radio","0"))
168        {
169            printf("Random ssid 5G\n");
170            /* Set correct ssid for 2.4G */
171            sprintf(wl0_ssid, "%s%s", RANDOM_SSID_2G,
172                    &wl1_ssid[strlen(RANDOM_SSID_5G)]);
173            nvram_set("wl0_ssid", wl0_ssid);
174            /* Foxconn added start dennis 05/29/2012 */
175            /* Fix a issue where 2.4G radio is disabled,
176             * router uses incorrect random ssid/passphrase.
177             */
178            if (nvram_match("wl0_radio","0"))
179                nvram_set("wl0_wpa_psk", nvram_get("wl1_wpa_psk"));
180            /* Foxconn added end pling 05/29/2012 */
181        }
182        nvram_unset("wps_pbc_conn_success");
183    }
184    else
185    {
186        /* case 2 */
187        /* now check whether external register is from:
188         * 1. UPnP,
189         * 2. 2.4GHz radio
190         * 3. 5GHz radio
191         */
192        if (nvram_match("wps_is_upnp", "1"))
193        {
194            /* Case 1: UPnP: wired registrar */
195            /* SSID for both interface should be same already.
196             * So nothing to do.
197             */
198            printf("Wired External registrar!\n");
199        }
200        else
201        if (nvram_match("wps_currentRFband", "1"))
202        {
203            /* Case 2: 2.4GHz radio */
204            /* Need to add "-5G" to the SSID of the 5GHz band */
205            char ssid_suffix[] = "-5G";
206            if (MAX_SSID_LEN - strlen(wl0_ssid) >= strlen(ssid_suffix))
207            {
208                printf("2.4G Wireless External registrar 1!\n");
209                /* SSID is not long, so append suffix to wl1_ssid */
210                sprintf(wl1_ssid, "%s%s", wl0_ssid, ssid_suffix);
211            }
212            else
213            {
214                printf("2.4G Wireless External registrar 2!\n");
215                /* SSID is too long, so replace last few chars of ssid
216                 * with suffix
217                 */
218                strcpy(wl1_ssid, wl0_ssid);
219                strcpy(&wl1_ssid[MAX_SSID_LEN - strlen(ssid_suffix)], ssid_suffix);
220            }
221            if (strlen(wl1_ssid) > MAX_SSID_LEN)
222                printf("Error wl1_ssid too long (%d)!\n", strlen(wl1_ssid));
223
224            nvram_set("wl1_ssid", wl1_ssid);
225        }
226        else
227        if (nvram_match("wps_currentRFband", "2"))
228        {
229            /* Case 3: 5GHz radio */
230            /* Need to add "-2.4G" to the SSID of the 2.4GHz band */
231            char ssid_suffix[] = "-2.4G";
232
233            if (MAX_SSID_LEN - strlen(wl1_ssid) >= strlen(ssid_suffix))
234            {
235                printf("5G Wireless External registrar 1!\n");
236                /* SSID is not long, so append suffix to wl1_ssid */
237                sprintf(wl0_ssid, "%s%s", wl1_ssid, ssid_suffix);
238            }
239            else
240            {
241                printf("5G Wireless External registrar 2!\n");
242                /* Replace last few chars ssid with suffix */
243                /* SSID is too long, so replace last few chars of ssid
244                 * with suffix
245                 */
246                strcpy(wl0_ssid, wl1_ssid);
247                strcpy(&wl0_ssid[MAX_SSID_LEN - strlen(ssid_suffix)], ssid_suffix);
248            }
249            nvram_set("wl0_ssid", wl0_ssid);
250        }
251        else
252            printf("Error! unknown external register!\n");
253    }
254    /* Foxconn added end pling 03/05/2010 */
255
256    nvram_set("wla_ssid", nvram_safe_get("wl0_ssid"));
257    nvram_set("wla_temp_ssid", nvram_safe_get("wl0_ssid"));
258
259    if ( strncmp(nvram_safe_get("wl0_akm"), "psk psk2", 7) == 0 )
260    {
261        nvram_set("wla_secu_type", "WPA-AUTO-PSK");
262        nvram_set("wla_temp_secu_type", "WPA-AUTO-PSK");
263        nvram_set("wla_passphrase", nvram_safe_get("wl0_wpa_psk"));
264
265        /* If router changes from 'unconfigured' to 'configured' state by
266         * adding a WPS client, the wsc_randomssid and wsc_randomkey will
267         * be set. In this case, router should use mixedmode security.
268         */
269
270        if (!nvram_match("wps_randomssid", "") ||
271            !nvram_match("wps_randomkey", ""))
272        {
273            nvram_set("wla_secu_type", "WPA-AUTO-PSK");
274            nvram_set("wla_temp_secu_type", "WPA-AUTO-PSK");
275
276            nvram_set("wl0_akm", "psk psk2 ");
277            nvram_set("wl0_crypto", "tkip+aes");
278
279            nvram_set("wps_mixedmode", "2");
280            //nvram_set("wps_randomssid", "");
281            //nvram_set("wps_randomkey", "");
282            config_flag = 1;
283            /* Since we changed to mixed mode,
284             * so we need to disable WDS if it is already enabled
285             */
286            if (nvram_match("wla_wds_enable", "1"))
287            {
288                nvram_set("wla_wds_enable",  "0");
289                nvram_set("wl0_wds", "");
290                nvram_set("wl0_mode", "ap");
291            }
292        }
293        else
294        {
295            /* Foxconn added start pling 02/25/2007 */
296            /* Disable WDS if it is already enabled */
297            if (nvram_match("wla_wds_enable", "1"))
298            {
299                nvram_set("wla_wds_enable",  "0");
300                nvram_set("wl0_wds", "");
301                nvram_set("wl0_mode", "ap");
302            }
303            /* Foxconn added end pling 02/25/2007 */
304        }
305    }
306    else if ( strncmp(nvram_safe_get("wl0_akm"), "psk2", 4) == 0 )
307    {
308        nvram_set("wla_secu_type", "WPA2-PSK");
309        nvram_set("wla_temp_secu_type", "WPA2-PSK");
310        nvram_set("wla_passphrase", nvram_safe_get("wl0_wpa_psk"));
311
312
313        /* If router changes from 'unconfigured' to 'configured' state by
314         * adding a WPS client, the wsc_randomssid and wsc_randomkey will
315         * be set. In this case, router should use mixedmode security.
316         */
317        /* Foxconn added start pling 06/15/2010 */
318        if (nvram_match("wl0_crypto", "tkip"))
319        {
320            /* DTM fix:
321             * Registrar may set to WPA2-PSK TKIP mode.
322             * In this case, don't try to modify the
323             * security type.
324            */
325            nvram_unset("wps_mixedmode");
326        }
327        else
328        /* Foxconn added end pling 06/15/2010 */
329        if (!nvram_match("wps_randomssid", "") ||
330            !nvram_match("wps_randomkey", ""))
331        {
332            nvram_set("wla_secu_type", "WPA-AUTO-PSK");
333            nvram_set("wla_temp_secu_type", "WPA-AUTO-PSK");
334
335            nvram_set("wl0_akm", "psk psk2 ");
336            nvram_set("wl0_crypto", "tkip+aes");
337
338            nvram_set("wps_mixedmode", "2");
339            //nvram_set("wps_randomssid", "");
340            //nvram_set("wps_randomkey", "");
341            config_flag = 1;
342            /* Since we changed to mixed mode,
343             * so we need to disable WDS if it is already enabled
344             */
345            if (nvram_match("wla_wds_enable", "1"))
346            {
347                nvram_set("wla_wds_enable",  "0");
348                nvram_set("wl0_wds", "");
349                nvram_set("wl0_mode", "ap");
350            }
351        }
352        else
353        {
354            /* Foxconn added start pling 02/25/2007 */
355            /* Disable WDS if it is already enabled */
356            if (nvram_match("wla_wds_enable", "1"))
357            {
358                nvram_set("wla_wds_enable",  "0");
359                nvram_set("wl0_wds", "");
360                nvram_set("wl0_mode", "ap");
361            }
362            /* Foxconn added end pling 02/25/2007 */
363        }
364    }
365    else if ( strncmp(nvram_safe_get("wl0_akm"), "psk", 3) == 0 )
366    {
367        nvram_set("wla_secu_type", "WPA-PSK");
368        nvram_set("wla_temp_secu_type", "WPA-PSK");
369        nvram_set("wla_passphrase", nvram_safe_get("wl0_wpa_psk"));
370
371        /* If router changes from 'unconfigured' to 'configured' state by
372         * adding a WPS client, the wsc_randomssid and wsc_randomkey will
373         * be set. In this case, router should use mixedmode security.
374         */
375        /* Foxconn added start pling 06/15/2010 */
376        if (nvram_match("wl0_crypto", "aes"))
377        {
378            /* DTM fix:
379             * Registrar may set to WPA-PSK AES mode.
380             * In this case, don't try to modify the
381             * security type.
382            */
383            nvram_unset("wps_mixedmode");
384        }
385        else
386        /* Foxconn added end pling 06/15/2010 */
387        if (!nvram_match("wps_randomssid", "") ||
388            !nvram_match("wps_randomkey", ""))
389        {
390            /* Foxconn add start, Tony W.Y. Wang, 11/30/2009 */
391            /* WiFi TKIP changes for WNDR3400*/
392            /*
393            When external registrar configures our router as WPA-PSK [TKIP], security,
394            we auto change the wireless mode to Up to 54Mbps. This should only apply to
395            router when router is in "WPS Unconfigured" state.
396            */
397            nvram_set("wla_mode",  "g and b");
398
399            /* Disable 11n support, copied from bcm_wlan_util.c */
400            acosNvramConfig_set("wl_nmode", "0");
401            acosNvramConfig_set("wl0_nmode", "0");
402
403            acosNvramConfig_set("wl_gmode", "1");
404            acosNvramConfig_set("wl0_gmode", "1");
405
406            /* Set bandwidth to 20MHz */
407#if ( !(defined BCM4718) && !(defined BCM4716) && !(defined U12H189) )
408            acosNvramConfig_set("wl_nbw", "20");
409            acosNvramConfig_set("wl0_nbw", "20");
410#endif
411
412            acosNvramConfig_set("wl_nbw_cap", "0");
413            acosNvramConfig_set("wl0_nbw_cap", "0");
414
415            /* Disable extension channel */
416            acosNvramConfig_set("wl_nctrlsb", "none");
417            acosNvramConfig_set("wl0_nctrlsb", "none");
418
419            /* Now set the security */
420            nvram_set("wla_secu_type", "WPA-PSK");
421            nvram_set("wla_temp_secu_type", "WPA-PSK");
422
423            nvram_set("wl0_akm", "psk ");
424            nvram_set("wl0_crypto", "tkip");
425
426            /*
427            nvram_set("wla_secu_type", "WPA-AUTO-PSK");
428            nvram_set("wla_temp_secu_type", "WPA-AUTO-PSK");
429
430            nvram_set("wl0_akm", "psk psk2 ");
431            nvram_set("wl0_crypto", "tkip+aes");
432            */
433            /* Foxconn add end, Tony W.Y. Wang, 11/30/2009 */
434            nvram_set("wps_mixedmode", "1");
435            //nvram_set("wps_randomssid", "");
436            //nvram_set("wps_randomkey", "");
437            config_flag = 1;
438            /* Since we changed to mixed mode,
439             * so we need to disable WDS if it is already enabled
440             */
441            if (nvram_match("wla_wds_enable", "1"))
442            {
443                nvram_set("wla_wds_enable",  "0");
444                nvram_set("wl0_wds", "");
445                nvram_set("wl0_mode", "ap");
446            }
447        }
448    }
449    else if ( strncmp(nvram_safe_get("wl0_wep"), "enabled", 7) == 0 )
450    {
451        int key_len=0;
452        if ( strncmp(nvram_safe_get("wl0_auth"), "1", 1) == 0 ) /*shared mode*/
453        {
454            nvram_set("wla_auth_type", "sharedkey");
455            nvram_set("wla_temp_auth_type", "sharedkey");
456        }
457        else
458        {
459            nvram_set("wla_auth_type", "opensystem");
460            nvram_set("wla_temp_auth_type", "opensystem");
461        }
462
463        nvram_set("wla_secu_type", "WEP");
464        nvram_set("wla_temp_secu_type", "WEP");
465        nvram_set("wla_defaKey", "0");
466        nvram_set("wla_temp_defaKey", "0");
467        /* Foxconn add start by aspen Bai, 02/24/2009 */
468        /*
469        nvram_set("wla_key1", nvram_safe_get("wl_key1"));
470        nvram_set("wla_temp_key1", nvram_safe_get("wl_key1"));
471
472        printf("wla_wep_length: %d\n", strlen(nvram_safe_get("wl_key1")));
473
474        key_len = atoi(nvram_safe_get("wl_key1"));
475        */
476        nvram_set("wla_key1", nvram_safe_get("wl0_key1"));
477        nvram_set("wla_temp_key1", nvram_safe_get("wl0_key1"));
478
479        printf("wla_wep_length: %d\n", strlen(nvram_safe_get("wl0_key1")));
480
481        key_len = strlen(nvram_safe_get("wl0_key1"));
482        /* Foxconn add end by aspen Bai, 02/24/2009 */
483        if (key_len==5 || key_len==10)
484        {
485            nvram_set("wla_wep_length", "1");
486        }
487        else
488        {
489            nvram_set("wla_wep_length", "2");
490        }
491        /* Foxconn add start by aspen Bai, 02/24/2009 */
492        if (key_len==5 || key_len==13)
493        {
494            char HexKeyArray[32];
495            char key[32], tmp[32];
496            int i;
497
498            strcpy(key, nvram_safe_get("wl0_key1"));
499            memset(HexKeyArray, 0, sizeof(HexKeyArray));
500            for (i=0; i<key_len; i++)
501            {
502                sprintf(tmp, "%02X", (unsigned char)key[i]);
503                strcat(HexKeyArray, tmp);
504            }
505            printf("ASCII WEP key (%s) convert -> HEX WEP key (%s)\n", key, HexKeyArray);
506
507            nvram_set("wla_key1", HexKeyArray);
508            nvram_set("wla_temp_key1", HexKeyArray);
509        }
510        /* Foxconn add end by aspen Bai, 02/24/2009 */
511    }
512    else
513    {
514        nvram_set("wla_secu_type", "None");
515        nvram_set("wla_temp_secu_type", "None");
516        nvram_set("wla_passphrase", "");
517    }
518    /* Foxconn add start, Tony W.Y. Wang, 11/23/2009 */
519    nvram_set("wlg_ssid", nvram_safe_get("wl1_ssid"));
520    nvram_set("wlg_temp_ssid", nvram_safe_get("wl1_ssid"));
521
522    if ( strncmp(nvram_safe_get("wl1_akm"), "psk psk2", 7) == 0 )
523    {
524        nvram_set("wlg_secu_type", "WPA-AUTO-PSK");
525        nvram_set("wlg_temp_secu_type", "WPA-AUTO-PSK");
526        nvram_set("wlg_passphrase", nvram_safe_get("wl1_wpa_psk"));
527
528        /* If router changes from 'unconfigured' to 'configured' state by
529         * adding a WPS client, the wsc_randomssid and wsc_randomkey will
530         * be set. In this case, router should use mixedmode security.
531         */
532
533        if (!nvram_match("wps_randomssid", "") ||
534            !nvram_match("wps_randomkey", ""))
535        {
536            nvram_set("wlg_secu_type", "WPA-AUTO-PSK");
537            nvram_set("wlg_temp_secu_type", "WPA-AUTO-PSK");
538
539            nvram_set("wl1_akm", "psk psk2 ");
540            nvram_set("wl1_crypto", "tkip+aes");
541
542            nvram_set("wps_mixedmode", "2");
543            //nvram_set("wps_randomssid", "");
544            //nvram_set("wps_randomkey", "");
545            config_flag = 1;
546            /* Since we changed to mixed mode,
547             * so we need to disable WDS if it is already enabled
548             */
549            if (nvram_match("wlg_wds_enable", "1"))
550            {
551                nvram_set("wlg_wds_enable",  "0");
552                nvram_set("wl1_wds", "");
553                nvram_set("wl1_mode", "ap");
554            }
555        }
556        else
557        {
558            /* Foxconn added start pling 02/25/2007 */
559            /* Disable WDS if it is already enabled */
560            if (nvram_match("wlg_wds_enable", "1"))
561            {
562                nvram_set("wlg_wds_enable",  "0");
563                nvram_set("wl1_wds", "");
564                nvram_set("wl1_mode", "ap");
565            }
566            /* Foxconn added end pling 02/25/2007 */
567        }
568    }
569    else if ( strncmp(nvram_safe_get("wl1_akm"), "psk2", 4) == 0 )
570    {
571        nvram_set("wlg_secu_type", "WPA2-PSK");
572        nvram_set("wlg_temp_secu_type", "WPA2-PSK");
573        nvram_set("wlg_passphrase", nvram_safe_get("wl1_wpa_psk"));
574
575
576        /* If router changes from 'unconfigured' to 'configured' state by
577         * adding a WPS client, the wsc_randomssid and wsc_randomkey will
578         * be set. In this case, router should use mixedmode security.
579         */
580
581        /* Foxconn added start pling 06/15/2010 */
582        if (nvram_match("wl1_crypto", "tkip"))
583        {
584            /* DTM fix:
585             * Registrar may set to WPA2-PSK TKIP mode.
586             * In this case, don't try to modify the
587             * security type.
588            */
589            nvram_unset("wps_mixedmode");
590        }
591        else
592        /* Foxconn added end pling 06/15/2010 */
593        if (!nvram_match("wps_randomssid", "") ||
594            !nvram_match("wps_randomkey", ""))
595        {
596            nvram_set("wlg_secu_type", "WPA-AUTO-PSK");
597            nvram_set("wlg_temp_secu_type", "WPA-AUTO-PSK");
598
599            nvram_set("wl1_akm", "psk psk2 ");
600            nvram_set("wl1_crypto", "tkip+aes");
601
602            nvram_set("wps_mixedmode", "2");
603            //nvram_set("wps_randomssid", "");
604            //nvram_set("wps_randomkey", "");
605            config_flag = 1;
606            /* Since we changed to mixed mode,
607             * so we need to disable WDS if it is already enabled
608             */
609            if (nvram_match("wlg_wds_enable", "1"))
610            {
611                nvram_set("wlg_wds_enable",  "0");
612                nvram_set("wl1_wds", "");
613                nvram_set("wl1_mode", "ap");
614            }
615        }
616        else
617        {
618            /* Foxconn added start pling 02/25/2007 */
619            /* Disable WDS if it is already enabled */
620            if (nvram_match("wlg_wds_enable", "1"))
621            {
622                nvram_set("wlg_wds_enable",  "0");
623                nvram_set("wl1_wds", "");
624                nvram_set("wl1_mode", "ap");
625            }
626            /* Foxconn added end pling 02/25/2007 */
627        }
628    }
629    else if ( strncmp(nvram_safe_get("wl1_akm"), "psk", 3) == 0 )
630    {
631        nvram_set("wlg_secu_type", "WPA-PSK");
632        nvram_set("wlg_temp_secu_type", "WPA-PSK");
633        nvram_set("wlg_passphrase", nvram_safe_get("wl1_wpa_psk"));
634
635        /* If router changes from 'unconfigured' to 'configured' state by
636         * adding a WPS client, the wsc_randomssid and wsc_randomkey will
637         * be set. In this case, router should use mixedmode security.
638         */
639
640        /* Foxconn added start pling 06/15/2010 */
641        if (nvram_match("wl1_crypto", "aes"))
642        {
643            /* DTM fix:
644             * Registrar may set to WPA-PSK AES mode.
645             * In this case, don't try to modify the
646             * security type.
647            */
648            nvram_unset("wps_mixedmode");
649        }
650        else
651        /* Foxconn added end pling 06/15/2010 */
652        if (!nvram_match("wps_randomssid", "") ||
653            !nvram_match("wps_randomkey", ""))
654        {
655            /* Foxconn add start, Tony W.Y. Wang, 11/30/2009 */
656            /* WiFi TKIP changes for WNDR3400*/
657            /*
658            When external registrar configures our router as WPA-PSK [TKIP], security,
659            we auto change the wireless mode to Up to 54Mbps. This should only apply to
660            router when router is in "WPS Unconfigured" state.
661            */
662            nvram_set("wlg_mode",  "g and b");
663
664            /* Disable 11n support, copied from bcm_wlan_util.c */
665            acosNvramConfig_set("wl1_nmode", "0");
666
667            acosNvramConfig_set("wl1_gmode", "1");
668
669            /* Set bandwidth to 20MHz */
670#if ( !(defined BCM4718) && !(defined BCM4716) && !(defined U12H189) )
671            acosNvramConfig_set("wl1_nbw", "20");
672#endif
673
674            acosNvramConfig_set("wl1_nbw_cap", "0");
675
676            /* Disable extension channel */
677            acosNvramConfig_set("wl1_nctrlsb", "none");
678
679            /* Now set the security */
680            nvram_set("wlg_secu_type", "WPA-PSK");
681            nvram_set("wlg_temp_secu_type", "WPA-PSK");
682
683            nvram_set("wl1_akm", "psk ");
684            nvram_set("wl1_crypto", "tkip");
685            /*
686            nvram_set("wlg_secu_type", "WPA-AUTO-PSK");
687            nvram_set("wlg_temp_secu_type", "WPA-AUTO-PSK");
688
689            nvram_set("wl1_akm", "psk psk2 ");
690            nvram_set("wl1_crypto", "tkip+aes");
691            */
692            /* Foxconn add end, Tony W.Y. Wang, 11/30/2009 */
693            nvram_set("wps_mixedmode", "1");
694            //nvram_set("wps_randomssid", "");
695            //nvram_set("wps_randomkey", "");
696            config_flag = 1;
697            /* Since we changed to mixed mode,
698             * so we need to disable WDS if it is already enabled
699             */
700            if (nvram_match("wlg_wds_enable", "1"))
701            {
702                nvram_set("wlg_wds_enable",  "0");
703                nvram_set("wl1_wds", "");
704                nvram_set("wl1_mode", "ap");
705            }
706        }
707    }
708    else if ( strncmp(nvram_safe_get("wl1_wep"), "enabled", 7) == 0 )
709    {
710        int key_len=0;
711        if ( strncmp(nvram_safe_get("wl1_auth"), "1", 1) == 0 ) /*shared mode*/
712        {
713            nvram_set("wlg_auth_type", "sharedkey");
714            nvram_set("wlg_temp_auth_type", "sharedkey");
715        }
716        else
717        {
718            nvram_set("wlg_auth_type", "opensystem");
719            nvram_set("wlg_temp_auth_type", "opensystem");
720        }
721
722        nvram_set("wlg_secu_type", "WEP");
723        nvram_set("wlg_temp_secu_type", "WEP");
724        nvram_set("wlg_defaKey", "0");
725        nvram_set("wlg_temp_defaKey", "0");
726        /* Foxconn add start by aspen Bai, 02/24/2009 */
727        /*
728        nvram_set("wla_key1", nvram_safe_get("wl_key1"));
729        nvram_set("wla_temp_key1", nvram_safe_get("wl_key1"));
730
731        printf("wla_wep_length: %d\n", strlen(nvram_safe_get("wl_key1")));
732
733        key_len = atoi(nvram_safe_get("wl_key1"));
734        */
735        nvram_set("wlg_key1", nvram_safe_get("wl1_key1"));
736        nvram_set("wlg_temp_key1", nvram_safe_get("wl1_key1"));
737
738        printf("wlg_wep_length: %d\n", strlen(nvram_safe_get("wl1_key1")));
739
740        key_len = strlen(nvram_safe_get("wl1_key1"));
741        /* Foxconn add end by aspen Bai, 02/24/2009 */
742        if (key_len==5 || key_len==10)
743        {
744            nvram_set("wlg_wep_length", "1");
745        }
746        else
747        {
748            nvram_set("wlg_wep_length", "2");
749        }
750        /* Foxconn add start by aspen Bai, 02/24/2009 */
751        if (key_len==5 || key_len==13)
752        {
753            char HexKeyArray[32];
754            char key[32], tmp[32];
755            int i;
756
757            strcpy(key, nvram_safe_get("wl1_key1"));
758            memset(HexKeyArray, 0, sizeof(HexKeyArray));
759            for (i=0; i<key_len; i++)
760            {
761                sprintf(tmp, "%02X", (unsigned char)key[i]);
762                strcat(HexKeyArray, tmp);
763            }
764            printf("ASCII WEP key (%s) convert -> HEX WEP key (%s)\n", key, HexKeyArray);
765
766            nvram_set("wlg_key1", HexKeyArray);
767            nvram_set("wlg_temp_key1", HexKeyArray);
768        }
769        /* Foxconn add end by aspen Bai, 02/24/2009 */
770    }
771    else
772    {
773        nvram_set("wlg_secu_type", "None");
774        nvram_set("wlg_temp_secu_type", "None");
775        nvram_set("wlg_passphrase", "");
776    }
777
778    if (config_flag == 1)
779    {
780        //nvram_set("wps_randomssid", "");
781        //nvram_set("wps_randomkey", "");
782        nvram_set("wl0_wps_config_state", "1");
783        nvram_set("wl1_wps_config_state", "1");
784    }
785    /* Foxconn add end, Tony W.Y. Wang, 11/23/2009 */
786    nvram_set("allow_registrar_config", "0");  /* Foxconn added pling, 05/16/2007 */
787
788    /* Foxconn added start pling 02/25/2008 */
789    /* 'wl_unit' is changed to "0.-1" after Vista configure router (using Borg DTM1.3 patch).
790     * This will make WPS fail to work on the correct interface.
791     * Set it back to "0" if it is not.
792     */
793    if (!nvram_match("wl_unit", "0"))
794        nvram_set("wl_unit", "0");
795    /* Foxconn added end pling 02/25/2008 */
796}
797/* Foxconn added end by EricHuang, 12/13/2006 */
798
799/* foxconn added start wklin, 11/02/2006 */
800static void save_wlan_time(void)
801{
802    struct sysinfo info;
803    char command[128];
804    sysinfo(&info);
805    sprintf(command, "echo %lu > /tmp/wlan_time", info.uptime);
806    system(command);
807    return;
808}
809/* foxconn added end, wklin, 11/02/2006 */
810
811/* foxconn added start, zacker, 01/13/2012, @iptv_igmp */
812#ifdef CONFIG_RUSSIA_IPTV
813static int config_iptv_params(void)
814{
815    unsigned int iptv_bridge_intf = 0x00;
816    char vlan1_ports[16] = "";
817    char vlan_iptv_ports[16] = "";
818    /*added by dennis start,05/04/2012,for guest network reconnect issue*/
819    char br0_ifnames[64]="";
820    char if_name[16]="";
821    char wl_param[16]="";
822    char command[128]="";
823    int i = 0;
824    /*added by dennis end,05/04/2012,for guest network reconnect issue*/
825
826
827    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
828    {
829        char iptv_intf[32];
830
831        strcpy(iptv_intf, nvram_safe_get(NVRAM_IPTV_INTF));
832        sscanf(iptv_intf, "0x%02X", &iptv_bridge_intf);
833    }
834
835    if (iptv_bridge_intf & IPTV_LAN1)
836        strcat(vlan_iptv_ports, "0 ");
837    else
838        strcat(vlan1_ports, "0 ");
839
840    if (iptv_bridge_intf & IPTV_LAN2)   /* Foxconn modified pling 02/09/2012, fix a typo */
841        strcat(vlan_iptv_ports, "1 ");
842    else
843        strcat(vlan1_ports, "1 ");
844
845    if (iptv_bridge_intf & IPTV_LAN3)
846        strcat(vlan_iptv_ports, "2 ");
847    else
848        strcat(vlan1_ports, "2 ");
849
850    if (iptv_bridge_intf & IPTV_LAN4)
851        strcat(vlan_iptv_ports, "3 ");
852    else
853        strcat(vlan1_ports, "3 ");
854
855    strcat(vlan1_ports, "8*");
856    nvram_set("vlan1ports", vlan1_ports);
857
858    /* build vlan3 for IGMP snooping on IPTV ports */
859    if (strlen(vlan_iptv_ports))
860    {
861        strcat(vlan_iptv_ports, "8");
862        nvram_set("vlan3ports", vlan_iptv_ports);
863        nvram_set("vlan3hwname", nvram_safe_get("vlan2hwname"));
864    }
865    else
866    {
867        nvram_unset("vlan3ports");
868        nvram_unset("vlan3hwname");
869    }
870
871    if (iptv_bridge_intf & IPTV_MASK)
872    {
873        char lan_ifnames[32] = "vlan1 ";
874        char wan_ifnames[32] = "vlan2 ";
875
876#ifdef __CONFIG_IGMP_SNOOPING__
877        /* always enable snooping for IPTV */
878        nvram_set("emf_enable", "1");
879#endif
880
881        /* always build vlan2 and br1 and enable vlan tag output for all vlan */
882        nvram_set("vlan2ports", "4 8");
883
884        /* build vlan3 for IGMP snooping on IPTV ports */
885        if (strlen(vlan_iptv_ports))
886            strcat(wan_ifnames, "vlan3 ");
887
888        if (iptv_bridge_intf & IPTV_WLAN1)
889            strcat(wan_ifnames, "eth1 ");
890        else
891            strcat(lan_ifnames, "eth1 ");
892
893        if (iptv_bridge_intf & IPTV_WLAN2)
894            strcat(wan_ifnames, "eth2 ");
895        else
896            strcat(lan_ifnames, "eth2 ");
897
898
899
900        //nvram_set("lan_ifnames", lan_ifnames);
901        strcpy(br0_ifnames,lan_ifnames);
902        nvram_set("wan_ifnames", wan_ifnames);
903        nvram_set("lan1_ifnames", wan_ifnames);
904
905        nvram_set("wan_ifname", "br1");
906        nvram_set("lan1_ifname", "br1");
907    }
908    else
909    {
910
911        //nvram_set("lan_ifnames", "vlan1 eth1 eth2 wl0.1");
912        /*modified by dennis start, 05/03/2012,fixed guest network cannot reconnect issue*/
913        strcpy(br0_ifnames,"vlan1 eth1 eth2");
914        /*modified by dennis end, 05/03/2012,fixed guest network cannot reconnect issue*/
915        nvram_set("lan1_ifnames", "");
916        nvram_set("lan1_ifname", "");
917
918#ifdef __CONFIG_IGMP_SNOOPING__
919        if (nvram_match("emf_enable", "1"))
920        {
921            nvram_set("vlan2ports", "4 8");
922            nvram_set("wan_ifnames", "vlan2 ");
923            nvram_set("wan_ifname", "vlan2");
924        }
925        else
926#endif
927        {
928            nvram_set("vlan2ports", "4 8u");
929            nvram_set("wan_ifnames", "eth0 ");
930            nvram_set("wan_ifname", "eth0");
931
932        }
933    }
934
935     /*added by dennis start, 05/03/2012,fixed guest network cannot reconnect issue*/
936     for(i = MIN_BSSID_NUM; i <= MAX_BSSID_NUM; i++){
937        sprintf(wl_param, "%s_%d", "wla_sec_profile_enable", i);
938        if(nvram_match(wl_param, "1")){
939            sprintf(if_name, "wl0.%d", i-1);
940            strcat(br0_ifnames, " ");
941            strcat(br0_ifnames, if_name);
942        }
943     }
944
945     for(i = MIN_BSSID_NUM; i <= MAX_BSSID_NUM; i++){
946         sprintf(wl_param, "%s_%d", "wlg_sec_profile_enable", i);
947         if(nvram_match(wl_param, "1")){
948             sprintf(if_name, "wl1.%d", i-1);
949             strcat(br0_ifnames, " ");
950             strcat(br0_ifnames, if_name);
951         }
952     }
953     nvram_set("lan_ifnames", br0_ifnames);
954    /*added by dennis start, 05/03/2012,fixed guest network cannot reconnect issue*/
955
956    /* Foxconn added start pling 09/10/2012 */
957    /* Fix: When IPTV is enabled, WAN interface is "br1".
958     * This can cause CTF/pktc to work abnormally.
959     * So bypass CTF/pktc altogether */
960    if (nvram_match(NVRAM_IPTV_ENABLED, "1"))
961        eval("et", "robowr", "0xFFFF", "0xFB", "1");
962    else
963        eval("et", "robowr", "0xFFFF", "0xFB", "0");
964    /* Foxconn added end pling 09/10/2012 */
965
966    return 0;
967}
968
969static int active_vlan(void)
970{
971    char buf[128];
972    unsigned char mac[ETHER_ADDR_LEN];
973    char eth0_mac[32];
974
975    strcpy(eth0_mac, nvram_safe_get("et0macaddr"));
976    ether_atoe(eth0_mac, mac);
977
978    /* Set MAC address byte 0 */
979    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X%02X", VCFG_PAGE, VCFG_REG, MAC_BYTE0, mac[0]);
980    system(buf);
981    /* Set MAC address byte 1 */
982    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X%02X", VCFG_PAGE, VCFG_REG, MAC_BYTE1, mac[1]);
983    system(buf);
984    /* Set MAC address byte 2 */
985    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X%02X", VCFG_PAGE, VCFG_REG, MAC_BYTE2, mac[2]);
986    system(buf);
987    /* Set MAC address byte 3 */
988    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X%02X", VCFG_PAGE, VCFG_REG, MAC_BYTE3, mac[3]);
989    system(buf);
990    /* Set MAC address byte 4 */
991    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X%02X", VCFG_PAGE, VCFG_REG, MAC_BYTE4, mac[4]);
992    system(buf);
993    /* Set MAC address byte 5 */
994    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X%02X", VCFG_PAGE, VCFG_REG, MAC_BYTE5, mac[5]);
995    system(buf);
996    /* Issue command to activate new vlan configuration. */
997    sprintf(buf, "et robowr 0x%04X 0x%02X 0x%02X00", VCFG_PAGE, VCFG_REG, SET_VLAN);
998    system(buf);
999
1000    return 0;
1001}
1002#endif
1003
1004#if (defined INCLUDE_QOS) || (defined __CONFIG_IGMP_SNOOPING__)
1005/* these settings are for BCM53115S switch */
1006static int config_switch_reg(void)
1007{
1008    if (
1009#if (defined __CONFIG_IGMP_SNOOPING__)
1010        nvram_match("emf_enable", "1") ||
1011#endif
1012        (nvram_match("qos_enable", "1")
1013        && !nvram_match("wla_repeater", "1")
1014#if (defined INCLUDE_DUAL_BAND)
1015        && !nvram_match("wlg_repeater", "1")
1016#endif
1017        && !nvram_match("qos_port", "")))
1018    {
1019        /* Enables the receipt of unicast, multicast and broadcast on IMP port */
1020        system("et robowr 0x00 0x08 0x1C");
1021        /* Enable Frame-managment mode */
1022        system("et robowr 0x00 0x0B 0x07");
1023        /* Enable management port */
1024        system("et robowr 0x02 0x00 0x80");
1025        /* CRC bypass and auto generation */
1026        system("et robowr 0x34 0x06 0x11");
1027#if (defined __CONFIG_IGMP_SNOOPING__)
1028        if (nvram_match("emf_enable", "1"))
1029        {
1030            /* Set IMP port default tag id */
1031            system("et robowr 0x34 0x20 0x02");
1032            /* Enable IPMC bypass V fwdmap */
1033            system("et robowr 0x34 0x01 0x2E");
1034            /* Set Multiport address enable */
1035            system("et robowr 0x04 0x0E 0x0AAA");
1036        }
1037#endif
1038        /* Turn on the flags for kernel space (et/emf/igs) handling */
1039        system("et robowr 0xFFFF 0xFE 0x03");
1040    }
1041    else
1042    {
1043        system("et robowr 0x00 0x08 0x00");
1044        system("et robowr 0x00 0x0B 0x06");
1045        system("et robowr 0x02 0x00 0x00");
1046        system("et robowr 0x34 0x06 0x10");
1047#if (defined __CONFIG_IGMP_SNOOPING__)
1048        system("et robowr 0x34 0x20 0x02");
1049        system("et robowr 0x34 0x01 0x0E");
1050        system("et robowr 0x04 0x0E 0x0000");
1051#endif
1052        if (nvram_match("qos_enable", "1"))
1053            system("et robowr 0xFFFF 0xFE 0x01");
1054        else if (!nvram_match("qos_port", ""))
1055            system("et robowr 0xFFFF 0xFE 0x02");
1056        else
1057            system("et robowr 0xFFFF 0xFE 0x00");
1058    }
1059
1060    return 0;
1061}
1062/* foxconn added end, zacker, 01/13/2012, @iptv_igmp */
1063
1064/* foxconn modified start, zacker, 01/13/2012, @iptv_igmp */
1065static void config_switch(void)
1066{
1067    /* BCM5325 & BCM53115 switch request to change these vars
1068     * to output ethernet port tag/id in packets.
1069     */
1070    struct nvram_tuple generic[] = {
1071        { "wan_ifname", "eth0", 0 },
1072        { "wan_ifnames", "eth0 ", 0 },
1073        { "vlan1ports", "0 1 2 3 8*", 0 },
1074        { "vlan2ports", "4 8u", 0 },
1075        { 0, 0, 0 }
1076    };
1077
1078    struct nvram_tuple vlan[] = {
1079        { "wan_ifname", "vlan2", 0 },
1080        { "wan_ifnames", "vlan2 ", 0 },
1081        { "vlan1ports", "0 1 2 3 8*", 0 },
1082        { "vlan2ports", "4 8", 0 },
1083        { 0, 0, 0 }
1084    };
1085
1086    struct nvram_tuple *u = generic;
1087    int commit = 0;
1088
1089    if (nvram_match("emf_enable", "1")) {
1090        u = vlan;
1091    }
1092
1093    /* don't need vlan in repeater mode */
1094    if (nvram_match("wla_repeater", "1")
1095#if (defined INCLUDE_DUAL_BAND)
1096        || nvram_match("wlg_repeater", "1")
1097#endif
1098        ) {
1099        u = generic;
1100    }
1101
1102    for ( ; u && u->name; u++) {
1103        if (strcmp(nvram_safe_get(u->name), u->value)) {
1104            commit = 1;
1105            nvram_set(u->name, u->value);
1106        }
1107    }
1108
1109    if (commit) {
1110        cprintf("Commit new ethernet config...\n");
1111        nvram_commit();
1112        commit = 0;
1113    }
1114}
1115#endif
1116/* foxconn modified end, zacker, 01/13/2012, @iptv_igmp */
1117
1118/* foxconn modified start, zacker, 01/04/2011 */
1119static int should_stop_wps(void)
1120{
1121    /* WPS LED OFF */
1122    if (nvram_match("wla_wlanstate","Disable")
1123#if (defined INCLUDE_DUAL_BAND)
1124        && nvram_match("wlg_wlanstate","Disable")
1125#endif
1126       )
1127        return WPS_LED_STOP_RADIO_OFF;
1128
1129    /* WPS LED quick blink for 5sec */
1130    if (nvram_match("wps_mode", "disabled")
1131        || nvram_match("wla_repeater", "1")
1132#if (defined INCLUDE_DUAL_BAND)
1133        || nvram_match("wlg_repeater", "1")
1134#endif
1135       )
1136        return WPS_LED_STOP_DISABLED;
1137
1138    /* WPS LED original action */
1139    return WPS_LED_STOP_NO;
1140}
1141
1142static int is_secure_wl(void)
1143{
1144    if (   (!nvram_match("wla_secu_type", "None")
1145            && nvram_match("wla_wlanstate","Enable"))
1146#if (defined INCLUDE_DUAL_BAND)
1147        || (!nvram_match("wlg_secu_type", "None")
1148            && nvram_match("wlg_wlanstate","Enable"))
1149#endif
1150        )
1151        return 1;
1152
1153    return 0;
1154}
1155
1156/* Foxconn added start, Wins, 04/20/2011 @RU_IPTV */
1157#ifdef CONFIG_RUSSIA_IPTV
1158static int is_russia_specific_support (void)
1159{
1160    int result = 0;
1161    char sku_name[8];
1162
1163    /* Router Spec v2.0:                                                        *
1164     *   Case 1: RU specific firmware.                                          *
1165     *   Case 2: single firmware & region code is RU.                           *
1166     *   Case 3: WW firmware & GUI language is Russian.                         *
1167     *   Case 4: single firmware & region code is WW & GUI language is Russian. *
1168     * Currently, new built firmware will be single firmware.                   */
1169    strcpy(sku_name, nvram_get("sku_name"));
1170    if (!strcmp(sku_name, "RU"))
1171    {
1172        /* Case 2: single firmware & region code is RU. */
1173        /* Region is RU (0x0005) */
1174        result = 1;
1175    }
1176    else if (!strcmp(sku_name, "WW"))
1177    {
1178        /* Region is WW (0x0002) */
1179        char gui_region[16];
1180        strcpy(gui_region, nvram_get("gui_region"));
1181        if (!strcmp(gui_region, "Russian"))
1182        {
1183            /* Case 4: single firmware & region code is WW & GUI language is Russian */
1184            /* GUI language is Russian */
1185            result = 1;
1186        }
1187    }
1188
1189    return result;
1190}
1191#endif /* CONFIG_RUSSIA_IPTV */
1192/* Foxconn added end, Wins, 04/20/2011 @RU_IPTV */
1193
1194static int send_wps_led_cmd(int cmd, int arg)
1195{
1196    int ret_val=0;
1197    int fd;
1198
1199    fd = open(DEV_WPS_LED, O_RDWR);
1200    if (fd < 0)
1201        return -1;
1202
1203    if (is_secure_wl())
1204        arg = 1;
1205    else
1206        arg = 0;
1207
1208    switch (should_stop_wps())
1209    {
1210        case WPS_LED_STOP_RADIO_OFF:
1211            cmd = WPS_LED_BLINK_OFF;
1212            break;
1213
1214        case WPS_LED_STOP_DISABLED:
1215            if (cmd == WPS_LED_BLINK_NORMAL)
1216                cmd = WPS_LED_BLINK_QUICK;
1217            break;
1218
1219        case WPS_LED_STOP_NO:
1220        default:
1221            break;
1222    }
1223
1224    ret_val = ioctl(fd, cmd, arg);
1225    close(fd);
1226
1227    return ret_val;
1228}
1229/* foxconn modified end, zacker, 01/04/2011 */
1230
1231static int
1232build_ifnames(char *type, char *names, int *size)
1233{
1234	char name[32], *next;
1235	int len = 0;
1236	int s;
1237
1238	/* open a raw scoket for ioctl */
1239	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
1240		return -1;
1241
1242	/*
1243	 * go thru all device names (wl<N> il<N> et<N> vlan<N>) and interfaces to
1244	 * build an interface name list in which each i/f name coresponds to a device
1245	 * name in device name list. Interface/device name matching rule is device
1246	 * type dependant:
1247	 *
1248	 *	wl:	by unit # provided by the driver, for example, if eth1 is wireless
1249	 *		i/f and its unit # is 0, then it will be in the i/f name list if
1250	 *		wl0 is in the device name list.
1251	 *	il/et:	by mac address, for example, if et0's mac address is identical to
1252	 *		that of eth2's, then eth2 will be in the i/f name list if et0 is
1253	 *		in the device name list.
1254	 *	vlan:	by name, for example, vlan0 will be in the i/f name list if vlan0
1255	 *		is in the device name list.
1256	 */
1257	foreach(name, type, next) {
1258		struct ifreq ifr;
1259		int i, unit;
1260		char var[32], *mac;
1261		unsigned char ea[ETHER_ADDR_LEN];
1262
1263		/* vlan: add it to interface name list */
1264		if (!strncmp(name, "vlan", 4)) {
1265			/* append interface name to list */
1266			len += snprintf(&names[len], *size - len, "%s ", name);
1267			continue;
1268		}
1269
1270		/* others: proceed only when rules are met */
1271		for (i = 1; i <= DEV_NUMIFS; i ++) {
1272			/* ignore i/f that is not ethernet */
1273			ifr.ifr_ifindex = i;
1274			if (ioctl(s, SIOCGIFNAME, &ifr))
1275				continue;
1276			if (ioctl(s, SIOCGIFHWADDR, &ifr))
1277				continue;
1278			if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
1279				continue;
1280			if (!strncmp(ifr.ifr_name, "vlan", 4))
1281				continue;
1282
1283			/* wl: use unit # to identify wl */
1284			if (!strncmp(name, "wl", 2)) {
1285				if (wl_probe(ifr.ifr_name) ||
1286				    wl_ioctl(ifr.ifr_name, WLC_GET_INSTANCE, &unit, sizeof(unit)) ||
1287				    unit != atoi(&name[2]))
1288					continue;
1289			}
1290			/* et/il: use mac addr to identify et/il */
1291			else if (!strncmp(name, "et", 2) || !strncmp(name, "il", 2)) {
1292				snprintf(var, sizeof(var), "%smacaddr", name);
1293				if (!(mac = nvram_get(var)) || !ether_atoe(mac, ea) ||
1294				    bcmp(ea, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN))
1295					continue;
1296			}
1297			/* mac address: compare value */
1298			else if (ether_atoe(name, ea) &&
1299				!bcmp(ea, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN))
1300				;
1301			/* others: ignore */
1302			else
1303				continue;
1304
1305			/* append interface name to list */
1306			len += snprintf(&names[len], *size - len, "%s ", ifr.ifr_name);
1307		}
1308	}
1309
1310	close(s);
1311
1312	*size = len;
1313	return 0;
1314}
1315
1316#ifdef __CONFIG_WPS__
1317static void rc_randomKey()
1318{
1319	char random_ssid[33] = {0};
1320	unsigned char random_key[65] = {0};
1321	int i = 0;
1322	unsigned short key_length;
1323
1324	RAND_bytes((unsigned char *)&key_length, sizeof(key_length));
1325	key_length = ((((long)key_length + 56791 )*13579)%8) + 8;
1326
1327	/* random a ssid */
1328	sprintf(random_ssid, "Broadcom_");
1329
1330	while (i < 6) {
1331		RAND_bytes(&random_ssid[9 + i], 1);
1332		if ((islower(random_ssid[9 + i]) || isdigit(random_ssid[9 + i])) && (random_ssid[9 + i] < 0x7f)) {
1333			i++;
1334		}
1335	}
1336
1337	nvram_set("wl_ssid", random_ssid);
1338
1339	i = 0;
1340	/* random a key */
1341	while (i < key_length) {
1342		RAND_bytes(&random_key[i], 1);
1343		if ((islower(random_key[i]) || isdigit(random_key[i])) && (random_key[i] < 0x7f)) {
1344			i++;
1345		}
1346	}
1347	random_key[key_length] = 0;
1348
1349	nvram_set("wl_wpa_psk", random_key);
1350
1351	/* Set default config to wps-psk, tkip */
1352	nvram_set("wl_akm", "psk ");
1353	nvram_set("wl_auth", "0");
1354	nvram_set("wl_wep", "disabled");
1355	nvram_set("wl_crypto", "tkip");
1356
1357}
1358static void
1359wps_restore_defaults(void)
1360{
1361	/* cleanly up nvram for WPS */
1362	nvram_unset("wps_config_state");
1363	nvram_unset("wps_device_pin");
1364	nvram_unset("wps_proc_status");
1365	nvram_unset("wps_sta_pin");
1366	nvram_unset("wps_restart");
1367	nvram_unset("wps_config_method");
1368}
1369#endif /* __CONFIG_WPS__ */
1370static void
1371ses_cleanup(void)
1372{
1373	/* well known event to cleanly initialize state machine */
1374	nvram_set("ses_event", "2");
1375
1376	/* Delete lethal dynamically generated variables */
1377	nvram_unset("ses_bridge_disable");
1378}
1379
1380static void
1381ses_restore_defaults(void)
1382{
1383	char tmp[100], prefix[] = "wlXXXXXXXXXX_ses_";
1384	int i, j;
1385	int len = 0;
1386
1387	/* Delete dynamically generated variables */
1388	for (i = 0; i < MAX_NVPARSE; i++) {
1389		sprintf(prefix, "wl%d_ses_", i);
1390		nvram_unset(strcat_r(prefix, "ssid", tmp));
1391		nvram_unset(strcat_r(prefix, "closed", tmp));
1392		nvram_unset(strcat_r(prefix, "wpa_psk", tmp));
1393		nvram_unset(strcat_r(prefix, "auth", tmp));
1394		nvram_unset(strcat_r(prefix, "wep", tmp));
1395		nvram_unset(strcat_r(prefix, "auth_mode", tmp));
1396		nvram_unset(strcat_r(prefix, "crypto", tmp));
1397		nvram_unset(strcat_r(prefix, "akm", tmp));
1398		nvram_unset(strcat_r(prefix, "wds", tmp));
1399		nvram_unset(strcat_r(prefix, "wds_timeout", tmp));
1400	}
1401
1402	/* Delete dynamically generated variables */
1403	for (i = 0; i < DEV_NUMIFS; i++) {
1404		sprintf(prefix, "wl%d_wds", i);
1405		len = strlen(prefix);
1406		for (j = 0; j < MAX_NVPARSE; j++) {
1407			sprintf(&prefix[len], "%d", j);
1408			nvram_unset(prefix);
1409		}
1410	}
1411
1412	nvram_unset("ses_fsm_current_states");
1413	nvram_unset("ses_fsm_last_status");
1414}
1415static void
1416virtual_radio_restore_defaults(void)
1417{
1418	char tmp[100], prefix[] = "wlXXXXXXXXXX_mssid_";
1419	int i, j;
1420
1421	nvram_unset("unbridged_ifnames");
1422	nvram_unset("ure_disable");
1423
1424	/* Delete dynamically generated variables */
1425	for (i = 0; i < MAX_NVPARSE; i++) {
1426		sprintf(prefix, "wl%d_", i);
1427		nvram_unset(strcat_r(prefix, "vifs", tmp));
1428		nvram_unset(strcat_r(prefix, "ssid", tmp));
1429		nvram_unset(strcat_r(prefix, "guest", tmp));
1430		nvram_unset(strcat_r(prefix, "ure", tmp));
1431		nvram_unset(strcat_r(prefix, "ipconfig_index", tmp));
1432		nvram_unset(strcat_r(prefix, "nas_dbg", tmp));
1433		sprintf(prefix, "lan%d_", i);
1434		nvram_unset(strcat_r(prefix, "ifname", tmp));
1435		nvram_unset(strcat_r(prefix, "ifnames", tmp));
1436		nvram_unset(strcat_r(prefix, "gateway", tmp));
1437		nvram_unset(strcat_r(prefix, "proto", tmp));
1438		nvram_unset(strcat_r(prefix, "ipaddr", tmp));
1439		nvram_unset(strcat_r(prefix, "netmask", tmp));
1440		nvram_unset(strcat_r(prefix, "lease", tmp));
1441		nvram_unset(strcat_r(prefix, "stp", tmp));
1442		nvram_unset(strcat_r(prefix, "hwaddr", tmp));
1443		sprintf(prefix, "dhcp%d_", i);
1444		nvram_unset(strcat_r(prefix, "start", tmp));
1445		nvram_unset(strcat_r(prefix, "end", tmp));
1446
1447		/* clear virtual versions */
1448		for (j = 0; j < 16; j++) {
1449			sprintf(prefix, "wl%d.%d_", i, j);
1450			nvram_unset(strcat_r(prefix, "ssid", tmp));
1451			nvram_unset(strcat_r(prefix, "ipconfig_index", tmp));
1452			nvram_unset(strcat_r(prefix, "guest", tmp));
1453			nvram_unset(strcat_r(prefix, "closed", tmp));
1454			nvram_unset(strcat_r(prefix, "wpa_psk", tmp));
1455			nvram_unset(strcat_r(prefix, "auth", tmp));
1456			nvram_unset(strcat_r(prefix, "wep", tmp));
1457			nvram_unset(strcat_r(prefix, "auth_mode", tmp));
1458			nvram_unset(strcat_r(prefix, "crypto", tmp));
1459			nvram_unset(strcat_r(prefix, "akm", tmp));
1460			nvram_unset(strcat_r(prefix, "hwaddr", tmp));
1461			nvram_unset(strcat_r(prefix, "bss_enabled", tmp));
1462			nvram_unset(strcat_r(prefix, "bss_maxassoc", tmp));
1463			nvram_unset(strcat_r(prefix, "wme_bss_disable", tmp));
1464			nvram_unset(strcat_r(prefix, "ifname", tmp));
1465			nvram_unset(strcat_r(prefix, "unit", tmp));
1466			nvram_unset(strcat_r(prefix, "ap_isolate", tmp));
1467			nvram_unset(strcat_r(prefix, "macmode", tmp));
1468			nvram_unset(strcat_r(prefix, "maclist", tmp));
1469			nvram_unset(strcat_r(prefix, "maxassoc", tmp));
1470			nvram_unset(strcat_r(prefix, "mode", tmp));
1471			nvram_unset(strcat_r(prefix, "radio", tmp));
1472			nvram_unset(strcat_r(prefix, "radius_ipaddr", tmp));
1473			nvram_unset(strcat_r(prefix, "radius_port", tmp));
1474			nvram_unset(strcat_r(prefix, "radius_key", tmp));
1475			nvram_unset(strcat_r(prefix, "key", tmp));
1476			nvram_unset(strcat_r(prefix, "key1", tmp));
1477			nvram_unset(strcat_r(prefix, "key2", tmp));
1478			nvram_unset(strcat_r(prefix, "key3", tmp));
1479			nvram_unset(strcat_r(prefix, "key4", tmp));
1480			nvram_unset(strcat_r(prefix, "wpa_gtk_rekey", tmp));
1481			nvram_unset(strcat_r(prefix, "nas_dbg", tmp));
1482		}
1483	}
1484}
1485
1486#ifdef __CONFIG_URE__
1487static void
1488ure_restore_defaults(int unit)
1489{
1490	char tmp[100], prefix[] = "wlXXXXXXXXXX_";
1491	struct nvram_tuple *t;
1492
1493	sprintf(prefix, "wl%d.1_", unit);
1494
1495	for (t = router_defaults; t->name; t++) {
1496		if (!strncmp(t->name, "wl_", 3)) {
1497			strcat_r(prefix, &t->name[3], tmp);
1498			nvram_unset(tmp);
1499		}
1500	}
1501
1502	sprintf(prefix, "wl%d_ure", unit);
1503	nvram_unset(prefix);
1504}
1505
1506static void
1507set_ure_vars(int unit)
1508{
1509	int wl_unit = unit;
1510	int travel_router;
1511	char prefix[] = "wlXXXXXXXXXX_";
1512	struct nvram_tuple *t;
1513	char nv_param[NVRAM_MAX_PARAM_LEN];
1514	char nv_value[NVRAM_MAX_VALUE_LEN];
1515	char nv_interface[NVRAM_MAX_PARAM_LEN];
1516	char os_interface[NVRAM_MAX_PARAM_LEN];
1517	int os_interface_size = sizeof(os_interface);
1518	char *temp = NULL;
1519	char interface_list[NVRAM_MAX_VALUE_LEN];
1520	int interface_list_size = sizeof(interface_list);
1521	char *wan0_ifname = "wan0_ifname";
1522	char *lan_ifnames = "lan_ifnames";
1523	char *wan_ifnames = "wan_ifnames";
1524
1525	sprintf(prefix, "wl%d.1_", wl_unit);
1526
1527	/* Clone default wl nvram settings to wl0.1 */
1528	for (t = router_defaults; t->name; t++) {
1529		if (!strncmp(t->name, "wl_", 3)) {
1530			strcat_r(prefix, &t->name[3], nv_param);
1531			nvram_set(nv_param, t->value);
1532		}
1533	}
1534
1535	/* Overwrite some specific nvram settings */
1536	sprintf(nv_param, "wl%d_ure", wl_unit);
1537	nvram_set(nv_param, "1");
1538
1539	sprintf(nv_param, "wl%d_vifs", wl_unit);
1540	sprintf(nv_value, "wl%d.1", wl_unit);
1541	nvram_set(nv_param, nv_value);
1542
1543	sprintf(nv_param, "wl%d.1_unit", wl_unit);
1544	sprintf(nv_value, "%d.1", wl_unit);
1545	nvram_set(nv_param, nv_value);
1546
1547	nvram_set("wl_ampdu_rr_rtylimit_tid", "3 3 3 3 3 3 3 3");
1548	nvram_set("wl_ampdu_rtylimit_tid", "7 7 7 7 7 7 7 7");
1549	sprintf(nv_param, "wl%d_ampdu_rr_rtylimit_tid", wl_unit);
1550	nvram_set(nv_param, "3 3 3 3 3 3 3 3");
1551	sprintf(nv_param, "wl%d_ampdu_rtylimit_tid", wl_unit);
1552	nvram_set(nv_param, "7 7 7 7 7 7 7 7");
1553
1554	if (nvram_match("router_disable", "1"))
1555		travel_router = 0;
1556	else
1557		travel_router = 1;
1558
1559	/* Set the wl modes for the primary wireless adapter
1560	 * and it's virtual interface
1561	 */
1562	sprintf(nv_param, "wl%d_mode", wl_unit);
1563	if (travel_router == 1) {
1564		nvram_set(nv_param, "sta");
1565		nvram_set("wl_mode", "sta");
1566	}
1567	else {
1568		nvram_set(nv_param, "wet");
1569		nvram_set("wl_mode", "wet");
1570	}
1571
1572	sprintf(nv_param, "wl%d.1_mode", wl_unit);
1573	nvram_set(nv_param, "ap");
1574
1575	if (travel_router == 1) {
1576		/* For URE with routing (Travel Router) we're using the STA part
1577		 * of our URE enabled radio as our WAN connection. So, we need to
1578		 * remove this interface from the list of bridged lan interfaces
1579		 * and set it up as the WAN device.
1580		 */
1581		temp = nvram_safe_get(lan_ifnames);
1582		strncpy(interface_list, temp, interface_list_size);
1583
1584		/* Leverage build_ifnames() to get OS-dependent interface name.
1585		 * One white space is appended after build_ifnames(); need to
1586		 * remove it.
1587		 */
1588		sprintf(nv_interface, "wl%d", wl_unit);
1589		memset(os_interface, 0, os_interface_size);
1590		build_ifnames(nv_interface, os_interface, &os_interface_size);
1591		if (strlen(os_interface) > 1) {
1592			os_interface[strlen(os_interface) - 1] = '\0';
1593		}
1594		remove_from_list(os_interface, interface_list, interface_list_size);
1595		nvram_set(lan_ifnames, interface_list);
1596
1597		/* Now remove the existing WAN interface from "wan_ifnames" */
1598		temp = nvram_safe_get(wan_ifnames);
1599		strncpy(interface_list, temp, interface_list_size);
1600
1601		temp = nvram_safe_get(wan0_ifname);
1602		if (strlen(temp) != 0) {
1603			/* Stash this interface name in an nvram variable in case
1604			 * we need to restore this interface as the WAN interface
1605			 * when URE is disabled.
1606			 */
1607			nvram_set("old_wan0_ifname", temp);
1608			remove_from_list(temp, interface_list, interface_list_size);
1609		}
1610
1611		/* Set the new WAN interface as the pimary WAN interface and add to
1612		 * the list wan_ifnames.
1613		 */
1614		nvram_set(wan0_ifname, os_interface);
1615		add_to_list(os_interface, interface_list, interface_list_size);
1616		nvram_set(wan_ifnames, interface_list);
1617
1618		/* Now add the AP to the list of bridged lan interfaces */
1619		temp = nvram_safe_get(lan_ifnames);
1620		strncpy(interface_list, temp, interface_list_size);
1621		sprintf(nv_interface, "wl%d.1", wl_unit);
1622
1623		/* Virtual interfaces that appear in NVRAM lists are ALWAYS stored
1624		 * as the NVRAM_FORM so we can add to list without translating.
1625		 */
1626		add_to_list(nv_interface, interface_list, interface_list_size);
1627		nvram_set(lan_ifnames, interface_list);
1628	}
1629	else {
1630		/* For URE without routing (Range Extender) we're using the STA
1631		 * as a WET device to connect to the "upstream" AP. We need to
1632		 * add our virtual interface(AP) to the bridged lan.
1633		 */
1634		temp = nvram_safe_get(lan_ifnames);
1635		strncpy(interface_list, temp, interface_list_size);
1636
1637		sprintf(nv_interface, "wl%d.1", wl_unit);
1638		add_to_list(nv_interface, interface_list, interface_list_size);
1639		nvram_set(lan_ifnames, interface_list);
1640	}
1641
1642	/* Make lan1_ifname, lan1_ifnames empty so that br1 is not created in URE mode. */
1643	nvram_set("lan1_ifname", "");
1644	nvram_set("lan1_ifnames", "");
1645
1646	if (nvram_match("wl0_ure_mode", "wre")) {
1647		/* By default, wl0 bss is disabled in WRE mode */
1648		nvram_set("wl_bss_enabled", "0");
1649		nvram_set("wl0_bss_enabled", "0");
1650#ifdef __CONFIG_HSPOT__
1651		nvram_set("wl_bss_hs2_enabled", "0");
1652		nvram_set("wl0_bss_hs2_enabled", "0");
1653#endif  /* __CONFIG_HSPOT__ */
1654	}
1655}
1656#endif /* __CONFIG_URE__ */
1657
1658static void
1659ses_cl_cleanup(void)
1660{
1661	/* well known event to cleanly initialize state machine */
1662	nvram_set("ses_cl_event", "0");
1663}
1664
1665#ifdef __CONFIG_NAT__
1666static void
1667auto_bridge(void)
1668{
1669
1670	struct nvram_tuple generic[] = {
1671		{ "lan_ifname", "br0", 0 },
1672		{ "lan_ifnames", "eth0 eth2 eth3 eth4", 0 },
1673		{ "wan_ifname", "eth1", 0 },
1674		{ "wan_ifnames", "eth1", 0 },
1675		{ 0, 0, 0 }
1676	};
1677#ifdef __CONFIG_VLAN__
1678	struct nvram_tuple vlan[] = {
1679		{ "lan_ifname", "br0", 0 },
1680		{ "lan_ifnames", "vlan0 eth1 eth2 eth3", 0 },
1681		{ "wan_ifname", "vlan1", 0 },
1682		{ "wan_ifnames", "vlan1", 0 },
1683		{ 0, 0, 0 }
1684	};
1685#endif	/* __CONFIG_VLAN__ */
1686	struct nvram_tuple dyna[] = {
1687		{ "lan_ifname", "br0", 0 },
1688		{ "lan_ifnames", "", 0 },
1689		{ "wan_ifname", "", 0 },
1690		{ "wan_ifnames", "", 0 },
1691		{ 0, 0, 0 }
1692	};
1693	struct nvram_tuple generic_auto_bridge[] = {
1694		{ "lan_ifname", "br0", 0 },
1695		{ "lan_ifnames", "eth0 eth1 eth2 eth3 eth4", 0 },
1696		{ "wan_ifname", "", 0 },
1697		{ "wan_ifnames", "", 0 },
1698		{ 0, 0, 0 }
1699	};
1700#ifdef __CONFIG_VLAN__
1701	struct nvram_tuple vlan_auto_bridge[] = {
1702		{ "lan_ifname", "br0", 0 },
1703		{ "lan_ifnames", "vlan0 vlan1 eth1 eth2 eth3", 0 },
1704		{ "wan_ifname", "", 0 },
1705		{ "wan_ifnames", "", 0 },
1706		{ 0, 0, 0 }
1707	};
1708#endif	/* __CONFIG_VLAN__ */
1709
1710	struct nvram_tuple dyna_auto_bridge[] = {
1711		{ "lan_ifname", "br0", 0 },
1712		{ "lan_ifnames", "", 0 },
1713		{ "wan_ifname", "", 0 },
1714		{ "wan_ifnames", "", 0 },
1715		{ 0, 0, 0 }
1716	};
1717
1718	struct nvram_tuple *linux_overrides;
1719	struct nvram_tuple *t, *u;
1720	int auto_bridge=0, i;
1721#ifdef __CONFIG_VLAN__
1722	uint boardflags;
1723#endif	/* __CONFIG_VLAN_ */
1724	char *landevs, *wandevs;
1725	char lan_ifnames[128], wan_ifnames[128];
1726	char dyna_auto_ifnames[128];
1727	char wan_ifname[32], *next;
1728	int len;
1729	int ap=0;
1730
1731	printf(" INFO : enter function auto_bridge()\n");
1732
1733	if (!strcmp(nvram_safe_get("auto_bridge_action"),"1")){
1734		auto_bridge=1;
1735		cprintf("INFO: Start auto bridge...\n");
1736	}
1737	else{
1738		nvram_set("router_disable_auto", "0");
1739		cprintf("INFO: Start non auto_bridge...\n");
1740	}
1741
1742
1743	/* Delete dynamically generated variables */
1744	if (auto_bridge) {
1745		char tmp[100], prefix[] = "wlXXXXXXXXXX_";
1746		for (i = 0; i < MAX_NVPARSE; i++) {
1747
1748			del_filter_client(i);
1749			del_forward_port(i);
1750#if !defined(AUTOFW_PORT_DEPRECATED)
1751			del_autofw_port(i);
1752#endif
1753
1754			snprintf(prefix, sizeof(prefix), "wan%d_", i);
1755			for (t = router_defaults; t->name; t ++) {
1756				if (!strncmp(t->name, "wan_", 4))
1757					nvram_unset(strcat_r(prefix, &t->name[4], tmp));
1758			}
1759		}
1760	}
1761
1762	/*
1763	 * Build bridged i/f name list and wan i/f name list from lan device name list
1764	 * and wan device name list. Both lan device list "landevs" and wan device list
1765	 * "wandevs" must exist in order to preceed.
1766	 */
1767	if ((landevs = nvram_get("landevs")) && (wandevs = nvram_get("wandevs"))) {
1768		/* build bridged i/f list based on nvram variable "landevs" */
1769		len = sizeof(lan_ifnames);
1770		if (!build_ifnames(landevs, lan_ifnames, &len) && len)
1771			dyna[1].value = lan_ifnames;
1772		else
1773			goto canned_config;
1774		/* build wan i/f list based on nvram variable "wandevs" */
1775		len = sizeof(wan_ifnames);
1776		if (!build_ifnames(wandevs, wan_ifnames, &len) && len) {
1777			dyna[3].value = wan_ifnames;
1778			foreach (wan_ifname, wan_ifnames, next) {
1779				dyna[2].value = wan_ifname;
1780				break;
1781			}
1782		}
1783		else
1784			ap = 1;
1785
1786		if(auto_bridge)
1787		{
1788
1789			printf("INFO: lan_ifnames=%s\n", lan_ifnames);
1790			printf("INFO: wan_ifnames=%s\n", wan_ifnames);
1791			sprintf(dyna_auto_ifnames, "%s %s", lan_ifnames, wan_ifnames);
1792			printf("INFO: dyna_auto_ifnames=%s\n", dyna_auto_ifnames);
1793			dyna_auto_bridge[1].value = dyna_auto_ifnames;
1794			linux_overrides = dyna_auto_bridge;
1795			printf("INFO: linux_overrides=dyna_auto_bridge \n");
1796		}
1797		else
1798		{
1799			linux_overrides = dyna;
1800			printf("INFO: linux_overrides=dyna \n");
1801		}
1802
1803	}
1804	/* override lan i/f name list and wan i/f name list with default values */
1805	else {
1806canned_config:
1807#ifdef __CONFIG_VLAN__
1808		boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
1809		if (boardflags & BFL_ENETVLAN){
1810			if(auto_bridge)
1811			{
1812				linux_overrides = vlan_auto_bridge;
1813				printf("INFO: linux_overrides=vlan_auto_bridge \n");
1814			}
1815			else
1816			{
1817				linux_overrides = vlan;
1818				printf("INFO: linux_overrides=vlan \n");
1819			}
1820		}
1821		else{
1822#endif	/* __CONFIG_VLAN__ */
1823			if(auto_bridge)
1824			{
1825				linux_overrides = generic_auto_bridge;
1826				printf("INFO: linux_overrides=generic_auto_bridge \n");
1827			}
1828			else
1829			{
1830				linux_overrides = generic;
1831				printf("INFO: linux_overrides=generic \n");
1832			}
1833#ifdef __CONFIG_VLAN__
1834		}
1835#endif	/* __CONFIG_VLAN__ */
1836
1837	}
1838
1839		for (u = linux_overrides; u && u->name; u++) {
1840			nvram_set(u->name, u->value);
1841			printf("INFO: action nvram_set %s, %s\n", u->name, u->value);
1842			}
1843
1844	/* Force to AP */
1845	if (ap)
1846		nvram_set("router_disable", "1");
1847
1848	if (auto_bridge){
1849		printf("INFO: reset auto_bridge flag.\n");
1850		nvram_set("auto_bridge_action", "0");
1851	}
1852
1853	nvram_commit();
1854	cprintf("auto_bridge done\n");
1855}
1856
1857#endif	/* __CONFIG_NAT__ */
1858
1859
1860static void
1861upgrade_defaults(void)
1862{
1863	char temp[100];
1864	int i;
1865	bool bss_enabled = TRUE;
1866	char *val;
1867
1868	/* Check whether upgrade is required or not
1869	 * If lan1_ifnames is not found in NVRAM , upgrade is required.
1870	 */
1871	if (!nvram_get("lan1_ifnames") && !RESTORE_DEFAULTS()) {
1872		cprintf("NVRAM upgrade required.  Starting.\n");
1873
1874		if (nvram_match("ure_disable", "1")) {
1875			nvram_set("lan1_ifname", "br1");
1876			nvram_set("lan1_ifnames", "wl0.1 wl0.2 wl0.3 wl1.1 wl1.2 wl1.3");
1877		}
1878		else {
1879			nvram_set("lan1_ifname", "");
1880			nvram_set("lan1_ifnames", "");
1881			for (i = 0; i < 2; i++) {
1882				snprintf(temp, sizeof(temp), "wl%d_ure", i);
1883				if (nvram_match(temp, "1")) {
1884					snprintf(temp, sizeof(temp), "wl%d.1_bss_enabled", i);
1885					nvram_set(temp, "1");
1886				}
1887				else {
1888					bss_enabled = FALSE;
1889					snprintf(temp, sizeof(temp), "wl%d.1_bss_enabled", i);
1890					nvram_set(temp, "0");
1891				}
1892			}
1893		}
1894		if (nvram_get("lan1_ipaddr")) {
1895			nvram_set("lan1_gateway", nvram_get("lan1_ipaddr"));
1896		}
1897
1898		for (i = 0; i < 2; i++) {
1899			snprintf(temp, sizeof(temp), "wl%d_bss_enabled", i);
1900			nvram_set(temp, "1");
1901			snprintf(temp, sizeof(temp), "wl%d.1_guest", i);
1902			if (nvram_match(temp, "1")) {
1903				nvram_unset(temp);
1904				if (bss_enabled) {
1905					snprintf(temp, sizeof(temp), "wl%d.1_bss_enabled", i);
1906					nvram_set(temp, "1");
1907				}
1908			}
1909
1910			snprintf(temp, sizeof(temp), "wl%d.1_net_reauth", i);
1911			val = nvram_get(temp);
1912			if(!val || (*val == 0))
1913				nvram_set(temp, nvram_default_get(temp));
1914
1915			snprintf(temp, sizeof(temp), "wl%d.1_wpa_gtk_rekey", i);
1916			val = nvram_get(temp);
1917			if(!val || (*val == 0))
1918				nvram_set(temp, nvram_default_get(temp));
1919		}
1920
1921		nvram_commit();
1922
1923		cprintf("NVRAM upgrade complete.\n");
1924	}
1925}
1926
1927static void
1928restore_defaults(void)
1929{
1930#if 0 /* foxconn wklin removed start, 10/22/2008 */
1931	struct nvram_tuple generic[] = {
1932		{ "lan_ifname", "br0", 0 },
1933		{ "lan_ifnames", "eth0 eth2 eth3 eth4", 0 },
1934		{ "wan_ifname", "eth1", 0 },
1935		{ "wan_ifnames", "eth1", 0 },
1936		{ "lan1_ifname", "br1", 0 },
1937		{ "lan1_ifnames", "wl0.1 wl0.2 wl0.3 wl1.1 wl1.2 wl1.3", 0 },
1938		{ 0, 0, 0 }
1939	};
1940#ifdef __CONFIG_VLAN__
1941	struct nvram_tuple vlan[] = {
1942		{ "lan_ifname", "br0", 0 },
1943		{ "lan_ifnames", "vlan0 eth1 eth2 eth3", 0 },
1944		{ "wan_ifname", "vlan1", 0 },
1945		{ "wan_ifnames", "vlan1", 0 },
1946		{ "lan1_ifname", "br1", 0 },
1947		{ "lan1_ifnames", "wl0.1 wl0.2 wl0.3 wl1.1 wl1.2 wl1.3", 0 },
1948		{ 0, 0, 0 }
1949	};
1950#endif	/* __CONFIG_VLAN__ */
1951	struct nvram_tuple dyna[] = {
1952		{ "lan_ifname", "br0", 0 },
1953		{ "lan_ifnames", "", 0 },
1954		{ "wan_ifname", "", 0 },
1955		{ "wan_ifnames", "", 0 },
1956		{ "lan1_ifname", "br1", 0 },
1957		{ "lan1_ifnames", "wl0.1 wl0.2 wl0.3 wl1.1 wl1.2 wl1.3", 0 },
1958		{ 0, 0, 0 }
1959	};
1960#endif /* 0 */ /* foxconn wklin removed end, 10/22/2008 */
1961
1962	/* struct nvram_tuple *linux_overrides; *//* foxconn wklin removed, 10/22/2008 */
1963	struct nvram_tuple *t, *u;
1964	int restore_defaults, i;
1965#ifdef __CONFIG_VLAN__
1966	uint boardflags;
1967#endif	/* __CONFIG_VLAN_ */
1968    /* foxconn  wklin removed start, 10/22/2008*/
1969    /*
1970	char *landevs, *wandevs;
1971	char lan_ifnames[128], wan_ifnames[128];
1972	char wan_ifname[32], *next;
1973	int len;
1974	int ap = 0;
1975#ifdef TRAFFIC_MGMT
1976	int j;
1977#endif
1978    */
1979    /* foxconn wklin removed end, 10/22/2008 */
1980
1981	/* Restore defaults if told to or OS has changed */
1982    /* [MJ] for debugging 5G crash */
1983	restore_defaults = RESTORE_DEFAULTS();
1984    /* [MJ] for debugging 5G crash */
1985	if (restore_defaults)
1986		cprintf("Restoring defaults...");
1987
1988	/* Delete dynamically generated variables */
1989	if (restore_defaults) {
1990		char tmp[100], prefix[] = "wlXXXXXXXXXX_";
1991		for (i = 0; i < MAX_NVPARSE; i++) {
1992#ifdef __CONFIG_NAT__
1993			del_filter_client(i);
1994			del_forward_port(i);
1995#if !defined(AUTOFW_PORT_DEPRECATED)
1996			del_autofw_port(i);
1997#endif
1998#endif	/* __CONFIG_NAT__ */
1999			snprintf(prefix, sizeof(prefix), "wl%d_", i);
2000			for (t = router_defaults; t->name; t ++) {
2001				if (!strncmp(t->name, "wl_", 3))
2002					nvram_unset(strcat_r(prefix, &t->name[3], tmp));
2003			}
2004#ifdef __CONFIG_NAT__
2005			snprintf(prefix, sizeof(prefix), "wan%d_", i);
2006			for (t = router_defaults; t->name; t ++) {
2007				if (!strncmp(t->name, "wan_", 4))
2008					nvram_unset(strcat_r(prefix, &t->name[4], tmp));
2009			}
2010#endif	/* __CONFIG_NAT__ */
2011#ifdef TRAFFIC_MGMT
2012			snprintf(prefix, sizeof(prefix), "wl%d_", i);
2013			for (j = 0; j < MAX_NUM_TRF_MGMT_RULES; j++) {
2014				del_trf_mgmt_port(prefix, j);
2015			}
2016#endif  /* TRAFFIC_MGMT */
2017		}
2018		ses_restore_defaults();
2019#ifdef __CONFIG_WPS__
2020		wps_restore_defaults();
2021#endif /* __CONFIG_WPS__ */
2022#ifdef __CONFIG_WAPI_IAS__
2023		nvram_unset("as_mode");
2024#endif /* __CONFIG_WAPI_IAS__ */
2025		virtual_radio_restore_defaults();
2026#ifdef __CONFIG_URE__
2027		if (nvram_match("wl0_ure_mode", "wre") ||
2028		    nvram_match("wl0_ure_mode", "ure")) {
2029			ure_restore_defaults(0);
2030		}
2031#endif /* __CONFIG_URE__ */
2032	}
2033#if 0 /* foxconn removed start, wklin, 10/22/2008, we don't need this */
2034	/*
2035	 * Build bridged i/f name list and wan i/f name list from lan device name list
2036	 * and wan device name list. Both lan device list "landevs" and wan device list
2037	 * "wandevs" must exist in order to preceed.
2038	 */
2039	if ((landevs = nvram_get("landevs")) && (wandevs = nvram_get("wandevs"))) {
2040		/* build bridged i/f list based on nvram variable "landevs" */
2041		len = sizeof(lan_ifnames);
2042		if (!build_ifnames(landevs, lan_ifnames, &len) && len)
2043			dyna[1].value = lan_ifnames;
2044		else
2045			goto canned_config;
2046		/* build wan i/f list based on nvram variable "wandevs" */
2047		len = sizeof(wan_ifnames);
2048		if (!build_ifnames(wandevs, wan_ifnames, &len) && len) {
2049			dyna[3].value = wan_ifnames;
2050			foreach (wan_ifname, wan_ifnames, next) {
2051				dyna[2].value = wan_ifname;
2052				break;
2053			}
2054		}
2055		else
2056			ap = 1;
2057		linux_overrides = dyna;
2058	}
2059	/* override lan i/f name list and wan i/f name list with default values */
2060	else {
2061canned_config:
2062#ifdef __CONFIG_VLAN__
2063		boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
2064		if (boardflags & BFL_ENETVLAN)
2065			linux_overrides = vlan;
2066		else
2067#endif	/* __CONFIG_VLAN__ */
2068			linux_overrides = generic;
2069	}
2070
2071	/* Check if nvram version is set, but old */
2072	if (nvram_get("nvram_version")) {
2073		int old_ver, new_ver;
2074
2075		old_ver = atoi(nvram_get("nvram_version"));
2076		new_ver = atoi(NVRAM_SOFTWARE_VERSION);
2077		if (old_ver < new_ver) {
2078			cprintf("NVRAM: Updating from %d to %d\n", old_ver, new_ver);
2079			nvram_set("nvram_version", NVRAM_SOFTWARE_VERSION);
2080		}
2081	}
2082#endif /* 0 */ /* foxconn removed end, wklin, 10/22/2008 */
2083
2084	/* Restore defaults */
2085	for (t = router_defaults; t->name; t++) {
2086		if (restore_defaults || !nvram_get(t->name)) {
2087#if 0 /* foxconn removed, wklin, 10/22/2008 , no overrides */
2088			for (u = linux_overrides; u && u->name; u++) {
2089				if (!strcmp(t->name, u->name)) {
2090					nvram_set(u->name, u->value);
2091					break;
2092				}
2093			}
2094			if (!u || !u->name)
2095#endif
2096			nvram_set(t->name, t->value);
2097			//if(nvram_get(t->name))
2098				//cprintf("%s:%s\n", t->name, nvram_default_get(t->name));
2099		}
2100	}
2101
2102#ifdef __CONFIG_WSCCMD__
2103	//rc_randomKey();
2104#endif
2105	/* Force to AP */
2106#if 0 /* foxconn wklin removed, 10/22/2008 */
2107	if (ap)
2108		nvram_set("router_disable", "1");
2109#endif
2110
2111	/* Always set OS defaults */
2112	nvram_set("os_name", "linux");
2113	nvram_set("os_version", ROUTER_VERSION_STR);
2114	nvram_set("os_date", __DATE__);
2115	/* Always set WL driver version! */
2116	nvram_set("wl_version", EPI_VERSION_STR);
2117
2118	nvram_set("is_modified", "0");
2119	nvram_set("ezc_version", EZC_VERSION_STR);
2120
2121	if (restore_defaults) {
2122		FILE *fp;
2123		char memdata[256] = {0};
2124		uint memsize = 0;
2125		char pktq_thresh[8] = {0};
2126
2127		if ((fp = fopen("/proc/meminfo", "r")) != NULL) {
2128			/* get memory count in MemTotal = %d */
2129			while (fgets(memdata, 255, fp) != NULL) {
2130				if (strstr(memdata, "MemTotal") != NULL) {
2131					sscanf(memdata, "MemTotal:        %d kB", &memsize);
2132					break;
2133				}
2134			}
2135			fclose(fp);
2136		}
2137
2138		if (memsize <= 32768) {
2139			/* Set to 512 as long as onboard memory <= 32M */
2140			sprintf(pktq_thresh, "512");
2141		}
2142		else {
2143			/* We still have to set the thresh to prevent oom killer */
2144			sprintf(pktq_thresh, "1024");
2145		}
2146
2147		nvram_set("wl_txq_thresh", pktq_thresh);
2148		nvram_set("et_txq_thresh", pktq_thresh);
2149#if defined(__CONFIG_USBAP__)
2150		nvram_set("wl_rpcq_rxthresh", pktq_thresh);
2151#endif
2152	}
2153
2154#ifdef __CONFIG_URE__
2155	if (restore_defaults) {
2156		if (nvram_match("wl0_ure_mode", "ure") ||
2157		    nvram_match("wl0_ure_mode", "wre")) {
2158			nvram_set("ure_disable", "0");
2159			nvram_set("router_disable", "1");
2160			/* Set ure related nvram settings */
2161			set_ure_vars(0);
2162		}
2163	}
2164#endif /* __CONFIG_URE__ */
2165
2166#ifdef __CONFIG_PLC__
2167	/* plc_pconfig_state = 3 will trigger a plc restore_to_defaults on
2168	 * plcnvm daemon. plcnvm will unset it.
2169	 */
2170	if (restore_defaults) {
2171		nvram_set("plc_pconfig_state", "0");
2172	}
2173#endif /* __CONFIG_PLC__ */
2174
2175	/* Commit values */
2176	if (restore_defaults) {
2177
2178	    /* Foxconn removed start, Tony W.Y. Wang, 04/06/2010 */
2179#if 0
2180	    /* Foxconn add start by aspen Bai, 02/12/2009 */
2181		nvram_unset("pa2gw0a0");
2182		nvram_unset("pa2gw1a0");
2183		nvram_unset("pa2gw2a0");
2184		nvram_unset("pa2gw0a1");
2185		nvram_unset("pa2gw1a1");
2186		nvram_unset("pa2gw2a1");
2187#ifdef FW_VERSION_NA
2188		acosNvramConfig_setPAParam(0);
2189#else
2190		acosNvramConfig_setPAParam(1);
2191#endif
2192		/* Foxconn add end by aspen Bai, 02/12/2009 */
2193#endif
2194		/* Foxconn removed end, Tony W.Y. Wang, 04/06/2010 */
2195
2196		/* foxconn modified start, zacker, 08/06/2010 */
2197		/* Create a new value to inform loaddefault in "read_bd" */
2198		nvram_set("load_defaults", "1");
2199        eval("read_bd"); /* foxconn wklin added, 10/22/2008 */
2200		/* finished "read_bd", unset load_defaults flag */
2201		nvram_unset("load_defaults");
2202		/* foxconn modified end, zacker, 08/06/2010 */
2203        /* Foxconn add start, Tony W.Y. Wang, 04/06/2010 */
2204#ifdef SINGLE_FIRMWARE
2205        if (nvram_match("sku_name", "NA"))
2206            acosNvramConfig_setPAParam(0);
2207        else
2208            acosNvramConfig_setPAParam(1);
2209#else
2210		#ifdef FW_VERSION_NA
2211			acosNvramConfig_setPAParam(0);
2212		#else
2213			acosNvramConfig_setPAParam(1);
2214		#endif
2215#endif
2216        /* Foxconn add end, Tony W.Y. Wang, 04/06/2010 */
2217		nvram_commit();
2218		sync();         /* Foxconn added start pling 12/25/2006 */
2219		cprintf("done\n");
2220	}
2221}
2222
2223#ifdef __CONFIG_NAT__
2224static void
2225set_wan0_vars(void)
2226{
2227	int unit;
2228	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
2229
2230	/* check if there are any connections configured */
2231	for (unit = 0; unit < MAX_NVPARSE; unit ++) {
2232		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
2233		if (nvram_get(strcat_r(prefix, "unit", tmp)))
2234			break;
2235	}
2236	/* automatically configure wan0_ if no connections found */
2237	if (unit >= MAX_NVPARSE) {
2238		struct nvram_tuple *t;
2239		char *v;
2240
2241		/* Write through to wan0_ variable set */
2242		snprintf(prefix, sizeof(prefix), "wan%d_", 0);
2243		for (t = router_defaults; t->name; t ++) {
2244			if (!strncmp(t->name, "wan_", 4)) {
2245				if (nvram_get(strcat_r(prefix, &t->name[4], tmp)))
2246					continue;
2247				v = nvram_get(t->name);
2248				nvram_set(tmp, v ? v : t->value);
2249			}
2250		}
2251		nvram_set(strcat_r(prefix, "unit", tmp), "0");
2252		nvram_set(strcat_r(prefix, "desc", tmp), "Default Connection");
2253		nvram_set(strcat_r(prefix, "primary", tmp), "1");
2254	}
2255}
2256#endif	/* __CONFIG_NAT__ */
2257
2258static int noconsole = 0;
2259
2260static void
2261sysinit(void)
2262{
2263	char buf[PATH_MAX];
2264	struct utsname name;
2265	struct stat tmp_stat;
2266	time_t tm = 0;
2267	char *loglevel;
2268
2269	struct utsname unamebuf;
2270	char *lx_rel;
2271
2272	/* Use uname() to get the system's hostname */
2273	uname(&unamebuf);
2274	lx_rel = unamebuf.release;
2275
2276	if (memcmp(lx_rel, "2.6", 3) == 0) {
2277		int fd;
2278		if ((fd = open("/dev/console", O_RDWR)) < 0) {
2279			if (memcmp(lx_rel, "2.6.36", 6) == 0) {
2280				mount("devfs", "/dev", "devtmpfs", MS_MGC_VAL, NULL);
2281			} else {
2282				mount("devfs", "/dev", "tmpfs", MS_MGC_VAL, NULL);
2283				mknod("/dev/console", S_IRWXU|S_IFCHR, makedev(5, 1));
2284			}
2285		}
2286		else {
2287			close(fd);
2288		}
2289	}
2290
2291	/* /proc */
2292	mount("proc", "/proc", "proc", MS_MGC_VAL, NULL);
2293#ifdef LINUX26
2294	mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL);
2295#endif /* LINUX26 */
2296
2297	/* /tmp */
2298	mount("ramfs", "/tmp", "ramfs", MS_MGC_VAL, NULL);
2299
2300	/* /var */
2301	mkdir("/tmp/var", 0777);
2302	mkdir("/var/lock", 0777);
2303	mkdir("/var/log", 0777);
2304	mkdir("/var/run", 0777);
2305	mkdir("/var/tmp", 0777);
2306	mkdir("/tmp/media", 0777);
2307
2308#ifdef __CONFIG_UTELNETD__
2309	/* If kernel enable unix908 pty then we have to make following things. */
2310	mkdir("/dev/pts", 0777);
2311	if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, NULL) == 0) {
2312		/* pty master */
2313		mknod("/dev/ptmx", S_IRWXU|S_IFCHR, makedev(5, 2));
2314	} else {
2315		rmdir("/dev/pts");
2316	}
2317#endif	/* LINUX2636 && __CONFIG_UTELNETD__ */
2318
2319#ifdef __CONFIG_SAMBA__
2320	/* Add Samba Stuff */
2321	mkdir("/tmp/samba", 0777);
2322	mkdir("/tmp/samba/lib", 0777);
2323	mkdir("/tmp/samba/private", 0777);
2324	mkdir("/tmp/samba/var", 0777);
2325	mkdir("/tmp/samba/var/locks", 0777);
2326#endif
2327
2328#ifdef BCMQOS
2329	mkdir("/tmp/qos", 0777);
2330#endif
2331	/* Setup console */
2332	if (console_init())
2333		noconsole = 1;
2334
2335#ifdef LINUX26
2336	mkdir("/dev/shm", 0777);
2337	eval("/sbin/hotplug2", "--coldplug");
2338#endif /* LINUX26 */
2339
2340	if ((loglevel = nvram_get("console_loglevel")))
2341		klogctl(8, NULL, atoi(loglevel));
2342	else
2343		klogctl(8, NULL, 1);
2344
2345	/* Modules */
2346	uname(&name);
2347	snprintf(buf, sizeof(buf), "/lib/modules/%s", name.release);
2348	if (stat("/proc/modules", &tmp_stat) == 0 &&
2349	    stat(buf, &tmp_stat) == 0) {
2350		char module[80], *modules, *next;
2351
2352		/* foxconn modified start, zacker, 08/06/2010 */
2353		/* Restore defaults if necessary */
2354		restore_defaults();
2355
2356
2357        /* For 4500 IR-159. by MJ. 2011.07.04  */
2358        /* Foxconn added start pling 02/11/2011 */
2359        /* WNDR4000 IR20: unset vifs NVRAM and let
2360         * bcm_wlan_util.c to reconstruct them if
2361         * necessary. move to here since they should be
2362         * done before read_bd */
2363        nvram_unset("wl0_vifs");
2364        nvram_unset("wl1_vifs");
2365        /* Foxconn added end pling 02/11/2011 */
2366
2367		/* Read ethernet MAC, RF params, etc */
2368		eval("read_bd");
2369		/* foxconn modified end, zacker, 08/06/2010 */
2370
2371		/* Load ctf */
2372    /* Foxconn added start pling 08/19/2010 */
2373    /* Make sure the NVRAM "ctf_disable" exist, otherwise
2374     * MultiSsidCntrl will not work.
2375     */
2376    if (nvram_get("ctf_disable") == NULL)
2377        nvram_set("ctf_disable", "1");
2378    /* Foxconn added end pling 08/19/2010 */
2379		if (!nvram_match("ctf_disable", "1"))
2380			eval("insmod", "ctf");
2381#if defined(__CONFIG_WAPI__) || defined(__CONFIG_WAPI_IAS__)
2382		wapi_mtd_restore();
2383#endif /* __CONFIG_WAPI__ || __CONFIG_WAPI_IAS__ */
2384
2385
2386/* #ifdef BCMVISTAROUTER */
2387#ifdef __CONFIG_IPV6__
2388		eval("insmod", "ipv6");
2389#endif /* __CONFIG_IPV6__ */
2390/* #endif */
2391
2392#ifdef __CONFIG_EMF__
2393		/* Load the EMF & IGMP Snooper modules */
2394		load_emf();
2395#endif /*  __CONFIG_EMF__ */
2396
2397
2398    /* Bob added start to avoid sending unexpected dad, 09/16/2009 */
2399#ifdef INCLUDE_IPV6
2400		if (nvram_match("ipv6ready","1"))
2401		{
2402			system("echo 0 > /proc/sys/net/ipv6/conf/default/dad_transmits");
2403		}
2404
2405		/* Foxconn added start pling 12/06/2010 */
2406		/* By default ipv6_spi is inserted to system to drop all packets. */
2407		system("/sbin/insmod /lib/modules/2.6.22/kernel/lib/ipv6_spi.ko");
2408		/* Foxconn added end pling 12/06/2010 */
2409#endif
2410    /* Bob added end to avoid sending unexpected dad, 09/16/2009 */
2411
2412
2413		/* Foxconn added start pling 09/02/2010 */
2414		/* Need to initialise switch related NVRAM before
2415		 * insert ethernet module.
2416		 */
2417#ifdef __CONFIG_IGMP_SNOOPING__
2418		config_switch();
2419#endif
2420		/* Foxconn added end pling 09/02/2010 */
2421		/* Load kernel modules. Make sure dpsta is loaded before wl
2422		 * due to symbol dependency.
2423		 */
2424		//modules = nvram_get("kernel_mods") ? : "et bcm57xx dpsta wl";
2425		modules = nvram_get("kernel_mods") ? : "et dpsta wl"; /* foxconn wklin modified, 10/22/2008 */
2426
2427		foreach(module, modules, next){
2428            /*Foxconn, [MJ] for GPIO debugging. */
2429#ifdef WIFI_DISABLE
2430            if(strcmp(module, "wl")){
2431			    eval("insmod", module);
2432            }else
2433                cprintf("we don't insert wl.ko.\n");
2434#else
2435            eval("insmod", module);
2436#endif
2437        }
2438#ifdef __CONFIG_USBAP__
2439		/* We have to load USB modules after loading PCI wl driver so
2440		 * USB driver can decide its instance number based on PCI wl
2441		 * instance numbers (in hotplug_usb())
2442		 */
2443		eval("insmod", "usbcore");
2444
2445        /* Foxconn, [MJ] start, we can't insert usb-storage easiler than
2446         * automount being started. */
2447#if 0
2448
2449		eval("insmod", "usb-storage");
2450        /* Foxconn, [MJ], for debugging. */
2451        cprintf("--> insmod usb-storage.\n");
2452#endif
2453        /* Foxconn, [MJ] end, we can't insert usb-storage easiler than
2454         * automount being started. */
2455		{
2456			char	insmod_arg[128];
2457			int	i = 0, maxwl_eth = 0, maxunit = -1;
2458			char	ifname[16] = {0};
2459			int	unit = -1;
2460			char arg1[20] = {0};
2461			char arg2[20] = {0};
2462			char arg3[20] = {0};
2463			char arg4[20] = {0};
2464			char arg5[20] = {0};
2465			char arg6[20] = {0};
2466			char arg7[20] = {0};
2467			const int wl_wait = 3;	/* max wait time for wl_high to up */
2468
2469			/* Save QTD cache params in nvram */
2470			sprintf(arg1, "log2_irq_thresh=%d", atoi(nvram_safe_get("ehciirqt")));
2471			sprintf(arg2, "qtdc_pid=%d", atoi(nvram_safe_get("qtdc_pid")));
2472			sprintf(arg3, "qtdc_vid=%d", atoi(nvram_safe_get("qtdc_vid")));
2473			sprintf(arg4, "qtdc0_ep=%d", atoi(nvram_safe_get("qtdc0_ep")));
2474			sprintf(arg5, "qtdc0_sz=%d", atoi(nvram_safe_get("qtdc0_sz")));
2475			sprintf(arg6, "qtdc1_ep=%d", atoi(nvram_safe_get("qtdc1_ep")));
2476			sprintf(arg7, "qtdc1_sz=%d", atoi(nvram_safe_get("qtdc1_sz")));
2477
2478			eval("insmod", "ehci-hcd", arg1, arg2, arg3, arg4, arg5,
2479				arg6, arg7);
2480
2481			/* Search for existing PCI wl devices and the max unit number used.
2482			 * Note that PCI driver has to be loaded before USB hotplug event.
2483			 * This is enforced in rc.c
2484			 */
2485			for (i = 1; i <= DEV_NUMIFS; i++) {
2486				sprintf(ifname, "eth%d", i);
2487				if (!wl_probe(ifname)) {
2488					if (!wl_ioctl(ifname, WLC_GET_INSTANCE, &unit,
2489						sizeof(unit))) {
2490						maxwl_eth = i;
2491						maxunit = (unit > maxunit) ? unit : maxunit;
2492					}
2493				}
2494			}
2495
2496			/* Set instance base (starting unit number) for USB device */
2497			sprintf(insmod_arg, "instance_base=%d", maxunit + 1);
2498            /*Foxconn, [MJ] for GPIO debugging. */
2499#ifndef WIFI_DISABLE
2500			eval("insmod", "wl_high", insmod_arg);
2501#endif
2502			/* Hold until the USB/HSIC interface is up (up to wl_wait sec) */
2503			sprintf(ifname, "eth%d", maxwl_eth + 1);
2504			i = wl_wait;
2505			while (wl_probe(ifname) && i--) {
2506				sleep(1);
2507			}
2508			if (!wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit)))
2509				cprintf("wl%d is up in %d sec\n", unit, wl_wait - i);
2510			else
2511				cprintf("wl%d not up in %d sec\n", unit, wl_wait);
2512		}
2513#ifdef LINUX26
2514		mount("usbdeffs", "/proc/bus/usb", "usbfs", MS_MGC_VAL, NULL);
2515#else
2516		mount("none", "/proc/bus/usb", "usbdevfs", MS_MGC_VAL, NULL);
2517#endif /* LINUX26 */
2518
2519#if (defined WNDR3400v2)
2520        /* pling added, for usb, only for WNDR3400v2 */
2521        #include "../libbcm/bcmgpio.h"
2522        bcmgpio_connect(21, BCMGPIO_DIRN_OUT);
2523        bcmgpio_out(1<<21, 1<<21);
2524        /* pling ended, for usb */
2525#endif
2526
2527#endif /* __CONFIG_USBAP__ */
2528
2529#ifdef __CONFIG_WCN__
2530		modules = "scsi_mod sd_mod usbcore usb-ohci usb-storage fat vfat msdos";
2531		foreach(module, modules, next){
2532            /* Foxconn, [MJ] for debugging. */
2533            cprintf("--> insmod %s\n", ,module);
2534			eval("insmod", module);
2535        }
2536#endif
2537
2538#ifdef __CONFIG_SOUND__
2539		modules = "soundcore snd snd-timer snd-page-alloc snd-pcm snd-pcm-oss "
2540		        "snd-soc-core i2c-core i2c-algo-bit i2c-gpio snd-soc-bcm947xx-i2s "
2541		        "snd-soc-bcm947xx-pcm snd-soc-wm8750 snd-soc-wm8955 snd-soc-bcm947xx";
2542		foreach(module, modules, next)
2543			eval("insmod", module);
2544		mknod("/dev/dsp", S_IRWXU|S_IFCHR, makedev(14, 3));
2545		mkdir("/dev/snd", 0777);
2546		mknod("/dev/snd/controlC0", S_IRWXU|S_IFCHR, makedev(116, 0));
2547		mknod("/dev/snd/pcmC0D0c", S_IRWXU|S_IFCHR, makedev(116, 24));
2548		mknod("/dev/snd/pcmC0D0p", S_IRWXU|S_IFCHR, makedev(116, 16));
2549		mknod("/dev/snd/timer", S_IRWXU|S_IFCHR, makedev(116, 33));
2550#endif
2551	}
2552
2553	if (memcmp(lx_rel, "2.6.36", 6) == 0) {
2554		int fd;
2555		if ((fd = open("/proc/irq/163/smp_affinity", O_RDWR)) >= 0) {
2556			close(fd);
2557			if (!nvram_match("txworkq", "1")) {
2558				system("echo 2 > /proc/irq/163/smp_affinity");
2559				system("echo 2 > /proc/irq/169/smp_affinity");
2560			}
2561			system("echo 2 > /proc/irq/112/smp_affinity");
2562		}
2563	}
2564	/* Set a sane date */
2565	stime(&tm);
2566
2567	dprintf("done\n");
2568}
2569
2570/* States */
2571enum {
2572	RESTART,
2573	STOP,
2574	START,
2575	TIMER,
2576	IDLE,
2577	WSC_RESTART,
2578	WLANRESTART, /* Foxconn added by EricHuang, 11/24/2006 */
2579	PPPSTART    /* Foxconn added by EricHuang, 01/09/2008 */
2580};
2581static int state = START;
2582static int signalled = -1;
2583
2584/* foxconn added start, zacker, 05/20/2010, @spec_1.9 */
2585static int next_state = IDLE;
2586
2587static int
2588next_signal(void)
2589{
2590	int tmp_sig = next_state;
2591	next_state = IDLE;
2592	return tmp_sig;
2593}
2594/* foxconn added end, zacker, 05/20/2010, @spec_1.9 */
2595
2596/* Signal handling */
2597static void
2598rc_signal(int sig)
2599{
2600	if (state == IDLE) {
2601		if (sig == SIGHUP) {
2602			dprintf("signalling RESTART\n");
2603			signalled = RESTART;
2604		}
2605		else if (sig == SIGUSR2) {
2606			dprintf("signalling START\n");
2607			signalled = START;
2608		}
2609		else if (sig == SIGINT) {
2610			dprintf("signalling STOP\n");
2611			signalled = STOP;
2612		}
2613		else if (sig == SIGALRM) {
2614			dprintf("signalling TIMER\n");
2615			signalled = TIMER;
2616		}
2617		else if (sig == SIGUSR1) {
2618			dprintf("signalling WSC RESTART\n");
2619			signalled = WSC_RESTART;
2620		}
2621		/* Foxconn modified start by EricHuang, 01/09/2008 */
2622		else if (sig == SIGQUIT) {
2623		    dprintf("signalling WLANRESTART\n");
2624		    signalled = WLANRESTART;
2625		}
2626		else if (sig == SIGILL) {
2627		    signalled = PPPSTART;
2628		}
2629		/* Foxconn modified end by EricHuang, 01/09/2008 */
2630	}
2631	/* foxconn added start, zacker, 05/20/2010, @spec_1.9 */
2632	else if (next_state == IDLE)
2633	{
2634		if (sig == SIGHUP) {
2635			dprintf("signalling RESTART\n");
2636			next_state = RESTART;
2637		}
2638		else if (sig == SIGUSR2) {
2639			dprintf("signalling START\n");
2640			next_state = START;
2641		}
2642		else if (sig == SIGINT) {
2643			dprintf("signalling STOP\n");
2644			next_state = STOP;
2645		}
2646		else if (sig == SIGALRM) {
2647			dprintf("signalling TIMER\n");
2648			next_state = TIMER;
2649		}
2650		else if (sig == SIGUSR1) {
2651			dprintf("signalling WSC RESTART\n");
2652			next_state = WSC_RESTART;
2653		}
2654		else if (sig == SIGQUIT) {
2655			printf("signalling WLANRESTART\n");
2656			next_state = WLANRESTART;
2657		}
2658		else if (sig == SIGILL) {
2659			next_state = PPPSTART;
2660		}
2661	}
2662	/* foxconn added end, zacker, 05/20/2010, @spec_1.9 */
2663}
2664
2665/* Get the timezone from NVRAM and set the timezone in the kernel
2666 * and export the TZ variable
2667 */
2668static void
2669set_timezone(void)
2670{
2671	time_t now;
2672	struct tm gm, local;
2673	struct timezone tz;
2674	struct timeval *tvp = NULL;
2675
2676	/* Export TZ variable for the time libraries to
2677	 * use.
2678	 */
2679	setenv("TZ", nvram_get("time_zone"), 1);
2680
2681	/* Update kernel timezone */
2682	time(&now);
2683	gmtime_r(&now, &gm);
2684	localtime_r(&now, &local);
2685	tz.tz_minuteswest = (mktime(&gm) - mktime(&local)) / 60;
2686	settimeofday(tvp, &tz);
2687
2688#if defined(__CONFIG_WAPI__) || defined(__CONFIG_WAPI_IAS__)
2689#ifndef	RC_BUILDTIME
2690#define	RC_BUILDTIME	1252636574
2691#endif
2692	{
2693		struct timeval tv = {RC_BUILDTIME, 0};
2694
2695		time(&now);
2696		if (now < RC_BUILDTIME)
2697			settimeofday(&tv, &tz);
2698	}
2699#endif /* __CONFIG_WAPI__ || __CONFIG_WAPI_IAS__ */
2700}
2701
2702/* Timer procedure.Gets time from the NTP servers once every timer interval
2703 * Interval specified by the NVRAM variable timer_interval
2704 */
2705int
2706do_timer(void)
2707{
2708	int interval = atoi(nvram_safe_get("timer_interval"));
2709
2710	dprintf("%d\n", interval);
2711
2712	if (interval == 0)
2713		return 0;
2714
2715	/* Report stats */
2716	if (nvram_invmatch("stats_server", "")) {
2717		char *stats_argv[] = { "stats", nvram_get("stats_server"), NULL };
2718		_eval(stats_argv, NULL, 5, NULL);
2719	}
2720
2721	/* Sync time */
2722	start_ntpc();
2723
2724	alarm(interval);
2725
2726	return 0;
2727}
2728
2729/* Main loop */
2730static void
2731main_loop(void)
2732{
2733#ifdef CAPI_AP
2734	static bool start_aput = TRUE;
2735#endif
2736	sigset_t sigset;
2737	pid_t shell_pid = 0;
2738#ifdef __CONFIG_VLAN__
2739	uint boardflags;
2740#endif
2741
2742    /* foxconn wklin added start, 10/22/2008 */
2743	sysinit();
2744
2745	/* Foxconn added start pling 03/20/2014 */
2746	/* Router Spec Rev 12: disable/enable ethernet interface when dhcp server start */
2747	eval("landown");
2748	/* Foxconn added end pling 03/20/2014 */
2749
2750	/* Add loopback */
2751	config_loopback();
2752	/* Restore defaults if necessary */
2753	//restore_defaults(); /* foxconn removed, zacker, 08/06/2010, move to sysinit() */
2754
2755	/* Convert deprecated variables */
2756	convert_deprecated();
2757
2758	/* Upgrade NVRAM variables to MBSS mode */
2759	upgrade_defaults();
2760    /* FXCN Tab Tseng add, 05/22/2014, disable nar in both 2.4G and 5G */
2761        nvram_set("wl0_nar","0");
2762        nvram_set("wl1_nar","0");
2763    /* FXCN Tab Tseng add, 05/22/2014, disable nar in both 2.4G and 5G */
2764    /*Foxconn Tab Tseng add, 03/05/2014, remove "Wireless Repeating" from GUI, disable WDS if it is enabled*/
2765        if (nvram_match("wla_wds_enable", "1"))
2766        {
2767                nvram_set("wla_wds_enable",  "0");
2768                nvram_set("wl0_wds", "");
2769                nvram_set("wl0_mode", "ap");
2770                nvram_set("wla_repeater", "0");
2771        }
2772        if (nvram_match("wlg_wds_enable", "1"))
2773        {
2774                nvram_set("wlg_wds_enable",  "0");
2775                nvram_set("wl1_wds", "");
2776                nvram_set("wl1_mode", "ap");
2777                nvram_set("wlg_repeater", "0");
2778        }
2779    /*Foxconn Tab Tseng add, 03/05/2014, remove "Wireless Repeating" from GUI, disable WDS if it is enabled*/
2780
2781    /* Read ethernet MAC, etc */
2782    //eval("read_bd"); /* foxconn removed, zacker, 08/06/2010, move to sysinit() */
2783    /* foxconn wklin added end, 10/22/2008 */
2784
2785    /* Reset some wps-related parameters */
2786    nvram_set("wps_start",   "none");
2787    /* foxconn added start, zacker, 05/20/2010, @spec_1.9 */
2788    nvram_set("wps_status", "0"); /* start_wps() */
2789    nvram_set("wps_proc_status", "0");
2790    /* foxconn added end, zacker, 05/20/2010, @spec_1.9 */
2791
2792    /* Foxconn Perry added start, 2011/05/13, for IPv6 router advertisment prefix information */
2793    /* reset IPv6 obsolete prefix information after reboot */
2794    nvram_set("radvd_lan_obsolete_ipaddr", "");
2795    nvram_set("radvd_lan_obsolete_ipaddr_length", "");
2796    nvram_set("radvd_lan_new_ipaddr", "");
2797    nvram_set("radvd_lan_new_ipaddr_length", "");
2798    /* Foxconn Perry added end, 2011/05/13, for IPv6 router advertisment prefix information */
2799
2800    /* Foxconn added start, zacker, 06/17/2010, @new_tmp_lock */
2801    /* do this in case "wps_aplockdown_forceon" is set to "1" for tmp_lock
2802     * purpose but then there are "nvram_commit" and "reboot" action
2803     */
2804    if (nvram_match("wsc_pin_disable", "1"))
2805        nvram_set("wps_aplockdown_forceon", "1");
2806    else
2807        nvram_set("wps_aplockdown_forceon", "0");
2808    /* Foxconn added end, zacker, 06/17/2010, @new_tmp_lock */
2809
2810    /* Foxconn added start, Wins, 04/20/2011, @RU_IPTV */
2811#ifdef CONFIG_RUSSIA_IPTV
2812    if (!is_russia_specific_support())
2813    {
2814        nvram_set(NVRAM_IPTV_ENABLED, "0");
2815        nvram_set(NVRAM_IPTV_INTF, "0x00");
2816    }
2817#endif /* CONFIG_RUSSIA_IPTV */
2818    /* Foxconn added end, Wins, 04/20/2011, @RU_IPTV */
2819
2820    /* Foxconn add start, Max Ding, 02/26/2010 */
2821#ifdef RESTART_ALL_PROCESSES
2822    nvram_unset("restart_all_processes");
2823#endif
2824    /* Foxconn add end, Max Ding, 02/26/2010 */
2825
2826
2827	/* Basic initialization */
2828	//sysinit();
2829
2830	/* Setup signal handlers */
2831	signal_init();
2832	signal(SIGHUP, rc_signal);
2833	signal(SIGUSR2, rc_signal);
2834	signal(SIGINT, rc_signal);
2835	signal(SIGALRM, rc_signal);
2836	signal(SIGUSR1, rc_signal);
2837	signal(SIGQUIT, rc_signal); /* Foxconn added by EricHuang, 11/24/2006 */
2838	signal(SIGILL, rc_signal); //ppp restart
2839	sigemptyset(&sigset);
2840
2841	/* Give user a chance to run a shell before bringing up the rest of the system */
2842	if (!noconsole)
2843		run_shell(1, 0);
2844
2845	/* Get boardflags to see if VLAN is supported */
2846#ifdef __CONFIG_VLAN__
2847	boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
2848#endif	/* __CONFIG_VLAN__ */
2849
2850
2851#if 0 /* foxconn modified, wklin 10/22/2008, move the the start of this function */
2852	/* Add loopback */
2853	config_loopback();
2854	/* Convert deprecated variables */
2855	convert_deprecated();
2856
2857	/* ses cleanup of variables left half way through */
2858	ses_cleanup();
2859
2860	/* ses_cl cleanup of variables left half way through */
2861	ses_cl_cleanup();
2862
2863	/* Upgrade NVRAM variables to MBSS mode */
2864	upgrade_defaults();
2865
2866	/* Restore defaults if necessary */
2867	restore_defaults();
2868
2869    /* Foxconn added start pling 06/20/2007 */
2870    /* Read board data again, since the "restore_defaults" action
2871     * above will overwrite some of our settings */
2872    eval("read_bd");
2873    /* Foxconn added end pling 06/20/2006 */
2874#endif /* 0 */
2875
2876#ifdef __CONFIG_NAT__
2877	/* Auto Bridge if neccessary */
2878	if (!strcmp(nvram_safe_get("auto_bridge"),"1") )
2879	{
2880		auto_bridge();
2881	}
2882	/* Setup wan0 variables if necessary */
2883	set_wan0_vars();
2884#endif	/* __CONFIG_NAT__ */
2885
2886    /* Foxconn added start pling 07/13/2009 */
2887    /* create the USB semaphores */
2888#ifdef SAMBA_ENABLE
2889    usb_sem_init(); //[MJ] for 5G crash
2890#endif
2891    /* Foxconn added end pling 07/13/2009 */
2892	/* Loop forever */
2893    for (;;) {
2894        switch (state) {
2895            case RESTART:
2896                dprintf("RESTART\n");
2897                /* Fall through */
2898                /* Foxconn added start pling 06/14/2007 */
2899                /* When vista finished configuring this router (wl0_wps_config_state: 0->1),
2900                 * then we come here to restart WLAN
2901                 */
2902                stop_wps();
2903                stop_nas();
2904                stop_eapd();
2905                stop_bcmupnp();
2906                stop_wlan();
2907                /*Foxconn add start by Hank 06/14/2012*/
2908                /*Enable 2.4G auto channel detect, kill acsd for stop change channel*/
2909                if((nvram_match("wla_channel", "0") || nvram_match("wlg_channel", "0")) && nvram_match("enable_sta_mode","0"))
2910                    stop_acsd();
2911                /*Foxconn add end by Hank 06/14/2012*/
2912
2913                convert_wlan_params();  /* For WCN , added by EricHuang, 12/21/2006 */
2914                sleep(2);               /* Wait some time for wsc, etc to terminate */
2915
2916                /* if "unconfig" to "config" mode, force it to built-in registrar and proxy mode */
2917                /* added start by EricHuang, 11/04/2008 */
2918                if ( nvram_match("wps_status", "0") ) //restart wlan for wsc
2919                {
2920                    nvram_set("lan_wps_reg", "enabled");
2921                    nvram_set("wl_wps_reg", "enabled");
2922                    nvram_set("wl0_wps_reg", "enabled");
2923#if (defined INCLUDE_DUAL_BAND)
2924                    nvram_set("wl0_wps_reg", "enabled");
2925#endif
2926                    /* Foxconn modify start, Max Ding, 08/28/2010 for NEW_BCM_WPS */
2927                    /* New NVRAM to BSP 5.22.83.0, 'wlx_wps_config_state' not used anymore. */
2928                    //printf("restart -- wl0_wps_config_state=%s\n", nvram_get("wl0_wps_config_state"));
2929                    //nvram_set("wl_wps_config_state", nvram_get("wl0_wps_config_state"));
2930                    if ( nvram_match("lan_wps_oob", "enabled") )
2931                    {
2932                        nvram_set("wl_wps_config_state", "0");
2933                        nvram_set("wl0_wps_config_state", "0");
2934#if (defined INCLUDE_DUAL_BAND)
2935                        nvram_set("wl1_wps_config_state", "0");
2936#endif
2937                    }
2938                    else
2939                    {
2940                        nvram_set("wl_wps_config_state", "1");
2941                        nvram_set("wl0_wps_config_state", "1");
2942#if (defined INCLUDE_DUAL_BAND)
2943                        nvram_set("wl1_wps_config_state", "1");
2944#endif
2945                    }
2946                    /* Foxconn modify end, Max Ding, 08/28/2010 */
2947                }
2948                /* added end by EricHuang, 11/04/2008 */
2949
2950                /* hide unnecessary warnings (Invaid XXX, out of range xxx etc...)*/
2951                {
2952#include <fcntl.h>
2953                    int fd1, fd2;
2954                    fd1 = dup(2);
2955                    fd2 = open("/dev/null", O_WRONLY);
2956                    close(2);
2957                    dup2(fd2, 2);
2958                    close(fd2);
2959                    start_wlan(); //<-- to hide messages generated here
2960                    close(2);
2961                    dup2(fd1, 2);
2962                    close(fd1);
2963                }
2964
2965                save_wlan_time();
2966                start_bcmupnp();
2967                start_eapd();           /* Foxconn modify by aspen Bai, 10/08/2008 */
2968                start_nas();            /* Foxconn modify by aspen Bai, 08/01/2008 */
2969                start_wps();            /* Foxconn modify by aspen Bai, 08/01/2008 */
2970                if(nvram_match("enable_sta_mode","0"))
2971                    start_acsd();
2972                sleep(2);               /* Wait for WSC to start */
2973                /* Foxconn add start by aspen Bai, 09/10/2008 */
2974                /* Must call it when start wireless */
2975                start_wl();
2976                /* Foxconn add end by aspen Bai, 09/10/2008 */
2977                nvram_commit();         /* Save WCN obtained parameters */
2978
2979                /* foxconn modified start, zacker, 05/20/2010, @spec_1.9 */
2980                //state = IDLE;
2981                state = next_signal();
2982                /* foxconn modified end, zacker, 05/20/2010, @spec_1.9 */
2983
2984#if 0       /* foxconn removed start, zacker, 09/17/2009, @wps_led */
2985#ifdef BCM4716
2986                if (nvram_match("wla_secu_type", "None"))
2987                {
2988                    system("/sbin/gpio 7 0");
2989                }
2990                else
2991                {
2992                    system("/sbin/gpio 7 1");
2993                }
2994#else
2995                if (nvram_match("wla_secu_type", "None"))
2996                {
2997                    system("/sbin/gpio 1 0");
2998                }
2999                else
3000                {
3001                    system("/sbin/gpio 1 1");
3002                }
3003#endif
3004#endif      /* foxconn removed end, zacker, 09/17/2009, @wps_led */
3005
3006                break;
3007                /* Foxconn added end pling 06/14/2007 */
3008
3009            case STOP:
3010                dprintf("STOP\n");
3011                pmon_init();
3012                stop_wps();
3013                stop_nas();
3014                stop_eapd();
3015                stop_bcmupnp();
3016
3017                stop_lan();
3018#ifdef __CONFIG_VLAN__
3019                if (boardflags & BFL_ENETVLAN)
3020                    stop_vlan();
3021#endif	/* __CONFIG_VLAN__ */
3022                if (state == STOP) {
3023                    /* foxconn modified start, zacker, 05/20/2010, @spec_1.9 */
3024                    //state = IDLE;
3025                    state = next_signal();
3026                    /* foxconn modified end, zacker, 05/20/2010, @spec_1.9 */
3027                    break;
3028                }
3029                /* Fall through */
3030            case START:
3031                dprintf("START\n");
3032                pmon_init();
3033                /* foxconn added start, zacker, 01/13/2012, @iptv_igmp */
3034#ifdef CONFIG_RUSSIA_IPTV
3035                if (!nvram_match("wla_repeater", "1")
3036#if (defined INCLUDE_DUAL_BAND)
3037                        && !nvram_match("wlg_repeater", "1")
3038#endif
3039                   )
3040                {
3041                    /* don't do this in cgi since "rc stop" need to do cleanup */
3042                    config_iptv_params();
3043                    /* always do this to active new vlan settings */
3044                    active_vlan();
3045                }
3046#endif /* CONFIG_RUSSIA_IPTV */
3047
3048#if (defined INCLUDE_QOS) || (defined __CONFIG_IGMP_SNOOPING__)
3049                config_switch_reg();
3050#endif
3051                /* foxconn added end, zacker, 01/13/2012, @iptv_igmp */
3052                /*foxconn added start, water, 12/21/09*/
3053#ifdef RESTART_ALL_PROCESSES
3054                if ( nvram_match("restart_all_processes", "1") )
3055                {
3056                    restore_defaults();
3057                    eval("read_bd");
3058                    convert_deprecated();
3059                    /* Foxconn add start, Max Ding, 03/03/2010 */
3060
3061#if (defined BCM5325E) || (defined BCM53125)
3062                    system("/usr/sbin/et robowr 0x34 0x00 0x00e0");
3063#endif
3064                    /* Foxconn add end, Max Ding, 03/03/2010 */
3065                }
3066#endif
3067
3068                /*foxconn added end, water, 12/21/09*/
3069                { /* Set log level on restart */
3070                    char *loglevel;
3071                    int loglev = 8;
3072
3073                    if ((loglevel = nvram_get("console_loglevel"))) {
3074                        loglev = atoi(loglevel);
3075                    }
3076                    klogctl(8, NULL, loglev);
3077                    if (loglev < 7) {
3078                        printf("WARNING: console log level set to %d\n", loglev);
3079                    }
3080                }
3081
3082                set_timezone();
3083#ifdef __CONFIG_VLAN__
3084                if (boardflags & BFL_ENETVLAN)
3085                    /* Foxconn add start by aspen Bai, 08/28/2008 */
3086                    start_vlan();
3087#endif	/* __CONFIG_VLAN__ */
3088                /* wklin modified start, 10/23/2008 */
3089                /* hide unnecessary warnings (Invaid XXX, out of range xxx etc...)*/
3090                {
3091#include <fcntl.h>
3092                    int fd1, fd2;
3093                    fd1 = dup(2);
3094                    fd2 = open("/dev/null", O_WRONLY);
3095                    close(2);
3096                    dup2(fd2, 2);
3097                    close(fd2);
3098                    start_lan(); //<-- to hide messages generated here
3099                    start_wlan(); //<-- need it to bring up 5G interface
3100                    close(2);
3101                    dup2(fd1, 2);
3102                    close(fd1);
3103                }
3104                if (nvram_match("wla_repeater", "1")
3105#if (defined INCLUDE_DUAL_BAND)
3106                        || nvram_match("wlg_repeater", "1")
3107#endif
3108                   )
3109                {
3110                    /* if repeater mode, del vlan1 from br0 and disable vlan */
3111#ifdef BCM4716
3112                    system("/usr/sbin/brctl delif br0 vlan0");
3113                    system("/usr/sbin/et robowr 0x34 0x00 0x00");
3114#else
3115                    /*foxconn modified start, water, 01/07/10, @lan pc ping DUT failed when repeater mode & igmp enabled*/
3116                    //system("/usr/sbin/brctl delif br0 vlan1");
3117                    //system("/usr/sbin/et robowr 0x34 0x00 0x00");
3118#ifdef IGMP_PROXY
3119                    if (!nvram_match("igmp_proxying_enable", "1"))
3120#endif
3121                    {
3122                        system("/usr/sbin/brctl delif br0 vlan1");
3123                        system("/usr/sbin/et robowr 0x34 0x00 0x00");
3124                    }
3125                    /*foxconn modified end, water, 01/07/10*/
3126#endif
3127                }
3128                /* wklin modified end, 10/23/2008 */
3129                save_wlan_time();
3130                start_bcmupnp();
3131                start_eapd();
3132                start_nas();
3133                start_wps();
3134                if(nvram_match("enable_sta_mode","0") )
3135                    start_acsd();
3136                sleep(2);
3137                start_wl();
3138                /* Now start ACOS services */
3139                eval("acos_init");
3140                eval("acos_service", "start");
3141
3142                /* Start wsc if it is in 'unconfiged' state, and if PIN is not disabled */
3143                if (nvram_match("wl0_wps_config_state", "0") && !nvram_match("wsc_pin_disable", "1"))
3144                {
3145                    /* if "unconfig" to "config" mode, force it to built-in registrar and proxy mode */
3146                    nvram_set("wl_wps_reg", "enabled");
3147                    nvram_set("wl0_wps_reg", "enabled");
3148                    nvram_set("wps_proc_status", "0");
3149                    nvram_set("wps_method", "1");
3150                    //nvram_set("wps_config_command", "1");
3151                }
3152
3153                /* Foxconn added start pling 03/30/2009 */
3154                /* Fix antenna diversiy per Netgear Bing's request */
3155#if 0//(!defined WNR3500v2VCNA)        // pling added 04/10/2009, vnca don't want fixed antenna
3156                eval("wl", "down");
3157                eval("wl", "nphy_antsel", "0x02", "0x02", "0x02", "0x02");
3158                eval("wl", "up");
3159#endif
3160                /* Foxconn added end pling 03/30/2009 */
3161                //eval("wl", "interference", "2");    // pling added 03/27/2009, per Netgear Fanny request
3162
3163#if ( (defined SAMBA_ENABLE) || (defined HSDPA) )
3164                if (!acosNvramConfig_match("wla_wlanstate", "Enable"))
3165                {/*water, 05/15/2009, @disable wireless, router will reboot continually*/
3166                    /*on WNR3500L, WNR3500U, MBR3500, it was just a work around..*/
3167                    eval("wl", "down");
3168                }
3169#endif
3170
3171                /* Fall through */
3172            case TIMER:
3173                /* Foxconn removed start pling 07/12/2006 */
3174#if 0
3175                dprintf("TIMER\n");
3176                do_timer();
3177#endif
3178                /* Foxconn removed end pling 07/12/2006 */
3179                /* Fall through */
3180            case IDLE:
3181                dprintf("IDLE\n");
3182                /* foxconn modified start, zacker, 05/20/2010, @spec_1.9 */
3183                //state = IDLE;
3184                state = next_signal();
3185                if (state != IDLE)
3186                    break;
3187                /* foxconn modified end, zacker, 05/20/2010, @spec_1.9 */
3188
3189#ifdef CAPI_AP
3190                if(start_aput == TRUE) {
3191                    system("/usr/sbin/wfa_aput_all&");
3192                    start_aput = FALSE;
3193                }
3194#endif /* CAPI_AP */
3195
3196                /* foxconn added start, zacker, 09/17/2009, @wps_led */
3197                if (nvram_match("wps_start",   "none"))
3198                    /* Foxconn add modified, Tony W.Y. Wang, 12/03/2009 */
3199                    //send_wps_led_cmd(WPS_LED_BLINK_OFF, 0);
3200                    if (acosNvramConfig_match("dome_led_status", "ON"))
3201                        send_wps_led_cmd(WPS_LED_BLINK_OFF, 3);
3202                    else if (acosNvramConfig_match("dome_led_status", "OFF"))
3203                        send_wps_led_cmd(WPS_LED_BLINK_OFF, 2);
3204                /* foxconn added end, zacker, 09/17/2009, @wps_led */
3205
3206                /* Wait for user input or state change */
3207                while (signalled == -1) {
3208                    if (!noconsole && (!shell_pid || kill(shell_pid, 0) != 0))
3209                        shell_pid = run_shell(0, 1);
3210                    else {
3211
3212                        sigsuspend(&sigset);
3213                    }
3214#ifdef LINUX26
3215                    //system("echo 1 > /proc/sys/vm/drop_caches");
3216                    system("echo 8192 > /proc/sys/vm/min_free_kbytes");
3217#elif defined(__CONFIG_SHRINK_MEMORY__)
3218                    eval("cat", "/proc/shrinkmem");
3219#endif	/* LINUX26 */
3220                }
3221                state = signalled;
3222                signalled = -1;
3223                break;
3224
3225            case WSC_RESTART:
3226                dprintf("WSC_RESTART\n");
3227                /* foxconn modified start, zacker, 05/20/2010, @spec_1.9 */
3228                //state = IDLE;
3229                state = next_signal();
3230                /* foxconn modified end, zacker, 05/20/2010, @spec_1.9 */
3231                stop_wps();    /* Foxconn modify by aspen Bai, 08/01/2008 */
3232                start_wps();    /* Foxconn modify by aspen Bai, 08/01/2008 */
3233                break;
3234
3235                /* Foxconn added start pling 06/14/2007 */
3236                /* We come here only if user press "apply" in Wireless GUI */
3237            case WLANRESTART:
3238
3239                stop_wps();
3240                stop_nas();
3241                stop_eapd();
3242                stop_bcmupnp();
3243
3244                stop_wlan();
3245
3246                /*Foxconn add start by Hank 06/14/2012*/
3247                /*Enable 2.4G auto channel detect, kill acsd stop change channel*/
3248                if((nvram_match("wla_channel", "0") || nvram_match("wlg_channel", "0")) && nvram_match("enable_sta_mode","0"))
3249                    stop_acsd();
3250                /*Foxconn add end by Hank 06/14/2012*/
3251                eval("read_bd");    /* sync foxconn and brcm nvram params */
3252
3253                /* wklin modified start, 01/29/2007 */
3254                /* hide unnecessary warnings (Invaid XXX, out of range xxx etc...)*/
3255                {
3256#include <fcntl.h>
3257                    int fd1, fd2;
3258                    fd1 = dup(2);
3259                    fd2 = open("/dev/null", O_WRONLY);
3260                    close(2);
3261                    dup2(fd2, 2);
3262                    close(fd2);
3263                    start_wlan(); //<-- to hide messages generated here
3264                    close(2);
3265                    dup2(fd1, 2);
3266                    close(fd1);
3267                }
3268                /* wklin modified end, 01/29/2007 */
3269#if 0
3270                /* Foxconn add start, Tony W.Y. Wang, 03/25/2010 @Single Firmware Implementation */
3271                if (nvram_match("sku_name", "NA"))
3272                {
3273                    printf("set wl country and power of NA\n");
3274                    eval("wl", "country", "Q1/15");
3275                    /* Foxconn modify start, Max Ding, 12/27/2010 "US/39->US/8" for open DFS band 2&3 channels */
3276                    //eval("wl", "-i", "eth2", "country", "US/39");
3277                    eval("wl", "-i", "eth2", "country", "Q1/15");
3278                    /* Foxconn modify end, Max Ding, 12/27/2010 */
3279                    /* Foxconn remove start, Max Ding, 12/27/2010 fix time zone bug for NA sku */
3280                    //nvram_set("time_zone", "-8");
3281                    /* Foxconn remove end, Max Ding, 12/27/2010 */
3282                    nvram_set("wla_region", "11");
3283                    nvram_set("wla_temp_region", "11");
3284                    nvram_set("wl_country", "Q1");
3285                    nvram_set("wl_country_code", "Q1");
3286                    nvram_set("ver_type", "NA");
3287                }
3288                /*
3289                   else if (nvram_match("sku_name", "WW"))
3290                   {
3291                   printf("set wl country and power of WW\n");
3292                   eval("wl", "country", "EU/5");
3293                   eval("wl", "-i", "eth2", "country", "EU/5");
3294                   nvram_set("time_zone", "0");
3295                   nvram_set("wla_region", "5");
3296                   nvram_set("wla_temp_region", "5");
3297                   nvram_set("wl_country", "EU5");
3298                   nvram_set("wl_country_code", "EU5");
3299                   nvram_set("ver_type", "WW");
3300                   }
3301                   */
3302                /* Foxconn add end, Tony W.Y. Wang, 03/25/2010 @Single Firmware Implementation */
3303#endif
3304
3305                save_wlan_time();
3306                start_bcmupnp();
3307                start_eapd();
3308                start_nas();
3309                start_wps();
3310                if(nvram_match("enable_sta_mode","0") )
3311                    start_acsd();
3312                sleep(2);           /* Wait for WSC to start */
3313                start_wl();
3314
3315                /* Start wsc if it is in 'unconfiged' state */
3316                if (nvram_match("wl0_wps_config_state", "0") && !nvram_match("wsc_pin_disable", "1"))
3317                {
3318                    /* if "unconfig" to "config" mode, force it to built-in registrar and proxy mode */
3319                    nvram_set("wl_wps_reg", "enabled");
3320                    nvram_set("wl0_wps_reg", "enabled");
3321                    nvram_set("wps_proc_status", "0");
3322                    nvram_set("wps_method", "1");
3323                    //nvram_set("wps_config_command", "1");
3324                }
3325                /* foxconn modified start, zacker, 05/20/2010, @spec_1.9 */
3326                //state = IDLE;
3327                state = next_signal();
3328                /* foxconn modified end, zacker, 05/20/2010, @spec_1.9 */
3329                break;
3330                /* Foxconn added end pling 06/14/2007 */
3331                /* Foxconn added start by EricHuang, 01/09/2008 */
3332            case PPPSTART:
3333                {
3334                    //char *pptp_argv[] = { "pppd", NULL };
3335                    char *pptp_argv[] = { "pppd", "file", "/tmp/ppp/options", NULL };
3336
3337                    _eval(pptp_argv, NULL, 0, NULL);
3338
3339                    /* foxconn modified start, zacker, 05/20/2010, @spec_1.9 */
3340                    //state = IDLE;
3341                    state = next_signal();
3342                    /* foxconn modified end, zacker, 05/20/2010, @spec_1.9 */
3343                    break;
3344                }
3345                /* Foxconn added end by EricHuang, 01/09/2008 */
3346
3347            default:
3348                dprintf("UNKNOWN\n");
3349                return;
3350        }
3351    }
3352}
3353
3354int
3355main(int argc, char **argv)
3356{
3357	char *base = strrchr(argv[0], '/');
3358
3359
3360    /* Foxconn modified start pling 05/20/2010 */
3361#ifdef LINUX26
3362    if (getpid() == 1)
3363        base = "preinit";
3364    else
3365#endif
3366    {
3367        base = strrchr(argv[0], '/');
3368    	base = base ? base + 1 : argv[0];
3369    }
3370    /* Foxconn modified end pling 05/20/2010 */
3371
3372	/* init */
3373#ifdef LINUX26
3374	if (strstr(base, "preinit")) {
3375		mount("devfs", "/dev", "tmpfs", MS_MGC_VAL, NULL);
3376		/* Michael added */
3377//        mknod("/dev/nvram", S_IRWXU|S_IFCHR, makedev(252, 0));
3378/*        mknod("/dev/mtdblock16", S_IRWXU|S_IFBLK, makedev(31, 16));
3379        mknod("/dev/mtdblock17", S_IRWXU|S_IFBLK, makedev(31, 17));
3380        mknod("/dev/mtd16", S_IRWXU|S_IFCHR, makedev(90, 32));
3381        mknod("/dev/mtd16ro", S_IRWXU|S_IFCHR, makedev(90, 33));
3382        mknod("/dev/mtd17", S_IRWXU|S_IFCHR, makedev(90, 34));
3383        mknod("/dev/mtd17ro", S_IRWXU|S_IFCHR, makedev(90, 35));*/
3384		/* Michael ended */
3385		mknod("/dev/console", S_IRWXU|S_IFCHR, makedev(5, 1));
3386		mknod("/dev/aglog", S_IRWXU|S_IFCHR, makedev(AGLOG_MAJOR_NUM, 0));
3387		mknod("/dev/wps_led", S_IRWXU|S_IFCHR, makedev(WPS_LED_MAJOR_NUM, 0));
3388#ifdef __CONFIG_UTELNETD__
3389		mkdir("/dev/pts", 0777);
3390		mknod("/dev/pts/ptmx", S_IRWXU|S_IFCHR, makedev(5, 2));
3391		mknod("/dev/pts/0", S_IRWXU|S_IFCHR, makedev(136, 0));
3392		mknod("/dev/pts/1", S_IRWXU|S_IFCHR, makedev(136, 1));
3393#endif	/* __CONFIG_UTELNETD__ */
3394#else /* LINUX26 */
3395	if (strstr(base, "init")) {
3396#endif /* LINUX26 */
3397		main_loop();
3398		return 0;
3399	}
3400
3401	/* Set TZ for all rc programs */
3402	setenv("TZ", nvram_safe_get("time_zone"), 1);
3403
3404	/* rc [stop|start|restart ] */
3405	if (strstr(base, "rc")) {
3406		if (argv[1]) {
3407			if (strncmp(argv[1], "start", 5) == 0)
3408				return kill(1, SIGUSR2);
3409			else if (strncmp(argv[1], "stop", 4) == 0)
3410				return kill(1, SIGINT);
3411			else if (strncmp(argv[1], "restart", 7) == 0)
3412				return kill(1, SIGHUP);
3413		    /* Foxconn added start by EricHuang, 11/24/2006 */
3414		    else if (strcmp(argv[1], "wlanrestart") == 0)
3415		        return kill(1, SIGQUIT);
3416		    /* Foxconn added end by EricHuang, 11/24/2006 */
3417		} else {
3418			fprintf(stderr, "usage: rc [start|stop|restart|wlanrestart]\n");
3419			return EINVAL;
3420		}
3421	}
3422
3423#ifdef __CONFIG_NAT__
3424	/* ppp */
3425	else if (strstr(base, "ip-up"))
3426		return ipup_main(argc, argv);
3427	else if (strstr(base, "ip-down"))
3428		return ipdown_main(argc, argv);
3429
3430	/* udhcpc [ deconfig bound renew ] */
3431	else if (strstr(base, "udhcpc"))
3432		return udhcpc_wan(argc, argv);
3433#endif	/* __CONFIG_NAT__ */
3434
3435#if 0 /* foxconn wklin removed, 05/14/2009 */
3436	/* ldhclnt [ deconfig bound renew ] */
3437	else if (strstr(base, "ldhclnt"))
3438		return udhcpc_lan(argc, argv);
3439
3440	/* stats [ url ] */
3441	else if (strstr(base, "stats"))
3442		return http_stats(argv[1] ? : nvram_safe_get("stats_server"));
3443#endif
3444
3445	/* erase [device] */
3446	else if (strstr(base, "erase")) {
3447		/* foxconn modified, zacker, 07/09/2010 */
3448		/*
3449		if (argv[1] && ((!strcmp(argv[1], "boot")) ||
3450			(!strcmp(argv[1], "linux")) ||
3451			(!strcmp(argv[1], "rootfs")) ||
3452			(!strcmp(argv[1], "nvram")))) {
3453		*/
3454		if (argv[1]) {
3455			return mtd_erase(argv[1]);
3456		} else {
3457			fprintf(stderr, "usage: erase [device]\n");
3458			return EINVAL;
3459		}
3460	}
3461
3462	/* write [path] [device] */
3463	else if (strstr(base, "write")) {
3464		if (argc >= 3)
3465			return mtd_write(argv[1], argv[2]);
3466		else {
3467			fprintf(stderr, "usage: write [path] [device]\n");
3468			return EINVAL;
3469		}
3470	}
3471
3472	/* hotplug [event] */
3473	else if (strstr(base, "hotplug")) {
3474		if (argc >= 2) {
3475			if (!strcmp(argv[1], "net"))
3476				return hotplug_net();
3477		/*foxconn modified start, water, @usb porting, 11/11/2008*/
3478/*#ifdef __CONFIG_WCN__
3479			else if (!strcmp(argv[1], "usb"))
3480				return hotplug_usb();
3481#endif*/
3482        /*for mount usb disks, 4m board does not need these codes.*/
3483
3484#if (defined SAMBA_ENABLE || defined HSDPA) /* Foxconn add, FredPeng, 03/16/2009 @HSDPA */
3485			/* else if (!strcmp(argv[1], "usb"))
3486				return usb_hotplug(); */
3487				/*return hotplug_usb();*/
3488			else if (!strcmp(argv[1], "block"))
3489                return hotplug_block(); /* wklin modified, 02/09/2011 */
3490#if defined(LINUX_2_6_36)
3491			else if (!strcmp(argv[1], "platform"))
3492				return coma_uevent();
3493#endif /* LINUX_2_6_36 */
3494#endif
3495#if defined(BONJOUR_PRINTER)
3496			else if (!strcmp(argv[1], "usb")){
3497                            return hotplug_usb_printer();
3498                        }
3499#endif
3500            /* Foxconn added start pling 10/05/2012 */
3501            /* For USB LED after Kcode printer detection */
3502#if (defined INCLUDE_USB_LED)
3503            else
3504            {
3505                char *driver = getenv("PHYSDEVDRIVER");
3506                if (driver && strstr(driver, "NetUSB"))
3507                {
3508                    hotplug_NetUSB();
3509                }
3510            }
3511#endif
3512            /* Foxconn added end pling 10/05/2012 */
3513
3514        /*foxconn modified end, water, @usb porting, 11/11/2008*/
3515		} else {
3516			fprintf(stderr, "usage: hotplug [event]\n");
3517			return EINVAL;
3518		}
3519	}
3520
3521	return EINVAL;
3522}
3523