/*
 * Copyright 2003-2004 by Gemtek Technology Co., Ltd
 *
 * All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Gemtek not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <fcntl.h>

#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysinfo.h>
#include <sys/wait.h>

#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if_arp.h>

#include <ctype.h>
#include <typedefs.h>
#include <proto/ethernet.h>
#include <wlioctl.h>
#include <wlutils.h>

#include <bcmnvram.h>
#include <netconf.h>
#include <shutils.h>
#include <rc.h>

#include <ap.h>
#include <ap_hdr.h>		/* add header herer */
#include <ap_ver.h>
#include <ap_shared.h>

#include <linux/mtd/mtd.h>
#include <etsockio.h>
#include <epivers.h>

#define wlconfig(name)	eval("wlconfig", name)

#ifdef Link
#include <netconf.h>
typedef u_int64_t u64;
typedef u_int32_t u32;
typedef u_int16_t u16;
typedef u_int8_t  u8;
#include <linux/ethtool.h>
#include <linux/sockios.h>
#endif

/* for global var */

struct stat assoclist ;

/* start for declaration function */
#ifdef AP_Client
int start_ap_client() ;
#endif /* AP_Client */
#ifdef SiteSurvay
int do_SiteSurvay(char *mac, char *mode) ;
struct site_survay_t {
	char SSID[33];
	char Mode[10];
	int  RSSI;
	char noise[4];
	char Channel[3];
	char BSSID[18];
	char Capability[30];
	char SupRate;
	char WPA;
} site_survay_table[SITESURVEY_CNT] ;
#endif /* end of SiteSurvay */
#ifdef SITESURVEY_QUEUE
SITESURVEY_LIST *SL = NULL ;
#endif /* end of SITESURVEY_QUEUE */
/******** End of declaration function *******/

struct params_t {
	char *name ;
	char *default_val ;
} necessary_params_table[] = {
#ifdef SETDEFVALS
	{	"def_wl_ssid", 			"" 		},
	{	"def_wl_key1", 			"" 		},
	{	"def_wl_key2", 			"" 		},
	{	"def_wl_key3", 			"" 		},
	{	"def_wl_key4", 			"" 		},
	{	"def_wl_wep", 			"" 		},
	{	"def_auth_mode",		"" 		},
#endif /* end of SETDEFVALS */
	{	"EnableLAN", 			"on" 		},
#ifdef SetAntDiv
	{	"antenna_selection", 	"default" 	},
#endif
	{	"security_mode_page", 	"4" 		}, /* WEP.asp */
#if defined(DetectModleNumber)
	{	"chk_fw_hdr", 		"Enabled" 		},
#endif /* DetectModleNumber */
#if defined(DetectDownGrade)
	{	"chk_downgrade_hdr","Enabled" 		},
#endif /* DetectDownGrade */
#if defined(FCCTesting)
	{	"pwr", 				"32" 			},
	{	"receive", 			"stop" 			},
	{	"client_ipaddr", 	"192.168.1.100"	},
	{	"ip_1", 			"192" 			},
	{	"ip_2", 			"168" 			},
	{	"ip_3", 			"1" 			},
	{	"ip_4", 			"100" 			},
	{	"single_carrier", 	"Disable"		},
#endif
#if defined(BCM4712APBOARD)
	{	"wl0gpio0", 	    "0"		        },
	{	"wl0gpio1", 	    "0"		        },
	{	"wl0gpio2", 	    "0"		        },
	{	"wl0gpio3", 	    "0"		        },
	{	"wl0gpio4", 	    "0"		        },
	{	"wl0gpio5", 	    "2"		        }, /* 2 for wireless activity */
	{	"ap_client_wep",    "off"	        },
	{	"ap_client_wep_key", ""		        },
	{	"ap_client_wep_mode", "open"		},
	{	"ap_repeater_mode", "stop"		},
#endif
	{	0,      				0      		},
};

struct wireless_params_t {
	char *p1;
	char *p2;
} convert_wireless_table[] = {
	   /* original */     				  /* changed */
	{   	"wl_channel", 			"wl0_channel" 					},
	{   	"wl_gmode",			"wl0_gmode"					},
	{	"wl_hwaddr",    			"wl0_hwaddr"  					},
	{   	"wl_lazywds",   			"wl0_lazywds" 					},
	//{	"wl_auth",      			"wl0_auth"   	 				},
	{	"wl_wds",				"wl0_wds"	  					},
	//{	"wl_key",       			"wl0_key"     					},
	//{	"wl_key1",      			"wl0_key1"    					},
	//{	"wl_key2",      			"wl0_key2"    					},
	//{	"wl_key3", 	     		"wl0_key3"    					},
	//{	"wl_key4",      			"wl0_key4"    					},
	{	"wl_country",			"wl0_country" 					},
	{	"wl_radio",			"wl0_radio"   					},
	{   	"wl_macmode",			"wl0_macmode" 				},
	{	"wl_maclist",			"wl0_maclist" 					},
	//{	"wl_ssid",				"wl0_ssid"    					},
	{	"wl_mode",			"wl0_mode"	  				},
	{	"wl_closed",			"wl0_closed"					},
	//{	"wl_wep",				"wl0_wep"						},
	{	"wl_mac_hwaddr",		"wl0_maclist"					},
	{	"wl_auth_mode",        	"wl0_auth_mode"        	     		},
	//{	"wl_akm",				"wl0_akm" 		       	     		},
	//{	"wl_akm",				0		 		       	     		},
	//{   	"wl_wpa_psk",          	"wl0_wpa_psk"              		 	},
	//{   	"wl_wpa_gtk_rekey",	"wl0_wpa_gtk_rekey"         		},
	//{   	"wl_crypto",			"wl0_crypto"					},
	{   	"wl_radius_ipaddr",    	"wl0_radius_ipaddr"         			},
	{   	"wl_radius_key",       	"wl0_radius_key"            			},
	{   	"wl_radius_port",      	"wl0_radius_port"           			},
	{   	"wl_corerev", 			"wl0_corerev"               			},
	{   	"wl_radioids",			"wl0_radioids"					},
	{   	"wl_frameburst",		"wl0_frameburst"				},
	{   	"wl0_unit",			0							},
	{	"wl0_ifname",			0							},
	{	"wl0_phytype",			0							},
	{	"wl_plcphdr",			"wl0_plcphdr"					},
	{	"wl_rate",				"wl0_rate"						},
	{	"wan_hostname",		"wan0_hostname"						},

	{	"wl_country_code",		"wl0_country_code"				},
	{   0, 					0 						 	}
};

#ifdef B_3_11_19_0
int wl_ioctl(char *name, int cmd, void *buf, int len)
{
	struct ifreq ifr;
	wl_ioctl_t ioc;
	int ret = 0;
 	int s;

	/* open socket to kernel */
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket");
		return errno;
	}

	/* do it */
	ioc.cmd = cmd;
	ioc.buf = buf;
	ioc.len = len;
	strncpy(ifr.ifr_name, name, IFNAMSIZ);
	ifr.ifr_data = (caddr_t) &ioc;
	if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0)
		perror(ifr.ifr_name);

	/* cleanup */
	close(s);
	return ret;
}
#endif


void start_my_services()
{
char bridge_buf[100];

make_scripts();

#if defined(AP_Repeater)
	system( "/sbin/AutoScanOnBtn &" );
	system( "/sbin/APRepeaterDaemon &" );
	start_ap_repeater();
#endif

// PANTELTJE
//	system( "/sbin/easyconf &" );

#ifdef BCM4712APBOARD
#ifndef FCCTesting

// PANTELTJE
//	system( "/sbin/RestoreDefaults &" );

#endif
#else

// PANTELTJE
//	system( "/sbin/ResetToDefault &" );


#endif

//#ifdef __CONFIG_SNMPDSET__
	system( "/sbin/snmpdset &" );
//#endif

#ifdef AssociateDaemon
	system( "/sbin/assoclistd &" );
#endif


#ifdef SetAntDiv
	start_antenna_selection() ;
#endif

	make_killall_daemons_script("/tmp/killall_daemons");

#ifdef AP_Client
	start_ap_client() ;
#endif

	save_firmware_version();

#ifdef FCCTesting
	start_fcc_test() ;
#endif

#ifdef AP_Client
	//check_ap_client();
#endif

// +++ Vic Yu added
#if 1
	if(strcmp(nvram_safe_get("ap_mode"),"3")==0)
	{
		// Bridge mode
		fprintf(stderr,"Pointer !!\n");
		memset( bridge_buf, '\0', sizeof(bridge_buf) );
		if(strcmp(nvram_safe_get("wds0"),"")!=0)
		{
			fprintf(stderr,"1-");
			sprintf( bridge_buf, "/usr/sbin/wl wds %s &", nvram_safe_get("wds0") );
			system( bridge_buf );
			sleep(1);
		}
		if(strcmp(nvram_safe_get("wds1"),"")!=0)
		{
			fprintf(stderr,"2-");
			sprintf( bridge_buf, "/usr/sbin/wl wds %s &", nvram_safe_get("wds1") );
			system( bridge_buf );
			sleep(1);
		}
		if(strcmp(nvram_safe_get("wds2"),"")!=0)
		{
			fprintf(stderr,"3-");
			sprintf( bridge_buf, "/usr/sbin/wl wds %s &", nvram_safe_get("wds2") );
			system( bridge_buf );
			sleep(1);
		}
		if(strcmp(nvram_safe_get("wds3"),"")!=0)
		{
			fprintf(stderr,"4");
			sprintf( bridge_buf, "/usr/sbin/wl wds %s &", nvram_safe_get("wds3") );
			system( bridge_buf );
			sleep(1);
		}
		fprintf(stderr,"Script Finish!!\n");
	}

#endif
// - - - Vic Yu added , re-start wireless interface for WPA authentication
	//system( "/sbin/easyconf &" );
	dprintf("done\n");
}


void stop_my_services()
{
	eval( "killall", "easyconf" );

#if defined(AP_Repeater)
	eval( "killall", "AutoScanOnBtn" );
	eval( "killall", "DetectWDSLink" );
#endif
#ifdef BCM4712APBOARD
	eval( "killall", "RestoreDefaults" );
#else
	eval( "killall", "ResetToDefault" );
#endif
#if !defined(LinksysWRE54G)
	eval( "killall", "snmpdset" );
	eval( "killall", "udhcpc" );
#endif
#ifdef Associate_List
	eval( "killall", "assoclistd" );
#endif

	unlink( "/tmp/config.bin" );
	set_log_info( "System log daemon exiting." );

	dprintf("done\n");
}


