#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"
#include	"main.h"
#include	"lcmComm.h"
#include	"Image.h"
#include	"qrcode.h"

#define ARRAY_SIZE(A)			(sizeof(A) / sizeof(A[0]))
#define PASS					1
#define FAIL					-1
#define YES						1
#define NO						0
#define ON						1
#define OFF						0
#define PAGE_DISPLAY_PERIOD		3

struct SysConfigAndInfo			*ShmSysConfigAndInfo;
struct StatusCodeData 			*ShmStatusCodeData;
struct Charger					*ShmCharger;

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 Uart1Fd;
QRCode qrcode;


//=================================
// Common routine
//=================================
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_LcmControl",
						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;
}

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);
	}
}

//==========================================
// Page routine
//==========================================
void page_booting()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_INIT);
			break;
	}
}

void page_idle()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 4, 8, 64, 64, IMG_ADDR_QRCODE);
			dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 70, 18, 70+48, 18+38, IMG_ADDR_TAP_RFID);

			break;
	}
}

void page_authorizing()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_VERIFY);
			break;
	}
}

void page_preparing()
{
	static uint8_t idxPage = 0;

	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 15, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 10, 128, 54, IMG_ADDR_HANDSHAKE_1+idxPage);
			break;
	}

	idxPage ^= 1;
}

void page_charging()
{
	uint8_t buf[128];
	static uint8_t idxBatt = 0;
	static uint8_t idxPage = 0;

	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 0, 19, 48, 36, IMG_ADDR_ICON_B0+idxBatt);
			//dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 0, 40, 48, 64, IMG_ADDR_ICON_COMPLETE);

			switch(idxPage/PAGE_DISPLAY_PERIOD)
			{
				case 0:
					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_ENERGY);
					sprintf((char*)buf, " 000.0000");
					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));

					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_TIME);
					sprintf((char*)buf, " 000:00");
					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));

					idxPage++;
					break;
				case 1:
					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_COST);
					sprintf((char*)buf, "     0.45");
					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));

					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_PRICE);
					sprintf((char*)buf, " 123.88");
					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));

					idxPage++;
					break;
				default:
					idxPage = 0;
					break;
			}

			break;
	}

	if(idxBatt<5)
		idxBatt++;
	else
		idxBatt =0;
}

void page_complete()
{
	uint8_t buf[128];
	static uint8_t idxPage = 0;

	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 0, 20, 48, 36, IMG_ADDR_ICON_B100);
			dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 0, 40, 48, 64, IMG_ADDR_ICON_COMPLETE);

			switch(idxPage/PAGE_DISPLAY_PERIOD)
			{
				case 0:
					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_ENERGY);
					sprintf((char*)buf, " 000.0000");
					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));

					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_TIME);
					sprintf((char*)buf, " 000:00");
					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));

					idxPage++;
					break;
				case 1:
					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_COST);
					sprintf((char*)buf, "     0.45");
					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));

					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_PRICE);
					sprintf((char*)buf, " 123.88");
					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));

					idxPage++;
					break;
			}

			break;
	}
}

void page_terminating()
{
	uint8_t buf[128];
	static uint8_t idxPage = 0;

	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 0, 20, 48, 36, IMG_ADDR_ICON_B100);
			dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 0, 40, 48, 64, IMG_ADDR_ICON_COMPLETE);

			switch(idxPage/PAGE_DISPLAY_PERIOD)
			{
				case 0:
					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_ENERGY);
					sprintf((char*)buf, " 000.0000");
					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));

					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_TIME);
					sprintf((char*)buf, " 000:00");
					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));

					idxPage++;
					break;
				case 1:
					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_COST);
					sprintf((char*)buf, "     0.45");
					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));

					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_PRICE);
					sprintf((char*)buf, " 123.88");
					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));

					idxPage++;
					break;
			}

			break;
	}
}

void page_alarm()
{
	uint8_t buf[128];

	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 32, 24, 48, 40, IMG_ADDR_ICON_ALERT);
			sprintf((char*)buf, "012336");
			dispCharacterArea(Uart1Fd, AREAD_ID_1, 50, 26, 128, 40, FONT_ASCII_8X12, buf, strlen((char*)buf));
			break;
	}
}

void page_fault()
{
	uint8_t buf[128];

	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 32, 24, 48, 40, IMG_ADDR_ICON_ALERT);
			sprintf((char*)buf, "012336");
			dispCharacterArea(Uart1Fd, AREAD_ID_1, 50, 26, 128, 40, FONT_ASCII_8X12, buf, strlen((char*)buf));
			break;
	}
}

