Skip to content

Commit

Permalink
Bluetooth: Mesh: Add support for Upload OOB Start
Browse files Browse the repository at this point in the history
This adds support for the Upload OOB Start message to the DFD server, by
providing callbacks that the application can use to hook any OOB scheme
into the model behavior.

There are also extensive changes to the dfu_slot module, to accomodate
the new needs that appeared with the support for OOB transfer (mainly,
fwid, size and metadata are no longer available when the slot is
allocated, they appear later in the handling).

Signed-off-by: Ludvig Samuelsen Jordet <[email protected]>
  • Loading branch information
ludvigsj authored and fabiobaltieri committed Sep 18, 2023
1 parent dd090f0 commit b990a74
Show file tree
Hide file tree
Showing 13 changed files with 792 additions and 326 deletions.
5 changes: 2 additions & 3 deletions doc/connectivity/bluetooth/api/mesh/shell.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1034,15 +1034,14 @@ Firmware Update Client model
The Firmware Update Client model can be added to the mesh shell by enabling configuration options :kconfig:option:`CONFIG_BT_MESH_BLOB_CLI` and :kconfig:option:`CONFIG_BT_MESH_DFU_CLI`. The Firmware Update Client demonstrates the firmware update Distributor role by transferring a dummy firmware update to a set of Target nodes.


``mesh models dfu slot add <Size> [<FwID> [<Metadata> [<URI>]]]``
``mesh models dfu slot add <Size> <FwID> [<Metadata>]``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Add a virtual DFU image slot that can be transferred as a DFU image. The image slot will be assigned an image slot index, which is printed as a response, and can be used to reference the slot in other commands. To update the image slot, remove it using the ``mesh models dfu slot del`` shell command and then add it again.

* ``Size``: DFU image slot size in bytes.
* ``FwID``: Optional firmware ID, formatted as a hexstring.
* ``FwID``: Firmware ID, formatted as a hexstring.
* ``Metadata``: Optional firmware metadata, formatted as a hexstring.
* ``URI``: Optional URI for the firmware.


``mesh models dfu slot del <SlotIdx>``
Expand Down
163 changes: 162 additions & 1 deletion include/zephyr/bluetooth/mesh/dfd_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,47 @@ extern "C" {
#define CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX 0
#endif

#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE
#define CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE 0
#endif

#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE
#define CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE 0
#endif

struct bt_mesh_dfd_srv;

#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
/**
*
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB
* upload support.
*
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
* @param[in] _oob_schemes Array of OOB schemes supported by the server,
* each scheme being a code point from the
* Bluetooth SIG Assigned Numbers document.
* @param[in] _oob_schemes_count Number of schemes in @c _oob_schemes.
*/
#define BT_MESH_DFD_SRV_OOB_INIT(_cb, _oob_schemes, _oob_schemes_count) \
{ \
.cb = _cb, \
.dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \
.upload = { \
.blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \
}, \
.oob_schemes = { \
.schemes = _oob_schemes, \
.count = _oob_schemes_count, \
}, \
}
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */

/**
*
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv.
*
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
*/
#define BT_MESH_DFD_SRV_INIT(_cb) \
{ \
Expand Down Expand Up @@ -75,6 +111,64 @@ struct bt_mesh_dfd_srv_cb {
const struct bt_mesh_dfu_slot *slot,
const struct bt_mesh_blob_io **io);

#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
/** @brief Firmware upload OOB start callback.
*
* Called at the start of an OOB firmware upload. The application must
* start a firmware check using an OOB mechanism, and then call
* @ref bt_mesh_dfd_srv_oob_check_complete. Depending on the return
* value of this function, the application must then start storing the
* firmware image using an OOB mechanism, and call
* @ref bt_mesh_dfd_srv_oob_store_complete. This callback is mandatory
* to support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot Slot to be used for the upload.
* @param uri Pointer to buffer containing the URI used to
* check for new firmware.
* @param uri_len Length of the URI buffer.
* @param fwid Pointer to buffer containing the current
* firmware ID to be used when checking for
* availability of new firmware.
* @param fwid_len Length of the current firmware ID. Must be set
* to the length of the new firmware ID if it is
* available, or to 0 if new firmware is not
* available.
*
* @return BT_MESH_DFD_SUCCESS on success, or error code otherwise.
*/
int (*start_oob_upload)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const char *uri, uint8_t uri_len,
const uint8_t *fwid, uint16_t fwid_len);

/** @brief Cancel store OOB callback
*
* Called when an OOB store is cancelled. The application must stop
* any ongoing OOB image transfer. This callback is mandatory to
* support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot to cancel
*/
void (*cancel_oob_upload)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);

/** @brief Get the progress of an ongoing OOB store
*
* Called by the Firmware Distribution Server model when it needs to
* get the current progress of an ongoing OOB store from the
* application. This callback is mandatory to support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot to get progress for.
*
* @return The current progress of the ongoing OOB store, in percent.
*/
uint8_t (*oob_progress_get)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */

