airtalk_net_ctrl.lua 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. local speech_state = SP_T_IDLE
  2. local speech_mdoe
  3. local g_mqttc = nil
  4. local client_id
  5. local downlink_topic
  6. local topic_auth
  7. local topic_list_update
  8. local topic_talk_start
  9. local topic_talk_stop
  10. local topic_list_update_ack
  11. local topic_talk_start_ack
  12. local topic_talk_stop_ack
  13. local speech_topic
  14. local speech_sample
  15. local dev_list
  16. local function task_cb(msg)
  17. log.info("未处理消息", msg[1], msg[2], msg[3], msg[4])
  18. end
  19. local function airtalk_event_cb(event, param)
  20. log.info("airtalk event", event, param)
  21. end
  22. local function next_auth()
  23. if speech_state == SP_T_IDLE then
  24. obj = {["key"] = PRODUCT_KEY, ["device_type"] = 1}
  25. data = json.encode(obj)
  26. log.info(topic_auth, data)
  27. mqttc:publish(topic_auth, data)
  28. end
  29. end
  30. local function mqtt_cb(mqttc, event, topic, payload)
  31. -- log.info(event)
  32. local msg,data,obj,speech_topic,speech_sample
  33. if event == "conack" then
  34. -- 联上了
  35. mqttc:subscribe("ctrl/downlink/" .. client_id .. "/#")--单主题订阅
  36. elseif event == "suback" then
  37. if speech_state == SP_T_IDLE then
  38. obj = {["key"] = PRODUCT_KEY, ["device_type"] = 1}
  39. data = json.encode(obj)
  40. log.info(topic_auth, data)
  41. mqttc:publish(topic_auth, data)
  42. sys.timerLoopStart(next_auth, 60000) --1分钟就尝试重新鉴权
  43. elseif speech_state == SP_T_CONNECTING then
  44. speech_state = SP_T_CONNECTED
  45. obj = {["result"] = SUCC, ["topic"] = msg[2], ["info"] = ""}
  46. data = json.encode(obj)
  47. log.info(topic_talk_start_ack, data)
  48. mqttc:publish(topic_talk_start_ack, data)
  49. airtalk.speech(true, speech_mdoe, speech_sample)
  50. else
  51. end
  52. elseif event == "recv" then
  53. local result = string.match(topic, downlink_topic)
  54. if result then
  55. log.info(topic, payload)
  56. local obj,res,err = json.decode(payload)
  57. if result == "0102" then
  58. if res and obj["topic"] and obj["ssrc"] and obj["audio_code"] then
  59. if speech_state == SP_T_CONNECTED then
  60. obj = {["result"] = "failed", ["topic"] = msg[2], ["info"] = "last speech is running"}
  61. data = json.encode(obj)
  62. log.info(topic_talk_start_ack, data)
  63. mqttc:publish(topic_talk_start_ack, data)
  64. airtalk.speech(true, speech_mdoe, speech_sample)
  65. elseif speech_state == SP_T_DISCONNECTING then
  66. obj = {["result"] = "failed", ["topic"] = msg[2], ["info"] = "last speech not stop"}
  67. data = json.encode(obj)
  68. log.info(topic_talk_start_ack, data)
  69. mqttc:publish(topic_talk_start_ack, data)
  70. airtalk.speech(true, speech_mdoe, speech_sample)
  71. else
  72. speech_state = SP_T_CONNECTING
  73. speech_topic = msg[2]
  74. speech_sample = msg[4] == "amr-nb" and 8000 or 16000
  75. mqttc:subscribe(speech_topic)
  76. airtalk.set_topic(speech_topic)
  77. airtalk.set_ssrc(msg[3])
  78. speech_mdoe = airtalk.MODE_PERSON
  79. end
  80. else
  81. obj = {["result"] = "failed", ["info"] = "json info error"}
  82. data = json.encode(obj)
  83. log.info(topic_talk_start_ack, data)
  84. mqttc:publish(topic_talk_start_ack, data)
  85. end
  86. elseif result == "0103" then
  87. if speech_state == SP_T_IDLE then
  88. obj = {["result"] = "failed", ["info"] = "no speech"}
  89. else
  90. obj = {["result"] = SUCC, ["info"] = ""}
  91. speech_state = SP_T_IDLE
  92. mqttc:unsubscribe(speech_topic)
  93. airtalk.speech(false)
  94. speech_topic = nil
  95. end
  96. data = json.encode(obj)
  97. mqttc:publish(topic_talk_stop_ack, data)
  98. elseif result == "0101" then
  99. if res then
  100. dev_list = obj["dev_list"]
  101. for i=1,#dev_list do
  102. log.info(dev_list[i]["id"],dev_list[i]["name"])
  103. end
  104. obj = {["result"] = SUCC, ["info"] = ""}
  105. else
  106. obj = {["result"] = "failed", ["info"] = "json info error"}
  107. end
  108. data = json.encode(obj)
  109. log.info(topic_list_update_ack, data)
  110. mqttc:publish(topic_list_update_ack, data)
  111. elseif result == "8003" then
  112. elseif result == "8004" then
  113. elseif result == "8001" then
  114. if res and obj["result"] then
  115. sys.timerLoopStart(next_auth, 3600000) --鉴权通过则60分钟后尝试重新鉴权
  116. mqttc:publish(topic_list_update, "")
  117. end
  118. elseif result == "8002" then
  119. if res and obj["result"] == SUCC then
  120. dev_list = obj["dev_list"]
  121. for i=1,#dev_list do
  122. log.info(dev_list[i]["id"],dev_list[i]["name"])
  123. end
  124. sys.sendMsg(USER_TASK_NAME, MSG_READY)
  125. end
  126. else
  127. end
  128. decode_data = nil
  129. end
  130. result = nil
  131. data = nil
  132. obj = nil
  133. elseif event == "sent" then
  134. -- log.info("mqtt", "sent", "pkgid", data)
  135. elseif event == "disconnect" then
  136. speech_state = SP_T_IDLE
  137. -- 非自动重连时,按需重启mqttc
  138. -- mqttc:connect()
  139. else
  140. end
  141. end
  142. function airtalk_mqtt_task()
  143. local msg,data,obj,speech_topic,speech_sample
  144. --client_id也可以自己设置
  145. client_id = mobile.imei()
  146. downlink_topic = "ctrl/downlink/" .. client_id .. "/(%w%w%w%w)"
  147. topic_auth = "ctrl/uplink/" .. client_id .."/0001"
  148. topic_list_update = "ctrl/uplink/" .. client_id .."/0002"
  149. topic_talk_start = "ctrl/uplink/" .. client_id .."/0003"
  150. topic_talk_stop = "ctrl/uplink/" .. client_id .."/0004"
  151. topic_list_update_ack = "ctrl/uplink/" .. client_id .."/8101"
  152. topic_talk_start_ack = "ctrl/uplink/" .. client_id .."/8102"
  153. topic_talk_stop_ack = "ctrl/uplink/" .. client_id .."/8103"
  154. sys.timerLoopStart(next_auth, 900000)
  155. g_mqttc = mqtt.create(nil, "mqtt.airtalk.luatos.com", 1883, false, {rxSize = 32768})
  156. airtalk.config(airtalk.PROTOCOL_MQTT, g_mqttc, 200) -- 缓冲至少200ms播放
  157. airtalk.on(airtalk_event_cb)
  158. airtalk.start()
  159. g_mqttc:auth(client_id,client_id,mobile.muid()) -- client_id必填,其余选填
  160. g_mqttc:keepalive(240) -- 默认值240s
  161. g_mqttc:autoreconn(true, 3000) -- 自动重连机制
  162. g_mqttc:debug(false)
  163. g_mqttc:on(mqtt_cb)
  164. -- mqttc自动处理重连, 除非自行关闭
  165. g_mqttc:connect()
  166. while true do
  167. msg = sys.waitMsg(AIRTALK_TASK_NAME)
  168. if type(msg) == 'table' and type(msg[1]) == "number" then
  169. if msg[1] == MSG_PERSON_SPEECH_REQ then
  170. -- if speech_state =
  171. -- speech_state = SP_T_CONNECTING
  172. -- obj = {["to"] = msg[2]}
  173. -- data = json.encode(obj)
  174. -- log.info(topic_talk_start, data)
  175. -- mqttc:publish(topic_talk_start, data)
  176. elseif msg[1] == MSG_SPEECH_STOP_REQ then
  177. speech_state = SP_T_IDLE
  178. mqttc:unsubscribe(speech_topic)
  179. airtalk.speech(false)
  180. speech_topic = nil
  181. data = json.encode(obj)
  182. log.info(topic_talk_stop, data)
  183. mqttc:publish(topic_talk_stop, data)
  184. end
  185. obj = nil
  186. else
  187. log.info(type(msg), type(msg[1]))
  188. end
  189. msg = nil
  190. end
  191. end
  192. function airtalk_mqtt_init()
  193. sys.taskInitEx(airtalk_mqtt_task, AIRTALK_TASK_NAME, task_cb)
  194. end