Skip to content

Commit 986ea39

Browse files
nordicjmcarlescufi
authored andcommitted
mgmt: mcumgr: img_mgmt: Switch to new event callback system
Switches to the new event callback system for the img_mgmt functionality and removes the old code. Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
1 parent 4e8fde1 commit 986ea39

File tree

6 files changed

+140
-111
lines changed

6 files changed

+140
-111
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2022 Laird Connectivity
3+
* Copyright (c) 2022 Nordic Semiconductor ASA
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#ifndef H_MCUMGR_IMG_MGMT_CALLBACKS_
9+
#define H_MCUMGR_IMG_MGMT_CALLBACKS_
10+
11+
#include <img_mgmt/img_mgmt.h>
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
/**
18+
* @brief MCUmgr img_mgmt callback API
19+
* @defgroup mcumgr_callback_api_img_mgmt MCUmgr img_mgmt callback API
20+
* @ingroup mcumgr_callback_api
21+
* @{
22+
*/
23+
24+
/**
25+
* Structure provided in the MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK notification callback: This callback
26+
* function is used to notify the application about a pending firmware upload packet from a client
27+
* and authorise or deny it. Upload will be allowed so long as all notification handlers return
28+
* MGMT_ERR_EOK, if one returns an error then the upload will be denied.
29+
*/
30+
struct img_mgmt_upload_check {
31+
/** Action to take */
32+
struct img_mgmt_upload_action *action;
33+
34+
/** Upload request information */
35+
struct img_mgmt_upload_req *req;
36+
};
37+
38+
/**
39+
* @}
40+
*/
41+
42+
#ifdef __cplusplus
43+
}
44+
#endif
45+
46+
#endif

include/zephyr/mgmt/mcumgr/mgmt/callbacks.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#include <zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h>
1616
#endif
1717

