/*
 * Module_PhBackend.c
 *
 *  Created on: 2020/06/11
 *      Author: foluswen
 */
#include "Module_PhBackend.h"

int StoreLogMsg(const char *fmt, ...)
{
	char Buf[4096+256];
	char buffer[4096];
	time_t CurrentTime;
	struct tm *tm;
	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);
	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d] - %s\" >> /Storage/SystemLog/[%04d.%02d]Module_PhBackend",
			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
			buffer,
			tm->tm_year+1900,tm->tm_mon+1);
#ifdef SystemLogMessage
	system(Buf);
#endif

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

	return rc;
}

uint8_t split(char *src, const char *separator, char **dest)
{
     char *pNext;
     int count = 0;

     if (src == NULL || strlen(src) == 0)
        return count;
     if (separator == NULL || strlen(separator) == 0)
        return count;
     pNext = (char *)strtok(src,separator);
     while(pNext != NULL)
     {
         *dest++ = pNext;
         ++count;
         pNext = (char *)strtok(NULL,separator);
    }

     return count;
}

//==========================================
// 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
    {}

    return result;
}

uint8_t checksum_valid(struct Message *message)
{
	uint8_t chksum = 0;

	for(uint16_t idx=6;idx<(message->buffer[2] | ((uint16_t)message->buffer[3]<<8));idx++)
		chksum += message->buffer[idx];

	chksum += 11;

	return ((chksum&0xff)==message->buffer[(message->buffer[2] | ((uint16_t)message->buffer[3]<<8))-1]?PASS:FAIL);
}

uint8_t checksum_cal(struct Message *message)
{
	uint8_t chksum = 0;

	for(uint16_t idx=6;idx<(message->size-1);idx++)
		chksum += message->buffer[idx];

	chksum += 11;

	return (chksum & 0xff);
}