void Conf_ETH1(char *lan_ifname)
{
#if defined(PHYCONF)
	start_phyconf() ;
#endif

	if( !strcmp(nvram_safe_get("wan_proto"), "static") )
	{	/* Static IP Address */
		/* Bring up and configure LAN interface */
		ifconfig(lan_ifname, IFUP, nvram_safe_get("wan_ipaddr"), nvram_safe_get("wan_netmask"));
		/* Set default route to gateway if specified */
		if(strcmp(nvram_safe_get("wan_gateway"), "0.0.0.0"))
		{
			route_add(lan_ifname, 0, "0.0.0.0", nvram_safe_get("wan_gateway"), "0.0.0.0");
		}
	}
	else if( !strcmp(nvram_safe_get("wan_proto"), "dhcp") )
	{	/* DHCP Client */
		char *wan_hostname = nvram_get("wan_hostname");
		char *lan_ifname = "br0" ;
		char *dhcp_argv[] =
		{ "udhcpc",
		  "-i", lan_ifname,
		  "-p", "/var/run/udhcpc.pid",
		  "-s", "/tmp/udhcpc",
		  wan_hostname && *wan_hostname ? "-H" : NULL,
		  wan_hostname && *wan_hostname ? wan_hostname : NULL,
		  NULL
		};
		pid_t pid;

		symlink("/sbin/rc", "/tmp/udhcpc");

		_eval(dhcp_argv, NULL, 0, &pid);
	}

#ifdef BACKUP_RESTORE
#ifdef B_3_21_7_0
	make_nvram_list();
#endif
	/* make /tmp/config.bin */
	{
		char *restore_argv[7] ;

		restore_argv[0] = "restore" ;
		restore_argv[1] = "/tmp/var/tmp/nvram" ;
		restore_argv[2] = "1" ;
		restore_argv[3] = "/tmp/config.bin" ;
		restore_argv[4] = "/tmp/restore_test" ;
		restore_argv[5] = "linksyswap11" ;
		restore_argv[6] = NULL ;
		pid_t pid;
		int ret ;

		ret = _eval(restore_argv, NULL, 0, &pid);
		waitpid(pid, &ret, WUNTRACED);
	}

#ifdef AddRestoreHdr
	add_restore_hdr("/tmp/config.bin");
#endif /* end of AddRestoreHdr */

#endif /* end of BACKUP_RESTORE */
}


int ap_syslogd(char* msg)
{
	char *remote_ipaddr = NULL ;
	char *log_ipaddr_4 = NULL ;
	char log_ipaddr[16] ;
	int sockfd ;
	struct sockaddr_in serv_addr, cli_addr ;
	int n ;

	/* get log_ipaddr */
	remote_ipaddr = nvram_safe_get( "log_ipaddr" );
	log_ipaddr_4 = nvram_safe_get( "log_ipaddr_4" );

	if( remote_ipaddr != NULL &&
		strcmp(remote_ipaddr, "0.0.0.0") &&
		log_ipaddr_4 != NULL )
	{
		memset( log_ipaddr, '\0', sizeof(log_ipaddr) );
		sprintf( log_ipaddr, "%s.%s.%s.%s",
				 nvram_safe_get( "wan_ipaddr_1" ), nvram_safe_get( "wan_ipaddr_2" ),
				 nvram_safe_get( "wan_ipaddr_3" ), nvram_safe_get( "log_ipaddr_4" ) );

		/* save log */
		set_log_info( msg );

		bzero( (char *)&serv_addr, sizeof(serv_addr) ) ;
		serv_addr.sin_family = AF_INET ;
		serv_addr.sin_addr.s_addr = inet_addr(log_ipaddr) ;
		serv_addr.sin_port = htons(SERV_UDP_PORT) ;

		/* open a UDP socket */
		if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
		{
			perror( "open a UDP socket fail " );
			return -1 ;
		}

		/* bind any local address for us */
		bzero( (char *)&cli_addr, sizeof(cli_addr) ) ;
		cli_addr.sin_family = AF_INET ;
		cli_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
		cli_addr.sin_port = htons(0) ;

		if( bind( sockfd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) < 0 )
	{
			perror( "client: can't bind local address " );
			return -1 ;
		}

		n = strlen(msg) ;

		if( sendto(sockfd, msg, n, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != n )
		{
			perror( "sendto error " );
			return -1 ;
		}

		close(sockfd) ;
	}

	return 0;
}


#if 0
void send_log(char* msg)
{
	char *remote_ipaddr = NULL ;
	char *log_ipaddr_4 = NULL ;
	int sockfd ;
	struct sockaddr_in serv_addr, cli_addr ;
	int n ;

	/* get log_ipaddr */
	remote_ipaddr = nvram_get( "log_ipaddr" );
	log_ipaddr_4 = nvram_get( "log_ipaddr_4" );

	if( remote_ipaddr != NULL &&
		strcmp(remote_ipaddr, "0.0.0.0") &&
		log_ipaddr_4 != NULL )
	{
		bzero( (char *)&serv_addr, sizeof(serv_addr) ) ;
		serv_addr.sin_family = AF_INET ;
		serv_addr.sin_addr.s_addr = inet_addr(remote_ipaddr) ;
		serv_addr.sin_port = htons(SERV_UDP_PORT) ;

		/* open a UDP socket */
		if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
		{
			perror( "open a UDP socket fail " );
			goto fail ;
		}

		/* bind any local address for us */
		bzero( (char *)&cli_addr, sizeof(cli_addr) ) ;
		cli_addr.sin_family = AF_INET ;
		cli_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
		cli_addr.sin_port = htons(0) ;

		if( bind( sockfd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) < 0 )
		{
			perror( "client: can't bind local address " );
			goto fail ;
		}

		n = strlen(msg) ;

		if( sendto(sockfd, msg, n, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != n )
		{
			perror( "sendto error " );
			goto fail ;
		}

		close(sockfd) ;
	}
fail:
}
#endif


void start_wl_assoclist()
{
#if defined(Associate_List_5G)
	int ret = 0 ;

	ASSOCDBG(fprintf( stderr, "/* make /tmp/assoclist_5G */\n");)
	/* /tmp/assoclist_5G */
	ret = MakeAssocList_5G() ;
	if( ret == 0 )
	{
		/* get size of /tmp/assoclist_5G */
		stat( ASSOCLIST_5G, &assoclist_5G );
		ASSOCDBG(fprintf( stderr, "assoclist_5G.st_size=<%d>\n", assoclist_5G.st_size );)
	}
#endif

#if defined(Associate_List)
#if 0
	ASSOCDBG(fprintf( stderr, "/* make /tmp/assoclist */\n");)
	/* /tmp/assoclist */
	system("/usr/sbin/wl assoclist >/tmp/assoclist" );
	/* get size of /tmp/assoclist */
	stat( ASSOCLIST, &assoclist );
#endif
	assoclist.st_size = 0 ;
	ASSOCDBG(fprintf( stderr, "assoclist.st_size=<%d>\n", assoclist.st_size );)
#endif

	while(1)
	{
#if defined(Associate_List_5G)
		ASSOCDBG(fprintf( stderr, "/* start Associate_List_5G */\n");)
		sleep(2) ;
		WirelessAssocList_5G() ;
#endif
#if defined(Associate_List)
		ASSOCDBG(fprintf( stderr, "/* start Associate_List */\n");)
		sleep(2);
		WirelessAssocList() ;
#endif
	}
}


void WirelessAssocList()
{
	FILE *fp = NULL ;
	char *buf ;
	struct stat my_assoclist ;
	int assoclist_cnt = 0;
	int my_assoclist_cnt = 0;
	int cnt = 0;
	int diff = 0 ;
	int i = 0;
	char val1[10], val2[18] ;
	char msg[50];
	char *boardtype = NULL ;

	boardtype = nvram_safe_get("boardtype");

	/* /tmp/assoclist */
	if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
		system("/usr/sbin/wl -i eth1 assoclist >/tmp/assoclist" );
	else
		system("/usr/sbin/wl -i eth2 assoclist >/tmp/assoclist" );

	/* get size of /tmp/assoclist */
	stat( ASSOCLIST, &my_assoclist );

	ASSOCDBG(fprintf( stderr, "assoclist.st_size=<%d> ", assoclist.st_size );)
	ASSOCDBG(fprintf( stderr, "my_assoclist.st_size=<%d>\n", my_assoclist.st_size );)

	if( my_assoclist.st_size > assoclist.st_size )
	{
		assoclist_cnt = (assoclist.st_size)/28 ;
		my_assoclist_cnt = (my_assoclist.st_size)/28 ;

		ASSOCDBG(fprintf( stderr, "assoclist.st_size=<%d> ", assoclist.st_size );)
		ASSOCDBG(fprintf( stderr, "my_assoclist.st_size=<%d>\n", my_assoclist.st_size );)
		ASSOCDBG(fprintf( stderr, "assoclist_cnt=<%d> ", assoclist_cnt );)
		ASSOCDBG(fprintf( stderr, "my_assoclist_cnt=<%d>\n", my_assoclist_cnt );)

		/* Allocate buf */
		buf = (char *)malloc(1024) ;

		/* open /tmp/assoclist */
		fp = fopen( ASSOCLIST, "r" ) ;
		if( fp == NULL )
		{
			DanielDBG(fprintf( stderr, "open /tmp/assoclist error \n" );)
		}

		diff = my_assoclist_cnt-assoclist_cnt ;

		while( !feof(fp) )
		{
			if( (cnt <= assoclist_cnt)&&
				(assoclist_cnt != 0) )
			{
				fgets( buf, 1024, fp );
			}
			else
			{
				fgets( buf, 1024, fp );
				if( i < diff )
				{
					sscanf( buf, "%s %s", val1, val2 );
					memset( msg, '\0', sizeof(msg) );
					sprintf( msg, "Wireless PC connected %s", val2 );
					ap_syslogd( msg );
					i++ ;
				}
			}

			cnt++ ;
		}

		/* close fp */
		fclose(fp);

		/* free buf */
		free(buf);

		assoclist.st_size = my_assoclist.st_size ;
	}
}


#ifdef UpgradePmon
int start_upgrade_pmon()
{
	char pmon_fifo[] = "/sbin/pmon.bin";
	char *write_argv[] = { "write", pmon_fifo, "pmon", NULL };
	char *GemtekPmonVer = NULL ;
	char *etxphyaddr = NULL ;
	char *board = NULL ;
	pid_t pid;
	int ret = EINVAL;

	GemtekPmonVer = nvram_safe_get( "GemtekPmonVer" );
	etxphyaddr = nvram_safe_get( "et1phyaddr" );
	board = nvram_safe_get( "boardtype" );

	if(board && (memcmp(board,"0x0446",6)==0  || memcmp(boardtype, "0x0467", 6)==0 || memcmp(boardtype, "0x467", 5)==0) )  // 4712 board
	{
		fprintf(stderr,"4712 Board !\n");
		return 0;
	}

	if( strcmp( etxphyaddr, "0") || strcmp( GemtekPmonVer, "10") )
	{
		fprintf(stderr, "start upgrade pmon...\n");
		/* excute write function */
		if(	_eval(write_argv, NULL, 0, &pid) )
		{
			fprintf( stderr, "excute write function fail !!!\n" );
			goto fail ;
		}

		/* Wait for write to terminate */
		waitpid(pid, &ret, 0);

fail:
		/* Reboot if successful */
		if( ret == 65280 )
			return 0 ;
		else
		{
			nvram_set( "boardtype", "bcm94710dev" );
			nvram_set( "et0phyaddr", "30" );
			nvram_set( "et1phyaddr", "0" );
			nvram_set( "Pmon_Upgrade", "1" );
			nvram_commit();
			sleep(1);
			system( "/sbin/reboot &" ) ;
		}
	}

	fprintf(stderr, "End of start_upgrade_pmon()\n");
	return 0 ;
}
#endif /* UpgradePmon */


#ifdef FCCTesting
void start_fcc_test()
{
#if 0
	char sys_buf[100];
	char *receive = NULL ;
	char *pwr = NULL ;
	char *client_ipaddr = NULL ;
	char *single_carrier = NULL ;
	char *channel = NULL ;
	int pwr_index = 0 ;

	receive = nvram_safe_get("receive") ;
	pwr = nvram_safe_get("pwr") ;
	client_ipaddr = nvram_safe_get("client_ipaddr") ;
	single_carrier = nvram_safe_get("single_carrier") ;
	channel = nvram_safe_get("wl_channel") ;

	/* single carrier */
	if( !strcmp( single_carrier, "Enable" ) )
	{	/* Only for China */
		memset( sys_buf, '\0', sizeof(sys_buf) );
		system( "/usr/sbin/wl out" );
		DanielDBG(fprintf( stderr, "/usr/sbin/wl out\n" );)
		sprintf( sys_buf, "/usr/sbin/wl fqacurcy %s", channel );
		DanielDBG(fprintf(stderr,"sys_buf=<%s>\n", sys_buf );)
		system( sys_buf );
	}

	if( client_ipaddr != NULL && receive != NULL )
	{
		if( !strcmp( receive, "main" ) )
		{
			system( "/usr/sbin/wl antdiv 0" );
			DanielDBG(fprintf( stderr, "/usr/sbin/wl antdiv 0\n" );)
			system( "/usr/sbin/wl txant 0" );
			DanielDBG(fprintf( stderr, "/usr/sbin/wl txant 0\n" );)

			if( pwr != NULL )
			{

				//pwr_index = *pwr - 64 ;
				pwr_index = atoi(pwr);
				memset( sys_buf, '\0', sizeof(sys_buf) );
				sprintf( sys_buf, "/usr/sbin/wl txpwr1 -o -q %d", pwr_index );
				system( sys_buf );
			}

			memset( sys_buf, '\0', sizeof(sys_buf) );
			sprintf( sys_buf, "/usr/sbin/epi_ttcp -tsu -l 1000 -n 10000000000 %s &", nvram_safe_get("client_ipaddr") );
			/* -l 8760 */
			sleep(1);
			system( sys_buf );
		}
		else if( !strcmp( receive, "aux" ) )
		{
			system( "/usr/sbin/wl antdiv 1" );
			DanielDBG(fprintf( stderr, "/usr/sbin/wl antdiv 1\n" );)
			system( "/usr/sbin/wl txant 1" );
			DanielDBG(fprintf( stderr, "/usr/sbin/wl txant 1\n" );)

			if( pwr != NULL )
			{

				//pwr_index = *pwr - 64 ;
				pwr_index = atoi(pwr);
				memset( sys_buf, '\0', sizeof(sys_buf) );
				sprintf( sys_buf, "/usr/sbin/wl txpwr1 -o -q %d", pwr_index );
				system( sys_buf );
			}

			memset( sys_buf, '\0', sizeof(sys_buf) );
			sprintf( sys_buf, "/usr/sbin/epi_ttcp -tsu -l 1000 -n 10000000000 %s &", nvram_safe_get("client_ipaddr") );
			/* -l 8760 */
			sleep(1);
			system( sys_buf );
		}
	}
#endif
}
#endif /* FCCTesting */


void start_mem_test()
{
	struct sysinfo info;
	char send_buf[20] ;

	while(1)
	{
		memset( send_buf, '\0', sizeof(send_buf) );
		sysinfo(&info);
		//sprintf( send_buf, "%d", (info.freeram/1024) );
		//send_log( send_buf );
		fprintf( stderr, "freeram=%dKB\n\n", (info.freeram/1024) );
		sleep(3) ;
	}
}


int start_test_script(char *mode)
{
	return 0 ;
}


#ifdef AP_Client
int check_ap_client(void)
{
	FILE *p_fp = NULL ;
	char buf[1024] ;
	char *p, *ap_mode, *boardtype ;
	char *sta_argv[2] ;
	int ret, isZero = 0 ;
	pid_t pid ;

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)

	ap_mode = boardtype = p = NULL ;
	ap_mode = nvram_safe_get( "ap_mode" );
	boardtype = nvram_safe_get("boardtype");

	if( strcmp( ap_mode, "1" ) )
		return -1 ;

	p_fp = popen( "/usr/sbin/wl dump", "r" );
	if( p_fp == NULL )
	{
		perror( "popen" );
		return -1 ;
	}

	while( !feof(p_fp) )
	{
		memset( buf, '\0', sizeof(buf) );
		fgets( buf, sizeof(buf), p_fp );
		p = strstr( buf, "00:00:00:00:00:00" );
		if( p != NULL )
		{
			isZero = 1 ;
			break ;
		}
	}

	pclose(p_fp);

	if(isZero)
	{	/* re-join AP/Router */
		sta_argv[0] = "/tmp/besta" ;
		sta_argv[1] = NULL ;

		ret = _eval( sta_argv, NULL, 0, &pid);
		DanielDBG(fprintf( stderr, "%s waitpid...\n", sta_argv[0]);)
		waitpid(pid, &ret, WUNTRACED);
	}

	return 0 ;
}


int make_ap_client_script(char *path)
{
	FILE *fp = NULL ;
	char buf[100];
	char *on, *mode, *boardtype ;

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)

	on = mode = boardtype = NULL ;
	on = nvram_safe_get("ap_client_wep");
	mode = nvram_safe_get("ap_client_wep_mode");
	DanielDBG(fprintf(stderr,"on=<%s> ", on);)
	DanielDBG(fprintf(stderr,"mode=<%s>\n", mode);)
	boardtype = nvram_safe_get("boardtype");

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		return 0 ;
	}

	bzero(buf, sizeof(buf));
	fprintf( fp, "#!/bin/sh\n" );
	fprintf( fp, "nvram set wl0_mode=\"wet\"\n" );
	// Security mode
	fprintf( fp, "nvram set wl0_wep=\"%s\"\n" ,nvram_safe_get("wl_wep"));
	fprintf( fp, "nvram set wl0_akm=\"%s\"\n" ,nvram_safe_get("wl_akm"));
	fprintf( fp, "nvram set wl0_lazywds=\"1\"\n" );

	if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
	{
		fprintf( fp, "wlconf eth1 down\n" );
		fprintf( fp, "wlconf eth1 up\n" );
	}
	else
	{
		fprintf( fp, "wlconf eth2 down\n" );
		fprintf( fp, "wlconf eth2 up\n" );
	}

	//if( !strcmp(on, "off") )
	//{
		if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
			sprintf( buf, "/usr/sbin/wl -i eth1 join \"%s\"", nvram_safe_get("ap_client_ssid") );
		else
			sprintf( buf, "/usr/sbin/wl -i eth2 join \"%s\"", nvram_safe_get("ap_client_ssid") );
	//}
