

#include "iec101.h"
#include "iec10x_conf.h"
#include "iec10x_type.h"

#ifdef IEC101_SET
/*
 * GLOABLE VARIALBLE
 */
iec_8u Iec101_Respon_Confirm = 0;
iec_8u Iec101_Sendbuf[IEC101_MAX_BUF_LEN];

iec_8u  IEC10X_Call_AllQoi   = 0;
iec_8u  IEC10X_Call_GroupQoi = 0;
iec_16u IEC101_Pulse_Cnt     = 0;

/*
 * STATE
 * */
iec_8u IEC101_STATE_FLAG_INIT    = IEC101_FLAG_LINK_CLOSED;
iec_8u IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_CLOSED;
iec_8u IEC101_STATE_FLAG_GROUP   = IEC101_FLAG_LINK_CLOSED;
iec_8u IEC101_STATE_FLAG_CLOCK   = IEC101_FLAG_LINK_CLOSED;
iec_8u IEC101_STATE_FLAG_DELAY   = IEC101_FLAG_LINK_CLOSED;
iec_8u IEC101_STATE_FLAG_PULSE   = IEC101_FLAG_LINK_CLOSED;

iec_8u IEC10X_RetStatusOk(iec_16u addr)
{

    iec_16u      len;
    PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;

    len = IEC101_STABLE_LEN;

    Iec10x->_begin = IEC101_STABLE_BEGING;

    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_SLAVE;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CAN_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_RES_LINK_STATUS;

    Iec10x->_addr = addr;
    Iec10x->_cs   = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
    Iec10x->_end  = IEC101_STABLE_END;

    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);

    return RET_SUCESS;
}
static iec_8u IEC10X_ResConfirm(iec_8u Prio)
{

    iec_16u len;

    PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;

    len = IEC101_STABLE_LEN;

    Iec10x->_begin = IEC101_STABLE_BEGING;

    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_SLAVE;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CAN_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_RES_CONFIRM;

    Iec10x->_addr = Iec10x_Sta_Addr;
    Iec10x->_cs   = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
    Iec10x->_end  = IEC101_STABLE_END;

    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);

    return RET_SUCESS;
}
iec_8u IEC10X_ReqLinkStatus()
{

    iec_16u len;

    PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;

    LOG("%s \n", __FUNCTION__);

    len = IEC101_STABLE_LEN;

    Iec10x->_begin = IEC101_STABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.down._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.down._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.down._fcb = IEC101_CTRL_FCB_OPPO_NONE;
    Iec10x->_ctrl.down._fcv = IEC101_CTRL_FCV_DISABLE;

    Iec10x->_ctrl.up._func = IEC101_CTRL_REQ_LINK_STATUS;

    Iec10x->_addr = Iec10x_Sta_Addr;
    Iec10x->_cs   = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
    Iec10x->_end  = IEC101_STABLE_END;

    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);

    return RET_SUCESS;
}

iec_8u IEC10X_ResetLink(void)
{

    iec_16u len;

    PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;

    len = IEC101_STABLE_LEN;

    Iec10x->_begin = IEC101_STABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.down._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.down._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.down._fcb = IEC101_CTRL_FCB_OPPO_NONE;
    Iec10x->_ctrl.down._fcv = IEC101_CTRL_FCV_DISABLE;

    Iec10x->_ctrl.up._func = IEC101_CTRL_RESET_LINK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    Iec10x->_cs   = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
    Iec10x->_end  = IEC101_STABLE_END;

    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);

    return RET_SUCESS;
}

iec_8u IEC101_BuildFinInit(void)
{

    iec_16u len     = 0;
    iec_8u  cs_temp = 0, i;

    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = Iec10x_M_EI_NA_1;
    asdu->_num._num       = 1;
    asdu->_reason._reason = IEC10X_ASDU_REASON_INIT;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr       = IEC10X_INFO_ADDR_NONE;
    info->_element[0] = 0;

    /*len*/
    len          = IEC101_VARIABLE_LEN + asdu->_num._num;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);

    return RET_SUCESS;
}
iec_8u IEC101_BuildActConfirm(iec_8u qoi, iec_8u Prio)
{

    iec_16u len     = 0;
    iec_8u  cs_temp = 0, i;

    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = IEC10X_C_IC_NA_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = 1;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_ASDU_REASON_ACTCON;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr       = IEC10X_INFO_ADDR_NONE;
    info->_element[0] = qoi;
    /*len*/
    len          = IEC101_VARIABLE_LEN + asdu->_num._num;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);

    return RET_SUCESS;
}

