Line data Source code
1 0 : /*
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_cli Firmware Uppdate Client model
10 : * @ingroup bt_mesh_dfu
11 : * @{
12 : * @brief API for the Bluetooth Mesh Firmware Update Client model
13 : */
14 :
15 : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__
16 : #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__
17 :
18 : #include <zephyr/bluetooth/mesh/access.h>
19 : #include <zephyr/bluetooth/mesh/blob_cli.h>
20 : #include <zephyr/bluetooth/mesh/dfu.h>
21 :
22 : #ifdef __cplusplus
23 : extern "C" {
24 : #endif
25 :
26 : struct bt_mesh_dfu_cli;
27 :
28 : /**
29 : *
30 : * @brief Initialization parameters for the @ref bt_mesh_dfu_cli.
31 : *
32 : * @sa bt_mesh_dfu_cli_cb.
33 : *
34 : * @param _handlers Handler callback structure.
35 : */
36 1 : #define BT_MESH_DFU_CLI_INIT(_handlers) \
37 : { \
38 : .cb = _handlers, \
39 : .blob = { .cb = &_bt_mesh_dfu_cli_blob_handlers }, \
40 : }
41 :
42 : /**
43 : *
44 : * @brief Firmware Update Client model Composition Data entry.
45 : *
46 : * @param _cli Pointer to a @ref bt_mesh_dfu_cli instance.
47 : */
48 1 : #define BT_MESH_MODEL_DFU_CLI(_cli) \
49 : BT_MESH_MODEL_BLOB_CLI(&(_cli)->blob), \
50 : BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFU_CLI, _bt_mesh_dfu_cli_op, NULL, \
51 : _cli, &_bt_mesh_dfu_cli_cb)
52 :
53 : /** DFU Target node. */
54 1 : struct bt_mesh_dfu_target {
55 : /** BLOB Target node */
56 1 : struct bt_mesh_blob_target blob;
57 : /** Image index on the Target node */
58 1 : uint8_t img_idx;
59 : /** Expected DFU effect, see @ref bt_mesh_dfu_effect. */
60 1 : uint8_t effect;
61 : /** Current DFU status, see @ref bt_mesh_dfu_status. */
62 1 : uint8_t status;
63 : /** Current DFU phase, see @ref bt_mesh_dfu_phase. */
64 1 : uint8_t phase;
65 : };
66 :
67 : /** Metadata status response. */
68 1 : struct bt_mesh_dfu_metadata_status {
69 : /** Image index. */
70 1 : uint8_t idx;
71 : /** Status code. */
72 1 : enum bt_mesh_dfu_status status;
73 : /** Effect of transfer. */
74 1 : enum bt_mesh_dfu_effect effect;
75 : };
76 :
77 : /** DFU Target node status parameters. */
78 1 : struct bt_mesh_dfu_target_status {
79 : /** Status of the previous operation. */
80 1 : enum bt_mesh_dfu_status status;
81 : /** Phase of the current DFU transfer. */
82 1 : enum bt_mesh_dfu_phase phase;
83 : /** The effect the update will have on the Target device's state. */
84 1 : enum bt_mesh_dfu_effect effect;
85 : /** BLOB ID used in the transfer. */
86 1 : uint64_t blob_id;
87 : /** Image index to transfer. */
88 1 : uint8_t img_idx;
89 : /** TTL used in the transfer. */
90 1 : uint8_t ttl;
91 :
92 : /** Additional response time for the Target nodes, in 10-second increments.
93 : *
94 : * The extra time can be used to give the Target nodes more time to respond
95 : * to messages from the Client. The actual timeout will be calculated
96 : * according to the following formula:
97 : *
98 : * @verbatim
99 : * timeout = 20 seconds + (10 seconds * timeout_base) + (100 ms * TTL)
100 : * @endverbatim
101 : *
102 : * If a Target node fails to respond to a message from the Client within the
103 : * configured transfer timeout, the Target node is dropped.
104 : */
105 1 : uint16_t timeout_base;
106 : };
107 :
108 : /** @brief DFU image callback.
109 : *
110 : * The image callback is called for every DFU image on the Target node when
111 : * calling @ref bt_mesh_dfu_cli_imgs_get.
112 : *
113 : * @param cli Firmware Update Client model instance.
114 : * @param ctx Message context of the received message.
115 : * @param idx Image index.
116 : * @param total Total number of images on the Target node.
117 : * @param img Image information for the given image index.
118 : * @param cb_data Callback data.
119 : *
120 : * @retval BT_MESH_DFU_ITER_STOP Stop iterating through the image list and
121 : * return from @ref bt_mesh_dfu_cli_imgs_get.
122 : * @retval BT_MESH_DFU_ITER_CONTINUE Continue iterating through the image list
123 : * if any images remain.
124 : */
125 : typedef enum bt_mesh_dfu_iter (*bt_mesh_dfu_img_cb_t)(
126 : struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, uint8_t idx,
127 : uint8_t total, const struct bt_mesh_dfu_img *img, void *cb_data);
128 :
129 : /** Firmware Update Client event callbacks. */
130 1 : struct bt_mesh_dfu_cli_cb {
131 : /** @brief BLOB transfer is suspended.
132 : *
133 : * Called when the BLOB transfer is suspended due to response timeout from all Target nodes.
134 : *
135 : * @param cli Firmware Update Client model instance.
136 : */
137 1 : void (*suspended)(struct bt_mesh_dfu_cli *cli);
138 :
139 : /** @brief DFU ended.
140 : *
141 : * Called when the DFU transfer ends, either because all Target nodes were
142 : * lost or because the transfer was completed successfully.
143 : *
144 : * @param cli Firmware Update Client model instance.
145 : * @param reason Reason for ending.
146 : */
147 1 : void (*ended)(struct bt_mesh_dfu_cli *cli,
148 : enum bt_mesh_dfu_status reason);
149 :
150 : /** @brief DFU transfer applied on all active Target nodes.
151 : *
152 : * Called at the end of the apply procedure started by @ref
153 : * bt_mesh_dfu_cli_apply.
154 : *
155 : * @param cli Firmware Update Client model instance.
156 : */
157 1 : void (*applied)(struct bt_mesh_dfu_cli *cli);
158 :
159 : /** @brief DFU transfer confirmed on all active Target nodes.
160 : *
161 : * Called at the end of the apply procedure started by @ref
162 : * bt_mesh_dfu_cli_confirm.
163 : *
164 : * @param cli Firmware Update Client model instance.
165 : */
166 1 : void (*confirmed)(struct bt_mesh_dfu_cli *cli);
167 :
168 : /** @brief DFU Target node was lost.
169 : *
170 : * A DFU Target node was dropped from the receivers list. The Target node's
171 : * @c status is set to reflect the reason for the failure.
172 : *
173 : * @param cli Firmware Update Client model instance.
174 : * @param target DFU Target node that was lost.
175 : */
176 1 : void (*lost_target)(struct bt_mesh_dfu_cli *cli,
177 : struct bt_mesh_dfu_target *target);
178 : };
179 :
180 : /** Firmware Update Client model instance.
181 : *
182 : * Should be initialized with @ref BT_MESH_DFU_CLI_INIT.
183 : */
184 1 : struct bt_mesh_dfu_cli {
185 : /** Callback structure. */
186 1 : const struct bt_mesh_dfu_cli_cb *cb;
187 : /** Underlying BLOB Transfer Client. */
188 1 : struct bt_mesh_blob_cli blob;
189 :
190 : /* runtime state */
191 :
192 0 : uint32_t op;
193 0 : const struct bt_mesh_model *mod;
194 :
195 : struct {
196 0 : const struct bt_mesh_dfu_slot *slot;
197 0 : const struct bt_mesh_blob_io *io;
198 0 : struct bt_mesh_blob_xfer blob;
199 0 : uint8_t state;
200 0 : uint8_t flags;
201 0 : } xfer;
202 :
203 : struct {
204 0 : uint8_t ttl;
205 0 : uint8_t type;
206 0 : uint8_t img_cnt;
207 0 : uint16_t addr;
208 0 : struct k_sem sem;
209 0 : void *params;
210 0 : bt_mesh_dfu_img_cb_t img_cb;
211 0 : } req;
212 : };
213 :
214 : /** BLOB parameters for Firmware Update Client transfer: */
215 1 : struct bt_mesh_dfu_cli_xfer_blob_params {
216 : /* Logarithmic representation of the block size. */
217 0 : uint8_t block_size_log;
218 : /** Base chunk size. May be smaller for the last chunk. */
219 1 : uint16_t chunk_size;
220 : };
221 :
222 : /** Firmware Update Client transfer parameters: */
223 1 : struct bt_mesh_dfu_cli_xfer {
224 : /** BLOB ID to use for this transfer, or 0 to set it randomly. */
225 1 : uint64_t blob_id;
226 : /** DFU image slot to transfer. */
227 1 : const struct bt_mesh_dfu_slot *slot;
228 : /** Transfer mode (Push (Push BLOB Transfer Mode) or Pull (Pull BLOB Transfer Mode)) */
229 1 : enum bt_mesh_blob_xfer_mode mode;
230 : /** BLOB parameters to be used for the transfer, or NULL to retrieve Target nodes'
231 : * capabilities before sending a firmware.
232 : */
233 1 : const struct bt_mesh_dfu_cli_xfer_blob_params *blob_params;
234 : };
235 :
236 : /** @brief Start distributing a DFU.
237 : *
238 : * Starts distribution of the firmware in the given slot to the list of DFU
239 : * Target nodes in @c ctx. The transfer runs in the background, and its end is
240 : * signalled through the @ref bt_mesh_dfu_cli_cb::ended callback.
241 : *
242 : * @note The BLOB Transfer Client transfer inputs @c targets list must point to a list of @ref
243 : * bt_mesh_dfu_target nodes.
244 : *
245 : * @param cli Firmware Update Client model instance.
246 : * @param inputs BLOB Transfer Client transfer inputs.
247 : * @param io BLOB stream to read BLOB from.
248 : * @param xfer Firmware Update Client transfer parameters.
249 : *
250 : * @return 0 on success, or (negative) error code otherwise.
251 : */
252 1 : int bt_mesh_dfu_cli_send(struct bt_mesh_dfu_cli *cli,
253 : const struct bt_mesh_blob_cli_inputs *inputs,
254 : const struct bt_mesh_blob_io *io,
255 : const struct bt_mesh_dfu_cli_xfer *xfer);
256 :
257 : /** @brief Suspend a DFU transfer.
258 : *
259 : * @param cli Firmware Update Client instance.
260 : *
261 : * @return 0 on success, or (negative) error code otherwise.
262 : */
263 1 : int bt_mesh_dfu_cli_suspend(struct bt_mesh_dfu_cli *cli);
264 :
265 : /** @brief Resume the suspended transfer.
266 : *
267 : * @param cli Firmware Update Client instance.
268 : *
269 : * @return 0 on success, or (negative) error code otherwise.
270 : */
271 1 : int bt_mesh_dfu_cli_resume(struct bt_mesh_dfu_cli *cli);
272 :
273 : /** @brief Cancel a DFU transfer.
274 : *
275 : * Will cancel the ongoing DFU transfer, or the transfer on a specific Target
276 : * node if @c ctx is valid.
277 : *
278 : * @param cli Firmware Update Client model instance.
279 : * @param ctx Message context, or NULL to cancel the ongoing DFU transfer.
280 : *
281 : * @return 0 on success, or (negative) error code otherwise.
282 : */
283 1 : int bt_mesh_dfu_cli_cancel(struct bt_mesh_dfu_cli *cli,
284 : struct bt_mesh_msg_ctx *ctx);
285 :
286 : /** @brief Apply the completed DFU transfer.
287 : *
288 : * A transfer can only be applied after it has ended successfully. The Firmware
289 : * Update Client's @c applied callback is called at the end of the apply procedure.
290 : *
291 : * @param cli Firmware Update Client model instance.
292 : *
293 : * @return 0 on success, or (negative) error code otherwise.
294 : */
295 1 : int bt_mesh_dfu_cli_apply(struct bt_mesh_dfu_cli *cli);
296 :
297 : /** @brief Confirm that the active transfer has been applied on the Target nodes.
298 : *
299 : * A transfer can only be confirmed after it has been applied. The Firmware Update
300 : * Client's @c confirmed callback is called at the end of the confirm
301 : * procedure.
302 : *
303 : * Target nodes that have reported the effect as @ref BT_MESH_DFU_EFFECT_UNPROV
304 : * are expected to not respond to the query, and will fail if they do.
305 : *
306 : * @param cli Firmware Update Client model instance.
307 : *
308 : * @return 0 on success, or (negative) error code otherwise.
309 : */
310 1 : int bt_mesh_dfu_cli_confirm(struct bt_mesh_dfu_cli *cli);
311 :
312 : /** @brief Get progress as a percentage of completion.
313 : *
314 : * @param cli Firmware Update Client model instance.
315 : *
316 : * @return The progress of the current transfer in percent, or 0 if no
317 : * transfer is active.
318 : */
319 1 : uint8_t bt_mesh_dfu_cli_progress(struct bt_mesh_dfu_cli *cli);
320 :
321 : /** @brief Check whether a DFU transfer is in progress.
322 : *
323 : * @param cli Firmware Update Client model instance.
324 : *
325 : * @return true if the BLOB Transfer Client is currently participating in a transfer,
326 : * false otherwise.
327 : */
328 1 : bool bt_mesh_dfu_cli_is_busy(struct bt_mesh_dfu_cli *cli);
329 :
330 : /** @brief Perform a DFU image list request.
331 : *
332 : * Requests the full list of DFU images on a Target node, and iterates through
333 : * them, calling the @c cb for every image.
334 : *
335 : * The DFU image list request can be used to determine which image index the
336 : * Target node holds its different firmwares in.
337 : *
338 : * Waits for a response until the procedure timeout expires.
339 : *
340 : * @param cli Firmware Update Client model instance.
341 : * @param ctx Message context.
342 : * @param cb Callback to call for each image index.
343 : * @param cb_data Callback data to pass to @c cb.
344 : * @param max_count Max number of images to return.
345 : *
346 : * @return 0 on success, or (negative) error code otherwise.
347 : */
348 1 : int bt_mesh_dfu_cli_imgs_get(struct bt_mesh_dfu_cli *cli,
349 : struct bt_mesh_msg_ctx *ctx,
350 : bt_mesh_dfu_img_cb_t cb, void *cb_data,
351 : uint8_t max_count);
352 :
353 : /** @brief Perform a metadata check for the given DFU image slot.
354 : *
355 : * The metadata check procedure allows the Firmware Update Client to check if a Target
356 : * node will accept a transfer of this DFU image slot, and what the effect would be.
357 : *
358 : * Waits for a response until the procedure timeout expires.
359 : *
360 : * @param cli Firmware Update Client model instance.
361 : * @param ctx Message context.
362 : * @param img_idx Target node's image index to check.
363 : * @param slot DFU image slot to check for.
364 : * @param rsp Metadata status response buffer.
365 : *
366 : * @return 0 on success, or (negative) error code otherwise.
367 : */
368 1 : int bt_mesh_dfu_cli_metadata_check(struct bt_mesh_dfu_cli *cli,
369 : struct bt_mesh_msg_ctx *ctx, uint8_t img_idx,
370 : const struct bt_mesh_dfu_slot *slot,
371 : struct bt_mesh_dfu_metadata_status *rsp);
372 :
373 : /** @brief Get the status of a Target node.
374 : *
375 : * @param cli Firmware Update Client model instance.
376 : * @param ctx Message context.
377 : * @param rsp Response data buffer.
378 : *
379 : * @return 0 on success, or (negative) error code otherwise.
380 : */
381 1 : int bt_mesh_dfu_cli_status_get(struct bt_mesh_dfu_cli *cli,
382 : struct bt_mesh_msg_ctx *ctx,
383 : struct bt_mesh_dfu_target_status *rsp);
384 :
385 : /** @brief Get the current procedure timeout value.
386 : *
387 : * @return The configured procedure timeout.
388 : */
389 1 : int32_t bt_mesh_dfu_cli_timeout_get(void);
390 :
391 : /** @brief Set the procedure timeout value.
392 : *
393 : * @param timeout The new procedure timeout.
394 : */
395 1 : void bt_mesh_dfu_cli_timeout_set(int32_t timeout);
396 :
397 : /** @cond INTERNAL_HIDDEN */
398 : extern const struct bt_mesh_blob_cli_cb _bt_mesh_dfu_cli_blob_handlers;
399 : extern const struct bt_mesh_model_cb _bt_mesh_dfu_cli_cb;
400 : extern const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[];
401 : /** @endcond */
402 :
403 : #ifdef __cplusplus
404 : }
405 : #endif
406 :
407 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__ */
408 :
409 : /** @} */
|