Device Pairing

Last Updated on : 2023-11-29 09:11:01download

This topic describes how pairing works on Bluetooth devices.

Overview

Concepts

Tuya’s pairing protocol is an application layer specification built on the Bluetooth Low Energy (LE) standard. It defines a set of protocols for pairing Bluetooth LE devices with the mobile app. Multi-layer encrypted data exchange via Tuya-specific services in tandem with Tuya’s things data model enables secure and reliable point-to-point Bluetooth data transferring for IoT applications. Tuya’s pairing protocol is compatible with all versions of Bluetooth 4.x and 5.x standards.

Besides the Primary Service, Tuya’s pairing protocol also includes the Tuya-specific service (UUID: 0xFD50). This service defines properties (read, write, and notify) for characteristic values and specifies Bluetooth LE parameters such as advertising period/interval, connection interval/mode, and data exchange method to maximize Bluetooth performance.

Concepts

Device Pairing

Role

There are two major players involved in the pairing process: the central and the peripheral. Usually, the central is the mobile app, and the peripheral is the Bluetooth smart device.

  • Centrals: Smart Life app (mobile phone) and Bluetooth gateway.

  • Peripherals: Bluetooth smart devices, such as door locks, lights, trackers, body fat scales, and wrist-worn wearables.

How a central and a peripheral interact with each other:

  1. A central can discover a peripheral that is advertising.
  2. A central initiates a connection request to an authorized peripheral. After successful pairing, the peripheral is bound with the device.
  3. They communicate with each other (including the exchange of data point data) over a secure channel in compliance with Bluetooth specifications.

Pairing process

The following figures show the process of establishing a secure channel (pairing).

  • Pairing:

    Device Pairing
  • Reconnect:

    Device Pairing

Concepts in the pairing process:

  • Connect: Indicates a Bluetooth device is in the connection state in the link layer.

  • Pair: Refers to a process where a range of keys is exchanged between devices.

  • Bound: Refers to a kind of status. The status of a paired device is bound. Paired devices communicate with each other over a secure channel.

  • Reconnect: Refers to a process where a range of keys is exchanged between devices, in other words, a simplified pairing process. To enter this process, the device should have been bound.

  • Unpair: also known as remove or unbind, refers to a process where the key is deleted, and the binding status is cleared.

Unbinding process

  • Unbind

    • Trigger: Tap the Unbind button on the app panel.

    • Event: TUYA_BLE_CB_EVT_UNBOUND

  • Unbind and clear data

    • Trigger: Tap the Unbind and Clear Data button on the app panel.

    • Event: TUYA_BLE_CB_EVT_DEVICE_RESET

Data structure

tuya_ble_addr_type_t

typedef enum {
    TUYA_BLE_ADDRESS_TYPE_PUBLIC, // public address
    TUYA_BLE_ADDRESS_TYPE_RANDOM, // random address
} tuya_ble_addr_type_t;
  • TUYA_BLE_ADDRESS_TYPE_PUBLIC: The type of the public address.
  • TUYA_BLE_ADDRESS_TYPE_RANDOM: The type of the random address.

tuya_ble_gap_addr_t

typedef struct {
    tuya_ble_addr_type_t addr_type;
    UINT8_T addr[6];
} tuya_ble_gap_addr_t;
  • addr_type: See tuya_ble_addr_type_t.
  • addr: The 6-byte MAC address.

tuya_ble_product_id_type_t

typedef enum {
    TUYA_BLE_PRODUCT_ID_TYPE_PID,
    TUYA_BLE_PRODUCT_ID_TYPE_PRODUCT_KEY,
} tuya_ble_product_id_type_t;
  • TUYA_BLE_PRODUCT_ID_TYPE_PID: The type of the product ID.
  • TUYA_BLE_PRODUCT_ID_TYPE_PRODUCT_KEY: The type of the product key.

tuya_ble_device_param_t

