tr_queue.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * queue.c
  3. *
  4. * Created on: 2025年8月20日
  5. * Author: 龙三郎
  6. */
  7. #include <tr_queue.h>
  8. #include <stdio.h>
  9. // 初始化队列
  10. void initializeQueue(Queue *q)
  11. {
  12. q->front = 0;
  13. q->rear = 0;
  14. }
  15. // 判断队列是否已满
  16. bool isFull(Queue *q)
  17. {
  18. return (q->rear + 1) % QUEUE_MAX_SIZE == q->front;
  19. }
  20. // 判断队列是否为空
  21. bool isEmpty(Queue *q)
  22. {
  23. return q->front == q->rear;
  24. }
  25. // 队列现有元素个数
  26. int currentItems(Queue *q)
  27. {
  28. if(q->rear >= q->front) {
  29. return q->rear - q->front;
  30. } else {
  31. return q->rear + QUEUE_MAX_SIZE - q->front + 1;
  32. }
  33. }
  34. // 队列剩余空间
  35. int remainSpace(Queue *q)
  36. {
  37. return QUEUE_MAX_SIZE - currentItems(q);
  38. }
  39. // 入队列,单个元素
  40. bool enqueue(Queue *q, unsigned char element)
  41. {
  42. if (isFull(q)) {
  43. return false; // 队列已满,无法添加新元素
  44. }
  45. q->items[q->rear] = element; // 将元素添加到队尾
  46. q->rear = (q->rear + 1) % QUEUE_MAX_SIZE; // 更新队尾指针,注意循环队列的处理方式
  47. return true; // 成功入队返回true
  48. }
  49. // 批量入队列
  50. bool enqueueBatch(Queue *q, unsigned char *elements, unsigned int elSize)
  51. {
  52. if(remainSpace(q) < elSize)
  53. {
  54. return false; // 队列空间不够,无法批量添加。
  55. }
  56. int i;
  57. for(i = 0; i < elSize; i++)
  58. {
  59. enqueue(q, *(elements + i));
  60. }
  61. return true;
  62. }
  63. // 出队列,单个元素
  64. bool dequeue(Queue *q, unsigned char *element)
  65. {
  66. if (isEmpty(q)) {
  67. return false; // 队列为空,无法移除元素
  68. }
  69. *element = q->items[q->front]; // 获取队首元素的值并传出参数(可选)
  70. q->front = (q->front + 1) % QUEUE_MAX_SIZE; // 更新队首指针,注意循环队列的处理方式
  71. return true; // 成功出队返回true
  72. }
  73. // 批量出队列
  74. bool dequeueBatch(Queue *q, unsigned short len, unsigned char *elements)
  75. {
  76. if (currentItems(q) < len) {
  77. return false; // 长度不够
  78. }
  79. int i;
  80. for(i = 0; i < len; i++)
  81. {
  82. dequeue(q, elements + i);
  83. }
  84. return true; // 成功出队返回true
  85. }
  86. // 查看队列中的元素,不出队列
  87. static bool queryQueue(Queue *q, unsigned short start, unsigned short len, unsigned char *element)
  88. {
  89. if (currentItems(q) < (start + len)) {
  90. return false; // 长度不够
  91. }
  92. int i;
  93. for(i = 0; i < len; i++)
  94. {
  95. int index = (q->front + start + i) % QUEUE_MAX_SIZE;
  96. *(element + i) = q->items[index]; // 获取队首元素的值并传出参数(可选)
  97. }
  98. return true; // 成功出队返回true
  99. }
  100. // 数据转发协议相关
  101. // 将源数据打包成协议数据
  102. static bool packageSourceData(unsigned char *s, unsigned short sl, unsigned char *d, unsigned short *dl, unsigned char da, unsigned char sa, unsigned char type)
  103. {
  104. unsigned short length = sl + 7;
  105. *(d) = 'T';
  106. *(d+1) = 'R';
  107. *(d+2) = 0x01;
  108. *(d+3) = (da & 0x0f) | ((sa << 4) & 0xf0);
  109. *(d+4) = (length >> 8) & 0xff;
  110. *(d+5) = length & 0xff;
  111. *(d+6) = type;
  112. memcpy((d+7), s, sl);
  113. *dl = length;
  114. return true;
  115. }
  116. // 将数据加上协议格式,并放入队列。
  117. static unsigned char buffer[BUFFER_SIZE_2K];
  118. static unsigned short bufferLength = 0;
  119. bool enqueueBatchWithProtocol(Queue *q, unsigned char *s, unsigned short sl, unsigned char da, unsigned char sa, unsigned char type)
  120. {
  121. packageSourceData(s, sl, buffer, &bufferLength, da, sa, type);
  122. return enqueueBatch(q, buffer, bufferLength);
  123. }
  124. // 从队列中取出一个数据包。
  125. bool dequeueBatchWithProtocol(Queue *q, unsigned char *d, unsigned short *dl)
  126. {
  127. while(true)
  128. {
  129. unsigned char pheader[3] = {0};
  130. if(!queryQueue(q, 0, 3, pheader))
  131. {
  132. return false;
  133. }
  134. if(pheader[0] == 'T' && pheader[1] == 'R' && pheader[2] == 0x01)
  135. {
  136. break;
  137. }
  138. else
  139. {
  140. dequeue(q, pheader);
  141. }
  142. }
  143. unsigned char plength[2] = {0};
  144. if(!queryQueue(q, 4, 2, plength))
  145. {
  146. return false;
  147. }
  148. unsigned short length = 0;
  149. length |= (plength[0] << 8) & 0xff00;
  150. length |= plength[1] & 0x00ff;
  151. // printf("length=%d\r\n", length);
  152. *dl = length;
  153. return dequeueBatch(q, length, d);
  154. }
  155. // 协议解析相关
  156. // 获取协议版本
  157. static bool verifyProtocol(unsigned char *p, unsigned short pl)
  158. {
  159. if(pl < 7)
  160. {
  161. return false;
  162. }
  163. unsigned short length = 0;
  164. length |= (*(p + 4) << 8) & 0xff00;
  165. length |= *(p + 5) & 0x00ff;
  166. if(length != pl)
  167. {
  168. return false;
  169. }
  170. return true;
  171. }
  172. bool getVerFromProtocol(unsigned char *p, unsigned short pl, unsigned char *ver)
  173. {
  174. if(!verifyProtocol(p, pl))
  175. {
  176. return false;
  177. }
  178. *ver = *(p + 2);
  179. return true;
  180. }
  181. // 获取目的地址
  182. bool getDaFromProtocol(unsigned char *p, unsigned short pl, unsigned char *da)
  183. {
  184. if(!verifyProtocol(p, pl))
  185. {
  186. return false;
  187. }
  188. *da = *(p + 3) & 0x0f;
  189. return true;
  190. }
  191. // 获取数据类型
  192. bool getTypeFromProtocol(unsigned char *p, unsigned short pl, unsigned char *type)
  193. {
  194. if(!verifyProtocol(p, pl))
  195. {
  196. return false;
  197. }
  198. *type = *(p + 6);
  199. return true;
  200. }
  201. // 获取来源地址
  202. bool getSaFromProtocol(unsigned char *p, unsigned short pl, unsigned char *sa)
  203. {
  204. if(!verifyProtocol(p, pl))
  205. {
  206. return false;
  207. }
  208. *sa = (*(p + 3) >> 4) & 0x0f;
  209. return true;
  210. }
  211. // 获取源数据
  212. bool getPayloadFromProtocol(unsigned char *p, unsigned short pl, unsigned char *s, unsigned short *sl)
  213. {
  214. if(!verifyProtocol(p, pl))
  215. {
  216. return false;
  217. }
  218. unsigned short length = pl - 7;
  219. *sl = length;
  220. memcpy(s, (p + 7), length);
  221. if(*sl == 0)
  222. {
  223. return false;
  224. }
  225. return true;
  226. }
  227. // 转发业务相关
  228. // 初始化
  229. Queue queueList[QUEUE_NUM];
  230. void dataforwardInit(void)
  231. {
  232. int i;
  233. for(i = 0; i < QUEUE_NUM; i++)
  234. {
  235. initializeQueue(&queueList[i]);
  236. }
  237. }
  238. // 主流程
  239. static unsigned char dfmBuffer[BUFFER_SIZE_2K];
  240. static unsigned short dfmBufferLength = 0;
  241. void dataforwardMain(void)
  242. {
  243. int i;
  244. for(i = 0; i < QUEUE_NUM; i++)
  245. {
  246. while(dequeueBatchWithProtocol(&queueList[i], dfmBuffer, &dfmBufferLength))
  247. {
  248. unsigned char da, sa, type;
  249. if(!getDaFromProtocol(dfmBuffer, dfmBufferLength, &da)
  250. || !getSaFromProtocol(dfmBuffer, dfmBufferLength, &sa)
  251. || !getTypeFromProtocol(dfmBuffer, dfmBufferLength, &type))
  252. {
  253. continue;
  254. }
  255. if(da == THIS_ADDRESS)
  256. {
  257. dataNotForwardedHandle(dfmBuffer, dfmBufferLength, sa, type);
  258. }
  259. else
  260. {
  261. dataForwardedHandle(dfmBuffer, dfmBufferLength, da);
  262. }
  263. }
  264. }
  265. }
  266. // 将从usb发来的协议数据入队列
  267. bool enqueueFromUsb(unsigned char *s, unsigned short sl)
  268. {
  269. return enqueueBatch(&queueList[QUEUE_INDEX_USB], s, sl);
  270. }
  271. // 将从以太网发来的协议数据入队列
  272. bool enqueueFromEthernet(unsigned char *s, unsigned short sl)
  273. {
  274. return enqueueBatch(&queueList[QUEUE_INDEX_ETHERNET], s, sl);
  275. }
  276. // 将从uart发来的协议数据入队列
  277. bool enqueueFromUart(unsigned char c)
  278. {
  279. return enqueue(&queueList[QUEUE_INDEX_UART], c);
  280. }
  281. // 将从uart发来的协议数据入队列
  282. bool enqueueFromUartBatch(unsigned char *s, unsigned short sl)
  283. {
  284. return enqueueBatch(&queueList[QUEUE_INDEX_UART], s, sl);
  285. }
  286. // 从本模块发出的数据入队列,源数据。不带协议格式
  287. bool enqueueFromHere(unsigned char *s, unsigned short sl, unsigned char da, unsigned char type)
  288. {
  289. return enqueueBatchWithProtocol(&queueList[QUEUE_INDEX_HEAR], s, sl, da, THIS_ADDRESS, type);
  290. }