iec104.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. #include "iec104.h"
  2. iec_8u iec104_send_buf[IEC104_MAX_BUF_LEN];
  3. iec_8u IEC104_STATE_FLAG_INIT = IEC104_FLAG_CLOSED;
  4. iec_8u IEC104_STATE_FLAG_CALLALL = IEC104_FLAG_CLOSED;
  5. iec_8u IEC104_STATE_FLAG_GROUP = IEC104_FLAG_CLOSED;
  6. iec_8u IEC104_STATE_FLAG_CLOCK = IEC104_FLAG_CLOSED;
  7. iec_8u IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
  8. iec_8u IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_CLOSED;
  9. iec_32s iec104_build_send_sn = 0;
  10. iec_32s iec104_build_recv_sn = 0;
  11. iec_32s iec104_deal_send_sn = -1;
  12. iec_32s iec104_deal_recv_sn = 0;
  13. iec_8u IEC104_Call_AllQoi = 0;
  14. iec_8u IEC104_Call_GroupQoi = 0;
  15. #define IEC104_CYCLE_TIME_MS 100 /*100ms*/
  16. #define IEC104_RESEND_TIME_MS (30 * 1000) /*30s*/
  17. #define IEC104_S_ACK_TIMEOUT (5 * 1000) /*5s*/
  18. #define IEC104_TESTER_IDLE_TIMEOUT (1 * 30 * 1000) /*2min*/
  19. iec_32u Iec104_TimeCount = 0;
  20. iec_32u Iec104_TimeCycle = IEC104_RESEND_TIME_MS;
  21. iec_32u Iec104_TimeCycle_S = 0;
  22. iec_32u Iec104_TimeCycle_TesterIdle = 0;
  23. iec_8u Iec104_TesterCount = 0;
  24. iec_32u Iec10x_Update_SeekAddr = 0;
  25. iec_16u FirmFlagCount = 0;
  26. iec_8u iec104_upload_addr(void)
  27. {
  28. iec_8u len = 0;
  29. iec_8u *ptr = NULL;
  30. iec_32u temp32 = 0;
  31. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  32. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  33. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  34. /*build head*/
  35. Iec104_data->head = IEC104_HEAD;
  36. /*build control code*/
  37. Iec104_data->ctrl.i.type = 0;
  38. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  39. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  40. /*build ASDU , COT ,Addr*/
  41. asdu->_type = IEC104_ASDU_TYPE_M_DTU_INF_1;
  42. asdu->_num._sq = 0;
  43. asdu->_num._num = 1;
  44. asdu->_reason._reason = IEC10X_ASDU_COT_UNKNOW;
  45. asdu->_addr = iec104_state_addr;
  46. /*build info*/
  47. ptr = info->_addr;
  48. temp32 = 0;
  49. memcpy(ptr, &temp32, 3);
  50. ptr = info->_element;
  51. temp32 = IEC104_INFO_SIGNATURE;
  52. memcpy(ptr, &temp32, 4);
  53. ptr += 4;
  54. temp32 = iec104_state_addr;
  55. memcpy(ptr, &temp32, 2);
  56. ptr += 2;
  57. /*len*/
  58. len = ptr - iec104_send_buf;
  59. Iec104_data->len = len - 2;
  60. dump_hex(Iec104_Sendbuf, len);
  61. /* enqueue to the transmisson queue */
  62. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  63. return RET_SUCESS;
  64. }
  65. iec_8u iec104_build_init_fin(void)
  66. {
  67. iec_8u len = 0;
  68. iec_8u *ptr = NULL;
  69. iec_32u temp32 = 0;
  70. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  71. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  72. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  73. /*build head*/
  74. Iec104_data->head = IEC104_HEAD;
  75. /*build control code*/
  76. Iec104_data->ctrl.i.type = 0;
  77. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  78. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  79. /*build ASDU , COT ,Addr*/
  80. asdu->_type = Iec10x_M_EI_NA_1;
  81. asdu->_num._sq = 0;
  82. asdu->_num._num = 1;
  83. asdu->_reason._reason = IEC10X_ASDU_REASON_INIT;
  84. asdu->_addr = iec104_state_addr;
  85. /*build info*/
  86. ptr = info->_addr;
  87. temp32 = 0;
  88. memcpy(ptr, &temp32, 3);
  89. ptr = info->_element;
  90. // temp32 = 0;
  91. // memcpy(ptr, &temp32, 4);
  92. info->_element[0] = 0;
  93. ptr++;
  94. /*len*/
  95. len = ptr - iec104_send_buf;
  96. Iec104_data->len = len - 2;
  97. dump_hex(Iec104_Sendbuf, len);
  98. /* enqueue to the transmisson queue */
  99. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  100. return RET_SUCESS;
  101. }
  102. iec_8u iec104_build_call_ack(iec_8u qoi, iec_8u Prio)
  103. {
  104. iec_8u len = 0;
  105. iec_8u *ptr = NULL;
  106. iec_32u temp32 = 0;
  107. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  108. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  109. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  110. /*build head*/
  111. Iec104_data->head = IEC104_HEAD;
  112. /*build control code*/
  113. Iec104_data->ctrl.i.type = 0;
  114. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  115. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  116. /*build ASDU , COT ,Addr*/
  117. asdu->_type = IEC10X_C_IC_NA_1;
  118. asdu->_num._sq = 0;
  119. asdu->_num._num = 1;
  120. asdu->_reason._reason = IEC10X_ASDU_REASON_ACTCON;
  121. asdu->_addr = iec104_state_addr;
  122. /*build info*/
  123. ptr = info->_addr;
  124. temp32 = 0;
  125. memcpy(ptr, &temp32, 3);
  126. ptr = info->_element;
  127. ptr[0] = qoi;
  128. ptr += 1;
  129. /*len*/
  130. len = ptr - iec104_send_buf;
  131. Iec104_data->len = len - 2;
  132. dump_hex(Iec104_Sendbuf, len);
  133. /* enqueue to the transmisson queue */
  134. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  135. return RET_SUCESS;
  136. }
  137. iec_8u iec104_build_signal_spon(iec_8u time_flag, iec_8u v_signal, iec_16u v_addr)
  138. {
  139. iec_8u len = 0, asdu_num = 0, i;
  140. iec_8u *ptr = NULL;
  141. iec_32u temp32 = 0;
  142. PCP56Time2a_T time = NULL;
  143. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  144. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  145. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  146. /* check Time flag */
  147. if (time_flag != 1 && time_flag != 0)
  148. {
  149. LOG("-%s-, error time flag(%d) \n", __FUNCTION__, time_flag);
  150. return RET_ERROR;
  151. }
  152. LOG("-%s-, time flag(%d) signalV(%d) \n", __FUNCTION__, time_flag, v_signal);
  153. /*get value*/
  154. asdu_num = 1;
  155. /*build head*/
  156. Iec104_data->head = IEC104_HEAD;
  157. /*build control code*/
  158. Iec104_data->ctrl.i.type = 0;
  159. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  160. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  161. /*build ASDU , COT ,Addr*/
  162. if (time_flag == 0)
  163. asdu->_type = IEC10X_M_SP_NA_1;
  164. else
  165. asdu->_type = IEC10X_M_SP_TB_1;
  166. asdu->_num._sq = 1;
  167. asdu->_num._num = asdu_num;
  168. asdu->_reason._reason = IEC10X_COT_SPONT;
  169. asdu->_addr = iec104_state_addr;
  170. /*build info addr*/
  171. ptr = info->_addr;
  172. temp32 = v_addr;
  173. memcpy(ptr, &temp32, 3);
  174. /*build info value*/
  175. ptr = info->_element;
  176. for (i = 0; i < asdu_num; i++)
  177. {
  178. *ptr = v_signal;
  179. ptr++;
  180. }
  181. if (time_flag == 1)
  182. {
  183. time = (PCP56Time2a_T)ptr;
  184. iec104->get_time(time);
  185. ptr += sizeof(CP56Time2a_T);
  186. }
  187. /*len*/
  188. len = ptr - iec104_send_buf;
  189. Iec104_data->len = len - 2;
  190. // DumpHEX(Iec101_Sendbuf,len);
  191. /* enqueue to the transmisson queue */
  192. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_SPON, NULL, NULL);
  193. return RET_SUCESS;
  194. }
  195. iec_8u iec104_build_detect_spont(iec_8u TimeFlag, PIEC10X_DETECT_T detectV, iec_16u addrV)
  196. {
  197. iec_8u len = 0, asdu_num = 0;
  198. iec_8u *ptr = NULL;
  199. iec_32u temp32 = 0;
  200. PIEC10X_DETECT_T detect = NULL;
  201. PCP56Time2a_T time = NULL;
  202. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  203. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  204. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  205. /* check Time flag */
  206. if (TimeFlag != 1 && TimeFlag != 0)
  207. {
  208. LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
  209. return RET_ERROR;
  210. }
  211. /*get value*/
  212. asdu_num = 1;
  213. /*build head*/
  214. Iec104_data->head = IEC104_HEAD;
  215. /*build control code*/
  216. Iec104_data->ctrl.i.type = 0;
  217. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  218. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  219. /*build ASDU , COT ,Addr*/
  220. if (TimeFlag == 0)
  221. asdu->_type = IEC10X_M_ME_NA_1;
  222. else
  223. asdu->_type = IEC10X_M_ME_TD_1;
  224. asdu->_num._sq = 1;
  225. asdu->_num._num = asdu_num;
  226. asdu->_reason._reason = IEC10X_COT_SPONT;
  227. asdu->_addr = iec104_state_addr;
  228. /*build info addr*/
  229. ptr = info->_addr;
  230. temp32 = addrV;
  231. memcpy(ptr, &temp32, 3);
  232. /*build info value*/
  233. ptr = info->_element;
  234. detect = (PIEC10X_DETECT_T)ptr;
  235. detect->_detect = detectV->_detect;
  236. detect->_qds = detectV->_qds;
  237. ptr += sizeof(IEC10X_DETECT_T);
  238. if (TimeFlag == 1)
  239. {
  240. time = (PCP56Time2a_T)ptr;
  241. iec104->get_time(time);
  242. ptr += sizeof(CP56Time2a_T);
  243. }
  244. /*len*/
  245. len = ptr - iec104_send_buf;
  246. Iec104_data->len = len - 2;
  247. // DumpHEX(Iec101_Sendbuf,len);
  248. /* enqueue to the transmisson queue */
  249. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_SPON, NULL, NULL);
  250. return RET_SUCESS;
  251. }
  252. iec_8u iec104_build_detect_f_spont(iec_8u TimeFlag, float detectV, iec_16u addrV)
  253. {
  254. iec_8u len = 0, asdu_num = 0;
  255. iec_8u *ptr = NULL;
  256. iec_32u temp32 = 0;
  257. PIEC10X_DETECT_F_T detect = NULL;
  258. PCP56Time2a_T time = NULL;
  259. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  260. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  261. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  262. /* check Time flag */
  263. if (TimeFlag != 1 && TimeFlag != 0)
  264. {
  265. LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
  266. return RET_ERROR;
  267. }
  268. /*get value*/
  269. asdu_num = 1;
  270. /*build head*/
  271. Iec104_data->head = IEC104_HEAD;
  272. /*build control code*/
  273. Iec104_data->ctrl.i.type = 0;
  274. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  275. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  276. /*build ASDU , COT ,Addr*/
  277. if (TimeFlag == 0)
  278. asdu->_type = IEC10X_M_ME_NC_1;
  279. else
  280. asdu->_type = IEC10X_M_ME_TF_1;
  281. asdu->_num._sq = 1;
  282. asdu->_num._num = asdu_num;
  283. asdu->_reason._reason = IEC10X_COT_SPONT;
  284. asdu->_addr = iec104_state_addr;
  285. /*build info addr*/
  286. ptr = info->_addr;
  287. temp32 = addrV;
  288. memcpy(ptr, &temp32, 3);
  289. /*build info value*/
  290. ptr = info->_element;
  291. detect = (PIEC10X_DETECT_F_T)ptr;
  292. detect->_detect = detectV;
  293. detect->_qds = 0;
  294. ptr += sizeof(IEC10X_DETECT_F_T);
  295. if (TimeFlag == 1)
  296. {
  297. time = (PCP56Time2a_T)ptr;
  298. iec104->get_time(time);
  299. ptr += sizeof(CP56Time2a_T);
  300. }
  301. /*len*/
  302. len = ptr - iec104_send_buf;
  303. Iec104_data->len = len - 2;
  304. // DumpHEX(Iec101_Sendbuf,len);
  305. /* enqueue to the transmisson queue */
  306. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_SPON, NULL, NULL);
  307. return RET_SUCESS;
  308. }
  309. iec_8u iec104_build_signal(iec_8u reason, iec_8u Prio, iec_8u dev_type)
  310. {
  311. iec_8u len = 0, asdu_num = 0;
  312. iec_16u i = 0;
  313. iec_8u *ptr = NULL;
  314. iec_32u temp32 = 0;
  315. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  316. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  317. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  318. /*get value*/
  319. iec104->get_info_num(&asdu_num, dev_type);
  320. LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
  321. /*build head*/
  322. Iec104_data->head = IEC104_HEAD;
  323. /*build control code*/
  324. Iec104_data->ctrl.i.type = 0;
  325. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  326. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  327. /*build ASDU , COT ,Addr*/
  328. asdu->_type = IEC10X_M_SP_NA_1;
  329. asdu->_num._sq = 1;
  330. asdu->_num._num = asdu_num;
  331. asdu->_reason._reason = reason;
  332. asdu->_addr = iec104_state_addr;
  333. /*build info addr*/
  334. ptr = info->_addr;
  335. if (dev_type == ENDDEVICE_TYPE_HXTM)
  336. {
  337. temp32 = IEC104_INFOADDR_STATE_HXTM;
  338. }
  339. else if (dev_type == ENDDEVICE_TYPE_HXGF)
  340. {
  341. temp32 = IEC104_INFOADDR_STATE_HXGF;
  342. }
  343. else
  344. {
  345. LOG("-%s-, error dev type:%d \n", __FUNCTION__, dev_type);
  346. return RET_ERROR;
  347. }
  348. memcpy(ptr, &temp32, 3);
  349. /*build info value*/
  350. ptr = info->_element;
  351. for (i = 0; i < asdu_num; i++)
  352. {
  353. *ptr = iec104->get_station_state(i, dev_type);
  354. ptr++;
  355. }
  356. /*len*/
  357. len = ptr - iec104_send_buf;
  358. Iec104_data->len = len - 2;
  359. // DumpHEX(Iec101_Sendbuf,len);
  360. /* enqueue to the transmisson queue */
  361. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  362. return RET_SUCESS;
  363. }
  364. iec_8u iec104_build_detect(iec_8u reason, iec_8u ValueType, iec_8u Prio, iec_8u dev_type)
  365. {
  366. iec_8u len = 0, asdu_num = 0, i;
  367. iec_8u *ptr = NULL;
  368. iec_32u temp32 = 0;
  369. PIEC10X_DETECT_T detect = NULL;
  370. PIEC10X_DETECT_F_T detect_f = NULL;
  371. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  372. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  373. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  374. /*get value*/
  375. iec104->get_info_num(&asdu_num, dev_type);
  376. LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
  377. /*build head*/
  378. Iec104_data->head = IEC104_HEAD;
  379. /*build control code*/
  380. Iec104_data->ctrl.i.type = 0;
  381. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  382. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  383. /*build ASDU , COT ,Addr*/
  384. asdu->_type = ValueType;
  385. asdu->_num._sq = 1;
  386. asdu->_num._num = asdu_num;
  387. asdu->_reason._reason = reason;
  388. asdu->_addr = iec104_state_addr;
  389. /*build info addr*/
  390. ptr = info->_addr;
  391. if (dev_type == ENDDEVICE_TYPE_HXTM)
  392. {
  393. temp32 = IEC104_INFOADDR_VALUE_HXTM;
  394. }
  395. else if (dev_type == ENDDEVICE_TYPE_HXGF)
  396. {
  397. temp32 = IEC104_INFOADDR_VALUE_HXGF;
  398. }
  399. else
  400. {
  401. LOG("-%s-, error dev type:%d \n", __FUNCTION__, dev_type);
  402. return RET_ERROR;
  403. }
  404. memcpy(ptr, &temp32, 3);
  405. /*Build Detect value*/
  406. ptr = info->_element;
  407. for (i = 0; i < asdu_num; i++)
  408. {
  409. /*short int*/
  410. if (ValueType == IEC10X_M_ME_NA_1)
  411. {
  412. detect = (PIEC10X_DETECT_T)ptr;
  413. detect->_detect = iec104->get_sta_value(i, dev_type);
  414. detect->_qds = 0;
  415. ptr += sizeof(IEC10X_DETECT_T);
  416. }
  417. /*float*/
  418. else if (ValueType == IEC10X_M_ME_NC_1)
  419. {
  420. detect_f = (PIEC10X_DETECT_F_T)ptr;
  421. detect_f->_detect = iec104->get_sta_value(i, dev_type);
  422. detect_f->_qds = 0;
  423. ptr += sizeof(IEC10X_DETECT_F_T);
  424. }
  425. }
  426. /*len*/
  427. len = ptr - iec104_send_buf;
  428. Iec104_data->len = len - 2;
  429. // DumpHEX(Iec101_Sendbuf,len);
  430. /* enqueue to the transmisson queue */
  431. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  432. return RET_SUCESS;
  433. }
  434. iec_8u iec104_build_upload(iec_8u ValueType, iec_8u Prio, iec_8u dev_type)
  435. {
  436. iec_8u len = 0, asdu_num = 0, i;
  437. iec_8u *ptr = NULL;
  438. iec_32u temp32 = 0;
  439. PIEC10X_DETECT_T detect = NULL;
  440. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  441. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  442. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  443. /*get value*/
  444. iec104->get_info_num(&asdu_num, dev_type);
  445. LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
  446. /*build head*/
  447. Iec104_data->head = IEC104_HEAD;
  448. /*build control code*/
  449. Iec104_data->ctrl.i.type = 0;
  450. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  451. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  452. /*build ASDU , COT ,Addr*/
  453. asdu->_type = ValueType;
  454. asdu->_num._sq = 1;
  455. asdu->_num._num = asdu_num;
  456. asdu->_reason._reason = AP_COT_BASE_INFO;
  457. asdu->_addr = iec104_state_addr;
  458. /*build info addr*/
  459. ptr = info->_addr;
  460. temp32 = IEC104_INFOADDR_BASE_DEVINFO;
  461. memcpy(ptr, &temp32, 3);
  462. ptr += 3;
  463. /*Build Detect value*/
  464. ptr = info->_element;
  465. for (i = 0; i < asdu_num; i++)
  466. {
  467. detect = (PIEC10X_DETECT_T)ptr;
  468. detect->_detect = iec104->get_sta_value(i, dev_type);
  469. detect->_qds = 0;
  470. ptr += sizeof(IEC10X_DETECT_T);
  471. }
  472. /*len*/
  473. len = ptr - iec104_send_buf;
  474. Iec104_data->len = len - 2;
  475. // DumpHEX(Iec101_Sendbuf,len);
  476. /* enqueue to the transmisson queue */
  477. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  478. return RET_SUCESS;
  479. }
  480. iec_8u iec104_build_act_finish(iec_8u qoi, iec_8u Prio)
  481. {
  482. iec_8u len = 0, asdu_num = 0;
  483. iec_8u *ptr = NULL;
  484. iec_32u temp32 = 0;
  485. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  486. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  487. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  488. /*build head*/
  489. Iec104_data->head = IEC104_HEAD;
  490. /*build control code*/
  491. Iec104_data->ctrl.i.type = 0;
  492. Iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  493. Iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  494. /*build ASDU , COT ,Addr*/
  495. asdu->_type = IEC10X_C_IC_NA_1;
  496. asdu->_num._sq = 1;
  497. asdu->_num._num = asdu_num;
  498. asdu->_reason._reason = IEC10X_ASDU_REASON_ACTTERM;
  499. asdu->_addr = iec104_state_addr;
  500. /*build info addr*/
  501. ptr = info->_addr;
  502. temp32 = IEC10X_INFO_ADDR_SIG_BASE + IEC10X_INFO_ADDR_SIG_TEMP_HX_OFF;
  503. memcpy(ptr, &temp32, 3);
  504. /*Build Detect value*/
  505. ptr = info->_element;
  506. ptr[0] = qoi;
  507. ptr += 1;
  508. /*len*/
  509. len = ptr - iec104_send_buf;
  510. Iec104_data->len = len - 2;
  511. // DumpHEX(Iec101_Sendbuf,len);
  512. /* enqueue to the transmisson queue */
  513. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  514. return RET_SUCESS;
  515. }
  516. iec_8u iec104_build_u(iec_8u UType, iec_8u Ack)
  517. {
  518. iec_8u len = 0, Tester, Start, Stop;
  519. iec_8u *ptr = NULL;
  520. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  521. /*build head*/
  522. Iec104_data->head = IEC104_HEAD;
  523. /*build control code*/
  524. if (Ack)
  525. {
  526. Tester = IEC104_U_FUNC_TESTER_ACK;
  527. Start = IEC104_U_FUNC_STARTDT_ACK;
  528. Stop = IEC104_U_FUNC_STOPDT_ACK;
  529. }
  530. else
  531. {
  532. Tester = IEC104_U_FUNC_TESTER;
  533. Start = IEC104_U_FUNC_STARTDT;
  534. Stop = IEC104_U_FUNC_STOPDT;
  535. }
  536. switch (UType)
  537. {
  538. case IEC104_U_FUNC_STARTDT:
  539. Iec104_data->ctrl.func.func = Start;
  540. break;
  541. case IEC104_U_FUNC_STOPDT:
  542. Iec104_data->ctrl.func.func = Stop;
  543. break;
  544. case IEC104_U_FUNC_TESTER:
  545. Iec104_data->ctrl.func.func = Tester;
  546. break;
  547. default:
  548. LOG(">%s<, U Type Error(%d) !\n", __FUNCTION__, UType);
  549. return RET_ERROR;
  550. }
  551. /*build ASDU , COT ,Addr*/
  552. ptr = Iec104_data->asdu;
  553. /*build info*/
  554. /*len*/
  555. len = ptr - iec104_send_buf;
  556. Iec104_data->len = len - 2;
  557. // DumpHEX(Iec101_Sendbuf,len);
  558. /* enqueue to the transmisson queue */
  559. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  560. return RET_SUCESS;
  561. }
  562. iec_8u iec104_build_s_ack(void)
  563. {
  564. iec_8u len = 0;
  565. iec_8u *ptr = NULL;
  566. p_iec104_data_t Iec104_data = (p_iec104_data_t)iec104_send_buf;
  567. /*build head*/
  568. Iec104_data->head = IEC104_HEAD;
  569. /*build control code*/
  570. Iec104_data->ctrl.s.type_1 = 1;
  571. Iec104_data->ctrl.s.type_2 = 0;
  572. Iec104_data->ctrl.s.reserve = 0;
  573. Iec104_data->ctrl.s.recv_sn = iec104_build_recv_sn;
  574. /*build ASDU , COT ,Addr*/
  575. ptr = Iec104_data->asdu;
  576. /*build info*/
  577. /*len*/
  578. len = ptr - iec104_send_buf;
  579. Iec104_data->len = len - 2;
  580. // DumpHEX(Iec101_Sendbuf,len);
  581. /* enqueue to the transmisson queue */
  582. iec104_enqueue(iec104_send_buf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  583. return RET_SUCESS;
  584. }
  585. iec_8u iec104_asdu_call(p_iec10x_asdu_t Iec10x_Asdu)
  586. {
  587. p_asdu_info_t asdu_info = (p_asdu_info_t)(Iec10x_Asdu->_info);
  588. iec_8u qoi = asdu_info->_element[0];
  589. iec_8u Prio = 0;
  590. iec_32u InfoAddr = 0;
  591. /* check info addrest */
  592. memcpy(&InfoAddr, asdu_info->_addr, 3);
  593. if (InfoAddr != 0)
  594. {
  595. LOG("-%s- call cmd active error addr(%x) \n", __FUNCTION__, InfoAddr);
  596. return RET_ERROR;
  597. }
  598. switch (Iec10x_Asdu->_reason._reason)
  599. {
  600. case IEC10X_ASDU_REASON_ACT:
  601. switch (qoi)
  602. {
  603. case IEC10X_CALL_QOI_TOTAL:
  604. Prio = IEC10X_PRIO_CALLALL;
  605. IEC104_STATE_FLAG_CALLALL = IEC104_FLAG_CALL_ALLDATA;
  606. IEC104_Call_AllQoi = qoi;
  607. break;
  608. case IEC10X_CALL_QOI_GROUP1:
  609. case IEC10X_CALL_QOI_GROUP2:
  610. case IEC10X_CALL_QOI_GROUP9:
  611. case IEC10X_CALL_QOI_GROUP10:
  612. Prio = IEC10X_PRIO_CALLGROUP;
  613. IEC104_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROURPDATA;
  614. IEC104_Call_GroupQoi = qoi;
  615. break;
  616. default:
  617. LOG("-%s- call cmd error qoi(%d) \n", __FUNCTION__, qoi);
  618. return RET_ERROR;
  619. }
  620. iec104_build_call_ack(qoi, Prio);
  621. /**/
  622. iec104_build_signal(qoi, Prio, ENDDEVICE_TYPE_HXTM);
  623. iec104_build_detect(qoi, IEC10X_M_ME_NA_1, Prio, ENDDEVICE_TYPE_HXTM);
  624. /**/
  625. iec104_build_signal(qoi, Prio, ENDDEVICE_TYPE_HXGF);
  626. iec104_build_detect(qoi, IEC10X_M_ME_NA_1, Prio, ENDDEVICE_TYPE_HXGF);
  627. iec104_build_act_finish(qoi, Prio);
  628. break;
  629. default:
  630. LOG("-%s- call cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
  631. break;
  632. }
  633. return RET_SUCESS;
  634. }
  635. iec_8u iec104_asdu_clock(p_iec10x_asdu_t Iec10x_Asdu)
  636. {
  637. p_asdu_info_t asdu_info = (p_asdu_info_t)(Iec10x_Asdu->_info);
  638. memcpy(&IEC10X_Cp56time2a, asdu_info->_element, sizeof(CP56Time2a_T));
  639. if (asdu_info->_addr[0] != 0 || asdu_info->_addr[1] != 0 || asdu_info->_addr[2] != 0)
  640. {
  641. LOG("-%s- Clock cmd error addr(0x%02x:%02x:%02x) \n", __FUNCTION__, asdu_info->_addr[0], asdu_info->_addr[2], asdu_info->_addr[2]);
  642. return RET_ERROR;
  643. }
  644. switch (Iec10x_Asdu->_reason._reason)
  645. {
  646. case IEC10X_COT_ACT:
  647. 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,
  648. IEC10X_Cp56time2a._day._dayofweek, IEC10X_Cp56time2a._hour._hours, IEC10X_Cp56time2a._min._minutes, IEC10X_Cp56time2a._milliseconds);
  649. /*get time*/
  650. /*...*/
  651. iec104->set_time(&IEC10X_Cp56time2a);
  652. // IEC104_Build_S_Ack();
  653. break;
  654. case IEC10X_COT_SPONT:
  655. LOG("-%s- Clock cmd spont \n", __FUNCTION__);
  656. break;
  657. default:
  658. LOG("-%s- Clock cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
  659. break;
  660. }
  661. return RET_SUCESS;
  662. }
  663. iec_8u iec104_asdu_set_act(p_iec10x_asdu_t Iec10x_Asdu, iec_8u Type)
  664. {
  665. p_asdu_info_t asdu_info = (p_asdu_info_t)(Iec10x_Asdu->_info);
  666. iec_8u *ptr = NULL;
  667. iec_8u n = Iec10x_Asdu->_num._num, Sq = Iec10x_Asdu->_num._sq, i;
  668. float Value = 0.0;
  669. iec_32u InfoAddr = 0;
  670. /* if sq == 1 */
  671. PIEC10X_DETECT_T detect = NULL;
  672. PIEC10X_DETECT_F_T detect_f = NULL;
  673. /* if sq == 0 */
  674. PIEC10X_DETECT_SQ0_T detect_Sq0 = NULL;
  675. PIEC10X_DETECT_SQ0_F_T detect_Sq0_f = NULL;
  676. /* check info addrest */
  677. memcpy(&InfoAddr, asdu_info->_addr, 3);
  678. switch (Iec10x_Asdu->_reason._reason)
  679. {
  680. case IEC10X_COT_ACT:
  681. switch (Type)
  682. {
  683. case IEC10X_C_SE_NA_1:
  684. if (Sq == 1)
  685. {
  686. ptr = asdu_info->_element;
  687. for (i = 0; i < n; i++)
  688. {
  689. detect = (PIEC10X_DETECT_T)ptr;
  690. Value = (float)(detect->_detect);
  691. ptr += sizeof(IEC10X_DETECT_T);
  692. iec104->set_config(Value, InfoAddr + i);
  693. }
  694. }
  695. else if (Sq == 0)
  696. {
  697. ptr = Iec10x_Asdu->_info;
  698. for (i = 0; i < n; i++)
  699. {
  700. detect_Sq0 = (PIEC10X_DETECT_SQ0_T)ptr;
  701. Value = (float)(detect_Sq0->_detect);
  702. InfoAddr = 0;
  703. memcpy(&InfoAddr, detect_Sq0->_addr, 3);
  704. iec104->set_config(Value, InfoAddr);
  705. ptr += sizeof(IEC10X_DETECT_SQ0_T);
  706. }
  707. }
  708. break;
  709. case IEC10X_C_SE_NC_1:
  710. if (Sq == 1)
  711. {
  712. ptr = asdu_info->_element;
  713. for (i = 0; i < n; i++)
  714. {
  715. detect_f = (PIEC10X_DETECT_F_T)ptr;
  716. Value = detect_f->_detect;
  717. ptr += sizeof(IEC10X_DETECT_F_T);
  718. iec104->set_config(Value, InfoAddr + i);
  719. }
  720. }
  721. else if (Sq == 0)
  722. {
  723. ptr = Iec10x_Asdu->_info;
  724. for (i = 0; i < n; i++)
  725. {
  726. detect_Sq0_f = (PIEC10X_DETECT_SQ0_F_T)ptr;
  727. Value = (float)(detect_Sq0_f->_detect);
  728. memcpy(&InfoAddr, detect_Sq0_f->_addr, 3);
  729. iec104->set_config(Value, InfoAddr);
  730. ptr += sizeof(IEC10X_DETECT_SQ0_F_T);
  731. }
  732. }
  733. break;
  734. default:
  735. LOG("-%s-, Type error !", __FUNCTION__);
  736. return RET_ERROR;
  737. }
  738. break;
  739. default:
  740. LOG("-%s- , error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
  741. return RET_ERROR;
  742. }
  743. return RET_SUCESS;
  744. }
  745. iec_8u iec104_build_set_ack(iec_8u Prio, iec_8u Type)
  746. {
  747. iec_8u len = 0;
  748. iec_8u *ptr = NULL;
  749. p_iec104_data_t iec104_data = (p_iec104_data_t)iec104_send_buf;
  750. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(iec104_data->asdu);
  751. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  752. /*build head*/
  753. iec104_data->head = IEC104_HEAD;
  754. /*build control code*/
  755. iec104_data->ctrl.i.type = 0;
  756. iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  757. iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  758. /*build ASDU , COT ,Addr*/
  759. asdu->_type = Type;
  760. asdu->_num._sq = 0;
  761. asdu->_num._num = 0;
  762. asdu->_reason._reason = IEC10X_ASDU_REASON_ACTFIN;
  763. asdu->_addr = iec104_state_addr;
  764. /*build info*/
  765. ptr = info->_addr;
  766. /*len*/
  767. len = ptr - iec104_send_buf;
  768. iec104_data->len = len - 2;
  769. // DumpHEX(Iec104_Sendbuf,len);
  770. /* enqueue to the transmisson queue */
  771. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  772. return RET_SUCESS;
  773. }
  774. iec_8u iec104_deal_sn(iec_16u SendSn, iec_16u RecvSn)
  775. {
  776. LOG("Receive Pakage I(%d,%d), Send(%d,%d)\n", SendSn, RecvSn, iec104_build_send_sn, iec104_build_recv_sn);
  777. #if 0
  778. if(SendSn > Iec104_DealSendSn+1){
  779. LOG("-%s-, error,send last(%d),now(%d) \n",__FUNCTION__,Iec104_DealSendSn,SendSn);
  780. IEC104_STATE_FLAG_INIT = IEC104_FLAG_SEND_CLOSED;
  781. return RET_ERROR;
  782. }else if(SendSn < Iec104_DealSendSn+1){
  783. LOG("-%s-, Retransmit,send last(%d),now(%d) \n",__FUNCTION__,Iec104_DealSendSn,SendSn);
  784. return RET_ERROR;
  785. }
  786. if(RecvSn != Iec104_BuildSendSn){
  787. LOG("-%s-, error,receive last(%d),now(%d) \n",__FUNCTION__,Iec104_BuildSendSn,RecvSn);
  788. IEC104_STATE_FLAG_INIT = IEC104_FLAG_SEND_CLOSED;
  789. return RET_ERROR;
  790. }
  791. if(RecvSn < Iec104_DealRecvSn){
  792. LOG("-%s-, error,receive2 last(%d),now(%d) \n",__FUNCTION__,Iec104_DealRecvSn,RecvSn);
  793. return RET_ERROR;
  794. }
  795. #endif
  796. if (SendSn < iec104_deal_send_sn || RecvSn < iec104_deal_recv_sn)
  797. {
  798. LOG("-%s-, error,send last(%d),now(%d). recv last(%d),now(%d) \n", __FUNCTION__,
  799. iec104_deal_send_sn, SendSn, iec104_deal_recv_sn, RecvSn);
  800. return RET_ERROR;
  801. }
  802. iec104_build_recv_sn = SendSn + 1;
  803. iec104_deal_send_sn = SendSn;
  804. iec104_deal_recv_sn = RecvSn;
  805. // Iec104_BuildRecvSn++;
  806. /* return S ACK */
  807. IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_S_ACK;
  808. Iec104_TimeCycle_S = 0;
  809. return RET_SUCESS;
  810. }
  811. iec_8s iec104_build_data_ack(iec_8u TI, iec_16u COT, iec_32u InfoAddr, iec_16u Info, iec_8u Prio)
  812. {
  813. iec_8u len = 0;
  814. iec_8u *ptr = NULL;
  815. iec_32u temp32 = 0;
  816. /* build head */
  817. p_iec104_data_t iec104_data = (p_iec104_data_t)iec104_send_buf;
  818. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(iec104_data->asdu);
  819. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  820. /*build head*/
  821. iec104_data->head = IEC104_HEAD;
  822. /*build control code*/
  823. iec104_data->ctrl.i.type = 0;
  824. iec104_data->ctrl.i.send_sn = iec104_build_send_sn++;
  825. iec104_data->ctrl.i.recv_sn = iec104_build_recv_sn;
  826. /*build ASDU , COT ,Addr*/
  827. asdu->_type = TI;
  828. asdu->_num._sq = 0;
  829. asdu->_num._num = 1;
  830. asdu->_reason._reason = COT;
  831. asdu->_addr = iec104_state_addr;
  832. /*build info*/
  833. ptr = info->_addr;
  834. temp32 = InfoAddr;
  835. memcpy(ptr, &temp32, 3);
  836. ptr = info->_element;
  837. if (COT == IEC10X_COT_ACT_TERMINAL || COT == IEC10X_COT_ACTCON || COT == IEC10X_COT_ACT_TERMINAL_ACK || COT == IEC10X_TI_AP_FIRM_BACKOFF)
  838. {
  839. ptr[0] = 0;
  840. ptr[1] = 0;
  841. ptr += 2;
  842. }
  843. else if (COT == IEC10X_COT_DATA_ACK || COT == IEC10X_COT_DATA_FIN_ACK)
  844. {
  845. memcpy(ptr, &Info, 2);
  846. ptr += 2;
  847. }
  848. /*len*/
  849. len = ptr - iec104_send_buf;
  850. iec104_data->len = len - 2;
  851. // DumpHEX(Iec104_Sendbuf,len);
  852. /* enqueue to the transmisson queue */
  853. iec104_enqueue(iec104_send_buf, len, Prio, NULL, NULL);
  854. return RET_SUCESS;
  855. }
  856. iec_8s iec104_deal_firmware_update(p_iec10x_asdu_t asdu, iec_8u Len)
  857. {
  858. iec_16u cot = asdu->_reason._reason;
  859. iec_16u FlagNum = 0, i;
  860. iec_8u DataLen = Len - IEC104_DATA_LEN - 3; /* flag num 2, check sum 1 byte*/
  861. p_asdu_info_t element = (p_asdu_info_t)(asdu->_info);
  862. iec_8u *DataPtr = (iec_8u *)(element->_element) + 3;
  863. iec_8u TI = asdu->_type, csum = 0, CsumTemp = 0;
  864. iec_32u FirmwareType = 0;
  865. iec_8s ret = 0;
  866. p_asdu_info_t info = (p_asdu_info_t)(asdu->_info);
  867. FlagNum = *(iec_16u *)(info->_element);
  868. memcpy(&FirmwareType, asdu->_info, 3);
  869. if (Len == 0)
  870. {
  871. LOG("-%s-,data:%d,Len:%d error!\n", __FUNCTION__, FlagNum, DataLen);
  872. return RET_ERROR;
  873. }
  874. /* reset the flag counter */
  875. if (FlagNum == 1)
  876. {
  877. FirmFlagCount = 0;
  878. Iec10x_Update_SeekAddr = 0;
  879. }
  880. switch (cot)
  881. {
  882. case IEC10X_COT_DATA:
  883. if (FlagNum == FirmFlagCount + 1)
  884. {
  885. /* check sum */
  886. csum = info->_element[2];
  887. for (i = 0; i < DataLen; i++)
  888. {
  889. CsumTemp += DataPtr[i];
  890. }
  891. if (CsumTemp == csum)
  892. {
  893. LOG("-%s-,data:%d,Len:%d,seek:%d \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr);
  894. for (i = 0; i < 3; i++)
  895. {
  896. ret = iec104->save_firmware(DataLen, DataPtr, FirmwareType, Iec10x_Update_SeekAddr);
  897. if (ret == RET_SUCESS)
  898. break;
  899. }
  900. if (ret == RET_ERROR)
  901. {
  902. LOG("save firmware error \n");
  903. break;
  904. }
  905. FirmFlagCount = FlagNum;
  906. Iec10x_Update_SeekAddr += DataLen;
  907. }
  908. else
  909. {
  910. LOG("%s, check sum error:%d,need:%d,num:%d\n", __FUNCTION__, CsumTemp, csum, FlagNum);
  911. }
  912. }
  913. else if (FlagNum < FirmFlagCount + 1)
  914. {
  915. LOG("update flag resend,need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
  916. }
  917. else
  918. {
  919. LOG("update flag error! need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
  920. // Iec104_BuildDataAck(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, FlagNum,1);
  921. }
  922. break;
  923. case IEC10X_COT_DATA_NEEDACK:
  924. if (FlagNum == FirmFlagCount + 1)
  925. {
  926. /* check sum */
  927. csum = info->_element[2];
  928. for (i = 0; i < DataLen; i++)
  929. {
  930. CsumTemp += DataPtr[i];
  931. }
  932. if (CsumTemp == csum)
  933. {
  934. LOG("-%s-,data need ack:%d,Len:%d,seek:%d \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr);
  935. for (i = 0; i < 3; i++)
  936. {
  937. ret = iec104->save_firmware(DataLen, DataPtr, FirmwareType, Iec10x_Update_SeekAddr);
  938. if (ret == RET_SUCESS)
  939. break;
  940. }
  941. if (ret == RET_ERROR)
  942. {
  943. LOG("save firmware error \n");
  944. break;
  945. }
  946. iec104_build_data_ack(TI, IEC10X_COT_DATA_ACK, FirmwareType, FlagNum, 1);
  947. FirmFlagCount = FlagNum;
  948. Iec10x_Update_SeekAddr += DataLen;
  949. }
  950. else
  951. {
  952. LOG("%s,need ack check sum error:%d,need:%d,num...:%d\n", __FUNCTION__, CsumTemp, csum, FlagNum);
  953. // Iec104_BuildDataAck(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, FlagNum,1);
  954. }
  955. }
  956. else if (FlagNum < FirmFlagCount + 1)
  957. {
  958. LOG("update flag resend,need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
  959. iec104_build_data_ack(TI, IEC10X_COT_DATA_ACK, FirmwareType, FlagNum, 1);
  960. }
  961. else
  962. {
  963. LOG("update flag error! need:%d,flag:%d\n", FirmFlagCount + 1, FlagNum);
  964. // Iec104_BuildDataAck(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, FlagNum,1);
  965. }
  966. break;
  967. case IEC10X_COT_DATA_FIN:
  968. if (FirmFlagCount == FlagNum)
  969. {
  970. LOG("-%s-,data finish:%d,Len:%d,Total Len:%d \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr);
  971. ret = iec104->check_firmware(FirmwareType, Iec10x_Update_SeekAddr);
  972. if (ret == RET_SUCESS)
  973. {
  974. iec104_build_data_ack(TI, IEC10X_COT_DATA_FIN_ACK, FirmwareType, FlagNum, 1);
  975. iec104->update_firmware(FirmwareType);
  976. }
  977. else
  978. {
  979. /* check firmware error ,terminal update */
  980. iec104_build_data_ack(TI, IEC10X_COT_ACT_TERMINAL, FirmwareType, 0, 1);
  981. }
  982. }
  983. else
  984. {
  985. LOG("-%s-,data finish error:%d,Len:%d,Total Len:%d,FirmFlagCount:%d,FlagNum:%d, \n", __FUNCTION__, FlagNum, DataLen, Iec10x_Update_SeekAddr, FirmFlagCount, FlagNum);
  986. return RET_ERROR;
  987. }
  988. break;
  989. case IEC10X_COT_ACT_TERMINAL:
  990. LOG("-%s-, Terminal:%d,Len:%d \n", __FUNCTION__, FlagNum, DataLen);
  991. iec104_build_data_ack(TI, IEC10X_COT_ACT_TERMINAL_ACK, FirmwareType, 0, 1);
  992. break;
  993. case IEC10X_COT_ACT_TERMINAL_ACK:
  994. LOG("-%s-, Terminal Ack \n", __FUNCTION__);
  995. break;
  996. default:
  997. LOG("-%s-,data:%d,Len:%d error cot: \n", __FUNCTION__, FlagNum, Len);
  998. return RET_ERROR;
  999. }
  1000. return RET_SUCESS;
  1001. }
  1002. void iec104_tester_timer(void)
  1003. {
  1004. IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
  1005. Iec104_TimeCycle_TesterIdle = 0;
  1006. }
  1007. iec_8u iec104_deal_i(p_iec104_data_t Iec104_data, iec_16u len)
  1008. {
  1009. iec_8u Type;
  1010. iec_16u RecvSn, SendSn;
  1011. iec_32u FirmwareType = 0;
  1012. p_iec10x_asdu_t asdu = (p_iec10x_asdu_t)(Iec104_data->asdu);
  1013. SendSn = Iec104_data->ctrl.i.send_sn;
  1014. RecvSn = Iec104_data->ctrl.i.recv_sn;
  1015. /* check asdu addrest */
  1016. if (iec104_state_addr != asdu->_addr)
  1017. {
  1018. LOG("-%s-, error asdu addr(%x)(%x) \n", __FUNCTION__, iec10x_state_addr, asdu->_addr);
  1019. return RET_ERROR;
  1020. }
  1021. /* deal the receive and send serial number */
  1022. if (iec104_deal_sn(SendSn, RecvSn) == RET_ERROR)
  1023. {
  1024. return RET_ERROR;
  1025. }
  1026. /* Start tester timer */
  1027. iec104_tester_timer();
  1028. Type = asdu->_type;
  1029. switch (Type)
  1030. {
  1031. case IEC10X_C_IC_NA_1:
  1032. LOG("++++Asdu Type Call cmd... \n");
  1033. iec104_asdu_call(asdu);
  1034. IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_IDLE;
  1035. break;
  1036. case IEC10X_C_CS_NA_1:
  1037. LOG("++++Asdu Type Clock syc cmd... \n");
  1038. iec104_asdu_clock(asdu);
  1039. break;
  1040. case IEC10X_C_SE_NA_1:
  1041. case IEC10X_C_SE_NC_1:
  1042. LOG("++++Asdu Type Set type(%d)... \n", Type);
  1043. iec104_asdu_set_act(asdu, Type);
  1044. iec104_build_set_ack(1, Type);
  1045. break;
  1046. case IEC10X_TI_FIRM_UPDATE:
  1047. LOG("++++Asdu Type Firmware Update... \n");
  1048. iec104_deal_firmware_update(asdu, len);
  1049. break;
  1050. case IEC10X_TI_AP_FIRM_BACKOFF:
  1051. LOG("++++Asdu Type Firmware Backoff... \n");
  1052. memcpy(&FirmwareType, asdu->_info, 3);
  1053. iec104_build_data_ack(IEC10X_TI_AP_FIRM_BACKOFF, IEC10X_COT_ACTCON, FirmwareType, 0, 1);
  1054. iec104->backoff_firmware(FirmwareType);
  1055. break;
  1056. default:
  1057. LOG("-%s-, error Type(%d) \n", __FUNCTION__, Type);
  1058. return RET_ERROR;
  1059. }
  1060. return RET_SUCESS;
  1061. }
  1062. iec_8u iec104_deal_s(p_iec104_data_t Iec104_data, iec_16u len)
  1063. {
  1064. return RET_SUCESS;
  1065. }
  1066. iec_8u iec104_deal_u(p_iec104_data_t iec104_data, iec_16u len)
  1067. {
  1068. switch (iec104_data->ctrl.func.func)
  1069. {
  1070. case IEC104_U_FUNC_STARTDT:
  1071. LOG(">%s<, function STARTDT \n", __FUNCTION__);
  1072. IEC104_STATE_FLAG_INIT = IEC104_FLAG_LINK_INIT;
  1073. Iec104_TimeCycle = 0;
  1074. Iec104_TimeCount = 0;
  1075. // IEC104_Build_U(IEC104_U_FUNC_STARTDT,1);
  1076. // IEC104_Build_InitFin();
  1077. break;
  1078. case IEC104_U_FUNC_STOPDT:
  1079. LOG(">%s<, function STOPDT \n", __FUNCTION__);
  1080. iec104->close_link();
  1081. iec104_build_u(IEC104_U_FUNC_STOPDT, 1);
  1082. IEC104_STATE_FLAG_INIT = IEC104_FLAG_RECV_CLOSED;
  1083. break;
  1084. case IEC104_U_FUNC_TESTER:
  1085. LOG(">%s<, function TESTER \n", __FUNCTION__);
  1086. iec104_build_u(IEC104_U_FUNC_TESTER, 1);
  1087. break;
  1088. /* U ACK */
  1089. case IEC104_U_FUNC_STARTDT_ACK:
  1090. LOG(">%s<, function STARTDT ACK\n", __FUNCTION__);
  1091. break;
  1092. case IEC104_U_FUNC_STOPDT_ACK:
  1093. LOG(">%s<, function STOPDT ACK\n", __FUNCTION__);
  1094. IEC104_STATE_FLAG_INIT = IEC104_FLAG_RECV_CLOSED;
  1095. break;
  1096. case IEC104_U_FUNC_TESTER_ACK:
  1097. LOG(">%s<, function TESTER ACK\n", __FUNCTION__);
  1098. Iec104_TesterCount = 0;
  1099. break;
  1100. default:
  1101. LOG(">%s<, function ERROR \n", __FUNCTION__);
  1102. break;
  1103. }
  1104. return RET_SUCESS;
  1105. }
  1106. void iec104_receive(iec_8u *buf, iec_16u len)
  1107. {
  1108. iec_8u *BufTemp = NULL;
  1109. iec_16s LenRemain, LenTmp;
  1110. p_iec104_data_t Iec104_data = NULL;
  1111. if (buf == NULL)
  1112. {
  1113. LOG("-%s-,buffer (null)", __FUNCTION__);
  1114. return;
  1115. }
  1116. #if 0
  1117. if(len <= 0 || len>IEC104_MAX_BUF_LEN || len<BufTemp[0]+2){
  1118. LOG("-%s-,buffer len error(%d) \n",__FUNCTION__,len);
  1119. return;
  1120. }
  1121. #endif
  1122. BufTemp = buf;
  1123. LenRemain = len;
  1124. while (BufTemp < buf + len)
  1125. {
  1126. Iec104_data = (p_iec104_data_t)BufTemp;
  1127. iec104_lock();
  1128. if (Iec104_data->head == IEC104_HEAD)
  1129. {
  1130. LenTmp = Iec104_data->len + 2;
  1131. if (LenRemain < IEC104_HEAD_LEN)
  1132. {
  1133. LOG("_%s_,len error(%d) \n", __FUNCTION__, len);
  1134. iec104_unlock();
  1135. return;
  1136. }
  1137. if (Iec104_data->ctrl.type.type_1 == 0)
  1138. {
  1139. LOG("-%s-,frame type i \n", __FUNCTION__);
  1140. iec104_deal_i(Iec104_data, LenTmp);
  1141. }
  1142. else if (Iec104_data->ctrl.type.type_1 == 1 && Iec104_data->ctrl.type.type_2 == 0)
  1143. {
  1144. LOG("-%s-,frame type s \n", __FUNCTION__);
  1145. iec104_deal_s(Iec104_data, LenTmp);
  1146. }
  1147. else if (Iec104_data->ctrl.type.type_1 == 1 && Iec104_data->ctrl.type.type_2 == 1)
  1148. {
  1149. LOG("-%s-,frame type u \n", __FUNCTION__);
  1150. iec104_deal_u(Iec104_data, LenTmp);
  1151. }
  1152. }
  1153. else
  1154. {
  1155. LOG("-%s-,head type error(%d) \n", __FUNCTION__, BufTemp[0]);
  1156. iec104_unlock();
  1157. return;
  1158. }
  1159. iec104_unlock();
  1160. BufTemp += LenTmp;
  1161. LenRemain -= LenTmp;
  1162. }
  1163. return;
  1164. }
  1165. void iec104_reset_flag(void)
  1166. {
  1167. IEC104_STATE_FLAG_CALLALL = IEC104_FLAG_IDLE;
  1168. IEC104_STATE_FLAG_GROUP = IEC104_FLAG_IDLE;
  1169. IEC104_STATE_FLAG_CLOCK = IEC104_FLAG_IDLE;
  1170. IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
  1171. iec104_build_send_sn = 0;
  1172. iec104_build_recv_sn = 0;
  1173. iec104_deal_send_sn = -1;
  1174. iec104_deal_recv_sn = 0;
  1175. Iec104_TesterCount = 0;
  1176. }
  1177. iec_32u TestCount_Temp = 0;
  1178. iec_8u iec104_state_machine(void)
  1179. {
  1180. /*Init link*/
  1181. switch (IEC104_STATE_FLAG_INIT)
  1182. {
  1183. case IEC104_FLAG_CLOSED:
  1184. IEC104_STATE_FLAG_INIT = IEC104_FLAG_START_LINK;
  1185. iec104_queue_clear();
  1186. iec104_reset_flag();
  1187. break;
  1188. case IEC104_FLAG_SEND_CLOSED:
  1189. Iec104_TimeCycle += IEC104_CYCLE_TIME_MS;
  1190. if (Iec104_TimeCycle > IEC104_RESEND_TIME_MS)
  1191. {
  1192. Iec104_TimeCycle = 0;
  1193. Iec104_TimeCount++;
  1194. iec104_build_u(IEC104_U_FUNC_STOPDT, 0);
  1195. }
  1196. if (Iec104_TimeCount >= 3)
  1197. {
  1198. Iec104_TimeCount = 0;
  1199. IEC104_STATE_FLAG_INIT = IEC104_FLAG_IDLE;
  1200. iec104->close_link();
  1201. }
  1202. break;
  1203. case IEC104_FLAG_RECV_CLOSED:
  1204. iec104_reset_flag();
  1205. iec104_queue_clear();
  1206. IEC104_STATE_FLAG_INIT = IEC104_FLAG_CONNECT_SUCESS;
  1207. break;
  1208. case IEC104_FLAG_LINK_INIT:
  1209. LOG("Iec104 machine state :IEC104_FLAG_LINK_INIT \n");
  1210. iec104_reset_flag();
  1211. iec104_state_addr = iec104->get_link_addr();
  1212. iec104_build_u(IEC104_U_FUNC_STARTDT, 1);
  1213. iec104_build_init_fin();
  1214. iec104_build_upload(IEC10X_TI_AP_BASE_INFO, IEC10X_PRIO_INITLINK, AP_TYPE_BASE_INFO);
  1215. IEC104_STATE_FLAG_INIT = IEC104_FLAG_CONNECT_SUCESS;
  1216. break;
  1217. case IEC104_FLAG_UPLOAD_ADDR:
  1218. Iec104_TimeCycle += IEC104_CYCLE_TIME_MS;
  1219. if (Iec104_TimeCycle > IEC104_RESEND_TIME_MS)
  1220. {
  1221. iec104_state_addr = iec104->get_link_addr();
  1222. Iec104_TimeCycle = 0;
  1223. Iec104_TimeCount++;
  1224. iec104_upload_addr();
  1225. }
  1226. if (Iec104_TimeCount >= 3)
  1227. {
  1228. Iec104_TimeCount = 0;
  1229. IEC104_STATE_FLAG_INIT = IEC104_FLAG_IDLE;
  1230. iec104->close_link();
  1231. }
  1232. break;
  1233. case IEC104_FLAG_CONNECT_SUCESS:
  1234. case IEC104_FLAG_IDLE:
  1235. default:
  1236. break;
  1237. }
  1238. if (IEC104_STATE_FLAG_INIT == IEC104_FLAG_CONNECT_SUCESS)
  1239. {
  1240. /* Return s ack */
  1241. switch (IEC104_STATE_FLAG_S_ACK)
  1242. {
  1243. case IEC104_FLAG_S_ACK:
  1244. Iec104_TimeCycle_S += IEC104_CYCLE_TIME_MS;
  1245. if (Iec104_TimeCycle_S > IEC104_S_ACK_TIMEOUT)
  1246. {
  1247. Iec104_TimeCycle_S = 0;
  1248. iec104_build_s_ack();
  1249. IEC104_STATE_FLAG_S_ACK = IEC104_FLAG_IDLE;
  1250. }
  1251. break;
  1252. case IEC104_FLAG_IDLE:
  1253. break;
  1254. default:
  1255. break;
  1256. }
  1257. /* test spon */
  1258. #if 1
  1259. if (TestCount_Temp++ > (10 * 60 * 20))
  1260. {
  1261. TestCount_Temp = 0;
  1262. iec104_build_signal_spon(1, 1, IEC104_INFOADDR_STATE_HXGF + 2);
  1263. iec104_build_detect_f_spont(1, 60.2, IEC104_INFOADDR_VALUE_HXTM + 2);
  1264. iec104_build_detect_f_spont(1, 61.1, IEC104_INFOADDR_VALUE_HXGF + 2);
  1265. }
  1266. #endif
  1267. }
  1268. /* Tester */
  1269. switch (IEC104_STATE_FLAG_TESTER)
  1270. {
  1271. case IEC104_FLAG_TESTER:
  1272. iec104_build_u(IEC104_U_FUNC_TESTER, 0);
  1273. IEC104_STATE_FLAG_TESTER = IEC104_FLAG_IDLE;
  1274. Iec104_TesterCount++;
  1275. LOG("Tester Count(%d)... \n", Iec104_TesterCount);
  1276. if (Iec104_TesterCount > 3)
  1277. {
  1278. Iec104_TesterCount = 0;
  1279. LOG("Tester error(%d)... \n", Iec104_TesterCount);
  1280. IEC104_STATE_FLAG_INIT = IEC104_FLAG_CLOSED;
  1281. iec104->close_link();
  1282. }
  1283. break;
  1284. case IEC104_FLAG_TESTER_STOP:
  1285. break;
  1286. case IEC104_FLAG_IDLE:
  1287. Iec104_TimeCycle_TesterIdle += IEC104_CYCLE_TIME_MS;
  1288. if (Iec104_TimeCycle_TesterIdle > IEC104_TESTER_IDLE_TIMEOUT)
  1289. {
  1290. Iec104_TimeCycle_TesterIdle = 0;
  1291. IEC104_STATE_FLAG_TESTER = IEC104_FLAG_TESTER;
  1292. }
  1293. break;
  1294. default:
  1295. break;
  1296. }
  1297. return RET_SUCESS;
  1298. }