iec101.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. #include "iec101.h"
  2. #include "project_var.h"
  3. #ifdef IEC101_STM32
  4. /*
  5. * GLOABLE VARIALBLE
  6. */
  7. uint8_t Iec101_Respon_Confirm = 0;
  8. uint8_t Iec101_Sendbuf[IEC101_MAX_BUF_LEN];
  9. uint8_t IEC10X_Call_AllQoi = 0;
  10. uint8_t IEC10X_Call_GroupQoi = 0;
  11. uint16_t IEC101_Pulse_Cnt = 0;
  12. /*
  13. * STATE
  14. * */
  15. uint8_t IEC101_STATE_FLAG_INIT = IEC101_FLAG_LINK_CLOSED;
  16. uint8_t IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_CLOSED;
  17. uint8_t IEC101_STATE_FLAG_GROUP = IEC101_FLAG_LINK_CLOSED;
  18. uint8_t IEC101_STATE_FLAG_CLOCK = IEC101_FLAG_LINK_CLOSED;
  19. uint8_t IEC101_STATE_FLAG_DELAY = IEC101_FLAG_LINK_CLOSED;
  20. uint8_t IEC101_STATE_FLAG_PULSE = IEC101_FLAG_LINK_CLOSED;
  21. uint8_t IEC10X_RetStatusOk(uint16_t addr)
  22. {
  23. uint16_t len;
  24. PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;
  25. len = IEC101_STABLE_LEN;
  26. Iec10x->_begin = IEC101_STABLE_BEGING;
  27. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  28. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_SLAVE;
  29. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  30. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CAN_REC;
  31. Iec10x->_ctrl.up._func = IEC101_CTRL_RES_LINK_STATUS;
  32. Iec10x->_addr = addr;
  33. Iec10x->_cs = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
  34. Iec10x->_end = IEC101_STABLE_END;
  35. /* enqueue to the transmisson queue */
  36. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  37. return RET_SUCESS;
  38. }
  39. static uint8_t IEC10X_ResConfirm(uint8_t Prio)
  40. {
  41. uint16_t len;
  42. PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;
  43. len = IEC101_STABLE_LEN;
  44. Iec10x->_begin = IEC101_STABLE_BEGING;
  45. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  46. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_SLAVE;
  47. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  48. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CAN_REC;
  49. Iec10x->_ctrl.up._func = IEC101_CTRL_RES_CONFIRM;
  50. Iec10x->_addr = Iec10x_Sta_Addr;
  51. Iec10x->_cs = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
  52. Iec10x->_end = IEC101_STABLE_END;
  53. /* enqueue to the transmisson queue */
  54. IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);
  55. return RET_SUCESS;
  56. }
  57. uint8_t IEC10X_ReqLinkStatus()
  58. {
  59. uint16_t len;
  60. PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;
  61. LOG("%s \n", __FUNCTION__);
  62. len = IEC101_STABLE_LEN;
  63. Iec10x->_begin = IEC101_STABLE_BEGING;
  64. /*Ctrol*/
  65. Iec10x->_ctrl.down._dir = IEC101_CTRL_DIR_UP;
  66. Iec10x->_ctrl.down._prm = IEC101_CTRL_PRM_MASTER;
  67. Iec10x->_ctrl.down._fcb = IEC101_CTRL_FCB_OPPO_NONE;
  68. Iec10x->_ctrl.down._fcv = IEC101_CTRL_FCV_DISABLE;
  69. Iec10x->_ctrl.up._func = IEC101_CTRL_REQ_LINK_STATUS;
  70. Iec10x->_addr = Iec10x_Sta_Addr;
  71. Iec10x->_cs = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
  72. Iec10x->_end = IEC101_STABLE_END;
  73. /* enqueue to the transmisson queue */
  74. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  75. return RET_SUCESS;
  76. }
  77. uint8_t IEC10X_ResetLink(void)
  78. {
  79. uint16_t len;
  80. PIEC101_10_T Iec10x = (PIEC101_10_T)Iec101_Sendbuf;
  81. len = IEC101_STABLE_LEN;
  82. Iec10x->_begin = IEC101_STABLE_BEGING;
  83. /*Ctrol*/
  84. Iec10x->_ctrl.down._dir = IEC101_CTRL_DIR_UP;
  85. Iec10x->_ctrl.down._prm = IEC101_CTRL_PRM_MASTER;
  86. Iec10x->_ctrl.down._fcb = IEC101_CTRL_FCB_OPPO_NONE;
  87. Iec10x->_ctrl.down._fcv = IEC101_CTRL_FCV_DISABLE;
  88. Iec10x->_ctrl.up._func = IEC101_CTRL_RESET_LINK;
  89. Iec10x->_addr = Iec10x_Sta_Addr;
  90. Iec10x->_cs = Iec101_Sendbuf[1] + Iec101_Sendbuf[2] + Iec101_Sendbuf[3];
  91. Iec10x->_end = IEC101_STABLE_END;
  92. /* enqueue to the transmisson queue */
  93. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  94. return RET_SUCESS;
  95. }
  96. uint8_t IEC101_BuildFinInit(void)
  97. {
  98. uint16_t len = 0;
  99. uint8_t cs_temp = 0, i;
  100. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  101. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  102. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  103. len = IEC101_STABLE_LEN;
  104. /*head*/
  105. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  106. /*Ctrol*/
  107. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  108. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  109. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
  110. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  111. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  112. Iec10x->_addr = Iec10x_Sta_Addr;
  113. /*asdu*/
  114. asdu->_type = Iec10x_M_EI_NA_1;
  115. asdu->_num._num = 1;
  116. asdu->_reason._reason = IEC10X_ASDU_REASON_INIT;
  117. asdu->_addr = Iec10x_Sta_Addr;
  118. /*info*/
  119. info->_addr = IEC10X_INFO_ADDR_NONE;
  120. info->_element[0] = 0;
  121. /*len*/
  122. len = IEC101_VARIABLE_LEN + asdu->_num._num;
  123. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  124. /*end*/
  125. for (i = 4; i < len - 2; i++)
  126. {
  127. cs_temp += Iec101_Sendbuf[i];
  128. }
  129. Iec101_Sendbuf[len - 2] = cs_temp;
  130. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  131. // DumpHEX(Iec101_Sendbuf,len);
  132. /* enqueue to the transmisson queue */
  133. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_INITLINK, NULL, NULL);
  134. return RET_SUCESS;
  135. }
  136. uint8_t IEC101_BuildActConfirm(uint8_t qoi, uint8_t Prio)
  137. {
  138. uint16_t len = 0;
  139. uint8_t cs_temp = 0, i;
  140. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  141. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  142. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  143. len = IEC101_STABLE_LEN;
  144. /*head*/
  145. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  146. /*Ctrol*/
  147. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  148. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  149. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  150. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  151. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  152. Iec10x->_addr = Iec10x_Sta_Addr;
  153. /*asdu*/
  154. asdu->_type = IEC10X_C_IC_NA_1;
  155. asdu->_num._sq = 0;
  156. asdu->_num._num = 1;
  157. asdu->_reason._pn = 0;
  158. asdu->_reason._test = 0;
  159. asdu->_reason._reason = IEC10X_ASDU_REASON_ACTCON;
  160. asdu->_addr = Iec10x_Sta_Addr;
  161. /*info*/
  162. info->_addr = IEC10X_INFO_ADDR_NONE;
  163. info->_element[0] = qoi;
  164. /*len*/
  165. len = IEC101_VARIABLE_LEN + asdu->_num._num;
  166. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  167. /*end*/
  168. for (i = 4; i < len - 2; i++)
  169. {
  170. cs_temp += Iec101_Sendbuf[i];
  171. }
  172. Iec101_Sendbuf[len - 2] = cs_temp;
  173. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  174. // DumpHEX(Iec101_Sendbuf,len);
  175. /* enqueue to the transmisson queue */
  176. IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);
  177. return RET_SUCESS;
  178. }
  179. uint8_t IEC101_BuildActFinish(uint8_t qoi, uint8_t Prio)
  180. {
  181. uint16_t len = 0;
  182. uint8_t cs_temp = 0, i;
  183. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  184. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  185. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  186. len = IEC101_STABLE_LEN;
  187. /*head*/
  188. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  189. /*Ctrol*/
  190. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  191. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  192. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
  193. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  194. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  195. Iec10x->_addr = Iec10x_Sta_Addr;
  196. /*asdu*/
  197. asdu->_type = IEC10X_C_IC_NA_1;
  198. asdu->_num._sq = 0;
  199. asdu->_num._num = 1;
  200. asdu->_reason._pn = 0;
  201. asdu->_reason._test = 0;
  202. asdu->_reason._reason = IEC10X_ASDU_REASON_ACTTERM;
  203. asdu->_addr = Iec10x_Sta_Addr;
  204. /*info*/
  205. info->_addr = IEC10X_INFO_ADDR_NONE;
  206. info->_element[0] = qoi;
  207. /*len*/
  208. len = IEC101_VARIABLE_LEN + asdu->_num._num;
  209. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  210. /*end*/
  211. for (i = 4; i < len - 2; i++)
  212. {
  213. cs_temp += Iec101_Sendbuf[i];
  214. }
  215. Iec101_Sendbuf[len - 2] = cs_temp;
  216. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  217. // DumpHEX(Iec101_Sendbuf,len);
  218. /* enqueue to the transmisson queue */
  219. IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);
  220. return RET_SUCESS;
  221. }
  222. uint8_t IEC101_BuildSignal(uint8_t reason, uint8_t Prio)
  223. {
  224. uint16_t len = 0, addr;
  225. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL, signal, sum;
  226. /*init struct*/
  227. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  228. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  229. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  230. /*get value*/
  231. IEC10X->GetStationInfo(&addr, 0, &asdu_num);
  232. len = IEC101_STABLE_LEN;
  233. LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
  234. /*head*/
  235. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  236. /*Ctrol*/
  237. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  238. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  239. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
  240. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  241. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  242. Iec10x->_addr = Iec10x_Sta_Addr;
  243. /*asdu*/
  244. asdu->_type = IEC10X_M_SP_NA_1;
  245. asdu->_num._sq = 1;
  246. asdu->_num._num = asdu_num;
  247. asdu->_reason._pn = 0;
  248. asdu->_reason._test = 0;
  249. asdu->_reason._reason = reason;
  250. asdu->_addr = Iec10x_Sta_Addr;
  251. /*info*/
  252. info->_addr = IEC10X_INFO_ADDR_SIG_BASE + IEC10X_INFO_ADDR_SIG_TEMP_HX_OFF;
  253. /*signal value*/
  254. ptr = info->_element;
  255. for (i = 0; i < asdu_num; i++)
  256. {
  257. if (IEC10X->GetStationInfo(&addr, i, &asdu_num) == RET_SUCESS)
  258. *ptr = 1;
  259. else
  260. *ptr = 0;
  261. ptr++;
  262. }
  263. /*len*/
  264. len = ptr + 2 - Iec101_Sendbuf;
  265. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  266. /*end*/
  267. for (i = 4; i < len - 2; i++)
  268. {
  269. cs_temp += Iec101_Sendbuf[i];
  270. }
  271. Iec101_Sendbuf[len - 2] = cs_temp;
  272. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  273. // DumpHEX(Iec101_Sendbuf,len);
  274. /* enqueue to the transmisson queue */
  275. IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);
  276. return RET_SUCESS;
  277. }
  278. uint8_t IEC101_BuildDetect(uint8_t reason, uint8_t type, uint8_t Prio)
  279. {
  280. uint16_t len = 0, addr;
  281. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
  282. PIEC10X_DETECT_T detect = NULL;
  283. PIEC10X_DETECT_F_T detect_f = NULL;
  284. /*init struct*/
  285. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  286. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  287. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  288. /*get value*/
  289. IEC10X->GetStationInfo(&addr, 0, &asdu_num);
  290. LOG("-%s- total info (%d) \n\n", __FUNCTION__, asdu_num);
  291. len = IEC101_STABLE_LEN;
  292. /*head*/
  293. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  294. /*Ctrol*/
  295. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  296. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  297. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  298. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  299. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  300. Iec10x->_addr = Iec10x_Sta_Addr;
  301. /*asdu*/
  302. asdu->_type = type;
  303. asdu->_num._sq = 1;
  304. asdu->_num._num = asdu_num;
  305. asdu->_reason._pn = 0;
  306. asdu->_reason._test = 0;
  307. asdu->_reason._reason = reason;
  308. asdu->_addr = Iec10x_Sta_Addr;
  309. /*info*/
  310. info->_addr = IEC10X_INFO_ADDR_DET + IEC10X_INFO_ADDR_DET_TEMP_HX_OFF;
  311. /*Detect value*/
  312. ptr = info->_element;
  313. for (i = 0; i < asdu_num; i++)
  314. {
  315. /*short int*/
  316. if (type == IEC10X_M_ME_NA_1)
  317. {
  318. detect = (PIEC10X_DETECT_T)ptr;
  319. detect->_detect = IEC10X->GetStaTemp(i);
  320. detect->_qds = 0;
  321. ptr += sizeof(IEC10X_DETECT_T);
  322. }
  323. /*float*/
  324. else if (type == IEC10X_M_ME_NC_1)
  325. {
  326. detect_f = (PIEC10X_DETECT_F_T)ptr;
  327. detect_f->_detect = IEC10X->GetStaTemp(i);
  328. detect_f->_qds = 0;
  329. ptr += sizeof(IEC10X_DETECT_F_T);
  330. }
  331. }
  332. /*len*/
  333. len = ptr + 2 - Iec101_Sendbuf; /* add cs+end*/
  334. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  335. /*end*/
  336. for (i = 4; i < len - 2; i++)
  337. {
  338. cs_temp += Iec101_Sendbuf[i];
  339. }
  340. Iec101_Sendbuf[len - 2] = cs_temp;
  341. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  342. // DumpHEX(Iec101_Sendbuf,len);
  343. /* enqueue to the transmisson queue */
  344. IEC10X_Enqueue(Iec101_Sendbuf, len, Prio, NULL, NULL);
  345. return RET_SUCESS;
  346. }
  347. uint8_t IEC101_BuildSignal_Spont(uint8_t TimeFlag, uint8_t signalV, uint16_t addrV)
  348. {
  349. uint16_t len = 0;
  350. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
  351. PCP56Time2a_T time = NULL;
  352. /*init struct*/
  353. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  354. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  355. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  356. if (TimeFlag != 1 && TimeFlag != 0)
  357. {
  358. LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
  359. return RET_ERROR;
  360. }
  361. LOG("-%s-, time flag(%d) signalV(%d) \n", __FUNCTION__, TimeFlag, signalV);
  362. /*get value*/
  363. asdu_num = 1;
  364. len = IEC101_STABLE_LEN;
  365. /*head*/
  366. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  367. /*Ctrol*/
  368. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  369. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  370. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_WITH_DATA;
  371. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  372. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  373. Iec10x->_addr = Iec10x_Sta_Addr;
  374. /*asdu*/
  375. if (TimeFlag == 0)
  376. asdu->_type = IEC10X_M_SP_NA_1;
  377. else
  378. asdu->_type = IEC10X_M_SP_TB_1;
  379. asdu->_num._sq = 0;
  380. asdu->_num._num = asdu_num;
  381. asdu->_reason._pn = 0;
  382. asdu->_reason._test = 0;
  383. asdu->_reason._reason = IEC10X_COT_SPONT;
  384. asdu->_addr = Iec10x_Sta_Addr;
  385. /*info*/
  386. info->_addr = addrV;
  387. /*signal value*/
  388. ptr = info->_element;
  389. for (i = 0; i < asdu_num; i++)
  390. {
  391. *ptr = signalV;
  392. ptr++;
  393. }
  394. if (TimeFlag == 1)
  395. {
  396. time = (PCP56Time2a_T)ptr;
  397. IEC10X->GetTime(time);
  398. ptr += sizeof(CP56Time2a_T);
  399. }
  400. /*len*/
  401. len = ptr + 2 - Iec101_Sendbuf;
  402. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  403. /*end*/
  404. for (i = 4; i < len - 2; i++)
  405. {
  406. cs_temp += Iec101_Sendbuf[i];
  407. }
  408. Iec101_Sendbuf[len - 2] = cs_temp;
  409. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  410. // DumpHEX(Iec101_Sendbuf,len);
  411. /* enqueue to the transmisson queue */
  412. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_SPON, NULL, NULL);
  413. return RET_SUCESS;
  414. }
  415. uint8_t IEC101_BuildDetect_Spont(uint8_t TimeFlag, PIEC10X_DETECT_T detectV, uint16_t addrV)
  416. {
  417. uint16_t len = 0;
  418. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
  419. PIEC10X_DETECT_T detect = NULL;
  420. PCP56Time2a_T time = NULL;
  421. /*init struct*/
  422. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  423. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  424. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  425. if (TimeFlag != 1 && TimeFlag != 0)
  426. {
  427. LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
  428. return RET_ERROR;
  429. }
  430. /*get value*/
  431. asdu_num = 1;
  432. len = IEC101_STABLE_LEN;
  433. /*head*/
  434. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  435. /*Ctrol*/
  436. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  437. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  438. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  439. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  440. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  441. Iec10x->_addr = Iec10x_Sta_Addr;
  442. /*asdu*/
  443. if (TimeFlag == 0)
  444. asdu->_type = IEC10X_M_ME_NA_1;
  445. else
  446. asdu->_type = IEC10X_M_ME_TD_1;
  447. asdu->_num._sq = 0;
  448. asdu->_num._num = asdu_num;
  449. asdu->_reason._pn = 0;
  450. asdu->_reason._test = 0;
  451. asdu->_reason._reason = IEC10X_COT_SPONT;
  452. asdu->_addr = Iec10x_Sta_Addr;
  453. /*info*/
  454. info->_addr = addrV;
  455. /*Detect value*/
  456. ptr = info->_element;
  457. detect = (PIEC10X_DETECT_T)ptr;
  458. detect->_detect = detectV->_detect;
  459. detect->_qds = detectV->_qds;
  460. ptr += sizeof(IEC10X_DETECT_T);
  461. if (TimeFlag == 1)
  462. {
  463. time = (PCP56Time2a_T)ptr;
  464. IEC10X->GetTime(time);
  465. ptr += sizeof(CP56Time2a_T);
  466. }
  467. /*len*/
  468. len = ptr + 2 - Iec101_Sendbuf; /* add cs+end*/
  469. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  470. /*end*/
  471. for (i = 4; i < len - 2; i++)
  472. {
  473. cs_temp += Iec101_Sendbuf[i];
  474. }
  475. Iec101_Sendbuf[len - 2] = cs_temp;
  476. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  477. // DumpHEX(Iec101_Sendbuf,len);
  478. /* enqueue to the transmisson queue */
  479. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_SPON, NULL, NULL);
  480. return RET_SUCESS;
  481. }
  482. uint8_t IEC101_BuildDetectF_Spont(uint8_t TimeFlag, float detectV, uint16_t addrV)
  483. {
  484. uint16_t len = 0;
  485. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
  486. PIEC10X_DETECT_F_T detect = NULL;
  487. PCP56Time2a_T time = NULL;
  488. /*init struct*/
  489. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  490. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  491. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  492. if (TimeFlag != 1 && TimeFlag != 0)
  493. {
  494. LOG("-%s-, error time flag(%d) \n", __FUNCTION__, TimeFlag);
  495. return RET_ERROR;
  496. }
  497. /*get value*/
  498. asdu_num = 1;
  499. len = IEC101_STABLE_LEN;
  500. /*head*/
  501. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  502. /*Ctrol*/
  503. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  504. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  505. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  506. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  507. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  508. Iec10x->_addr = Iec10x_Sta_Addr;
  509. /*asdu*/
  510. if (TimeFlag == 0)
  511. asdu->_type = IEC10X_M_ME_NC_1;
  512. else
  513. asdu->_type = IEC10X_M_ME_TF_1;
  514. asdu->_num._sq = 0;
  515. asdu->_num._num = asdu_num;
  516. asdu->_reason._pn = 0;
  517. asdu->_reason._test = 0;
  518. asdu->_reason._reason = IEC10X_COT_SPONT;
  519. asdu->_addr = Iec10x_Sta_Addr;
  520. /*info*/
  521. info->_addr = addrV;
  522. /*Detect value*/
  523. ptr = info->_element;
  524. detect = (PIEC10X_DETECT_F_T)ptr;
  525. detect->_detect = detectV;
  526. detect->_qds = 0;
  527. ptr += sizeof(IEC10X_DETECT_F_T);
  528. if (TimeFlag == 1)
  529. {
  530. time = (PCP56Time2a_T)ptr;
  531. IEC10X->GetTime(time);
  532. ptr += sizeof(CP56Time2a_T);
  533. }
  534. /*len*/
  535. len = ptr + 2 - Iec101_Sendbuf; /* add cs+end*/
  536. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  537. /*end*/
  538. for (i = 4; i < len - 2; i++)
  539. {
  540. cs_temp += Iec101_Sendbuf[i];
  541. }
  542. Iec101_Sendbuf[len - 2] = cs_temp;
  543. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  544. // DumpHEX(Iec101_Sendbuf,len);
  545. /* enqueue to the transmisson queue */
  546. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_SPON, NULL, NULL);
  547. return RET_SUCESS;
  548. }
  549. uint8_t IEC101_BuildDelayAct(uint16_t delay_time)
  550. {
  551. uint16_t len = 0;
  552. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
  553. uint16_t cp16time2a = delay_time;
  554. /*init struct*/
  555. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  556. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  557. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  558. /*get value*/
  559. asdu_num = 1;
  560. len = IEC101_STABLE_LEN;
  561. /*head*/
  562. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  563. /*Ctrol*/
  564. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  565. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  566. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  567. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  568. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  569. Iec10x->_addr = Iec10x_Sta_Addr;
  570. /*asdu*/
  571. asdu->_type = IEC10X_C_CD_NA_1;
  572. asdu->_num._sq = 0;
  573. asdu->_num._num = asdu_num;
  574. asdu->_reason._pn = 0;
  575. asdu->_reason._test = 0;
  576. asdu->_reason._reason = IEC10X_COT_ACTCON;
  577. asdu->_addr = Iec10x_Sta_Addr;
  578. /*info*/
  579. info->_addr = IEC10X_INFO_ADDR_NONE;
  580. /*delay value*/
  581. ptr = info->_element;
  582. *(uint16_t *)ptr = IEC10X_Cp16time2a;
  583. ptr += 2;
  584. /*len*/
  585. len = ptr + 2 - Iec101_Sendbuf;
  586. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  587. /*end*/
  588. for (i = 4; i < len - 2; i++)
  589. {
  590. cs_temp += Iec101_Sendbuf[i];
  591. }
  592. Iec101_Sendbuf[len - 2] = cs_temp;
  593. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  594. // DumpHEX(Iec101_Sendbuf,len);
  595. /* enqueue to the transmisson queue */
  596. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_DELAY, NULL, NULL);
  597. return RET_SUCESS;
  598. }
  599. uint8_t IEC101_BuildClockAct()
  600. {
  601. uint16_t len = 0;
  602. uint8_t cs_temp = 0, i, asdu_num = 0, *ptr = NULL;
  603. /*init struct*/
  604. PIEC101_68_T Iec10x = (PIEC101_68_T)Iec101_Sendbuf;
  605. PIEC10X_ASDU_T asdu = (PIEC10X_ASDU_T)(Iec10x->_asdu);
  606. PASDU_INFO_T info = (PASDU_INFO_T)(asdu->_info);
  607. PCP56Time2a_T time = (PCP56Time2a_T)(info->_element);
  608. /*get value*/
  609. asdu_num = 1;
  610. len = IEC101_STABLE_LEN;
  611. /*head*/
  612. Iec10x->_begin = Iec10x->_begin_cfm = IEC101_VARIABLE_BEGING;
  613. /*Ctrol*/
  614. Iec10x->_ctrl.up._dir = IEC101_CTRL_DIR_UP;
  615. Iec10x->_ctrl.up._prm = IEC101_CTRL_PRM_MASTER;
  616. Iec10x->_ctrl.up._acd = IEC101_CTRL_ACD_NONE_DATA;
  617. Iec10x->_ctrl.up._dfc = IEC101_CTRL_DFC_CANNOT_REC;
  618. Iec10x->_ctrl.up._func = IEC101_CTRL_SEND_USR_DATA_ACK;
  619. Iec10x->_addr = Iec10x_Sta_Addr;
  620. /*asdu*/
  621. asdu->_type = IEC10X_C_CS_NA_1;
  622. asdu->_num._sq = 0;
  623. asdu->_num._num = asdu_num;
  624. asdu->_reason._pn = 0;
  625. asdu->_reason._test = 0;
  626. asdu->_reason._reason = IEC10X_COT_ACTCON;
  627. asdu->_addr = Iec10x_Sta_Addr;
  628. /*info*/
  629. info->_addr = IEC10X_INFO_ADDR_NONE;
  630. /*clock value*/
  631. ptr = info->_element;
  632. // time;
  633. IEC10X->GetTime(time);
  634. ptr += sizeof(CP56Time2a_T);
  635. /*len*/
  636. len = ptr + 2 - Iec101_Sendbuf;
  637. Iec10x->_len = Iec10x->_len_cfm = len - 4 - 2; /*-start-len-len-start -cs-end*/
  638. /*end*/
  639. for (i = 4; i < len - 2; i++)
  640. {
  641. cs_temp += Iec101_Sendbuf[i];
  642. }
  643. Iec101_Sendbuf[len - 2] = cs_temp;
  644. Iec101_Sendbuf[len - 1] = IEC101_VARIABLE_END;
  645. // DumpHEX(Iec101_Sendbuf,len);
  646. /* enqueue to the transmisson queue */
  647. IEC10X_Enqueue(Iec101_Sendbuf, len, IEC10X_PRIO_CLOCK, NULL, NULL);
  648. return RET_SUCESS;
  649. }
  650. IEC10X_ASDU_CALL_Qoi(uint8_t qoi)
  651. {
  652. switch (qoi)
  653. {
  654. case IEC10X_CALL_QOI_TOTAL:
  655. LOG("-%s- call cmd active \n", __FUNCTION__);
  656. IEC101_BuildSignal(IEC10X_COT_INTROGEN, IEC10X_PRIO_CALLALL);
  657. IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_SIG_TOTAL;
  658. break;
  659. case IEC10X_CALL_QOI_GROUP1:
  660. LOG("-%s- call cmd call group1 \n", __FUNCTION__);
  661. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
  662. IEC101_BuildSignal(IEC10X_COT_INTRO1, IEC10X_PRIO_CALLGROUP);
  663. break;
  664. case IEC10X_CALL_QOI_GROUP2:
  665. LOG("-%s- call cmd call group2 \n", __FUNCTION__);
  666. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
  667. IEC101_BuildSignal(IEC10X_COT_INTRO2, IEC10X_PRIO_CALLGROUP);
  668. break;
  669. case IEC10X_CALL_QOI_GROUP9:
  670. LOG("-%s- call cmd call group9 \n", __FUNCTION__);
  671. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
  672. IEC101_BuildDetect(IEC10X_COT_INTRO9, IEC10X_M_ME_NA_1, IEC10X_PRIO_CALLGROUP);
  673. break;
  674. case IEC10X_CALL_QOI_GROUP10:
  675. LOG("-%s- call cmd call group10 \n", __FUNCTION__);
  676. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_GROUP;
  677. IEC101_BuildDetect(IEC10X_COT_INTRO10, IEC10X_M_ME_NA_1, IEC10X_PRIO_CALLGROUP);
  678. break;
  679. default:
  680. LOG("-%s- call cmd active error(%d) \n", __FUNCTION__, qoi);
  681. break;
  682. }
  683. }
  684. uint8_t IEC10X_ASDU_Call(PIEC10X_ASDU_T Iec10x_Asdu)
  685. {
  686. PASDU_INFO_T asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info);
  687. uint8_t qoi = asdu_info->_element[0];
  688. uint8_t Prio = 0;
  689. if (asdu_info->_addr != 0)
  690. {
  691. LOG("-%s- call cmd active error addr(%x) \n", __FUNCTION__, asdu_info->_addr);
  692. return RET_ERROR;
  693. }
  694. switch (Iec10x_Asdu->_reason._reason)
  695. {
  696. case IEC10X_ASDU_REASON_ACT:
  697. switch (qoi)
  698. {
  699. case IEC10X_CALL_QOI_TOTAL:
  700. Prio = IEC10X_PRIO_CALLALL;
  701. IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_ACT_RET;
  702. IEC10X_Call_AllQoi = qoi;
  703. break;
  704. case IEC10X_CALL_QOI_GROUP1:
  705. case IEC10X_CALL_QOI_GROUP2:
  706. case IEC10X_CALL_QOI_GROUP9:
  707. case IEC10X_CALL_QOI_GROUP10:
  708. Prio = IEC10X_PRIO_CALLGROUP;
  709. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_ACT_RET;
  710. IEC10X_Call_GroupQoi = qoi;
  711. break;
  712. default:
  713. LOG("-%s- call cmd error qoi(%d) \n", __FUNCTION__, qoi);
  714. return RET_ERROR;
  715. }
  716. IEC10X_ResConfirm(Prio);
  717. IEC101_BuildActConfirm(qoi, Prio);
  718. break;
  719. default:
  720. LOG("-%s- call cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
  721. break;
  722. }
  723. return RET_SUCESS;
  724. }
  725. uint8_t IEC10X_ASDU_Delay(PIEC10X_ASDU_T Iec10x_Asdu)
  726. {
  727. PASDU_INFO_T asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info);
  728. if (asdu_info->_addr != 0)
  729. {
  730. LOG("-%s- delay cmd error addr(%d) \n", __FUNCTION__, asdu_info->_addr);
  731. return RET_ERROR;
  732. }
  733. switch (Iec10x_Asdu->_reason._reason)
  734. {
  735. case IEC10X_COT_ACT:
  736. IEC10X_Cp16time2a = *(uint16_t *)(asdu_info->_element);
  737. LOG("-%s- delay cmd (0x%x%x)(%d)ms \n", __FUNCTION__, asdu_info->_element[0], asdu_info->_element[1], IEC10X_Cp16time2a);
  738. IEC101_STATE_FLAG_DELAY = IEC101_FLAG_DELAY_ACT;
  739. IEC10X_ResConfirm(IEC10X_PRIO_DELAY);
  740. IEC101_BuildDelayAct(IEC10X_Cp16time2a);
  741. break;
  742. case IEC10X_COT_SPONT:
  743. IEC10X_Cp16time2a_V = *(uint16_t *)(asdu_info->_element);
  744. LOG("-%s- delay cmd delay value(%d)ms \n", __FUNCTION__, IEC10X_Cp16time2a_V);
  745. IEC10X_ResConfirm(IEC10X_PRIO_DELAY);
  746. break;
  747. default:
  748. LOG("-%s- delay cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
  749. break;
  750. }
  751. return RET_SUCESS;
  752. }
  753. uint8_t IEC10X_ASDU_CLOCK(PIEC10X_ASDU_T Iec10x_Asdu)
  754. {
  755. PASDU_INFO_T asdu_info = (PASDU_INFO_T)(Iec10x_Asdu->_info);
  756. PCP56Time2a_T time = (PCP56Time2a_T)(asdu_info->_element);
  757. memcpy(&IEC10X_Cp56time2a, asdu_info->_element, sizeof(CP56Time2a_T));
  758. if (asdu_info->_addr != 0)
  759. {
  760. LOG("-%s- Clock cmd error addr(%d) \n", __FUNCTION__, asdu_info->_addr);
  761. return RET_ERROR;
  762. }
  763. switch (Iec10x_Asdu->_reason._reason)
  764. {
  765. case IEC10X_COT_ACT:
  766. LOG("-%s- Clock cmd (20%d-%d-%d %d %d:%d:%d) delay(%d) \n", __FUNCTION__, IEC10X_Cp56time2a._year._year, IEC10X_Cp56time2a._month._month, IEC10X_Cp56time2a._day._dayofmonth,
  767. IEC10X_Cp56time2a._day._dayofweek, IEC10X_Cp56time2a._hour._hours, IEC10X_Cp56time2a._min._minutes, IEC10X_Cp56time2a._milliseconds, IEC10X_Cp16time2a_V);
  768. IEC10X_Cp56time2a._milliseconds += IEC10X_Cp16time2a_V;
  769. /*get time*/
  770. /*...*/
  771. IEC10X->SetTime(&IEC10X_Cp56time2a);
  772. IEC101_STATE_FLAG_DELAY = IEC101_FLAG_CLOCK_SYS;
  773. IEC10X_ResConfirm(IEC10X_PRIO_CLOCK);
  774. IEC101_BuildClockAct();
  775. break;
  776. case IEC10X_COT_SPONT:
  777. LOG("-%s- Clock cmd spont \n", __FUNCTION__);
  778. break;
  779. default:
  780. LOG("-%s- Clock cmd error reason(%d) \n", __FUNCTION__, Iec10x_Asdu->_reason._reason);
  781. break;
  782. }
  783. return RET_SUCESS;
  784. }
  785. uint8_t Iec10x_Deal_10(uint8_t *buf, uint16_t len)
  786. {
  787. uint8_t cfun, sta, i;
  788. uint8_t cs_temp = 0;
  789. PIEC101_10_T Iec10x_10 = NULL;
  790. Iec10x_10 = (PIEC101_10_T)buf;
  791. /* check check_sum*/
  792. for (i = 1; i < len - 2; i++)
  793. {
  794. cs_temp += buf[i];
  795. }
  796. if (Iec10x_10->_cs != cs_temp)
  797. {
  798. LOG("-%s-,check sum error(%x) \n", __FUNCTION__, cs_temp);
  799. return RET_ERROR;
  800. }
  801. /* check end of the frame*/
  802. if (Iec10x_10->_end != 0x16)
  803. {
  804. LOG("-%s-,iec10x_10 end error(%d) \n", __FUNCTION__, Iec10x_10->_end);
  805. return RET_ERROR;
  806. }
  807. /*deal the function code*/
  808. cfun = Iec10x_10->_ctrl.down._func;
  809. sta = Iec10x_10->_ctrl.down._prm;
  810. // IEC10X->GetLinkAddr();
  811. #ifdef IEC10XLOCK
  812. if (IEC10X->LOCK != NULL)
  813. IEC10X->LOCK();
  814. #endif
  815. if (sta == IEC101_CTRL_PRM_MASTER)
  816. {
  817. switch (cfun)
  818. {
  819. case IEC101_CTRL_RESET_LINK:
  820. LOG("++++Reset link... \n");
  821. IEC101_STATE_FLAG_INIT = IEC101_FLAG_RESET_LINK;
  822. break;
  823. case IEC101_CTRL_PULSE:
  824. LOG("++++PULSE... \n");
  825. IEC101_STATE_FLAG_PULSE = IEC101_FLAG_PULSE;
  826. IEC10X_ResConfirm(IEC10X_PRIO_PULSE);
  827. break;
  828. case IEC101_CTRL_SEND_DATA:
  829. LOG("++++Send data... \n");
  830. break;
  831. case IEC101_CTRL_REQ_LINK_STATUS:
  832. LOG("++++Request link status... \n");
  833. IEC101_STATE_FLAG_INIT = IEC101_FLAG_INIT_LINK;
  834. // Iec10x_Sta_Addr = IEC10X->GetLinkAddr();
  835. // Iec10x_Sta_Addr = 0x138a;
  836. // IEC10X_RetStatusOk(Iec10x_Sta_Addr);
  837. break;
  838. default:
  839. LOG("++++error DOWN function code (%d)... \n", cfun);
  840. break;
  841. }
  842. }
  843. else if (sta == IEC101_CTRL_PRM_SLAVE)
  844. {
  845. switch (cfun)
  846. {
  847. case IEC101_CTRL_RES_LINK_STATUS:
  848. LOG("++++Respon link status... \n");
  849. LOG("IEC101_FLAG_RESET_REMOTE_LINK \n");
  850. IEC10X_ResetLink();
  851. IEC101_STATE_FLAG_INIT = IEC101_FLAG_RESET_REMOTE_LINK;
  852. break;
  853. case IEC101_CTRL_RES_CONFIRM:
  854. LOG("++++Respon confirm... \n");
  855. Iec101_Respon_Confirm = 1;
  856. break;
  857. default:
  858. LOG("++++error UP function code (%d)... \n", cfun);
  859. break;
  860. }
  861. }
  862. #ifdef IEC10XLOCK
  863. if (IEC10X->UNLOCK != NULL)
  864. IEC10X->UNLOCK();
  865. #endif
  866. return RET_SUCESS;
  867. }
  868. uint8_t Iec10x_Deal_68(uint8_t *buf, uint16_t len)
  869. {
  870. uint8_t cfun, sta, i;
  871. uint8_t cs_temp = 0;
  872. PIEC101_68_T Iec10x_68 = NULL;
  873. PIEC10X_ASDU_T Iec10x_Asdu = NULL;
  874. Iec10x_68 = (PIEC101_68_T)buf;
  875. Iec10x_Asdu = (PIEC10X_ASDU_T)Iec10x_68->_asdu;
  876. /* check check_sum*/
  877. for (i = 4; i < len - 2; i++)
  878. {
  879. cs_temp += buf[i];
  880. }
  881. if (buf[len - 2] != cs_temp)
  882. {
  883. LOG("-%s-,iec10x_68 check sum error (%d)(%d) \n", __FUNCTION__, buf[len - 2], cs_temp);
  884. return RET_ERROR;
  885. }
  886. /* check end of the frame*/
  887. if (buf[len - 1] != IEC101_VARIABLE_END)
  888. {
  889. LOG("-%s-,iec10x_68 end error(%d) \n", __FUNCTION__, buf[len - 1]);
  890. return RET_ERROR;
  891. }
  892. /* check len of the receive frame */
  893. if (Iec10x_68->_len + 6 != len)
  894. {
  895. LOG("-%s-,iec10x_68 rec len error(%d)(%d) \n", __FUNCTION__, Iec10x_68->_len, len);
  896. return RET_ERROR;
  897. }
  898. /* check len of the frame */
  899. if (Iec10x_68->_len != Iec10x_68->_len_cfm)
  900. {
  901. LOG("-%s-,iec10x_68 len error(%d)(%d) \n", __FUNCTION__, Iec10x_68->_len, Iec10x_68->_len_cfm);
  902. return RET_ERROR;
  903. }
  904. /*deal the function code*/
  905. cfun = Iec10x_68->_ctrl.down._func;
  906. sta = Iec10x_68->_ctrl.down._prm;
  907. #ifdef IEC10XLOCK
  908. if (IEC10X->LOCK != NULL)
  909. IEC10X->LOCK();
  910. #endif
  911. switch (cfun)
  912. {
  913. case IEC101_CTRL_SEND_USR_DATA_ACK:
  914. Iec101_Respon_Confirm = 0;
  915. LOG("++++Send user data need ack... \n");
  916. switch (Iec10x_Asdu->_type)
  917. {
  918. case IEC10X_C_IC_NA_1:
  919. LOG("++++asdu type call cmd... \n");
  920. IEC10X_ASDU_Call(Iec10x_Asdu);
  921. break;
  922. case IEC10X_C_CD_NA_1:
  923. LOG("++++asdu type delay active... \n");
  924. IEC10X_ASDU_Delay(Iec10x_Asdu);
  925. break;
  926. case IEC10X_C_CS_NA_1:
  927. LOG("++++asdu type clock active... \n");
  928. IEC10X_ASDU_CLOCK(Iec10x_Asdu);
  929. break;
  930. default:
  931. break;
  932. }
  933. break;
  934. default:
  935. LOG("++++error function code (%d)... \n", cfun);
  936. break;
  937. }
  938. #ifdef IEC10XLOCK
  939. if (IEC10X->UNLOCK != NULL)
  940. IEC10X->UNLOCK();
  941. #endif
  942. return RET_SUCESS;
  943. }
  944. void Iex101_main(uint8_t *buf, uint16_t len)
  945. {
  946. uint8_t *BufTemp = NULL;
  947. int16_t LenRemain, LenTmp;
  948. if (buf == NULL)
  949. {
  950. LOG("-%s-,buffer (null)", __FUNCTION__);
  951. return;
  952. }
  953. if (len <= 0 || len > IEC101_MAX_BUF_LEN)
  954. {
  955. LOG("-%s-,buffer len error(%d) \n", __FUNCTION__, len);
  956. return;
  957. }
  958. BufTemp = buf;
  959. LenRemain = len;
  960. while (BufTemp < buf + len)
  961. {
  962. if (BufTemp[0] == IEC101_STABLE_BEGING)
  963. {
  964. LenTmp = 6;
  965. IEC101_Pulse_Cnt = 0;
  966. if (LenRemain < 6)
  967. {
  968. LOG("_%s_,len error(%d) \n", __FUNCTION__, len);
  969. return;
  970. }
  971. Iec10x_Deal_10(BufTemp, LenTmp);
  972. }
  973. else if (BufTemp[0] == IEC101_VARIABLE_BEGING)
  974. {
  975. LenTmp = BufTemp[1] + 6;
  976. IEC101_Pulse_Cnt = 0;
  977. if (BufTemp[1] != BufTemp[2])
  978. {
  979. LOG("_%s_,len error(%d)(%d) \n", __FUNCTION__, BufTemp[1], BufTemp[2]);
  980. return;
  981. }
  982. Iec10x_Deal_68(BufTemp, LenTmp);
  983. }
  984. else
  985. {
  986. LOG("-%s-,head type error(%d) \n", __FUNCTION__, BufTemp[0]);
  987. return;
  988. }
  989. BufTemp += LenTmp;
  990. LenRemain -= LenTmp;
  991. }
  992. return;
  993. }
  994. uint8_t Iec101_StateMachine(void)
  995. {
  996. /*Init link*/
  997. switch (IEC101_STATE_FLAG_INIT)
  998. {
  999. case IEC101_FLAG_LINK_CLOSED:
  1000. break;
  1001. case IEC101_FLAG_INIT_LINK:
  1002. LOG("IEC101_FLAG_INIT_LINK \n");
  1003. Iec101_Respon_Confirm = 0;
  1004. Iec10x_Sta_Addr = IEC10X->GetLinkAddr();
  1005. IEC10X_RetStatusOk(Iec10x_Sta_Addr);
  1006. IEC101_STATE_FLAG_INIT = IEC101_FLAG_LINK_IDLE;
  1007. break;
  1008. case IEC101_FLAG_RESET_LINK:
  1009. LOG("IEC101_FLAG_RESET_LINK \n");
  1010. IEC10X_ClearQ();
  1011. IEC10X_ResConfirm(IEC10X_PRIO_INITLINK);
  1012. IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_CLOSED;
  1013. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_LINK_CLOSED;
  1014. IEC101_STATE_FLAG_DELAY = IEC101_FLAG_LINK_CLOSED;
  1015. IEC101_STATE_FLAG_PULSE = IEC101_FLAG_LINK_CLOSED;
  1016. IEC101_STATE_FLAG_INIT = IEC101_FLAG_REQ_LINK;
  1017. break;
  1018. case IEC101_FLAG_REQ_LINK:
  1019. LOG("IEC101_FLAG_REQ_LINK \n");
  1020. IEC10X_ReqLinkStatus();
  1021. IEC101_STATE_FLAG_INIT = IEC101_FLAG_LINK_IDLE;
  1022. break;
  1023. case IEC101_FLAG_RESET_REMOTE_LINK:
  1024. if (Iec101_Respon_Confirm)
  1025. {
  1026. Iec101_Respon_Confirm = 0;
  1027. IEC101_STATE_FLAG_INIT = IEC101_FLAG_INIT_FIN;
  1028. LOG("IEC101_FLAG_INIT_FIN! \n");
  1029. IEC101_BuildFinInit();
  1030. }
  1031. break;
  1032. case IEC101_FLAG_INIT_FIN:
  1033. if (Iec101_Respon_Confirm)
  1034. {
  1035. Iec101_Respon_Confirm = 0;
  1036. IEC101_STATE_FLAG_INIT = IEC101_FLAG_CONNECT_OK;
  1037. }
  1038. break;
  1039. case IEC101_FLAG_CONNECT_OK:
  1040. case IEC101_FLAG_LINK_IDLE:
  1041. default:
  1042. break;
  1043. }
  1044. /*total call*/
  1045. switch (IEC101_STATE_FLAG_CALLALL)
  1046. {
  1047. case IEC101_FLAG_CALL_ACT:
  1048. break;
  1049. case IEC101_FLAG_CALL_ACT_RET:
  1050. if (Iec101_Respon_Confirm)
  1051. {
  1052. Iec101_Respon_Confirm = 0;
  1053. IEC10X_ASDU_CALL_Qoi(IEC10X_Call_AllQoi);
  1054. }
  1055. break;
  1056. case IEC101_FLAG_CALL_SIG_TOTAL:
  1057. if (Iec101_Respon_Confirm)
  1058. {
  1059. Iec101_Respon_Confirm = 0;
  1060. IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_DET_TOTAL;
  1061. IEC101_BuildDetect(IEC10X_COT_INTROGEN, IEC10X_M_ME_NA_1, IEC10X_PRIO_CALLALL);
  1062. }
  1063. break;
  1064. case IEC101_FLAG_CALL_DET_TOTAL:
  1065. if (Iec101_Respon_Confirm)
  1066. {
  1067. Iec101_Respon_Confirm = 0;
  1068. IEC101_BuildActFinish(IEC10X_Call_AllQoi, IEC10X_PRIO_CALLALL);
  1069. IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_CALL_ACT_FIN;
  1070. }
  1071. break;
  1072. case IEC101_FLAG_CALL_ACT_FIN:
  1073. if (Iec101_Respon_Confirm)
  1074. {
  1075. Iec101_Respon_Confirm = 0;
  1076. IEC101_STATE_FLAG_CALLALL = IEC101_FLAG_LINK_IDLE;
  1077. }
  1078. break;
  1079. case IEC101_FLAG_LINK_IDLE:
  1080. default:
  1081. break;
  1082. }
  1083. /*group call*/
  1084. switch (IEC101_STATE_FLAG_GROUP)
  1085. {
  1086. case IEC101_FLAG_CALL_ACT:
  1087. break;
  1088. case IEC101_FLAG_CALL_ACT_RET:
  1089. if (Iec101_Respon_Confirm)
  1090. {
  1091. Iec101_Respon_Confirm = 0;
  1092. IEC10X_ASDU_CALL_Qoi(IEC10X_Call_GroupQoi);
  1093. }
  1094. break;
  1095. case IEC101_FLAG_CALL_GROUP:
  1096. if (Iec101_Respon_Confirm)
  1097. {
  1098. Iec101_Respon_Confirm = 0;
  1099. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_CALL_ACT_FIN;
  1100. IEC101_BuildActFinish(IEC10X_Call_GroupQoi, IEC10X_PRIO_CALLGROUP);
  1101. }
  1102. break;
  1103. case IEC101_FLAG_CALL_ACT_FIN:
  1104. if (Iec101_Respon_Confirm)
  1105. {
  1106. Iec101_Respon_Confirm = 0;
  1107. IEC101_STATE_FLAG_GROUP = IEC101_FLAG_LINK_IDLE;
  1108. }
  1109. break;
  1110. case IEC101_FLAG_LINK_IDLE:
  1111. default:
  1112. break;
  1113. }
  1114. /*delay and clock*/
  1115. switch (IEC101_STATE_FLAG_DELAY)
  1116. {
  1117. case IEC101_FLAG_DELAY_ACT:
  1118. break;
  1119. case IEC101_FLAG_CLOCK_SYS:
  1120. IEC101_STATE_FLAG_DELAY = IEC101_FLAG_LINK_IDLE;
  1121. break;
  1122. case IEC101_FLAG_LINK_IDLE:
  1123. default:
  1124. break;
  1125. }
  1126. /*pulse*/
  1127. switch (IEC101_STATE_FLAG_PULSE)
  1128. {
  1129. case IEC101_FLAG_PULSE:
  1130. break;
  1131. case IEC101_FLAG_LINK_IDLE:
  1132. break;
  1133. default:
  1134. break;
  1135. }
  1136. return RET_SUCESS;
  1137. }
  1138. #endif