iec104.c 44 KB

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