Skip to content

Commit

Permalink
ext: lib: mgmt: mcumgr: update to latest master
Browse files Browse the repository at this point in the history
This patch introduce version which add two new features:
 - ability to resume partial upload
 - option to not compile taskstat and echo commands

Origin: mcumgr
License: Apache 2.0
URL: https://github.com/apache/mynewt-mcumgr
Commit: 6251689367fcfe92898b90978b877a242b6e4b24
Purpose: New features
Maintained-by: External

Signed-off-by: Szymon Janc <[email protected]>
  • Loading branch information
sjanc authored and carlescufi committed Nov 4, 2018
1 parent dc6b0c8 commit 18d9cd8
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 14 deletions.
85 changes: 73 additions & 12 deletions ext/lib/mgmt/mcumgr/cmd/img_mgmt/src/img_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "img_mgmt_priv.h"
#include "img_mgmt_config.h"

#define IMG_MGMT_DATA_SHA_LEN 32

static mgmt_handler_fn img_mgmt_upload;
static mgmt_handler_fn img_mgmt_erase;

Expand Down Expand Up @@ -66,6 +68,10 @@ static struct {

/** Total length of image currently being uploaded. */
size_t len;

/** Hash of image data; used for resume of a partial upload. */
uint8_t data_sha_len;
uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN];
} img_mgmt_ctxt;

/**
Expand Down Expand Up @@ -247,6 +253,9 @@ img_mgmt_erase(struct mgmt_ctxt *ctxt)
return MGMT_ERR_ENOMEM;
}

/* reset uploading information on erase */
img_mgmt_ctxt.uploading = false;

return 0;
}

Expand All @@ -270,26 +279,35 @@ img_mgmt_encode_upload_rsp(struct mgmt_ctxt *ctxt, int status)
return 0;
}

