Ayla Device Bluetooth Services
This page provides high-level application notes for device application developers using Ayla’s Device Bluetooth (ADB) services.
Ayla’s Bluetooth services provide two major features:
- Wi-Fi configuration and device registration (device onboarding)
- BLE Local Control, which enables a device to be managed and controlled over a Bluetooth connection.
The BLE Local Control feature is optional and not required to support the Wi-Fi configuration and registration features. However, the local control feature may not be used without enabling base Bluetooth support, which include the Wi-Fi configuration and registration features.
Building the Ayla Device Agent with BLE Services
Support for Bluetooth features in the Ayla Device Agent is enabled using the following compiler defines.
Compiler Define | Description |
---|---|
AYLA_BLUETOOTH_SUPPORT | Includes base Bluetooth functionality in compilation. This includes the Wi-Fi configuration and device registration functionality. |
AYLA_LOCAL_CONTROL_SUPPORT | Includes local control support, enabling the device to be monitored and controlled over BLE.AYLA_BLUETOOTH_SUPPORT must also be defined. |
Initializing Ayla Bluetooth Services from Device Application
On startup, an application desiring to use Ayla Bluetooth features must initialize the Bluetooth subsystem and register the BLE GATT services that enable these features.
void app_bt_register_services_cb(void)
{
adb_ayla_svc_register(NULL);
adb_conn_svc_register(NULL);
adb_lctrl_svc_register(NULL);
adb_wifi_cfg_svc_register(NULL);
}
/*
* Application initialization code
*/
...
al_bt_init(app_bt_register_services_cb);
...
}
The register services callback function is called at the appropriate time during initialization. All BLE GATT-based services that are going to be used must be registered at this time. Services may not be deregistered. By the BLE standard devices are generally expected to have a fixed set of services that do not change over the life of the device. Therefore, all services should be registered in the same order each time the device restarts. There are four Ayla defined BLE GATT services:
Service | Description |
---|---|
Ayla Serviceadb_ayla_svc_register | Provides access to basic identification information for an Ayla device, such as DSN (Device Serial Number) and OEM model, etc. * Identify function - write this characteristic to generate a callback to a function registered with adb_ayla_svc_identify_cb_set function to be called to blink an LED, make a sound, etc., to help the user identify the device from a list on a mobile app. |
Ayla Connection Serviceadb_conn_svc_register | Provides a characteristic for the mobile app to write a “setup token” used to associate the device with a user during onboarding. |
Ayla Local Control Serviceadb_lctrl_svc_register | Provides characteristics used to send and receive messages used to monitor and control the device over a BLE connection. |
Ayla Wi-Fi Configuration Serviceadb_wifi_cfg_svc_register | Provides characteristics that enable initial Wi-Fi provisioning so the device can connect to a Wi-Fi network and gain access to the Internet. This service may only be used when the device has not previously been configured or has been factory reset. |
Identify Callback Registration
The Ayla service provides a characteristic that when written will make a function call to a callback the application registers, if one has been registered. This callback function my be used to provide an indication to an end user that will help that user identify a particular device from a list of devices shown on the mobile app. For example, the callback function may cause an LED to blink for a few seconds enabling the user to determine which device is which. The following is an example that prints a message:
void demo_identify_cb(void)
{
printf("%s called\n", __func__);
}
/*
* App initialization or Bluetooth service registration
*/
...
adb_ayla_svc_identify_cb_set(demo_identify_cb);
...
Factory Configuration of Ayla Bluetooth Features
There are Bluetooth configuration items that may be configured during factory configuration of a device.
Configuration Item | Description |
---|---|
bt/hostname | The BT device name advertised by the device during onboarding. This is the name that will be displayed on the mobile app when selecting a device to onboard. The name is defined by the following format string: <prefix>%<digits>[X] where: <prefix> - any ASCII string that doesn't include '%'<digits> - even number of hex digits of BT device address to appendX - optional, to specify upper case hex, defaults to lower caseExample: “Ayla%4X” will result in a name like Ayla1234 NOTE: BLE advertisement frames only provide for 37 bytes of payload. One item of the payload is the name. Therefore, the name configured here should be very short, in the range of 8 to 12 characters. Default, if not configured: “Ayla%4X” |
bt/key | Configured passkey used during onboarding. Passkeys are 6 digits that may include leading zeros. Configuration is as follows: 0 - 999999 : fixed passkey defined by config-1 : no-passkey auth-2 : random passkeyAll other configured values or no configured value result in no-passkey auth. Default if not configured: -1 |
bt/wifi/time | Timeout for Wi-Fi on-boarding, in seconds. Default if not configured or set to 0: use the default time, currently 300 s. This requires ada-1.11 or later. |
bt/wifi/user | If 1, indicates that Wi-Fi on-boarding should not start until the API al_bt_wifi_timeout_set() is used to start push-button on-boarding.Default, if not configured or 0: start advertising for onboarding begins after reset if Wi-Fi is not configured. This requires ada-1.11 or later. |
Advertising, Pairing and Bonding
The Ayla Device Bluetooth features provide a number of advertisement and pairing modes that vary depending on the configuration state of the device.
Advertisement and Pairing Behavior of an Un-configured Device
Advertising for Wi-Fi onboarding occurs when the device is not configured with an enabled Wi-Fi profile. The presence of an enabled Wi-Fi profile indicates that the device has successfully connected to the Ayla service as a result of a successful onboarding. This advertising occurs for the time configured as bt/wifi/time
just after boot or can be delayed until later and started by the host application on detecting a button push or other event. Note that in releases before ada-1.11, push-button onboarding is not available, and the time is not configurable.
The device advertises its name based on the bt/hostname
factory configuration item. If the bt/hostname
is not configured, the default name format Ayla%4X
will be used. The device allows a single Bluetooth connection and supports pairing with no passkey, with a factory configured 6-digit numeric passkey, or with a randomly generated 6-digit passkey depending on the configuration of the bt/key
item. If the bt/key
item is not configured, the default is no passkey, which allows any device to connect without authentication.
If AYLA_LOCAL_CONTROL_SUPPORT
is not enabled, pairing will only apply for the duration of the BLE connection. The pairing will not be persisted for future connections. In addition, once the device is onboarded, Bluetooth services will be terminated and not restarted unless the device is factory reset. Note, the BLE features of the ESP32 consume a significant amount of RAM that is made available to the heap when BLE is disabled.
If AYLA_LOCAL_CONTROL_SUPPORT
is enabled, keys generated during the initial pairing will be persisted and the Bluetooth services will continue to operate after onboarding has been completed. This is referred to as the device and the mobile being “bonded”. This enables future connections by the same mobile device without requiring pairing operation each time the mobile connects for local control.
There is a timeout for configuring an un-configured or factory reset device. The time may be configured as bt/wifi/time
and defaults to 5 minutes. After the device has been running for this period without being configured, Bluetooth services will be shutdown, such that if end users' devices that are never configured will not be left open to malicious activity over the BLE interface. A reset or power cycle or API call to al_bt_wifi_timeout_set()
will restart Bluetooth services subject to another timeout.
Advertisement and Pairing Behavior of a Configured Device
NOTE: This case only applies to devices that have AYLA_LOCAL_CONTROL_SUPPORT
enabled.
Once a device has been onboarded, the advertisement and pairing behavior changes permanently unless the device is factory reset to the un-configured state.
After onboarding is complete and the device has connected to the Ayla cloud, the BLE interface will stop advertising a name and switch to advertising a resolvable randomized Ayla ID. This is done to reduce the ability to track devices based on advertisements. The Ayla ID is a meaningless value to most observers except authorized mobile devices that have a key that enables securely associating an Ayla ID with a specific device. Mobile applications use the Ayla ID advertisements to discover devices they intend to connect with.
In addition, after onboarding has completed, pairing is disabled but may be temporarily re-enabled by the device application. For example, the device may re-enable pairing for a period of time (e.g. one minute) after the user presses a button on the device. The device application enables pairing by using the al_bt_pairing_mode_set
API:
enum adb_pairing_mode {
ADB_PM_DISABLED, /**< no pairing allowed */
ADB_PM_NO_PASSKEY, /**< no passkey, no mitm protection */
ADB_PM_CONFIGURED_PASSKEY, /**< require configured passkey */
ADB_PM_RANDOM_PASSKEY, /**< random passkey, requires a display */
ADB_PM_AYLA_PASSKEY, /**< require LAN IP key generated passkey */
};
/**
* Set the pairing mode.
*
* \param mode is the pairing mode to configure.
* \param duration is the duration in seconds to enable this mode, 0 means
* no time limit.
*/
al_bt_pairing_mode_set(enum adb_pairing_mode mode, u16 duration)
NOTE: The ADB_PM_AYLA_PASSKEY
mode is not currently supported by the Ayla mobile SDKs.
As with the initial pairing, subsequent pairings are persisted as bonds such that each mobile device only needs to be paired once. Up to 5 devices may be paired but only 3 many be connected at the same time.
Displaying a Passkey
If the device has a means to display a passkey, the application can register a callback, which will be called with the 6 digit passkey value when the passkey needs to be displayed. The API to register this callback is:
void al_bt_passkey_callback_set(void (*callback)(u32 passkey));
Ayla Device Bluetooth APIs
ADB APIs are fully documented in the following header files:
adb.h
al_bt.h
adb_ayla_svc.h
adb_conn_svc.h
adb_lctrl_svc.h
adb_wifi_cfg_svc.h
Bluetooth Debugging
Logging
Logging for Bluetooth features is under the bt
module. Logs may be enabled and disabled for various levels using the log command. For example, debug level logging is enabled using the following command:
log --mod bt debug
Debug level logging is disable with the following command:
log --mod bt -debug
BT CLI Command
The bt
CLI command provides current Bluetooth status information:
# bt
Device name: Ayla-6f72
Ayla id: 36b1eccc:dcf183f0
BLE advertisements: active
Pairing mode: disabled
Active connections:
0: handle 0 peer 88:66:a5:68:1d:c2
--- records in persisted storage ---
Our security:
0: 88:66:a5:68:1d:c2 key-size 16 ltk 1 irk 0 csrk 0 auth 0 sc 1
Peer security:
0: 88:66:a5:68:1d:c2 key-size 16 ltk 1 irk 1 csrk 0 auth 0 sc 1
CCCD:
0: 88:66:a5:68:1d:c2 handle 38 flags 0x0001 changed 0
1: 88:66:a5:68:1d:c2 handle 43 flags 0x0001 changed 0
2: 88:66:a5:68:1d:c2 handle 8 flags 0x0002 changed 0
3: 88:66:a5:68:1d:c2 handle 30 flags 0x0002 changed 0
Checking BLE Local Control Config
The enable status of BLE Local Control and LAN-mode can be determined by examining the device config.
On AylaDevKit devices (be sure to look for the entry starting with “s”, the factory config “f” will always contain 0:
--> conf
...
s client/lan/enable = "3"
...
On ADA ayla_demo devices:
# nvs-get ada.client/lan/enable
ada.client/lan/enable : 3
The value of the enable parameter are a bit mask with 0x1
assigned to LAN-mode and 0x2
assigned to BLE LC:
0
- disabled
1
- LAN-mode enabled, BLE LC disabled
2
- LAN-mode disabled, BLE LC enabled
3
- LAN-mode enabled, BLE LC enabled
BT Error Codes in Log Messages
Error and reason codes a values from the Nimble BLE stack. Errors codes are printed in decimal but often need decoding to identify the specifics of the error Nimble is reporting. The following is an example of a log message with an error code given in decimal:
18:45:31.936 d b bt: disconnect reason 531
Error and reason codes a values from the Nimble BLE stack. If the value is less than 255, it is usually a direct error code from the Nimble host stack (ble_hs.h
):
/**
* @brief Bluetooth Host Error Code
* @defgroup bt_host_err Bluetooth Host Error Code
*
* Defines error codes returned by Bluetooth host. If error comes from specific
* component (eg L2CAP or Security Manager) it is shifted by base allowing to
* identify component.
* @{
*/
#define BLE_HS_EAGAIN 1
#define BLE_HS_EALREADY 2
#define BLE_HS_EINVAL 3
#define BLE_HS_EMSGSIZE 4
#define BLE_HS_ENOENT 5
#define BLE_HS_ENOMEM 6
#define BLE_HS_ENOTCONN 7
#define BLE_HS_ENOTSUP 8
#define BLE_HS_EAPP 9
#define BLE_HS_EBADDATA 10
#define BLE_HS_EOS 11
#define BLE_HS_ECONTROLLER 12
#define BLE_HS_ETIMEOUT 13
#define BLE_HS_EDONE 14
#define BLE_HS_EBUSY 15
#define BLE_HS_EREJECT 16
#define BLE_HS_EUNKNOWN 17
#define BLE_HS_EROLE 18
#define BLE_HS_ETIMEOUT_HCI 19
#define BLE_HS_ENOMEM_EVT 20
#define BLE_HS_ENOADDR 21
#define BLE_HS_ENOTSYNCED 22
#define BLE_HS_EAUTHEN 23
#define BLE_HS_EAUTHOR 24
#define BLE_HS_EENCRYPT 25
#define BLE_HS_EENCRYPT_KEY_SZ 26
#define BLE_HS_ESTORE_CAP 27
#define BLE_HS_ESTORE_FAIL 28
#define BLE_HS_EPREEMPTED 29
#define BLE_HS_EDISABLED 30
#define BLE_HS_ESTALLED 31
Error values larger than 255 include a subsystem code in the most significant byte and an error code in the least significant byte. Decoding the error is a bit arcane. To do so, convert the decimal value to hexadecimal then look up the base using the upper byte with a lower byte of 0x00
:
/** Error base for ATT errors */
#define BLE_HS_ERR_ATT_BASE 0x100
/** Error base for HCI errors */
#define BLE_HS_ERR_HCI_BASE 0x200
/** Error base for L2CAP errors */
#define BLE_HS_ERR_L2C_BASE 0x300
/** Error base for local Security Manager errors */
#define BLE_HS_ERR_SM_US_BASE 0x400
/** Error base for remote (peer) Security Manager errors */
#define BLE_HS_ERR_SM_PEER_BASE 0x500
/** Error base for hardware errors */
#define BLE_HS_ERR_HW_BASE 0x600
The definition of the error code depends on the subsystem. They are most often errors defined by the BLE spec (ble.h
):
/* BLE Error Codes (Core v4.2 Vol 2 part D) */
enum ble_error_codes
{
/* An "error" code of 0x0 means success */
BLE_ERR_SUCCESS = 0x00,
BLE_ERR_UNKNOWN_HCI_CMD = 0x01,
BLE_ERR_UNK_CONN_ID = 0x02,
BLE_ERR_HW_FAIL = 0x03,
BLE_ERR_PAGE_TMO = 0x04,
BLE_ERR_AUTH_FAIL = 0x05,
BLE_ERR_PINKEY_MISSING = 0x06,
BLE_ERR_MEM_CAPACITY = 0x07,
BLE_ERR_CONN_SPVN_TMO = 0x08,
BLE_ERR_CONN_LIMIT = 0x09,
BLE_ERR_SYNCH_CONN_LIMIT = 0x0a,
BLE_ERR_ACL_CONN_EXISTS = 0x0b,
BLE_ERR_CMD_DISALLOWED = 0x0c,
BLE_ERR_CONN_REJ_RESOURCES = 0x0d,
BLE_ERR_CONN_REJ_SECURITY = 0x0e,
BLE_ERR_CONN_REJ_BD_ADDR = 0x0f,
BLE_ERR_CONN_ACCEPT_TMO = 0x10,
BLE_ERR_UNSUPPORTED = 0x11,
BLE_ERR_INV_HCI_CMD_PARMS = 0x12,
BLE_ERR_REM_USER_CONN_TERM = 0x13,
BLE_ERR_RD_CONN_TERM_RESRCS = 0x14,
BLE_ERR_RD_CONN_TERM_PWROFF = 0x15,
BLE_ERR_CONN_TERM_LOCAL = 0x16,
BLE_ERR_REPEATED_ATTEMPTS = 0x17,
BLE_ERR_NO_PAIRING = 0x18,
BLE_ERR_UNK_LMP = 0x19,
BLE_ERR_UNSUPP_REM_FEATURE = 0x1a,
BLE_ERR_SCO_OFFSET = 0x1b,
BLE_ERR_SCO_ITVL = 0x1c,
BLE_ERR_SCO_AIR_MODE = 0x1d,
BLE_ERR_INV_LMP_LL_PARM = 0x1e,
BLE_ERR_UNSPECIFIED = 0x1f,
BLE_ERR_UNSUPP_LMP_LL_PARM = 0x20,
BLE_ERR_NO_ROLE_CHANGE = 0x21,
BLE_ERR_LMP_LL_RSP_TMO = 0x22,
BLE_ERR_LMP_COLLISION = 0x23,
BLE_ERR_LMP_PDU = 0x24,
BLE_ERR_ENCRYPTION_MODE = 0x25,
BLE_ERR_LINK_KEY_CHANGE = 0x26,
BLE_ERR_UNSUPP_QOS = 0x27,
BLE_ERR_INSTANT_PASSED = 0x28,
BLE_ERR_UNIT_KEY_PAIRING = 0x29,
BLE_ERR_DIFF_TRANS_COLL = 0x2a,
/* BLE_ERR_RESERVED = 0x2b */
BLE_ERR_QOS_PARM = 0x2c,
BLE_ERR_QOS_REJECTED = 0x2d,
BLE_ERR_CHAN_CLASS = 0x2e,
BLE_ERR_INSUFFICIENT_SEC = 0x2f,
BLE_ERR_PARM_OUT_OF_RANGE = 0x30,
/* BLE_ERR_RESERVED = 0x31 */
BLE_ERR_PENDING_ROLE_SW = 0x32,
/* BLE_ERR_RESERVED = 0x33 */
BLE_ERR_RESERVED_SLOT = 0x34,
BLE_ERR_ROLE_SW_FAIL = 0x35,
BLE_ERR_INQ_RSP_TOO_BIG = 0x36,
BLE_ERR_SEC_SIMPLE_PAIR = 0x37,
BLE_ERR_HOST_BUSY_PAIR = 0x38,
BLE_ERR_CONN_REJ_CHANNEL = 0x39,
BLE_ERR_CTLR_BUSY = 0x3a,
BLE_ERR_CONN_PARMS = 0x3b,
BLE_ERR_DIR_ADV_TMO = 0x3c,
BLE_ERR_CONN_TERM_MIC = 0x3d,
BLE_ERR_CONN_ESTABLISHMENT = 0x3e,
BLE_ERR_MAC_CONN_FAIL = 0x3f,
BLE_ERR_COARSE_CLK_ADJ = 0x40,
BLE_ERR_TYPE0_SUBMAP_NDEF = 0x41,
BLE_ERR_UNK_ADV_INDENT = 0x42,
BLE_ERR_LIMIT_REACHED = 0x43,
BLE_ERR_OPERATION_CANCELLED = 0x44,
BLE_ERR_MAX = 0xff
};
Error codes from the ATT subsystem are:
#define BLE_ATT_ERR_INVALID_HANDLE 0x01
#define BLE_ATT_ERR_READ_NOT_PERMITTED 0x02
#define BLE_ATT_ERR_WRITE_NOT_PERMITTED 0x03
#define BLE_ATT_ERR_INVALID_PDU 0x04
#define BLE_ATT_ERR_INSUFFICIENT_AUTHEN 0x05
#define BLE_ATT_ERR_REQ_NOT_SUPPORTED 0x06
#define BLE_ATT_ERR_INVALID_OFFSET 0x07
#define BLE_ATT_ERR_INSUFFICIENT_AUTHOR 0x08
#define BLE_ATT_ERR_PREPARE_QUEUE_FULL 0x09
#define BLE_ATT_ERR_ATTR_NOT_FOUND 0x0a
#define BLE_ATT_ERR_ATTR_NOT_LONG 0x0b
#define BLE_ATT_ERR_INSUFFICIENT_KEY_SZ 0x0c
#define BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN 0x0d
#define BLE_ATT_ERR_UNLIKELY 0x0e
#define BLE_ATT_ERR_INSUFFICIENT_ENC 0x0f
#define BLE_ATT_ERR_UNSUPPORTED_GROUP 0x10
#define BLE_ATT_ERR_INSUFFICIENT_RES 0x11
Here is an example of decoding a result code in the following message:
18:45:31.936 d b bt: disconnect reason 531
531 = 0x213
- base: 0x200 (
BLE_HS_ERR_HCI_BASE
) - error code: 0x13 (
BLE_ERR_REM_USER_CONN_TERM
)
The HCI subsystem (Host Controller Interface) has indicated that the remote user terminated the connection (mobile app was shutdown in this case).
Updated over 2 years ago