UdpListenerService.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. using AntDesign;
  2. using Microsoft.Extensions.Hosting;
  3. using Microsoft.Extensions.Logging;
  4. using OneOf.Types;
  5. using System.Net.Sockets;
  6. using System.Runtime.InteropServices;
  7. using System.Security.Cryptography;
  8. using System.Text;
  9. using static System.Runtime.InteropServices.JavaScript.JSType;
  10. namespace EasyTemplate.Service
  11. {
  12. public class UdpListenerService : IHostedService
  13. {
  14. private readonly ILogger<UdpListenerService> _logger;
  15. private UdpClient? _udpClient;
  16. public static List<string> ReceivedMessages { get; } = new();
  17. public Dictionary<int, NozzleState> g_mNozzleState = new Dictionary<int, NozzleState>();
  18. public UdpListenerService(ILogger<UdpListenerService> logger)
  19. {
  20. _logger = logger;
  21. }
  22. public string GetUdpData()
  23. {
  24. return "";
  25. }
  26. public Dictionary<int, NozzleState> GetNozzleState()
  27. {
  28. return g_mNozzleState;
  29. }
  30. public int getbufferdata(byte[] Buffer, ref int startIndex, int length)
  31. {
  32. if (startIndex + length > Buffer.Length)
  33. {
  34. return 0;
  35. }
  36. byte[] segment = new byte[length];
  37. Array.Copy(Buffer, startIndex, segment, 0, length);
  38. startIndex += length;
  39. int val = Tool.BytesToInt(segment);
  40. return val;
  41. }
  42. public Task StartAsync(CancellationToken cancellationToken)
  43. {
  44. _udpClient = new UdpClient(8080); // 监听8080端口
  45. _logger.LogInformation("开始监听UDP端口 8080");
  46. for (int i = 0; i < 40; i++)
  47. {
  48. NozzleState ns = new NozzleState();
  49. ns.noz = i + 1;
  50. ns.warnstate = i % 3;
  51. ns.oil = i % 2 == 0 ? "92#" : "95#";
  52. g_mNozzleState.Add(ns.noz, ns);
  53. }
  54. Task.Run(async () =>
  55. {
  56. while (!cancellationToken.IsCancellationRequested)
  57. {
  58. try
  59. {
  60. var result = await _udpClient.ReceiveAsync(cancellationToken);
  61. var message = Encoding.UTF8.GetString(result.Buffer);
  62. //dest-2;source-2;frame-1;length-2;cmd-1
  63. int datalength = result.Buffer[5] * 256 + result.Buffer[6];
  64. if (datalength + 9 == result.Buffer.Length)
  65. {
  66. // 计算crc
  67. int packlen = result.Buffer.Length;
  68. byte[] tmpbuf = result.Buffer;
  69. ushort nSum = Tool.chkcrc(tmpbuf, (ushort)(packlen - 2), 0xA001);
  70. ushort newSum = nSum;
  71. newSum = (ushort)(newSum / 256 + newSum % 256 * 256);
  72. ushort oldSum = BitConverter.ToUInt16(tmpbuf, packlen - 2);
  73. if (oldSum == newSum)
  74. {
  75. Console.WriteLine("CRC校验成功");
  76. }
  77. else
  78. {
  79. Console.WriteLine("crc校验失败");
  80. continue;
  81. }
  82. }
  83. else if (datalength + 9 == result.Buffer.Length + 2)
  84. {
  85. //旧协议无crc
  86. }
  87. else
  88. {
  89. continue;
  90. }
  91. int cmdtype = result.Buffer[7];
  92. int startindex = 8;
  93. switch (cmdtype)
  94. {
  95. case 1:
  96. filling_nozzleup up = extractFillingNozzleUP(result.Buffer, startindex);
  97. g_mNozzleState[up.noz].nozzlestate = Tool.NozzleState_Filling;
  98. break;
  99. case 2:
  100. filling_process process = extractFillingProcess(result.Buffer, startindex);
  101. g_mNozzleState[process.noz].nozzlestate = Tool.NozzleState_Filling;
  102. g_mNozzleState[process.noz].VLR = ((double)process.VLR / 1000).ToString("F2");
  103. break;
  104. case 3:
  105. filling_nozzledown down = extractFillingNozzleDown(result.Buffer, startindex);
  106. g_mNozzleState[down.noz].nozzlestate = Tool.NozzleState_Idle;
  107. break;
  108. case 4:
  109. filling_record record = extractFillingRecord(result.Buffer, startindex);
  110. g_mNozzleState[record.noz].nozzlestate = Tool.NozzleState_Idle;
  111. g_mNozzleState[record.noz].VLR = ((double)record.VLR / 1000).ToString("F2");
  112. break;
  113. default:
  114. continue;
  115. }
  116. string result1 = string.Join(", ", result.Buffer);
  117. lock (ReceivedMessages)
  118. {
  119. ReceivedMessages.Add($"{DateTime.Now:HH:mm:ss} - {message}");
  120. if (ReceivedMessages.Count > 100) ReceivedMessages.RemoveAt(0);
  121. }
  122. _logger.LogInformation($"接收到消息: {message}");
  123. // Echo back
  124. byte[] responseData = Encoding.UTF8.GetBytes("Echo: " + message);
  125. await _udpClient.SendAsync(responseData, responseData.Length, result.RemoteEndPoint);
  126. }
  127. catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
  128. {
  129. break;
  130. }
  131. catch (Exception ex)
  132. {
  133. _logger.LogError(ex, "接收UDP数据出错");
  134. }
  135. }
  136. }, cancellationToken);
  137. return Task.CompletedTask;
  138. }
  139. public Task StopAsync(CancellationToken cancellationToken)
  140. {
  141. _udpClient?.Close();
  142. _logger.LogInformation("停止监听UDP端口");
  143. return Task.CompletedTask;
  144. }
  145. public filling_nozzleup extractFillingNozzleUP(byte[] Buffer, int startIndex)
  146. {
  147. filling_nozzleup data = new filling_nozzleup();
  148. BufferHandler handler = new BufferHandler(Buffer, startIndex);
  149. data.board = handler.getData(1);
  150. data.noz = handler.getData(1);
  151. data.fip = data.board;
  152. data.time = handler.getDataString_BCD(7);
  153. return data;
  154. }
  155. public filling_nozzledown extractFillingNozzleDown(byte[] Buffer, int startIndex)
  156. {
  157. filling_nozzledown data = new filling_nozzledown();
  158. BufferHandler handler = new BufferHandler(Buffer, startIndex);
  159. data.board = handler.getData(1);
  160. data.noz = handler.getData(1);
  161. data.fip = data.board;
  162. data.time = handler.getDataString_BCD(7);
  163. return data;
  164. }
  165. public filling_process extractFillingProcess(byte[] Buffer, int startIndex)
  166. {
  167. filling_process data = new filling_process();
  168. BufferHandler handler = new BufferHandler(Buffer, startIndex);
  169. data.board = handler.getData(1);
  170. data.noz = handler.getData(1);
  171. data.fip = data.board;
  172. data.liquidVL = handler.getData(3);
  173. data.vaporVL = handler.getData(3);
  174. data.vaporFR = handler.getData(2);
  175. data.VLR = handler.getData(2);
  176. data.vaporPA = handler.getData(2);
  177. data.errornum = handler.getData(2);
  178. data.liquidFR = handler.getData(2);
  179. data.pwm = handler.getData(2);
  180. data.current = handler.getData(2);
  181. return data;
  182. }
  183. public filling_record extractFillingRecord(byte[] Buffer, int startIndex)
  184. {
  185. int bufferlen = Buffer.Length;
  186. filling_record data = new filling_record();
  187. BufferHandler handler = new BufferHandler(Buffer, startIndex);
  188. data.board = handler.getData(1);
  189. data.noz = handler.getData(1);
  190. data.fip = data.board;
  191. if (bufferlen != 22)//兼容旧协议,解析顺序改变
  192. {
  193. data.ttc = handler.getData(4);
  194. }
  195. data.liquidVL = handler.getData(3);
  196. data.liquidFR = handler.getData(2);
  197. data.vaporVL = handler.getData(3);
  198. data.vaporFR = handler.getData(2);
  199. data.VLR = handler.getData(2);
  200. data.tmBegin = handler.getDataString_BCD(7);
  201. data.tmEnd = handler.getDataString_BCD(7);
  202. data.errornum = handler.getData(2);
  203. data.vaporPA = handler.getData(2);
  204. data.pwm = handler.getData(2);
  205. return data;
  206. }
  207. public class BufferHandler
  208. {
  209. public byte[] buffer = Array.Empty<byte>();
  210. public int startIndex = 0;
  211. public int length = 0;
  212. public BufferHandler(byte[] buf, int startindex = 0)
  213. {
  214. buffer = buf;
  215. startIndex = startindex;
  216. length = buf.Length;
  217. }
  218. public string getDataString_BCD(int len)
  219. {
  220. if (startIndex + len > length)
  221. {
  222. return "";
  223. }
  224. byte[] segment = new byte[len];
  225. Array.Copy(buffer, startIndex, segment, 0, len);
  226. string result = Tool.BytesToBcd(segment);
  227. startIndex += len;
  228. return result;
  229. }
  230. public int getData(int len)
  231. {
  232. if (startIndex + len > length)
  233. {
  234. return 0;
  235. }
  236. byte[] segment = new byte[len];
  237. Array.Copy(buffer, startIndex, segment, 0, len);
  238. int val = Tool.BytesToInt(segment);
  239. startIndex += len;
  240. return val;
  241. }
  242. }
  243. //public filling_process struct2filling(s_vr_status cmd)
  244. //{
  245. // filling_process data = new filling_process();
  246. // //data.liquidVL = (uint)(st.liqvol[0] << 16 | st.liqvol[1] << 8 | st.liqvol[2]);
  247. // data.fip = cmd.fip;
  248. // data.noz = cmd.noz;
  249. // data.liquidVL = Tool.BytesToInt(cmd.liqvol);
  250. // data.liquidFR = Tool.BytesToInt(cmd.liqflow);
  251. // data.vaporFR = Tool.BytesToInt(cmd.vapflow);
  252. // data.vaporVL = Tool.BytesToInt(cmd.vapvol);
  253. // data.VLR = Tool.BytesToInt(cmd.vlr);
  254. // data.vaporPA = Tool.BytesToInt(cmd.press);
  255. // data.pwm = Tool.BytesToInt(cmd.pwm);
  256. // data.current = Tool.BytesToInt(cmd.current);
  257. // return data;
  258. //}
  259. public class NozzleState
  260. {
  261. public int noz = 0;
  262. public string VLR = "0";
  263. public string oil = string.Empty;
  264. public int nozzlestate = Tool.NozzleState_Offline;
  265. public int warnstate = Tool.WarningState_Normal;
  266. }
  267. public struct filling_nozzleup
  268. {
  269. public int fip;
  270. public int board;
  271. public int noz;
  272. public string time;
  273. /* byte cmd;
  274. byte fip;
  275. byte noz;
  276. byte time[7];
  277. byte product[4];*/
  278. /* auto& cmd = src->data.CMD1;
  279. dst.target = cmd.noz;
  280. _ubcd_to_str (dst.time, sizeof dst.time, cmd.time, sizeof cmd.time);
  281. _ubcd_to_str (dst.product, sizeof dst.product, cmd.product, sizeof cmd.product);*/
  282. }
  283. public struct filling_nozzledown
  284. {
  285. public int fip;
  286. public int board;
  287. public int noz;
  288. public string time;
  289. }
  290. public struct filling_record
  291. {
  292. public int fip;
  293. public int board;
  294. public int noz;
  295. public int liquidVL;
  296. public int vaporVL;
  297. public int liquidFR;
  298. public int vaporFR;
  299. public int VLR;
  300. public int vaporPA;
  301. public int ttc;
  302. public int VLR_BEFORE;
  303. public int VLR_OFFSET;
  304. public int pwm;
  305. public string tmBegin;
  306. public string tmEnd;
  307. public int overproof;
  308. public int uploadflag;
  309. public int uploadflag2;
  310. public int uploadflag3;
  311. public int downloadflag1;
  312. public int yz;
  313. public int tankpressure;
  314. public int refuelingseconds;
  315. public int errorcontrolvalue;
  316. public int errornum;
  317. public int callbackflag;
  318. public string vccerrorinfo;
  319. }
  320. public struct filling_process
  321. {
  322. public int fip;
  323. public int board;
  324. public int noz;
  325. public int liquidVL;
  326. public int vaporVL;
  327. public int liquidFR;
  328. public int vaporFR;
  329. public int VLR;
  330. public int vaporPA;
  331. public int ttc;
  332. public int VLR_BEFORE;
  333. public int VLR_OFFSET;
  334. public int errornum;
  335. public int pwm;
  336. public int current;
  337. }
  338. //[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  339. //public struct s_vr_status
  340. //{
  341. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  342. // public byte[] dest;
  343. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  344. // public byte[] source;
  345. // public byte frame;
  346. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  347. // public byte[] length;
  348. // public byte cmd;
  349. // public byte fip;
  350. // public byte noz;
  351. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  352. // public byte[] liqvol;
  353. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  354. // public byte[] vapvol;
  355. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  356. // public byte[] vapflow;
  357. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  358. // public byte[] vlr;
  359. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  360. // public byte[] press;
  361. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  362. // public byte[] errornum;
  363. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  364. // public byte[] liqflow;
  365. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  366. // public byte[] pwm;
  367. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  368. // public byte[] current;
  369. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
  370. // public byte[] crc;
  371. //}
  372. }
  373. }