void showCmdRaw(struct Message *message, uint8_t isTx)
{
	if(isTx)
		DEBUG_INFO("%s -----> Server\n", ShmSysConfigAndInfo->SysConfig.SystemId);
	else
		DEBUG_INFO("%s <----- Server\n", ShmSysConfigAndInfo->SysConfig.SystemId);

	DEBUG_INFO("- CMD_%04d ------------------------------------\n", (message->buffer[6] | ((uint16_t)message->buffer[7]<<8)));
	DEBUG_INFO("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
	DEBUG_INFO("-----------------------------------------------\n");

	for(uint8_t idx=0;idx<((message->size/16)+1);idx++)
	{
		DEBUG_INFO("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", message->buffer[idx*16+0],
																									  message->buffer[idx*16+1],
																									  message->buffer[idx*16+2],
																									  message->buffer[idx*16+3],
																									  message->buffer[idx*16+4],
																									  message->buffer[idx*16+5],
																									  message->buffer[idx*16+6],
																									  message->buffer[idx*16+7],
																									  message->buffer[idx*16+8],
																									  message->buffer[idx*16+9],
																									  message->buffer[idx*16+10],
																									  message->buffer[idx*16+11],
																									  message->buffer[idx*16+12],
																									  message->buffer[idx*16+13],
																									  message->buffer[idx*16+14],
																									  message->buffer[idx*16+15]);
	}

	DEBUG_INFO("-----------------------------------------------\n");
}

void handle_cmd_1001(struct Message *in, struct Message *out)
{
	uint32_t startAddr;
	uint32_t offset = 0;
	uint8_t	count;
	uint32_t value;

	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	if(in->buffer[12])
			DEBUG_INFO("CMD Type: Set\n");
	else
		DEBUG_INFO("CMD Type: Query\n");

	startAddr = in->buffer[13] | ((uint32_t)in->buffer[14]<<8) | ((uint32_t)in->buffer[15]<<16) | ((uint32_t)in->buffer[16]<<24);
	count = in->buffer[17];

	if(in->buffer[12])
	{
		for(int idx=startAddr;idx<(startAddr+count);idx++)
		{
			value = in->buffer[20+(offset*4)] | ((uint32_t)in->buffer[21+(offset*4)]<<8) | ((uint32_t)in->buffer[22+(offset*4)]<<16) | ((uint32_t)in->buffer[23+(offset*4)]<<24);

			switch(idx)
			{
				case 1:
					DEBUG_INFO("Sign in interval: %d\n", value);
					offset++;
					break;
				case 2:
					DEBUG_INFO("Charger type: %d\n", value);
					offset++;
					break;
				case 3:
					DEBUG_INFO("Charger gun count: %d\n", value);
					offset++;
					break;
				case 4:
					DEBUG_INFO("Communication No: %d\n", value);
					offset++;
					break;
				case 5:
					offset++;
					break;
				case 6:
					offset++;
					break;
				case 7:
					offset++;
					break;
				case 8:
					offset++;
					break;
				case 9:
					offset++;
					break;
				case 10:
					offset++;
					break;
				case 11:
					offset++;
					break;
				case 12:
					offset++;
					break;
				case 13:
					offset++;
					break;
				case 14:
					offset++;
					break;
				case 15:
					offset++;
					break;
				case 16:
					offset++;
					break;
				case 17:
					offset++;
					break;
				case 18:
					offset++;
					break;
				case 19:
					offset++;
					break;
				case 20:
					DEBUG_INFO("Report interval: %d\n", value);
					offset++;
					break;
				case 21:
					DEBUG_INFO("Heart beat interval: %d\n", value);
					backend_info.interval_heartbeat = value;
					offset++;
					break;
				case 22:
					DEBUG_INFO("Heart beat overtime count: %d\n", value);
					backend_info.retry_heartbeat = value;
					offset++;
					break;
				case 23:
					DEBUG_INFO("Status report interval: %d\n", value);
					offset++;
					break;
				case 24:
					offset++;
					break;
				case 25:
					offset++;
					break;
				case 26:
					offset++;
					break;
				case 27:
					DEBUG_INFO("Service price: %.2f\n", (value/100.0));
					offset++;
					break;
				case 28:
					DEBUG_INFO("Charging price: %.2f\n", (value/100.0));
					offset++;
					break;
				case 29:
					offset++;
					break;
				case 30:
					offset++;
					break;
				case 31:
					offset++;
					break;
				case 32:
					offset++;
					break;
				case 33:
					offset++;
					break;
				case 34:
					offset++;
					break;
				case 35:
					offset++;
					break;
			}
		}
	}

	create_Cmd_1002(out, in->buffer[12], startAddr, count);
}

void handle_cmd_1003(struct Message *in, struct Message *out)
{
	uint32_t startAddr;
	uint8_t data[in->size-11-9];
	uint8_t *server_info[3];

	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	if(in->buffer[12])
		DEBUG_INFO("CMD Type: Set\n");
	else
		DEBUG_INFO("CMD Type: Query\n");

	startAddr = in->buffer[13] | ((uint32_t)in->buffer[14]<<8) | ((uint32_t)in->buffer[15]<<16) | ((uint32_t)in->buffer[16]<<24);
	memcpy(&data[0], &in->buffer[19], ARRAY_SIZE(data));

	switch(startAddr)
	{
		case 1:
			break;
		case 2:
			DEBUG_INFO("Server time: %02X%02X-%02X-%02X %02X:%02X:%02X\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 7:
			break;
		case 8:
			break;
		case 9:
			break;
		case 10:
			break;
		case 11:
			memset(server_addr, 0x00, ARRAY_SIZE(server_addr));
			memcpy(&server_addr[0], &in->buffer[19], 128);
			split((char*)server_addr, ":", (char**)server_info);

			message_header = strtol((char*)server_info[2], NULL, 16);
			server_port = atoi((char*)server_info[1]);
			sprintf((char*)server_addr, "%s", (char*)server_info[0]);

			DEBUG_INFO("Server address: %s\n", server_addr);
			DEBUG_INFO("Server port: %d\n", server_port);
			DEBUG_INFO("Message header: %04X\n", message_header);
			break;
		case 12:
			DEBUG_INFO("Customer ID: %s\n", data);
			break;
	}

	create_Cmd_1004(out, in->buffer[12], startAddr, &data[0], ARRAY_SIZE(data));
}

void handle_cmd_1005(struct Message *in, struct Message *out)
{
	uint32_t startAddr;
	uint32_t offset = 0;
	uint8_t	count;
	uint32_t value;
	uint8_t	gun_index;

	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));

	gun_index = in->buffer[12];
	startAddr = in->buffer[13] | ((uint32_t)in->buffer[14]<<8) | ((uint32_t)in->buffer[15]<<16) | ((uint32_t)in->buffer[16]<<24);
	count = in->buffer[17];

	for(int idx=startAddr;idx<(startAddr+count);idx++)
	{
		value = in->buffer[20+(offset*4)] | ((uint32_t)in->buffer[21+(offset*4)]<<8) | ((uint32_t)in->buffer[22+(offset*4)]<<16) | ((uint32_t)in->buffer[23+(offset*4)]<<24);

		switch(idx)
		{
			case 1:
				if(value == 0x55)
				{
					DEBUG_INFO("Charger start.\n");
				}
				offset++;
				break;
			case 2:
				if(value == 0x55)
				{
					DEBUG_INFO("Charger stop.\n");
				}
				offset++;
				break;

			case 3:
				if(value == 0)
				{
					DEBUG_INFO("Charge soon.\n");
				}
				else if(value ==1)
				{
					DEBUG_INFO("Charge reserve.\n");
				}
				offset++;
				break;
			case 4:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 5:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 6:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 7:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 8:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 9:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 10:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 11:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 12:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 13:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 14:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 15:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 16:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 17:
				if(value == 0x55)
				{
					DEBUG_INFO("Upload log request.\n");
					system("/usr/bin/run_tmate_restart.sh");
				}
				offset++;
				break;

			case 18:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 19:
				if(value == 0x55)
				{

				}
				offset++;
				break;

			case 20:
				if(value == 0x55)
				{

				}
				offset++;
				break;
		}
	}

	create_Cmd_1006(out, gun_index, startAddr, count, true);
}

