Analysis of AliOS Things Bluetooth Protocol Stack

1 Introduction

Version 3.1.0 of AliOS Things includes a full-featured Bluetooth protocol stack, so how should we use the Bluetooth function in the AliOS Thing system?

This article takes the HaaS branch of AliOS Things: https://github.com/alibaba/AliOS-Things/tree/dev_3.1.0_haas as an example to take you to understand the Bluetooth protocol stack architecture in AliOS Things.

After understanding the Bluetooth protocol stack architecture, you can refer to the BLE example on HaaS100:

HaaS100 low energy Bluetooth experience

 

2. Introduction to Bluetooth protocol stack

According to the definition of the Bluetooth SIG organization, the entire Bluetooth protocol can be roughly divided into classic Bluetooth, low energy Bluetooth (BLE) and the latest Bluetooth mesh technology. You can see the following picture to understand the framework of the entire Bluetooth protocol.

image.png

Since most of the Bluetooth chips currently on the market are usually divided into single-mode (single low-power) chips and dual-mode (classic + low-power) chips, in order to adapt to these two chips, we use the Bluetooth in AliOS Things The protocol stack is also divided into two types:

  • BLE protocol stack, path components/wireless/bluetooth/ble_host
  • Classic Bluetooth + Bluetooth Low Energy + mesh protocol stack, path components/wireless/bluetooth/btstack/.

 

3. BLE protocol stack code architecture

The Bluetooth low energy protocol stack uses the open source Zephyr protocol stack. Its code directory structure and main content are as follows. The code implemented by the protocol stack is in the ble_host/bt_host/host/ directory, as shown in the following figure.

image.png

As you can see, compared to the Bluetooth protocol stack hierarchy diagram in section 2, the code file names implemented by the Bluetooth protocol stack are named according to the different layers and functional modules of the ble protocol, such as hci_core.c, hci_ecc.c, l2cap.c, att.c, gatt.c, smp.c and so on.

  • hci_core.c: The core code of the Bluetooth HCI protocol layer.
  • hci_ecc.c: The software implements the HCI elliptic curve algorithm part, which is convenient to adapt to the weaker Bluetooth chip.
  • l2cap.c: Bluetooth L2CAP layer implementation.
  • att.c: Bluetooth ATT protocol layer implementation.
  • gatt.c: Bluetooth GATT specification implementation, this layer defines BLE basic interaction specifications.
  • smp.c Bluetooth SMP protocol layer implementation, this layer is the security layer of BLE, used to negotiate encryption keys.

You can read the relevant code to learn how this layer protocol is implemented.

When using the Bluetooth protocol at the beginning, you need to initialize the hci interface and the Bluetooth protocol stack, and add the following code:

    /* we need first init hci driver */
    hci_h4_driver_init();

    /* bt stack init */
    ret = ble_stack_init(&init);
    if (ret) {
        EXAMPLE_TRACE_ERROR("ble_stack_init!, ret = %x\r\n", ret);
        return -1;
    }

3.1 BLE broadcast

Common functions of BLE include BLE broadcast. The interface to set BLE broadcast and start/stop broadcast is as follows

/** @brief Start advertising
 *
 *  Set advertisement data, scan response data, advertisement parameters
 *  and start advertising.
 *
 *  @param param Advertising parameters.
 *  @param ad Data to be used in advertisement packets.
 *  @param ad_len Number of elements in ad
 *  @param sd Data to be used in scan response packets.
 *  @param sd_len Number of elements in sd
 *
 *  @return Zero on success or (negative) error code otherwise.
 */
int bt_le_adv_start (const struct bt_le_adv_param * param,
            const struct bt_data *ad, size_t ad_len,
            const struct bt_data *sd, size_t sd_len);

/** @brief Stop advertising
 *
 *  Stops ongoing advertising.
 *
 *  @return Zero on success or (negative) error code otherwise.
 */
int bt_le_adv_stop (void);

 

3.2 BLE connection

