蓝牙配网

更新时间:2024-09-18 03:30:28下载pdf

蓝牙配网是将扫地机设备通过蓝牙接收手机发来的配网信息,即路由热点的 SSID 和密码。收到配网信息后,扫地机执行激活流程,直至配网成功。

配网流程的业务逻辑已经在 TuyaOS SDK 内部实现,TuyaOS SDK 定义一套 TuyaOS Kernel Layer(简称 TKL)接口来屏蔽硬件和系统差异。TKL 接口由您实现,在 TKL 接口完成底层硬件的操作。本文将提供 TKL 接口开发指导。

流程说明

TuyaOS SDKApp路由器云端设备初始化,发送蓝牙-广播发现蓝牙广播,从而发现设备连接设备下发设备查询指令,获取设备信息下发配对指令下发蓝牙配网指令获取 SSID 和密码连接路由器连云激活TuyaOS SDKApp路由器云端
  1. 设备 TuyaOS SDK 初始化完成,发送蓝牙广播。
  2. App 主动连接未配网设备。
  3. App 获取设备信息。
  4. App 下发配对指令,未配对的连接超过 30s 就会被设备当做非法设备踢除,从而使蓝牙断连。
  5. App 下发蓝牙配网指令。设备通过此指令获取到路由 SSID、密码和 Token 信息。
  6. 设备 TuyaOS SDK 通过 SSID 和密码,连接路由器。
  7. 设备 TuyaOS SDK 通过 Token 连云激活,完成整个配网流程。

从以上流程可以看出,蓝牙配网流程很简单,除了通过蓝牙通道获取路由信息 SSID、密码和 Token,后面的配网流程和热点配网一样。

开发指导

环境准备

  • 准备涂鸦体系的 App、设备和路由器。
  • 设备蓝牙 LE 开启广播模式。

使用方法

  • tkl_ble_stack_init

    OPERATE_RET tkl_ble_stack_init(UCHAR_T role);
    

    TuyaOS SDK 初始化时调用该接口,应用可以在该接口中实现初始化蓝牙协议栈的功能。如果不需要初始化蓝牙相关业务,该接口为空实现即可。

  • tkl_ble_gap_callback_register

    OPERATE_RET tkl_ble_gap_callback_register(CONST TKL_BLE_GAP_EVT_FUNC_CB gap_evt);
    

    注册蓝牙 Generic Access Profile(GAP)层的事件回调接口,应用需要把 gap_evt 函数指针保存到全局变量。当应用收到蓝牙 GAP 数据时,通过函数指针把 GAP 数据传递给 TuyaOS SDK 处理。

    蓝牙配网过程中,主要关注的 GAP 是 TKL_BLE_GAP_EVT_CONNECT 事件。当应用检测到手机与扫地机设备建立蓝牙连接时,应用通过函数指针把 GAP 数据传递给 TuyaOS SDK。

  • tkl_ble_gatt_callback_register

    OPERATE_RET tkl_ble_gatt_callback_register(CONST TKL_BLE_GATT_EVT_FUNC_CB gatt_evt);
    

    注册蓝牙 Generic Attribute Profile(GATT)层的事件回调接口,应用需要把 gatt_evt 函数指针保存到全局变量。当应用收到蓝牙 GATT 数据时,通过函数指针把 GATT 数据传递给 TuyaOS SDK 处理。

    蓝牙配网过程中,主要关注的 GATT 是 TKL_BLE_GATT_EVT_WRITE_REQ 事件。当应用收到手机发送的 Service UUID 为 0xFD50 的 Write Request 时,应用通过函数指针把 GATT 数据传递给 TuyaOS SDK。

  • tkl_ble_gatts_service_add

    OPERATE_RET tkl_ble_gatts_service_add(TKL_BLE_GATTS_PARAMS_T *p_service);
    

    蓝牙 GATT 添加服务,并分配三个服务(WRITE、NOTIFY、READ)的 Handle 句柄值。该值可以是蓝牙平台反馈的值,也可以是您在适配层提供的固定值。此处服务的 Handle 句柄值要与数据传输给 TuyaOS SDK 时的 Handle 句柄值一致,例如 TKL_BLE_GATT_EVT_WRITE_REQ 类型的数据回复。

  • tkl_ble_gap_adv_rsp_data_set

    OPERATE_RET tkl_ble_gap_addr_set(TKL_BLE_GAP_ADDR_T CONST *p_peer_addr);
    

    TuyaOS SDK 设置广播以及扫描响应数据的接口,应用需要在接口中实现把广播数据以及扫描响应数据缓存起来。广播时使用广播数据,回复扫描响应请求时使用扫描响应数据。

  • tkl_ble_gap_adv_start

    OPERATE_RET tkl_ble_gap_adv_start(TKL_BLE_GAP_ADV_PARAMS_T CONST *p_adv_params);
    

    TuyaOS SDK 通知应用开启蓝牙广播的接口,应用需要在接口中实现开启蓝牙广播的功能,广播和扫描响应数据由 tkl_ble_gap_adv_rsp_data_set 接口设置。

  • tkl_ble_gap_adv_stop

    OPERATE_RET tkl_ble_gap_adv_stop(VOID);
    

    TuyaOS SDK 通知应用停止蓝牙广播的接口,应用需要在接口中实现关闭广播功能。

  • tkl_ble_gatts_value_notify

    OPERATE_RET tkl_ble_gatts_value_notify(USHORT_T conn_handle, USHORT_T char_handle, UCHAR_T *p_data, USHORT_T length);
    

    TuyaOS SDK 需要发送蓝牙 GATT 数据给手机时,会调用该接口。应用需要在接口中实现把 GATT 数据通过蓝牙发送给手机。

  • tkl_ble_gattc_exchange_mtu_request

    OPERATE_RET tkl_ble_gattc_exchange_mtu_request(USHORT_T conn_handle, USHORT_T client_rx_mtu);
    

    MTU 是设备与 App 协商的值,设备端设定一个 MTU 值,需要实现 tkl_ble_gattc_exchange_mtu_request 接口,将设备端的 MTU 上报给 TuyaOS SDK。如果未实现 tkl_ble_gattc_exchange_mtu_request 接口,那么 MTU 采用默认值 23

    以上是蓝牙配网必须实现的接口。蓝牙中的其他 TKL 接口实现,参考 移植 TuyaOS 到 Linux 平台