void handle_cmd_1101(struct Message *in)
{
	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	backend_info.sn_heartbeat = (in->buffer[12] | ((uint16_t)in->buffer[13]<<8));
	backend_info.counter_heartbeat_retry = 0;
}

void handle_cmd_1103(struct Message *in)
{
	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	DEBUG_INFO("Connector id: %d\n", in->buffer[12]);
}

void handle_cmd_1105(struct Message *in)
{
	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	DEBUG_INFO("Charger sign in OK.\n");
	backend_info.isSignin = ON;
	backend_info.st_hearbeat = time((time_t*)NULL);
	backend_info.counter_heartbeat_retry = 0;
	backend_info.interval_heartbeat = 10;
}

void handle_cmd_2303(struct Message *in, struct Message *out)
{
	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	create_Cmd_2304(out);
}

void handle_cmd_2305(struct Message *in, struct Message *out)
{
	DEBUG_INFO("User ID: %d\n", (in->buffer[8] | ((uint16_t)in->buffer[9]<<8)));
	DEBUG_INFO("CMD SN: %d\n", (in->buffer[10] | ((uint16_t)in->buffer[11]<<8)));
	create_Cmd_2306(out);
}



void create_Cmd_1002(struct Message *out, uint8_t cmd_type, uint32_t address, uint32_t count)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
	out->size = 9 + 43 + (count*4);

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (1002>>0) & 0xff;
	out->buffer[0x07] = (1002>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Charger ID
	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);

	// Command type (0:Check  1:Set)
	out->buffer[0x2c] = cmd_type;

	// Start adress
	out->buffer[0x2d] = (address>>0) & 0xff;
	out->buffer[0x2e] = (address>>8) & 0xff;
	out->buffer[0x2f] = (address>>16) & 0xff;
	out->buffer[0x30] = (address>>24) & 0xff;

	// Count
	out->buffer[0x31] = count;

	// Result (0:Success  1:Fail)
	out->buffer[0x31] = 0x00;

	memset(&out->buffer[0x32], 0x00, (count*4));

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);

}