/**
* Processes an upload request specifying an offset of 0 (i.e., the first image
* chunk). The caller is responsible for encoding the response.
*/
/* check if header for first packet is valid */
static int
img_mgmt_upload_first_chunk(struct mgmt_ctxt *ctxt, const uint8_t *req_data,
size_t len)
img_mgmt_check_header(const uint8_t *req_data, size_t len)
{
struct image_header hdr;
int rc;

if (len < sizeof hdr) {
if (len < sizeof(hdr)) {
return MGMT_ERR_EINVAL;
}

memcpy(&hdr, req_data, sizeof hdr);
memcpy(&hdr, req_data, sizeof(hdr));
if (hdr.ih_magic != IMAGE_MAGIC) {
return MGMT_ERR_EINVAL;
}

return 0;
}

/**
* Processes an upload request specifying an offset of 0 (i.e., the first image
* chunk). The caller is responsible for encoding the response.
*/
static int
img_mgmt_upload_first_chunk(struct mgmt_ctxt *ctxt, const uint8_t *req_data,
size_t len, const uint8_t *data_sha,
size_t data_sha_len)
{
int rc;

if (img_mgmt_slot_in_use(1)) {
/* No free slot. */
return MGMT_ERR_ENOMEM;
Expand All @@ -304,6 +322,16 @@ img_mgmt_upload_first_chunk(struct mgmt_ctxt *ctxt, const uint8_t *req_data,
img_mgmt_ctxt.off = 0;
img_mgmt_ctxt.len = 0;

/*
* We accept SHA trimmed to any length by client since it's up to client
* to make sure provided data are good enough to avoid collisions when
* resuming upload.
*/
img_mgmt_ctxt.data_sha_len = data_sha_len;
memcpy(img_mgmt_ctxt.data_sha, data_sha, data_sha_len);
memset(&img_mgmt_ctxt.data_sha[data_sha_len], 0,
IMG_MGMT_DATA_SHA_LEN - data_sha_len);

return 0;
}

Expand All @@ -314,14 +342,16 @@ static int
img_mgmt_upload(struct mgmt_ctxt *ctxt)
{
uint8_t img_mgmt_data[IMG_MGMT_UL_CHUNK_SIZE];
uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN];
size_t data_sha_len = 0;
unsigned long long len;
unsigned long long off;
size_t data_len;
size_t new_off;
bool last;
int rc;

const struct cbor_attr_t off_attr[4] = {
const struct cbor_attr_t off_attr[] = {
[0] = {
.attribute = "data",
.type = CborAttrByteStringType,
Expand All @@ -341,7 +371,14 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt)
.addr.uinteger = &off,
.nodefault = true
},
[3] = { 0 },
[3] = {
.attribute = "sha",
.type = CborAttrByteStringType,
.addr.bytestring.data = data_sha,
.addr.bytestring.len = &data_sha_len,
.len = sizeof(data_sha)
},
[4] = { 0 },
};

len = ULLONG_MAX;
Expand All @@ -358,7 +395,31 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt)
return MGMT_ERR_EINVAL;
}

rc = img_mgmt_upload_first_chunk(ctxt, img_mgmt_data, data_len);
rc = img_mgmt_check_header(img_mgmt_data, data_len);
if (rc) {
return rc;
}

/* Reject if SHA len is to big */
if (data_sha_len > IMG_MGMT_DATA_SHA_LEN) {
return MGMT_ERR_EINVAL;
}

/*
* If request includes proper data hash we can check whether there is
* upload in progress (interrupted due to e.g. link disconnection) with
* the same data hash so we can just resume it by simply including
* current upload offset in response.
*/
if ((data_sha_len > 0) && img_mgmt_ctxt.uploading) {
if ((img_mgmt_ctxt.data_sha_len == data_sha_len) &&
!memcmp(img_mgmt_ctxt.data_sha, data_sha, data_sha_len)) {
return img_mgmt_encode_upload_rsp(ctxt, 0);
}
}

rc = img_mgmt_upload_first_chunk(ctxt, img_mgmt_data, data_len,
data_sha, data_sha_len);
if (rc != 0) {
return rc;
}
Expand Down
14 changes: 12 additions & 2 deletions ext/lib/mgmt/mcumgr/cmd/os_mgmt/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,27 @@
# Under the License.

menuconfig MCUMGR_CMD_OS_MGMT
bool "Enable mcumgr handlers for OS management"
bool
prompt "Enable mcumgr handlers for OS management"
select REBOOT
help
Enables mcumgr handlers for OS management

if MCUMGR_CMD_OS_MGMT
config OS_MGMT_RESET_MS
int "Delay before executing reset command (ms)"
int
prompt "Delay before executing reset command (ms)"
default 250
help
When a reset command is received, the system waits this many milliseconds
before performing the reset. This delay allows time for the mcumgr
response to be delivered.

config OS_MGMT_TASKSTAT
bool "Support for taskstat command"
default y

config OS_MGMT_ECHO
bool "Support for echo command"
default y
endif
14 changes: 14 additions & 0 deletions ext/lib/mgmt/mcumgr/cmd/os_mgmt/src/os_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,27 @@
#include "os_mgmt/os_mgmt_impl.h"
#include "os_mgmt_config.h"

#ifdef OS_MGMT_ECHO
static mgmt_handler_fn os_mgmt_echo;
#endif

static mgmt_handler_fn os_mgmt_reset;

#ifdef OS_MGMT_TASKSTAT
static mgmt_handler_fn os_mgmt_taskstat_read;
#endif

static const struct mgmt_handler os_mgmt_group_handlers[] = {
#ifdef OS_MGMT_ECHO
[OS_MGMT_ID_ECHO] = {
os_mgmt_echo, os_mgmt_echo
},
#endif
#ifdef OS_MGMT_TASKSTAT
[OS_MGMT_ID_TASKSTAT] = {
os_mgmt_taskstat_read, NULL
},
#endif
[OS_MGMT_ID_RESET] = {
NULL, os_mgmt_reset
},
Expand All @@ -54,6 +64,7 @@ static struct mgmt_group os_mgmt_group = {
/**
* Command handler: os echo
*/
#ifdef OS_MGMT_ECHO
static int
os_mgmt_echo(struct mgmt_ctxt *ctxt)
{
Expand Down Expand Up @@ -89,7 +100,9 @@ os_mgmt_echo(struct mgmt_ctxt *ctxt)

return 0;
}
#endif

#ifdef OS_MGMT_TASKSTAT
/**
* Encodes a single taskstat entry.
*/
Expand Down Expand Up @@ -173,6 +186,7 @@ os_mgmt_taskstat_read(struct mgmt_ctxt *ctxt)

return 0;
}
#endif

/**
* Command handler: os reset
Expand Down
4 changes: 4 additions & 0 deletions ext/lib/mgmt/mcumgr/cmd/os_mgmt/src/os_mgmt_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@
#include "syscfg/syscfg.h"

#define OS_MGMT_RESET_MS MYNEWT_VAL(OS_MGMT_RESET_MS)
#define OS_MGMT_TASKSTAT MYNEWT_VAL(OS_MGMT_TASKSTAT)
#define OS_MGMT_ECHO MYNEWT_VAL(OS_MGMT_ECHO)

#elif defined __ZEPHYR__

#define OS_MGMT_RESET_MS CONFIG_OS_MGMT_RESET_MS
#define OS_MGMT_TASKSTAT CONFIG_OS_MGMT_TASKSTAT
#define OS_MGMT_ECHO CONFIG_OS_MGMT_ECHO

#else

Expand Down

0 comments on commit 18d9cd8

Please sign in to comment.