#include 	<sys/time.h>
#include 	<sys/timeb.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include 	<sys/types.h>
#include 	<sys/ioctl.h>
#include 	<sys/socket.h>
#include 	<sys/ipc.h>
#include 	<sys/shm.h>
#include 	<sys/shm.h>
#include 	<sys/mman.h>
#include 	<linux/wireless.h>
#include 	<arpa/inet.h>
#include 	<netinet/in.h>

#include 	<unistd.h>
#include 	<stdarg.h>
#include    <stdio.h>
#include    <stdlib.h>
#include    <unistd.h>
#include    <fcntl.h>
#include    <termios.h>
#include    <errno.h>
#include 	<errno.h>
#include 	<string.h>
#include	<time.h>
#include	<ctype.h>
#include 	<ifaddrs.h>
#include	"define.h"

#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)

#define Debug
#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
#define PASS				1
#define FAIL				-1
#define OUTPUT_FLASH		0x01
#define OUTPUT_FILE			0x02


struct SysConfigData 			SysConfig;
struct SysConfigAndInfo			*ShmSysConfigAndInfo;
struct StatusCodeData 			*ShmStatusCodeData;
struct FanModuleData			*ShmFanModuleData;
void trim(char *s);
int mystrcmp(char *p1,char *p2);
void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
void split(char **arr, char *str, const char *del);



int StoreLogMsg(const char *fmt, ...)
{
	char Buf[4096+256];
	char buffer[4096];
	time_t CurrentTime;
	struct tm *tm;
	struct timeval tv;
	va_list args;

	va_start(args, fmt);
	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
	va_end(args);

	memset(Buf,0,sizeof(Buf));
	CurrentTime = time(NULL);
	tm=localtime(&CurrentTime);
	gettimeofday(&tv, NULL); // get microseconds, 10^-6

	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]-%s\" >> /Storage/SystemLog/[%04d.%02d]Module_FactoryConfig",
				tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec,
				buffer,
				tm->tm_year+1900,tm->tm_mon+1);


#ifdef SystemLogMessage
	system(Buf);
#endif

#ifdef ConsloePrintLog
	printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer);
#endif

	return rc;
}

int DiffTimeb(struct timeb ST, struct timeb ET)
{
	//return milli-second
	unsigned int StartTime,StopTime;

	StartTime=(unsigned int)ST.time;
	StopTime=(unsigned int)ET.time;
	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
}

//=================================
// Common routine
//=================================
void trim(char *s)
{
    int i=0, j, k, l=0;

    while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
        i++;

    j = strlen(s)-1;
    while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
        j--;

    if(i==0 && j==strlen(s)-1) { }
    else if(i==0) s[j+1] = '\0';
    else {
        for(k=i; k<=j; k++) s[l++] = s[k];
        s[l] = '\0';
    }
}

int mystrcmp(char *p1,char *p2)
{
    while(*p1==*p2)
    {
        if(*p1=='\0' || *p2=='\0')
            break;
        p1++;
        p2++;
    }
    if(*p1=='\0' && *p2=='\0')
        return(PASS);
    else
        return(FAIL);
}

void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
{
	strncpy(dest, src + start, cnt);
	dest[cnt] = 0;
}

void split(char **arr, char *str, const char *del)
{
	char *s = strtok(str, del);

	while(s != NULL)
	{
		*arr++ = s;
		s = strtok(NULL, del);
	}
}

int runShellCmd(const char*cmd)
{
	int result = FAIL;
	char buf[256];
	FILE *fp;

	fp = popen(cmd, "r");
	if(fp != NULL)
	{
		while(fgets(buf, sizeof(buf), fp) != NULL)
		{
			DEBUG_INFO("%s\n", buf);
		}

		result = PASS;
	}
	pclose(fp);

	return result;
}