/** @brief Slot delete callback.
*
* Called when the Firmware Distribution Server is about to delete a DFU image slot.
Expand Down Expand Up @@ -129,12 +223,79 @@ struct bt_mesh_dfd_srv {

struct {
enum bt_mesh_dfd_upload_phase phase;
const struct bt_mesh_dfu_slot *slot;
struct bt_mesh_dfu_slot *slot;
const struct flash_area *area;
struct bt_mesh_blob_srv blob;
#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
bool is_oob;
struct {
uint8_t uri_len;
uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN];
uint16_t current_fwid_len;
uint8_t current_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
struct bt_mesh_msg_ctx ctx;
} oob;
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
} upload;

#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
struct {
const uint8_t *schemes;
const uint8_t count;
} oob_schemes;
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
};

#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
/** @brief Call when an OOB check has completed or failed
*
* This should be called by the application after an OOB check started by the @c start_oob_upload
* callback has completed or failed. The @p status param should be set to one of the following
* values:
*
* * @c BT_MESH_DFD_SUCCESS if the check was succesfull and a new firmware ID was found.
* * @c BT_MESH_DFD_ERR_URI_MALFORMED if the URI is not formatted correctly.
* * @c BT_MESH_DFD_ERR_URI_NOT_SUPPORTED if the URI scheme is not supported by the node.
* * @c BT_MESH_DFD_ERR_URI_UNREACHABLE if the URI can't be reached.
* * @c BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE if the check completes successfully but no new
* firmware is available.
*
* If this function returns 0, the application should then download the firmware to the
* slot. If an error code is returned, the application should abort the OOB upload.
*
* @param srv Firmware Distribution Server model instance.
* @param slot The slot used in the OOB upload.
* @param status The result of the firmware check.
* @param fwid If the check was successful and new firmware found, this should point to a
* buffer containing the new firmware ID to store.
* @param fwid_len The length of the firmware ID pointed to by @p fwid.
*
* @return 0 on success, (negative) error code otherwise.
*/
int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot, int status,
uint8_t *fwid, size_t fwid_len);

/** @brief Call when an OOB store has completed or failed
*
* This should be called by the application after an OOB store started after a succesfull call to
* @c bt_mesh_dfd_srv_oob_check_complete has completed successfully or failed.
*
* @param srv Firmware Distribution Server model instance.
* @param slot The slot used when storing the firmware image.
* @param success @c true if the OOB store completed successfully, @c false otherwise.
* @param size The size of the stored firmware image, in bytes.
* @param metadata Pointer to the metadata received OOB, or @c NULL if no metadata was
* received.
* @param metadata_len Size of the metadata pointed to by @p metadata.
*
* @return 0 on success, (negative) error code otherwise.
*/
int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot, bool success,
size_t size, const uint8_t *metadata, size_t metadata_len);
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */

/** @cond INTERNAL_HIDDEN */
extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfd_srv_cb;
Expand Down
13 changes: 5 additions & 8 deletions include/zephyr/bluetooth/mesh/dfu.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ extern "C" {
#define CONFIG_BT_MESH_DFU_URI_MAXLEN 0
#endif

#ifndef CONFIG_BT_MESH_DFU_SLOT_CNT
#define CONFIG_BT_MESH_DFU_SLOT_CNT 0
#endif

/** DFU transfer phase. */
enum bt_mesh_dfu_phase {
/** Ready to start a Receive Firmware procedure. */
Expand Down Expand Up @@ -140,10 +144,7 @@ struct bt_mesh_dfu_img {
/** Length of the firmware ID. */
size_t fwid_len;

/** Update URI, or NULL.
*
* Must use one of the http: or https: schemes.
*/
/** Update URI, or NULL. */
const char *uri;
};

Expand All @@ -155,14 +156,10 @@ struct bt_mesh_dfu_slot {
size_t fwid_len;
/** Length of the metadata. */
size_t metadata_len;
/** Length of the image URI. */
size_t uri_len;
/** Firmware ID. */
uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
/** Metadata. */
uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN];
/** Image URI. */
char uri[CONFIG_BT_MESH_DFU_URI_MAXLEN];
};

/** @} */
Expand Down
8 changes: 8 additions & 0 deletions subsys/bluetooth/mesh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,14 @@ config BT_MESH_DFD_SRV_TARGETS_MAX
This value defines the maximum number of Target nodes the Firmware
Distribution Server can target simultaneously.

config BT_MESH_DFD_SRV_OOB_UPLOAD
bool "Support for DFU image OOB upload"
help
This enables support for OOB upload of firmware images for
distribution. This makes several callbacks and use of the init
macro BT_MESH_DFD_SRV_INIT_OOB mandatory. See the API documentation
for bt_mesh_dfd_srv_cb for details about the mandatory callbacks.

endif

config BT_MESH_RPR_SRV
Expand Down
Loading

0 comments on commit b990a74

Please sign in to comment.