1 /* 2 * Copyright (c) 2020 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file 9 * @defgroup bt_mesh_dfd_srv Firmware Distribution Server model 10 * @ingroup bt_mesh_dfd 11 * @{ 12 * @brief API for the Firmware Distribution Server model 13 */ 14 15 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_H__ 16 #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_H__ 17 18 #include <zephyr/bluetooth/mesh/access.h> 19 #include <zephyr/bluetooth/mesh/dfd.h> 20 #include <zephyr/bluetooth/mesh/blob_srv.h> 21 #include <zephyr/bluetooth/mesh/blob_cli.h> 22 #include <zephyr/bluetooth/mesh/dfu_cli.h> 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #ifndef CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX 29 #define CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX 0 30 #endif 31 32 #ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE 33 #define CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE 0 34 #endif 35 36 #ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE 37 #define CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE 0 38 #endif 39 40 struct bt_mesh_dfd_srv; 41 42 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD 43 /** 44 * 45 * @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB 46 * upload support. 47 * 48 * @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance. 49 * @param[in] _oob_schemes Array of OOB schemes supported by the server, 50 * each scheme being a code point from the 51 * Bluetooth SIG Assigned Numbers document. 52 * @param[in] _oob_schemes_count Number of schemes in @c _oob_schemes. 53 */ 54 #define BT_MESH_DFD_SRV_OOB_INIT(_cb, _oob_schemes, _oob_schemes_count) \ 55 { \ 56 .cb = _cb, \ 57 .dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \ 58 .upload = { \ 59 .blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \ 60 }, \ 61 .oob_schemes = { \ 62 .schemes = _oob_schemes, \ 63 .count = _oob_schemes_count, \ 64 }, \ 65 } 66 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ 67 68 /** 69 * 70 * @brief Initialization parameters for the @ref bt_mesh_dfd_srv. 71 * 72 * @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance. 73 */ 74 #define BT_MESH_DFD_SRV_INIT(_cb) \ 75 { \ 76 .cb = _cb, \ 77 .dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \ 78 .upload = { \ 79 .blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \ 80 }, \ 81 } 82 83 /** 84 * 85 * @brief Firmware Distribution Server model Composition Data entry. 86 * 87 * @param _srv Pointer to a @ref bt_mesh_dfd_srv instance. 88 */ 89 #define BT_MESH_MODEL_DFD_SRV(_srv) \ 90 BT_MESH_MODEL_DFU_CLI(&(_srv)->dfu), \ 91 BT_MESH_MODEL_BLOB_SRV(&(_srv)->upload.blob), \ 92 BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFD_SRV, _bt_mesh_dfd_srv_op, NULL, \ 93 _srv, &_bt_mesh_dfd_srv_cb) 94 95 /** Firmware Distribution Server callbacks: */ 96 struct bt_mesh_dfd_srv_cb { 97 98 /** @brief Slot receive callback. 99 * 100 * Called at the start of an upload procedure. The callback must fill 101 * @c io with a pointer to a writable BLOB stream for the Firmware Distribution 102 * Server to write the firmware image to. 103 * 104 * @param srv Firmware Distribution Server model instance. 105 * @param slot DFU image slot being received. 106 * @param io BLOB stream response pointer. 107 * 108 * @return 0 on success, or (negative) error code otherwise. 109 */ 110 int (*recv)(struct bt_mesh_dfd_srv *srv, 111 const struct bt_mesh_dfu_slot *slot, 112 const struct bt_mesh_blob_io **io); 113 114 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD 115 /** @brief Firmware upload OOB start callback. 116 * 117 * Called at the start of an OOB firmware upload. The application must 118 * start a firmware check using an OOB mechanism, and then call 119 * @ref bt_mesh_dfd_srv_oob_check_complete. Depending on the return 120 * value of this function, the application must then start storing the 121 * firmware image using an OOB mechanism, and call 122 * @ref bt_mesh_dfd_srv_oob_store_complete. This callback is mandatory 123 * to support OOB uploads. 124 * 125 * @param srv Firmware Distribution Server model instance. 126 * @param slot Slot to be used for the upload. 127 * @param uri Pointer to buffer containing the URI used to 128 * check for new firmware. 129 * @param uri_len Length of the URI buffer. 130 * @param fwid Pointer to buffer containing the current 131 * firmware ID to be used when checking for 132 * availability of new firmware. 133 * @param fwid_len Length of the current firmware ID. Must be set 134 * to the length of the new firmware ID if it is 135 * available, or to 0 if new firmware is not 136 * available. 137 * 138 * @return BT_MESH_DFD_SUCCESS on success, or error code otherwise. 139 */ 140 int (*start_oob_upload)(struct bt_mesh_dfd_srv *srv, 141 const struct bt_mesh_dfu_slot *slot, 142 const char *uri, uint8_t uri_len, 143 const uint8_t *fwid, uint16_t fwid_len); 144 145 /** @brief Cancel store OOB callback 146 * 147 * Called when an OOB store is cancelled. The application must stop 148 * any ongoing OOB image transfer. This callback is mandatory to 149 * support OOB uploads. 150 * 151 * @param srv Firmware Distribution Server model instance. 152 * @param slot DFU image slot to cancel 153 */ 154 void (*cancel_oob_upload)(struct bt_mesh_dfd_srv *srv, 155 const struct bt_mesh_dfu_slot *slot); 156 157 /** @brief Get the progress of an ongoing OOB store 158 * 159 * Called by the Firmware Distribution Server model when it needs to 160 * get the current progress of an ongoing OOB store from the 161 * application. This callback is mandatory to support OOB uploads. 162 * 163 * @param srv Firmware Distribution Server model instance. 164 * @param slot DFU image slot to get progress for. 165 * 166 * @return The current progress of the ongoing OOB store, in percent. 167 */ 168 uint8_t (*oob_progress_get)(struct bt_mesh_dfd_srv *srv, 169 const struct bt_mesh_dfu_slot *slot); 170 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ 171 172 /** @brief Slot delete callback. 173 * 174 * Called when the Firmware Distribution Server is about to delete a DFU image slot. 175 * All allocated data associated with the firmware slot should be 176 * deleted. 177 * 178 * @param srv Firmware Update Server instance. 179 * @param slot DFU image slot being deleted. 180 */ 181 void (*del)(struct bt_mesh_dfd_srv *srv, 182 const struct bt_mesh_dfu_slot *slot); 183 184 /** @brief Slot send callback. 185 * 186 * Called at the start of a distribution procedure. The callback must 187 * fill @c io with a pointer to a readable BLOB stream for the Firmware 188 * Distribution Server to read the firmware image from. 189 * 190 * @param srv Firmware Distribution Server model instance. 191 * @param slot DFU image slot being sent. 192 * @param io BLOB stream response pointer. 193 * 194 * @return 0 on success, or (negative) error code otherwise. 195 */ 196 int (*send)(struct bt_mesh_dfd_srv *srv, 197 const struct bt_mesh_dfu_slot *slot, 198 const struct bt_mesh_blob_io **io); 199 200 /** @brief Phase change callback (Optional). 201 * 202 * Called whenever the phase of the Firmware Distribution Server changes. 203 * 204 * @param srv Firmware Distribution Server model instance. 205 * @param phase New Firmware Distribution phase. 206 */ 207 void (*phase)(struct bt_mesh_dfd_srv *srv, enum bt_mesh_dfd_phase phase); 208 }; 209 210 /** Firmware Distribution Server instance. */ 211 struct bt_mesh_dfd_srv { 212 const struct bt_mesh_dfd_srv_cb *cb; 213 struct bt_mesh_model *mod; 214 struct bt_mesh_dfu_cli dfu; 215 struct bt_mesh_dfu_target targets[CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX]; 216 struct bt_mesh_blob_target_pull pull_ctxs[CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX]; 217 const struct bt_mesh_blob_io *io; 218 uint16_t target_cnt; 219 uint16_t slot_idx; 220 bool apply; 221 enum bt_mesh_dfd_phase phase; 222 struct bt_mesh_blob_cli_inputs inputs; 223 224 struct { 225 enum bt_mesh_dfd_upload_phase phase; 226 struct bt_mesh_dfu_slot *slot; 227 const struct flash_area *area; 228 struct bt_mesh_blob_srv blob; 229 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD 230 bool is_oob; 231 bool is_pending_oob_check; 232 struct { 233 uint8_t uri_len; 234 uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN]; 235 uint16_t current_fwid_len; 236 uint8_t current_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN]; 237 struct bt_mesh_msg_ctx ctx; 238 } oob; 239 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ 240 } upload; 241 242 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD 243 struct { 244 const uint8_t *schemes; 245 const uint8_t count; 246 } oob_schemes; 247 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ 248 }; 249 250 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD 251 /** @brief Call when an OOB check has completed or failed 252 * 253 * This should be called by the application after an OOB check started by the @c start_oob_upload 254 * callback has completed or failed. The @p status param should be set to one of the following 255 * values: 256 * 257 * * @c BT_MESH_DFD_SUCCESS if the check was succesfull and a new firmware ID was found. 258 * * @c BT_MESH_DFD_ERR_URI_MALFORMED if the URI is not formatted correctly. 259 * * @c BT_MESH_DFD_ERR_URI_NOT_SUPPORTED if the URI scheme is not supported by the node. 260 * * @c BT_MESH_DFD_ERR_URI_UNREACHABLE if the URI can't be reached. 261 * * @c BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE if the check completes successfully but no new 262 * firmware is available. 263 * 264 * If this function returns 0, the application should then download the firmware to the 265 * slot. If an error code is returned, the application should abort the OOB upload. 266 * 267 * @param srv Firmware Distribution Server model instance. 268 * @param slot The slot used in the OOB upload. 269 * @param status The result of the firmware check. 270 * @param fwid If the check was successful and new firmware found, this should point to a 271 * buffer containing the new firmware ID to store. 272 * @param fwid_len The length of the firmware ID pointed to by @p fwid. 273 * 274 * @return 0 on success, (negative) error code otherwise. 275 */ 276 int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv, 277 const struct bt_mesh_dfu_slot *slot, int status, 278 uint8_t *fwid, size_t fwid_len); 279 280 /** @brief Call when an OOB store has completed or failed 281 * 282 * This should be called by the application after an OOB store started after a succesfull call to 283 * @c bt_mesh_dfd_srv_oob_check_complete has completed successfully or failed. 284 * 285 * @param srv Firmware Distribution Server model instance. 286 * @param slot The slot used when storing the firmware image. 287 * @param success @c true if the OOB store completed successfully, @c false otherwise. 288 * @param size The size of the stored firmware image, in bytes. 289 * @param metadata Pointer to the metadata received OOB, or @c NULL if no metadata was 290 * received. 291 * @param metadata_len Size of the metadata pointed to by @p metadata. 292 * 293 * @return 0 on success, (negative) error code otherwise. 294 */ 295 int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv, 296 const struct bt_mesh_dfu_slot *slot, bool success, 297 size_t size, const uint8_t *metadata, size_t metadata_len); 298 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */ 299 300 /** @cond INTERNAL_HIDDEN */ 301 extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[]; 302 extern const struct bt_mesh_model_cb _bt_mesh_dfd_srv_cb; 303 extern const struct bt_mesh_dfu_cli_cb _bt_mesh_dfd_srv_dfu_cb; 304 extern const struct bt_mesh_blob_srv_cb _bt_mesh_dfd_srv_blob_cb; 305 /** @endcond */ 306 307 #ifdef __cplusplus 308 } 309 #endif 310 311 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_H__ */ 312 313 /** @} */ 314