iec104.c 44 KB

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