/*
 * Main.c
 *
 *  Created on: 2019�~8��6��
 *      Author: 7564
 */


#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>      /*�зǿ�J��X�w�q*/
#include    <stdlib.h>     /*�зǨ�Ʈw�w�q*/
#include    <unistd.h>     /*Unix �зǨ�Ʃw�q*/
#include    <fcntl.h>      /*�ɱ���w�q*/
#include    <termios.h>    /*PPSIX �׺ݱ���w�q*/
#include    <errno.h>      /*���~���w�q*/
#include 	<errno.h>
#include 	<string.h>
#include	<time.h>
#include	<ctype.h>
#include 	<ifaddrs.h>
#include 	<math.h>
#include 	<stdbool.h>
#include 	"../../define.h"

typedef unsigned char			byte;
#define PASS				1
#define FAIL				-1
#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
#define	NO_DEFINE			255
#define DEFAULT_AC_INDEX	2

#define TTY_PATH            "/dev/tty"
#define STTY_US             "stty raw -echo -F "
#define STTY_DEF            "stty -raw echo -F "

struct SysConfigAndInfo			*ShmSysConfigAndInfo;
struct StatusCodeData 			*ShmStatusCodeData;
struct PrimaryMcuData			*ShmPrimaryMcuData;
struct CHAdeMOData				*ShmCHAdeMOData;
struct CcsData					*ShmCcsData;
struct GBTData					*ShmGBTData;
struct FanModuleData			*ShmFanModuleData;
struct RelayModuleData			*ShmRelayModuleData;
struct PsuData 					*ShmPsuData;

struct ChargingInfoData 		*_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
struct ChargingInfoData 		*ac_chargingInfo[AC_QUANTITY];

char *msg = "state : get gun state (index) \n"
		"card : scanning card (x) : \n"
		"gun : get gun plugit state (index) \n"
		"lock : get gun locked state (index) \n"
		"self : self test state (x) \n"
		"ver : ver of board (407 or index or rb or fan) \n"
		"ac : get ac relay state (x) \n";

bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
{
	for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
		{
			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
			return true;
		}
	}

	for (byte index = 0; index < CCS_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
		{
			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
			return true;
		}
	}

	for (byte index = 0; index < GB_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
		{
			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
			return true;
		}
	}

	return false;
}

bool FindAcChargingInfoData(byte target, struct ChargingInfoData **acChargingData)
{
	if (target < AC_QUANTITY)
	{
		acChargingData[target] = &ShmSysConfigAndInfo->SysInfo.AcChargingData[target];
		return true;
	}

	return false;
}

int InitShareMemory()
{
	int result = PASS;
	int MeterSMId;

	//initial ShmSysConfigAndInfo
	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
    {
		result = FAIL;
	}
    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	result = FAIL;
   	 }
    else
    {}

   	//initial ShmStatusCodeData
   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
    {
   		result = FAIL;
	}
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	result = FAIL;
   	}
    else
    {}

	if (CHAdeMO_QUANTITY > 0) {
		if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData),
		IPC_CREAT | 0777)) < 0) {
			result = FAIL;
		} else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0))
				== (void *) -1) {
			result = FAIL;
		} else {
		}
	}

	if (CCS_QUANTITY > 0) {
		if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData),
		IPC_CREAT | 0777)) < 0) {
			result = FAIL;
		} else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) {
			result = FAIL;
		} else {
		}
	}

	if (GB_QUANTITY > 0) {
		if ((MeterSMId = shmget(ShmGBTCommKey, sizeof(struct GBTData),
		IPC_CREAT | 0777)) < 0) {
			return 0;
		} else if ((ShmGBTData = shmat(MeterSMId, NULL, 0)) == (void *) -1) {
			return 0;
		}
		memset(ShmGBTData, 0, sizeof(struct GBTData));
	}

   	if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), IPC_CREAT | 0777)) < 0)
   	{
   		result = FAIL;
   	}
   	else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
   	{
   		result = FAIL;
   	}

   	if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData),	IPC_CREAT | 0777)) < 0)
   	{
   		result = FAIL;
   	}
   	else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
   	{
   		result = FAIL;
   	}

   	if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData),	IPC_CREAT | 0777)) < 0)
   	{
   		result = FAIL;
   	}
   	else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
   	{
   		result = FAIL;
   	}

   	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),	IPC_CREAT | 0777)) < 0)
   	{
   		result = FAIL;
   	}
   	else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
   	{
   		result = FAIL;
   	}

    return result;
}