数据格式

蓝牙广播和扫描响应的数据格式:

蓝牙配网

Service 和 Characteristic 定义如下:

Service UUID:0xFD50

Characteristic                           UUID                           说明
WRITE_UUID           “00000001-0000-1001-8001-00805f9b07d0”   // Tuya 蓝牙 LE Write Characteristic UUID

NOTIFY_UUID          “00000002-0000-1001-8001-00805f9b07d0”   // Tuya 蓝牙 LE Notify Characteristic UUID

READ_UUID            “00000003-0000-1001-8001-00805f9b07d0”   // Tuya 蓝牙 LE Read Characteristic UUID

设备开发

  • 打开蓝牙服务开关

    /**
    * @brief Set enable switch for bluetooth service
    *
    * @param[in] switch: enable switch: TRUE-open, FALSE-close
    *
    * @note This API is used for setting enable switch for bluetooth service, it should be called before SDK initialization.
    *
    * @return VOID
    */
    VOID_T tuya_ble_set_serv_switch(BOOL_T swith);
    
  • 代码示例

    /**
    * @brief  系统启动的入口
    * @param  [int] mode
    * @param  [char *] token
    * @return [*]
    */
    OPERATE_RET ty_sys_start(WIFI_INIT_MODE_E connect_mode, CHAR_T *p_token)
    {
        OPERATE_RET ret = OPRT_OK;
        PR_DEBUG("sys start ");
        ret = ty_iot_sdk_init(connect_mode, p_token);    //IOT SDK 初始化
        if(OPRT_OK != ret){
            PR_ERR("tuya iot sdk init failed\n");
            return ret;
        }
        #if defined(TY_BT_MOD) && TY_BT_MOD == 1   //能力值打开的情况下,须在 IoT SDK 初始化之后调用
            tuya_ble_set_serv_switch(true);    //蓝牙能力开关
        #endif
        ret = ty_robot_media_sdk_init();    //机器人媒体 SDK 初始化
        if(OPRT_OK != ret){
            PR_ERR("ty robot media sdk init failed\n");
            return ret;
        }
        /***您业务上需要初始化的接口可以在此完成***/
        /***您业务上需要初始化的接口可以在此完成***/
        return ret;
    }
    

常见注意事项

  • TuyaOS SDK 的蓝牙广播长度是标准的 31 字节,有些平台的广播长度只支持 28 字节,会导致广播数据无法发送,需要蓝牙厂家将广播长度修改成 31 字节。

  • TuyaOS SDK 蓝牙初始化成功之后,需要蓝牙协议栈完成之后的回调事件(必须是蓝牙平台的底层协议栈真实的回调)发送给 TuyaOS SDK,TuyaOS SDK 才能发起广播更新(调用 tkl_ble_gap_adv_rsp_data_set)接口。

  • 在加入 GATT 服务的时候,Client Characteristic Configuration 描述符下需要增加 0x2902 的 UUID。如果没有加上,NOTIFY 服务会不起作用。

    蓝牙配网
  • tkl_ble_gatts_service_add 接口注册时,蓝牙平台要分配三个服务(WRITE、NOTIFY、READ)的 Handle 句柄值。可以是蓝牙平台反馈的值,也可以适配层的固定值。

    此处注册的 Handle 句柄值必须与实际传输给 TuyaOS SDK 的 Handle 句柄值保持一致,例如 TKL_BLE_GATT_EVT_WRITE_REQ 类型的数据回复就需要 Handle 句柄值给到 TuyaOS SDK,否则会导致 TuyaOS SDK 收不到蓝牙数据。

  • 如下问题就是注册的句柄值与上报给 TuyaOS SDK 的句柄值不一致,使得设备没有响应 App 下发的 0x01 指令,导致蓝牙连接后没有配对成功。在 30s 超时后,设备蓝牙被 App 认为是非法连接而被剔除。

    蓝牙配网
  • 参考激光扫地机 Demo 中的 ble_test 文件夹,验证 TKL 接口完整性,建议先用安卓手机来验证。

  • TKL 接口不允许阻塞,耗时的任务建议做异步处理。

  • 涂鸦蓝牙配网采用私有服务和私有数据,所有数据均由 SDK 解析和封装,您无需关心数据内容,直接透传处理。

  • 目前,部分安卓手机系统存在蓝牙兼容性问题,可能导致蓝牙配网失败。为解决此问题,您可以把蓝牙底层的 MTU 值修改为 247。例如,在 BlueZ 中,可以修改 BT_ATT_MAX_LE_MTU 宏值。