void create_Cmd_1004(struct Message *out, uint8_t cmd_type, uint32_t address, uint8_t *data, uint8_t data_len)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
	out->size = 9 + 42 + data_len;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (1004>>0) & 0xff;
	out->buffer[0x07] = (1004>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Charger ID
	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);

	// Command type (0:Check  1:Set)
	out->buffer[0x2c] = cmd_type;

	// Start adress
	out->buffer[0x2d] = (address>>0) & 0xff;
	out->buffer[0x2e] = (address>>8) & 0xff;
	out->buffer[0x2f] = (address>>16) & 0xff;
	out->buffer[0x30] = (address>>24) & 0xff;

	// Result (0:Success  1:Fail)
	out->buffer[0x31] = 0x00;

	// Result data
	memcpy(&out->buffer[0x32], &data[0], data_len);

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);
}

void create_Cmd_1006(struct Message *out, uint8_t gun_index, uint32_t address, uint8_t count, uint8_t isExecuted)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
	out->size = 0x34;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (1006>>0) & 0xff;
	out->buffer[0x07] = (1006>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Charger ID
	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);

	// Gun index
	out->buffer[0x2c] = gun_index;

	// Start adress
	out->buffer[0x2d] = (address>>0) & 0xff;
	out->buffer[0x2e] = (address>>8) & 0xff;
	out->buffer[0x2f] = (address>>16) & 0xff;
	out->buffer[0x30] = (address>>24) & 0xff;

	// Command count
	out->buffer[0x31] = count;

	// Command execute result;
	out->buffer[0x32] = isExecuted;

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);
}

void create_Cmd_1102(struct Message *out)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));

	out->size = 0x2f;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (1102>>0) & 0xff;
	out->buffer[0x07] = (1102>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Charger ID
	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);

	// Heart beat sn
	out->buffer[0x2c] = (backend_info.sn_heartbeat>>0) & 0xff;
	out->buffer[0x2d] = (backend_info.sn_heartbeat>>8) & 0xff;

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);
}