void RunStatusProc(char *v1, char *v2)
{
	int _index = atoi(v1);
	if (_index <= 1)
	{
		if (!FindChargingInfoData(_index, &_chargingData[0]))
		{
			printf ("FindChargingInfoData error\n");
			return;
		}

		if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
		{
			// get
			printf ("index = %x, status = %x (%d)\n", _index, _chargingData[_index]->SystemStatus, _chargingData[_index]->IsAvailable);
			printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
					ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag, ShmSysConfigAndInfo->SysInfo.PageIndex);
		}
		else
		{
			// set
			_chargingData[_index]->SystemStatus = atoi(v2);
		}
	}
	else
	{
		if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
		{
			printf("FindChargingInfoData (AC) false \n");
		}

		if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
		{
			// get
			printf ("AC Type, status = %x (%d)\n", ac_chargingInfo[0]->SystemStatus, ac_chargingInfo[0]->IsAvailable);
		}
		else
		{
			// set
			ac_chargingInfo[0]->SystemStatus = atoi(v2);
		}
	}
}

void RunCardProc(char *v1, char *v2)
{
	if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0)
	{
		if (ShmSysConfigAndInfo->SysInfo.WaitForPlugit)
		{
			ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x00;
			printf ("SysInfo.WaitForPlugit = %x \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
		}
		else
		{
			ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x01;
			printf ("SysInfo.WaitForPlugit = %x \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
		}
	}
	else
	{
		memcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, v1, ARRAY_SIZE(v1));
		printf("StartUserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId);
	}
}

void RunGunPlugitProc(char *v1, char *v2)
{
	int _index = atoi(v1);
	if (!FindChargingInfoData(_index, &_chargingData[0]))
	{
		printf("FindChargingInfoData error\n");
		return;
	}

	if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
	{
		// get
		printf("index = %x, plug it = %x\n", _index, _chargingData[_index]->ConnectorPlugIn);
	}
	else
	{
		// set
		_chargingData[_index]->ConnectorPlugIn = atoi(v2);
	}
}

void GetGunLockStatusProc(char *v1, char *v2)
{
	int _index = atoi(v1);
	if (!FindChargingInfoData(_index, &_chargingData[0]))
	{
		printf("FindChargingInfoData error\n");
		return;
	}

	printf("Gun Locked Status = %x \n", _chargingData[_index]->GunLocked);
}

void SetSystemIDProc()
{
	char *systemId = "Alston_Test";
	memcpy(&ShmSysConfigAndInfo->SysConfig.SystemId, systemId, strlen(systemId));
}

void RunSelfProc()
{
	printf("self test status = %x\n", ShmSysConfigAndInfo->SysInfo.SelfTestSeq);
}

void GetFwVerProc(char *v1)
{
	if (strcmp(v1, "407") == 0)
	{
		printf("407 FW Version = %s \n", ShmPrimaryMcuData->version);
	}
	else if (strcmp(v1, "0") == 0)
	{
		printf("Ev board 0 FW Version = %s \n", ShmCHAdeMOData->evse[0].version);
	}
	else if (strcmp(v1, "1") == 0)
	{
		printf("Ev board 1 FW Version = %s \n", ShmCcsData->V2GMessage_DIN70121->version);
	}
	else if (strcmp(v1, "2") == 0)
	{
		printf("Ev board 2 FW Version = %s \n", ShmGBTData->evse[0].version);
	}
	else if (strcmp(v1, "rb") == 0)
	{
		printf("RB Version = %s \n", ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev);
	}
	else if (strcmp(v1, "fan") == 0)
	{
		printf("FAN Version = %s \n", ShmSysConfigAndInfo->SysInfo.FanModuleFwRev);
	}
	else if (strcmp(v1, "dc") == 0)
	{
		printf("DC Main Version = %s \n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
	}
	else if (strcmp(v1, "ac") == 0)
	{
		if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
		{
			printf("FindChargingInfoData (AC) false \n");
		}
		printf("AC Version = %s \n", ac_chargingInfo[0]->version);
	}
}

void CreateOneError(char *v1)
{
	int value = atoi(v1);

	ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = value;
	ShmSysConfigAndInfo->SysConfig.BillingData.isBilling = value;
}

void FwUpdateFlagProc()
{
	ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = 0x01;
}

void CheckAcStatus(char *v1)
{
	if (strcmp(v1, "-1") == 0|| strcmp(v1, "") == 0)
	{
		printf("AC Status = %d \n", ShmSysConfigAndInfo->SysInfo.AcContactorStatus);
	}
}

void SetCableChkStatus(char *v1, char *v2)
{
	int _index = atoi(v1);
	if (!FindChargingInfoData(_index, &_chargingData[0]))
	{
		printf ("FindChargingInfoData error\n");
		return;
	}

	_chargingData[_index]->GroundFaultStatus = atoi(v2);
}

void SetPowerValue(char *v1, char *v2)
{
	int _index = atoi(v1);
	float _Current = atof(v2);
	// ���R���ɭԤ~���\�ϥ�~
	if (_chargingData[_index]->Type != 9)
		return;

	if (!FindChargingInfoData(_index, &_chargingData[0]))
	{
		printf ("FindChargingInfoData error\n");
		return;
	}

	_chargingData[_index]->EvBatterytargetCurrent = _Current * 10;
}

void GetSystemInfo()
{
	printf ("ModelName = %s \n", ShmSysConfigAndInfo->SysConfig.ModelName);
	printf ("MaxChargingPower = %d, MaxChargingCurrent = %d \n",
			ShmSysConfigAndInfo->SysConfig.MaxChargingPower,
			ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
}

void ChangeGunNum()
{
	if (ShmSysConfigAndInfo->SysInfo.CurGunSelected + 1 < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount)
	{
		ShmSysConfigAndInfo->SysInfo.CurGunSelected += 1;
		ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE;
	}
	else if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 &&
			ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == NO_DEFINE)
		ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
	else
	{
		ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0;
		ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE;
	}
}

void GetGunSelectedNum(char *v1)
{
	if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0)
	{
		if (AC_QUANTITY > 0 &&
			ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE)
		{
			printf("connector select changed = AC \n");
		}
		else
			printf("connector selected = %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected);
	}
	else
	{
		int _index = atoi(v1);
		if (_index <= 1)
		{
			ShmSysConfigAndInfo->SysInfo.CurGunSelected = _index;
			ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE;
			printf("connector select changed = %d \n", _index);
		}
		else if (AC_QUANTITY > 0)
		{
			ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
			printf("connector select changed = AC \n");
		}
	}
}

void SetFanSpeed(char *v1)
{
	int speed = atoi(v1);

	ShmFanModuleData->TestFanSpeed = speed;
}

void GetFanSpeed()
{
	printf("ShmFanModuleData->PresentFan1Speed = %d \n", ShmFanModuleData->PresentFan1Speed);
	printf("ShmFanModuleData->PresentFan2Speed = %d \n", ShmFanModuleData->PresentFan2Speed);
	printf("ShmFanModuleData->PresentFan3Speed = %d \n", ShmFanModuleData->PresentFan3Speed);
	printf("ShmFanModuleData->PresentFan4Speed = %d \n", ShmFanModuleData->PresentFan4Speed);
}

void SetDebugMode(char *v1)
{
	int mode = atoi(v1);

	ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag = mode;
}

void SetGFDMode(char *v1)
{
	int mode = atoi(v1);

	ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag = mode;
}

void GetPsuTemp()
{
	for (byte index = 0; index < ShmPsuData->GroupCount; index++)
	{
		for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
		{
			printf("PSU Temp = %d \n", ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp);
		}
	}
}

void GetAcInputVol()
{
	printf("L1N_L12 = %f, L2N_L23 = %f, L3N_L31 = %f \n",
			ShmSysConfigAndInfo->SysInfo.InputVoltageR,
			ShmSysConfigAndInfo->SysInfo.InputVoltageS,
			ShmSysConfigAndInfo->SysInfo.InputVoltageT);
}

void GetPsuInformation(char *v1)
{
	printf("**********************AC Contact needed*************************\n");
	if(strcmp(v1, "count") == 0)
	{
		for (int i = 0; i < 4; i++)
		{
			printf("Group Index = %d, Module Count = %d \n", i, ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity);
		}
	}
	else if(strcmp(v1, "ver") == 0)
	{
		for (int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++)
		{
			printf("Psu Index = %d, PriVersion = %s, SecVersion = %s \n",
					i, ShmPsuData->PsuVersion[i].FwPrimaryVersion, ShmPsuData->PsuVersion[i].FwSecondVersion);
		}

		for (int i = 0; i < ShmPsuData->GroupCount; i++)
		{
			for (int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++)
			{
				printf("Group Index = %d, Psu Index = %d, Version = %s \n",
					i, j, ShmPsuData->PsuGroup[i].PsuModule[j].FwVersion);
			}
		}
	}
	else if(strcmp(v1, "cap") == 0)
	{
		for (int i = 0; i < ShmPsuData->GroupCount; i++)
		{
			printf("Group Index = %d, MaxCur = %d, Power = %d \n",
					i, ShmPsuData->PsuGroup[i].GroupAvailableCurrent, ShmPsuData->PsuGroup[i].GroupAvailablePower);
		}
	}
	else if (strcmp(v1, "output") == 0)
	{
		for (int i = 0; i < ShmPsuData->GroupCount; i++)
		{
			printf("Group Index = %d, OutputV = %d, OutputC = %d \n",
					i, ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage, ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent);
		}
	}
	printf("*************************************************\n");
}

void GetConnectorCapInfo(char *v1)
{
	int _GunIndex = atoi(v1);

	if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
	{
		printf ("FindChargingInfoData error\n");
		return;
	}

	printf ("Charger Max Current = %d, Max Power = %d \n",
			ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10,
			ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10);

	printf ("Index = %d, MaxPow = %f, MaxVol = %f, MaxCur = %f\n",
			_GunIndex,
			_chargingData[_GunIndex]->RealMaxPower,
			_chargingData[_GunIndex]->RealMaxVoltage,
			_chargingData[_GunIndex]->RealMaxCurrent);
}

static void get_char(char *word)
{
    fd_set rfds;
    struct timeval tv;

    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    tv.tv_sec = 0;
    tv.tv_usec = 10; //wait input timout time

    //if input
    if (select(1, &rfds, NULL, NULL, &tv) > 0)
    {
    	fgets(word, 128, stdin);
    }
}

void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
{
	int _GunIndex = atoi(v1);
	float _Voltage = atof(v2);
	float _Current = atof(v3);
	unsigned char PreviousSystemStatus = 0xff;

	if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
	{
		printf ("FindChargingInfoData error\n");
		return;
	}

    printf ("ReqVoltage = %f, ReqCurrent = %f\n", _Voltage, _Current);

    if(_Voltage > 1000 || _Voltage < 50)
    {

        printf ("Input Voltage over range\n");
        return;
    }

//    if(_Current > 100 || _Current < 2){
//
//        printf ("Input Current over range\n");
//        return;
//    }

    //���մ��������L�ۧڴ��� _STEST_COMPLETE = 0xfe
    //ShmSysConfigAndInfo->SysInfo.SelfTestSeq = 0xfe;

    //kill ev task
    system("killall Module_EvComm");

    _Voltage = (_Voltage * 10);
    _Current = (_Current * 10);

    //system(STTY_US TTY_PATH);

    while(true)
    {
        //fix gun 1
        ShmSysConfigAndInfo->SysInfo.CurGunSelected = _GunIndex;

    	switch(_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
    	{
            case S_IDLE:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;

        	        printf ("[UnconditionalCharge - S_IDLE]\n");

        	    }

        	    ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = 0x01;
                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_PREPARNING;
    		}
    		break;


    		case S_PREPARNING:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;

        	        printf ("[UnconditionalCharge - S_PREPARNIN]\n");

        	        //���� AC Relay �f�W�B���Ҳ� (main �b�� statue �䥦 task �|�h����)
        	        printf ("wait find module\n");

        	    }
    		    //main �|�b�����q�P�_�H�U��Ƹ���U�@�� state
    		    //�Ψӱo�� AC �O�_���f�W (�f�W�Ҳժ���T�~�|�X��) �]���C��  AC_Contactor


    		    //ShmPsuData->SystemPresentPsuQuantity;
    		    //ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity;
    		    //ShmPsuData->PsuGroup[gun_index].GroupAvailablePower;
    		    //_chargingData[gun_index]->AvailableChargingPower;

    		    //���� AC Relay �f�W�B���Ҳ� (main �b�� statue �䥦 task �|�h����)
    		    //sleep(10);

    		    //�M�� main timeout ����
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->TimeoutFlag = 0;
    		    //���׬O���� type ���j���T�N�]�� Chademo ���] Prechage step
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->Type = 9;

    		}
    		break;

    		case S_PREPARING_FOR_EV:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;

        	        printf ("[UnconditionalCharge - S_PREPARING_FOR_EV]\n");
        	        printf ("ReqVoltage = %f, ReqCurrent = %f \n", _Voltage,_Current);

        	    }
    		    //�M�� main timeout ����
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->TimeoutFlag = 0;
    		    //���׬O���� type ���j���T�N�]�� Chademo ���] Prechage step
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->Type = 9;

    		    //�R�q�q���q�y
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
   		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = 5000;
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = 20;
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;

    		    //****** �`�N~���欰�O���� K1K2 ���}�ɨ�L�k���� ( Relay Board �b�� state �٥��f�W K1K2 )
    		    //�T�w�Ҳդv��������
    		    //if(_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage <=  (3000+500) &&
    		    //  _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage >=  (3000-500) )
    		    {
    		        printf ("Precharge Done = %f \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage);
    		        //EV done
    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_PREPARING_FOR_EVSE;
    		    }

    		}
    		break;


    		case S_PREPARING_FOR_EVSE:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;

        	        printf ("[UnconditionalCharge - S_PREPARING_FOR_EVSE]\n");

        	    }
        	    //printf ("tar vol = %d \n", _Voltage);
        	    //printf ("tar cur = %d \n", _Current);

    		    //�M�� main timeout ����
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->TimeoutFlag = 0;
    		    //���׬O���� type ���j���T�N�]�� Chademo ���] Prechage step
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->Type = 9;

    		    //�R�q�q���q�y
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = 5000;
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = 20;
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;

    		    //printf ("tar vol_ = %d \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage);
        	   // printf ("tar cur_ = %d \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent);

    		    //****** �`�N~���欰�O���� K1K2 ���}�ɨ�L�k���� ( Relay Board �b�� state �٥��f�W K1K2 )
    		    //�T�w�Ҳդv��������
    		    if(_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x01 ||
    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x03)
    		    {
    		        printf ("First Ground Fault State (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
    		        printf ("Wait K1K2 = %f \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage);
    		        sleep(5);
    		        //EV done
    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_CHARGING;
    		    }
    		    else if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus > 0x02)
    		    {
    		        printf ("First Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
    		    }

    		}
    		break;

    		case S_CHARGING:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;

        	        //�R�q�q���q�y
        	        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
        	        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
        	        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
        	        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;

        	        printf ("[UnconditionalCharge - S_CHARGING]\n");
        	    }

    		    //ev task do this
    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower =
    		    		((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent)) / 1000);

    		    if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x02){
    		         printf ("Charging Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
    		    }

    		    if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x03){
    		         printf ("Charging Ground Fault Warning (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
    		    }

    		}
    		break;

     		case S_TERMINATING:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
        	        system("/root/Module_EvComm &");

        	        printf ("[UnconditionalCharge - S_TERMINATING]\n");
        	        //�L���밻�� keybaord ����
        	        system(STTY_DEF TTY_PATH);

        	    }

        	    sleep(3);
        	    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_COMPLETE;
        	    return;
    		}
    		break;

    		case S_COMPLETE:
    		{
        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
        	    {
        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;

        	        printf ("[UnconditionalCharge - S_COMPLETE]\n");
        	    }
        	    sleep(3);
        	    return;
    		}
    		break;
    	}

    	char word[128];
    	char newString[7][10];
    	int i,j,ctr;

    	memset(word, 0x00, sizeof(word));
    	get_char(word);

    	if (strlen(word) == 0)
    		continue;

    	j=0; ctr=0;
    	strcpy(newString[1], "-1");
    	strcpy(newString[2], "-1");
    	for (i = 0; i <= (strlen(word)); i++)
    	{
    		if (word[i] == ' ' || word[i] == '\0' || word[i] == 10)
    		{
    			newString[ctr][j] = '\0';
    			ctr++;
    			j = 0;
    		}
    		else
    		{
    			newString[ctr][j] = word[i];
    			j++;
    		}
    	}

    	if(strcmp(newString[0], "chg") == 0)
    	{
    		if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
    		   continue;
    		if (strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
    		   continue;

    		float _vol = atof(newString[1]);
    		float _cur = atof(newString[2]);

    		if (_cur <= 0 || _cur <= 0)
    		   continue;

    		printf("vol = %f, cur = %f \n", _vol, _cur);
    		_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _vol * 10;
    		_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _cur * 10;
    	}
    	else if (strcmp(newString[0], "c") == 0)
    	{
    		printf("stop \n\r");
    		ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = 0x00;
    		_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
    	}

    	usleep(100000);
    }
}