The interface to establish or disconnect the BLE connection is in conn.c

/** @brief Disconnect from a remote device or cancel pending connection.
 *
 *  Disconnect an active connection with the specified reason code or cancel
 *  pending outgoing connection.
 *
 *  @param conn Connection to disconnect.
 *  @param reason Reason code for the disconnection.
 *
 *  @return Zero on success or (negative) error code on failure.
 */
int bt_conn_disconnect(struct bt_conn *conn, u8_t reason);

/** @brief Initiate an LE connection to a remote device.
 *
 *  Allows initiate new LE link to remote peer using its address.
 *  Returns a new reference that the the caller is responsible for managing.
 *
 *  @param peer  Remote address.
 *  @param param Initial connection parameters.
 *
 *  @return Valid connection object on success or NULL otherwise.
 */
struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
                  const struct bt_le_conn_param *param);

 

3.3 BLE service

If you use the already implemented profile, you can directly add the initialization of each profile in the callback function after the initialization of the protocol stack, for example

    hrs_init(0x01);
    bas_init ();
    dis_init("AOS_BLE_MODEL", "Manufacturer");

If you want to use a custom service, you can use these two interfaces to register/deregister the gatt service

/* Server API */

/** @brief Register GATT service.
 *
 *  Register GATT service. Applications can make use of
 *  macros such as BT_GATT_PRIMARY_SERVICE, BT_GATT_CHARACTERISTIC,
 *  BT_GATT_DESCRIPTOR, etc.
 *
 *  @param svc Service containing the available attributes
 *
 *  @return 0 in case of success or negative value in case of error.
 */
int bt_gatt_service_register(struct bt_gatt_service *svc);

/** @brief Unregister GATT service.
 * *
 *  @param svc Service to be unregistered.
 *
 *  @return 0 in case of success or negative value in case of error.
 */
int bt_gatt_service_unregister(struct bt_gatt_service *svc);

The processing function interface for reading and writing of native service attributes is defined in the structure bt_gatt_attr

struct bt_gatt_attr {
    /** Attribute UUID */
    const struct bt_uuid    *uuid;

    /** Attribute read callback
     *
     *  @param conn   The connection that is requesting to read
     *  @param attr   The attribute that's being read
     *  @param buf    Buffer to place the read result in
     *  @param len    Length of data to read
     *  @param offset Offset to start reading from
     *
     *  @return Number fo bytes read, or in case of an error
     * BT_GATT_ERR () with a specific ATT error code.
     */
    ssize_t         (*read)(struct bt_conn *conn,
                    const struct bt_gatt_attr *attr,
                    void *buf, u16_t len,
                    u16_t offset);

    /** Attribute write callback
     *
     *  @param conn   The connection that is requesting to write
     *  @param attr   The attribute that's being written
     *  @param buf    Buffer with the data to write
     *  @param len    Number of bytes in the buffer
     *  @param offset Offset to start writing from
     *  @param flags  Flags (BT_GATT_WRITE_*)
     *
     *  @return Number of bytes written, or in case of an error
     * BT_GATT_ERR () with a specific ATT error code.
     */
    ssize_t         (*write)(struct bt_conn *conn,
                     const struct bt_gatt_attr *attr,
                     const void *buf, u16_t len,
                     u16_t offset, u8_t flags);

    /** Attribute user data */
    void            *user_data;
    /** Attribute handle */
    u16_t           handle;
    /** Attribute permissions */
    u8_t            perm;
};

And to read and write an attribute of the other device, use these interfaces

/** @brief Read Attribute Value by handle
 *
 *  This procedure read the attribute value and return it to the callback.
 *
 *  Note: This procedure is asynchronous therefore the parameters need to
 *  remains valid while it is active.
 *
 *  @param conn Connection object.
 *  @param params Read parameters.
 *
 *  @return 0 in case of success or negative value in case of error.
 */
int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params);