void create_Cmd_1104(struct Message *out, uint8_t gun_index)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));

	out->size = 0xd7;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (1102>>0) & 0xff;
	out->buffer[0x07] = (1102>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Charger ID
	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 0x20);

	// Charger connector quantity
	out->buffer[0x2c] = AC_QUANTITY + CCS_QUANTITY + GB_QUANTITY + CHAdeMO_QUANTITY;

	// Connector id
	out->buffer[0x2d] = gun_index;

	// Charger model type (1: DC, 2: AC)
	out->buffer[0x2e] = (ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D'?1:2);

	// Connector status
	switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+gun_index])
	{
		case '1' ... '9':
			if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_UPDATE))
				out->buffer[0x2f] = 7;
			else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_IDLE)
				out->buffer[0x2f] = 0;
			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_PREPARING))
				out->buffer[0x2f] = 1;
			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_TERMINATING))
				out->buffer[0x2f] = 2;
			else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_COMPLETE)
				out->buffer[0x2f] = 3;
			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_FAULT))
				out->buffer[0x2f] = 6;
			else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[9-gun_index].SystemStatus == SYS_MODE_RESERVATION)
				out->buffer[0x2f] = 5;
			else
				out->buffer[0x2f] = 0;
			break;
		case 'J':
			if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_UPDATE))
				out->buffer[0x2f] = 7;
			else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_IDLE)
				out->buffer[0x2f] = 0;
			else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARING))
				out->buffer[0x2f] = 1;
			else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_TERMINATING))
				out->buffer[0x2f] = 2;
			else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_COMPLETE)
				out->buffer[0x2f] = 3;
			else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_FAULT))
				out->buffer[0x2f] = 6;
			else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[7+gun_index].SystemStatus == SYS_MODE_RESERVATION)
				out->buffer[0x2f] = 5;
			else
				out->buffer[0x2f] = 0;
			break;
		case 'U':
		case 'E':
			if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_UPDATE))
				out->buffer[0x2f] = 7;
			else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_IDLE)
				out->buffer[0x2f] = 0;
			else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARING))
				out->buffer[0x2f] = 1;
			else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_TERMINATING))
				out->buffer[0x2f] = 2;
			else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_COMPLETE)
				out->buffer[0x2f] = 3;
			else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_FAULT))
				out->buffer[0x2f] = 6;
			else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[7+gun_index].SystemStatus == SYS_MODE_RESERVATION)
				out->buffer[0x2f] = 5;
			else
				out->buffer[0x2f] = 0;
			break;
		case 'G':
			if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_UPDATE))
				out->buffer[0x2f] = 7;
			else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_IDLE)
				out->buffer[0x2f] = 0;
			else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_AUTHORIZING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARING))
				out->buffer[0x2f] = 1;
			else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_PREPARE_FOR_EV) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_TERMINATING))
				out->buffer[0x2f] = 2;
			else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_COMPLETE)
				out->buffer[0x2f] = 3;
			else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_FAULT))
				out->buffer[0x2f] = 6;
			else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[7+gun_index].SystemStatus == SYS_MODE_RESERVATION)
				out->buffer[0x2f] = 5;
			else
				out->buffer[0x2f] = 0;
			break;
		default:
			break;
	}

	// SOC
	out->buffer[0x30] = 0x00;

	// Alarm code
	out->buffer[0x31] = 0x00;
	out->buffer[0x32] = 0x00;
	out->buffer[0x33] = 0x00;
	out->buffer[0x34] = 0x00;

	// Connect status
	out->buffer[0x35] = 0x00;

	// Charging amount
	out->buffer[0x36] = 0x00;
	out->buffer[0x37] = 0x00;
	out->buffer[0x38] = 0x00;
	out->buffer[0x39] = 0x00;

	// Charging temperature
	out->buffer[0x3a] = 0x00;
	out->buffer[0x3b] = 0x00;
	out->buffer[0x3c] = 0x00;
	out->buffer[0x3d] = 0x00;

	// Total power consumption
	out->buffer[0x3e] = 0x00;
	out->buffer[0x3f] = 0x00;
	out->buffer[0x40] = 0x00;
	out->buffer[0x41] = 0x00;

	// DC voltage
	out->buffer[0x42] = 0x00;
	out->buffer[0x43] = 0x00;

	// DC current
	out->buffer[0x44] = 0x00;
	out->buffer[0x45] = 0x00;

	// BMS voltage request
	out->buffer[0x46] = 0x00;
	out->buffer[0x47] = 0x00;

	// BMS current request
	out->buffer[0x48] = 0x00;
	out->buffer[0x49] = 0x00;

	// BMS charging mode
	out->buffer[0x4a] = 0x00;

	// AC L1 voltage
	out->buffer[0x4b] = 0x00;
	out->buffer[0x4c] = 0x00;

	// AC L2 voltage
	out->buffer[0x4d] = 0x00;
	out->buffer[0x4e] = 0x00;

	// AC L3 voltage
	out->buffer[0x4f] = 0x00;
	out->buffer[0x50] = 0x00;

	// AC L1 current
	out->buffer[0x51] = 0x00;
	out->buffer[0x52] = 0x00;

	// AC L2 current
	out->buffer[0x53] = 0x00;
	out->buffer[0x54] = 0x00;

	// AC L3 current
	out->buffer[0x55] = 0x00;
	out->buffer[0x56] = 0x00;

	// Charging remind time
	out->buffer[0x57] = 0x00;
	out->buffer[0x58] = 0x00;

	// Charging time
	out->buffer[0x59] = 0x00;
	out->buffer[0x5a] = 0x00;
	out->buffer[0x5b] = 0x00;
	out->buffer[0x5c] = 0x00;

	// Charging power consumption
	out->buffer[0x5d] = 0x00;
	out->buffer[0x5e] = 0x00;
	out->buffer[0x5f] = 0x00;
	out->buffer[0x60] = 0x00;

	// Before charging meter value
	out->buffer[0x61] = 0x00;
	out->buffer[0x62] = 0x00;
	out->buffer[0x63] = 0x00;
	out->buffer[0x64] = 0x00;

	// After charging meter value
	out->buffer[0x65] = 0x00;
	out->buffer[0x66] = 0x00;
	out->buffer[0x67] = 0x00;
	out->buffer[0x68] = 0x00;

	// Start method
	out->buffer[0x69] = 0x00;

	// Charging strategy
	out->buffer[0x6a] = 0x00;

	// Charging parameter
	out->buffer[0x6b] = 0x00;
	out->buffer[0x6c] = 0x00;
	out->buffer[0x6d] = 0x00;
	out->buffer[0x6e] = 0x00;

	// Reservation flag
	out->buffer[0x6f] = 0x00;

	// User
	memset(&out->buffer[0x70], 0x00, 0x24);

	// Reservation over time
	out->buffer[0x94] = 0x00;

	// Start time
	memset(&out->buffer[0x95], 0x00, 0x08);

	// Surplus
	memset(&out->buffer[0x9d], 0x00, 0x04);

	// System variable reserve
	memset(&out->buffer[0xa1], 0x00, 0x14);

	// RFID/Member flag
	out->buffer[0xb5] = 0x00;

	// Order No.
	memset(&out->buffer[0xb6], 0x00, 0x20);

	// SN
	memset(&out->buffer[0xd6], 0x00, 0x10);

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);
}