iec_8u IEC101_BuildActFinish(iec_8u qoi, iec_8u Prio)
{

    iec_16u len     = 0;
    iec_8u  cs_temp = 0, i;

    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = IEC10X_C_IC_NA_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = 1;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_ASDU_REASON_ACTTERM;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr       = IEC10X_INFO_ADDR_NONE;
    info->_element[0] = qoi;

    /*len*/
    len          = IEC101_VARIABLE_LEN + asdu->_num._num;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);

    return RET_SUCESS;
}

iec_8u IEC101_BuildSignal(iec_8u reason, iec_8u Prio)
{

    iec_16u len     = 0, addr;
    iec_8u  cs_temp = 0, i, asdu_num = 0, *ptr = NULL, signal, sum;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    /*get value*/
    IEC10X->GetStationInfo(&addr, 0, &asdu_num);
    len = IEC101_STABLE_LEN;
    LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = IEC10X_M_SP_NA_1;
    asdu->_num._sq        = 1;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = reason;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr = IEC10X_INFO_ADDR_SIG_BASE + IEC10X_INFO_ADDR_SIG_TEMP_HX_OFF;

    /*signal value*/
    ptr = info->_element;
    for (i = 0; i < asdu_num; i++)
    {
        if (IEC10X->GetStationInfo(&addr, i, &asdu_num) == RET_SUCESS)
            *ptr = 1;
        else
            *ptr = 0;
        ptr++;
    }
    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);

    return RET_SUCESS;
}

iec_8u IEC101_BuildDetect(iec_8u reason, iec_8u type, iec_8u Prio)
{

    iec_16u            len     = 0, addr;
    iec_8u             cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
    PIEC10X_DETECT_T   detect   = NULL;
    PIEC10X_DETECT_F_T detect_f = NULL;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    /*get value*/
    IEC10X->GetStationInfo(&addr, 0, &asdu_num);
    LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = type;
    asdu->_num._sq        = 1;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = reason;
    asdu->_addr           = Iec10x_Sta_Addr;

    /*info*/
    info->_addr = IEC10X_INFO_ADDR_DET + IEC10X_INFO_ADDR_DET_TEMP_HX_OFF;

    /*Detect value*/
    ptr = info->_element;
    for (i = 0; i < asdu_num; i++)
    {
        /*short int*/
        if (type == IEC10X_M_ME_NA_1)
        {
            detect          = (PIEC10X_DETECT_T)ptr;
            detect->_detect = IEC10X->GetStaTemp(i);
            detect->_qds    = 0;
            ptr += sizeof(IEC10X_DETECT_T);
        }
        /*float*/
        else if (type == IEC10X_M_ME_NC_1)
        {
            detect_f          = (PIEC10X_DETECT_F_T)ptr;
            detect_f->_detect = IEC10X->GetStaTemp(i);
            detect_f->_qds    = 0;
            ptr += sizeof(IEC10X_DETECT_F_T);
        }
    }

    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;       /* add cs+end*/
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);

    return RET_SUCESS;
}

