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_dfu_srv Firmware Update Server model 10 * @ingroup bt_mesh_dfu 11 * @{ 12 * @brief API for the Bluetooth mesh Firmware Update Server model 13 */ 14 15 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__ 16 #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__ 17 18 #include <zephyr/bluetooth/mesh/dfu.h> 19 #include <zephyr/bluetooth/mesh/blob_srv.h> 20 #include <zephyr/bluetooth/mesh/access.h> 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 struct bt_mesh_dfu_srv; 27 28 /** 29 * 30 * @brief Initialization parameters for @ref bt_mesh_dfu_srv. 31 * 32 * @param _handlers DFU handler function structure. 33 * @param _imgs List of @ref bt_mesh_dfu_img managed by this Server. 34 * @param _img_count Number of DFU images managed by this Server. 35 */ 36 #define BT_MESH_DFU_SRV_INIT(_handlers, _imgs, _img_count) \ 37 { \ 38 .blob = { .cb = &_bt_mesh_dfu_srv_blob_cb }, .cb = _handlers, \ 39 .imgs = _imgs, .img_count = _img_count, \ 40 } 41 42 /** 43 * 44 * @brief Firmware Update Server model entry. 45 * 46 * @param _srv Pointer to a @ref bt_mesh_dfu_srv instance. 47 */ 48 #define BT_MESH_MODEL_DFU_SRV(_srv) \ 49 BT_MESH_MODEL_BLOB_SRV(&(_srv)->blob), \ 50 BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFU_SRV, _bt_mesh_dfu_srv_op, NULL, \ 51 _srv, &_bt_mesh_dfu_srv_cb) 52 53 /** @brief Firmware Update Server event callbacks. */ 54 struct bt_mesh_dfu_srv_cb { 55 /** @brief Transfer check callback. 56 * 57 * The transfer check can be used to validate the incoming transfer 58 * before it starts. The contents of the metadata is implementation 59 * specific, and should contain all the information the application 60 * needs to determine whether this image should be accepted, and what 61 * the effect of the transfer would be. 62 * 63 * If applying the image will have an effect on the provisioning state 64 * of the mesh stack, this can be communicated through the @c effect 65 * return parameter. 66 * 67 * The metadata check can be performed both as part of starting a new 68 * transfer and as a separate procedure. 69 * 70 * This handler is optional. 71 * 72 * @param srv Firmware Update Server instance. 73 * @param img DFU image the metadata check is performed on. 74 * @param metadata Image metadata. 75 * @param effect Return parameter for the image effect on the 76 * provisioning state of the mesh stack. 77 * 78 * @return 0 on success, or (negative) error code otherwise. 79 */ 80 int (*check)(struct bt_mesh_dfu_srv *srv, 81 const struct bt_mesh_dfu_img *img, 82 struct net_buf_simple *metadata, 83 enum bt_mesh_dfu_effect *effect); 84 85 /** @brief Transfer start callback. 86 * 87 * Called when the Firmware Update Server is ready to start a new DFU transfer. 88 * The application must provide an initialized BLOB stream to be used 89 * during the DFU transfer. 90 * 91 * The following error codes are treated specially, and should be used 92 * to communicate these issues: 93 * - @c -ENOMEM: The device cannot fit this image. 94 * - @c -EBUSY: The application is temporarily unable to accept the 95 * transfer. 96 * - @c -EALREADY: The device has already received and verified this 97 * image, and there's no need to transfer it again. The Firmware Update model 98 * will skip the transfer phase, and mark the image as verified. 99 * 100 * This handler is mandatory. 101 * 102 * @param srv Firmware Update Server instance. 103 * @param img DFU image being updated. 104 * @param metadata Image metadata. 105 * @param io BLOB stream return parameter. Must be set to a 106 * valid BLOB stream by the callback. 107 * 108 * @return 0 on success, or (negative) error code otherwise. Return 109 * codes @c -ENOMEM, @c -EBUSY @c -EALREADY will be passed to 110 * the updater, other error codes are reported as internal 111 * errors. 112 */ 113 int (*start)(struct bt_mesh_dfu_srv *srv, 114 const struct bt_mesh_dfu_img *img, 115 struct net_buf_simple *metadata, 116 const struct bt_mesh_blob_io **io); 117 118 /** @brief Transfer end callback. 119 * 120 * This handler is optional. 121 * 122 * If the transfer is successful, the application should verify the 123 * firmware image, and call either @ref bt_mesh_dfu_srv_verified or 124 * @ref bt_mesh_dfu_srv_rejected depending on the outcome. 125 * 126 * If the transfer fails, the Firmware Update Server will be available for new 127 * transfers immediately after this function returns. 128 * 129 * @param srv Firmware Update Server instance. 130 * @param img DFU image that failed the update. 131 * @param success Whether the DFU transfer was successful. 132 */ 133 void (*end)(struct bt_mesh_dfu_srv *srv, 134 const struct bt_mesh_dfu_img *img, bool success); 135 136 /** @brief Transfer recovery callback. 137 * 138 * If the device reboots in the middle of a transfer, the Firmware Update Server 139 * calls this function when the Bluetooth mesh subsystem is started. 140 * 141 * This callback is optional, but transfers will not be recovered after 142 * a reboot without it. 143 * 144 * @param srv Firmware Update Server instance. 145 * @param img DFU image being updated. 146 * @param io BLOB stream return parameter. Must be set to a valid BLOB 147 * stream by the callback. 148 * 149 * @return 0 on success, or (negative) error code to abandon the 150 * transfer. 151 */ 152 int (*recover)(struct bt_mesh_dfu_srv *srv, 153 const struct bt_mesh_dfu_img *img, 154 const struct bt_mesh_blob_io **io); 155 156 /** @brief Transfer apply callback. 157 * 158 * Called after a transfer has been validated, and the updater sends an 159 * apply message to the Target nodes. 160 * 161 * This handler is optional. 162 * 163 * @param srv Firmware Update Server instance. 164 * @param img DFU image that should be applied. 165 * 166 * @return 0 on success, or (negative) error code otherwise. 167 */ 168 int (*apply)(struct bt_mesh_dfu_srv *srv, 169 const struct bt_mesh_dfu_img *img); 170 }; 171 172 /** @brief Firmware Update Server instance. 173 * 174 * Should be initialized with @ref BT_MESH_DFU_SRV_INIT. 175 */ 176 struct bt_mesh_dfu_srv { 177 /** Underlying BLOB Transfer Server. */ 178 struct bt_mesh_blob_srv blob; 179 /** Callback structure. */ 180 const struct bt_mesh_dfu_srv_cb *cb; 181 /** List of updatable images. */ 182 const struct bt_mesh_dfu_img *imgs; 183 /** Number of updatable images. */ 184 size_t img_count; 185 186 /* Runtime state */ 187 struct bt_mesh_model *mod; 188 struct { 189 /* Effect of transfer, @see bt_mesh_dfu_effect. */ 190 uint8_t effect; 191 /* Current phase, @see bt_mesh_dfu_phase. */ 192 uint8_t phase; 193 uint8_t ttl; 194 uint8_t idx; 195 uint16_t timeout_base; 196 uint16_t meta; 197 } update; 198 }; 199 200 /** @brief Accept the received DFU transfer. 201 * 202 * Should be called at the end of a successful DFU transfer. 203 * 204 * If the DFU transfer completes successfully, the application should verify 205 * the image validity (including any image authentication or integrity checks), 206 * and call this function if the image is ready to be applied. 207 * 208 * @param srv Firmware Update Server instance. 209 */ 210 void bt_mesh_dfu_srv_verified(struct bt_mesh_dfu_srv *srv); 211 212 /** @brief Reject the received DFU transfer. 213 * 214 * Should be called at the end of a successful DFU transfer. 215 * 216 * If the DFU transfer completes successfully, the application should verify 217 * the image validity (including any image authentication or integrity checks), 218 * and call this function if one of the checks fail. 219 * 220 * @param srv Firmware Update Server instance. 221 */ 222 void bt_mesh_dfu_srv_rejected(struct bt_mesh_dfu_srv *srv); 223 224 /** @brief Cancel the ongoing DFU transfer. 225 * 226 * @param srv Firmware Update Server instance. 227 */ 228 void bt_mesh_dfu_srv_cancel(struct bt_mesh_dfu_srv *srv); 229 230 /** @brief Confirm that the received DFU transfer was applied. 231 * 232 * Should be called as a result of the @ref bt_mesh_dfu_srv_cb.apply callback. 233 * 234 * @param srv Firmware Update Server instance. 235 */ 236 void bt_mesh_dfu_srv_applied(struct bt_mesh_dfu_srv *srv); 237 238 /** @brief Check if the Firmware Update Server is busy processing a transfer. 239 * 240 * @param srv Firmware Update Server instance. 241 * 242 * @return true if a DFU procedure is in progress, false otherwise. 243 */ 244 bool bt_mesh_dfu_srv_is_busy(const struct bt_mesh_dfu_srv *srv); 245 246 /** @brief Get the progress of the current DFU procedure, in percent. 247 * 248 * @param srv Firmware Update Server instance. 249 * 250 * @return The current transfer progress in percent. 251 */ 252 uint8_t bt_mesh_dfu_srv_progress(const struct bt_mesh_dfu_srv *srv); 253 254 /** @cond INTERNAL_HIDDEN */ 255 extern const struct bt_mesh_model_op _bt_mesh_dfu_srv_op[]; 256 extern const struct bt_mesh_model_cb _bt_mesh_dfu_srv_cb; 257 extern const struct bt_mesh_blob_srv_cb _bt_mesh_dfu_srv_blob_cb; 258 /** @endcond */ 259 260 #ifdef __cplusplus 261 } 262 #endif 263 264 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__ */ 265 266 /** @} */ 267