#if 0
	else if( !strcmp(on, "wep") )
	{
		if( !strcmp(mode, "open") )
		{
			if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
				sprintf( buf, "/usr/sbin/wl -i eth1 join \"%s\" key %s imode bss amode open",
					 nvram_safe_get("ap_client_ssid"), nvram_safe_get("ap_client_wep_key") );
			else
				sprintf( buf, "/usr/sbin/wl -i eth2 join \"%s\" key %s imode bss amode open",
					 nvram_safe_get("ap_client_ssid"), nvram_safe_get("ap_client_wep_key") );
		}
		else if( !strcmp(mode, "shared") )
		{
			if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
				sprintf( buf, "/usr/sbin/wl -i eth1 join \"%s\" key %s imode bss amode shared",
					 nvram_safe_get("ap_client_ssid"), nvram_safe_get("ap_client_wep_key") );
			else
				sprintf( buf, "/usr/sbin/wl -i eth2 join \"%s\" key %s imode bss amode shared",
					 nvram_safe_get("ap_client_ssid"), nvram_safe_get("ap_client_wep_key") );
		}
	}
	else if( !strcmp(on, "psk") )  // WPA-PSK
	{

		fprintf( fp, "wl sup_wpa 1\n" );

		if( !strcmp(mode, "tkip") )  // TKIP
			fprintf( fp, "wl wsec 2\n" );
		else if( !strcmp(mode, "aes") )
			fprintf( fp, "wl wsec 4\n" );

		fprintf( fp, "wl sup_wpa  1\n" );
		fprintf( fp, "wl wpa_auth 2\n" );

		sprintf( buf, "wl set_pmk \"%s\"\n" , nvram_safe_get("ap_client_wep_key"));
		fprintf( fp, "%s", buf );

		sprintf( buf, "wl ssid \"%s\"\n" , nvram_safe_get("ap_client_ssid"));

		/*fprintf( fp, "nvram set wl0_auth_mode=\"psk\"\n" );

		if( !strcmp(mode, "tkip") )
			fprintf( fp, "nvram set wl0_crypto=\"tkip\"\n" );
		else if( !strcmp(mode, "aes") )
			fprintf( fp, "nvram set wl0_crypto=\"aes\"\n" );

		sprintf( buf, "nvram set wl0_wpa_psk=\"%s\"\n" , nvram_safe_get("ap_client_wep_key"));
		fprintf( fp, "%s", buf );

		sprintf( buf, "/usr/sbin/wl -i eth1 join \"%s\" \n",nvram_safe_get("ap_client_ssid"));
		fprintf( fp, "%s", buf );

		if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6)) )
			sprintf( buf, "wlconf eth1 down\nwlconf eth1 up\n");
		else
			sprintf( buf, "wlconf eth2 down\nwlconf eth2 up\n");
		*/
	}
#endif
	fprintf( fp, "%s\n", buf );
	fclose(fp);

	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}


int start_ap_client(void)
{
	char *mode, *ssid, *mac, *ap_mode ;
	char buf[WLC_IOCTL_MAXLEN] ;
#if !defined(BCM4712APBOARD)
	char *name = "eth2" ;
#endif
	int ret ;
	pid_t pid;
	char *sta_argv[2] ;

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)

	mode = ssid = mac = ap_mode = NULL ;
	mode = nvram_safe_get("wl_mode") ;
	ap_mode = nvram_safe_get("ap_mode") ;

	DanielDBG(fprintf(stderr, "mode=<%s> ", mode);)
	DanielDBG(fprintf(stderr, "ap_mode=<%s>\n", ap_mode);)

	if( !strcmp(ap_mode, "1") )
	{	/* AP Client */
		mac  = nvram_safe_get("ap_client_mac") ;
		DanielDBG(fprintf(stderr, "ap_client_mac=<%s>\n", mac);)
		ret = do_SiteSurvay(mac, "1") ;
		DanielDBG(fprintf(stderr,"ret=%d\n", ret);)
	}
	else
		return -1 ;

	ssid = nvram_safe_get("ap_client_ssid") ;

	DanielDBG(fprintf( stderr, "(%s:%d)mode=<%s> ", __FUNCTION__, __LINE__, mode );)
	DanielDBG(fprintf( stderr, "ssid=<%s> ", ssid );)
	DanielDBG(fprintf( stderr, "mac =<%s>\n", mac );)

	if( !strcmp(ap_mode, "1") && strcmp(mac, "") && strcmp(ssid, "") )
	{	/* start to join another AP */
#ifdef BCM4712APBOARD
		make_ap_client_script("/tmp/besta");
		sta_argv[0] = "/tmp/besta" ;
#else
		sta_argv[0] = "besta" ;
#endif /* !BCM4712APBOARD */
		sta_argv[1] = NULL ;
		ret = _eval( sta_argv, NULL, 0, &pid);
		DanielDBG(fprintf( stderr, "%s waitpid...\n", sta_argv[0]);)
		waitpid(pid, &ret, WUNTRACED);
	}

	return 0 ;
}
#endif /* end of AP_Client */