//==========================================
// Init all share memory
//==========================================
int InitShareMemory()
{
	int result = PASS;
	int MeterSMId;

	//creat ShmSysConfigAndInfo
	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
    {
		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");

		result = FAIL;
	}
    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");

    	result = FAIL;
   	 }
    else
    {}

   	 //creat ShmStatusCodeData
   	 if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
    {
   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");

   		result = FAIL;
	}
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");

    	result = FAIL;
   	}
    else
    {}

    return result;
}

void helpOutput(void)
{
	printf("Usage: Module_FactoryConfig [OPTION]...\n\n");
	printf("Generate factory default configuration value\n\n");
	printf("OPTION:\n");
	printf("	-a Write to file(/mnt) & flash\n");
	printf("	-f Write to file(/mnt)\n");
	printf("	-m Write to flash\n");
}

//================================================
// Main process
//================================================
int main(int argc, char *argv[])
{
	unsigned char outType=0;
	unsigned int i,Chk,MtdBlockSize=0x300000;
	unsigned char *ptr;
	int fd,wrd;

	ptr=malloc(MtdBlockSize);
	if(ptr==NULL)
	{
		#ifdef SystemLogMessage
		StoreLogMsg("[FactoryConfig]main: malloc for SysConfigData NG");
		#endif
		return 0;
	}
	memset(ptr,0,MtdBlockSize);
	memset(&SysConfig,0,sizeof(struct SysConfigData));

	/*
	 * TODO: Set factory default configuration
	 */
	// System configuration
	time_t t = time(NULL);
	struct tm tm = *localtime(&t);
	
	// Initial Share Memory
	if(InitShareMemory() == FAIL)
	{
		DEBUG_ERROR("InitShareMemory NG\n");

		strcpy((char*)SysConfig.ModelName, "");
		strcpy((char*)SysConfig.SerialNumber, "");
		sleep(5);
	}
	else
	{
		memcpy((char*)SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.ModelName, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName));
		memcpy((char*)SysConfig.SerialNumber, ShmSysConfigAndInfo->SysConfig.SerialNumber, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber));
		memcpy((char*)SysConfig.CsuBootLoadFwRev, ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev));

		DEBUG_INFO("InitShareMemory OK.\n");
	}
	
	sprintf((char*)SysConfig.SystemId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
	sprintf((char*)SysConfig.SystemDateTime, "%d-%d-%d %d:%d:%d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
	SysConfig.AuthorisationMode = 0;		// 0: enable, 1: disable
	SysConfig.DefaultLanguage  = 0;			// 0: English 1: Big5 2: GB 3: JN 4: Français 5: Italiano 6: Español 7: Deutsch 8: Nederland 9: Norsk 10: Suomalainen 11: Svenska 12: Pусский 13: ไทย
	SysConfig.RfidCardNumEndian = 0;		// 0: Little endian 1: Big endian
	SysConfig.BillingData.isBilling = 0;	// 0: not for business	1: for business
	SysConfig.isQRCode = 1;					// for AuthorisationMode = 0; 0:false, 1:true
	SysConfig.isRFID = 1;					// for AuthorisationMode = 0; 0:false, 1:true
	SysConfig.isAPP = 0;					// for AuthorisationMode = 0; 0:false, 1:true

	// Charging configuration
	SysConfig.MaxChargingEnergy = 0;		// 0: No limit	Other: 1~65536 KWH
	SysConfig.MaxChargingPower = 0;			// 0: No limit	Other: 1~65536 KW
	SysConfig.MaxChargingCurrent = 0;		// 0: Rating value	Other: 1~Rating A
	SysConfig.MaxChargingDuration = 0;		// 0: No limit	Other: 1~65536 Minute
	SysConfig.PhaseLossPolicy = 0;			// 0: Charging	1: Stop charging
	SysConfig.AcPhaseCount = 1;				// 1: One phase	3: Three phase

	// Network configuration
	strcpy((char*)SysConfig.FtpServer, "");
	SysConfig.Eth0Interface.EthDhcpClient = 0;
	strcpy((char*)SysConfig.Eth0Interface.EthIpAddress, "192.168.1.10");
	strcpy((char*)SysConfig.Eth0Interface.EthSubmaskAddress, "255.255.255.0");
	strcpy((char*)SysConfig.Eth0Interface.EthGatewayAddress, "192.168.1.254");

	SysConfig.Eth1Interface.EthDhcpClient = 0;
	strcpy((char*)SysConfig.Eth1Interface.EthIpAddress, "192.168.0.10");
	strcpy((char*)SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
	strcpy((char*)SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");

	// Wifi configuration
	SysConfig.AthInterface.WifiMode = 2;								// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
	SysConfig.AthInterface.WifiRssi = 0;								// Wifi rssi value
	strcpy((char *) SysConfig.AthInterface.WifiSsid, "");				// default: Null
	strcpy((char *) SysConfig.AthInterface.WifiPassword, "");			// default: Null
	SysConfig.AthInterface.WifiDhcpServer = 0;							// 0: Enable 1: Disable
	SysConfig.AthInterface.WifiDhcpClient = 0;							// 0: Enable 1: Disable
	SysConfig.AthInterface.WifiBroadcastSsid = 1;						// 0: hidden 1: broadcast

	// Telecom configuration
	strcpy((char*)SysConfig.TelecomInterface.TelcomApn, "");			// default: Null
	SysConfig.TelecomInterface.TelcomEnabled = 1; 						// 0: disable, 1: enable
	SysConfig.TelecomInterface.TelcomRssi = 0;							// default: 0
	SysConfig.TelecomInterface.TelcomSimStatus = 0;						// SIM card status
	SysConfig.TelecomInterface.TelcomModemMode = 0;						// 0: No services 1: CDMA 2: GSM/GPRS 3: WCDMA 4: GSM/WCDMA 5: TD_SCDMA 6: Unknown
	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapId, "");	// default: Null
	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapPwd, "");	// default: Null
	strcpy((char *) SysConfig.TelecomInterface.TelcomModemImei, "");	// default: Null
	strcpy((char *) SysConfig.TelecomInterface.TelcomSimImsi, "");		// default: Null
	strcpy((char *) SysConfig.TelecomInterface.TelcomSimIccid, "");		// default: Null

	// Backend configuration
	strcpy((char*)SysConfig.OcppServerURL, "");
	sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
	strcpy((char *)SysConfig.chargePointVendor, "");	// default: Null
	strcpy((char*)SysConfig.MaintainServerURL, "");
	SysConfig.BackendConnTimeout=300; 		// 300 seconds
	SysConfig.OfflinePolicy = 2;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
	SysConfig.OfflineMaxChargeEnergy = 0;	// 0: Same as MaxChargeEnergy	Other: 1~65535KWH
	SysConfig.OfflineMaxChargeDuration = 0; // 0: Same as MaxChargeDuration Other: 1~65535 minutes
	SysConfig.isReqFirstUpgrade = 1;		// 0: Skip first upgrade, 	1: Process first upgrade

	// Customization configuration item
	if(SysConfig.ModelName[12] == 'P')
	{
		strcpy((char*)SysConfig.OcppServerURL, "");
		sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
		strcpy((char *)SysConfig.chargePointVendor, "");
		strcpy((char*)SysConfig.MaintainServerURL, "wss://ocpp.phihong.com.tw:2013/");
	}
	else if(SysConfig.ModelName[12] == 'N')
	{
		if((SysConfig.ModelName[2] == 'Y') || (SysConfig.ModelName[2] == 'D') || (SysConfig.ModelName[2] == 'W'))
		{
			if(SysConfig.ModelName[13] == '0')
			{
				SysConfig.AuthorisationMode = 0;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
			else
			{
				SysConfig.AuthorisationMode = 0;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
		}
		else
		{
			if(SysConfig.ModelName[13] == '1')
			{
				SysConfig.AuthorisationMode = 1;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
			else if(SysConfig.ModelName[13] == '2')
			{
				SysConfig.AuthorisationMode = 0;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
			else if(SysConfig.ModelName[13] == '3')
			{
				SysConfig.AuthorisationMode = 1;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
			else if(SysConfig.ModelName[13] == '4')
			{
				SysConfig.AuthorisationMode = 0;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
			else
			{
				SysConfig.AuthorisationMode = 0;		// 0: enable, 1: disable
				SysConfig.RfidCardNumEndian = 1;		// 0: Little endian 1: Big endian
				
				SysConfig.AthInterface.WifiMode = 1;	// 0: Disable 1: Infrastructure client 2: Infrastructure server	3: Ad-Hoc
				strcpy((char *) SysConfig.AthInterface.WifiSsid, "NoodoeEV-LTE");				// default: Null
				strcpy((char *) SysConfig.AthInterface.WifiPassword, "LTE4NoodoeEV");			// default: Null
				
				SysConfig.OfflinePolicy = 0;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
				strcpy((char*)SysConfig.OcppServerURL, "wss://ocpp.noodoe.com:443/");
				sprintf((char*)SysConfig.ChargeBoxId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
				strcpy((char *)SysConfig.chargePointVendor, "Noodoe");	// default: Null
			}
		}
	}
	else
	{}

	// Copy default configuration to pointer
	memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));

	// Calculate CRC
	Chk=0;
	for(i=ARRAY_SIZE(SysConfig.CsuBootLoadFwRev);i<(MtdBlockSize-4);i++)
	{
		Chk+=*(ptr+i);
	}
	memcpy(ptr+MtdBlockSize-4, &Chk, 4);

	/*
	 * Parameter process
	 */
	if(argc>1)
	{
		char *arg = argv[1];
		switch(arg[0])
		{
			case '-':
				switch(arg[1])
				{
					case 'a':
						outType |= OUTPUT_FILE;
						outType |= OUTPUT_FLASH;
						break;
					case 'f':
						outType |= OUTPUT_FILE;
						break;
					case 'm':
						outType |= OUTPUT_FLASH;
						break;
					default:
						helpOutput();
						break;
				}
				break;
			default:
				helpOutput();
				break;
		}
	}
	else
	{
		helpOutput();
	}

	/*
	 * Configuration bin file generate
	 */
	// Save factory default setting value to file
	fd = open("/mnt/FactoryDefaultConfig.bin", O_RDWR|O_CREAT|O_TRUNC);
	if (fd < 0)
	{

		DEBUG_ERROR("open /mnt/FactoryDefaultConfig.bin NG\n");

		free(ptr);
		return 0;
	}
	wrd=write(fd, ptr, MtdBlockSize);
	close(fd);
	if(wrd<MtdBlockSize)
	{
		DEBUG_ERROR("write /mnt/FactoryDefaultConfig.bin NG\n");

		free(ptr);
		return 0;
	}

	DEBUG_INFO("FactoryConfig write to file in /mnt OK.\n");


	/*
	 * Flash memory write
	 */
	if((outType&OUTPUT_FLASH)>0)
	{
		DEBUG_INFO("Erase /dev/mtd10.\n");
		runShellCmd("flash_erase /dev/mtd10 0 0");
		DEBUG_INFO("Write /dev/mtd10.\n");
		runShellCmd("nandwrite -p /dev/mtd10 /mnt/FactoryDefaultConfig.bin");

		DEBUG_INFO("Erase /dev/mtd11.\n");
		runShellCmd("flash_erase /dev/mtd11 0 0");
		DEBUG_INFO("Write /dev/mtd11.\n");
		runShellCmd("nandwrite -p /dev/mtd11 /mnt/FactoryDefaultConfig.bin");

		DEBUG_INFO("Erase /dev/mtd12.\n");
		runShellCmd("flash_erase /dev/mtd12 0 0");
		DEBUG_INFO("Write /dev/mtd12.\n");
		runShellCmd("nandwrite -p /dev/mtd12 /mnt/FactoryDefaultConfig.bin");

		system("rm -f /mnt/FactoryDefaultConfig.bin");

		DEBUG_INFO("FactoryConfig write to flash OK\n");
	}
	free(ptr);

	return PASS;
}