GATT DFU SMP Service Client

This module implements a Simple Management Protocol (SMP) Service Client that can be used in the context of Device Firmware Updates (DFU). SMP is a basic transfer encoding for use with the MCUmgr management protocol. See SMP over Bluetooth for the service specification.

The SMP Client module can be used to interact with Zephyr’s SMP Server Sample.

The SMP Client implements only the service. It does not provide any functionality to process or interpret SMP commands and responses.

The SMP Service Client is used in the Bluetooth: Central DFU SMP sample.

Service UUID

The 128-bit service UUID is 8D53DC1D-1DB7-4CD3-868B-8A527460AA84 (16-bit offset: 0x0001).

Characteristics

This service has one characteristic that is used for both requests and responses.

SMP Characteristic (DA2E7828-FBCE-4E01-AE9E-261174997C48)

Write Without Response
  • Write an SMP command with data.

Notify
  • Response to the SMP command is sent using notification.

  • Multiple notifications may be generated if the response does not fit in a single MTU.

Usage

Note

Do not access any of the values in the bt_dfu_smp object structure directly. All values that should be accessed have accessor functions. The reason that the structure is fully defined is to allow the application to allocate the memory for it.

MTU negotiation

The current DFU SMP Server implementation in the SMP Server Sample requires the whole command to be sent in one transfer. For most operations, this requires a bigger MTU size than the default one. This requires MTU negotiation in the MTU exchange process (see bt_gatt_exchange_mtu()). Writing long characteristic values is not supported.

Note that this is a limitation of the SMP Server Sample, not of the SMP Client.

Sending a command

To send a command, use bt_dfu_smp_command(). The command is provided as a raw binary buffer consisting of a dfu_smp_header and the payload.

Processing the response

The response to a command is sent as notification. It is passed to the callback function that was provided when issuing the command with bt_dfu_smp_command().

Use bt_dfu_smp_rsp_state() to access the data of the current part of the response. As the response might be received in multiple notifications, use bt_dfu_smp_rsp_total_check() to verify if this is the last part of the response. The offset size of the current part and the total size are available in fields of the bt_dfu_smp_rsp_state structure.

API documentation

Header file: include/bluetooth/services/dfu_smp.h
Source file: subsys/bluetooth/services/dfu_smp.c
group bt_dfu_smp

API for the Bluetooth LE GATT DFU SMP (DFU_SMP) Client.

Defines

DFU_SMP_UUID_SERVICE

SMP Service.

The 128-bit service UUID is 8D53DC1D-1DB7-4CD3-868B-8A527460AA84.

BT_UUID_DFU_SMP_SERVICE
DFU_SMP_UUID_CHAR

SMP Characteristic.

The characteristic is used for both requests and responses. The UUID is DA2E7828-FBCE-4E01-AE9E-261174997C48.

BT_UUID_DFU_SMP_CHAR

Typedefs

typedef void (*bt_dfu_smp_rsp_part_cb)(struct bt_dfu_smp *dfu_smp)

Handle part of the response.

Parameters
  • dfu_smp: DFU SMP Client instance.

typedef void (*bt_dfu_smp_error_cb)(struct bt_dfu_smp *dfu_smp, int err)

Global function that is called when an error occurs.

Parameters
  • dfu_smp: DFU SMP Client instance.

  • err: Negative internal error code or positive GATT error code.

Functions

int bt_dfu_smp_init(struct bt_dfu_smp *dfu_smp, const struct bt_dfu_smp_init_params *params)

Initialize the DFU SMP Client module.

Parameters
  • [out] dfu_smp: DFU SMP Client instance.

  • [in] params: Initialization parameter.

Return Value
  • 0: If the operation was successful. Otherwise, a (negative) error code is returned.

int bt_dfu_smp_handles_assign(struct bt_gatt_dm *dm, struct bt_dfu_smp *dfu_smp)

Assign handles to the DFU SMP Client instance.

