Просмотр исходного кода

update: 继续完善nimble库, central模式能scan能connect但收发数据还有问题

Wendal Chen 3 лет назад
Родитель
Сommit
17b466d6d8

+ 2 - 2
components/nimble/src/luat_lib_nimble.c

@@ -274,8 +274,8 @@ static int l_nimble_mac(lua_State *L) {
 配置iBeacon的参数,仅iBeacon模式可用
 @api nimble.ibeacon(data, major, minor, measured_power)
 @string 数据, 必须是16字节
-@int 主版本号,默认2, 可选
-@int 次版本号,默认10,可选
+@int 主版本号,默认2, 可选, 范围 0 ~ 65536
+@int 次版本号,默认10,可选, 范围 0 ~ 65536
 @int 名义功率, 默认0, 范围 -126 到 20 
 @return bool 成功返回true,否则返回false
 @usage

+ 27 - 50
components/nimble/src/luat_nimble_mode_central.c

@@ -22,45 +22,21 @@
 
 /* BLE */
 #include "nimble/nimble_port.h"
-// #include "nimble/nimble_port_freertos.h"
 
-/* Heart-rate configuration */
-#define GATT_HRS_UUID                           0x180D
-#define GATT_HRS_MEASUREMENT_UUID               0x2A37
-#define GATT_HRS_BODY_SENSOR_LOC_UUID           0x2A38
-#define GATT_DEVICE_INFO_UUID                   0x180A
-#define GATT_MANUFACTURER_NAME_UUID             0x2A29
-#define GATT_MODEL_NUMBER_UUID                  0x2A24
-
-/** GATT server. */
-#define GATT_SVR_SVC_ALERT_UUID               0x1811
-#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
-#define GATT_SVR_CHR_NEW_ALERT                0x2A46
-#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
-#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
-#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
-
-// extern uint16_t hrs_hrm_handle;
-
-typedef void (*TaskFunction_t)( void * );
+static int ble_gatt_svc_counter = 0;
 
 struct ble_hs_cfg;
 struct ble_gatt_register_ctxt;
 
-
-
 typedef struct luat_nimble_scan_result
 {
     uint16_t uuids_16[16];
     uint32_t uuids_32[16];
     uint8_t uuids_128[16][16];
     char name[64];
-    ble_addr_t addr;
+    char addr[7]; // 地址类型 + MAC地址
 }luat_nimble_scan_result_t;
 
-// static void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
-// static int gatt_svr_init(void);
-
 void rand_bytes(uint8_t *data, int len);
 
 void print_bytes(const uint8_t *bytes, int len);
@@ -77,20 +53,9 @@ void print_conn_desc(const struct ble_gap_conn_desc *desc);
 
 void print_adv_fields(const struct ble_hs_adv_fields *fields);
 
-// static const char *manuf_name = "LuatOS";
-// static const char *model_num = "BLE Demo";
-// static uint16_t hrs_hrm_handle;
-// static uint16_t g_ble_attr_indicate_handle;
-// static uint16_t g_ble_attr_write_handle;
 extern uint16_t g_ble_conn_handle;
 extern uint16_t g_ble_state;
 
-#define WM_GATT_SVC_UUID      0xFFF0
-#define WM_GATT_INDICATE_UUID 0xFFF1
-#define WM_GATT_WRITE_UUID    0xFFF2
-#define WM_GATT_NOTIFY_UUID    0xFFF3
-
-
 #define LUAT_LOG_TAG "nimble"
 #include "luat_log.h"
 
@@ -182,6 +147,7 @@ int luat_nimble_blecent_connect(const char* _addr){
     int rc;
     ble_addr_t *addr;
     addr = (ble_addr_t *)_addr;
+    ble_gatt_svc_counter = 0;
 
     // 首先, 停止搜索
     rc = ble_gap_disc_cancel();
@@ -200,14 +166,16 @@ int luat_nimble_scan_cb(lua_State*L, void*ptr) {
 
     lua_pushliteral(L, "BLE_SCAN_RESULT");
 
-    lua_pushlstring(L, (const char*)&res->addr, 7);
-    lua_newtable(L);
-    // char buff[64];
+    lua_pushlstring(L, (const char*)res->addr, 7);
 
     if (res->name[0]) {
         lua_pushstring(L, res->name);
-        lua_setfield(L, -2, "name");
     }
+    else {
+        lua_pushliteral(L, ""); // 设备没有名字
+    }
+    lua_newtable(L);
+    // char buff[64];
 
     if (res->uuids_16[0]) {
         lua_newtable(L);
@@ -245,7 +213,7 @@ int luat_nimble_scan_cb(lua_State*L, void*ptr) {
     //     lua_setfield(L, -2, "uuids128");
     // }
     luat_heap_free(res);
-    lua_call(L, 3, 0);
+    lua_call(L, 4, 0);
     return 0;
 }
 
@@ -255,15 +223,17 @@ static int svc_disced(uint16_t conn_handle,
                                  void *arg) {
     LLOGD("ble_gatt_error status %d", error->status);
     if (error->status == BLE_HS_EDONE) {
-        LLOGD("service discovery done");
+        LLOGD("service discovery done count %d", ble_gatt_svc_counter);
         return 0;
     }
     if (error->status != 0) {
         return error->status;
     }
-
-
-
+    char buff[64] = {0};
+    ble_gatt_svc_counter ++;
+    LLOGD("service->start_handle %04X", service->start_handle);
+    LLOGD("service->end_handle %04X",   service->end_handle);
+    LLOGD("service->uuid %s",         ble_uuid_to_str(&service->uuid, buff));
     return 0;                
 }
 
@@ -292,22 +262,29 @@ static int blecent_gap_event(struct ble_gap_event *event, void *arg)
         if (res == NULL)
             return 0;
         memset(res, 0, sizeof(luat_nimble_scan_result_t));
+
+        char tmpbuff[64] = {0};
+
         for (i = 0; i < fields.num_uuids16 && i < 16; i++) {
+            LLOGD("uuids_16 %s", ble_uuid_to_str(&fields.uuids16[i], tmpbuff));
             res->uuids_16[i] = fields.uuids16[i].value;
         }
         for (i = 0; i < fields.num_uuids32 && i < 16; i++) {
+            LLOGD("uuids_32 %s", ble_uuid_to_str(&fields.uuids32[i], tmpbuff));
             res->uuids_32[i] = fields.uuids32[i].value;
         }
-        // for (i = 0; i < fields.num_uuids128 && i < 16; i++) {
-        //     memcpy(res->uuids_128[i], fields.uuids128[i].value, 16);
-        // }
-        memcpy(&res->addr, &event->disc.addr, sizeof(ble_addr_t));
+        for (i = 0; i < fields.num_uuids128 && i < 16; i++) {
+            LLOGD("uuids_128 %s", ble_uuid_to_str(&fields.uuids128[i], tmpbuff));
+            // memcpy(res->uuids_128[i], fields.uuids128[i].value, 16);
+        }
+        memcpy(res->addr, &event->disc.addr, 7);
         memcpy(res->name, fields.name, fields.name_len);
         LLOGD("addr %02X%02X%02X%02X%02X%02X", event->disc.addr.val[0], event->disc.addr.val[1], event->disc.addr.val[2], 
                                                event->disc.addr.val[3], event->disc.addr.val[4], event->disc.addr.val[5]);
         // for (i = 0; i < fields.num_uuids128 && i < 16; i++) {
         //     res->uuids_128[i] = fields.num_uuids128.value >> 32;
         // }
+        LLOGD("uuids 16=%d 32=%d 128=%d", fields.num_uuids16, fields.num_uuids32, fields.num_uuids128);
         msg.ptr = res;
         luat_msgbus_put(&msg, 0);
 

+ 0 - 108
components/nimble/src/luat_nimble_mode_peripheral.c

@@ -22,25 +22,6 @@
 
 /* BLE */
 #include "nimble/nimble_port.h"
-// #include "nimble/nimble_port_freertos.h"
-
-// /* Heart-rate configuration */
-// #define GATT_HRS_UUID                           0x180D
-// #define GATT_HRS_MEASUREMENT_UUID               0x2A37
-// #define GATT_HRS_BODY_SENSOR_LOC_UUID           0x2A38
-// #define GATT_DEVICE_INFO_UUID                   0x180A
-// #define GATT_MANUFACTURER_NAME_UUID             0x2A29
-// #define GATT_MODEL_NUMBER_UUID                  0x2A24
-
-// /** GATT server. */
-// #define GATT_SVR_SVC_ALERT_UUID               0x1811
-// #define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
-// #define GATT_SVR_CHR_NEW_ALERT                0x2A46
-// #define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
-// #define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
-// #define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
-
-// extern uint16_t hrs_hrm_handle;
 
 typedef void (*TaskFunction_t)( void * );
 
@@ -50,19 +31,11 @@ struct ble_gatt_register_ctxt;
 static void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
 static int gatt_svr_init(void);
 
-// static const char *manuf_name = "LuatOS";
-// static const char *model_num = "BLE Demo";
-// static uint16_t hrs_hrm_handle;
 static uint16_t g_ble_attr_indicate_handle;
 static uint16_t g_ble_attr_write_handle;
 extern uint16_t g_ble_conn_handle;
 extern uint16_t g_ble_state;
 
-// #define WM_GATT_SVC_UUID      0xFFF0
-// #define WM_GATT_INDICATE_UUID 0xFFF1
-// #define WM_GATT_WRITE_UUID    0xFFF2
-// #define WM_GATT_NOTIFY_UUID    0xFFF3
-
 extern ble_uuid_any_t ble_peripheral_srv_uuid;
 extern ble_uuid_any_t ble_peripheral_indicate_uuid;
 extern ble_uuid_any_t ble_peripheral_write_uuid;
@@ -102,19 +75,6 @@ static struct ble_gatt_svc_def gatt_svr_svcs[] = {
         .uuid = &ble_peripheral_srv_uuid,
         .characteristics = (struct ble_gatt_chr_def[])
         { {
-#if 0
-                /* Characteristic: Heart-rate measurement */
-                .uuid = BLE_UUID16_DECLARE(GATT_HRS_MEASUREMENT_UUID),
-                .access_cb = gatt_svr_chr_access_heart_rate,
-                .val_handle = &hrs_hrm_handle,
-                .flags = BLE_GATT_CHR_F_NOTIFY,
-            }, {
-                /* Characteristic: Body sensor location */
-                .uuid = BLE_UUID16_DECLARE(GATT_HRS_BODY_SENSOR_LOC_UUID),
-                .access_cb = gatt_svr_chr_access_heart_rate,
-                .flags = BLE_GATT_CHR_F_READ,
-            }, {
-#endif
                 /* Characteristic: Body sensor location */
                 // .uuid = BLE_UUID16_DECLARE(WM_GATT_WRITE_UUID),
                 .uuid = &ble_peripheral_write_uuid,
@@ -133,80 +93,12 @@ static struct ble_gatt_svc_def gatt_svr_svcs[] = {
             },
         }
     },
-#if 0
-    {
-        /* Service: Device Information */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = BLE_UUID16_DECLARE(GATT_DEVICE_INFO_UUID),
-        .characteristics = (struct ble_gatt_chr_def[])
-        { {
-                /* Characteristic: * Manufacturer name */
-                .uuid = BLE_UUID16_DECLARE(GATT_MANUFACTURER_NAME_UUID),
-                .access_cb = gatt_svr_chr_access_device_info,
-                .flags = BLE_GATT_CHR_F_READ,
-            }, {
-                /* Characteristic: Model number string */
-                .uuid = BLE_UUID16_DECLARE(GATT_MODEL_NUMBER_UUID),
-                .access_cb = gatt_svr_chr_access_device_info,
-                .flags = BLE_GATT_CHR_F_READ,
-            }, {
-                0, /* No more characteristics in this service */
-            },
-        }
-    },
-#endif
     {
         0, /* No more services */
     },
 };
 #endif
 
-#if 0
-static int
-gatt_svr_chr_access_heart_rate(uint16_t conn_handle, uint16_t attr_handle,
-                               struct ble_gatt_access_ctxt *ctxt, void *arg)
-{
-    /* Sensor location, set to "Chest" */
-    static uint8_t body_sens_loc = 0x01;
-    uint16_t uuid;
-    int rc;
-
-    uuid = ble_uuid_u16(ctxt->chr->uuid);
-
-    if (uuid == GATT_HRS_BODY_SENSOR_LOC_UUID) {
-        rc = os_mbuf_append(ctxt->om, &body_sens_loc, sizeof(body_sens_loc));
-
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-    }
-
-    assert(0);
-    return BLE_ATT_ERR_UNLIKELY;
-}
-
-static int
-gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
-                                struct ble_gatt_access_ctxt *ctxt, void *arg)
-{
-    uint16_t uuid;
-    int rc;
-
-    uuid = ble_uuid_u16(ctxt->chr->uuid);
-
-    if (uuid == GATT_MODEL_NUMBER_UUID) {
-        rc = os_mbuf_append(ctxt->om, model_num, strlen(model_num));
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-    }
-
-    if (uuid == GATT_MANUFACTURER_NAME_UUID) {
-        rc = os_mbuf_append(ctxt->om, manuf_name, strlen(manuf_name));
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-    }
-
-    assert(0);
-    return BLE_ATT_ERR_UNLIKELY;
-}
-#endif
-
 static void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
 {
     char buf[BLE_UUID_STR_LEN];

+ 69 - 0
demo/nimble/central/main.lua

@@ -0,0 +1,69 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "bledemo"
+VERSION = "1.0.0"
+
+--[[
+BLE centraldemo, 扫码并连接其他设备 ** 未完成 **
+支持的模块:
+1. Air101/Air103, 开发板的BLE天线未引出, 需要靠近使用, 且功耗高
+2. ESP32系列, 包括ESP32C3/ESP32S3
+
+-- 配合微信小程序 "LuatOS蓝牙调试"
+-- 1. 若开发板无天线, 将手机尽量靠近芯片也能搜到
+-- 2. 该小程序是开源的, 每次write会自动分包
+-- https://gitee.com/openLuat/luatos-miniapps
+]]
+
+log.info("main", PROJECT, VERSION)
+
+-- 一定要添加sys.lua !!!!
+sys = require("sys")
+
+--添加硬狗防止程序卡死
+if wdt then
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+
+-- 监听GATT服务器的WRITE_CHR, 也就是收取数据的回调
+sys.subscribe("BLE_GATT_WRITE_CHR", function(info, data)
+    -- info 是个table, 但当前没有数据
+    log.info("ble", "data got!!", data:toHex())
+end)
+
+-- 接收扫描结果
+sys.subscribe("BLE_SCAN_RESULT", function(addr, name, uuids)
+    log.info("ble scan", (addr:toHex()), name, json.encode(uuids))
+    if name == "LOS-065614A23900" then
+        nimble.connect(addr)
+    end
+end)
+
+sys.taskInit(function()
+    sys.wait(2000)
+
+    -- BLE模式, 默认是SERVER/Peripheral,即外设模式, 等待被连接的设
+    nimble.mode(nimble.CLIENT) -- 默认就是它, 不用调用
+
+    -- 可以自定义名称
+    -- nimble.init("LuatOS-Wendal") -- 蓝牙名称可修改,也有默认值LOS-$mac地址
+    nimble.init() -- 蓝牙名称可修改,也有默认值LOS-$mac地址
+
+    sys.wait(500)
+    -- 打印MAC地址
+    local mac = nimble.mac()
+    log.info("ble", "mac", mac and mac:toHex() or "Unknwn")
+    sys.wait(1000)
+
+    -- 发送数据
+    while 1 do
+        nimble.scan()
+        sys.wait(120000)
+    end
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 2 - 0
demo/nimble/ibeacon/main.lua

@@ -8,6 +8,8 @@ BLE iBeacon示例
 支持的模块:
 1. Air101/Air103, 开发板的BLE天线未引出, 需要靠近使用, 且功耗高
 2. ESP32系列, 包括ESP32C3/ESP32S3
+
+-- 使用蓝牙小程序, BeaconController, 可搜索到,且能看到数据变化
 ]]
 
 log.info("main", PROJECT, VERSION)

+ 1 - 11
demo/nimble/peripheral/main.lua

@@ -4,7 +4,7 @@ PROJECT = "bledemo"
 VERSION = "1.0.0"
 
 --[[
-BLE peripheral/外设/从机的demo, 等待被连接
+BLE peripheral的demo, 等待被连接的设备
 支持的模块:
 1. Air101/Air103, 开发板的BLE天线未引出, 需要靠近使用, 且功耗高
 2. ESP32系列, 包括ESP32C3/ESP32S3
@@ -26,16 +26,6 @@ if wdt then
     sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
 end
 
--- 监听BLE主适配的状态变化
-sys.subscribe("BLE_STATE_INC", function(state)
-    log.info("ble", "ble state changed", state)
-    if state == 1 then
-        nimble.server_init()
-    else
-        nimble.server_deinit()
-    end
-end)
-
 -- 监听GATT服务器的WRITE_CHR, 也就是收取数据的回调
 sys.subscribe("BLE_GATT_WRITE_CHR", function(info, data)
     -- info 是个table, 但当前没有数据