typedef struct {
    UINT8_T use_ext_license_key; //If use the license key stored by the SDK,initialized to 0, Otherwise 1.
    UINT8_T device_id_len;       //if ==20,Compressed into 16
    UINT8_T device_id[DEVICE_ID_LEN_MAX];
    UINT8_T auth_key[AUTH_KEY_LEN];
    tuya_ble_gap_addr_t mac_addr;
    UINT8_T mac_addr_string[MAC_STRING_LEN];

    tuya_ble_product_id_type_t p_type;
    UINT8_T product_id_len;
    UINT8_T product_id[TUYA_BLE_PRODUCT_ID_MAX_LEN];
    UINT8_T adv_local_name_len;
    UINT8_T adv_local_name[TUYA_BLE_ADV_LOCAL_NAME_MAX_SPACE_LEN]; //Only supported when TUYA_BLE_PROTOCOL_VERSION_HIGN >= 4.
    UINT32_T firmware_version; //0x00010102 : v1.1.2
    UINT32_T hardware_version;

    UINT8_T device_vid[DEVICE_VIRTUAL_ID_LEN];
    UINT8_T login_key[LOGIN_KEY_LEN];
    UINT8_T beacon_key[BEACON_KEY_LEN];
    UINT8_T bound_flag;

    UINT8_T reserve_1;
    UINT8_T reserve_2;
} tuya_ble_device_param_t;
  • use_ext_license_key: Specifies whether to use the debugged authorization information. 0: Not use. 1: Use.

  • device_id_len: The length of the device ID.

  • device_id: The device ID.

  • auth_key: The 32-byte authorization key.

  • mac_addr: See tuya_ble_gap_addr_t.

  • mac_addr_string: The 12-byte MAC address string.

  • p_type: See tuya_ble_product_id_type_t.

  • product_id_len: The length of the PID.

  • product_id: The PID.

  • adv_local_name_len: The length of the Bluetooth advertising name.

  • adv_local_name: The Bluetooth advertising name (the name shown on nRF Connect).

  • firmware_version: The firmware version, for example, 1.1.0.

  • hardware_version: The hardware version, for example, 1.0.0.

  • device_vid: The 22-byte virtual device ID.

  • login_key: The 6-byte registration key.

  • beacon_key: The 16-byte beacon key.

  • bound_flag: Specifies whether the device is bound.

See the example code in tal_ble_protocol_callback.c for usage.

tuya_ble_connect_status_t

typedef enum {
    UNBONDING_UNCONN = 0,
    UNBONDING_CONN,
    BONDING_UNCONN,
    BONDING_CONN,
    BONDING_UNAUTH_CONN,
    UNBONDING_UNAUTH_CONN,
    UNKNOW_STATUS
} tuya_ble_connect_status_t;
  • UNBONDING_UNCONN: The device is unbound and not connected.
  • UNBONDING_CONN: The device is unbound but connected.
  • BONDING_UNCONN: The device is bound but not connected.
  • BONDING_CONN: The device is bound and connected.
  • BONDING_UNAUTH_CONN: The device is bound and connected, but not authenticated.
  • UNBONDING_UNAUTH_CONN: The device is unbound and unauthorized but connected.
  • UNKNOW_STATUS: Unknown status.

The following figure shows how the state is changed.

Device Pairing

API description

Pairing initialization

This API is used to process pairing parameters and events in the communication between the Tuya-enabled Bluetooth device and the mobile app.

VOID_T tuya_ble_protocol_init(VOID_T)
{
    tuya_ble_protocol_param.firmware_version = tal_common_info.firmware_version,
    tuya_ble_protocol_param.hardware_version = tal_common_info.hardware_version,
    memcpy(tuya_ble_protocol_param.device_id,       device_id_test, DEVICE_ID_LEN);
    memcpy(tuya_ble_protocol_param.auth_key,        auth_key_test, AUTH_KEY_LEN);
    memcpy(tuya_ble_protocol_param.mac_addr_string, TY_DEVICE_MAC, MAC_STRING_LEN);
    memcpy(tuya_ble_protocol_param.product_id,      TY_DEVICE_PID, tuya_ble_protocol_param.product_id_len);
    memcpy(tuya_ble_protocol_param.adv_local_name, TY_DEVICE_NAME, tuya_ble_protocol_param.adv_local_name_len);
    tuya_ble_sdk_init(&tuya_ble_protocol_param);

    tuya_ble_callback_queue_register(tuya_ble_protocol_callback);

    ……
}
  • tuya_ble_sdk_init() is used to initialize the parameters including firmware version, MAC address, device ID, authkey, PID, and advertising name.

  • tuya_ble_callback_queue_register() is used to register callbacks to process pairing logic including pairing state, timestamp, DP data, and unbinding.

