#include "iec101.h" #include "project_var.h" #ifdef IEC101_STM32 /* * GLOABLE VARIALBLE */ uint8_t Iec101_Respon_Confirm = 0; uint8_t Iec101_Sendbuf[IEC101_MAX_BUF_LEN]; uint8_t IEC10X_Call_AllQoi = 0; uint8_t IEC10X_Call_GroupQoi = 0; uint16_t IEC101_Pulse_Cnt = 0; /* * STATE * */ uint8_t IEC101_STATE_FLAG_INIT = IEC101_FLAG_LINK_CLOSED; uint8_t IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_CLOSED; uint8_t IEC101_STATE_FLAG_GROUP = IEC101_FLAG_LINK_CLOSED; uint8_t IEC101_STATE_FLAG_CLOCK = IEC101_FLAG_LINK_CLOSED; uint8_t IEC101_STATE_FLAG_DELAY = IEC101_FLAG_LINK_CLOSED; uint8_t IEC101_STATE_FLAG_PULSE = IEC101_FLAG_LINK_CLOSED; uint8_t IEC10X_RetStatusOk(uint16_t addr) { uint16_t 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 uint8_t IEC10X_ResConfirm(uint8_t Prio) { uint16_t 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; } uint8_t IEC10X_ReqLinkStatus() { uint16_t 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; } uint8_t IEC10X_ResetLink(void) { uint16_t 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; } uint8_t IEC101_BuildFinInit(void) { uint16_t len = 0; uint8_t 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; } uint8_t IEC101_BuildActConfirm(uint8_t qoi, uint8_t Prio) { uint16_t len = 0; uint8_t 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; } uint8_t IEC101_BuildActFinish(uint8_t qoi, uint8_t Prio) { uint16_t len = 0; uint8_t 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; } uint8_t IEC101_BuildSignal(uint8_t reason, uint8_t Prio) { uint16_t len = 0, addr; uint8_t 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; } uint8_t IEC101_BuildDetect(uint8_t reason, uint8_t type, uint8_t Prio) { uint16_t len = 0, addr; uint8_t 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; } uint8_t IEC101_BuildSignal_Spont(uint8_t TimeFlag, uint8_t signalV, uint16_t addrV) { uint16_t len = 0; uint8_t 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; } uint8_t IEC101_BuildDetect_Spont(uint8_t TimeFlag, PIEC10X_DETECT_T detectV, uint16_t addrV) { uint16_t len = 0; uint8_t 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; } uint8_t IEC101_BuildDetectF_Spont(uint8_t TimeFlag, float detectV, uint16_t addrV) { uint16_t len = 0; uint8_t 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; } uint8_t IEC101_BuildDelayAct(uint16_t delay_time) { uint16_t len = 0; uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL; uint16_t 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; *(uint16_t *)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; } uint8_t IEC101_BuildClockAct() { uint16_t len = 0; uint8_t 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(uint8_t 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; } } uint8_t IEC10X_ASDU_Call(PIEC10X_ASDU_T Iec10x_Asdu) { PASDU_INFO_T asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info); uint8_t qoi = asdu_info->_element[0]; uint8_t 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; } uint8_t 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 = *(uint16_t *)(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 = *(uint16_t *)(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; } uint8_t 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; } uint8_t Iec10x_Deal_10(uint8_t *buf, uint16_t len) { uint8_t cfun, sta, i; uint8_t 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; } uint8_t Iec10x_Deal_68(uint8_t *buf, uint16_t len) { uint8_t cfun, sta, i; uint8_t 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(uint8_t *buf, uint16_t len) { uint8_t *BufTemp = NULL; int16_t 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; } uint8_t 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