void create_Cmd_1106(struct Message *out)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));

	out->size = 0x63;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (1106>>0) & 0xff;
	out->buffer[0x07] = (1106>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Charger ID
	memcpy(&out->buffer[0x0c], &ShmSysConfigAndInfo->SysConfig.SystemId[0], 32);

	// Charger type  (0:Normal  1:none polar  2:polling)
	out->buffer[0x2c] = 0x00;

	// Software version
	out->buffer[0x2d] = 0x01;
	out->buffer[0x2e] = 0x00;
	out->buffer[0x2f] = 0x00;
	out->buffer[0x30] = 0x00;

	// Charger item type
	out->buffer[0x31] = 0x00;
	out->buffer[0x32] = 0x00;

	// Start count
	out->buffer[0x33] = 0x00;
	out->buffer[0x34] = 0x00;
	out->buffer[0x35] = 0x00;
	out->buffer[0x36] = 0x00;

	// Data upload type  (1:Handshake  2:Report)
	out->buffer[0x37] = 0x02;

	// Register time  (Minute)
	out->buffer[0x38] = 0x00;
	out->buffer[0x39] = 0x00;

	// Spare
	out->buffer[0x3a] = 0x00;

	// Charge gun count
	out->buffer[0x3b] = 0x01;

	// Heart beat upload cycle
	out->buffer[0x3c] = 0x98;

	// Heart beat overtime count
	out->buffer[0x3d] = 0x00;

	// Charge record count
	out->buffer[0x3e] = 0x00;
	out->buffer[0x3f] = 0x00;
	out->buffer[0x40] = 0x00;
	out->buffer[0x41] = 0x00;

	// Current system time
	out->buffer[0x42] = 0x20;
	out->buffer[0x43] = 0x20;
	out->buffer[0x44] = 0x06;
	out->buffer[0x45] = 0x11;
	out->buffer[0x46] = 0x11;
	out->buffer[0x47] = 0x02;
	out->buffer[0x48] = 0x18;
	out->buffer[0x49] = 0xff;

	// Latest charge time
	out->buffer[0x4a] = 0x20;
	out->buffer[0x4b] = 0x20;
	out->buffer[0x4c] = 0x06;
	out->buffer[0x4d] = 0x11;
	out->buffer[0x4e] = 0x11;
	out->buffer[0x4f] = 0x01;
	out->buffer[0x50] = 0x52;
	out->buffer[0x51] = 0xff;

	// Latest start time
	out->buffer[0x52] = 0x20;
	out->buffer[0x53] = 0x20;
	out->buffer[0x54] = 0x06;
	out->buffer[0x55] = 0x11;
	out->buffer[0x56] = 0x11;
	out->buffer[0x57] = 0x01;
	out->buffer[0x58] = 0x52;
	out->buffer[0x59] = 0xff;

	// Latest register time
	out->buffer[0x5a] = 0x20;
	out->buffer[0x5b] = 0x20;
	out->buffer[0x5c] = 0x06;
	out->buffer[0x5d] = 0x11;
	out->buffer[0x5e] = 0x11;
	out->buffer[0x5f] = 0x02;
	out->buffer[0x60] = 0x08;
	out->buffer[0x61] = 0xff;

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);
}