#ifdef SiteSurvay
int ParseScanresults(char *path, char *mode);
int ParseScanresults(char *path, char *mode)
{	/* return: count of AP/Router */
	FILE *fp = NULL ;
	char buf[2048], tmp[100] ;
	int count = 0, isWPA = 0, isSSID = 0 ;
	struct site_survay_t *t ;
	char *p, *q ;
#ifdef SITESURVEY_QUEUE
	site_survey_t qt ;
	int isQueue = 0 ;

	if( !strcmp(mode, "queue") )
		isQueue = 1 ;
#endif

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)
	p = q = NULL ;
	memset( site_survay_table, '\0', sizeof(site_survay_table) );
	t = site_survay_table ;

	fp = fopen( path, "r" ) ;

	if( fp == NULL )
	{
		DanielDBG(fprintf(stderr, "fopen /tmp/scanresults error\n");)
		return 0 ;
	}

	while(!feof(fp))
	{
		memset(buf, '\0', sizeof(buf));
		fgets( buf, sizeof(buf), fp );

		if( !strncmp(buf, "SSID:", 5 ) )
		{
			/* get SSID */
			p = strchr(buf, '"');
			p += 1 ;
			q = strchr(p, '"');
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, p, q-p);
			//DanielDBG(fprintf(stderr, "SSID=<%s> ", tmp);)
			strcpy(t->SSID, tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				strcpy(qt.SSID, tmp);
#endif

			memset(buf, '\0', sizeof(buf));
			fgets( buf, sizeof(buf), fp );

			/* get Mode */
			p = strstr(buf, "Mode:");
			p += 6 ;
			q = strstr(p, "RSSI:");
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, p, q-p-1);
			//DanielDBG(fprintf(stderr, "Mode:%s ", tmp);)
			strcpy(t->Mode, tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				strcpy(qt.Mode, tmp);
#endif

			/* get RSSI */
			q += 6 ;
			p = strstr(q, "dBm");
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, q, p-q);
			//DanielDBG(fprintf(stderr, "RSSI:%s(dBm) ", tmp);)
			t->RSSI = atoi(tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				qt.RSSI = atoi(tmp) ;
#endif

			/* get noise */
			q = strstr(p, "noise:");
			q += 7 ;
			p = strstr(q, "dBm");
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, q, p-q);
			//DanielDBG(fprintf(stderr, "noise:%s(dBm) ", tmp);)
			strcpy(t->noise, tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				strcpy(qt.noise, tmp);
#endif

			/* get Channel */
			q = strstr(p, "Channel:");
			q += 9 ;
			p = strchr(q, 0x0a);
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, q, p-q);
			//DanielDBG(fprintf(stderr, "Channel:%s \n", tmp);)
			strcpy(t->Channel, tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				strcpy(qt.Channel, tmp);
#endif
			isSSID = 1 ;
		}
		else if( !strncmp(buf, "BSSID:", 6 ) )
		{
			/* get BSSID */
			p = strstr(buf, "BSSID:");
			p += 7 ;
			q = strchr(p, '\t');
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, p, q-p);
			//DanielDBG(fprintf(stderr, "BSSID=%s ", tmp);)
			strcpy(t->BSSID, tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				strcpy(qt.BSSID, tmp);
#endif

			/* get capability */
			q += 13 ;
			p = strchr(q, 0x0a);
			memset(tmp, '\0', sizeof(tmp));
			strncpy(tmp, q, p-q-1);
			//DanielDBG(fprintf(stderr, "Capability=%s \n", tmp);)
			strcpy(t->Capability, tmp);
#ifdef SITESURVEY_QUEUE
			if( isQueue )
				strcpy(qt.Capability, tmp);
#endif
		}
		else if( !strncmp(buf, "Supported Rates:", 16 ) )
		{
			p = strstr(buf, "Supported Rates:");
			p += 17 ;
			//DanielDBG(fprintf(stderr, "Supported Rates=%s\n", p);)
			if( strstr(p, "54") != NULL )
			{
				t->SupRate = 'g' ;
#ifdef SITESURVEY_QUEUE
				if( isQueue )
					qt.SupRate = 'g' ;
#endif
			}
			else
			{
				t->SupRate = 'b' ;
#ifdef SITESURVEY_QUEUE
				if( isQueue )
					qt.SupRate = 'b' ;
#endif
			}
		}
		else if( !strncmp(buf, "WSEC->WPA", 9 ) )
			isWPA = 1 ;
		else
		{
			if(isSSID)
			{
				if(isWPA)
				{
					t->WPA = '1' ;
#ifdef SITESURVEY_QUEUE
					if( isQueue )
						qt.WPA = '1' ;
#endif
				}
				else
				{
					t->WPA = '0' ;
#ifdef SITESURVEY_QUEUE
					if( isQueue )
						qt.WPA = '0' ;
#endif
				}

				isWPA = 0 ;
				t++;
#ifdef SITESURVEY_QUEUE
				if( isQueue )
					SL = AddItemToQueue(SL, &qt) ;
#endif
				count++;
				isSSID = 0 ;
			}
		}
	}

	fclose(fp);
	DanielDBG(fprintf(stderr, "count=%d\n", count);)
	return count ;
}


int do_SiteSurvay(char *mac, char *mode)
{
	char buf[1024] ;
	char tmp[100] ;
	char *p = NULL, *q = NULL ;
	int i, count = 0 ;
	int ret;
	pid_t pid;
	char *excute_argv[2] ;

	DanielDBG(fprintf( stderr, "%s()...\n", __FUNCTION__);)

	/* do site survay */
	excute_argv[0] = "/tmp/scan" ; // Modified by Vic Yu
	excute_argv[1] = NULL ;

	ret = _eval( excute_argv, NULL, 6, &pid);
	DanielDBG(fprintf( stderr, "ret=<%d> ", ret );)
	DanielDBG(fprintf( stderr, "pid=<%d>\n", pid );)

	if(ret)
	{
		DanielDBG(fprintf( stderr, "_eval() fail.\n" );)
		return -1 ;
	}

	DanielDBG(fprintf( stderr, "waitpid...\n" );)
	waitpid(pid, &ret, WUNTRACED);

	count = ParseScanresults("/tmp/scanresults", "buffer");

	DanielDBG(fprintf(stderr, "count=<%d>\n", count);)
#ifndef AP_Repeater
	for( i=0 ; i<count ; i++ )
	{
		if( !strncmp( site_survay_table[i].BSSID, mac, 17) )
		{
			DanielDBG(fprintf(stderr, "site_survay_table[%d].BSSID=<%s>\t", i, site_survay_table[i].BSSID);)
			DanielDBG(fprintf(stderr, "mac=<%s>\n", mac);)
			if( !strcmp( mode, "1" ) ) /* AP Client */
			{
				DanielDBG(fprintf(stderr, "site_survay_table[%d].SSID=<%s>\n", i, site_survay_table[i].SSID);)
				nvram_set( "ap_client_ssid", site_survay_table[i].SSID );
			}
			else if( !strcmp( mode, "2" ) ) /* AP Repeater */
			{
				DanielDBG(fprintf(stderr, "site_survay_table[%d].Channel=<%s>\n", i, site_survay_table[i].Channel);)
				nvram_set( "ap_repeater_channel", site_survay_table[i].Channel );
			}
		}
	}
#endif /* end of AP_Repeater */

	unlink("/tmp/scanresults");
	return 0 ;
}
#endif /* end of SiteSurvay */


void convert_wireless_params(void)
{
	struct wireless_params_t *p ;

	DanielDBG(fprintf( stderr,"%s();\n", __FUNCTION__ );)

	for( p=convert_wireless_table ; p->p1 ; p++ )
	{
		if( p->p2 == 0 )
		{
			if(!strcmp("wl0_unit", p->p1))
				nvram_set( p->p1, "0" );
			else if(!strcmp("wl0_ifname", p->p1))
#ifdef BCM4712APBOARD
				nvram_set( p->p1, "eth1" );
#else
				nvram_set( p->p1, "eth2" );
#endif
			else if(!strcmp("wl0_phytype", p->p1))
				nvram_set( p->p1, "g" );
			// +++ Vic Yu added
			//else if(!strcmp("wl_akm", p->p1) && !nvram_match("ses_enable","1"))
			//	nvram_set( "wl0_akm", "" );
			// - - - Vic Yu added

			//DanielDBG(fprintf( stderr, "%s=<%s>\n", p->p1, nvram_safe_get(p->p1) );)
		}
		else
		{
			if(strcmp(nvram_safe_get(p->p1), nvram_safe_get(p->p2)))
			{
				nvram_set( p->p2, nvram_safe_get(p->p1) );
			}

			//DanielDBG(fprintf( stderr, "%s=<%s>\t\t%s=<%s>\n", p->p1, nvram_safe_get(p->p1), p->p2, nvram_safe_get(p->p2) );)
		}
	}

	// Vic Yu added , convert all "lan*" to "wan*" parameter
	nvram_set("wan_ipaddr",nvram_safe_get("lan_ipaddr"));
	nvram_set("wan_netmask",nvram_safe_get("lan_netmask"));
	nvram_set("wan_gateway",nvram_safe_get("lan_gateway"));

}


int check_nvram_params_exist(char *name)
{
	char n[128];

	sprintf( n, "%s", nvram_get(name) );

	if(!memcmp("(null)", n, 6))
	{
		DanielDBG(fprintf( stderr, "(%s)%s=<%s>\n", __FUNCTION__, name, n );)
		return -1;
	}

	return 0 ;
}


