blob: 51f534f2828ce8c9d297d3c28cac60b8d61251aa [file] [log] [blame]
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @defgroup bt_mesh_dfu_cli Firmware Uppdate Client model
* @ingroup bt_mesh_dfu
* @{
* @brief API for the Bluetooth mesh Firmware Update Client model
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__
#include <zephyr/bluetooth/mesh/access.h>
#include <zephyr/bluetooth/mesh/blob_cli.h>
#include <zephyr/bluetooth/mesh/dfu.h>
#ifdef __cplusplus
extern "C" {
#endif
struct bt_mesh_dfu_cli;
/**
*
* @brief Initialization parameters for the @ref bt_mesh_dfu_cli.
*
* @sa bt_mesh_dfu_cli_cb.
*
* @param _handlers Handler callback structure.
*/
#define BT_MESH_DFU_CLI_INIT(_handlers) \
{ \
.cb = _handlers, \
.blob = { .cb = &_bt_mesh_dfu_cli_blob_handlers }, \
}
/**
*
* @brief Firmware Update Client model Composition Data entry.
*
* @param _cli Pointer to a @ref bt_mesh_dfu_cli instance.
*/
#define BT_MESH_MODEL_DFU_CLI(_cli) \
BT_MESH_MODEL_BLOB_CLI(&(_cli)->blob), \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFU_CLI, _bt_mesh_dfu_cli_op, NULL, \
_cli, &_bt_mesh_dfu_cli_cb)
/** DFU Target node. */
struct bt_mesh_dfu_target {
/** BLOB Target node */
struct bt_mesh_blob_target blob;
/** Image index on the Target node */
uint8_t img_idx;
/** Expected DFU effect, see @ref bt_mesh_dfu_effect. */
uint8_t effect;
/** Current DFU status, see @ref bt_mesh_dfu_status. */
uint8_t status;
/** Current DFU phase, see @ref bt_mesh_dfu_phase. */
uint8_t phase;
};
/** Metadata status response. */
struct bt_mesh_dfu_metadata_status {
/** Image index. */
uint8_t idx;
/** Status code. */
enum bt_mesh_dfu_status status;
/** Effect of transfer. */
enum bt_mesh_dfu_effect effect;
};
/** DFU Target node status parameters. */
struct bt_mesh_dfu_target_status {
/** Status of the previous operation. */
enum bt_mesh_dfu_status status;
/** Phase of the current DFU transfer. */
enum bt_mesh_dfu_phase phase;
/** The effect the update will have on the Target device's state. */
enum bt_mesh_dfu_effect effect;
/** BLOB ID used in the transfer. */
uint64_t blob_id;
/** Image index to transfer. */
uint8_t img_idx;
/** TTL used in the transfer. */
uint8_t ttl;
/** Additional response time for the Target nodes, in 10-second increments.
*
* The extra time can be used to give the Target nodes more time to respond
* to messages from the Client. The actual timeout will be calculated
* according to the following formula:
*
* @verbatim
* timeout = 20 seconds + (10 seconds * timeout_base) + (100 ms * TTL)
* @endverbatim
*
* If a Target node fails to respond to a message from the Client within the
* configured transfer timeout, the Target node is dropped.
*/
uint16_t timeout_base;
};
/** @brief DFU image callback.
*
* The image callback is called for every DFU image on the Target node when
* calling @ref bt_mesh_dfu_cli_imgs_get.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context of the received message.
* @param idx Image index.
* @param total Total number of images on the Target node.
* @param img Image information for the given image index.
* @param cb_data Callback data.
*
* @retval BT_MESH_DFU_ITER_STOP Stop iterating through the image list and
* return from @ref bt_mesh_dfu_cli_imgs_get.
* @retval BT_MESH_DFU_ITER_CONTINUE Continue iterating through the image list
* if any images remain.
*/
typedef enum bt_mesh_dfu_iter (*bt_mesh_dfu_img_cb_t)(
struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, uint8_t idx,
uint8_t total, const struct bt_mesh_dfu_img *img, void *cb_data);
/** Firmware Update Client event callbacks. */
struct bt_mesh_dfu_cli_cb {
/** @brief BLOB transfer is suspended.
*
* Called when the BLOB transfer is suspended due to response timeout from all Target nodes.
*
* @param cli Firmware Update Client model instance.
*/
void (*suspended)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU ended.
*
* Called when the DFU transfer ends, either because all Target nodes were
* lost or because the transfer was completed successfully.
*
* @param cli Firmware Update Client model instance.
* @param reason Reason for ending.
*/
void (*ended)(struct bt_mesh_dfu_cli *cli,
enum bt_mesh_dfu_status reason);
/** @brief DFU transfer applied on all active Target nodes.
*
* Called at the end of the apply procedure started by @ref
* bt_mesh_dfu_cli_apply.
*
* @param cli Firmware Update Client model instance.
*/
void (*applied)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU transfer confirmed on all active Target nodes.
*
* Called at the end of the apply procedure started by @ref
* bt_mesh_dfu_cli_confirm.
*
* @param cli Firmware Update Client model instance.
*/
void (*confirmed)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU Target node was lost.
*
* A DFU Target node was dropped from the receivers list. The Target node's
* @c status is set to reflect the reason for the failure.
*
* @param cli Firmware Update Client model instance.
* @param target DFU Target node that was lost.
*/
void (*lost_target)(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_dfu_target *target);
};
/** Firmware Update Client model instance.
*
* Should be initialized with @ref BT_MESH_DFU_CLI_INIT.
*/
struct bt_mesh_dfu_cli {
/** Callback structure. */
const struct bt_mesh_dfu_cli_cb *cb;
/** Underlying BLOB Transfer Client. */
struct bt_mesh_blob_cli blob;
/* runtime state */
uint32_t op;
struct bt_mesh_model *mod;
struct {
const struct bt_mesh_dfu_slot *slot;
const struct bt_mesh_blob_io *io;
struct bt_mesh_blob_xfer blob;
uint8_t state;
uint8_t flags;
} xfer;
struct {
uint8_t ttl;
uint8_t type;
uint8_t img_cnt;
uint16_t addr;
struct k_sem sem;
void *params;
bt_mesh_dfu_img_cb_t img_cb;
} req;
};
/** BLOB parameters for Firmware Update Client transfer: */
struct bt_mesh_dfu_cli_xfer_blob_params {
/* Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Base chunk size. May be smaller for the last chunk. */
uint16_t chunk_size;
};
/** Firmware Update Client transfer parameters: */
struct bt_mesh_dfu_cli_xfer {
/** BLOB ID to use for this transfer, or 0 to set it randomly. */
uint64_t blob_id;
/** DFU image slot to transfer. */
const struct bt_mesh_dfu_slot *slot;
/** Transfer mode (Push (Push BLOB Transfer Mode) or Pull (Pull BLOB Transfer Mode)) */
enum bt_mesh_blob_xfer_mode mode;
/** BLOB parameters to be used for the transfer, or NULL to retrieve Target nodes'
* capabilities before sending a firmware.
*/
const struct bt_mesh_dfu_cli_xfer_blob_params *blob_params;
};
/** @brief Start distributing a DFU.
*
* Starts distribution of the firmware in the given slot to the list of DFU
* Target nodes in @c ctx. The transfer runs in the background, and its end is
* signalled through the @ref bt_mesh_dfu_cli_cb::ended callback.
*
* @note The BLOB Transfer Client transfer inputs @c targets list must point to a list of @ref
* bt_mesh_dfu_target nodes.
*
* @param cli Firmware Update Client model instance.
* @param inputs BLOB Transfer Client transfer inputs.
* @param io BLOB stream to read BLOB from.
* @param xfer Firmware Update Client transfer parameters.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_send(struct bt_mesh_dfu_cli *cli,
const struct bt_mesh_blob_cli_inputs *inputs,
const struct bt_mesh_blob_io *io,
const struct bt_mesh_dfu_cli_xfer *xfer);
/** @brief Suspend a DFU transfer.
*
* @param cli Firmware Update Client instance.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_suspend(struct bt_mesh_dfu_cli *cli);
/** @brief Resume the suspended transfer.
*
* @param cli Firmware Update Client instance.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_resume(struct bt_mesh_dfu_cli *cli);
/** @brief Cancel a DFU transfer.
*
* Will cancel the ongoing DFU transfer, or the transfer on a specific Target
* node if @c ctx is valid.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context, or NULL to cancel the ongoing DFU transfer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_cancel(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx);
/** @brief Apply the completed DFU transfer.
*
* A transfer can only be applied after it has ended successfully. The Firmware
* Update Client's @c applied callback is called at the end of the apply procedure.
*
* @param cli Firmware Update Client model instance.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_apply(struct bt_mesh_dfu_cli *cli);
/** @brief Confirm that the active transfer has been applied on the Target nodes.
*
* A transfer can only be confirmed after it has been applied. The Firmware Update
* Client's @c confirmed callback is called at the end of the confirm
* procedure.
*
* Target nodes that have reported the effect as @ref BT_MESH_DFU_EFFECT_UNPROV
* are expected to not respond to the query, and will fail if they do.
*
* @param cli Firmware Update Client model instance.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_confirm(struct bt_mesh_dfu_cli *cli);
/** @brief Get progress as a percentage of completion.
*
* @param cli Firmware Update Client model instance.
*
* @return The progress of the current transfer in percent, or 0 if no
* transfer is active.
*/
uint8_t bt_mesh_dfu_cli_progress(struct bt_mesh_dfu_cli *cli);
/** @brief Check whether a DFU transfer is in progress.
*
* @param cli Firmware Update Client model instance.
*
* @return true if the BLOB Transfer Client is currently participating in a transfer,
* false otherwise.
*/
bool bt_mesh_dfu_cli_is_busy(struct bt_mesh_dfu_cli *cli);
/** @brief Perform a DFU image list request.
*
* Requests the full list of DFU images on a Target node, and iterates through
* them, calling the @c cb for every image.
*
* The DFU image list request can be used to determine which image index the
* Target node holds its different firmwares in.
*
* Waits for a response until the procedure timeout expires.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context.
* @param cb Callback to call for each image index.
* @param cb_data Callback data to pass to @c cb.
* @param max_count Max number of images to return.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_imgs_get(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx,
bt_mesh_dfu_img_cb_t cb, void *cb_data,
uint8_t max_count);
/** @brief Perform a metadata check for the given DFU image slot.
*
* The metadata check procedure allows the Firmware Update Client to check if a Target
* node will accept a transfer of this DFU image slot, and what the effect would be.
*
* Waits for a response until the procedure timeout expires.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context.
* @param img_idx Target node's image index to check.
* @param slot DFU image slot to check for.
* @param rsp Metadata status response buffer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_metadata_check(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint8_t img_idx,
const struct bt_mesh_dfu_slot *slot,
struct bt_mesh_dfu_metadata_status *rsp);
/** @brief Get the status of a Target node.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context.
* @param rsp Response data buffer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_status_get(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_dfu_target_status *rsp);
/** @brief Get the current procedure timeout value.
*
* @return The configured procedure timeout.
*/
int32_t bt_mesh_dfu_cli_timeout_get(void);
/** @brief Set the procedure timeout value.
*
* @param timeout The new procedure timeout.
*/
void bt_mesh_dfu_cli_timeout_set(int32_t timeout);
/** @cond INTERNAL_HIDDEN */
extern const struct bt_mesh_blob_cli_cb _bt_mesh_dfu_cli_blob_handlers;
extern const struct bt_mesh_model_cb _bt_mesh_dfu_cli_cb;
extern const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[];
/** @endcond */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__ */
/** @} */