void page_maintain()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
			break;
	}
}

void page_update()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
			break;
	}
}

void page_reservation()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			break;
	}
}

void page_booking()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			break;
	}
}

void page_debug()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
			break;
	}
}

void page_unknown()
{
	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
	{
		case LCD_LANG_CHT:
		case LCD_LANG_CHS:
		case LCD_LANG_JAPANESE:
		case LCD_LANG_FRENCH:
		case LCD_LANG_ITALIAN:
		case LCD_LANG_SPANISH:
		case LCD_LANG_GERMAN:
		case LCD_LANG_DUTCH:
		case LCD_LANG_NORWEGIAN:
		case LCD_LANG_FINNISH:
		case LCD_LANG_SWEDISH:
		case LCD_LANG_SLOVENIAN:
		case LCD_LANG_THAI:
		case LCD_LANG_ENGLISH:
		default:
			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
			break;
	}
}

void page_header()
{
	uint8_t buf[128];

	if(sysFlag.isEnable4G)
	{
		// Drawing 4G signal strength
		if((ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi == 0) || (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi == 99))
		{
			drawRfSignal(Uart1Fd, 0, YES);
		}
		else if((1 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 9))		// -95dBm ~ -111dBm
		{
			drawRfSignal(Uart1Fd, 1, YES);
		}
		else if((9 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 14))		// -85dBm ~ -95dBm
		{
			drawRfSignal(Uart1Fd, 2, YES);
		}
		else if((14 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 19))	// -75dBm ~ -85dBm
		{
			drawRfSignal(Uart1Fd, 3, YES);
		}
		else if((19 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 27))	// -60dBm ~ -75dBm
		{
			drawRfSignal(Uart1Fd, 4, YES);
		}
		else if((27 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi))	//  60dBm ~
		{
			drawRfSignal(Uart1Fd, 5, YES);
		}
		else
		{
			drawRfSignal(Uart1Fd, 0, YES);
		}

	}

	if(sysFlag.isEnableWiFi)
	{
		// Drawing WIFI signal strength
		if(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi == 0)
		{
			drawRfSignal(Uart1Fd, 0, NO);
		}
		else if((-100 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -80))
		{
			drawRfSignal(Uart1Fd, 1, NO);
		}
		else if((-80 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -70))
		{
			drawRfSignal(Uart1Fd, 2, NO);
		}
		else if((-70 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -50))
		{
			drawRfSignal(Uart1Fd, 3, NO);
		}
		else if((-50 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -30))
		{
			drawRfSignal(Uart1Fd, 4, NO);
		}
		else if((-30 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi))
		{
			drawRfSignal(Uart1Fd, 5, NO);
		}
		else
		{
			drawRfSignal(Uart1Fd, 0, NO);
		}

	}

	// Drawing ethernet status
	dispGraphic(Uart1Fd, YES, 121-(sysFlag.isEnableWiFi?26:0)+(sysFlag.isEnable4G?26:0), 0, (ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet?IMG_ADDR_ICON_LAN_OFF:IMG_ADDR_ICON_LAN_ON));

	// Unit price display
	if(ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
	{
		sprintf((char*)buf, "%.2f %s/KWH", ShmSysConfigAndInfo->SysConfig.BillingData.Cur_fee, Currency[ShmSysConfigAndInfo->SysConfig.BillingData.Currency]);
		dispCharacterArea(Uart1Fd, AREAD_ID_HEADER_PRICE, 0, 0, 30, 7, FONT_ASCII_4X6, buf, strlen((char*)buf));
	}
	else
	{
		dispCharacterArea(Uart1Fd, AREAD_ID_HEADER_PRICE, 0, 0, 30, 7, FONT_ASCII_4X6, (uint8_t*)"", strlen(""));
	}

	//dispCharacterConfig(Uart1Fd, AREAD_ID_HEADER, YES, 0, 0, 30, 7);
	//dispCharacterScroll(Uart1Fd, AREAD_ID_HEADER, 0, 0, 40, 7, FONT_ASCII_4X6, NO, 25, (uint8_t*)"012334", strlen("012334"));
	//dispCharacterBlink(Uart1Fd, AREAD_ID_HEADER, 0, 0, FONT_ASCII_4X6, 1, 100, (uint8_t*)"ABCDEFG", strlen("ABCDEFG"));
}

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

	//creat ShmSysConfigAndInfo
	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
    {
		#ifdef SystemLogMessage
		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
		#endif
		result = FAIL;
	}
    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	#ifdef SystemLogMessage
    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
		#endif
    	result = FAIL;
   	}
    else
    {}

   	//creat ShmStatusCodeData
   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
    {
		#ifdef SystemLogMessage
   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
		#endif
   		result = FAIL;
	}
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	#ifdef SystemLogMessage
    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
		#endif
    	result = FAIL;
   	}
    else
    {}

   	//Initial ShmCharger
	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
	{
		#ifdef SystemLogMessage
		DEBUG_ERROR("shmget ShmChargerKey NG\r\n");
		#endif
		result = FAIL;
	}
	else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1)
	{
		#ifdef SystemLogMessage
		DEBUG_ERROR("shmat ShmChargerKey NG\r\n");
		#endif
		result = FAIL;
	}

	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T'))
		sysFlag.isEnable4G = ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled;
	else
		sysFlag.isEnable4G = OFF;

	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W'))
		sysFlag.isEnableWiFi = ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode;
	else
		sysFlag.isEnableWiFi = OFF;

	DEBUG_INFO("sysFlag.isEnable4G: %d\n", sysFlag.isEnable4G);
	DEBUG_INFO("sysFlag.isEnableWiFi: %d\n", sysFlag.isEnableWiFi);

    return result;
}