int check_nvram_parameters(void)
{
	struct params_t *p ;

	DanielDBG(fprintf( stderr,"%s();\n", __FUNCTION__ );)

	for( p=necessary_params_table ; p->name ; p++ )
	{
		if(check_nvram_params_exist(p->name) == -1)
			nvram_set( p->name, p->default_val );
	}

#ifdef WiFi
	if(check_nvram_params_exist("d11g_rts_cts") == -1)
	{	/* d11g_rts_cts is not existed */
		if(!strcmp(EPI_VERSION_STR, "3.11.30.5"))
			nvram_set( "d11g_rts_cts", "0" );
		else
			nvram_set( "d11g_rts_cts", "off" );
	}

	if(!strcmp(EPI_VERSION_STR, "3.11.30.5"))
	{
		if(!strcmp(nvram_safe_get("d11g_rts_cts"), "off"))
			nvram_set( "d11g_rts_cts", "0" );
		else if(!strcmp(nvram_safe_get("d11g_rts_cts"), "auto"))
			nvram_set( "d11g_rts_cts", "-1" );
	}
	else
	{
		if(!strcmp(nvram_safe_get("d11g_rts_cts"), "0"))
			nvram_set( "d11g_rts_cts", "off" );
		else if(!strcmp(nvram_safe_get("d11g_rts_cts"), "-1"))
			nvram_set( "d11g_rts_cts", "auto" );
	}
#endif /* end of WiFi */

	if( strcmp(nvram_safe_get("ap_mode"), "2") )
	{	/* it's not equal to AP repeater */
		nvram_set( "EnableLAN", "on" );
	}

	if(	!strcmp(nvram_safe_get("sitesurvay"), "on") )
	{	/* do site survay */
		DanielDBG(fprintf( stderr, "/* do site survay */\n" );)
		nvram_set( "sitesurvay", "off" );
		if(!strcmp(nvram_safe_get("ap_mode"), "0"))
			nvram_set( "wl_mode", "ap" );
		else if(!strcmp(nvram_safe_get("ap_mode"), "2"))
			nvram_set( "wl_mode", "ap" );
		else if(!strcmp(nvram_safe_get("ap_mode"), "3"))
			nvram_set( "wl_mode", "wds" );
		DanielDBG(fprintf( stderr, "wl_mode=<%s>\n", nvram_safe_get("wl_mode") );)
		DanielDBG(fprintf( stderr, "ap_mode=<%s>\n", nvram_safe_get("ap_mode") );)
	}
	else
	{	/* check if ap_mode is matched to wl_mode ? */
		DanielDBG(fprintf( stderr, "/* check if ap_mode is matched to wl_mode ? */\n" );)
		if(!strcmp(nvram_safe_get("ap_mode"), "0"))
			nvram_set( "wl_mode", "ap" );
		else if(!strcmp(nvram_safe_get("ap_mode"), "2"))
			nvram_set( "wl_mode", "ap" );
		else if(!strcmp(nvram_safe_get("ap_mode"), "3"))
			nvram_set( "wl_mode", "wds" );
	}

#if 0
	del_unnecessary_parameters() ; /* delete parameters we don't need */
#endif

#ifdef BCM4712APBOARD
	check_ap_mode_params();
#endif /* end of BCM4712APBOARD */

#ifdef ABBA
	convert_wireless_params();
#endif /* end of ABBA */


	return 0 ;
}


#ifdef Link
int start_link_test()
{
	char *wan_ifname = "eth1" ;
	int s;
	struct ifreq ifr;
	struct ethtool_cmd ecmd;

	/* Open socket to kernel */
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		DanielDBG(fprintf(stderr, "Open socket to kernel error\n");)
		return -1 ;
	}

	/* Check for hardware link */
	strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
	ifr.ifr_data = (void *) &ecmd;
	ecmd.cmd = ETHTOOL_GSET;
	if (ioctl(s, SIOCETHTOOL, &ifr) < 0)
	{
		close(s);
		DanielDBG(fprintf(stderr, "Unknown\n");)
		return -1 ;
	}

	DanielDBG(fprintf(stderr, "ecmd.speed=<%d>\n", ecmd.speed );)
	DanielDBG(fprintf(stderr, "ecmd.duplex=<%d>\n", ecmd.duplex );)

	if (!ecmd.speed)
	{
		close(s);
		DanielDBG(fprintf(stderr, "Disconnected\n");)
		return -1 ;
	}
	else
	{
		close(s);
		DanielDBG(fprintf(stderr, "Connected\n");)
		return -1 ;
	}
#if 0
	/* Check for valid IP address */
	strncpy(ifr.ifr_name, wan_ifname, IFNAMSIZ);
	if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
	{
		close(s);
		DanielDBG(fprintf(stderr, "Connecting");)
		return -1 ;
	}
#endif
	/* Otherwise we are probably configured */
	close(s);

	return 0 ;
}
#endif


#ifdef GET_WL_IOCTL
int start_get_wl_ioctl(void)
{
	int ret ;
	int val ;
	char buf[WLC_IOCTL_MAXLEN] ;
#ifdef BCM4712APBOARD
	char *name = "eth1" ;
#else
	char *name = "eth2" ;
#endif

	ret = wl_ioctl(name, WLC_GET_AUTH, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_AUTH=<%d> ; ret=<%d>\n", val, ret );

	ret = wl_ioctl(name, WLC_GET_WEP, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_WEP=<%d> ; ret=<%d>\n", val, ret );

	ret = wl_ioctl(name, WLC_GET_WEP_RESTRICT, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_WEP_RESTRICT=<%d> ; ret=<%d>\n", val, ret );

	ret = wl_ioctl(name, WLC_GET_SCAN_CHANNEL_TIME, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_SCAN_CHANNEL_TIME=<%d> ; ret=<%d>\n", val, ret );

	ret = wl_ioctl(name, WLC_GET_SCAN_UNASSOC_TIME, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_SCAN_UNASSOC_TIME=<%d> ; ret=<%d>\n", val, ret );

	ret = wl_ioctl(name, WLC_GET_SCAN_HOME_TIME, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_SCAN_HOME_TIME=<%d> ; ret=<%d>\n", val, ret );

	ret = wl_ioctl(name, WLC_GET_SCAN_PASSES, &val, sizeof(val)) ;
	fprintf( stderr, "WLC_GET_SCAN_PASSES=<%d> ; ret=<%d>\n", val, ret );

	return 0 ;
}
#endif
#ifdef SPROM
void start_sprom_test(void)
{
	int ret, i ;
#ifdef BCM4712APBOARD
	char *name = "eth1" ;
#else
	char *name = "eth2" ;
#endif
	srom_rw_t *s ;
	char buf[1024] ;

	memset( buf, '\0', sizeof(buf) );
	fprintf( stderr, "sizeof(srom_rw_t)=<%d>\n", sizeof(srom_rw_t) );

	ret = wl_ioctl(name, WLC_GET_SROM, buf, sizeof(buf)) ;
	fprintf( stderr, "ret=<%d>\n", ret );

	for( s=(srom_rw_t *)buf,i=0 ; i<16 ; i++,s++ )
	{
		fprintf( stderr, "s->byteoff=<%XH>\t", s->byteoff );
		fprintf( stderr, "s->nbytes=<%XH>\t", s->nbytes );
		fprintf( stderr, "s->buf[1]=<%XH>\n", s->buf[1] );
	}
}
#endif
#ifdef SetAntDiv
void start_antenna_selection(void)
{
	int val ;
	char *value = NULL ;
#ifdef BCM4712APBOARD
	char *name = "eth1" ;
#else
	char *name = "eth2" ;
#endif

	value = nvram_safe_get("antenna_selection") ;

	if(value != NULL)
	{
		if( !strcmp(value, "default") || !strcmp(value, "diversity") )
		{
			val = 3 ; /* diversity */
#ifdef BCM4712APBOARD
			nvram_set( "wl_antdiv", "-1" );
			nvram_set( "wl0_antdiv", "-1" );
#endif
		}
		else if( !strcmp(value, "left") )
		{
			val = 0 ; /* main antenna */
#ifdef BCM4712APBOARD
			nvram_set( "wl_antdiv", "0" );
			nvram_set( "wl0_antdiv", "0" );
#endif
		}
		else if( !strcmp(value, "right") )
		{
			val = 1 ; /* aux antenna */
#ifdef BCM4712APBOARD
			nvram_set( "wl_antdiv", "1" );
			nvram_set( "wl0_antdiv", "1" );
#endif
		}

		WLDBG(fprintf( stderr, "val=<%d>\n", val);)

		WL_IOCTL(name, WLC_SET_ANTDIV, &val, sizeof(val)) ;
		WL_IOCTL(name, WLC_SET_TXANT, &val, sizeof(val)) ;
	}
}
#endif


#ifdef B_3_21_7_0
int make_nvram_list(void)
{	/* format: nvram_XXX */
	FILE *fp = NULL ;
	char nvram_buf[NVRAM_SPACE];
	char temp[1024];
	char *p, *q ;
	struct nvram_tuple *t ;
	extern struct nvram_tuple router_defaults[];

	fp = fopen( "/tmp/var/tmp/nvram", "w" );

	if( fp == NULL )
	{
		DanielDBG(fprintf( stderr, "open /tmp/var/tmp/nvram error !!!\n" );)
		return -1;
	}

	/* get name & value in nvram */
	nvram_getall(nvram_buf, NVRAM_SPACE);

	for( p = nvram_buf ; *p ; p = q+strlen(q)+1 )
	{
		memset( temp, '\0', sizeof(temp) );
		q = strchr( p, '=' );
		if( q != NULL )
		{
			*q++ = 0x00 ;

			for( t = router_defaults ; t->name ; t++ )
			{
				if( !strcmp( p, t->name ) )
				{
					bzero(temp, sizeof(temp));
					sprintf( temp, "nvram_%s=%s", p, q );
					fprintf( fp, "%s\n", temp );
					//fprintf(stderr, "%s\n", temp );
				}
			}
		}
	}

	fclose(fp) ;
	return 0 ;
}
#endif


int del_unnecessary_parameters(void)
{
	char nvram_buf[NVRAM_SPACE];
	char *p, *q, *r ;

	DanielDBG(fprintf(stderr, "%s();\n", __FUNCTION__);)

	/* get name & value in nvram */
	nvram_getall(nvram_buf, NVRAM_SPACE);

	for( p = nvram_buf ; *p ; p += strlen(p) + 1 )
	{
		if( !memcmp( p, "d11a_", 5 ) || !memcmp( p, "d11b_", 5 ) )
		{
			q = strchr( p, '=' );
			*q = 0x00 ;
			nvram_unset(p) ;
			*q = '=' ;
		}
		r = strstr( p, "_5G" ) ;
		if( r != NULL )
		{
			q = strchr( p, '=' );
			*q = 0x00 ;
			nvram_unset(p) ;
			*q = '=' ;
		}
	}

	return 0 ;
}


#ifdef PHYCONF
int start_phyconf(void)
{
	char *boardtype = NULL ;

	boardtype = nvram_safe_get("boardtype");

	if( boardtype && !memcmp(boardtype, "bcm94710", 8) )
	{
		fprintf(stderr, "start phyconf... \n");
		system( "/sbin/phyconf" );
	}

	return 0 ;
}
#endif


int start_configure_network(char *lan_ifname)
{

	Conf_ETH1(lan_ifname);

	return 0 ;
}


void restart_httpd(void)
{
	DanielDBG(fprintf( stderr, "%s()...\n", __FUNCTION__ );)

	system( "/usr/bin/killall httpd" );
	chdir("/www");
	system( "/usr/sbin/httpd &" );
}


void CheckMACAddr(void)
{
	char *boardtype = NULL ;
	char *macaddr = NULL ;
	char *hwaddr = NULL;

	boardtype = nvram_safe_get("boardtype");

	if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5) ) )
		macaddr = nvram_safe_get( "et1macaddr" );
	else
		macaddr = nvram_safe_get( "et0macaddr" );

	hwaddr = nvram_safe_get( "lan_hwaddr" );

	if( macaddr != NULL && !strcmp( macaddr, "00:11:22:33:44:56" ))
	{
		if( strcmp( hwaddr, "00:11:22:33:44:55" ) &&
			strcmp( hwaddr, "00:11:22:33:44:56" ) )
		{
			if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
				nvram_set( "et0macaddr", hwaddr );
			else
				nvram_set( "et1macaddr", hwaddr );

			restart_lan();
		}
	}
}


void restart_lan(void)
{
	char *lan_ifname = nvram_safe_get("lan_ifname");
	char name[80], *next;
#ifdef BCM4712APBOARD
	char *boardtype = NULL ;

	boardtype = nvram_safe_get("boardtype");
#endif /* BCM4712APBOARD */

	stop_lan();
	system( "/sbin/rmmod et" );
	system( "/sbin/insmod /lib/modules/2.4.20/kernel/drivers/net/et/et.o" );

	eval("brctl", "addbr", lan_ifname);
	eval("brctl", "setfd", lan_ifname, "0");

	if (nvram_match("router_disable", "1") || nvram_match("lan_stp", "0"))
		eval("brctl", "stp", lan_ifname, "dis");

	foreach(name, nvram_safe_get("lan_ifnames"), next)
	{
		/* Bring up interface */
		ifconfig(name, IFUP, "0.0.0.0", NULL);

		/* Only bridge main wireless interface in AP mode */
		if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6) || !memcmp(boardtype, "0x467", 5)) )
		{
			if( eval("wlconf", name, "up") )
				eval("brctl", "addif", lan_ifname, name);
		}
		else
		{
#ifdef BCM4712APBOARD
			if( eval("wlconf", name, "up") )
				eval("brctl", "addif", lan_ifname, name);
#else
			if (wlconfig(name) || nvram_match("wl_mode", "ap"))
				eval("brctl", "addif", lan_ifname, name);
#endif
		}
	}

	start_configure_network(lan_ifname) ;
}