Pairing callbacks

The callback to invoke when pairing is completed.

STATIC VOID_T tuya_ble_protocol_callback(tuya_ble_cb_evt_param_t* event)

The following snippet provides the events that might occur during pairing and communication.

typedef enum {
    TUYA_BLE_CB_EVT_CONNECTE_STATUS = TUYA_BLE_CB_EVT_BASE,
    TUYA_BLE_CB_EVT_DP_WRITE,          // old version
    TUYA_BLE_CB_EVT_DP_QUERY,
    TUYA_BLE_CB_EVT_DP_DATA_RECEIVED, // new version
    TUYA_BLE_CB_EVT_OTA_DATA,
    TUYA_BLE_CB_EVT_BULK_DATA,
    TUYA_BLE_CB_EVT_NETWORK_INFO,
    TUYA_BLE_CB_EVT_WIFI_SSID,
    TUYA_BLE_CB_EVT_TIME_STAMP,
    TUYA_BLE_CB_EVT_TIME_NORMAL,
    TUYA_BLE_CB_EVT_APP_LOCAL_TIME_NORMAL,
    TUYA_BLE_CB_EVT_TIME_STAMP_WITH_DST,
    TUYA_BLE_CB_EVT_DATA_PASSTHROUGH,
    TUYA_BLE_CB_EVT_DP_DATA_REPORT_RESPONSE,
    TUYA_BLE_CB_EVT_DP_DATA_WTTH_TIME_REPORT_RESPONSE,
    TUYA_BLE_CB_EVT_DP_DATA_WITH_FLAG_REPORT_RESPONSE,
    TUYA_BLE_CB_EVT_DP_DATA_WITH_FLAG_AND_TIME_REPORT_RESPONSE,
    TUYA_BLE_CB_EVT_DP_DATA_SEND_RESPONSE,               // new version
    TUYA_BLE_CB_EVT_DP_DATA_WITH_TIME_SEND_RESPONSE,     // new version
    TUYA_BLE_CB_EVT_UNBOUND,
    TUYA_BLE_CB_EVT_ANOMALY_UNBOUND,
    TUYA_BLE_CB_EVT_DEVICE_RESET,
    TUYA_BLE_CB_EVT_UPDATE_LOGIN_KEY_VID,
    TUYA_BLE_CB_EVT_UNBIND_RESET_RESPONSE,               // Notify the application of the result of the local reset
    TUYA_BLE_CB_EVT_WEATHER_DATA_REQ_RESPONSE,             // received request weather data app response
    TUYA_BLE_CB_EVT_WEATHER_DATA_RECEIVED,                  // received app sync weather data
    TUYA_BLE_CB_EVT_REMOTER_PROXY_AUTH_RESP,
    TUYA_BLE_CB_EVT_REMOTER_GROUP_SET,
    TUYA_BLE_CB_EVT_REMOTER_GROUP_DELETE,
    TUYA_BLE_CB_EVT_REMOTER_GROUP_GET,
} tuya_ble_cb_evt_t;

Query network status

tuya_ble_connect_status_t tuya_ble_connect_status_get(VOID_T);

tuya_ble_connect_status_t: See tuya_ble_connect_status_t.

How to use

Communication process

Device Pairing

Code development

See the example code in tal_ble_protocol_callback.c for usage.

STATIC tuya_ble_device_param_t tuya_ble_protocol_param = {
#if (TUYA_SDK_DEBUG_MODE)
    .use_ext_license_key = 1, //1-info in tuya_ble_protocol_callback.h, 0-auth info
    .device_id_len       = DEVICE_ID_LEN,
#else
    .use_ext_license_key = 0,
    .device_id_len       = 0,
#endif
    .p_type              = TUYA_BLE_PRODUCT_ID_TYPE_PID,
#if (TUYA_BLE_PROD_SUPPORT_OEM_TYPE == TUYA_BLE_PROD_OEM_TYPE_NONE)
    .product_id_len      = 8,
#else
    .product_id_len      = 0,
#endif
    .adv_local_name_len  = 4,
};