int main(void)
{
	if(InitShareMemory() == FAIL)
	{
		printf ("InitShareMemory = FAIL \n");
		if(ShmStatusCodeData != NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
		}
		sleep(5);
		return 0;
	}

	for(;;)
	{
		char word[128];
		char newString[7][10];
		int i,j,ctr;

		fgets(word, sizeof(word), stdin);

		j=0; ctr=0;
		strcpy(newString[1], "-1");
		strcpy(newString[2], "-1");
		for (i = 0; i <= (strlen(word)); i++)
		{
			if (word[i] == ' ' || word[i] == '\0' || word[i] == 10)
			{
				newString[ctr][j] = '\0';
				ctr++;
				j = 0;
			}
			else
			{
				newString[ctr][j] = word[i];
				j++;
			}
		}

		if(strcmp(newString[0], "state") == 0)
		{
			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
				continue;

			// �j���A
			RunStatusProc(newString[1], newString[2]);
		}
		else if(strcmp(newString[0], "card") == 0)
		{
			// ��d���A
			RunCardProc(newString[1], newString[2]);
		}
		else if(strcmp(newString[0], "gun") == 0)
		{
			if (strcmp(newString[1], "-1") == 0	|| strcmp(newString[1], "") == 0)
				continue;

			// ���j���A
			RunGunPlugitProc(newString[1], newString[2]);
		}
		else if(strcmp(newString[0], "lock") == 0)
		{
			if (strcmp(newString[1], "-1") == 0	|| strcmp(newString[1], "") == 0)
				continue;

			// ���j���A
			GetGunLockStatusProc(newString[1], newString[2]);
		}
		else if(strcmp(newString[0], "sysid") == 0)
		{
			// ���� sys id
			SetSystemIDProc();
		}
		else if(strcmp(newString[0], "self") == 0)
		{
			// CSU �ۧ��˴����A
			RunSelfProc(newString[1]);
		}
		else if(strcmp(newString[0], "ver") == 0)
		{
			if (strcmp(newString[1], "-1") == 0	|| strcmp(newString[1], "") == 0)
				continue;
			// �� FW ����
			GetFwVerProc(newString[1]);
		}
		else if (strcmp(newString[0], "update") == 0)
		{
			// ��s
			FwUpdateFlagProc(newString[1]);
		}
		else if (strcmp(newString[0], "ac") == 0)
		{
			// AC contactor ���A
			CheckAcStatus(newString[1]);
		}
		else if (strcmp(newString[0], "cable") == 0)
		{
			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
				continue;
			// cable check pass
			SetCableChkStatus(newString[1], newString[2]);
		}
		else if (strcmp(newString[0], "pow") == 0)
		{
			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
				continue;
			// cable check pass
			SetPowerValue(newString[1], newString[2]);
		}
		else if (strcmp(newString[0], "model") == 0)
		{
			GetSystemInfo();
		}
		else if(strcmp(newString[0], "select") == 0)
		{
			// ���o / �]�w ���e�諸�j��
			GetGunSelectedNum(newString[1]);
		}
		else if(strcmp(newString[0], "change") == 0)
		{
			// �������s���ܿ�j
			ChangeGunNum();
		}
		else if(strcmp(newString[0], "fan") == 0)
		{
			// �]�w�����t��
			SetFanSpeed(newString[1]);
		}
		else if(strcmp(newString[0], "speed") == 0)
		{
			// ���o�����t��
			GetFanSpeed();
		}
		else if(strcmp(newString[0], "debug") == 0)
		{
			// �]�w debug mode
			SetDebugMode(newString[1]);
		}
		else if (strcmp(newString[0], "gfd") == 0)
		{
			// �]�w���R�ϥ� GFD �\��
			SetGFDMode(newString[1]);
		}
		else if(strcmp(newString[0], "temp") == 0)
		{
			// ���o PSU �ū�
			GetPsuTemp();
		}
		else if(strcmp(newString[0], "acin") == 0)
		{
			// ���o�T�V��J�q��
			GetAcInputVol();
		}
		else if(strcmp(newString[0], "psu") == 0)
		{
			//�p�G�s�@�ӰѼƳ��S�� (���R�O���z�|) �[�W�P�_�ĤG�Ѽ�
			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
			{
				printf ("PSU : Param fail..Please retry again......\n");
				continue;
			}

			// ���o PSU ��T
			GetPsuInformation(newString[1]);
		}
		else if (strcmp(newString[0], "cap") == 0)
		{
			GetConnectorCapInfo(newString[1]);
		}
		else if(strcmp(newString[0], "error") == 0)
		{
			CreateOneError(newString[1]);
		}
		else if(strcmp(newString[0], "strchg") == 0)
		{
			//�p�G�s�@�ӰѼƳ��S�� (���R�O���z�|) �[�W�P�_�ĤG�Ѽ�
			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
					strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
			{
				printf ("Input cmd fail ------  strchg [vol 150-1000] [cru 2-100]\n");
				continue;
			}

			// �j���A
			RunUnconditionalChargeIndex1(newString[1], newString[2], newString[3]);
		}
		else
			printf ("%s\n", msg);
		usleep(100000);
	}

	return 0;
}