void save_firmware_version(void)
{

	nvram_set( "MyFirmwareVersion" , MyFirmwareVersion );
	nvram_set( "FirmwareVersion" , FirmwareVersion );
}


void start_kill_easyconf(void)
{
	eval( "killall", "easyconf" );
	sleep(1);
	system( "/sbin/easyconf &" );
}


#ifdef MakeWwwPartition
int check_www_dir(void)
{
	FILE *p_fp = NULL ;
	char *buf = NULL ;

	p_fp = popen( "/bin/ls /www", "r" );
	if( p_fp == NULL )
	{
		DanielDBG(fprintf( stderr, "popen /bin/ls error\n" );)
		return -1 ;
	}

	buf = (char *)malloc(sizeof(char)*1024) ;
	if( buf == NULL )
	{
		DanielDBG(fprintf( stderr, "malloc buf error\n" );)
		return -1 ;
	}

	memset( buf, '\0', sizeof(char)*1024 );
	fgets( buf, sizeof(char)*1024, p_fp );

	if( *buf == 0x00 )
		return -1 ;

	free(buf);
	pclose(p_fp);

	return 0 ;
}


int copy_upgrade_pages(void)
{
	system( "/tmp/copy_upgrade_pages" );

	return 0 ;
}


int get_path_len(void)
{
	FILE *p_fp = NULL ;
	char buf[100] ;
	int len = 0 ;
	char *p = NULL ;

	p_fp = popen( "/bin/cat /tmp/len", "r" );
	if( p_fp == NULL )
	{
		fprintf( stderr, "popen /bin/cat /tmp/len error\n" );
		return -1 ;
	}

	memset( buf, '\0', sizeof(buf) );
	fgets( buf, sizeof(buf), p_fp );
	p = strchr( buf, '\n' );
	if( p != NULL )
		*p = 0x00 ;

	len = atoi(buf);

	pclose(p_fp);
	return len ;
}
#endif /* MakeWwwPartition */


#ifdef BCM4712APBOARD
int start_restore_defaults(void)
{
	int fd ;
	int cnt = 0 ;
	int ret = 0 ;
	unsigned char val[4] ;

	fd = open( "/dev/gpio/GPIO7", O_RDWR );

	if( fd == -1 )
	{
		perror("open");
		return -1 ;
	}

	while(1)
	{
		bzero(val, sizeof(val));
		ret = read(fd, val, sizeof(val));
		sleep(1);

		val[0] |= 0xFE ; /* 0xFE for GPIO 0 */

		if( val[0] == 0xFE )
			cnt++ ;
		else
			cnt = 0 ;

		if( cnt == 3 )
			break ;
	}

	if( cnt == 3 )
	{
#ifdef AP_Repeater
		system( "/sbin/AutoScanBlinking &" );
#endif
		nvram_set( "restore_defaults", "1" );
		nvram_set( "wl_akm", "" );
		nvram_set( "wl0_akm", "" );
		nvram_commit();
		system( "/sbin/reboot" );
	}

	close(fd);
	return 0 ;
}


int start_MACAddrClone(void)
{
	char *et = nvram_safe_get("et0macaddr");
	char *il = nvram_safe_get("il0macaddr");

	if( et != NULL && memcmp( et, il, 17 ) )
	{
		DanielDBG(fprintf(stderr,"et0macaddr=<%s> il0macaddr=<%s>\n", et, il);)
		nvram_set( "il0macaddr", et );
		nvram_commit();
	}

	return 0 ;
}


int start_my_lan(void)
{
	char *lan_ifname = nvram_safe_get("lan_ifname");
	char name[80], *next;
	int ret ;
	char module[80], *modules ;

 	/* insert modules */
	/*
	modules = "et wl" ;
	foreach(module, modules, next)
		eval("insmod", module);
	*/

	/* check nvram parameters we need */
	check_nvram_parameters();

	/* Bring up bridged interfaces */
	if (strncmp(lan_ifname, "br", 2) == 0)
	{
		eval("brctl", "addbr", lan_ifname);
		eval("brctl", "setfd", lan_ifname, "0");

		if (nvram_match("router_disable", "1") || nvram_match("lan_stp", "0"))
			eval("brctl", "stp", lan_ifname, "dis");

		foreach(name, nvram_safe_get("lan_ifnames"), next)
		{
			/* Bring up interface */
			ifconfig(name, IFUP, NULL, NULL);

			/* If not a wl i/f then simply add it to the bridge */
			ret = eval("wlconf", name, "up") ;

			if (ret)
				eval("brctl", "addif", lan_ifname, name);
			else {
				/* get the instance number of the wl i/f */
				char wl_name[] = "wlXXXXXXXXXX_mode";
				int unit;
				wl_ioctl(name, WLC_GET_INSTANCE, &unit, sizeof(unit));
				snprintf(wl_name, sizeof(wl_name), "wl%d_mode", unit);
				/* Receive all multicast frames in WET mode */
				if (nvram_match(wl_name, "wet"))
					ifconfig(name, IFUP | IFF_ALLMULTI, NULL, NULL);
				/* Do not attach the main wl i/f if in wds mode */
				if (nvram_invmatch(wl_name, "wds"))
					eval("brctl", "addif", lan_ifname, name);
			}
		}
	}

	start_configure_network(lan_ifname) ;

	return 0 ;
}


int stop_my_lan(void)
{
	char *lan_ifname = nvram_safe_get("lan_ifname");
	char name[80], *next;
	char module[80], *modules ;

	/* Bring down LAN interface */
	ifconfig(lan_ifname, 0, NULL, NULL);

	/* Bring down bridged interfaces */
	if (strncmp(lan_ifname, "br", 2) == 0)
	{
		foreach(name, nvram_safe_get("lan_ifnames"), next)
		{
			eval("wlconf", name, "down");
			ifconfig(name, 0, NULL, NULL);
			eval("brctl", "delif", lan_ifname, name);
		}
		eval("brctl", "delbr", lan_ifname);
	}

	/* remove modules */
	/*
	modules = "et wl" ;
	foreach(module, modules, next)
		eval("rmmod", module);
	*/

	return 0 ;
}


int check_ap_mode_params(void)
{
	char *ap_mode, *lazywds ;

	ap_mode = lazywds = NULL ;
	ap_mode = nvram_safe_get("ap_mode");
	lazywds = nvram_safe_get("wl_lazywds");

	if( ap_mode && !strcmp(ap_mode, "0") )
	{
		if( strcmp(lazywds, "1") )
			nvram_set("wl_lazywds","1");
	}

	return 0 ;
}


int make_ap_repeater_script(char *path, int status)
{
	FILE *fp = NULL ;
	char *wep, *channel, *mode, *ch ;

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)
	wep = channel = mode = ch = NULL ;

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		return 0 ;
	}

	wep = nvram_safe_get("wl_wep");
	channel = nvram_safe_get("ap_repeater_channel");
	ch = nvram_safe_get("wl_channel");

	fprintf( fp, "#!/bin/sh\n" );

	DanielDBG(fprintf(stderr, "status=%d\t", status);)
	DanielDBG(fprintf(stderr, "channel=<%s>\t", channel);)
	DanielDBG(fprintf(stderr, "ch=<%s>\n", ch);)

	if( strcmp(ch, channel) )
		nvram_set( "ap_repeater_mode", "start" );

	mode = nvram_safe_get("ap_repeater_mode");
	DanielDBG(fprintf(stderr, "mode=<%s>\n", mode);)

	if( status != -1 && !strcmp(mode, "start") )
	{
		if( wep && !strcmp( wep, "enabled" ) )// Modified by Vic Yu, wep ==> enabled
			fprintf( fp, "nvram set wl_wep=\"enabled\"\n" );

		fprintf( fp, "nvram set wl_mode=\"ap\"\n" );
		fprintf( fp, "nvram set wl_lazywds=\"0\"\n" );
		fprintf( fp, "nvram set wl_wds=\"%s\"\n", nvram_safe_get("ap_repeater_mac") );
		fprintf( fp, "nvram set wl_channel=\"%s\"\n", channel );
		fprintf( fp, "nvram set ap_repeater_mode=\"stop\"\n" );
		fprintf( fp, "nvram commit\n" );
		fprintf( fp, "reboot\n" );
	}

	fclose(fp);
	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}


#if defined(AP_Client)
int check_ap_repeater(void)
{
	char *ap_mode, *mac, *mode, *ch, *r_ch ;
	char *sta_argv[] = { "/tmp/berepeater", NULL } ;
	int ret ;
	pid_t pid ;

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)
	ap_mode = mac = mode = ch = r_ch = NULL ;

	ap_mode = nvram_safe_get("ap_mode");
	if(strcmp(ap_mode, "2"))
		return -1 ;

	/* AP Repeater */
	mac  = nvram_safe_get("ap_repeater_mac");
	mode = nvram_safe_get("ap_repeater_mode");
	ch = nvram_safe_get("wl_channel");
	r_ch = nvram_safe_get("ap_repeater_channel");
	DanielDBG(fprintf(stderr, "ap_repeater_mac=<%s>\t", mac);)
	DanielDBG(fprintf(stderr, "ap_repeater_mode=<%s>\n", mode);)

	if( !strcmp( mode, "start" ) || strcmp(ch, r_ch) )
	{	/* previous scanned channel is not the same with channel I set */
		ret = do_SiteSurvay(mac, ap_mode) ;
		DanielDBG(fprintf(stderr,"ret=%d\n", ret);)
		make_ap_repeater_script("/tmp/berepeater", ret);
		ret = _eval( sta_argv, NULL, 0, &pid);
		DanielDBG(fprintf( stderr, "%s waitpid...\n", sta_argv[0]);)
		waitpid(pid, &ret, WUNTRACED);
	}

	return 0 ;
}
#endif /* end of AP_Client */