iec_8u IEC101_BuildSignal_Spont(iec_8u TimeFlag, iec_8u signalV, iec_16u addrV)
{

    iec_16u       len     = 0;
    iec_8u        cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
    PCP56Time2a_T time = NULL;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    if (TimeFlag != 1 && TimeFlag != 0)
    {
        LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
        return RET_ERROR;
    }
    LOG("-%s-, time flag(%d) signalV(%d) \n", __FUNCTION__, TimeFlag, signalV);
    /*get value*/
    asdu_num = 1;

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    if (TimeFlag == 0)
        asdu->_type = IEC10X_M_SP_NA_1;
    else
        asdu->_type = IEC10X_M_SP_TB_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_COT_SPONT;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr = addrV;

    /*signal value*/
    ptr = info->_element;
    for (i = 0; i < asdu_num; i++)
    {
        *ptr = signalV;
        ptr++;
    }
    if (TimeFlag == 1)
    {
        time = (PCP56Time2a_T)ptr;
        IEC10X->GetTime(time);
        ptr += sizeof(CP56Time2a_T);
    }

    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_SPON, NULL, NULL);

    return RET_SUCESS;
}
iec_8u IEC101_BuildDetect_Spont(iec_8u TimeFlag, PIEC10X_DETECT_T detectV, iec_16u addrV)
{

    iec_16u          len     = 0;
    iec_8u           cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
    PIEC10X_DETECT_T detect = NULL;
    PCP56Time2a_T    time   = NULL;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    if (TimeFlag != 1 && TimeFlag != 0)
    {
        LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
        return RET_ERROR;
    }

    /*get value*/
    asdu_num = 1;

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    if (TimeFlag == 0)
        asdu->_type = IEC10X_M_ME_NA_1;
    else
        asdu->_type = IEC10X_M_ME_TD_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_COT_SPONT;
    asdu->_addr           = Iec10x_Sta_Addr;

    /*info*/
    info->_addr = addrV;

    /*Detect value*/
    ptr             = info->_element;
    detect          = (PIEC10X_DETECT_T)ptr;
    detect->_detect = detectV->_detect;
    detect->_qds    = detectV->_qds;
    ptr += sizeof(IEC10X_DETECT_T);
    if (TimeFlag == 1)
    {
        time = (PCP56Time2a_T)ptr;
        IEC10X->GetTime(time);
        ptr += sizeof(CP56Time2a_T);
    }

    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;       /* add cs+end*/
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_SPON, NULL, NULL);

    return RET_SUCESS;
}
iec_8u IEC101_BuildDetectF_Spont(iec_8u TimeFlag, float detectV, iec_16u addrV)
{

    iec_16u            len     = 0;
    iec_8u             cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
    PIEC10X_DETECT_F_T detect = NULL;
    PCP56Time2a_T      time   = NULL;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    if (TimeFlag != 1 && TimeFlag != 0)
    {
        LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
        return RET_ERROR;
    }

    /*get value*/
    asdu_num = 1;

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    if (TimeFlag == 0)
        asdu->_type = IEC10X_M_ME_NC_1;
    else
        asdu->_type = IEC10X_M_ME_TF_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_COT_SPONT;
    asdu->_addr           = Iec10x_Sta_Addr;

    /*info*/
    info->_addr = addrV;

    /*Detect value*/
    ptr             = info->_element;
    detect          = (PIEC10X_DETECT_F_T)ptr;
    detect->_detect = detectV;
    detect->_qds    = 0;
    ptr += sizeof(IEC10X_DETECT_F_T);
    if (TimeFlag == 1)
    {
        time = (PCP56Time2a_T)ptr;
        IEC10X->GetTime(time);
        ptr += sizeof(CP56Time2a_T);
    }

    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;       /* add cs+end*/
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_SPON, NULL, NULL);

    return RET_SUCESS;
}
iec_8u IEC101_BuildDelayAct(iec_16u delay_time)
{

    iec_16u len     = 0;
    iec_8u  cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
    iec_16u cp16time2a = delay_time;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);

    /*get value*/
    asdu_num = 1;

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = IEC10X_C_CD_NA_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_COT_ACTCON;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr = IEC10X_INFO_ADDR_NONE;

    /*delay value*/
    ptr             = info->_element;
    *(iec_16u *)ptr = IEC10X_Cp16time2a;
    ptr += 2;

    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_DELAY, NULL, NULL);

    return RET_SUCESS;
}
iec_8u IEC101_BuildClockAct()
{

    iec_16u len     = 0;
    iec_8u  cs_temp = 0, i, asdu_num = 0, *ptr = NULL;

    /*init struct*/
    PIEC101_68_T   Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
    PIEC10X_ASDU_T asdu   = (PIEC10X_ASDU_T)(Iec10x->_asdu);
    PASDU_INFO_T   info   = (PASDU_INFO_T)(asdu->_info);
    PCP56Time2a_T  time   = (PCP56Time2a_T)(info->_element);

    /*get value*/
    asdu_num = 1;

    len = IEC101_STABLE_LEN;

    /*head*/
    Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;

    /*Ctrol*/
    Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
    Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
    Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
    Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;

    Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;

    Iec10x->_addr = Iec10x_Sta_Addr;
    /*asdu*/
    asdu->_type           = IEC10X_C_CS_NA_1;
    asdu->_num._sq        = 0;
    asdu->_num._num       = asdu_num;
    asdu->_reason._pn     = 0;
    asdu->_reason._test   = 0;
    asdu->_reason._reason = IEC10X_COT_ACTCON;
    asdu->_addr           = Iec10x_Sta_Addr;
    /*info*/
    info->_addr = IEC10X_INFO_ADDR_NONE;

    /*clock value*/
    ptr = info->_element;
    // time;
    IEC10X->GetTime(time);
    ptr += sizeof(CP56Time2a_T);

    /*len*/
    len          = ptr + 2 - Iec101_Sendbuf;
    Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start   -cs-end*/

    /*end*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += Iec101_Sendbuf[i];
    }
    Iec101_Sendbuf[len - 2] = cs_temp;
    Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;

    // DumpHEX(Iec101_Sendbuf,len);
    /* enqueue to the transmisson queue */
    IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_CLOCK, NULL, NULL);

    return RET_SUCESS;
}
IEC10X_ASDU_CALL_Qoi(iec_8u qoi)
{

    switch (qoi)
    {
    case IEC10X_CALL_QOI_TOTAL:
        LOG("-%s- call cmd active \n", __FUNCTION__);
        IEC101_BuildSignal(IEC10X_COT_INTROGEN, IEC10X_PRIO_CALLALL);
        IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_SIG_TOTAL;
        break;
    case IEC10X_CALL_QOI_GROUP1:
        LOG("-%s- call cmd call group1 \n", __FUNCTION__);
        IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
        IEC101_BuildSignal(IEC10X_COT_INTRO1, IEC10X_PRIO_CALLGROUP);
        break;
    case IEC10X_CALL_QOI_GROUP2:
        LOG("-%s- call cmd call group2 \n", __FUNCTION__);
        IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
        IEC101_BuildSignal(IEC10X_COT_INTRO2, IEC10X_PRIO_CALLGROUP);
        break;
    case IEC10X_CALL_QOI_GROUP9:
        LOG("-%s- call cmd call group9 \n", __FUNCTION__);
        IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
        IEC101_BuildDetect(IEC10X_COT_INTRO9, IEC10X_M_ME_NA_1, IEC10X_PRIO_CALLGROUP);
        break;
    case IEC10X_CALL_QOI_GROUP10:
        LOG("-%s- call cmd call group10 \n", __FUNCTION__);
        IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
        IEC101_BuildDetect(IEC10X_COT_INTRO10, IEC10X_M_ME_NA_1, IEC10X_PRIO_CALLGROUP);
        break;
    default:
        LOG("-%s- call cmd active error(%d) \n", __FUNCTION__, qoi);
        break;
    }
}

