/*
 * Module_ChargerSelfTest.c
 *
 *  Created on: 2021年9月24日
 *      Author: 7978
 */

#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/can.h>
#include    <linux/can/raw.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>     /*Unix 標準函數定義*/
#include    <fcntl.h>      /*檔控制定義*/
#include    <termios.h>    /*PPSIX 終端控制定義*/
#include    <errno.h>      /*錯誤號定義*/
#include    <errno.h>
#include    <string.h>
#include    <time.h>
#include    <ctype.h>
#include    <ifaddrs.h>
#include    <signal.h>
#include    <net/if_arp.h>
#include    "../../define.h"
#include    "Module_ChargerSelfTest.h"
#include    "Config.h"
#include    "Common.h"

#define     SELFTEST_TIMEOUT        60                  // unit: 1s
#define     VERSION_RETRY_TIMEOUT   180                 // unit: 1s
#define     CABINET_ROLE_TIMEOUT    3                   // unit: 1s
#define     PSU_SELF_TIMEOUT        60                  // unit: 1s
#define     PSU_RETRY_TIMEOUT       60                  // unit: 1s
#define     MAX_PSU_RETRY_CNT       3
#define     EMG_BTN_INTERVAL        1                   // unit: 1s

struct SysConfigAndInfo         *ShmSysConfigAndInfo;
struct StatusCodeData           *ShmStatusCodeData;
struct PsuData                  *ShmPsuData;
struct PrimaryMcuData           *ShmPrimaryMcuData;
struct FanModuleData            *ShmFanModuleData;
struct RelayModuleData          *ShmRelayModuleData[2];
struct LedModuleData            *ShmLedModuleData;
ChargerInfoData                 *ShmChargerInfo;
PsuGroupCollectionData          *ShmGroupCollection;
struct OCPP16Data               *ShmOCPP16Data;
struct OCPP20Data               *ShmOCPP20Data;

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

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

    }

    // initial status code share memory
    if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("[main]CreatShareMemory:shmget ShmStatusCodeData NG");
        #endif
        return 0;
    }
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("[main]CreatShareMemory:shmat ShmStatusCodeData NG");
        #endif
        return 0;
    }

    // initial psu share memory
    if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmget ShmPsuData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmPsuData NG");
        #endif
        result = FAIL;
    }

    // initial DO360 RC1 share memory
    if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmget ShmRelayModuleData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmRelayModuleData[0] = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmRelayModuleData NG");
        #endif
        result = FAIL;
    }

    // initial DO360 RC2 share memory
    if ((MeterSMId = shmget(ShmRelay2BdKey, sizeof(struct RelayModuleData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmget ShmRelay2ModuleData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmRelayModuleData[1] = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmRelay2ModuleData NG");
        #endif
        result = FAIL;
    }

    // initial fan board share memory
    if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmget ShmFanModuleData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmFanModuleData NG");
        #endif
        result = FAIL;
    }

    // initial led board share memory
    if ((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmget ShmLedModuleData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmLedModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmLedModuleData NG");
        #endif
        result = FAIL;
    }

    // initial primary share memory
    if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmget ShmPrimaryMcuData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmPrimaryMcuData NG");
        #endif
        result = FAIL;
    }

    if ((MeterSMId = shmget(SM_ChargerInfoKey, sizeof(ChargerInfoData), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ChargerInfoData NG");
        #endif
        result = FAIL;
    }
    else if ((ShmChargerInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ChargerInfoData NG");
        #endif
        result = FAIL;
    }

    if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("shmat ShmOCPP16Data NG");
        #endif
        result = FAIL;
    }
    else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        LOG_ERROR("shmat ShmOCPP16Data NG");
        result = FAIL;
    }

    if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), 0777)) < 0)
    {
        LOG_ERROR("[main]CreatShareMemory:shmget OCPP20Data NG\n");
        result = FAIL;
    }
    else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
        LOG_ERROR("[main]CreatShareMemory:shmat OCPP20Data NG\n");
        result = FAIL;
    }

    if(result == PASS)
    {
        ShmGroupCollection = &ShmChargerInfo->PsuGrouping.GroupCollection[0];
    }

    return result;
}

void SetSelfTestSate(unsigned char selfTest)
{
    if(ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE || selfTest == _STEST_FAIL)
    {
        ShmSysConfigAndInfo->SysInfo.SelfTestSeq = selfTest;
    }
    ShmChargerInfo->Control.SelfTestStep = selfTest;
}

