123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548 |
- #include "iec104.h"
- iec_8u iec104_send_buf[IEC104_MAX_BUF_LEN];
- iec_8u IEC104_STATE_FLAG_INIT = IEC104_FLAG_CLOSED;
- iec_8u IEC104_STATE_FLAG_CALLALL = IEC104_FLAG_CLOSED;
- iec_8u IEC104_STATE_FLAG_GROUP = IEC104_FLAG_CLOSED;
- iec_8u IEC104_STATE_FLAG_CLOCK = IEC104_FLAG_CLOSED;
- iec_8u IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
- iec_8u IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_CLOSED;
- iec_32s iec104_build_send_sn = 0;
- iec_32s iec104_build_recv_sn = 0;
- iec_32s iec104_deal_send_sn = -1;
- iec_32s iec104_deal_recv_sn = 0;
- iec_8u IEC104_Call_AllQoi = 0;
- iec_8u IEC104_Call_GroupQoi = 0;
- #define IEC104_CYCLE_TIME_MS 100 /*100ms*/
- #define IEC104_RESEND_TIME_MS (30 * 1000) /*30s*/
- #define IEC104_S_ACK_TIMEOUT (5 * 1000) /*5s*/
- #define IEC104_TESTER_IDLE_TIMEOUT (1 * 30 * 1000) /*2min*/
- iec_32u Iec104_TimeCount = 0;
- iec_32u Iec104_TimeCycle = IEC104_RESEND_TIME_MS;
- iec_32u Iec104_TimeCycle_S = 0;
- iec_32u Iec104_TimeCycle_TesterIdle = 0;
- iec_8u Iec104_TesterCount = 0;
- iec_32u Iec10x_Update_SeekAddr = 0;
- iec_16u FirmFlagCount = 0;
- iec_8u iec104_upload_addr(void)
- {
- iec_8u len = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = IEC104_ASDU_TYPE_M_DTU_INF_1;
- asdu->_num._sq = 0;
- asdu->_num._num = 1;
- asdu->_reason._reason = IEC10X_ASDU_COT_UNKNOW;
- asdu->_addr = iec104_state_addr;
- /*build info*/
- ptr = info->_addr;
- temp32 = 0;
- memcpy(ptr, &temp32, 3);
- ptr = info->_element;
- temp32 = IEC104_INFO_SIGNATURE;
- memcpy(ptr, &temp32, 4);
- ptr += 4;
- temp32 = iec104_state_addr;
- memcpy(ptr, &temp32, 2);
- ptr += 2;
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- dump_hex(Iec104_Sendbuf, len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_init_fin(void)
- {
- iec_8u len = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = Iec10x_M_EI_NA_1;
- asdu->_num._sq = 0;
- asdu->_num._num = 1;
- asdu->_reason._reason = IEC10X_ASDU_REASON_INIT;
- asdu->_addr = iec104_state_addr;
- /*build info*/
- ptr = info->_addr;
- temp32 = 0;
- memcpy(ptr, &temp32, 3);
- ptr = info->_element;
- // temp32 = 0;
- // memcpy(ptr, &temp32, 4);
- info->_element[0] = 0;
- ptr++;
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- dump_hex(Iec104_Sendbuf, len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_call_ack(iec_8u qoi, iec_8u Prio)
- {
- iec_8u len = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = IEC10X_C_IC_NA_1;
- asdu->_num._sq = 0;
- asdu->_num._num = 1;
- asdu->_reason._reason = IEC10X_ASDU_REASON_ACTCON;
- asdu->_addr = iec104_state_addr;
- /*build info*/
- ptr = info->_addr;
- temp32 = 0;
- memcpy(ptr, &temp32, 3);
- ptr = info->_element;
- ptr[0] = qoi;
- ptr += 1;
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- dump_hex(Iec104_Sendbuf, len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_signal_spon(iec_8u time_flag, iec_8u v_signal, iec_16u v_addr)
- {
- iec_8u len = 0, asdu_num = 0, i;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- PCP56Time2a_T time = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /* check Time flag */
- if (time_flag != 1 && time_flag != 0)
- {
- LOG("-%s-, error time flag(%d) \n", __FUNCTION__, time_flag);
- return RET_ERROR;
- }
- LOG("-%s-, time flag(%d) signalV(%d) \n", __FUNCTION__, time_flag, v_signal);
- /*get value*/
- asdu_num = 1;
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- if (time_flag == 0)
- asdu->_type = IEC10X_M_SP_NA_1;
- else
- asdu->_type = IEC10X_M_SP_TB_1;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = IEC10X_COT_SPONT;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- temp32 = v_addr;
- memcpy(ptr, &temp32, 3);
- /*build info value*/
- ptr = info->_element;
- for (i = 0; i < asdu_num; i++)
- {
- *ptr = v_signal;
- ptr++;
- }
- if (time_flag == 1)
- {
- time = (PCP56Time2a_T)ptr;
- iec104->get_time(time);
- ptr += sizeof(CP56Time2a_T);
- }
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_SPON, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_detect_spont(iec_8u TimeFlag, PIEC10X_DETECT_T detectV, iec_16u addrV)
- {
- iec_8u len = 0, asdu_num = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- PIEC10X_DETECT_T detect = NULL;
- PCP56Time2a_T time = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /* check Time flag */
- if (TimeFlag != 1 && TimeFlag != 0)
- {
- LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
- return RET_ERROR;
- }
- /*get value*/
- asdu_num = 1;
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- if (TimeFlag == 0)
- asdu->_type = IEC10X_M_ME_NA_1;
- else
- asdu->_type = IEC10X_M_ME_TD_1;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = IEC10X_COT_SPONT;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- temp32 = addrV;
- memcpy(ptr, &temp32, 3);
- /*build info 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;
- iec104->get_time(time);
- ptr += sizeof(CP56Time2a_T);
- }
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_SPON, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_detect_f_spont(iec_8u TimeFlag, float detectV, iec_16u addrV)
- {
- iec_8u len = 0, asdu_num = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- PIEC10X_DETECT_F_T detect = NULL;
- PCP56Time2a_T time = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /* check Time flag */
- if (TimeFlag != 1 && TimeFlag != 0)
- {
- LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
- return RET_ERROR;
- }
- /*get value*/
- asdu_num = 1;
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- if (TimeFlag == 0)
- asdu->_type = IEC10X_M_ME_NC_1;
- else
- asdu->_type = IEC10X_M_ME_TF_1;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = IEC10X_COT_SPONT;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- temp32 = addrV;
- memcpy(ptr, &temp32, 3);
- /*build info 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;
- iec104->get_time(time);
- ptr += sizeof(CP56Time2a_T);
- }
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_SPON, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_signal(iec_8u reason, iec_8u Prio, iec_8u dev_type)
- {
- iec_8u len = 0, asdu_num = 0;
- iec_16u i = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*get value*/
- iec104->get_info_num(&asdu_num, dev_type);
- LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = IEC10X_M_SP_NA_1;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = reason;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- if (dev_type == ENDDEVICE_TYPE_HXTM)
- {
- temp32 = IEC104_INFOADDR_STATE_HXTM;
- }
- else if (dev_type == ENDDEVICE_TYPE_HXGF)
- {
- temp32 = IEC104_INFOADDR_STATE_HXGF;
- }
- else
- {
- LOG("-%s-, error dev type:%d \n", __FUNCTION__, dev_type);
- return RET_ERROR;
- }
- memcpy(ptr, &temp32, 3);
- /*build info value*/
- ptr = info->_element;
- for (i = 0; i < asdu_num; i++)
- {
- *ptr = iec104->get_station_state(i, dev_type);
- ptr++;
- }
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_detect(iec_8u reason, iec_8u ValueType, iec_8u Prio, iec_8u dev_type)
- {
- iec_8u len = 0, asdu_num = 0, i;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- PIEC10X_DETECT_T detect = NULL;
- PIEC10X_DETECT_F_T detect_f = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*get value*/
- iec104->get_info_num(&asdu_num, dev_type);
- LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = ValueType;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = reason;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- if (dev_type == ENDDEVICE_TYPE_HXTM)
- {
- temp32 = IEC104_INFOADDR_VALUE_HXTM;
- }
- else if (dev_type == ENDDEVICE_TYPE_HXGF)
- {
- temp32 = IEC104_INFOADDR_VALUE_HXGF;
- }
- else
- {
- LOG("-%s-, error dev type:%d \n", __FUNCTION__, dev_type);
- return RET_ERROR;
- }
- memcpy(ptr, &temp32, 3);
- /*Build Detect value*/
- ptr = info->_element;
- for (i = 0; i < asdu_num; i++)
- {
- /*short int*/
- if (ValueType == IEC10X_M_ME_NA_1)
- {
- detect = (PIEC10X_DETECT_T)ptr;
- detect->_detect = iec104->get_sta_value(i, dev_type);
- detect->_qds = 0;
- ptr += sizeof(IEC10X_DETECT_T);
- }
- /*float*/
- else if (ValueType == IEC10X_M_ME_NC_1)
- {
- detect_f = (PIEC10X_DETECT_F_T)ptr;
- detect_f->_detect = iec104->get_sta_value(i, dev_type);
- detect_f->_qds = 0;
- ptr += sizeof(IEC10X_DETECT_F_T);
- }
- }
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_upload(iec_8u ValueType, iec_8u Prio, iec_8u dev_type)
- {
- iec_8u len = 0, asdu_num = 0, i;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- PIEC10X_DETECT_T detect = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*get value*/
- iec104->get_info_num(&asdu_num, dev_type);
- LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = ValueType;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = AP_COT_BASE_INFO;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- temp32 = IEC104_INFOADDR_BASE_DEVINFO;
- memcpy(ptr, &temp32, 3);
- ptr += 3;
- /*Build Detect value*/
- ptr = info->_element;
- for (i = 0; i < asdu_num; i++)
- {
- detect = (PIEC10X_DETECT_T)ptr;
- detect->_detect = iec104->get_sta_value(i, dev_type);
- detect->_qds = 0;
- ptr += sizeof(IEC10X_DETECT_T);
- }
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_act_finish(iec_8u qoi, iec_8u Prio)
- {
- iec_8u len = 0, asdu_num = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.i.type = 0;
- Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = IEC10X_C_IC_NA_1;
- asdu->_num._sq = 1;
- asdu->_num._num = asdu_num;
- asdu->_reason._reason = IEC10X_ASDU_REASON_ACTTERM;
- asdu->_addr = iec104_state_addr;
- /*build info addr*/
- ptr = info->_addr;
- temp32 = IEC10X_INFO_ADDR_SIG_BASE + IEC10X_INFO_ADDR_SIG_TEMP_HX_OFF;
- memcpy(ptr, &temp32, 3);
- /*Build Detect value*/
- ptr = info->_element;
- ptr[0] = qoi;
- ptr += 1;
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_u(iec_8u UType, iec_8u Ack)
- {
- iec_8u len = 0, Tester, Start, Stop;
- iec_8u *ptr = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- if (Ack)
- {
- Tester = IEC104_U_FUNC_TESTER_ACK;
- Start = IEC104_U_FUNC_STARTDT_ACK;
- Stop = IEC104_U_FUNC_STOPDT_ACK;
- }
- else
- {
- Tester = IEC104_U_FUNC_TESTER;
- Start = IEC104_U_FUNC_STARTDT;
- Stop = IEC104_U_FUNC_STOPDT;
- }
- switch (UType)
- {
- case IEC104_U_FUNC_STARTDT:
- Iec104_data->ctrl.func.func = Start;
- break;
- case IEC104_U_FUNC_STOPDT:
- Iec104_data->ctrl.func.func = Stop;
- break;
- case IEC104_U_FUNC_TESTER:
- Iec104_data->ctrl.func.func = Tester;
- break;
- default:
- LOG(">%s<, U Type Error(%d) !\n", __FUNCTION__, UType);
- return RET_ERROR;
- }
- /*build ASDU , COT ,Addr*/
- ptr = Iec104_data->asdu;
- /*build info*/
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_build_s_ack(void)
- {
- iec_8u len = 0;
- iec_8u *ptr = NULL;
- p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
- /*build head*/
- Iec104_data->head = IEC104_HEAD;
- /*build control code*/
- Iec104_data->ctrl.s.type_1 = 1;
- Iec104_data->ctrl.s.type_2 = 0;
- Iec104_data->ctrl.s.reserve = 0;
- Iec104_data->ctrl.s.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- ptr = Iec104_data->asdu;
- /*build info*/
- /*len*/
- len = ptr - iec104_send_buf;
- Iec104_data->len = len - 2;
- // DumpHEX(Iec101_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_asdu_call(p_iec10x_asdu_t Iec10x_Asdu)
- {
- p_asdu_info_t asdu_info = (p_asdu_info_t)(Iec10x_Asdu->_info);
- iec_8u qoi = asdu_info->_element[0];
- iec_8u Prio = 0;
- iec_32u InfoAddr = 0;
- /* check info addrest */
- memcpy(&InfoAddr, asdu_info->_addr, 3);
- if (InfoAddr != 0)
- {
- LOG("-%s- call cmd active error addr(%x) \n", __FUNCTION__, InfoAddr);
- return RET_ERROR;
- }
- switch (Iec10x_Asdu->_reason._reason)
- {
- case IEC10X_ASDU_REASON_ACT:
- switch (qoi)
- {
- case IEC10X_CALL_QOI_TOTAL:
- Prio = IEC10X_PRIO_CALLALL;
- IEC104_STATE_FLAG_CALLALL = IEC104_FLAG_CALL_ALLDATA;
- IEC104_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;
- IEC104_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROURPDATA;
- IEC104_Call_GroupQoi = qoi;
- break;
- default:
- LOG("-%s- call cmd error qoi(%d) \n", __FUNCTION__, qoi);
- return RET_ERROR;
- }
- iec104_build_call_ack(qoi, Prio);
- /**/
- iec104_build_signal(qoi, Prio, ENDDEVICE_TYPE_HXTM);
- iec104_build_detect(qoi, IEC10X_M_ME_NA_1, Prio, ENDDEVICE_TYPE_HXTM);
- /**/
- iec104_build_signal(qoi, Prio, ENDDEVICE_TYPE_HXGF);
- iec104_build_detect(qoi, IEC10X_M_ME_NA_1, Prio, ENDDEVICE_TYPE_HXGF);
- iec104_build_act_finish(qoi, Prio);
- break;
- default:
- LOG("-%s- call cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
- break;
- }
- return RET_SUCESS;
- }
- iec_8u iec104_asdu_clock(p_iec10x_asdu_t Iec10x_Asdu)
- {
- p_asdu_info_t asdu_info = (p_asdu_info_t)(Iec10x_Asdu->_info);
- memcpy(&IEC10X_Cp56time2a, asdu_info->_element, sizeof(CP56Time2a_T));
- if (asdu_info->_addr[0] != 0 || asdu_info->_addr[1] != 0 || asdu_info->_addr[2] != 0)
- {
- LOG("-%s- Clock cmd error addr(0x%02x:%02x:%02x) \n", __FUNCTION__, asdu_info->_addr[0], asdu_info->_addr[2], asdu_info->_addr[2]);
- return RET_ERROR;
- }
- switch (Iec10x_Asdu->_reason._reason)
- {
- case IEC10X_COT_ACT:
- LOG("-%s- Clock cmd (20%d-%d-%d %d %d:%d:%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);
- /*get time*/
- /*...*/
- iec104->set_time(&IEC10X_Cp56time2a);
- // IEC104_Build_S_Ack();
- 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 iec104_asdu_set_act(p_iec10x_asdu_t Iec10x_Asdu, iec_8u Type)
- {
- p_asdu_info_t asdu_info = (p_asdu_info_t)(Iec10x_Asdu->_info);
- iec_8u *ptr = NULL;
- iec_8u n = Iec10x_Asdu->_num._num, Sq = Iec10x_Asdu->_num._sq, i;
- float Value = 0.0;
- iec_32u InfoAddr = 0;
- /* if sq == 1 */
- PIEC10X_DETECT_T detect = NULL;
- PIEC10X_DETECT_F_T detect_f = NULL;
- /* if sq == 0 */
- PIEC10X_DETECT_SQ0_T detect_Sq0 = NULL;
- PIEC10X_DETECT_SQ0_F_T detect_Sq0_f = NULL;
- /* check info addrest */
- memcpy(&InfoAddr, asdu_info->_addr, 3);
- switch (Iec10x_Asdu->_reason._reason)
- {
- case IEC10X_COT_ACT:
- switch (Type)
- {
- case IEC10X_C_SE_NA_1:
- if (Sq == 1)
- {
- ptr = asdu_info->_element;
- for (i = 0; i < n; i++)
- {
- detect = (PIEC10X_DETECT_T)ptr;
- Value = (float)(detect->_detect);
- ptr += sizeof(IEC10X_DETECT_T);
- iec104->set_config(Value, InfoAddr + i);
- }
- }
- else if (Sq == 0)
- {
- ptr = Iec10x_Asdu->_info;
- for (i = 0; i < n; i++)
- {
- detect_Sq0 = (PIEC10X_DETECT_SQ0_T)ptr;
- Value = (float)(detect_Sq0->_detect);
- InfoAddr = 0;
- memcpy(&InfoAddr, detect_Sq0->_addr, 3);
- iec104->set_config(Value, InfoAddr);
- ptr += sizeof(IEC10X_DETECT_SQ0_T);
- }
- }
- break;
- case IEC10X_C_SE_NC_1:
- if (Sq == 1)
- {
- ptr = asdu_info->_element;
- for (i = 0; i < n; i++)
- {
- detect_f = (PIEC10X_DETECT_F_T)ptr;
- Value = detect_f->_detect;
- ptr += sizeof(IEC10X_DETECT_F_T);
- iec104->set_config(Value, InfoAddr + i);
- }
- }
- else if (Sq == 0)
- {
- ptr = Iec10x_Asdu->_info;
- for (i = 0; i < n; i++)
- {
- detect_Sq0_f = (PIEC10X_DETECT_SQ0_F_T)ptr;
- Value = (float)(detect_Sq0_f->_detect);
- memcpy(&InfoAddr, detect_Sq0_f->_addr, 3);
- iec104->set_config(Value, InfoAddr);
- ptr += sizeof(IEC10X_DETECT_SQ0_F_T);
- }
- }
- break;
- default:
- LOG("-%s-, Type error !", __FUNCTION__);
- return RET_ERROR;
- }
- break;
- default:
- LOG("-%s- , error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
- return RET_ERROR;
- }
- return RET_SUCESS;
- }
- iec_8u iec104_build_set_ack(iec_8u Prio, iec_8u Type)
- {
- iec_8u len = 0;
- iec_8u *ptr = NULL;
- p_iec104_data_t iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*build head*/
- iec104_data->head = IEC104_HEAD;
- /*build control code*/
- iec104_data->ctrl.i.type = 0;
- iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = Type;
- asdu->_num._sq = 0;
- asdu->_num._num = 0;
- asdu->_reason._reason = IEC10X_ASDU_REASON_ACTFIN;
- asdu->_addr = iec104_state_addr;
- /*build info*/
- ptr = info->_addr;
- /*len*/
- len = ptr - iec104_send_buf;
- iec104_data->len = len - 2;
- // DumpHEX(Iec104_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8u iec104_deal_sn(iec_16u SendSn, iec_16u RecvSn)
- {
- LOG("Receive Pakage I(%d,%d), Send(%d,%d)\n", SendSn, RecvSn, iec104_build_send_sn, iec104_build_recv_sn);
- #if 0
- if(SendSn > Iec104_DealSendSn+1){
- LOG("-%s-, error,send last(%d),now(%d) \n",__FUNCTION__,Iec104_DealSendSn,SendSn);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_SEND_CLOSED;
- return RET_ERROR;
- }else if(SendSn < Iec104_DealSendSn+1){
- LOG("-%s-, Retransmit,send last(%d),now(%d) \n",__FUNCTION__,Iec104_DealSendSn,SendSn);
- return RET_ERROR;
- }
- if(RecvSn != Iec104_BuildSendSn){
- LOG("-%s-, error,receive last(%d),now(%d) \n",__FUNCTION__,Iec104_BuildSendSn,RecvSn);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_SEND_CLOSED;
- return RET_ERROR;
- }
- if(RecvSn < Iec104_DealRecvSn){
- LOG("-%s-, error,receive2 last(%d),now(%d) \n",__FUNCTION__,Iec104_DealRecvSn,RecvSn);
- return RET_ERROR;
- }
- #endif
- if (SendSn < iec104_deal_send_sn || RecvSn < iec104_deal_recv_sn)
- {
- LOG("-%s-, error,send last(%d),now(%d). recv last(%d),now(%d) \n", __FUNCTION__,
- iec104_deal_send_sn, SendSn, iec104_deal_recv_sn, RecvSn);
- return RET_ERROR;
- }
- iec104_build_recv_sn = SendSn + 1;
- iec104_deal_send_sn = SendSn;
- iec104_deal_recv_sn = RecvSn;
- // Iec104_BuildRecvSn++;
- /* return S ACK */
- IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_S_ACK;
- Iec104_TimeCycle_S = 0;
- return RET_SUCESS;
- }
- iec_8s iec104_build_data_ack(iec_8u TI, iec_16u COT, iec_32u InfoAddr, iec_16u Info, iec_8u Prio)
- {
- iec_8u len = 0;
- iec_8u *ptr = NULL;
- iec_32u temp32 = 0;
- /* build head */
- p_iec104_data_t iec104_data = (p_iec104_data_t)iec104_send_buf;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(iec104_data->asdu);
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- /*build head*/
- iec104_data->head = IEC104_HEAD;
- /*build control code*/
- iec104_data->ctrl.i.type = 0;
- iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
- iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
- /*build ASDU , COT ,Addr*/
- asdu->_type = TI;
- asdu->_num._sq = 0;
- asdu->_num._num = 1;
- asdu->_reason._reason = COT;
- asdu->_addr = iec104_state_addr;
- /*build info*/
- ptr = info->_addr;
- temp32 = InfoAddr;
- memcpy(ptr, &temp32, 3);
- ptr = info->_element;
- if (COT == IEC10X_COT_ACT_TERMINAL || COT == IEC10X_COT_ACTCON || COT == IEC10X_COT_ACT_TERMINAL_ACK || COT == IEC10X_TI_AP_FIRM_BACKOFF)
- {
- ptr[0] = 0;
- ptr[1] = 0;
- ptr += 2;
- }
- else if (COT == IEC10X_COT_DATA_ACK || COT == IEC10X_COT_DATA_FIN_ACK)
- {
- memcpy(ptr, &Info, 2);
- ptr += 2;
- }
- /*len*/
- len = ptr - iec104_send_buf;
- iec104_data->len = len - 2;
- // DumpHEX(Iec104_Sendbuf,len);
- /* enqueue to the transmisson queue */
- iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
- return RET_SUCESS;
- }
- iec_8s iec104_deal_firmware_update(p_iec10x_asdu_t asdu, iec_8u Len)
- {
- iec_16u cot = asdu->_reason._reason;
- iec_16u FlagNum = 0, i;
- iec_8u DataLen = Len - IEC104_DATA_LEN - 3; /* flag num 2, check sum 1 byte*/
- p_asdu_info_t element = (p_asdu_info_t)(asdu->_info);
- iec_8u *DataPtr = (iec_8u *)(element->_element) + 3;
- iec_8u TI = asdu->_type, csum = 0, CsumTemp = 0;
- iec_32u FirmwareType = 0;
- iec_8s ret = 0;
- p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
- FlagNum = *(iec_16u *)(info->_element);
- memcpy(&FirmwareType, asdu->_info, 3);
- if (Len == 0)
- {
- LOG("-%s-,data:%d,Len:%d error!\n", __FUNCTION__, FlagNum, DataLen);
- return RET_ERROR;
- }
- /* reset the flag counter */
- if (FlagNum == 1)
- {
- FirmFlagCount = 0;
- Iec10x_Update_SeekAddr = 0;
- }
- switch (cot)
- {
- case IEC10X_COT_DATA:
- if (FlagNum == FirmFlagCount + 1)
- {
- /* check sum */
- csum = info->_element[2];
- for (i = 0; i < DataLen; i++)
- {
- CsumTemp += DataPtr[i];
- }
- if (CsumTemp == csum)
- {
- LOG("-%s-,data:%d,Len:%d,seek:%d \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr);
- for (i = 0; i < 3; i++)
- {
- ret = iec104->save_firmware(DataLen, DataPtr, FirmwareType, Iec10x_Update_SeekAddr);
- if (ret == RET_SUCESS)
- break;
- }
- if (ret == RET_ERROR)
- {
- LOG("save firmware error \n");
- break;
- }
- FirmFlagCount = FlagNum;
- Iec10x_Update_SeekAddr += DataLen;
- }
- else
- {
- LOG("%s, check sum error:%d,need:%d,num:%d\n", __FUNCTION__, CsumTemp, csum, FlagNum);
- }
- }
- else if (FlagNum < FirmFlagCount + 1)
- {
- LOG("update flag resend,need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
- }
- else
- {
- LOG("update flag error! need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
- // Iec104_BuildDataAck(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, FlagNum,1);
- }
- break;
- case IEC10X_COT_DATA_NEEDACK:
- if (FlagNum == FirmFlagCount + 1)
- {
- /* check sum */
- csum = info->_element[2];
- for (i = 0; i < DataLen; i++)
- {
- CsumTemp += DataPtr[i];
- }
- if (CsumTemp == csum)
- {
- LOG("-%s-,data need ack:%d,Len:%d,seek:%d \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr);
- for (i = 0; i < 3; i++)
- {
- ret = iec104->save_firmware(DataLen, DataPtr, FirmwareType, Iec10x_Update_SeekAddr);
- if (ret == RET_SUCESS)
- break;
- }
- if (ret == RET_ERROR)
- {
- LOG("save firmware error \n");
- break;
- }
- iec104_build_data_ack(TI, IEC10X_COT_DATA_ACK, FirmwareType, FlagNum, 1);
- FirmFlagCount = FlagNum;
- Iec10x_Update_SeekAddr += DataLen;
- }
- else
- {
- LOG("%s,need ack check sum error:%d,need:%d,num...:%d\n", __FUNCTION__, CsumTemp, csum, FlagNum);
- // Iec104_BuildDataAck(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, FlagNum,1);
- }
- }
- else if (FlagNum < FirmFlagCount + 1)
- {
- LOG("update flag resend,need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
- iec104_build_data_ack(TI, IEC10X_COT_DATA_ACK, FirmwareType, FlagNum, 1);
- }
- else
- {
- LOG("update flag error! need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
- // Iec104_BuildDataAck(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, FlagNum,1);
- }
- break;
- case IEC10X_COT_DATA_FIN:
- if (FirmFlagCount == FlagNum)
- {
- LOG("-%s-,data finish:%d,Len:%d,Total Len:%d \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr);
- ret = iec104->check_firmware(FirmwareType, Iec10x_Update_SeekAddr);
- if (ret == RET_SUCESS)
- {
- iec104_build_data_ack(TI, IEC10X_COT_DATA_FIN_ACK, FirmwareType, FlagNum, 1);
- iec104->update_firmware(FirmwareType);
- }
- else
- {
- /* check firmware error ,terminal update */
- iec104_build_data_ack(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, 0, 1);
- }
- }
- else
- {
- LOG("-%s-,data finish error:%d,Len:%d,Total Len:%d,FirmFlagCount:%d,FlagNum:%d, \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr, FirmFlagCount, FlagNum);
- return RET_ERROR;
- }
- break;
- case IEC10X_COT_ACT_TERMINAL:
- LOG("-%s-, Terminal:%d,Len:%d \n", __FUNCTION__, FlagNum, DataLen);
- iec104_build_data_ack(TI, IEC10X_COT_ACT_TERMINAL_ACK, FirmwareType, 0, 1);
- break;
- case IEC10X_COT_ACT_TERMINAL_ACK:
- LOG("-%s-, Terminal Ack \n", __FUNCTION__);
- break;
- default:
- LOG("-%s-,data:%d,Len:%d error cot: \n", __FUNCTION__, FlagNum, Len);
- return RET_ERROR;
- }
- return RET_SUCESS;
- }
- void iec104_tester_timer(void)
- {
- IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
- Iec104_TimeCycle_TesterIdle = 0;
- }
- iec_8u iec104_deal_i(p_iec104_data_t Iec104_data, iec_16u len)
- {
- iec_8u Type;
- iec_16u RecvSn, SendSn;
- iec_32u FirmwareType = 0;
- p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
- SendSn = Iec104_data->ctrl.i.send_sn;
- RecvSn = Iec104_data->ctrl.i.recv_sn;
- /* check asdu addrest */
- if (iec104_state_addr != asdu->_addr)
- {
- LOG("-%s-, error asdu addr(%x)(%x) \n", __FUNCTION__, iec10x_state_addr, asdu->_addr);
- return RET_ERROR;
- }
- /* deal the receive and send serial number */
- if (iec104_deal_sn(SendSn, RecvSn) == RET_ERROR)
- {
- return RET_ERROR;
- }
- /* Start tester timer */
- iec104_tester_timer();
- Type = asdu->_type;
- switch (Type)
- {
- case IEC10X_C_IC_NA_1:
- LOG("++++Asdu Type Call cmd... \n");
- iec104_asdu_call(asdu);
- IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_IDLE;
- break;
- case IEC10X_C_CS_NA_1:
- LOG("++++Asdu Type Clock syc cmd... \n");
- iec104_asdu_clock(asdu);
- break;
- case IEC10X_C_SE_NA_1:
- case IEC10X_C_SE_NC_1:
- LOG("++++Asdu Type Set type(%d)... \n", Type);
- iec104_asdu_set_act(asdu, Type);
- iec104_build_set_ack(1, Type);
- break;
- case IEC10X_TI_FIRM_UPDATE:
- LOG("++++Asdu Type Firmware Update... \n");
- iec104_deal_firmware_update(asdu, len);
- break;
- case IEC10X_TI_AP_FIRM_BACKOFF:
- LOG("++++Asdu Type Firmware Backoff... \n");
- memcpy(&FirmwareType, asdu->_info, 3);
- iec104_build_data_ack(IEC10X_TI_AP_FIRM_BACKOFF, IEC10X_COT_ACTCON, FirmwareType, 0, 1);
- iec104->backoff_firmware(FirmwareType);
- break;
- default:
- LOG("-%s-, error Type(%d) \n", __FUNCTION__, Type);
- return RET_ERROR;
- }
- return RET_SUCESS;
- }
- iec_8u iec104_deal_s(p_iec104_data_t Iec104_data, iec_16u len)
- {
- return RET_SUCESS;
- }
- iec_8u iec104_deal_u(p_iec104_data_t iec104_data, iec_16u len)
- {
- switch (iec104_data->ctrl.func.func)
- {
- case IEC104_U_FUNC_STARTDT:
- LOG(">%s<, function STARTDT \n", __FUNCTION__);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_LINK_INIT;
- Iec104_TimeCycle = 0;
- Iec104_TimeCount = 0;
- // IEC104_Build_U(IEC104_U_FUNC_STARTDT,1);
- // IEC104_Build_InitFin();
- break;
- case IEC104_U_FUNC_STOPDT:
- LOG(">%s<, function STOPDT \n", __FUNCTION__);
- iec104->close_link();
- iec104_build_u(IEC104_U_FUNC_STOPDT, 1);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_RECV_CLOSED;
- break;
- case IEC104_U_FUNC_TESTER:
- LOG(">%s<, function TESTER \n", __FUNCTION__);
- iec104_build_u(IEC104_U_FUNC_TESTER, 1);
- break;
- /* U ACK */
- case IEC104_U_FUNC_STARTDT_ACK:
- LOG(">%s<, function STARTDT ACK\n", __FUNCTION__);
- break;
- case IEC104_U_FUNC_STOPDT_ACK:
- LOG(">%s<, function STOPDT ACK\n", __FUNCTION__);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_RECV_CLOSED;
- break;
- case IEC104_U_FUNC_TESTER_ACK:
- LOG(">%s<, function TESTER ACK\n", __FUNCTION__);
- Iec104_TesterCount = 0;
- break;
- default:
- LOG(">%s<, function ERROR \n", __FUNCTION__);
- break;
- }
- return RET_SUCESS;
- }
- void iec104_receive(iec_8u *buf, iec_16u len)
- {
- iec_8u *BufTemp = NULL;
- iec_16s LenRemain, LenTmp;
- p_iec104_data_t Iec104_data = NULL;
- if (buf == NULL)
- {
- LOG("-%s-,buffer (null)", __FUNCTION__);
- return;
- }
- #if 0
- if(len <= 0 || len>IEC104_MAX_BUF_LEN || len<BufTemp[0]+2){
- LOG("-%s-,buffer len error(%d) \n",__FUNCTION__,len);
- return;
- }
- #endif
- BufTemp = buf;
- LenRemain = len;
- while (BufTemp < buf + len)
- {
- Iec104_data = (p_iec104_data_t)BufTemp;
- iec104_lock();
- if (Iec104_data->head == IEC104_HEAD)
- {
- LenTmp = Iec104_data->len + 2;
- if (LenRemain < IEC104_HEAD_LEN)
- {
- LOG("_%s_,len error(%d) \n", __FUNCTION__, len);
- iec104_unlock();
- return;
- }
- if (Iec104_data->ctrl.type.type_1 == 0)
- {
- LOG("-%s-,frame type i \n", __FUNCTION__);
- iec104_deal_i(Iec104_data, LenTmp);
- }
- else if (Iec104_data->ctrl.type.type_1 == 1 && Iec104_data->ctrl.type.type_2 == 0)
- {
- LOG("-%s-,frame type s \n", __FUNCTION__);
- iec104_deal_s(Iec104_data, LenTmp);
- }
- else if (Iec104_data->ctrl.type.type_1 == 1 && Iec104_data->ctrl.type.type_2 == 1)
- {
- LOG("-%s-,frame type u \n", __FUNCTION__);
- iec104_deal_u(Iec104_data, LenTmp);
- }
- }
- else
- {
- LOG("-%s-,head type error(%d) \n", __FUNCTION__, BufTemp[0]);
- iec104_unlock();
- return;
- }
- iec104_unlock();
- BufTemp += LenTmp;
- LenRemain -= LenTmp;
- }
- return;
- }
- void iec104_reset_flag(void)
- {
- IEC104_STATE_FLAG_CALLALL = IEC104_FLAG_IDLE;
- IEC104_STATE_FLAG_GROUP = IEC104_FLAG_IDLE;
- IEC104_STATE_FLAG_CLOCK = IEC104_FLAG_IDLE;
- IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
- iec104_build_send_sn = 0;
- iec104_build_recv_sn = 0;
- iec104_deal_send_sn = -1;
- iec104_deal_recv_sn = 0;
- Iec104_TesterCount = 0;
- }
- iec_32u TestCount_Temp = 0;
- iec_8u iec104_state_machine(void)
- {
- /*Init link*/
- switch (IEC104_STATE_FLAG_INIT)
- {
- case IEC104_FLAG_CLOSED:
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_START_LINK;
- iec104_queue_clear();
- iec104_reset_flag();
- break;
- case IEC104_FLAG_SEND_CLOSED:
- Iec104_TimeCycle += IEC104_CYCLE_TIME_MS;
- if (Iec104_TimeCycle > IEC104_RESEND_TIME_MS)
- {
- Iec104_TimeCycle = 0;
- Iec104_TimeCount++;
- iec104_build_u(IEC104_U_FUNC_STOPDT, 0);
- }
- if (Iec104_TimeCount >= 3)
- {
- Iec104_TimeCount = 0;
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_IDLE;
- iec104->close_link();
- }
- break;
- case IEC104_FLAG_RECV_CLOSED:
- iec104_reset_flag();
- iec104_queue_clear();
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_CONNECT_SUCESS;
- break;
- case IEC104_FLAG_LINK_INIT:
- LOG("Iec104 machine state :IEC104_FLAG_LINK_INIT \n");
- iec104_reset_flag();
- iec104_state_addr = iec104->get_link_addr();
- iec104_build_u(IEC104_U_FUNC_STARTDT, 1);
- iec104_build_init_fin();
- iec104_build_upload(IEC10X_TI_AP_BASE_INFO, IEC10X_PRIO_INITLINK, AP_TYPE_BASE_INFO);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_CONNECT_SUCESS;
- break;
- case IEC104_FLAG_UPLOAD_ADDR:
- Iec104_TimeCycle += IEC104_CYCLE_TIME_MS;
- if (Iec104_TimeCycle > IEC104_RESEND_TIME_MS)
- {
- iec104_state_addr = iec104->get_link_addr();
- Iec104_TimeCycle = 0;
- Iec104_TimeCount++;
- iec104_upload_addr();
- }
- if (Iec104_TimeCount >= 3)
- {
- Iec104_TimeCount = 0;
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_IDLE;
- iec104->close_link();
- }
- break;
- case IEC104_FLAG_CONNECT_SUCESS:
- case IEC104_FLAG_IDLE:
- default:
- break;
- }
- if (IEC104_STATE_FLAG_INIT == IEC104_FLAG_CONNECT_SUCESS)
- {
- /* Return s ack */
- switch (IEC104_STATE_FLAG_S_ACK)
- {
- case IEC104_FLAG_S_ACK:
- Iec104_TimeCycle_S += IEC104_CYCLE_TIME_MS;
- if (Iec104_TimeCycle_S > IEC104_S_ACK_TIMEOUT)
- {
- Iec104_TimeCycle_S = 0;
- iec104_build_s_ack();
- IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_IDLE;
- }
- break;
- case IEC104_FLAG_IDLE:
- break;
- default:
- break;
- }
- /* test spon */
- #if 1
- if (TestCount_Temp++ > (10 * 60 * 20))
- {
- TestCount_Temp = 0;
- iec104_build_signal_spon(1, 1, IEC104_INFOADDR_STATE_HXGF + 2);
- iec104_build_detect_f_spont(1, 60.2, IEC104_INFOADDR_VALUE_HXTM + 2);
- iec104_build_detect_f_spont(1, 61.1, IEC104_INFOADDR_VALUE_HXGF + 2);
- }
- #endif
- }
- /* Tester */
- switch (IEC104_STATE_FLAG_TESTER)
- {
- case IEC104_FLAG_TESTER:
- iec104_build_u(IEC104_U_FUNC_TESTER, 0);
- IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
- Iec104_TesterCount++;
- LOG("Tester Count(%d)... \n", Iec104_TesterCount);
- if (Iec104_TesterCount > 3)
- {
- Iec104_TesterCount = 0;
- LOG("Tester error(%d)... \n", Iec104_TesterCount);
- IEC104_STATE_FLAG_INIT = IEC104_FLAG_CLOSED;
- iec104->close_link();
- }
- break;
- case IEC104_FLAG_TESTER_STOP:
- break;
- case IEC104_FLAG_IDLE:
- Iec104_TimeCycle_TesterIdle += IEC104_CYCLE_TIME_MS;
- if (Iec104_TimeCycle_TesterIdle > IEC104_TESTER_IDLE_TIMEOUT)
- {
- Iec104_TimeCycle_TesterIdle = 0;
- IEC104_STATE_FLAG_TESTER = IEC104_FLAG_TESTER;
- }
- break;
- default:
- break;
- }
- return RET_SUCESS;
- }
|