ble_scan.lua 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. --[[
  2. @module ble_ibeacon
  3. @summary Air8101演示scan功能模块
  4. @version 1.0
  5. @date 2025.11.18
  6. @author 王世豪
  7. @usage
  8. 本文件为Air8101核心板演示scan功能的代码示例,核心业务逻辑为:
  9. 观察者模式(scan)的基本流程(概要描述)
  10. 1. 初始化蓝牙框架
  11. 2. 创建BLE对象
  12. local ble_device = bluetooth_device:ble(ble_event_cb)
  13. 3.设置扫描模式
  14. ble_device:scan_create() -- 使用默认参数, addr_mode=0, scan_interval=100, scan_window=100
  15. 4. 开始扫描
  16. ble_device:scan_start()
  17. 5. 在回调函数中处理扫描事件, 如接收设备信息等
  18. 6. 按需停止扫描
  19. ble_device:scan_stop()
  20. ]]
  21. -- 扫描状态
  22. local scan_state = false
  23. -- 处理扫描报告事件
  24. local function handle_scan_report(ble_device, ble_param)
  25. -- 1. 打印基础设备信息
  26. log.info("ble_scan", "发现设备",
  27. "RSSI:", ble_param.rssi,
  28. "地址:", ble_param.adv_addr:toHex(),
  29. "数据:", ble_param.data:toHex())
  30. -- -- 2. 打印解析的广播数据
  31. -- local adv_data = ble_device:adv_decode(ble_param.data)
  32. -- if adv_data then
  33. -- for k, v in pairs(adv_data) do
  34. -- -- log.info("ble_scan", "广播数据", "长度:", v.len, "类型:", v.tp, "数据:", v.data:toHex())
  35. -- -- 以下是演示如何筛选ibeacon广播数据
  36. -- -- 检查Manufacturer Specific Data (类型0xFF)
  37. -- if v.tp == 0xFF then
  38. -- local mfg_data = v.data
  39. -- -- iBeacon格式检查
  40. -- if mfg_data:len() >= 25 then
  41. -- local company_id = mfg_data:byte(1) + mfg_data:byte(2) * 256
  42. -- local beacon_type = mfg_data:byte(3) -- 0x02
  43. -- local data_length = mfg_data:byte(4) -- 0x15 (21字节)
  44. -- if beacon_type == 0x02 and data_length == 0x15 then
  45. -- log.info("ble_scan", "发现iBeacon设备")
  46. -- -- 解析iBeacon数据
  47. -- local uuid = mfg_data:sub(5, 20):toHex()
  48. -- local major = mfg_data:byte(21) * 256 + mfg_data:byte(22)
  49. -- local minor = mfg_data:byte(23) * 256 + mfg_data:byte(24)
  50. -- local tx_power_byte = mfg_data:byte(25)
  51. -- local tx_power
  52. -- if tx_power_byte > 127 then
  53. -- tx_power = tx_power_byte - 256
  54. -- else
  55. -- tx_power = tx_power_byte
  56. -- end
  57. -- log.info("ble_scan", "iBeacon详情",
  58. -- "UUID:", uuid,
  59. -- "Major:", major,
  60. -- "Minor:", minor,
  61. -- "TxPower:", tx_power.. " dBm",
  62. -- "RSSI:", ble_param.rssi .. " dBm")
  63. -- end
  64. -- end
  65. -- end
  66. -- end
  67. -- end
  68. end
  69. -- 事件回调函数
  70. local function ble_callback(ble_device, ble_event, ble_param)
  71. -- 扫描初始化事件
  72. if ble_event == ble.EVENT_SCAN_INIT then
  73. log.info("ble_scan", "scan init")
  74. scan_state = true
  75. -- 扫描报告事件
  76. elseif ble_event == ble.EVENT_SCAN_REPORT then
  77. handle_scan_report(ble_device, ble_param)
  78. -- 停止扫描事件
  79. elseif ble_event == ble.EVENT_SCAN_STOP then
  80. log.info("ble_scan", "scan stop")
  81. scan_state = false
  82. -- 在这里可以添加自己的扫描停止后的处理逻辑
  83. end
  84. end
  85. function ble_scan_task_func()
  86. while true do
  87. -- 初始化蓝牙核心
  88. bluetooth_device = bluetooth_device or bluetooth.init()
  89. if not bluetooth_device then
  90. log.error("BLE", "蓝牙初始化失败")
  91. goto EXCEPTION_PROC
  92. end
  93. -- 初始化BLE功能
  94. ble_device = ble_device or bluetooth_device:ble(ble_callback)
  95. if not ble_device then
  96. log.error("BLE", "当前固件不支持完整的BLE")
  97. goto EXCEPTION_PROC
  98. end
  99. -- 创建扫描
  100. if not ble_device:scan_create() then
  101. log.error("BLE", "BLE创建扫描失败")
  102. goto EXCEPTION_PROC
  103. end
  104. log.info("ble_scan", "开始扫描")
  105. if not ble_device:scan_start() then
  106. log.error("ble_scan", "扫描启动失败")
  107. goto EXCEPTION_PROC
  108. end
  109. scan_state = true
  110. -- 等待直到扫描停止
  111. while scan_state do
  112. sys.wait(1000)
  113. end
  114. ::EXCEPTION_PROC::
  115. log.info("ble_scan", "检测到扫描异常,准备重新初始化")
  116. -- 停止扫描
  117. if ble_device then
  118. ble_device:scan_stop()
  119. ble_device = nil
  120. end
  121. -- 5秒后跳转到循环体开始位置,重新扫描
  122. sys.wait(5000)
  123. end
  124. end
  125. -- 启动扫描任务
  126. sys.taskInit(ble_scan_task_func)