| /* |
| * 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; |
| const 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__ */ |
| |
| /** @} */ |