int InitComPort()
{
	int fd;
	struct termios tios;

	fd = open("/dev/ttyS3", O_RDWR);
	if(fd<=0)
	{
		DEBUG_ERROR("open /dev/ttyS3 NG\n");

		return -1;
	}

	ioctl (fd, TCGETS, &tios);
	tios.c_cflag = B115200| CS8 | CLOCAL | CREAD;
	tios.c_lflag = 0;
	tios.c_iflag = 0;
	tios.c_oflag = 0;
	tios.c_cc[VMIN]=0;
	tios.c_cc[VTIME]=(unsigned char)1;		// timeout 0.5 secod
	tios.c_lflag=0;
	tcflush(fd, TCIFLUSH);
	ioctl (fd, TCSETS, &tios);

	return fd;
}

int InitLcdModule()
{
	int result = FAIL;
	uint8_t qrcodeData[qrcode_getBufferSize(SIZE_53X53)];
	uint8_t qrImageRaw[((53/8)+1)*53];
	uint16_t dataMaxLen = 512;
	uint8_t qrcontent[196];

	sprintf((char*)qrcontent, "%s%s", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber);
	qrcode_initText(&qrcode, qrcodeData, SIZE_53X53, 0, (char*)qrcontent);

	// Power on LCD
	setPower(Uart1Fd, ON);

	// Clear LCD page
	clearScreen(Uart1Fd, NO, 0, 0, 128, 64);

	// Set LCE brightness
	setContrast(Uart1Fd, 255, 255, 1);

	// Display initial screen
	page_booting();

	// QR code raw data generate
	memset(qrImageRaw, 0x00, ARRAY_SIZE(qrImageRaw));
	for(uint16_t idxY = 0;idxY<qrcode.size;idxY++)
	{
		for(uint16_t idxX = 0;idxX<qrcode.size;idxX++)
		{
			if(qrcode_getModule(&qrcode, idxX, idxY))
			{
				//drawPoint(Uart1Fd, idxX, idxY);
				qrImageRaw[(7*idxY) + (idxX/8)] |= (0x01<<(7-(idxX%8)));
			}
			else
			{
				qrImageRaw[(7*idxY) + (idxX/8)] &= ~(0x01<<(7-(idxX%8)));
			}
		}
	}

	// Upload image file
	// QR Code
	picUploadStart(Uart1Fd, IMG_ADDR_QRCODE, 53, 53);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(qrImageRaw)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(qrImageRaw)/dataMaxLen)) || ((idx == (ARRAY_SIZE(qrImageRaw)/dataMaxLen)) && ((ARRAY_SIZE(qrImageRaw)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_QRCODE, (idx*dataMaxLen), &qrImageRaw[idx*dataMaxLen], (idx<(ARRAY_SIZE(qrImageRaw)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(qrImageRaw)%dataMaxLen)) );
	}

	// LAN icon
	for(uint8_t idxLAN=0;idxLAN<6;idxLAN++)
	{
		picUploadStart(Uart1Fd, IMG_ADDR_ICON_LAN_OFF+idxLAN, 7, 7);
		for(uint8_t idx=0;idx<=ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen;idx++)
		{
			if((idx < (ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen)) || ((idx == (ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen)) && ((ARRAY_SIZE(LAN_Icon[idxLAN])%dataMaxLen)>0)))
				picUploadData(Uart1Fd, IMG_ADDR_ICON_LAN_OFF+idxLAN, (idx*dataMaxLen), &LAN_Icon[idxLAN][idx*dataMaxLen], (idx<(ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(LAN_Icon[idxLAN])%dataMaxLen)) );
		}
	}

	// RF icon
	for(uint8_t idxRF=0;idxRF<6;idxRF++)
	{
		picUploadStart(Uart1Fd, IMG_ADDR_RF_0+idxRF, 19, 7);
		for(uint8_t idx=0;idx<=ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen;idx++)
		{
			if((idx < (ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen)) || ((idx == (ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen)) && ((ARRAY_SIZE(RF_Icon[idxRF])%dataMaxLen)>0)))
				picUploadData(Uart1Fd, IMG_ADDR_RF_0+idxRF, (idx*dataMaxLen), &RF_Icon[idxRF][idx*dataMaxLen], (idx<(ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(RF_Icon[idxRF])%dataMaxLen)) );
		}
	}

	// Init image
	picUploadStart(Uart1Fd, IMG_ADDR_INIT, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_init)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_init)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_init)/dataMaxLen)) && ((ARRAY_SIZE(img_init)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_INIT, (idx*dataMaxLen), &img_init[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_init)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_init)%dataMaxLen)) );
	}

	// RIFD image
	picUploadStart(Uart1Fd, IMG_ADDR_TAP_RFID, 48, 38);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_rfid)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_rfid)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_rfid)/dataMaxLen)) && ((ARRAY_SIZE(img_rfid)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_TAP_RFID, (idx*dataMaxLen), &img_rfid[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_rfid)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_rfid)%dataMaxLen)) );
	}

	// Handshake 1 image
	picUploadStart(Uart1Fd, IMG_ADDR_HANDSHAKE_1, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_handshake_1)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_handshake_1)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_handshake_1)/dataMaxLen)) && ((ARRAY_SIZE(img_handshake_1)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_HANDSHAKE_1, (idx*dataMaxLen), &img_handshake_1[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_handshake_1)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_handshake_1)%dataMaxLen)) );
	}

	// Handshake 2 image
	picUploadStart(Uart1Fd, IMG_ADDR_HANDSHAKE_2, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_handshake_2)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_handshake_2)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_handshake_2)/dataMaxLen)) && ((ARRAY_SIZE(img_handshake_2)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_HANDSHAKE_2, (idx*dataMaxLen), &img_handshake_2[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_handshake_2)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_handshake_2)%dataMaxLen)) );
	}

	// Maintain image
	picUploadStart(Uart1Fd, IMG_ADDR_MAINTIAN, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_maintain)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_maintain)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_maintain)/dataMaxLen)) && ((ARRAY_SIZE(img_maintain)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_MAINTIAN, (idx*dataMaxLen), &img_maintain[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_maintain)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_maintain)%dataMaxLen)) );
	}

	// Verify image
	picUploadStart(Uart1Fd, IMG_ADDR_VERIFY, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_verify)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_verify)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_verify)/dataMaxLen)) && ((ARRAY_SIZE(img_verify)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_VERIFY, (idx*dataMaxLen), &img_verify[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_verify)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_verify)%dataMaxLen)) );
	}

	// Verify OK image
	picUploadStart(Uart1Fd, IMG_ADDR_VERIFYOK, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_verify_ok)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_verify_ok)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_verify_ok)/dataMaxLen)) && ((ARRAY_SIZE(img_verify_ok)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_VERIFYOK, (idx*dataMaxLen), &img_verify_ok[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_verify_ok)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_verify_ok)%dataMaxLen)) );
	}

	// Verify fail image
	picUploadStart(Uart1Fd, IMG_ADDR_VERIFYFAIL, 128, 64);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_verify_fail)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_verify_fail)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_verify_fail)/dataMaxLen)) && ((ARRAY_SIZE(img_verify_fail)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_VERIFYFAIL, (idx*dataMaxLen), &img_verify_fail[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_verify_fail)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_verify_fail)%dataMaxLen)) );
	}

	// Icon alert image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_ALERT, 16, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_alert)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_alert)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_alert)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_alert)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_ALERT, (idx*dataMaxLen), &img_icon_alert[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_alert)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_alert)%dataMaxLen)) );
	}

	// Icon energy image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_ENERGY, 24, 24);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_energy)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_energy)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_energy)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_energy)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_ENERGY, (idx*dataMaxLen), &img_icon_energy[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_energy)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_energy)%dataMaxLen)) );
	}

	// Icon energy image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_COST, 24, 24);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_cost)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_cost)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_cost)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_cost)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_COST, (idx*dataMaxLen), &img_icon_cost[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_cost)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_cost)%dataMaxLen)) );
	}

	// Icon time image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_TIME, 24, 24);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_time)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_time)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_time)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_time)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_TIME, (idx*dataMaxLen), &img_icon_time[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_time)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_time)%dataMaxLen)) );
	}

	// Icon price image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_PRICE, 33, 24);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_price)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_price)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_price)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_price)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_PRICE, (idx*dataMaxLen), &img_icon_price[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_price)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_price)%dataMaxLen)) );
	}

	// Icon battery 0% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B0, 48, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b0)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_b0)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b0)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b0)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_B0, (idx*dataMaxLen), &img_icon_b0[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b0)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b0)%dataMaxLen)) );
	}

	// Icon battery 20% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B20, 48, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b20)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_b20)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b20)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b20)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_B20, (idx*dataMaxLen), &img_icon_b20[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b20)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b20)%dataMaxLen)) );
	}

	// Icon battery 40% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B40, 48, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b40)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_b40)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b40)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b40)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_B40, (idx*dataMaxLen), &img_icon_b40[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b40)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b40)%dataMaxLen)) );
	}

	// Icon battery 60% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B60, 48, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b60)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_b60)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b60)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b60)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_B60, (idx*dataMaxLen), &img_icon_b60[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b60)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b60)%dataMaxLen)) );
	}

	// Icon battery 80% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B80, 48, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b80)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_b80)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b80)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b80)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_B80, (idx*dataMaxLen), &img_icon_b80[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b80)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b80)%dataMaxLen)) );
	}

	// Icon battery 100% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B100, 48, 16);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b100)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_b100)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b100)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b100)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_B100, (idx*dataMaxLen), &img_icon_b100[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b100)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b100)%dataMaxLen)) );
	}

	// Icon battery 100% image
	picUploadStart(Uart1Fd, IMG_ADDR_ICON_COMPLETE, 48, 18);
	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_complete)/dataMaxLen;idx++)
	{
		if((idx < (ARRAY_SIZE(img_icon_complete)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_complete)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_complete)%dataMaxLen)>0)))
			picUploadData(Uart1Fd, IMG_ADDR_ICON_COMPLETE, (idx*dataMaxLen), &img_icon_complete[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_complete)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_complete)%dataMaxLen)) );
	}

	return result;
}