int main(void)
{
    if(InitShareMemory() == FAIL)
    {
        #ifdef SystemLogMessage
        LOG_ERROR("InitShareMemory NG");
        #endif

        sleep(5);
        return 0;
    }

    bool _selfTestTimeout = false, _versionCheck = false, _switchCheck = false, _emgBtn = false;
    char _selfTest = 0, _preTest = -1, psuRetryCnt = 0;
    struct timespec _SelfTest_time, _TestStep_time;

    LOG_INFO("Charger Start Self Test...");
    ShmChargerInfo->Control.SysCtrl.bits.NeedSelfTest = YES;
    GetClockTime(&_SelfTest_time);
    ShmChargerInfo->Control.SelfTestStep = ShmSysConfigAndInfo->SysInfo.SelfTestSeq != _STEST_FAIL ?
        ShmSysConfigAndInfo->SysInfo.SelfTestSeq : _STEST_VERSION;

    while(1)
    {
        if(!ShmChargerInfo->Control.SysCtrl.bits.NeedSelfTest)
        {
            sleep(1);
            continue;
        }

        if(!_selfTestTimeout && ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE)
        {
            if(ShmSysConfigAndInfo->SysInfo.FirmwareUpdate == YES || ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq == YES)
            {
                _selfTestTimeout = true;
                LOG_INFO("Charger need firmware upgrade, stop self test!");
            }
            else if(ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL)
            {
                _selfTestTimeout = true;
                _emgBtn = true;
                LOG_INFO("Emergency button is pressed, stop self test!");
            }
        }

        if(ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
        {
            if(ShmSysConfigAndInfo->SysInfo.SelfTestSeq != _STEST_COMPLETE)
            {
                ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_COMPLETE;
                ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE;

                for(int i = 0; i < CONNECTOR_QUANTITY; i++)
                {
                    ShmChargerInfo->Control.GunAvailable[i] = YES;
                }
                LOG_INFO("Self Test Pass In Simulation Mode!");
            }
            sleep(1);
            continue;
        }

        _selfTest = ShmChargerInfo->Control.SelfTestStep;

        switch(_selfTest)
        {
            case _STEST_VERSION:
                if(_preTest != _selfTest)
                {
                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [VersionTest]");
                }

                if ((ShmChargerInfo->Control.SysCtrl.bits.FanBoardDisable || ShmFanModuleData->SelfTest_Comp) &&
                    (ShmChargerInfo->Control.SysCtrl.bits.RelayBoardDisable || ShmRelayModuleData[0]->SelfTest_Comp) &&
                    (ShmChargerInfo->Control.SysCtrl.bits.RelayBoardDisable ||
                    ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable == false ||
                    ShmRelayModuleData[1]->SelfTest_Comp) &&
                    ShmPrimaryMcuData->SelfTest_Comp)
                {
                    _versionCheck = true;

                    if(!_switchCheck)
                    {
                        SetSelfTestSate(_STEST_CabinetSwitch);
                        LOG_INFO("Self test version check ok");
                    }
                    else
                    {
                        // bypass cabinet switch detection
                        SetSelfTestSate(_STEST_FAIL);
                        LOG_INFO("VersionTest OK, Soft Reset And Retry!");
                    }
                }
                else
                {
                    if(_selfTestTimeout)
                    {
                        if(_switchCheck)
                        {
                            // self test timeout, set status code for timeout reason
                            if(!ShmChargerInfo->Control.SysCtrl.bits.FanBoardDisable && !ShmFanModuleData->SelfTest_Comp)
                            {
                                if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FanboardStestFail == NO)
                                {
                                    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FanboardStestFail = YES;
                                    LOG_INFO("FanBoard Self Test Fail!");
                                }
                            }

                            if((!ShmChargerInfo->Control.SysCtrl.bits.RelayBoardDisable && !ShmRelayModuleData[0]->SelfTest_Comp) ||
                            (!ShmChargerInfo->Control.SysCtrl.bits.RelayBoardDisable && ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable && !ShmRelayModuleData[1]->SelfTest_Comp))
                            {
                                if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RelayboardStestFail == NO)
                                {
                                    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RelayboardStestFail = YES;
                                    LOG_INFO("RelayBoard Self Test Fail!");
                                }
                            }

                            if(!ShmPrimaryMcuData->SelfTest_Comp)
                            {
                                if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail == NO)
                                {
                                    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = YES;
                                    LOG_INFO("Primary Self Test Fail!");
                                }
                            }

                            if(ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE)
                            {
                                LOG_INFO("Booting Completed, Version Self Test Fail!");
                            }
                            ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL;
                            ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE;

                            if(GetTimeoutValue(_TestStep_time) / uSEC_VAL >= VERSION_RETRY_TIMEOUT)
                            {
                                // bypass cabinet switch detection
                                SetSelfTestSate(_STEST_FAIL);
                                LOG_INFO("Version check still timeout, try soft reset and retry!");
                            }
                        }
                        else
                        {
                            SetSelfTestSate(_STEST_CabinetSwitch);
                            LOG_INFO("Version Self Test Timeout, Need Check Cabinet Switch Value");
                        }
                    }
                }
                break;

            case _STEST_CabinetSwitch:
                if(_preTest != _selfTest)
                {
                    ShmChargerInfo->Control.PrimaryCtrl.bits.CabinetSwitchDetect = YES;
                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [SwitchDetect]");
                }

                if(GetTimeoutValue(_TestStep_time) / uSEC_VAL >= CABINET_ROLE_TIMEOUT)
                {
                    _switchCheck = true;

                    char *str_cabinet_role[] = {STR_CABINET_ROLE_NONE, STR_CABINET_ROLE_MASTER, STR_CABINET_ROLE_SLAVE};

                    ShmChargerInfo->Control.CabinetRole = ShmChargerInfo->Control.CabinetSwitch <= _CROLE_SLAVE ?
                        ShmChargerInfo->Control.CabinetSwitch : _CROLE_SINGLE;

                    //ShmChargerInfo->Control.CabinetRole = _CROLE_MASTER;
                    //ShmChargerInfo->Control.CabinetRole = _CROLE_SLAVE;

                    ShmChargerInfo->Control.PrimaryCtrl.bits.CabinetSwitchDetect = NO;
                    LOG_INFO("Cabinet Role: [%s], Switch Value: %d",
                        ShmChargerInfo->Control.CabinetRole <= _CROLE_SLAVE ? str_cabinet_role[ShmChargerInfo->Control.CabinetRole] : "Unknown",
                        ShmChargerInfo->Control.CabinetSwitch);

                    if(_versionCheck)
                    {
                        if(!_emgBtn)
                        {
                            if(ShmChargerInfo->Control.CabinetRole == _CROLE_SLAVE)
                            {
                                SetSelfTestSate(_STEST_COMPLETE);
                            }
                            else
                            {
                                if(!ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputUVP)
                                {
                                    SetSelfTestSate(_STEST_PSU_DETECT);
                                }
                                else
                                {
                                    LOG_INFO("DC Input UVP, Bypass PSU Self-Test");
                                    SetSelfTestSate(_STEST_COMPLETE);
                                }
                            }
                        }
                        else
                        {
                            SetSelfTestSate(_STEST_EMG_BTN);
                        }
                    }
                    else
                    {
                        if(!_emgBtn)
                        {
                            SetSelfTestSate(_STEST_VERSION);
                        }
                        else
                        {
                            SetSelfTestSate(_STEST_EMG_BTN);
                        }
                    }
                }
                break;

            case _STEST_AC_CONTACTOR:
                if(_preTest != _selfTest)
                {
                    ShmChargerInfo->Control.RelayCtrl.bits.AcContactor = ON;

                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [AcContactor]");
                }

                SetSelfTestSate(_STEST_PSU_DETECT);
                break;

            case _STEST_PSU_DETECT:
                if(_preTest != _selfTest)
                {
                    ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK = NO;
                    ShmChargerInfo->Control.PsuCtrl.bits.NeedSelfTest = YES;
                    ShmChargerInfo->Control.RelayCtrl.bits.AcContactor = ON;

                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [PsuDetect]");
                }

                if(ShmPsuData->Work_Step >= GET_SYS_CAP)
                {
                    SetSelfTestSate(_STEST_PSU_CAP);
                }
                else
                {
                    if(_emgBtn)
                    {
                        SetSelfTestSate(_STEST_EMG_BTN);
                        break;
                    }

                    if(_selfTestTimeout)
                    {
                        // self test timeout, set status code for timeout reason
                        if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail == NO)
                        {
                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail = YES;
                            if(!ShmSysConfigAndInfo->SysInfo.AcContactorStatus)
                            {
                                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcContactStestFail = YES;
                                LOG_INFO("Ac Contactor Self Test Fail!");
                            }
                            LOG_INFO("PSU Self Test Fail!");
                        }

                        if(ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE)
                        {
                            LOG_INFO("Booting Completed, PSU Self Test Fail!");
                        }
                        ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL;
                        ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE;

                        if(GetTimeoutValue(_TestStep_time) / uSEC_VAL >= PSU_SELF_TIMEOUT)
                        {
                            SetSelfTestSate(_STEST_PSU_RETRY);
                        }
                    }
                }
                break;

            case _STEST_PSU_CAP:
                if(_preTest != _selfTest)
                {
                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [PsuCapability]");
                }

                if(ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK == YES)
                {
                    SetSelfTestSate(_STEST_COMPLETE);
                }
                else
                {
                    if(_emgBtn)
                    {
                        SetSelfTestSate(_STEST_EMG_BTN);
                        break;
                    }

                    if(_selfTestTimeout)
                    {
                        // self test timeout, set status code for timeout reason
                        if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail == NO)
                        {
                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail = YES;
                            LOG_INFO("PSU Self Test Fail!");
                        }

                        if(ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE)
                        {
                            LOG_INFO("Booting Completed, PSU Self Test Fail!");
                        }
                        ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL;
                        ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE;
                    }

                    if(GetTimeoutValue(_TestStep_time) / uSEC_VAL >= PSU_SELF_TIMEOUT)
                    {
                        SetSelfTestSate(_STEST_PSU_RETRY);
                    }
                }
                break;

            case _STEST_PSU_RETRY:
                if(_preTest != _selfTest)
                {
                    psuRetryCnt++;
                    ShmChargerInfo->Control.RelayCtrl.bits.AcContactor = OFF;

                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [PsuRetry]");
                }

                if(_emgBtn)
                {
                    SetSelfTestSate(_STEST_EMG_BTN);
                    break;
                }

                if(psuRetryCnt > MAX_PSU_RETRY_CNT)
                {
                    SetSelfTestSate(_STEST_FAIL);
                }

                if(GetTimeoutValue(_TestStep_time) / uSEC_VAL >= (PSU_RETRY_TIMEOUT))
                {
                    SetSelfTestSate(_STEST_PSU_DETECT);
                }
                break;

            case _STEST_EMG_BTN:
                if(_preTest != _selfTest)
                {
                    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = true;

                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [EmgBtn Fail]");
                }
                ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL;
                ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE;

                if(GetTimeoutValue(_TestStep_time) / uSEC_VAL >= EMG_BTN_INTERVAL)
                {
                    if(ShmPrimaryMcuData->InputDet.bits.EmergencyButton == NORMAL)
                    {
                        // bypass cabinet switch detection
                        SetSelfTestSate(_STEST_FAIL);
                        LOG_INFO("Emergency button recover, Soft Reset!");
                    }
                    GetClockTime(&_TestStep_time);
                }
                break;

            case _STEST_FAIL:
                if(_preTest != _selfTest)
                {
                    GetClockTime(&_TestStep_time);
                    LOG_INFO("SelfTest Process [SelfTestFail]");
                }

                // stop here
                // self test fail, need soft reset
                ShmChargerInfo->Control.SysCtrl.bits.NeedSoftReset = true;
                break;

            case _STEST_COMPLETE:
                if(_preTest != _selfTest)
                {
                    LOG_INFO("SelfTest Process [SelfTestDone]");
                }

                if(ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE)
                {
                    ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE;
                }

                if(_selfTestTimeout)
                {
                    // stop here
                    // self test completed but timeout, need soft reset
                    ShmChargerInfo->Control.SysCtrl.bits.NeedSoftReset = true;
                }
                break;

            default:
                if(_preTest != _selfTest)
                {
                    LOG_INFO("SelfTest Process [Unknown]");
                }
                SetSelfTestSate(_STEST_VERSION);
                break;
        }

        if(ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE)
        {
            if(GetTimeoutValue(_SelfTest_time) / uSEC_VAL >= SELFTEST_TIMEOUT)
            {
                _selfTestTimeout = true;
            }
        }

        _preTest = _selfTest;
        usleep(10000);
    }

    return 0;
}