tcp.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. --[[
  2. @module tcp
  3. @summary gnss使用psm测试功能模块
  4. @version 1.0
  5. @date 2025.07.27
  6. @author 李源龙
  7. @usage
  8. 使用Air8000核心板,连接TCP服务器,实现TCP通信功能
  9. ]]
  10. local tcp = {}
  11. local taskName = "TCP_TASK" -- sysplus库用到的任务名称,也作为任务id
  12. local uartid = 1 -- 根据实际设备选取不同的uartid
  13. local uart_rx_buff = zbuff.create(1024) -- 串口接收到的数据
  14. local libnet = require "libnet" -- libnet库,支持tcp、udp协议所用的同步阻塞接口
  15. local ip = "112.125.89.8" -- 连接tcp服务器的ip地址
  16. local port = 42009 -- 连接tcp服务器的端口
  17. local connect_state = false -- 连接状态 true:已连接 false:未连接
  18. local protocol = false -- 通讯协议 true:UDP协议 false:TCP协议
  19. local ssl = false -- 加密传输 true:加密 false:不加密
  20. local tx_buff = zbuff.create(1024) -- 发送至tcp服务器的数据
  21. local rx_buff = zbuff.create(1024) -- 从tcp服务器接收到的数据
  22. --初始化
  23. uart.setup(
  24. uartid,--串口id
  25. 9600,--波特率
  26. 8,--数据位
  27. 1--停止位
  28. )
  29. -- 处理未识别的消息
  30. local function tcp_client_main_cbfunc(msg)
  31. log.info("tcp_client_main_cbfunc", msg[1], msg[2], msg[3], msg[4])
  32. end
  33. --
  34. function tcp.latlngfnc(lat,lng)
  35. tx_buff:write(string.format('{"lat":%5f,"lng":%5f}', lat, lng))
  36. if connect_state then
  37. sys_send(taskName, socket.EVENT, 0)
  38. end
  39. end
  40. function TCP_TASK()
  41. -- 打印一下连接的目标ip和端口号
  42. log.info("connect ip: ", ip, "port:", port)
  43. while not socket.adapter() do
  44. log.warn("gnss_agps", "wait IP_READY")
  45. -- 在此处阻塞等待WIFI连接成功的消息"IP_READY"
  46. -- 或者等待30秒超时退出阻塞等待状态
  47. local result=sys.waitUntil("IP_READY", 30000)
  48. if result == false then
  49. log.warn("gnss_agps", "wait IP_READY timeout")
  50. return
  51. end
  52. end
  53. local socket_client
  54. while true do
  55. socket_client = socket.create(nil, taskName) -- 创建socket对象
  56. socket.debug(socket_client, true) -- 打开调试日志
  57. socket.config(socket_client, nil, protocol, ssl) -- 此配置为TCP连接,无SSL加密
  58. -- 连接服务器,返回是否连接成功
  59. result = libnet.connect(taskName, 15000, socket_client, ip, port)
  60. -- 收取数据会触发回调, 这里的"receive" 是固定值不要修改。
  61. uart.on(uartid, "receive", function(id, len)
  62. while true do
  63. local len = uart.rx(id, uart_rx_buff) -- 接收串口收到的数据,并赋值到uart_rx_buff
  64. if len <= 0 then -- 接收到的字节长度为0 则退出
  65. break
  66. end
  67. -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
  68. if connect_state then
  69. sys_send(taskName, socket.EVENT, 0)
  70. end
  71. break
  72. end
  73. end)
  74. -- 如果连接成功,则改变连接状态参数,并且随便发一条数据到服务器,看服务器能不能收到
  75. if result then
  76. connect_state = true
  77. libnet.tx(taskName, 0, socket_client, "TCP CONNECT")
  78. end
  79. -- 连接上服务器后,等待处理接收服务器下行至模块的数据 和 发送串口的数据到服务器
  80. while result do
  81. succ, param, _, _ = socket.rx(socket_client, rx_buff) -- 接收数据
  82. if not succ then
  83. log.info("服务器断开了", succ, param, ip, port)
  84. break
  85. end
  86. if rx_buff:used() > 0 then
  87. log.info("收到服务器数据,长度", rx_buff:used())
  88. uart.tx(uartid, rx_buff) -- 从服务器收到的数据转发 从串口输出
  89. rx_buff:del()
  90. end
  91. tx_buff:copy(nil, uart_rx_buff) -- 将串口数据赋值给tcp待发送数据的buff中
  92. uart_rx_buff:del() -- 清除串口buff的数据长度
  93. if tx_buff:used() > 0 then
  94. log.info("发送到服务器数据,长度", tx_buff:used())
  95. local result = libnet.tx(taskName, 0, socket_client, tx_buff) -- 发送数据
  96. if not result then
  97. log.info("发送失败了", result, param)
  98. break
  99. end
  100. end
  101. tx_buff:del()
  102. -- 如果zbuff对象长度超出,需要重新分配下空间
  103. if uart_rx_buff:len() > 1024 then
  104. uart_rx_buff:resize(1024)
  105. end
  106. if tx_buff:len() > 1024 then
  107. tx_buff:resize(1024)
  108. end
  109. if rx_buff:len() > 1024 then
  110. rx_buff:resize(1024)
  111. end
  112. log.info(rtos.meminfo("sys")) -- 打印系统内存
  113. -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
  114. result, param = libnet.wait(taskName, 15000, socket_client)
  115. if not result then
  116. log.info("服务器断开了", result, param)
  117. break
  118. end
  119. end
  120. -- 服务器断开后的行动,由于while true的影响,所以会再次重新执行进行 重新连接。
  121. connect_state = false
  122. libnet.close(d1Name, 5000, socket_client)
  123. socket.release(socket_client)
  124. tx_buff:clear(0)
  125. rx_buff:clear(0)
  126. socket_client=nil
  127. sys.wait(1000)
  128. end
  129. end
  130. -- libnet库依赖于sysplus,所以只能通过sysplus.taskInitEx创建的任务函数中运行
  131. sysplus.taskInitEx(TCP_TASK, taskName, tcp_client_main_cbfunc)
  132. return tcp