//================================================
// Main process
//================================================
int main(void)
{
	uint8_t previousMode = 0xff;
	uint8_t previousLan = 0xff;

	if(InitShareMemory() == FAIL)
	{
		#ifdef SystemLogMessage
		DEBUG_ERROR("InitShareMemory NG\n");
		#endif
		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
		}
		sleep(5);
		return FAIL;
	}

	Uart1Fd=InitComPort();
	if(Uart1Fd<0)
	{
		#ifdef SystemLogMessage
		DEBUG_ERROR("InitComPort NG\n");
		#endif
		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1;
		}
		sleep(5);
		return FAIL;
	}
	else
	{
		InitLcdModule();
	}
	DEBUG_INFO("Initial completed\n");

	for(;;)
	{
		// Clear LCD if page change.
		if((previousMode != ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus) ||
		   (previousLan != ShmSysConfigAndInfo->SysConfig.DefaultLanguage))
		{
			// Clear screen
			clearScreen(Uart1Fd, NO, 0, 0, 128, 64);

			previousMode = ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus;
			previousLan = ShmSysConfigAndInfo->SysConfig.DefaultLanguage;
		}

		switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus)
		{
			case SYS_MODE_BOOTING:
				page_booting();
				break;
			case SYS_MODE_IDLE:
				page_idle();
				break;
			case SYS_MODE_AUTHORIZING:
				page_authorizing();
				break;
			case SYS_MODE_PREPARING:
				page_preparing();
				break;
			case SYS_MODE_CHARGING:
				page_charging();
				break;
			case SYS_MODE_TERMINATING:
				page_terminating();
				break;
			case SYS_MODE_COMPLETE:
				page_complete();
				break;
			case SYS_MODE_ALARM:
				page_alarm();
				break;
			case SYS_MODE_FAULT:
				page_fault();
				break;
			case SYS_MODE_MAINTAIN:
				page_maintain();
				break;
			case SYS_MODE_UPDATE:
				page_update();
				break;
			case SYS_MODE_RESERVATION:
				page_reservation();
				break;
			case SYS_MODE_BOOKING:
				page_booking();
				break;
			case SYS_MODE_DEBUG:
				page_debug();
				break;
			default:
				page_unknown();
				break;
		}

		page_header();

		usleep(1000000);
	}

	return FAIL;
}