iec104_queue.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /**
  2. ************************************************************************************************
  3. * @文件 : Iec10x.c
  4. * @作者 : 樊春春
  5. * @版本 : V1.0
  6. * @时间 : 2022/07/09 16:18:42
  7. * @邮箱 : [email protected]
  8. * @说明 :
  9. ************************************************************************************************
  10. **/
  11. #include "iec104_queue.h"
  12. p_iec104_t iec104 = NULL;
  13. iec_16u iec104_state_addr = 0;
  14. iec104_prio_queue_t iec10x_prio_queue_array[IEC10X_PRIO_MAX];
  15. iec_16u IEC10X_Cp16time2a = 0;
  16. iec_16u IEC10X_Cp16time2a_V = 0;
  17. CP56Time2a_T IEC10X_Cp56time2a;
  18. void iec104_lock(void)
  19. {
  20. #ifdef IEC104LOCK
  21. if (iec104->lock != NULL)
  22. iec104->lock();
  23. #endif
  24. }
  25. void iec104_unlock(void)
  26. {
  27. #ifdef IEC104LOCK
  28. if (iec104->unlock != NULL)
  29. iec104->unlock();
  30. #endif
  31. }
  32. void iec104_queue_init(void)
  33. {
  34. iec_8u i;
  35. for (i = 0; i < IEC10X_PRIO_MAX; i++)
  36. {
  37. iec104->queue_init(&iec10x_prio_queue_array[i]);
  38. }
  39. }
  40. void iec104_queue_clear(void)
  41. {
  42. iec_8u i;
  43. for (i = 0; i < IEC10X_PRIO_MAX; i++)
  44. {
  45. iec104->queue_clear(&iec10x_prio_queue_array[i]);
  46. }
  47. }
  48. iec_8u iec104_prio_get(iec_8u State)
  49. {
  50. /*Prio from 0~7*/
  51. iec_8u Prio = 0;
  52. return Prio;
  53. }
  54. void iec104_enqueue(iec_8u *enq_buf, iec_16u Length, iec_8u Prio,
  55. void (*IEC10XCallBack)(iec104_callback_arg_t *Arg), iec104_callback_arg_t *CallbackArg)
  56. {
  57. iec104_prio_node_t *new_p;
  58. iec104_lock();
  59. if (Length < IEC10X_HEADER_LENGTH)
  60. {
  61. LOG("IEC10X_Enqueue,buffer too short \r\n");
  62. goto END;
  63. }
  64. new_p = (iec104_prio_node_t *)iec104->malloc(sizeof(iec104_prio_node_t) + Length - 1);
  65. if (new_p == NULL)
  66. {
  67. LOG("IEC10X_Enqueue,malloc error \r\n");
  68. goto END;
  69. }
  70. memcpy(new_p->value, enq_buf, Length);
  71. new_p->Length = Length;
  72. /* Prio from 1~8, Array from 0~7*/
  73. if (Prio >= IEC10X_PRIO_MAX)
  74. {
  75. LOG("IEC104_Enqueue, error Prio(%d) \r\n", Prio);
  76. goto END;
  77. }
  78. /* Set callback Argument */
  79. new_p->CallBack = IEC10XCallBack;
  80. if (CallbackArg != NULL)
  81. new_p->CallBackArg = *CallbackArg;
  82. new_p->CallBackArg.value = new_p->value;
  83. LOG("IEC104_Enqueue,Prio(%d) elementNum(%d)len(%d)(%d) \r\n", Prio, iec10x_prio_queue_array[Prio].element_num, Length, new_p->Length);
  84. // DumpHEX(new_p->value, new_p->Length);
  85. iec104->enqueue(&iec10x_prio_queue_array[Prio], new_p);
  86. END:
  87. iec104_unlock();
  88. return;
  89. }
  90. iec104_prio_node_t *iec104_dequeue(void)
  91. {
  92. iec_8u Prio;
  93. iec104_prio_node_t *ret;
  94. Prio = iec104->get_prio();
  95. if (Prio >= 8)
  96. {
  97. LOG("IEC104_Dequeue, Error Prio(%d) \r\n", Prio);
  98. return 0;
  99. }
  100. ret = iec104->dequeue(&iec10x_prio_queue_array[Prio]);
  101. if (ret)
  102. {
  103. iec10x_prio_queue_array[Prio].element_num--;
  104. }
  105. LOG("IEC104_Dequeue(%d) \r\n", ret->Length);
  106. return ret;
  107. }
  108. iec104_prio_node_t *IEC104_FindQHead(void)
  109. {
  110. iec_8u Prio;
  111. iec104_prio_node_t *ret;
  112. Prio = iec104->get_prio();
  113. if (Prio >= 8)
  114. {
  115. return 0;
  116. }
  117. ret = iec104->find_qhead(&iec10x_prio_queue_array[Prio]);
  118. return ret;
  119. }
  120. void iec104_scheduled(int socketfd)
  121. {
  122. iec104_prio_node_t *de_q_node;
  123. de_q_node = iec104_dequeue();
  124. if (de_q_node)
  125. {
  126. LOG("<<-------------------IEC10X (%d)-------------------->> \r\n", DeQNode->Length);
  127. /* call back funtion */
  128. if (de_q_node->CallBack)
  129. de_q_node->CallBack(&(de_q_node->CallBackArg));
  130. dump_hex(DeQNode->value, DeQNode->Length);
  131. iec104->send(socketfd, (char *)(de_q_node->value), de_q_node->Length);
  132. iec104_lock();
  133. iec104->free(de_q_node);
  134. iec104_unlock();
  135. }
  136. }
  137. iec_32s iec104_module_register(void *p_iec10x)
  138. {
  139. int ret;
  140. if (NULL == p_iec10x)
  141. {
  142. return -1;
  143. }
  144. else
  145. {
  146. iec104 = (p_iec104_t)p_iec10x;
  147. if (NULL == iec104->init)
  148. {
  149. return -1;
  150. }
  151. else
  152. {
  153. iec104_queue_init();
  154. // IEC10X_InitInfo();
  155. ret = iec104->init();
  156. if (0 == ret)
  157. {
  158. LOG("\r\nRegister \"%s\" IEC104 Success, < HuiXing 2014-2015 > ...\r\n", iec10x->name);
  159. }
  160. return ret;
  161. }
  162. }
  163. }
  164. #ifdef PRIO_QUEUE
  165. /*******************************************************************************
  166. * Function Name : iec10x_prio_highest
  167. * Description :
  168. * Input : None
  169. * Output : None
  170. * Return : RET_ERROR failure
  171. len sucess
  172. *******************************************************************************/
  173. iec_8u iec10x_prio_highest(void)
  174. {
  175. int i, prio;
  176. iec_8u flag = 0;
  177. prio = -1;
  178. // LOG("%s \r\n",__FUNCTION__);
  179. for (i = 0; i < IEC10X_PRIO_MAX; i++)
  180. {
  181. if (iec10x_prio_queue_array[i].element_num > 0 && !flag)
  182. {
  183. // return i;
  184. prio = i;
  185. flag = 1;
  186. LOG("<%s>Prio[%d],Num%d. \n", __FUNCTION__, i, iec10x_prio_queue_array[i].element_num);
  187. }
  188. LOG("[%d]%d.", i, iec10x_prio_queue_array[i].element_num);
  189. }
  190. LOG("out(%d)\r\n", prio);
  191. return prio;
  192. }
  193. void iec104_prio_queue_init(iec104_prio_queue_t *PrioQueue)
  194. {
  195. PrioQueue->header = NULL;
  196. PrioQueue->tail = NULL;
  197. PrioQueue->element_num = 0;
  198. }
  199. iec_8u iec104_prio_enqueue(iec104_prio_queue_t *queue_hdr, iec104_prio_node_t *new_p)
  200. {
  201. new_p->Next = NULL;
  202. if (queue_hdr->header == NULL)
  203. {
  204. queue_hdr->header = new_p;
  205. queue_hdr->tail = new_p;
  206. }
  207. else
  208. {
  209. queue_hdr->tail->Next = new_p;
  210. queue_hdr->tail = new_p;
  211. }
  212. queue_hdr->element_num++;
  213. LOG("%s ElementNum(%d) \r\n", __FUNCTION__, queue_hdr->element_num);
  214. return RET_SUCESS;
  215. }
  216. iec104_prio_node_t *iec104_prio_dequeue(iec104_prio_queue_t *queue_hdr)
  217. {
  218. iec104_prio_node_t *PrioNode_DeQ;
  219. if (queue_hdr->header == NULL)
  220. {
  221. LOG("PrioDeQueue,error \r\n");
  222. return NULL;
  223. }
  224. PrioNode_DeQ = queue_hdr->header;
  225. queue_hdr->header = queue_hdr->header->Next;
  226. if (queue_hdr->header == NULL)
  227. {
  228. queue_hdr->tail = NULL;
  229. }
  230. LOG("PrioDeQueue(%d) \r\n", PrioNode_DeQ->Length);
  231. return PrioNode_DeQ;
  232. }
  233. iec104_prio_node_t *iec104_prio_queue_find_head(iec104_prio_queue_t *queue_hdr)
  234. {
  235. iec104_prio_node_t *PrioNode_DeQ;
  236. if (queue_hdr->header == NULL)
  237. {
  238. // LOG("PrioDeQueue,error \r\n");
  239. return NULL;
  240. }
  241. PrioNode_DeQ = queue_hdr->header;
  242. // LOG("PrioDeQueue(%d) \r\n",PrioNode_DeQ->Length);
  243. return PrioNode_DeQ;
  244. }
  245. void *IEC10X_PeekQueue(iec104_prio_queue_t *queue_hdr)
  246. {
  247. if (queue_hdr->header == NULL)
  248. {
  249. // LOG(" ");
  250. return NULL;
  251. }
  252. return queue_hdr->header->value;
  253. }
  254. int IEC10X_Prio_IsEmptyQueue(iec104_prio_queue_t *queue_hdr)
  255. {
  256. if (queue_hdr->header == NULL)
  257. {
  258. return 1;
  259. }
  260. else
  261. {
  262. return 0;
  263. }
  264. }
  265. void iec104_prio_queue_clear(iec104_prio_queue_t *iec10x_prio_queue)
  266. {
  267. iec104_prio_node_t *p = iec10x_prio_queue->header;
  268. while (p != NULL)
  269. {
  270. iec10x_prio_queue->header = iec10x_prio_queue->header->Next;
  271. iec104->free(p);
  272. p = iec10x_prio_queue->header;
  273. }
  274. iec10x_prio_queue->tail = NULL;
  275. iec10x_prio_queue->element_num = 0;
  276. return;
  277. }
  278. #endif