18+
#ifdef CONFIG_MCUMGR_CMD_IMG_MGMT
19+
#include <zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h>
20+
#endif
21+
1822
#ifdef __cplusplus
1923
extern "C" {
2024
#endif

subsys/mgmt/mcumgr/lib/cmd/img_mgmt/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ config IMG_MGMT_FRUGAL_LIST
8484
a device but requires support in client software, which has to default omitted values.
8585
Works correctly with mcumgr-cli.
8686

87+
config MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK
88+
bool "Upload check hook"
89+
depends on MCUMGR_MGMT_NOTIFICATION_HOOKS
90+
help
91+
This will enable the upload check hook which will send image upload requests to
92+
registered callbacks to check with the user application if an upload should be accepted
93+
or rejected.
94+
95+
config MCUMGR_GRP_IMG_STATUS_HOOKS
96+
bool "Status hooks"
97+
depends on MCUMGR_MGMT_NOTIFICATION_HOOKS
98+
help
99+
This will enable DFU status hooks which can be checked by the application to monitor DFU
100+
uploads. Note that these are status checking only, to allow inspecting of a file upload
101+
or prevent it, CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK must be used.
102+
87103
module = MCUMGR_IMG_MGMT
88104
module-str = mcumgr_img_mgmt
89105
source "subsys/logging/Kconfig.template.log_config"

subsys/mgmt/mcumgr/lib/cmd/img_mgmt/include/img_mgmt/img_mgmt.h

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2018-2021 mcumgr authors
3+
* Copyright (c) 2022 Nordic Semiconductor ASA
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -192,53 +193,6 @@ int img_mgmt_state_set_pending(int slot, int permanent);
192193
*/
193194
int img_mgmt_state_confirm(void);
194195

195-
/** @brief Generic callback function for events */
196-
typedef void (*img_mgmt_dfu_cb)(void);
197-
198-
/** Callback function pointers */
199-
struct img_mgmt_dfu_callbacks_t {
200-
img_mgmt_dfu_cb dfu_started_cb;
201-
img_mgmt_dfu_cb dfu_stopped_cb;
202-
img_mgmt_dfu_cb dfu_pending_cb;
203-
img_mgmt_dfu_cb dfu_confirmed_cb;
204-
};
205-
206-
/** @typedef img_mgmt_upload_fn
207-
* @brief Application callback that is executed when an image upload request is
208-
* received.
209-
*
210-
* The callback's return code determines whether the upload request is accepted
211-
* or rejected. If the callback returns 0, processing of the upload request
212-
* proceeds. If the callback returns nonzero, the request is rejected with a
213-
* response containing an `rc` value equal to the return code.
214-
*
215-
* @param req Image upload request structure
216-
* @param action Image upload action structure
217-
*
218-
* @return 0 if the upload request should be accepted; nonzero to reject
219-
* the request with the specified status.
220-
*/
221-
typedef int (*img_mgmt_upload_fn)(const struct img_mgmt_upload_req req,
222-
const struct img_mgmt_upload_action action);
223-
224-
/**
225-
* @brief Configures a callback that gets called whenever a valid image upload
226-
* request is received.
227-
*
228-
* The callback's return code determines whether the upload request is accepted
229-
* or rejected. If the callback returns 0, processing of the upload request
230-
* proceeds. If the callback returns nonzero, the request is rejected with a
231-
* response containing an `rc` value equal to the return code.
232-
*
233-
* @param cb The callback to execute on rx of an upload request.
234-
*/
235-
void img_mgmt_set_upload_cb(img_mgmt_upload_fn cb);
236-
void img_mgmt_register_callbacks(const struct img_mgmt_dfu_callbacks_t *cb_struct);
237-
void img_mgmt_dfu_stopped(void);
238-
void img_mgmt_dfu_started(void);
239-
void img_mgmt_dfu_pending(void);
240-
void img_mgmt_dfu_confirmed(void);
241-
242196
/**
243197
* Compares two image version numbers in a semver-compatible way.
244198
*

subsys/mgmt/mcumgr/lib/cmd/img_mgmt/src/img_mgmt.c

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
#include <zephyr/dfu/flash_img.h>
2828
#endif
2929

30-
static img_mgmt_upload_fn img_mgmt_upload_cb;
31-
32-
const struct img_mgmt_dfu_callbacks_t *img_mgmt_dfu_callbacks_fn;
30+
#ifdef CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS
31+
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
32+
#endif
3333

3434
struct img_mgmt_state g_img_mgmt_state;
3535

@@ -295,7 +295,9 @@ img_mgmt_erase(struct smp_streamer *ctxt)
295295
img_mgmt_reset_upload();
296296

297297
if (rc != 0) {
298-
img_mgmt_dfu_stopped();
298+
#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS)
299+
(void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED, NULL, 0);
300+
#endif
299301
return rc;
300302
}
301303

@@ -355,7 +357,6 @@ img_mgmt_upload_log(bool is_first, bool is_last, int status)
355357
static int
356358
img_mgmt_upload(struct smp_streamer *ctxt)
357359
{
358-
struct mgmt_evt_op_cmd_status_arg cmd_status_arg;
359360
zcbor_state_t *zsd = ctxt->reader->zs;
360361
bool ok;
361362
size_t decoded = 0;
@@ -381,6 +382,20 @@ img_mgmt_upload(struct smp_streamer *ctxt)
381382
ZCBOR_MAP_DECODE_KEY_VAL(upgrade, zcbor_bool_decode, &req.upgrade)
382383
};
383384

385+
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
386+
struct mgmt_evt_op_cmd_arg cmd_status_arg = {
387+
.group = MGMT_GROUP_ID_IMAGE,
388+
.id = IMG_MGMT_ID_UPLOAD,
389+
};
390+
#endif
391+
392+
#if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK)
393+
struct img_mgmt_upload_check upload_check_data = {
394+
.action = &action,
395+
.req = &req,
396+
};
397+
#endif
398+
384399
ok = zcbor_map_decode_bulk(zsd, image_upload_decode,
385400
ARRAY_SIZE(image_upload_decode), &decoded) == 0;
386401

@@ -393,7 +408,10 @@ img_mgmt_upload(struct smp_streamer *ctxt)
393408
/* Determine what actions to take as a result of this request. */
394409
rc = img_mgmt_upload_inspect(&req, &action);
395410
if (rc != 0) {
396-
img_mgmt_dfu_stopped();
411+
#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS)
412+
(void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED, NULL, 0);
413+
#endif
414+
397415
MGMT_CTXT_SET_RC_RSN(ctxt, IMG_MGMT_UPLOAD_ACTION_RC_RSN(&action));
398416
return rc;
399417
}
@@ -405,17 +423,18 @@ img_mgmt_upload(struct smp_streamer *ctxt)
405423
return img_mgmt_upload_good_rsp(ctxt);
406424
}
407425

426+
#if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK)
408427
/* Request is valid. Give the application a chance to reject this upload
409428
* request.
410429
*/
411-
if (img_mgmt_upload_cb != NULL) {
412-
rc = img_mgmt_upload_cb(req, action);
430+
rc = mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK, &upload_check_data,
431+
sizeof(upload_check_data));
413432

414-
if (rc != 0) {
415-
IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(&action, img_mgmt_err_str_app_reject);
416-
goto end;
417-
}
433+
if (rc != MGMT_ERR_EOK) {
434+
IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(&action, img_mgmt_err_str_app_reject);
435+
goto end;
418436
}
437+
#endif
419438