iec_8u IEC10X_ASDU_Call(PIEC10X_ASDU_T Iec10x_Asdu)
{

    PASDU_INFO_T asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info);
    iec_8u       qoi       = asdu_info->_element[0];
    iec_8u       Prio      = 0;

    if (asdu_info->_addr != 0)
    {
        LOG("-%s- call cmd active error addr(%x) \n", __FUNCTION__, asdu_info->_addr);
        return RET_ERROR;
    }

    switch (Iec10x_Asdu->_reason._reason)
    {

    case IEC10X_ASDU_REASON_ACT:
        switch (qoi)
        {
        case IEC10X_CALL_QOI_TOTAL:
            Prio                      = IEC10X_PRIO_CALLALL;
            IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_ACT_RET;
            IEC10X_Call_AllQoi        = qoi;
            break;
        case IEC10X_CALL_QOI_GROUP1:
        case IEC10X_CALL_QOI_GROUP2:
        case IEC10X_CALL_QOI_GROUP9:
        case IEC10X_CALL_QOI_GROUP10:
            Prio                    = IEC10X_PRIO_CALLGROUP;
            IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_ACT_RET;
            IEC10X_Call_GroupQoi    = qoi;
            break;
        default:
            LOG("-%s- call cmd error qoi(%d) \n", __FUNCTION__, qoi);
            return RET_ERROR;
        }
        IEC10X_ResConfirm(Prio);
        IEC101_BuildActConfirm(qoi, Prio);
        break;

    default:
        LOG("-%s- call cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
        break;
    }
    return RET_SUCESS;
}

