Last Updated on : 2024-06-25 03:49:12download
This topic describes how pairing works on Bluetooth devices.
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.
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:
Pairing process
The following figures show the process of establishing a secure channel (pairing).
Pairing:
```mermaid
graph LR
a("Unbound") --> b("Connect") --> c("Pair") --> d("Bound") --> e("Secure
communication") --> f("Disconnect")
```
Reconnect:
```mermaid
graph LR
g("Reconnect") --> h("Bound") --> i("Secure
communication") --> j("……") --> k("Unpair") --> l("Unbound")
```
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
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.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.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.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.
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.
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.
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;
tuya_ble_connect_status_t tuya_ble_connect_status_get(VOID_T);
tuya_ble_connect_status_t
: See tuya_ble_connect_status_t
.
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);
…………
}
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.
Find the following snippet:
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,
};
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.
If you have any problems with host usage, see Logic Host User Guide.
If you have any problems with TuyaOS development, you can post your questions in the Tuya Developer Forum.
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback