Skip to content

Commit

Permalink
[nrf fromtree] mgmt: mcumgr: grp: img_mgmt: Add optional image slot s…
Browse files Browse the repository at this point in the history
…tate callback

Adds an optional callback which can be used to append custom
fields to the image slot state command response

Signed-off-by: Jamie McCrae <[email protected]>
(cherry picked from commit 031f9f2)
  • Loading branch information
nordicjm committed Sep 24, 2024
1 parent 5bb7bb0 commit 64d8497
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 22 deletions.
18 changes: 18 additions & 0 deletions include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#ifndef H_MCUMGR_IMG_MGMT_CALLBACKS_
#define H_MCUMGR_IMG_MGMT_CALLBACKS_

#include <stdbool.h>
#include <stdint.h>
#include <zcbor_common.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -37,6 +41,20 @@ struct img_mgmt_upload_check {
struct img_mgmt_upload_req *req;
};

/**
* Structure provided in the #MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE notification callback: This
* callback function is used to allow applications or modules append custom fields to the image
* slot state response.
*/
struct img_mgmt_state_slot_encode {
bool *ok;
zcbor_state_t *zse;
const uint32_t slot;
const char *version;
const uint8_t *hash;
const int flags;
};

/**
* @}
*/
Expand Down
3 changes: 3 additions & 0 deletions include/zephyr/mgmt/mcumgr/mgmt/callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ enum img_mgmt_group_events {
/** Callback when an image write command has finished writing to flash. */
MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 5),

/** Callback when an image slot's state is encoded for a response. */
MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 6),

/** Used to enable all img_mgmt_group events. */
MGMT_EVT_OP_IMG_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_IMG),
};
Expand Down
16 changes: 16 additions & 0 deletions subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,22 @@ config MCUMGR_GRP_IMG_TOO_LARGE_BOOTLOADER_INFO

endchoice

config MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_HOOK
bool "Image slot state hook"
depends on MCUMGR_MGMT_NOTIFICATION_HOOKS
help
Allows applications to add additional fields to responses for the image slot state
command.

config MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_STATES
int
prompt "Predicted maximum number of entries per group" if MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_HOOK
default 15
help
This is used for defining CBOR map holding group data.
The value does not affect memory allocation, it is used by zcbor
to figure out how to encode map depending on its predicted size.

config MCUMGR_GRP_IMG_QSPI_XIP_SPLIT_IMAGE
bool "QSPI XIP Split image mode"
depends on MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP
Expand Down
65 changes: 43 additions & 22 deletions subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,11 @@
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
#endif

LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL);
#ifdef CONFIG_MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_HOOK
#include <mgmt/mcumgr/transport/smp_internal.h>
#endif

/* The value here sets how many "characteristics" that describe image is
* encoded into a map per each image (like bootable flags, and so on).
* This value is only used for zcbor to predict map size and map encoding
* and does not affect memory allocation.
* In case when more "characteristics" are added to image map then
* zcbor_map_end_encode may fail it this value does not get updated.
*/
#define MAX_IMG_CHARACTERISTICS 15
LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL);

#ifndef CONFIG_MCUMGR_GRP_IMG_FRUGAL_LIST
#define ZCBOR_ENCODE_FLAG(zse, label, value) \
Expand Down Expand Up @@ -415,8 +410,9 @@ img_mgmt_state_confirm(void)
}