/** @brief Write Attribute Value by handle
 *
 * This procedure write the attribute value and return the result in the
 * callback.
 *
 * Note: This procedure is asynchronous therefore the parameters need to
 *  remains valid while it is active.
 *
 * @param conn Connection object.
 * @param params Write parameters.
 *
 * @return 0 in case of success or negative value in case of error.
 */
int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params);

/** @brief Write Attribute Value by handle without response
 *
 * This procedure write the attribute value without requiring an
 * acknowledgment that the write was successfully performed
 *
 * @param conn Connection object.
 * @param handle Attribute handle.
 * @param data Data to be written.
 * @param length Data length.
 * @param sign Whether to sign data
 *
 * @return 0 in case of success or negative value in case of error.
 */
int bt_gatt_write_without_response(struct bt_conn *conn, u16_t handle,
                   const void *data, u16_t length,
                   bool sign);

 

4. Classic Bluetooth+BLE+mesh protocol stack code architecture

In order to adapt to the classic Bluetooth+BLE dual-mode chip, AliOS Things also provides another classic Bluetooth+BLE+mesh protocol stack, which is ported to the open source Bluedroid protocol stack.

The mesh part uses Zehpyr's open source mesh protocol stack, located in the bt_stack/mesh directory. The code directory structure and main content are shown in the following figure:

image.png

The classic Bluetooth+BLE protocol stack uses Bluedroid, located in the bt_stack/host/bluedroid directory, and its code directory structure and main content are shown in the following figure:

image.png

There are a lot of Bluedroid protocol stack analysis on the Internet. You can refer to other articles on the architecture and analysis of the bluedroid protocol stack on the Internet. I will not discuss in detail here. The interface functions provided to upper-level applications are placed in the bt_stack/host/bluedroid/api/ directory. As you can see, the files are also named according to the supported profile.

The interface for initializing the Bluetooth protocol stack and turning on and off Bluetooth is in yoc_bt_main.c

/**
 * @brief     Get bluetooth stack status
 *
 * @return    Bluetooth stack status
 *
 */
yoc_bluedroid_status_t yoc_bluedroid_get_status(void);
    
/**
 * @brief     Enable bluetooth, must after yoc_bluedroid_init()
 *
 * @return
 *            - BT_OK : Succeed
 *            - Other  : Failed
 */
bt_err_t yoc_bluedroid_enable(void);

/**
 * @brief     Disable bluetooth, must prior to yoc_bluedroid_deinit()
 *
 * @return
 *            - BT_OK : Succeed
 *            - Other  : Failed
 */
bt_err_t yoc_bluedroid_disable(void);

/**
 * @brief     Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff
 *
 * @return
 *            - BT_OK : Succeed
 *            - Other  : Failed
 */
bt_err_t yoc_bluedroid_init(void);

/**
 * @brief     Deinit and free the resource for bluetooth, must be after every bluetooth stuff
 *
 * @return
 *            - BT_OK : Succeed
 *            - Other  : Failed
 */
bt_err_t yoc_bluedroid_deinit(void);

You can find the other interfaces in the corresponding files according to your actual needs.

 

5. Bluetooth application

The above is the introduction of the Bluetooth protocol stack of Alios Things. It can be seen that the two sets of Bluetooth protocol stacks of Alios Things can be used in BLE scenarios with high resource requirements and classic Bluetooth+BLE scenarios with high functional requirements.

The Bluetooth chip used by HaaS100 is a dual-mode Bluetooth chip that supports both BLE and classic Bluetooth, which can seamlessly use the two Bluetooth protocol stacks of Alios Things. In the future, we will have more Bluetooth application articles to use HaaS100 development board to complete Bluetooth applications in various scenarios, so stay tuned.

 

6. Developer technical support

If you need more technical support, you can join the DingTalk developer group or follow the WeChat public account

For more technology and solution introduction, please visit the Aliyun AIoT homepage https://iot.aliyun.com/

Guess you like

Origin blog.csdn.net/HaaSTech/article/details/112716348