ble_client_sender.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. --[[
  2. @module ble_client_sender
  3. @summary BLE client 数据发送应用功能模块
  4. @version 1.0
  5. @date 2025.08.20
  6. @author 王世豪
  7. @usage
  8. 本文件为BLE client 数据发送应用功能模块,核心业务逻辑为:
  9. 1、订阅"SEND_DATA_REQ"消息,将其他应用模块需要发送的数据存储到队列send_queue中;
  10. 2、BLE_client_sender task接收"CONNECT_OK"、"SEND_REQ"、两种类型的"BLE_EVENT"消息,处理队列中的数据;
  11. 3、接收"DISCONNECTED"类型的"BLE_EVENT"消息,清空发送队列;
  12. 4、数据发送完成后通过回调函数通知发送方。
  13. 本文件的对外接口有1个:
  14. 1. sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func); 订阅"SEND_DATA_REQ"消息;
  15. 其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的服务UUID、特征值UUID、数据、回调函数和回调参数一起publish出去;
  16. 本demo项目中ble_timer_app.lua中publish了这个消息;
  17. ]]
  18. local ble_client_sender = {}
  19. --[[
  20. 数据发送队列,数据结构为:
  21. {
  22. [1] = {service_uuid="service1", char_uuid="char1", data="data1", cb={func=callback_function1, para=callback_para1}},
  23. [2] = {service_uuid="service2", char_uuid="char2", data="data2", cb={func=callback_function2, para=callback_para2}},
  24. }
  25. service_uuid: BLE服务UUID,string类型,必须存在;
  26. char_uuid: BLE特征值UUID,string类型,必须存在;
  27. data: 要发送的数据,string类型,必须存在;
  28. cb.func: 数据发送结果的用户回调函数,可以不存在;
  29. cb.para: 数据发送结果的用户回调函数参数,可以不存在;
  30. ]]
  31. local send_queue = {}
  32. -- BLE client的任务名前缀
  33. ble_client_sender.TASK_NAME_PREFIX = "ble_client_"
  34. -- ble_client_sender的任务名
  35. ble_client_sender.TASK_NAME = ble_client_sender.TASK_NAME_PREFIX.."sender"
  36. -- "SEND_DATA_REQ"消息的处理函数
  37. local function send_data_req_proc_func(tag, service_uuid, char_uuid, data, cb)
  38. -- 将数据插入到发送队列send_queue中
  39. table.insert(send_queue, {service_uuid=service_uuid, char_uuid=char_uuid, data="send from " .. tag .. ": " .. data, cb=cb})
  40. -- 发送消息通知 BLE sender task,有新数据等待发送
  41. sys.sendMsg(ble_client_sender.TASK_NAME, "BLE_EVENT", "SEND_REQ")
  42. end
  43. -- 按照顺序发送send_queue中的数据
  44. -- 如果发送成功,则返回当前正在发送的数据项
  45. -- 如果发送失败,通知回调函数发送失败后,继续发送下一条数据
  46. local function send_item_func(ble_device)
  47. local item
  48. -- 如果发送队列中有数据等待发送
  49. while #send_queue>0 do
  50. -- 取出来第一条数据赋值给item
  51. -- 同时从队列send_queue中删除这一条数据
  52. item = table.remove(send_queue, 1)
  53. -- 发送数据
  54. local write_params = {
  55. uuid_service = string.fromHex(item.service_uuid),
  56. uuid_characteristic = string.fromHex(item.char_uuid)
  57. }
  58. local data = item.data
  59. local result = ble_device:write_value(write_params, data)
  60. -- 发送接口调用成功
  61. if result then
  62. -- 保存当前发送项,等待写入完成通知
  63. return item
  64. -- 发送接口调用失败
  65. else
  66. -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
  67. if item.cb and item.cb.func then
  68. item.cb.func(false, item.cb.para)
  69. end
  70. end
  71. end
  72. end
  73. -- 处理发送结果的回调函数
  74. local function send_item_cbfunc(item, result)
  75. if item then
  76. -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
  77. if item.cb and item.cb.func then
  78. item.cb.func(result, item.cb.para)
  79. end
  80. end
  81. end
  82. -- BLE client sender的任务处理函数
  83. local function ble_client_sender_task_func()
  84. local ble_device
  85. local send_item
  86. local result, msg
  87. while true do
  88. -- 等待"BLE_EVENT"消息
  89. msg = sys.waitMsg(ble_client_sender.TASK_NAME, "BLE_EVENT")
  90. -- BLE连接成功
  91. -- msg[3]表示ble_device对象
  92. if msg[2] == "CONNECT_OK" then
  93. sys.publish("BLE_CONNECT_STATUS", true)
  94. ble_device = msg[3]
  95. -- 发送send_queue中的数据
  96. send_item = send_item_func(ble_device)
  97. -- BLE发送数据请求
  98. elseif msg[2] == "SEND_REQ" then
  99. -- 如果ble_device对象存在,发送send_queue中的数据
  100. if ble_device then
  101. send_item_cbfunc(send_item, true)
  102. send_item = send_item_func(ble_device)
  103. end
  104. -- -- BLE发送完成(待完善......)
  105. -- elseif msg[2] == "SEND_OK" then
  106. -- -- send完成,执行回调并继续发送
  107. -- send_item_cbfunc(send_item, true)
  108. -- -- 发送send_queue中的下一条数据
  109. -- send_item = send_item_func(ble_device)
  110. -- BLE断开连接
  111. elseif msg[2] == "DISCONNECTED" then
  112. sys.publish("BLE_CONNECT_STATUS", false)
  113. -- 清空ble_device对象
  114. ble_device = nil
  115. -- 如果存在正在等待发送结果的发送项,执行回调函数通知发送方失败
  116. send_item_cbfunc(send_item, false)
  117. -- 如果发送队列中有数据等待发送
  118. while #send_queue>0 do
  119. -- 取出来第一条数据赋值给send_item
  120. -- 同时从队列send_queue中删除这一条数据
  121. send_item = table.remove(send_queue,1)
  122. -- 执行回调函数通知发送方失败
  123. send_item_cbfunc(send_item, false)
  124. end
  125. -- 当前没有正在等待发送结果的发送项
  126. send_item = nil
  127. end
  128. end
  129. end
  130. -- 订阅"SEND_DATA_REQ"消息;
  131. -- 其他应用模块如果需要发送数据,直接sys.publish这个消息即可
  132. -- 参数: tag(标签), service_uuid(服务UUID), char_uuid(特征值UUID), data(数据), cb(回调函数和参数)
  133. sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)
  134. --创建并且启动一个task
  135. --运行这个task的处理函数ble_client_sender_task_func
  136. sys.taskInitEx(ble_client_sender_task_func, ble_client_sender.TASK_NAME)
  137. return ble_client_sender