/* Return zcbor encoding result */
static bool img_mgmt_state_encode_slot(zcbor_state_t *zse, uint32_t slot, int state_flags)
static bool img_mgmt_state_encode_slot(struct smp_streamer *ctxt, uint32_t slot, int state_flags)
{
zcbor_state_t *zse = ctxt->writer->zs;
uint32_t flags;
char vers_str[IMG_MGMT_VER_MAX_STR_LEN];
uint8_t hash[IMAGE_HASH_LEN]; /* SHA256 hash */
Expand All @@ -425,17 +421,30 @@ static bool img_mgmt_state_encode_slot(zcbor_state_t *zse, uint32_t slot, int st
bool ok;
int rc = img_mgmt_read_info(slot, &ver, hash, &flags);

#if defined(CONFIG_MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_HOOK)
int32_t err_rc;
uint16_t err_group;
struct img_mgmt_state_slot_encode slot_encode_data = {
.ok = &ok,
.zse = zse,
.slot = slot,
.version = vers_str,
.hash = hash,
.flags = flags,
};
#endif

if (rc != 0) {
/* zcbor encoding did not fail */
return true;
}

ok = zcbor_map_start_encode(zse, MAX_IMG_CHARACTERISTICS) &&
ok = zcbor_map_start_encode(zse, CONFIG_MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_STATES) &&
(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 1 ||
(zcbor_tstr_put_lit(zse, "image") &&
zcbor_uint32_put(zse, slot >> 1))) &&
zcbor_tstr_put_lit(zse, "slot") &&
zcbor_uint32_put(zse, slot % 2) &&
(zcbor_tstr_put_lit(zse, "image") &&
zcbor_uint32_put(zse, slot >> 1))) &&
zcbor_tstr_put_lit(zse, "slot") &&
zcbor_uint32_put(zse, slot % 2) &&
zcbor_tstr_put_lit(zse, "version");

if (ok) {
Expand All @@ -447,15 +456,27 @@ static bool img_mgmt_state_encode_slot(zcbor_state_t *zse, uint32_t slot, int st
}
}

ok = ok && zcbor_tstr_put_lit(zse, "hash") &&
ok = ok && zcbor_tstr_put_lit(zse, "hash") &&
zcbor_bstr_encode(zse, &zhash) &&
ZCBOR_ENCODE_FLAG(zse, "bootable", !(flags & IMAGE_F_NON_BOOTABLE)) &&
ZCBOR_ENCODE_FLAG(zse, "pending", state_flags & REPORT_SLOT_PENDING) &&
ZCBOR_ENCODE_FLAG(zse, "confirmed", state_flags & REPORT_SLOT_CONFIRMED) &&
ZCBOR_ENCODE_FLAG(zse, "active", state_flags & REPORT_SLOT_ACTIVE) &&
ZCBOR_ENCODE_FLAG(zse, "permanent", state_flags & REPORT_SLOT_PERMANENT) &&
zcbor_map_end_encode(zse, MAX_IMG_CHARACTERISTICS);
ZCBOR_ENCODE_FLAG(zse, "permanent", state_flags & REPORT_SLOT_PERMANENT);

if (!ok) {
goto failed;
}

#if defined(CONFIG_MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_HOOK)
/* Send notification to application to optionally append more fields */
(void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE, &slot_encode_data,
sizeof(slot_encode_data), &err_rc, &err_group);
#endif

ok &= zcbor_map_end_encode(zse, CONFIG_MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_STATES);

failed:
return ok;
}

Expand Down Expand Up @@ -499,11 +520,11 @@ img_mgmt_state_read(struct smp_streamer *ctxt)

/* Need to report slots in proper order */
if (slot_a < slot_o) {
ok = img_mgmt_state_encode_slot(zse, slot_a, flags_a) &&
img_mgmt_state_encode_slot(zse, slot_o, flags_o);
ok = img_mgmt_state_encode_slot(ctxt, slot_a, flags_a) &&
img_mgmt_state_encode_slot(ctxt, slot_o, flags_o);
} else {
ok = img_mgmt_state_encode_slot(zse, slot_o, flags_o) &&
img_mgmt_state_encode_slot(zse, slot_a, flags_a);
ok = img_mgmt_state_encode_slot(ctxt, slot_o, flags_o) &&
img_mgmt_state_encode_slot(ctxt, slot_a, flags_a);
}
}

Expand Down

0 comments on commit 64d8497

Please sign in to comment.