ext: lib: mgmt: mcumgr: update to latest master

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 <szymon.janc@codecoup.pl>
This commit is contained in:
Szymon Janc 2018-11-02 12:41:13 +01:00 committed by Carles Cufí
commit 18d9cd8831
4 changed files with 105 additions and 16 deletions

View file

@ -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;
@ -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;
/**
@ -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;
}
@ -270,26 +279,35 @@ img_mgmt_encode_upload_rsp(struct mgmt_ctxt *ctxt, int status)
return 0;
}
/* check if header for first packet is valid */
static int
img_mgmt_check_header(const uint8_t *req_data, size_t len)
{
struct image_header hdr;
if (len < sizeof(hdr)) {
return MGMT_ERR_EINVAL;
}
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)
size_t len, const uint8_t *data_sha,
size_t data_sha_len)
{
struct image_header hdr;
int rc;
if (len < sizeof hdr) {
return MGMT_ERR_EINVAL;
}
memcpy(&hdr, req_data, sizeof hdr);
if (hdr.ih_magic != IMAGE_MAGIC) {
return MGMT_ERR_EINVAL;
}
if (img_mgmt_slot_in_use(1)) {
/* No free slot. */
return MGMT_ERR_ENOMEM;
@ -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;
}
@ -314,6 +342,8 @@ 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;
@ -321,7 +351,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt)
bool last;
int rc;
const struct cbor_attr_t off_attr[4] = {
const struct cbor_attr_t off_attr[] = {
[0] = {
.attribute = "data",
.type = CborAttrByteStringType,
@ -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;
@ -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;
}

View file

@ -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

View file

@ -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
},
@ -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)
{
@ -89,7 +100,9 @@ os_mgmt_echo(struct mgmt_ctxt *ctxt)
return 0;
}
#endif
#ifdef OS_MGMT_TASKSTAT
/**
* Encodes a single taskstat entry.
*/
@ -173,6 +186,7 @@ os_mgmt_taskstat_read(struct mgmt_ctxt *ctxt)
return 0;
}
#endif
/**
* Command handler: os reset

View file

@ -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