void create_Cmd_2304(struct Message *out)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));

	out->size = 0x0e;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (2304>>0) & 0xff;
	out->buffer[0x07] = (2304>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Result (0:Success  1:Fail)
	out->buffer[0x0c] = 0x00;

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);

}

void create_Cmd_2306(struct Message *out)
{
	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));

	out->size = 0x11;

	// Message header
	out->buffer[0x00] = (message_header>>8) & 0xff;
	out->buffer[0x01] = (message_header>>0) & 0xff;

	// Message length
	out->buffer[0x02] = (out->size>>0) & 0xff;
	out->buffer[0x03] = (out->size>>8) & 0xff;

	// Message protocol version
	out->buffer[0x04] = PROTOCOL_VER;

	// Message server command serial number
	out->buffer[0x05] = server_cmd_sn & 0xff;

	// Message command
	out->buffer[0x06] = (2306>>0) & 0xff;
	out->buffer[0x07] = (2306>>8) & 0xff;

	// Message user id
	out->buffer[0x08] = (server_user_id>>0) & 0xff;
	out->buffer[0x09] = (server_user_id>>8) & 0xff;

	// Message server command serial number
	out->buffer[0x0a] = (server_cmd_sn>>0) & 0xff;
	out->buffer[0x0b] = (server_cmd_sn>>8) & 0xff;

	// Result (0:Success  1:Fail)
	out->buffer[0x0c] = 0x00;
	out->buffer[0x0d] = 0x00;
	out->buffer[0x0e] = 0x00;
	out->buffer[0x0f] = 0x00;

	// Checksum
	out->buffer[out->size-1] = checksum_cal(out);

	showCmdRaw(out, true);
}