unsigned int start_gpio(int count, char **option)
{
	int fd ;
	unsigned int val = 0 ;
	unsigned int ret = 0 ;

	if( count == 4 )
	{	/* gpio 0x04 write hi/lo */
		if( !strcmp(option[2], "write") )
		{
			val = strtoul(option[1], NULL, 0);

			if( !strcmp(option[3], "hi") )
				fd = open( "/dev/gpio/GPIO_WRITE_HI", O_RDWR );
			else
				fd = open( "/dev/gpio/GPIO_WRITE_LO", O_RDWR );

			if( fd == -1 )
			{
				fprintf( stderr, "open /dev/gpio/GPIO_WRITE_HI(LO) error.\n" );
				return -1 ;
			}

			write( fd, &val, 4 );
		}
	}
	else if( count == 2 )
	{	/* gpio read */
		if( !strcmp(option[1], "read") )
		{
			fd = open( "/dev/gpio/in", O_RDWR );

			if( fd == -1 )
			{
				perror("open");
				return -1 ;
			}

			read(fd, &ret, sizeof(ret));
		}
	}

	close(fd);
	return ret ;
}
#endif /* end of BCM4712APBOARD */


int make_scripts(void)
{
#ifdef SiteSurvay
	make_scan_script("/tmp/scan");
#endif /* end of SiteSurvay */
#ifdef MakeWwwPartition
	make_mount_www_partition_script("/tmp/mount_www_partition");
	make_umount_www_partition_script("/tmp/umount_www_partition");
	make_copy_upgrade_pages_script("/tmp/copy_upgrade_pages");
#endif /* end of MakeWwwPartition */

// PANTELTJE
	make_mount_sdcard_script("/tmp/mount_sdcard");

	return 0 ;
}


int make_killall_daemons_script(char *path)
{
	FILE *fp = NULL ;
	int val ;

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		DanielDBG(fprintf(stderr,"fopen %s error\n", path);)
		return -1 ;
	}

	fprintf( fp, "#!/bin/sh\n" );