Parameters
  • [inout] dm: Discovery object.

  • [inout] dfu_smp: DFU SMP Client instance.

Return Value
  • 0: If the operation was successful. Otherwise, a (negative) error code is returned.

  • (-ENOTSUP): Special error code used when the UUID of the service does not match the expected UUID.

int bt_dfu_smp_command(struct bt_dfu_smp *dfu_smp, bt_dfu_smp_rsp_part_cb rsp_cb, size_t cmd_size, const void *cmd_data)

Execute a command.

Parameters
  • [inout] dfu_smp: DFU SMP Client instance.

  • [in] rsp_cb: Callback function to process the response.

  • [in] cmd_size: Size of the command data buffer.

  • [in] cmd_data: Data buffer.

Return Value
  • 0: If the operation was successful. Otherwise, a (negative) error code is returned.

struct bt_conn *bt_dfu_smp_conn(const struct bt_dfu_smp *dfu_smp)

Get the connection object that is used with the DFU SMP Client.

Return

Connection object.

Parameters
  • [in] dfu_smp: DFU SMP Client instance.

const struct bt_dfu_smp_rsp_state *bt_dfu_smp_rsp_state(const struct bt_dfu_smp *dfu_smp)

Get the current response state.

Note

This function should be used inside a response callback function that is provided to bt_dfu_smp_command.

Return

The pointer to the response state structure.

Parameters
  • dfu_smp: DFU SMP Client instance.

bool bt_dfu_smp_rsp_total_check(const struct bt_dfu_smp *dfu_smp)

Check if all response parts have been received.

This auxiliary function checks if the current response part is the final one.

Note

This function should be used inside a response callback function that is provided to bt_dfu_smp_command.

Parameters
  • dfu_smp: DFU SMP Client instance.

Return Value
  • true: If the current part is the final one.

  • false: If the current part is not the final one.

struct dfu_smp_header
#include <dfu_smp.h>

Header used internally by dfu_smp.

Public Members

uint8_t op

Operation.

uint8_t flags

Operational flags.

uint8_t len_h8

Payload length high byte.

uint8_t len_l8

Payload length low byte.

uint8_t group_h8

Group ID high byte.

uint8_t group_l8

Group ID low byte.

uint8_t seq

Sequence number.

uint8_t id

Command ID.

struct bt_dfu_smp_rsp_state
#include <dfu_smp.h>

Current response state.

Public Members

size_t total_size

Total size of the response.

Total expected size of the response. This value is retrieved from the first part of the response, where the SMP header is located.

size_t offset

Current data chunk offset.

size_t chunk_size

The size of the data chunk.

const uint8_t *data

Pointer to the data.

struct bt_dfu_smp_init_params
#include <dfu_smp.h>

DFU SMP Client parameters for the initialization function.

Public Members

bt_dfu_smp_error_cb error_cb

Callback pointer for error handler.

This function is called when an error occurs.

struct bt_dfu_smp
#include <dfu_smp.h>

DFU SMP Client structure.

Public Members

struct bt_conn *conn

Connection object.

struct bt_dfu_smp_rsp_state rsp_state

Current response state.

struct bt_gatt_subscribe_params notification_params

Response notification parameters.

These parameters are set for the SMP response notification.

The status of the notification is reflected by the notify field. Notifications must be enabled before the command is sent. This is handled automatically by the library.

struct bt_dfu_smp_cbs
#include <dfu_smp.h>

Callbacks.

Public Members

bt_dfu_smp_error_cb error_cb

Callback pointer for global error.

This function is called when a global error occurs.

bt_dfu_smp_rsp_part_cb rsp_part

Callback pointer for receiving the response.

The pointer is set to NULL when the response is finished.

struct bt_dfu_smp_handles
#include <dfu_smp.h>

Handles.

Public Members

uint16_t smp

SMP characteristic value handle.

uint16_t smp_ccc

SMP characteristic CCC handle.