STATIC VOID_T tuya_ble_protocol_callback(tuya_ble_cb_evt_param_t* event)
{
    switch (event->evt) {
        case TUYA_BLE_CB_EVT_CONNECTE_STATUS: {
            if (event->connect_status == BONDING_CONN) {
                TAL_PR_INFO("bonding and connecting");

                tuya_ble_update_conn_param_timer_start();
            }
        } break;

        case TUYA_BLE_CB_EVT_DP_DATA_RECEIVED: {
            app_dp_parser(event->dp_received_data.p_data, event->dp_received_data.data_len);
        } break;

        …………

        case TUYA_BLE_CB_EVT_UNBOUND: {
            TAL_PR_INFO("TUYA_BLE_CB_EVT_UNBOUND");
        } break;

        case TUYA_BLE_CB_EVT_ANOMALY_UNBOUND: {
            TAL_PR_INFO("TUYA_BLE_CB_EVT_ANOMALY_UNBOUND");
        } break;

        case TUYA_BLE_CB_EVT_DEVICE_RESET: {
            TAL_PR_INFO("TUYA_BLE_CB_EVT_DEVICE_RESET");
        } break;

        case TUYA_BLE_CB_EVT_UNBIND_RESET_RESPONSE: {
            TAL_PR_INFO("TUYA_BLE_CB_EVT_UNBIND_RESET_RESPONSE");
        } break;

        …………

        default: {
            TAL_PR_INFO("tuya_ble_protocol_callback Unprocessed event type 0x%04x", event->evt);
        } break;
    }
    …………
}

VOID_T tuya_ble_protocol_init(VOID_T)
{
    tuya_ble_protocol_param.firmware_version = tal_common_info.firmware_version,
    tuya_ble_protocol_param.hardware_version = tal_common_info.hardware_version,
    memcpy(tuya_ble_protocol_param.device_id,       TY_DEVICE_DID, DEVICE_ID_LEN);
    memcpy(tuya_ble_protocol_param.auth_key,        TY_DEVICE_AUTH_KEY,  AUTH_KEY_LEN);
    memcpy(tuya_ble_protocol_param.mac_addr_string, TY_DEVICE_MAC,  MAC_STRING_LEN);
    memcpy(tuya_ble_protocol_param.product_id,      TY_DEVICE_PID,  tuya_ble_protocol_param.product_id_len);
    memcpy(tuya_ble_protocol_param.adv_local_name,  TY_DEVICE_NAME, tuya_ble_protocol_param.adv_local_name_len);
    tuya_ble_sdk_init(&tuya_ble_protocol_param);

    tuya_ble_callback_queue_register(tuya_ble_protocol_callback);

    …………
}

Functional testing

Prerequisites

A Bluetooth device must be flashed with the firmware and authorized before it can be paired.

  • The flashing process varies by chip platform.

  • Authorization is usually used for mass production.

    If your project is not currently intended for production, you can perform temporary authorization in the following way. This is only for debugging purposes. Before production, change the code back.

  1. Find the following snippet:

    Device Pairing
  2. Edit the code as shown below:

    STATIC tuya_ble_device_param_t tuya_ble_protocol_param = {
        .use_ext_license_key = 1, //1-info in tuya_ble_sdk_demo.h, 0-auth info
        .device_id_len       = DEVICE_ID_LEN, //DEVICE_ID_LEN,
        .p_type              = TUYA_BLE_PRODUCT_ID_TYPE_PID,
        .product_id_len      = 8,
        .adv_local_name_len = 4,
    };
    

Procedure

After authorization, a Tuya-enabled Bluetooth LE device is activated.

You can open the Smart Life app and add the device by tapping the + icon in the top right corner. The host displays the updates of pairing state, MTU, timestamp, and connection parameters.

Device Pairing

If you have any problems with host usage, see Logic Host User Guide.

Support and help

If you have any problems with TuyaOS development, you can post your questions in the Tuya Developer Forum.