iec_8u IEC10X_ASDU_Delay(PIEC10X_ASDU_T Iec10x_Asdu)
{

    PASDU_INFO_T asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info);

    if (asdu_info->_addr != 0)
    {
        LOG("-%s- delay cmd error addr(%d) \n", __FUNCTION__, asdu_info->_addr);
        return RET_ERROR;
    }

    switch (Iec10x_Asdu->_reason._reason)
    {

    case IEC10X_COT_ACT:
        IEC10X_Cp16time2a = *(iec_16u *)(asdu_info->_element);
        LOG("-%s- delay cmd (0x%x%x)(%d)ms \n", __FUNCTION__, asdu_info->_element[0], asdu_info->_element[1], IEC10X_Cp16time2a);
        IEC101_STATE_FLAG_DELAY = IEC101_FLAG_DELAY_ACT;
        IEC10X_ResConfirm(IEC10X_PRIO_DELAY);
        IEC101_BuildDelayAct(IEC10X_Cp16time2a);
        break;
    case IEC10X_COT_SPONT:
        IEC10X_Cp16time2a_V = *(iec_16u *)(asdu_info->_element);
        LOG("-%s- delay cmd delay value(%d)ms \n", __FUNCTION__, IEC10X_Cp16time2a_V);
        IEC10X_ResConfirm(IEC10X_PRIO_DELAY);
        break;
    default:
        LOG("-%s- delay cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
        break;
    }
    return RET_SUCESS;
}

iec_8u IEC10X_ASDU_CLOCK(PIEC10X_ASDU_T Iec10x_Asdu)
{

    PASDU_INFO_T  asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info);
    PCP56Time2a_T time      = (PCP56Time2a_T)(asdu_info->_element);

    memcpy(&IEC10X_Cp56time2a, asdu_info->_element, sizeof(CP56Time2a_T));

    if (asdu_info->_addr != 0)
    {
        LOG("-%s- Clock cmd error addr(%d) \n", __FUNCTION__, asdu_info->_addr);
        return RET_ERROR;
    }

    switch (Iec10x_Asdu->_reason._reason)
    {

    case IEC10X_COT_ACT:
        LOG("-%s- Clock cmd (20%d-%d-%d %d %d:%d:%d) delay(%d) \n", __FUNCTION__, IEC10X_Cp56time2a._year._year, IEC10X_Cp56time2a._month._month, IEC10X_Cp56time2a._day._dayofmonth,
            IEC10X_Cp56time2a._day._dayofweek, IEC10X_Cp56time2a._hour._hours, IEC10X_Cp56time2a._min._minutes, IEC10X_Cp56time2a._milliseconds, IEC10X_Cp16time2a_V);
        IEC10X_Cp56time2a._milliseconds += IEC10X_Cp16time2a_V;
        /*get time*/
        /*...*/
        IEC10X->SetTime(&IEC10X_Cp56time2a);
        IEC101_STATE_FLAG_DELAY = IEC101_FLAG_CLOCK_SYS;
        IEC10X_ResConfirm(IEC10X_PRIO_CLOCK);
        IEC101_BuildClockAct();
        break;
    case IEC10X_COT_SPONT:
        LOG("-%s- Clock cmd spont \n", __FUNCTION__);
        break;
    default:
        LOG("-%s- Clock cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
        break;
    }
    return RET_SUCESS;
}