#if 0
	if( (val = get_file_pid("easyconf")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
	if( (val = get_file_pid("RestoreDefaults")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
	if( (val = get_file_pid("assoclistd")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
	if( (val = get_file_pid("snmpd")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
	if( (val = get_file_pid("epi_ttcp")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
	if( (val = get_file_pid("nas")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
#ifdef AP_Repeater
	if( (val = get_file_pid("AutoScanOnBtn")) != 0 )
		fprintf( fp, "kill -9 %d\n", val );
#endif

#else
	fprintf( fp, "killall easyconfu\n" );
	fprintf( fp, "killall RestoreDefaults\n" );
	fprintf( fp, "killall assoclistd\n" );
	fprintf( fp, "killall snmpd\n" );
	fprintf( fp, "killall ses\n" );

#endif // #if 0

	fclose(fp);
	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}


#ifdef SiteSurvay
int make_scan_script(char *path)
{
	FILE *fp = NULL ;
	char *boardtype = NULL ;

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		DanielDBG(fprintf(stderr,"fopen %s error\n", path);)
		return -1 ;
	}

	boardtype = nvram_safe_get("boardtype");

	fprintf( fp, "#!/bin/sh\n" );
	fprintf( fp, "/usr/sbin/nvram set wl0_mode=\"wet\"\n" );
	fprintf( fp, "/usr/sbin/nvram set wl0_wep=\"disabled\"\n" );
	fprintf( fp, "/usr/sbin/nvram set wl0_akm=\"\"\n" );

	if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6)) )
	{
		fprintf( fp, "/usr/sbin/wlconf eth1 down\n" );
		fprintf( fp, "/usr/sbin/wlconf eth1 up\n" );
		fprintf( fp, "sleep 1\n" );
		fprintf( fp, "/usr/sbin/wl -i eth1 scan\n" );
		fprintf( fp, "sleep 1\n" );
		fprintf( fp, "/usr/sbin/wl -i eth1 scanresults >/tmp/scanresults\n" );
	}
	else
	{
#ifdef BCM4712APBOARD
		fprintf( fp, "/usr/sbin/wlconf eth2 down\n" );
		fprintf( fp, "/usr/sbin/wlconf eth2 up\n" );
#else
		fprintf( fp, "/usr/sbin/wlconfig eth2\n" );
#endif
		fprintf( fp, "sleep 1\n" );
		fprintf( fp, "/usr/sbin/wl -i eth2 scan\n" );
		fprintf( fp, "sleep 1\n" );
		fprintf( fp, "/usr/sbin/wl -i eth2 scanresults >/tmp/scanresults\n" );
	}

	fclose(fp);

	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}
#endif /* end of SiteSurvay */


int get_file_pid(char *file)
{
	FILE *p_fp = NULL ;
	char buf[1024] ;
	int count = 0 ;
	char *p = NULL ;
	char *q = NULL ;
	int ret = 0 ;

	memset( buf, '\0', sizeof(buf) );
	sprintf( buf, "/bin/ps | /bin/grep %s", file );

	p_fp = popen( buf, "r" );
	if( p_fp == NULL )
	{
		perror( "popen" );
		return 0 ;
	}

	while( !feof(p_fp) && count == 0 )
	{
		memset( buf, '\0', sizeof(buf) );
		fgets( buf, sizeof(buf), p_fp );

		p = strstr( buf, "grep" );
		if( p != NULL )
		{
			count++ ;
			continue ;
		}

		for( p=buf ; *p == 0x20 ; p++ );
		for( q=p ; *q != 0x20 ; q++ );
		*q = 0x00 ;
		ret = atoi(p) ;
		count++ ;
	}

	pclose(p_fp);
	return ret ;
}


// PANTELTJE
int make_mount_sdcard_script(char *path)
{
FILE *fp = NULL ;

fp = fopen( path, "w" );
if( fp == NULL )
	{
	DanielDBG(fprintf(stderr,"fopen %s error\n", path);)
	return -1 ;
	}

fprintf( fp, "#!/bin/sh\n" );
//fprintf( fp, "/bin/mount /dev/mmc/disc0/disc /mnt -o ro\n" );
fprintf( fp, "/bin/mount /dev/mmc/disc0/disc /mnt\n" );
fclose(fp);

chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

return 0;
}


#ifdef MakeWwwPartition
int make_mount_www_partition_script(char *path)
{
	FILE *fp = NULL ;

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		DanielDBG(fprintf(stderr,"fopen %s error\n", path);)
		return -1 ;
	}

	fprintf( fp, "#!/bin/sh\n" );
	fprintf( fp, "/bin/mount -t cramfs /dev/mtdblock/3 /www\n" );
	fclose(fp);

	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}


int make_umount_www_partition_script(char *path)
{
	FILE *fp = NULL ;

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		DanielDBG(fprintf(stderr,"fopen %s error\n", path);)
		return -1 ;
	}

	fprintf( fp, "#!/bin/sh\n" );
	fprintf( fp, "/bin/umount /dev/mtdblock/3\n" );
	fclose(fp);

	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}


int make_copy_upgrade_pages_script(char *path)
{
	FILE *fp = NULL ;

	fp = fopen( path, "w" );
	if( fp == NULL )
	{
		DanielDBG(fprintf(stderr,"fopen %s error\n", path);)
		return -1 ;
	}

	fprintf( fp, "#!/bin/sh\n" );
	fprintf( fp, "cp /www/Upgrade.asp /tmp/www/Upgrade.asp\n" );
	fprintf( fp, "cp /www/show.js /tmp/www/show.js\n" );
	fprintf( fp, "cp /www/HFirmware.asp /tmp/www/HFirmware.asp\n" );
	fprintf( fp, "cp /www/test.asp /tmp/www/test.as\n" );
	fclose(fp);

	chmod( path, S_IRUSR | S_IWUSR | S_IXUSR );

	return 0 ;
}
#endif /* MakeWwwPartition */


#ifdef SETDEFVALS
int SetDefVals(char *name)
{
	char *argv[] =
	{ "wl_ssid", "def_wl_ssid",
	  "wl_key1", "def_wl_key1", "wl_key2", "def_wl_key2",
	  "wl_key3", "def_wl_key3", "wl_key4", "def_wl_key4",
      "wl_wep",  "def_wl_wep",  "auth_mode", "def_auth_mode", 0 } ;
	char **p = NULL ;

	for( p=argv ; *p ; p+=2 )
	{
		if( !strcmp(name, *p) )
		{
			DanielDBG(fprintf(stderr, "name=<%s>, *p=<%s>, *(p+1)=<%s>\n", name, *p, *(p+1));)
			nvram_set( *p, nvram_safe_get(*(p+1)) );
		}
	}

	return 0 ;
}
#endif /* SETDEFVALS */


#ifdef AddRestoreHdr
int add_restore_hdr(char *path)
{
	FILE *src_fp = NULL ;
	FILE *dest_fp = NULL ;
	char path_buf[30];
	int count ;
	char buf[1024];
	int cnt = 0 ;

	src_fp = fopen( path, "r" ) ;
	if(src_fp == NULL)
	{
		DanielDBG(fprintf(stderr, "fopen %s error !!!\n", path);)
		return -1 ;
	}

	bzero(path_buf, sizeof(path_buf));
	sprintf(path_buf, "%s.tmp", path);
	DanielDBG(fprintf(stderr, "path_buf=<%s>\n", path_buf);)

	dest_fp = fopen( path_buf, "w" ) ;
	if(dest_fp == NULL)
	{
		DanielDBG(fprintf(stderr, "fopen %s error !!!\n", path_buf);)
		return -1 ;
	}

	while( !feof(src_fp) )
	{
		if( cnt == 0 )
		{	/* add restore header */
			fwrite( ModleNumber, 1, sizeof(ModleNumber), dest_fp );
			fwrite( RESTOREFILE, 1, sizeof(RESTOREFILE), dest_fp );
			cnt++ ;
		}

		bzero(buf, sizeof(buf));
		count = fread( buf, 1, sizeof(buf), src_fp );
		fwrite( buf, 1, count, dest_fp );
	}

	fclose(src_fp);
	fclose(dest_fp);
	unlink(path);
	rename(path_buf, path);

	return 0 ;
}
#endif /* AddRestoreHdr */


#ifdef AP_Repeater
int start_ap_repeater(void)
{
	char *mac, *boardtype ;
	char buf[100];

	mac = boardtype = NULL ;
	mac = nvram_safe_get("ap_repeater_mac");
	boardtype = nvram_safe_get("boardtype");

	if( strlen(mac) != 0 )
	{
		bzero(buf, sizeof(buf));
		if( boardtype && (!memcmp(boardtype, "0x0446", 6) || !memcmp(boardtype, "0x0467", 6)) )
			sprintf(buf, "/usr/sbin/wl -i eth1 wds %s", mac);
		else
			sprintf(buf, "/usr/sbin/wl -i eth2 wds %s", mac);
		system(buf);
	}

#ifdef AUTOSCAN_ON_BOOT
	char *ap_mode, *mac ;
	int ret ;
	char *repeater_argv[] = { "/tmp/repeater", NULL } ;
	pid_t pid;
#ifdef SITESURVEY_QUEUE
	SITESURVEY_LIST *p ;
	site_survey_t *t ;
#endif

	DanielDBG(fprintf(stderr, "%s()...\n", __FUNCTION__);)
	ap_mode = mac = NULL ;
	ap_mode = nvram_safe_get("ap_mode");

	if( !strcmp(ap_mode, "2") )
	{
		mac  = nvram_safe_get("ap_repeater_mac") ;
		DanielDBG(fprintf(stderr, "ap_repeater_mac=<%s>\n", mac);)
		ret = do_SiteSurvay(mac, "2") ;
		DanielDBG(fprintf(stderr,"ret=%d\n", ret);)
	}
	else
		return -1 ;

#ifdef SITESURVEY_QUEUE
	SL = SortQueue(SL);

	p = SL ;
	if( p != NULL )
	{
		t = p->content ;
		DanielDBG(fprintf(stderr,"t->SSID=%s t->BSSID=%s t->Channel=%s\n", t->SSID, t->BSSID, t->Channel);)
		nvram_set( "ap_repeater_mac", t->BSSID );
		nvram_set( "ap_repeater_ssid", t->SSID );
		nvram_set( "ap_repeater_channel", t->Channel );
	}
#endif /* end of SITESURVEY_QUEUE */

	ap_repeater_script(repeater_argv[0]);
	ret = _eval(repeater_argv, NULL, 0, &pid);
	waitpid(pid, &ret, WUNTRACED);
#endif /* end of AUTOSCAN_ON_BOOT */

	return 0 ;
}


int SETDEFSSID(void)
{
	char *mac = NULL ;
	char buf[60] ;
	char mac_buf[6] ;

	bzero(buf, sizeof(buf));
	bzero(mac_buf, sizeof(mac_buf));
	mac = nvram_safe_get("et0macaddr");
	ether_atoe(mac, mac_buf);

	if( mac != NULL )
	{
		sprintf( buf, "linksysR%02x%02x%02x", mac_buf[3]&0xFF, mac_buf[4]&0xFF, mac_buf[5]&0xFF );
		nvram_set( "wl_ssid", buf );
	}

	return 0 ;
}


int start_AutoScanOnBtn(void)
{
	int cnt = 0 ;
	char *read_argv[2];
	unsigned int ret ;
	char buf[1024];
	int val ;
	FILE *pid_fp;

	/* Daemonize and log PID */
	if (daemon(1, 1) == -1)
	{
		perror("daemon");
		exit(errno);
	}

	if (!(pid_fp = fopen("/var/run/AutoScanOnBtn.pid", "w")))
	{
		perror("/var/run/AutoScanOnBtn.pid");
		return errno;
	}

	fprintf(pid_fp, "%d", getpid());
	fclose(pid_fp);

	read_argv[0] = "gpio" ;
	read_argv[1] = "read" ;

	while(1)
	{
		ret = start_gpio(2, read_argv);
		ret |= 0xEF ; /* 0xEF for GPIO 4 */

		if( ret == 0xEF )
			cnt++ ;
		else
			cnt = 0 ;

		if( cnt == 2 )
		{
			system( "/sbin/gpio 0x08 write hi" );
			/* kill DetectWDSLink */
			kill_pidfile("/var/run/DetectWDSLink.pid");
			system( "/sbin/AutoScanBlinking &");
			start_AutoScan();
		}

		sleep(1);
	}

	return 0 ;
}


int start_AutoScan(void)
{
#ifdef SITESURVEY_QUEUE
	SITESURVEY_LIST *p ;
	site_survey_t *t ;
	int ret = 0 ;
#endif
	char buf[1024];
	int val, i ;
	FILE *fp = fopen("/var/run/repeater.pid", "r");
	pid_t pid ;

	system( "/tmp/scan" );
#ifdef SITESURVEY_QUEUE
	ParseScanresults("/tmp/scanresults", "queue");
	SL = SortQueue(SL);

	p = SL ;
	t = &p->content[0] ;
	fprintf(stderr,"SSID=<%s> BSSID=<%s> Channel=<%s>\n", t->SSID, t->BSSID, t->Channel);
	DanielDBG(fprintf(stderr,"Capability=<%s>\n", t->Capability);)

	if( strlen(t->BSSID) != 0 && strlen(t->SSID) != 0 && strlen(t->Channel) != 0 )
	{
		nvram_set( "ap_repeater_mac", t->BSSID );
		nvram_set( "wl_ssid", t->SSID );
		nvram_set( "wl_channel", t->Channel );
		ap_repeater_script("/tmp/ap_repeater");
		fprintf(stderr, "test start !!!\n");
		system( "/tmp/ap_repeater" );
		fprintf(stderr, "test end !!!\n");
	}

	ClearQueue(SL);

	/* send message to APRepeaterDaemon for SIGUSR1 */
	bzero(buf, sizeof(buf));
	if( fp && fgets(buf, sizeof(buf), fp) )
	{
		pid = strtoul(buf, NULL, 0);
		fclose(fp);
		kill(pid, SIGUSR1);
  	}

	DanielDBG(fprintf(stderr, "sleep(3);\n");)
	sleep(3);
	system( "/sbin/DetectWDSLink &" );

	/* kill AutoScanBlinking */
	kill_pidfile("/var/run/AutoScanBlinking.pid");

	/* send message to APRepeaterDaemon for SIGUSR2 */
	kill(pid, SIGUSR2);
#endif

	return 0 ;
}


int start_detect_wds_link(void)
{
	char interface[10] ;
	int ret = 0, isBlue = 0, isRed = 0 ;
	FILE *pid_fp;
	char *mac ;

	mac = nvram_safe_get("ap_repeater_mac");
	if( !memcmp(mac, "<null>", 6) )
	{
		DanielDBG(fprintf(stderr, "There's no mac address !!!\n");)
		system("/sbin/gpio 0x08 write lo");
		return 0 ;
	}

	/* Daemonize and log PID */
	if (daemon(1, 1) == -1)
	{
		perror("daemon");
		exit(errno);
	}

	if (!(pid_fp = fopen("/var/run/DetectWDSLink.pid", "w")))
	{
		perror("/var/run/DetectWDSLink.pid");
		return errno;
	}

	fprintf(pid_fp, "%d", getpid());
	fclose(pid_fp);

	memset(interface, '\0', sizeof(interface));
	Get_WDS_Interface(interface);

	/* Check interface of WDS */
	memset(interface, '\0', sizeof(interface));
	Get_WDS_Interface(interface);
	if( strlen(interface) == 0 )
	{
		system("/sbin/gpio 0x08 write lo");
		return 0 ;
	}

	while(1)
	{
		ret = start_detect_link();

		if(ret)
		{
			isRed = 0 ;
			if(!isBlue)
			{
				isBlue = 1 ;
				system("/sbin/gpio 0x08 write hi");
			}
		}
		else
		{
			isBlue = 0 ;
			if(!isRed)
			{
				isRed = 1 ;
				system("/sbin/gpio 0x08 write lo");
			}
		}

		sleep(5);
	}

	return 0 ;
}


int start_AutoScanBlinking(void)
{
	FILE *pid_fp;

	/* Daemonize and log PID */
	if (daemon(1, 1) == -1)
	{
		perror("daemon");
		exit(errno);
	}

	if (!(pid_fp = fopen("/var/run/AutoScanBlinking.pid", "w")))
	{
		perror("/var/run/AutoScanBlinking.pid");
		return errno;
	}

	fprintf(pid_fp, "%d", getpid());
	fclose(pid_fp);

	while(1)
	{
		system("/sbin/gpio 0x08 write lo");
		sleep(1);
		system("/sbin/gpio 0x08 write hi");
		sleep(1);
	}

	return 0;
}


static void repeater_signal(int sig)
{
	if( sig == SIGUSR1 )
	{
		DanielDBG(fprintf(stderr, "system( \"/tmp/ap_repeater\" );\n");)
		system( "/tmp/ap_repeater" );
	}
	else if( sig == SIGUSR2 )
	{
		DanielDBG(fprintf(stderr, "kill AutoScanOnBtn\n");)
		kill_pidfile("/var/run/AutoScanOnBtn.pid");
		system( "/sbin/AutoScanOnBtn &" );
	}
}


int start_APRepeaterDaemon(void)
{
	FILE *pid_fp;

	/* Daemonize and log PID */
	if (daemon(1, 1) == -1)
	{
		perror("daemon");
		exit(errno);
	}

	if (!(pid_fp = fopen("/var/run/repeater.pid", "w")))
	{
		perror("/var/run/repeater.pid");
		return errno;
	}

	fprintf(pid_fp, "%d", getpid());
	fclose(pid_fp);

	signal( SIGUSR1, repeater_signal );
	signal( SIGUSR2, repeater_signal );

	while(1);

	return 0 ;
}
#endif /* end of AP_Repeater */


// +++ Vic Yu added
#ifdef BACKUP_RESTORE
void Prepare_restore_file( void)
{
#ifdef B_3_21_7_0
	make_nvram_list();
#endif
	/* make /tmp/config.bin */
	{
		char *restore_argv[7] ;

		restore_argv[0] = "restore" ;
		restore_argv[1] = "/tmp/var/tmp/nvram" ;
		restore_argv[2] = "1" ;
		restore_argv[3] = "/tmp/config.bin" ;
		restore_argv[4] = "/tmp/restore_test" ;
		restore_argv[5] = "linksyswap11" ;

		restore_argv[6] = NULL ;
		pid_t pid;
		int ret ;

		ret = _eval(restore_argv, NULL, 0, &pid);
		waitpid(pid, &ret, WUNTRACED);
	}

#ifdef AddRestoreHdr
	add_restore_hdr("/tmp/config.bin");
#endif /* end of AddRestoreHdr */

}
#endif /* end of BACKUP_RESTORE */


#if 0
static char *GTK_web_test_getfunc(char *param)
{
	return "Success!!";
}

/*Web_param_struct	Gemtek_Web_param_struct[]={
	{0	,"GTK_wl_channel"		,"wl_channel"		,NULL				,NULL				},
	{0	,"GTK_wl_paramA"		,0				,GTK_web_test_getfunc	,NULL				},
	{0	,"GTK_wl_paramB"		,"wl_ssid"			,NULL				,NULL				},
	{0	,0					,0				,0					,0					}
};*/


// return 1: success , return -1: fail
int web_transfer_param(char *param_str, Web_param_struct *index)
{
	int i=0;
	Web_param_struct	*tmp_ptr;

	if(!Gemtek_Web_param_ptr)
	{
		return -1;
	}

	if(param_str==NULL)
	{
		return -1;
	}

	if(!strcmp(param_str,""))
	{
		return -1;
	}

	memset(tmp_ptr,0x0,sizeof(Web_param_struct));

	// find parameter string index from Gemtek_Web_param_ptr[]
	for(tmp_ptr=Gemtek_Web_param_ptr; tmp_ptr->web_param; tmp_ptr++)
	{
		if(strcmp(param_str,tmp_ptr->web_param)==0) // paraemter index found
		{
			index=tmp_ptr;
			return 1;
		}
	}

	/*while(Gemtek_Web_param_ptr[i].web_param)
	{
		if(strcmp(param_str,Gemtek_Web_param_ptr[i].web_param)==0) // paraemter index found
		{
			memcpy(index,&Gemtek_Web_param_ptr[i],sizeof(Web_param_struct));
			return 1;

		}
		else
			i++;

	}*/
	return -1;
}
#endif
// - - - Vic Yu added

