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 committed Aug 11, 2023
1 parent 2491e89 commit 702ec88
Show file tree
Hide file tree
Showing 10 changed files with 646 additions and 319 deletions.
131 changes: 129 additions & 2 deletions include/zephyr/bluetooth/mesh/dfd_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,31 @@ 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;

/**
*
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv.
*/
#define BT_MESH_DFD_SRV_INIT(_cb) \
#define BT_MESH_DFD_SRV_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, \
}, \
}

/**
Expand Down Expand Up @@ -75,6 +87,60 @@ struct bt_mesh_dfd_srv_cb {
const struct bt_mesh_dfu_slot *slot,
const struct bt_mesh_blob_io **io);

/** @brief Firware 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
* @c 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
* @c bt_mesh_dfd_srv_oob_store_complete.
*
* @param srv Firmware Distribution Server model instance.
* @param slot Slot 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.
*
* @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.
*
* @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);

/** @brief Slot delete callback.
*
* Called when the Firmware Distribution Server is about to delete a DFU image slot.
Expand Down Expand Up @@ -128,13 +194,74 @@ struct bt_mesh_dfd_srv {
struct bt_mesh_blob_cli_inputs inputs;

struct {
bool is_oob;
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;
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;
} upload;

struct {
uint8_t *schemes;
uint8_t count;
} oob_schemes;
};

/** @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
* 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 by the @c start_oob
* callback has completed 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);

/** @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
Loading

0 comments on commit 702ec88

Please sign in to comment.