iec_8u Iec10x_Deal_10(iec_8u *buf, iec_16u len)
{

    iec_8u       cfun, sta, i;
    iec_8u       cs_temp   = 0;
    PIEC101_10_T Iec10x_10 = NULL;

    Iec10x_10 = (PIEC101_10_T)buf;
    /* check check_sum*/
    for (i = 1; i < len - 2; i++)
    {
        cs_temp += buf[i];
    }
    if (Iec10x_10->_cs != cs_temp)
    {
        LOG("-%s-,check sum error(%x) \n", __FUNCTION__, cs_temp);
        return RET_ERROR;
    }
    /* check end of the frame*/
    if (Iec10x_10->_end != 0x16)
    {
        LOG("-%s-,iec10x_10 end error(%d) \n", __FUNCTION__, Iec10x_10->_end);
        return RET_ERROR;
    }
    /*deal the function code*/
    cfun = Iec10x_10->_ctrl.down._func;
    sta  = Iec10x_10->_ctrl.down._prm;
    // IEC10X->GetLinkAddr();
#ifdef IEC10XLOCK
    if (IEC10X->LOCK != NULL)
        IEC10X->LOCK();
#endif
    if (sta == IEC101_CTRL_PRM_MASTER)
    {
        switch (cfun)
        {

        case IEC101_CTRL_RESET_LINK:
            LOG("++++Reset link... \n");
            IEC101_STATE_FLAG_INIT = IEC101_FLAG_RESET_LINK;
            break;
        case IEC101_CTRL_PULSE:
            LOG("++++PULSE... \n");
            IEC101_STATE_FLAG_PULSE = IEC101_FLAG_PULSE;
            IEC10X_ResConfirm(IEC10X_PRIO_PULSE);
            break;
        case IEC101_CTRL_SEND_DATA:
            LOG("++++Send data... \n");
            break;
        case IEC101_CTRL_REQ_LINK_STATUS:
            LOG("++++Request link status... \n");
            IEC101_STATE_FLAG_INIT = IEC101_FLAG_INIT_LINK;
            // Iec10x_Sta_Addr = IEC10X->GetLinkAddr();

            // Iec10x_Sta_Addr = 0x138a;
            // IEC10X_RetStatusOk(Iec10x_Sta_Addr);
            break;
        default:
            LOG("++++error DOWN function code (%d)... \n", cfun);
            break;
        }
    }
    else if (sta == IEC101_CTRL_PRM_SLAVE)
    {

        switch (cfun)
        {
        case IEC101_CTRL_RES_LINK_STATUS:
            LOG("++++Respon link status... \n");
            LOG("IEC101_FLAG_RESET_REMOTE_LINK \n");
            IEC10X_ResetLink();
            IEC101_STATE_FLAG_INIT = IEC101_FLAG_RESET_REMOTE_LINK;
            break;
        case IEC101_CTRL_RES_CONFIRM:
            LOG("++++Respon confirm... \n");
            Iec101_Respon_Confirm = 1;
            break;
        default:
            LOG("++++error UP function code (%d)... \n", cfun);
            break;
        }
    }
#ifdef IEC10XLOCK
    if (IEC10X->UNLOCK != NULL)
        IEC10X->UNLOCK();
#endif
    return RET_SUCESS;
}