420439
/* Remember flash area ID and image size for subsequent upload requests. */
421440
g_img_mgmt_state.area_id = action.area_id;
@@ -432,8 +451,13 @@ img_mgmt_upload(struct smp_streamer *ctxt)
432451

433452
g_img_mgmt_state.off = 0;
434453

435-
img_mgmt_dfu_started();
454+
#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS)
455+
(void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_STARTED, NULL, 0);
456+
#endif
457+
458+
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
436459
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_START;
460+
#endif
437461

438462
/*
439463
* We accept SHA trimmed to any length by client since it's up to client
@@ -456,8 +480,12 @@ img_mgmt_upload(struct smp_streamer *ctxt)
456480
*/
457481
g_img_mgmt_state.off = g_img_mgmt_state.size;
458482
img_mgmt_dfu_pending();
459-
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE;
460483
reset = true;
484+
485+
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
486+
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE;
487+
#endif
488+
461489
goto end;
462490
}
463491
#endif
@@ -474,7 +502,9 @@ img_mgmt_upload(struct smp_streamer *ctxt)
474502
}
475503
#endif
476504
} else {
505+
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
477506
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_ONGOING;
507+
#endif
478508
}
479509

480510
/* Write the image data to flash. */
@@ -490,31 +520,46 @@ img_mgmt_upload(struct smp_streamer *ctxt)
490520
g_img_mgmt_state.off += action.write_bytes;
491521
} else {
492522
/* Write failed, currently not able to recover from this */
523+
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
493524
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE;
525+
#endif
526+
494527
IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(&action,
495528
img_mgmt_err_str_flash_write_failed);
496529
reset = true;
530+
IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(&action,
531+
img_mgmt_err_str_flash_write_failed);
532+
497533
goto end;
498534
}
499535

500536
if (g_img_mgmt_state.off == g_img_mgmt_state.size) {
501537
/* Done */
502-
img_mgmt_dfu_pending();
503-
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE;
538+
#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS)
539+
(void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_PENDING, NULL, 0);
540+
#endif
541+
504542
reset = true;
543+
544+
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
545+
cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE;
546+
#endif
505547
}
506548
}
507549
end:
508550

509551
img_mgmt_upload_log(req.off == 0, g_img_mgmt_state.off == g_img_mgmt_state.size, rc);
510552

511553
#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS)
512-
(void)mgmt_callback_notify(MGMT_EVT_OP_CMD_STATUS, MGMT_GROUP_ID_IMAGE,
513-
IMG_MGMT_ID_UPLOAD, &cmd_status_arg, false);
554+
(void)mgmt_callback_notify(MGMT_EVT_OP_CMD_STATUS, &cmd_status_arg,
555+
sizeof(cmd_status_arg));
514556
#endif
515557

516558
if (rc != 0) {
517-
img_mgmt_dfu_stopped();
559+
#if defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS)
560+
(void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED, NULL, 0);
561+
#endif
562+
518563
return rc;
519564
}
520565

@@ -528,50 +573,6 @@ img_mgmt_upload(struct smp_streamer *ctxt)
528573
return rc;
529574
}
530575

531-
void
532-
img_mgmt_dfu_stopped(void)
533-
{
534-
if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_stopped_cb) {
535-
img_mgmt_dfu_callbacks_fn->dfu_stopped_cb();
536-
}
537-
}
538-
539-
void
540-
img_mgmt_dfu_started(void)
541-
{
542-
if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_started_cb) {
543-
img_mgmt_dfu_callbacks_fn->dfu_started_cb();
544-
}
545-
}
546-
547-
void
548-
img_mgmt_dfu_pending(void)
549-
{
550-
if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_pending_cb) {
551-
img_mgmt_dfu_callbacks_fn->dfu_pending_cb();
552-
}
553-
}
554-
555-
void
556-
img_mgmt_dfu_confirmed(void)
557-
{
558-
if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_confirmed_cb) {
559-
img_mgmt_dfu_callbacks_fn->dfu_confirmed_cb();
560-
}
561-
}
562-
563-
void
564-
img_mgmt_set_upload_cb(img_mgmt_upload_fn cb)
565-
{
566-
img_mgmt_upload_cb = cb;
567-
}
568-
569-
void
570-
img_mgmt_register_callbacks(const struct img_mgmt_dfu_callbacks_t *cb_struct)
571-
{
572-
img_mgmt_dfu_callbacks_fn = cb_struct;
573-
}
574-
575576
int
576577
img_mgmt_my_version(struct image_version *ver)
577578
{

0 commit comments

Comments
 (0)