int main(void)
{
	int 				sockfd;
	struct sockaddr_in 	info;
	struct hostent 		*ghbn;
	struct timeval 		tv;
	uint8_t 			socketEnable;

	struct Message		input;
	struct Message		intputBuf;
	struct Message		output;

	sprintf((char*)server_addr, "evsocket.phihong.com.tw");
	server_port = 9999;

	if(InitShareMemory() == FAIL)
	{
		DEBUG_ERROR("InitShareMemory NG\n");

		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON;
		}
		sleep(5);
		return 0;
	}

	for(;;)
	{
		while(!ShmSysConfigAndInfo->SysInfo.InternetConn)
		{
			sleep(1);
		}

		bzero(&info,sizeof(info));
		ghbn = gethostbyname((char*)server_addr);
		info.sin_family = PF_INET;
		info.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]));
		info.sin_port = htons(server_port);
		DEBUG_INFO("Connecto to %s:%d\n", inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]), server_port);

		sockfd = socket(AF_INET, SOCK_STREAM, 0);
		if (sockfd == -1)
		{
			DEBUG_ERROR("Fail to create a socket.");
			return 0;
		}

		if(connect(sockfd, (struct sockaddr *)&info,sizeof(info)) ==-1)
		{
			DEBUG_ERROR("Connection error");
		}
		else
		{
			DEBUG_INFO("Connect success.\n");
			tv.tv_sec = 0;
			tv.tv_usec = 500000;
			setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
			socketEnable = ON;
		}

		while(socketEnable)
		{
			memset(input.buffer, 0, ARRAY_SIZE(input.buffer));
			if((input.size = recv(sockfd, input.buffer, ARRAY_SIZE(input.buffer), 0)) > 0)
			{
				if(input.size < ARRAY_SIZE(input.buffer))
				{
					//DEBUG_INFO("Receive size: %d.\n", input.size);
					for(uint16_t idx=0;idx<input.size;idx++)
					{
						if((input.buffer[idx] == ((message_header>>8) & 0xff)) && (input.buffer[idx+1] == ((message_header>>0) & 0xff)))
						{
							//DEBUG_INFO("idx: %d\n", idx);
							memset(&intputBuf.buffer[0], 0x00, ARRAY_SIZE(intputBuf.buffer));
							memcpy(&intputBuf.buffer[0], &input.buffer[idx], input.buffer[idx+2] | ((uint16_t)input.buffer[idx+3]<<8));
							intputBuf.size = input.buffer[idx+2] | ((uint16_t)input.buffer[idx+3]<<8);
							idx += (input.buffer[idx+2] | (uint16_t)input.buffer[idx+3]) -1;
							server_cmd_sn = intputBuf.buffer[10] | ((uint16_t)intputBuf.buffer[11]<<8);

							if(!checksum_valid(&intputBuf))
								DEBUG_INFO("Message checksum wrong.\n");
							else
							{
								showCmdRaw(&intputBuf, OFF);
								switch(intputBuf.buffer[6] | ((uint16_t)intputBuf.buffer[7]<<8))
								{
									case 1001:
										handle_cmd_1001(&intputBuf, &output);
										send(sockfd, output.buffer, output.size, 0);
										break;
									case 1003:
										handle_cmd_1003(&intputBuf, &output);
										send(sockfd, output.buffer, output.size, 0);
										break;
									case 1005:
										handle_cmd_1005(&intputBuf, &output);
										send(sockfd, output.buffer, output.size, 0);
										break;
									case 1101:
										handle_cmd_1101(&intputBuf);
										break;
									case 1103:
										handle_cmd_1103(&intputBuf);
										break;
									case 1105:
										handle_cmd_1105(&intputBuf);
										break;
									case 2303:
										handle_cmd_2303(&intputBuf, &output);
										send(sockfd, output.buffer, output.size, 0);
										break;
									case 2305:
										handle_cmd_2305(&intputBuf, &output);
										send(sockfd, output.buffer, output.size, 0);
										break;
								}
							}
						}
					}
				}
			}
			else if(input.size == 0)
			{
				DEBUG_INFO("Disconnected.\n");
				fflush(stdout);
				backend_info.isSignin = OFF;
				socketEnable = OFF;
			}
			else if(input.size == -1)
			{
				// Sign in reqyest
				if(!backend_info.isSignin)
				{
					create_Cmd_1106(&output);
					send(sockfd, output.buffer, output.size, 0);
				}

				// Heart beat request
				if(backend_info.isSignin && (difftime(time((time_t*)NULL), backend_info.st_hearbeat) > backend_info.interval_heartbeat))
				{
					create_Cmd_1102(&output);
					send(sockfd, output.buffer, output.size, 0);
					backend_info.st_hearbeat = time((time_t*)NULL);
					backend_info.counter_heartbeat_retry++;
				}

				// Heart beat retry fail
				if(backend_info.isSignin &&  (backend_info.counter_heartbeat_retry > backend_info.retry_heartbeat))
				{
					fflush(stdout);
					backend_info.isSignin = OFF;
					socketEnable = OFF;
					DEBUG_ERROR("Heart beat retry over count.\n");
				}
			}
			usleep(100000);
		}
		close(sockfd);
		sleep(5);
	}

	return 0;
}