iec_8u Iec10x_Deal_68(iec_8u *buf, iec_16u len)
{

    iec_8u         cfun, sta, i;
    iec_8u         cs_temp     = 0;
    PIEC101_68_T   Iec10x_68   = NULL;
    PIEC10X_ASDU_T Iec10x_Asdu = NULL;

    Iec10x_68   = (PIEC101_68_T)buf;
    Iec10x_Asdu = (PIEC10X_ASDU_T)Iec10x_68->_asdu;

    /* check check_sum*/
    for (i = 4; i < len - 2; i++)
    {
        cs_temp += buf[i];
    }
    if (buf[len - 2] != cs_temp)
    {
        LOG("-%s-,iec10x_68 check sum error (%d)(%d) \n", __FUNCTION__, buf[len - 2], cs_temp);
        return RET_ERROR;
    }
    /* check end of the frame*/
    if (buf[len - 1] != IEC101_VARIABLE_END)
    {
        LOG("-%s-,iec10x_68 end error(%d) \n", __FUNCTION__, buf[len - 1]);
        return RET_ERROR;
    }
    /* check len of the receive frame */
    if (Iec10x_68->_len + 6 != len)
    {
        LOG("-%s-,iec10x_68 rec len error(%d)(%d) \n", __FUNCTION__, Iec10x_68->_len, len);
        return RET_ERROR;
    }
    /* check len of the frame */
    if (Iec10x_68->_len != Iec10x_68->_len_cfm)
    {
        LOG("-%s-,iec10x_68 len error(%d)(%d) \n", __FUNCTION__, Iec10x_68->_len, Iec10x_68->_len_cfm);
        return RET_ERROR;
    }
    /*deal the function code*/
    cfun = Iec10x_68->_ctrl.down._func;
    sta  = Iec10x_68->_ctrl.down._prm;
#ifdef IEC10XLOCK
    if (IEC10X->LOCK != NULL)
        IEC10X->LOCK();
#endif
    switch (cfun)
    {
    case IEC101_CTRL_SEND_USR_DATA_ACK:
        Iec101_Respon_Confirm = 0;
        LOG("++++Send user data need ack... \n");
        switch (Iec10x_Asdu->_type)
        {
        case IEC10X_C_IC_NA_1:
            LOG("++++asdu type call cmd... \n");
            IEC10X_ASDU_Call(Iec10x_Asdu);
            break;
        case IEC10X_C_CD_NA_1:
            LOG("++++asdu type delay active... \n");
            IEC10X_ASDU_Delay(Iec10x_Asdu);
            break;
        case IEC10X_C_CS_NA_1:
            LOG("++++asdu type clock active... \n");
            IEC10X_ASDU_CLOCK(Iec10x_Asdu);
            break;
        default:
            break;
        }
        break;
    default:
        LOG("++++error function code (%d)... \n", cfun);
        break;
    }
#ifdef IEC10XLOCK
    if (IEC10X->UNLOCK != NULL)
        IEC10X->UNLOCK();
#endif
    return RET_SUCESS;
}

void Iex101_main(iec_8u *buf, iec_16u len)
{

    iec_8u *BufTemp = NULL;
    iec_16s LenRemain, LenTmp;

    if (buf == NULL)
    {
        LOG("-%s-,buffer (null)", __FUNCTION__);
        return;
    }
    if (len <= 0 || len > IEC101_MAX_BUF_LEN)
    {
        LOG("-%s-,buffer len error(%d) \n", __FUNCTION__, len);
        return;
    }

    BufTemp   = buf;
    LenRemain = len;
    while (BufTemp < buf + len)
    {

        if (BufTemp[0] == IEC101_STABLE_BEGING)
        {
            LenTmp           = 6;
            IEC101_Pulse_Cnt = 0;
            if (LenRemain < 6)
            {
                LOG("_%s_,len error(%d) \n", __FUNCTION__, len);
                return;
            }
            Iec10x_Deal_10(BufTemp, LenTmp);
        }
        else if (BufTemp[0] == IEC101_VARIABLE_BEGING)
        {
            LenTmp           = BufTemp[1] + 6;
            IEC101_Pulse_Cnt = 0;
            if (BufTemp[1] != BufTemp[2])
            {
                LOG("_%s_,len error(%d)(%d) \n", __FUNCTION__, BufTemp[1], BufTemp[2]);
                return;
            }
            Iec10x_Deal_68(BufTemp, LenTmp);
        }
        else
        {
            LOG("-%s-,head type error(%d) \n", __FUNCTION__, BufTemp[0]);
            return;
        }
        BufTemp += LenTmp;
        LenRemain -= LenTmp;
    }
    return;
}

