onenetcoap.lua 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. --[[
  2. @module onenetcoap
  3. @summary 中移动OneNet平台COAP接入
  4. @version 1.0
  5. @date 2023.11.17
  6. @author wendal
  7. @demo onenet/coap
  8. @tag LUAT_USE_NETWORK
  9. @usage
  10. -- 使用方法请查阅demo
  11. ]]
  12. local onenet = {}
  13. local TAG = "onenet.coap"
  14. --[[
  15. 初始化onenet coap库
  16. @onenet.setup(conf)
  17. @table 配置项信息,必须有
  18. @return boolean 成功返回true,否则返回nil
  19. @usage
  20. -- 配置信息是一个table,具体键值如下:
  21. -- product_id 产品id,字符串,必须有
  22. -- device_name 设备名称,字符串,必须有
  23. -- device_key 设备密钥,字符串,必须有
  24. -- host coap服务器地址,字符串,默认"183.230.102.122"
  25. -- port coap服务器端口,整数,默认5683
  26. -- auto_reply 自动回复thing获取,布尔值,默认关闭false
  27. -- thing 物模型,类型是table,默认 {params={}}
  28. -- debug 调试开关,默认关闭false
  29. -- adapter 适配器编号,默认是最后一个注册的适配器
  30. -- callback 收到合法coap数据时的用户回调
  31. ]]
  32. function onenet.setup(conf)
  33. if not conf then
  34. return
  35. end
  36. if not conf.product_id then
  37. log.error(TAG, "配置信息缺product_id")
  38. return
  39. end
  40. if not conf.device_name then
  41. log.error(TAG, "配置信息缺device_name")
  42. return
  43. end
  44. if not conf.device_key then
  45. log.error(TAG, "配置信息缺device_key")
  46. return
  47. end
  48. onenet.product_id = conf.product_id
  49. onenet.device_name = conf.device_name
  50. -- log.info(">>", onenet.product_id, onenet.device_name, conf.device_key)
  51. _, _, onenet.login_token = iotauth.onenet(onenet.product_id, onenet.device_name, conf.device_key, "sha1")
  52. -- log.info("onenet.login_token", onenet.login_token)
  53. onenet.host = conf.host or "183.230.102.122"
  54. onenet.port = conf.port or 5683
  55. onenet.auto_reply = conf.auto_reply
  56. onenet.topic = conf.topic or "onenet_udp_inc"
  57. onenet.thing = conf.thing or {
  58. params = {}
  59. }
  60. onenet.debug = conf.debug
  61. onenet.thing_id = 1
  62. onenet.state = 0
  63. onenet.adapter = conf.adapter
  64. onenet.timeout = conf.timeout or 3000
  65. onenet.rx_buff = zbuff.create(1500)
  66. onenet.callback = conf.callback
  67. return true
  68. end
  69. function onenet.netc_cb(sc, event)
  70. -- log.info("udp", sc, string.format("%08X", event))
  71. local rxbuff = onenet.rx_buff
  72. if event == socket.EVENT then
  73. local ok, len, remote_ip, remote_port = socket.rx(sc, rxbuff)
  74. if ok then
  75. local data = rxbuff:query()
  76. rxbuff:del()
  77. log.info(TAG, "读到数据", data:toHex())
  78. ercoap.print(data)
  79. local resp = ercoap.parse(data)
  80. if resp and resp.code == 201 then
  81. log.info(TAG, "login success", resp.code, resp.payload:toHex())
  82. -- 这里非常重要, 获取其他请求所需要的token值
  83. onenet.post_token = resp.payload
  84. onenet.state = 2
  85. sys.publish(onenet.topic)
  86. end
  87. if resp then
  88. if onenet.callback then
  89. onenet.callback(resp)
  90. else
  91. sys.publish(onenet.topic, resp)
  92. end
  93. end
  94. else
  95. log.info(TAG, "服务器断开了连接")
  96. onenet.state = 0
  97. sys.publish(onenet.topic)
  98. end
  99. elseif event == socket.TX_OK then
  100. log.info(TAG, "上行完成")
  101. elseif event == socket.ON_LINE then
  102. log.info(TAG, "UDP已准备就绪,可以上行")
  103. -- 上行登陆包
  104. -- log.info("登陆参数", onenet.product_id, onenet.device_name, onenet.login_token)
  105. local data = ercoap.onenet("login", onenet.product_id, onenet.device_name, onenet.login_token)
  106. -- log.info("上行登陆包", data:toHex())
  107. socket.tx(sc, data)
  108. else
  109. log.info(TAG, "其他事件", event)
  110. end
  111. end
  112. function onenet.main_task()
  113. onenet.state = 1
  114. while onenet.state ~= 0 do
  115. local ok = onenet.main_loop()
  116. if not ok then
  117. sys.wait(500)
  118. end
  119. end
  120. end
  121. function onenet.main_loop()
  122. if onenet.netc == nil then
  123. onenet.netc = socket.create(onenet.adapter, onenet.netc_cb)
  124. end
  125. if onenet.netc == nil then
  126. log.info(TAG, "创建socket失败!!! 3秒后重试")
  127. return
  128. end
  129. local netc = onenet.netc
  130. if onenet.state ~= 2 then
  131. socket.config(netc, nil, true)
  132. if onenet.debug then
  133. socket.debug(netc, true)
  134. end
  135. socket.connect(netc, onenet.host, onenet.port)
  136. local result, resp = sys.waitUntil(onenet.topic, onenet.timeout)
  137. if not result then
  138. log.info(TAG, "等待底层连接成功超时了")
  139. return
  140. end
  141. end
  142. sys.waitUntil(onenet.topic, 3000)
  143. return
  144. end
  145. function onenet.start()
  146. if onenet.state ~= 0 then
  147. log.info("onenet", "coap", "已经在启动状态,不需要再启动")
  148. return
  149. end
  150. sys.taskInit(onenet.main_task)
  151. return true
  152. end
  153. function onenet.uplink(tp, payload)
  154. if not tp then
  155. return
  156. end
  157. if payload and payload["id"] == nil then
  158. payload["id"] = "1"
  159. end
  160. if type(payload) == "table" then
  161. payload = json.encode(payload, "7f")
  162. end
  163. -- log.info("uplink", onenet.product_id, onenet.device_name, onenet.post_token:toHex(), payload)
  164. local tmp = ercoap.onenet(tp, onenet.product_id, onenet.device_name, onenet.post_token, payload)
  165. -- log.info("uplink", tp, tmp:toHex())
  166. socket.tx(onenet.netc, tmp)
  167. return true
  168. end
  169. return onenet