iec_8u Iec101_StateMachine(void)
{

    /*Init link*/

    switch (IEC101_STATE_FLAG_INIT)
    {

    case IEC101_FLAG_LINK_CLOSED:
        break;
    case IEC101_FLAG_INIT_LINK:
        LOG("IEC101_FLAG_INIT_LINK \n");
        Iec101_Respon_Confirm = 0;
        Iec10x_Sta_Addr       = IEC10X->GetLinkAddr();
        IEC10X_RetStatusOk(Iec10x_Sta_Addr);
        IEC101_STATE_FLAG_INIT = IEC101_FLAG_LINK_IDLE;
        break;
    case IEC101_FLAG_RESET_LINK:
        LOG("IEC101_FLAG_RESET_LINK \n");
        IEC10X_ClearQ();
        IEC10X_ResConfirm(IEC10X_PRIO_INITLINK);

        IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_CLOSED;
        IEC101_STATE_FLAG_GROUP   = IEC101_FLAG_LINK_CLOSED;
        IEC101_STATE_FLAG_DELAY   = IEC101_FLAG_LINK_CLOSED;
        IEC101_STATE_FLAG_PULSE   = IEC101_FLAG_LINK_CLOSED;

        IEC101_STATE_FLAG_INIT = IEC101_FLAG_REQ_LINK;
        break;
    case IEC101_FLAG_REQ_LINK:
        LOG("IEC101_FLAG_REQ_LINK \n");
        IEC10X_ReqLinkStatus();
        IEC101_STATE_FLAG_INIT = IEC101_FLAG_LINK_IDLE;
        break;
    case IEC101_FLAG_RESET_REMOTE_LINK:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm  = 0;
            IEC101_STATE_FLAG_INIT = IEC101_FLAG_INIT_FIN;
            LOG("IEC101_FLAG_INIT_FIN! \n");
            IEC101_BuildFinInit();
        }
        break;
    case IEC101_FLAG_INIT_FIN:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm  = 0;
            IEC101_STATE_FLAG_INIT = IEC101_FLAG_CONNECT_OK;
        }
        break;
    case IEC101_FLAG_CONNECT_OK:
    case IEC101_FLAG_LINK_IDLE:
    default:
        break;
    }

    /*total call*/
    switch (IEC101_STATE_FLAG_CALLALL)
    {
    case IEC101_FLAG_CALL_ACT:
        break;
    case IEC101_FLAG_CALL_ACT_RET:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm = 0;
            IEC10X_ASDU_CALL_Qoi(IEC10X_Call_AllQoi);
        }
        break;
    case IEC101_FLAG_CALL_SIG_TOTAL:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm     = 0;
            IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_DET_TOTAL;
            IEC101_BuildDetect(IEC10X_COT_INTROGEN, IEC10X_M_ME_NA_1, IEC10X_PRIO_CALLALL);
        }
        break;
    case IEC101_FLAG_CALL_DET_TOTAL:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm = 0;
            IEC101_BuildActFinish(IEC10X_Call_AllQoi, IEC10X_PRIO_CALLALL);
            IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_ACT_FIN;
        }
        break;
    case IEC101_FLAG_CALL_ACT_FIN:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm     = 0;
            IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_IDLE;
        }
        break;
    case IEC101_FLAG_LINK_IDLE:
    default:
        break;
    }

    /*group call*/
    switch (IEC101_STATE_FLAG_GROUP)
    {
    case IEC101_FLAG_CALL_ACT:
        break;
    case IEC101_FLAG_CALL_ACT_RET:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm = 0;
            IEC10X_ASDU_CALL_Qoi(IEC10X_Call_GroupQoi);
        }
        break;
    case IEC101_FLAG_CALL_GROUP:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm   = 0;
            IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_ACT_FIN;
            IEC101_BuildActFinish(IEC10X_Call_GroupQoi, IEC10X_PRIO_CALLGROUP);
        }
        break;
    case IEC101_FLAG_CALL_ACT_FIN:
        if (Iec101_Respon_Confirm)
        {
            Iec101_Respon_Confirm   = 0;
            IEC101_STATE_FLAG_GROUP = IEC101_FLAG_LINK_IDLE;
        }
        break;
    case IEC101_FLAG_LINK_IDLE:
    default:
        break;
    }

    /*delay and clock*/
    switch (IEC101_STATE_FLAG_DELAY)
    {

    case IEC101_FLAG_DELAY_ACT:
        break;
    case IEC101_FLAG_CLOCK_SYS:
        IEC101_STATE_FLAG_DELAY = IEC101_FLAG_LINK_IDLE;
        break;
    case IEC101_FLAG_LINK_IDLE:
    default:
        break;
    }

    /*pulse*/
    switch (IEC101_STATE_FLAG_PULSE)
    {
    case IEC101_FLAG_PULSE:
        break;
    case IEC101_FLAG_LINK_IDLE:
        break;
    default:
        break;
    }
    return RET_SUCESS;
}

#endif
