From 97241e20577b9ba4817efc444ef2deea57278750 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 30 May 2019 15:40:26 -0700 Subject: [PATCH 01/65] mynewt core mcumgr port --- cborattr/include/cborattr/cborattr.h | 5 ++++- cborattr/pkg.yml | 2 +- cborattr/src/cborattr.c | 12 ++++++++---- mgmt/include/mgmt/mgmt.h | 2 +- mgmt/pkg.yml | 2 +- mgmt/src/mgmt.c | 2 +- smp/pkg.yml | 2 +- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/cborattr/include/cborattr/cborattr.h b/cborattr/include/cborattr/cborattr.h index 1cc14b35..c0c64d00 100644 --- a/cborattr/include/cborattr/cborattr.h +++ b/cborattr/include/cborattr/cborattr.h @@ -26,7 +26,8 @@ #include #include #include -#include "cbor.h" +#include "tinycbor/cbor.h" +#include #ifdef __cplusplus extern "C" { @@ -144,6 +145,8 @@ int cbor_read_array(struct CborValue *, const struct cbor_array_t *); int cbor_read_flat_attrs(const uint8_t *data, int len, const struct cbor_attr_t *attrs); +int cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, + const struct cbor_attr_t *attrs); #ifdef __cplusplus } diff --git a/cborattr/pkg.yml b/cborattr/pkg.yml index 8495f950..67a197f0 100644 --- a/cborattr/pkg.yml +++ b/cborattr/pkg.yml @@ -24,6 +24,6 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - "encoding/tinycbor" + - "@apache-mynewt-core/encoding/tinycbor" pkg.cflags.FLOAT_USER: -DFLOAT_SUPPORT diff --git a/cborattr/src/cborattr.c b/cborattr/src/cborattr.c index c76ecc82..fc46dbe8 100644 --- a/cborattr/src/cborattr.c +++ b/cborattr/src/cborattr.c @@ -19,8 +19,10 @@ //#include #include "cborattr/cborattr.h" -#include "cbor.h" -#include "cbor_buf_reader.h" +#include "tinycbor/cbor.h" +#include "tinycbor/cbor_buf_reader.h" +#include "tinycbor/cbor_mbuf_reader.h" +#include "os/os_mbuf.h" #define CBORATTR_MAX_SIZE 512 @@ -386,14 +388,17 @@ cbor_read_flat_attrs(const uint8_t *data, int len, CborError err; cbor_buf_reader_init(&reader, data, len); +#ifdef __ZEPHYR__ err = cbor_parser_cust_reader_init(&reader.r, 0, &parser, &value); +#else + err = cbor_parser_init(&reader.r, 0, &parser, &value); +#endif if (err != CborNoError) { return -1; } return cbor_read_object(&value, attrs); } -#if 0 /* * Read in cbor key/values from os_mbuf pointed by m, and fill them * into attrs. @@ -421,4 +426,3 @@ cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, } return cbor_read_object(&value, attrs); } -#endif diff --git a/mgmt/include/mgmt/mgmt.h b/mgmt/include/mgmt/mgmt.h index b17d6936..bcacbcfc 100644 --- a/mgmt/include/mgmt/mgmt.h +++ b/mgmt/include/mgmt/mgmt.h @@ -21,7 +21,7 @@ #define H_MGMT_MGMT_ #include -#include "cbor.h" +#include "tinycbor/cbor.h" #ifdef __cplusplus extern "C" { diff --git a/mgmt/pkg.yml b/mgmt/pkg.yml index 94839bd7..37ff8066 100644 --- a/mgmt/pkg.yml +++ b/mgmt/pkg.yml @@ -26,4 +26,4 @@ pkg.keywords: pkg.deps: - '@apache-mynewt-core/encoding/tinycbor' - '@apache-mynewt-core/kernel/os' - - '@mynewt-mcumgr/mgmt' + - '@apache-mynewt-mcumgr/mgmt' diff --git a/mgmt/src/mgmt.c b/mgmt/src/mgmt.c index 92872721..0907654e 100644 --- a/mgmt/src/mgmt.c +++ b/mgmt/src/mgmt.c @@ -18,7 +18,7 @@ */ #include -#include "cbor.h" +#include "tinycbor/cbor.h" #include "mgmt/endian.h" #include "mgmt/mgmt.h" diff --git a/smp/pkg.yml b/smp/pkg.yml index b9fcc78c..99c597b6 100644 --- a/smp/pkg.yml +++ b/smp/pkg.yml @@ -24,7 +24,7 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - '@apache-mynewt-core/encoding/cborattr' + - '@apache-mynewt-mcumgr/cborattr' - '@apache-mynewt-core/kernel/os' - '@apache-mynewt-core/util/mem' - '@mynewt-mcumgr/mgmt' From 682df33c0b6f6a7ce43f338b738d525f20539100 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 30 May 2019 16:07:46 -0700 Subject: [PATCH 02/65] Custome reader/writer only used for ZEPHYR --- mgmt/src/mgmt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mgmt/src/mgmt.c b/mgmt/src/mgmt.c index 0907654e..ec4fe4fa 100644 --- a/mgmt/src/mgmt.c +++ b/mgmt/src/mgmt.c @@ -145,13 +145,21 @@ mgmt_ctxt_init(struct mgmt_ctxt *ctxt, struct mgmt_streamer *streamer) { int rc; +#ifdef __ZEPHYR__ rc = cbor_parser_cust_reader_init(streamer->reader, 0, &ctxt->parser, &ctxt->it); +#else + rc = cbor_parser_init(streamer->reader, 0, &ctxt->parser, &ctxt->it); +#endif if (rc != CborNoError) { return mgmt_err_from_cbor(rc); } +#ifdef __ZEPHYR__ cbor_encoder_cust_writer_init(&ctxt->encoder, streamer->writer, 0); +#else + cbor_encoder_init(&ctxt->encoder, streamer->writer, 0); +#endif return 0; } From 43a2a8163ce5c325b663a10b038d0545b1c41bf1 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 30 May 2019 19:27:43 -0700 Subject: [PATCH 03/65] Mynewt: Fix Apache Mynewt MCUmgr nuild issues --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 28 ++++++++++++++++++ cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h | 10 +++++++ cmd/img_mgmt/pkg.yml | 5 +++- cmd/img_mgmt/port/mynewt/pkg.yml | 29 +++++++++++++++++++ .../port/mynewt/src/mynewt_img_mgmt.c | 22 ++++++++------ cmd/img_mgmt/src/img_mgmt.c | 8 +++++ cmd/img_mgmt/src/img_mgmt_priv.h | 7 ----- cmd/img_mgmt/src/img_mgmt_state.c | 11 ++----- cmd/img_mgmt/src/stubs.c | 2 +- util/pkg.yml | 24 +++++++++++++++ 10 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 cmd/img_mgmt/port/mynewt/pkg.yml create mode 100644 util/pkg.yml diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index 0f7f2bc5..b7cf4a4b 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -27,6 +27,24 @@ struct image_version; extern "C" { #endif +/* + * Image state flags + */ +#define IMG_MGMT_STATE_F_PENDING 0x01 +#define IMG_MGMT_STATE_F_CONFIRMED 0x02 +#define IMG_MGMT_STATE_F_ACTIVE 0x04 +#define IMG_MGMT_STATE_F_PERMANENT 0x08 + +#define IMG_MGMT_VER_MAX_STR_LEN 25 /* 255.255.65535.4294967295\0 */ + +/* + * Swap Types for image management state machine + */ +#define IMG_MGMT_SWAP_TYPE_NONE 0 +#define IMG_MGMT_SWAP_TYPE_TEST 1 +#define IMG_MGMT_SWAP_TYPE_PERM 2 +#define IMG_MGMT_SWAP_TYPE_REVERT 3 + /** * Command IDs for image management group. */ @@ -48,6 +66,16 @@ extern "C" { * @brief Registers the image management command handler group. */ void img_mgmt_register_group(void); +/** + * @brief Read info of an image give the slot number + */ +int img_mgmt_read_info(int image_slot, struct image_version *ver, + uint8_t *hash, uint32_t *flags); +/** + * @brief Get the current running image version + */ +int +img_mgmt_my_version(struct image_version *ver); #ifdef __cplusplus } diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h index d0898efa..1c28977c 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h @@ -27,6 +27,9 @@ #ifndef H_IMG_MGMT_IMPL_ #define H_IMG_MGMT_IMPL_ +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -100,6 +103,13 @@ int img_mgmt_impl_write_image_data(unsigned int offset, const void *data, */ int img_mgmt_impl_swap_type(void); +/** + * Collects information about the specified image slot. + * + * @return Flags of the specified image slot + */ +uint8_t img_mgmt_state_flags(int query_slot); + #ifdef __cplusplus } #endif diff --git a/cmd/img_mgmt/pkg.yml b/cmd/img_mgmt/pkg.yml index fd27c072..82353bd1 100644 --- a/cmd/img_mgmt/pkg.yml +++ b/cmd/img_mgmt/pkg.yml @@ -24,7 +24,10 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: + - '@apache-mynewt-mcumgr/cmd/img_mgmt/port/mynewt' - '@apache-mynewt-core/boot/split' - '@apache-mynewt-core/encoding/base64' - '@apache-mynewt-core/sys/flash_map' - - '@mynewt-mcumgr/mgmt' + - '@apache-mynewt-mcumgr/mgmt' + - '@apache-mynewt-mcumgr/cborattr' + - '@apache-mynewt-mcumgr/util' diff --git a/cmd/img_mgmt/port/mynewt/pkg.yml b/cmd/img_mgmt/port/mynewt/pkg.yml new file mode 100644 index 00000000..61a0946c --- /dev/null +++ b/cmd/img_mgmt/port/mynewt/pkg.yml @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/img_mgmt/port/mynewt +pkg.description: 'Image management command handlers for + Apache Mynewt for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-mcumgr/cmd/img_mgmt' + #- '@apache-mynewt-core/mgmt/imgmgr' diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c index c645d1b1..52988f74 100644 --- a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c @@ -21,7 +21,10 @@ #include "mgmt/mgmt.h" #include "img_mgmt/img_mgmt_impl.h" #include "img_mgmt/img_mgmt.h" -#include "img_mgmt_priv.h" +#include "split/split.h" +#include "flash_map/flash_map.h" +#include "sysflash/sysflash.h" +#include "img_mgmt/image.h" int img_mgmt_impl_erase_slot(void) @@ -58,19 +61,19 @@ img_mgmt_impl_write_pending(int slot, bool permanent) int split_app_active; int rc; - state_flags = imgmgr_state_flags(slot); + state_flags = img_mgmt_state_flags(slot); split_app_active = split_app_active_get(); /* Unconfirmed slots are always runable. A confirmed slot can only be * run if it is a loader in a split image setup. */ - if (state_flags & IMGMGR_STATE_F_CONFIRMED && + if (state_flags & IMG_MGMT_STATE_F_CONFIRMED && (slot != 0 || !split_app_active)) { return MGMT_ERR_EBADSTATE; } - rc = imgr_read_info(slot, NULL, NULL, &image_flags); + rc = img_mgmt_read_info(slot, NULL, NULL, &image_flags); if (rc != 0) { return MGMT_ERR_EUNKNOWN; } @@ -112,6 +115,8 @@ img_mgmt_impl_write_pending(int slot, bool permanent) int img_mgmt_impl_write_confirmed(void) { + int rc; + /* Confirm the unified image or loader in slot 0. */ rc = boot_set_confirmed(); if (rc != 0) { @@ -142,7 +147,7 @@ img_mgmt_impl_read(int slot, unsigned int offset, void *dst, int area_id; int rc; - area_id = flash_area_id_from_image_slot(image_slot); + area_id = flash_area_id_from_image_slot(slot); rc = flash_area_open(area_id, &fa); if (rc != 0) { return MGMT_ERR_EUNKNOWN; @@ -199,15 +204,14 @@ img_mgmt_impl_swap_type(void) void img_mgmt_module_init(void) { - int rc; - /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); - rc = img_mgmt_register_group(); - SYSINIT_PANIC_ASSERT(rc == 0); + img_mgmt_register_group(); #if MYNEWT_VAL(IMGMGR_CLI) + int rc; + rc = imgr_cli_register(); SYSINIT_PANIC_ASSERT(rc == 0); #endif diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index 3c90c3ab..d7ae3cbe 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -30,6 +30,8 @@ #include "img_mgmt_priv.h" #include "img_mgmt_config.h" +extern int boot_current_slot; + #define IMG_MGMT_DATA_SHA_LEN 32 static mgmt_handler_fn img_mgmt_upload; @@ -531,6 +533,12 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) return img_mgmt_encode_upload_rsp(ctxt, 0); } +int +img_mgmt_my_version(struct image_version *ver) +{ + return img_mgmt_read_info(boot_current_slot, ver, NULL, NULL); +} + void img_mgmt_register_group(void) { diff --git a/cmd/img_mgmt/src/img_mgmt_priv.h b/cmd/img_mgmt/src/img_mgmt_priv.h index a8a3a284..80bff9b4 100644 --- a/cmd/img_mgmt/src/img_mgmt_priv.h +++ b/cmd/img_mgmt/src/img_mgmt_priv.h @@ -26,11 +26,6 @@ extern "C" { #endif -#define IMG_MGMT_SWAP_TYPE_NONE 0 -#define IMG_MGMT_SWAP_TYPE_TEST 1 -#define IMG_MGMT_SWAP_TYPE_PERM 2 -#define IMG_MGMT_SWAP_TYPE_REVERT 3 - /* * Response to list: * { @@ -82,8 +77,6 @@ int img_mgmt_core_list(struct mgmt_ctxt *); int img_mgmt_core_load(struct mgmt_ctxt *); int img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver); int img_mgmt_find_by_ver(struct image_version *find, uint8_t *hash); -int img_mgmt_read_info(int image_slot, struct image_version *ver, - uint8_t *hash, uint32_t *flags); int img_mgmt_slot_in_use(int slot); int img_mgmt_state_read(struct mgmt_ctxt *ctxt); int img_mgmt_state_write(struct mgmt_ctxt *njb); diff --git a/cmd/img_mgmt/src/img_mgmt_state.c b/cmd/img_mgmt/src/img_mgmt_state.c index 299169b6..16d0a3ae 100644 --- a/cmd/img_mgmt/src/img_mgmt_state.c +++ b/cmd/img_mgmt/src/img_mgmt_state.c @@ -18,7 +18,7 @@ */ #include -#include "cbor.h" +#include "tinycbor/cbor.h" #include "cborattr/cborattr.h" #include "mgmt/mgmt.h" #include "img_mgmt/img_mgmt.h" @@ -26,17 +26,10 @@ #include "img_mgmt_priv.h" #include "img_mgmt/img_mgmt_impl.h" -#define IMG_MGMT_STATE_F_PENDING 0x01 -#define IMG_MGMT_STATE_F_CONFIRMED 0x02 -#define IMG_MGMT_STATE_F_ACTIVE 0x04 -#define IMG_MGMT_STATE_F_PERMANENT 0x08 - -#define IMG_MGMT_VER_MAX_STR_LEN 25 /* 255.255.65535.4294967295\0 */ - /** * Collects information about the specified image slot. */ -static uint8_t +uint8_t img_mgmt_state_flags(int query_slot) { uint8_t flags; diff --git a/cmd/img_mgmt/src/stubs.c b/cmd/img_mgmt/src/stubs.c index fa440dc4..6dafdda9 100644 --- a/cmd/img_mgmt/src/stubs.c +++ b/cmd/img_mgmt/src/stubs.c @@ -22,8 +22,8 @@ * implementation. */ -#include "mgmt/mgmt.h" #include "img_mgmt/img_mgmt_impl.h" +#include "mgmt/mgmt.h" int __attribute__((weak)) img_mgmt_impl_erase_slot(void) diff --git a/util/pkg.yml b/util/pkg.yml new file mode 100644 index 00000000..86c0f85b --- /dev/null +++ b/util/pkg.yml @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: util +pkg.description: Image management utility library +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: From 0a3fbb049292cbcf079ccfc8ec8af8ecd4f93347 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 31 May 2019 13:10:37 -0700 Subject: [PATCH 04/65] Remove stubs - were causing build issues since the packpages are separate for mynewt port --- cmd/img_mgmt/src/stubs.c | 64 ---------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 cmd/img_mgmt/src/stubs.c diff --git a/cmd/img_mgmt/src/stubs.c b/cmd/img_mgmt/src/stubs.c deleted file mode 100644 index 6dafdda9..00000000 --- a/cmd/img_mgmt/src/stubs.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * These stubs get linked in when there is no equivalent OS-specific - * implementation. - */ - -#include "img_mgmt/img_mgmt_impl.h" -#include "mgmt/mgmt.h" - -int __attribute__((weak)) -img_mgmt_impl_erase_slot(void) -{ - return MGMT_ERR_ENOTSUP; -} - -int __attribute__((weak)) -img_mgmt_impl_write_pending(int slot, bool permanent) -{ - return MGMT_ERR_ENOTSUP; -} - -int __attribute__((weak)) -img_mgmt_impl_write_confirmed(void) -{ - return MGMT_ERR_ENOTSUP; -} - -int __attribute__((weak)) -img_mgmt_impl_read(int slot, unsigned int offset, void *dst, - unsigned int num_bytes) -{ - return MGMT_ERR_ENOTSUP; -} - -int __attribute__((weak)) -img_mgmt_impl_write_image_data(unsigned int offset, const void *data, - unsigned int num_bytes, bool last) -{ - return MGMT_ERR_ENOTSUP; -} - -int __attribute__((weak)) -img_mgmt_impl_swap_type(void) -{ - return MGMT_ERR_ENOTSUP; -} From 6e4556a02e4a491540e5a662bdfc53d926e6e027 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 31 May 2019 18:42:23 -0700 Subject: [PATCH 05/65] Fix build issues --- mgmt/include/mgmt/mgmt.h | 3 +++ smp/pkg.yml | 4 ++-- smp/src/smp.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mgmt/include/mgmt/mgmt.h b/mgmt/include/mgmt/mgmt.h index bcacbcfc..068bebb5 100644 --- a/mgmt/include/mgmt/mgmt.h +++ b/mgmt/include/mgmt/mgmt.h @@ -27,6 +27,9 @@ extern "C" { #endif +/* MTU for newtmgr responses */ +#define MGMT_MAX_MTU 1024 + /** Opcodes; encoded in first byte of header. */ #define MGMT_OP_READ 0 #define MGMT_OP_READ_RSP 1 diff --git a/smp/pkg.yml b/smp/pkg.yml index 99c597b6..20c9e916 100644 --- a/smp/pkg.yml +++ b/smp/pkg.yml @@ -27,8 +27,8 @@ pkg.deps: - '@apache-mynewt-mcumgr/cborattr' - '@apache-mynewt-core/kernel/os' - '@apache-mynewt-core/util/mem' - - '@mynewt-mcumgr/mgmt' - - '@mynewt-mcumgr/smp' + - '@apache-mynewt-mcumgr/mgmt' + - '@apache-mynewt-mcumgr/smp' pkg.deps.NEWTMGR_BLE_HOST: - '@apache-mynewt-core/mgmt/newtmgr/transport/ble' diff --git a/smp/src/smp.c b/smp/src/smp.c index 9b929cad..fae40aa9 100644 --- a/smp/src/smp.c +++ b/smp/src/smp.c @@ -25,7 +25,7 @@ #include "mgmt/endian.h" #include "mgmt/mgmt.h" #include "smp/smp.h" -#include "cbor.h" +#include "tinycbor/cbor.h" static int smp_align4(int x) From 97c6ecd4182e74c0b4b991de7cf3e627d4709ff2 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 4 Jun 2019 18:51:44 -0700 Subject: [PATCH 06/65] Fix build issues --- cmd/os_mgmt/src/os_mgmt.c | 2 +- smp/pkg.yml | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/cmd/os_mgmt/src/os_mgmt.c b/cmd/os_mgmt/src/os_mgmt.c index f19418dc..a777be09 100644 --- a/cmd/os_mgmt/src/os_mgmt.c +++ b/cmd/os_mgmt/src/os_mgmt.c @@ -19,7 +19,7 @@ #include #include -#include "cbor.h" +#include "tinycbor/cbor.h" #include "cborattr/cborattr.h" #include "mgmt/mgmt.h" #include "os_mgmt/os_mgmt.h" diff --git a/smp/pkg.yml b/smp/pkg.yml index 20c9e916..0be9c3e4 100644 --- a/smp/pkg.yml +++ b/smp/pkg.yml @@ -28,13 +28,6 @@ pkg.deps: - '@apache-mynewt-core/kernel/os' - '@apache-mynewt-core/util/mem' - '@apache-mynewt-mcumgr/mgmt' - - '@apache-mynewt-mcumgr/smp' - -pkg.deps.NEWTMGR_BLE_HOST: - - '@apache-mynewt-core/mgmt/newtmgr/transport/ble' pkg.apis: - - newtmgr - -pkg.init: - smp_pkg_init: 500 + - smp From 8aec8434f715dc2c0ae6bcd62ab1b96ac951ffd0 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 5 Jun 2019 18:14:04 -0700 Subject: [PATCH 07/65] Add img_mgmt pkg_init --- cmd/img_mgmt/port/mynewt/pkg.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/img_mgmt/port/mynewt/pkg.yml b/cmd/img_mgmt/port/mynewt/pkg.yml index 61a0946c..ea5d8919 100644 --- a/cmd/img_mgmt/port/mynewt/pkg.yml +++ b/cmd/img_mgmt/port/mynewt/pkg.yml @@ -27,3 +27,6 @@ pkg.keywords: pkg.deps: - '@apache-mynewt-mcumgr/cmd/img_mgmt' #- '@apache-mynewt-core/mgmt/imgmgr' + +pkg.init: + img_mgmt_module_init: 501 From adb281c022bd8afccef90749171b55a84d5f8120 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 13 Jun 2019 19:13:33 -0700 Subject: [PATCH 08/65] cmd/os_mgmt: Fix mynewt port and misc fixes --- cmd/os_mgmt/pkg.yml | 5 ++++ cmd/os_mgmt/port/mynewt/pkg.yml | 28 ++++++++++++++++++++ cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c | 10 +++---- cmd/os_mgmt/src/os_mgmt.c | 6 +++++ 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 cmd/os_mgmt/port/mynewt/pkg.yml diff --git a/cmd/os_mgmt/pkg.yml b/cmd/os_mgmt/pkg.yml index c1389c4f..3aa0e3ce 100644 --- a/cmd/os_mgmt/pkg.yml +++ b/cmd/os_mgmt/pkg.yml @@ -25,3 +25,8 @@ pkg.keywords: pkg.deps: - '@apache-mynewt-core/kernel/os' + - '@apache-mynewt-mcumgr/cmd/os_mgmt/port/mynewt' + - '@apache-mynewt-mcumgr/mgmt' + +pkg.init: + os_mgmt_module_init: 501 diff --git a/cmd/os_mgmt/port/mynewt/pkg.yml b/cmd/os_mgmt/port/mynewt/pkg.yml new file mode 100644 index 00000000..51bcaa4a --- /dev/null +++ b/cmd/os_mgmt/port/mynewt/pkg.yml @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/os_mgmt/port/mynewt +pkg.description: 'OS management command handlers for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-mcumgr/cmd/os_mgmt' + - '@apache-mynewt-mcumgr/mgmt' diff --git a/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c b/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c index ccb94f08..492427a9 100644 --- a/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c +++ b/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c @@ -24,6 +24,8 @@ #include "reboot/log_reboot.h" #endif #include "os_mgmt/os_mgmt_impl.h" +#include "os_mgmt/os_mgmt.h" +#include "mgmt/mgmt.h" static struct os_callout mynewt_os_mgmt_reset_callout; @@ -102,15 +104,13 @@ os_mgmt_impl_task_info(int idx, struct os_mgmt_task_info *out_info) int os_mgmt_impl_reset(unsigned int delay_ms) { - int rc; - - os_callout_init(&mynewt_os_mgmt_reset_callout, mgmt_evq_get(), - nmgr_reset_tmo, NULL); + os_callout_init(&mynewt_os_mgmt_reset_callout, os_eventq_dflt_get(), + mynewt_os_mgmt_reset_tmo, NULL); #if MYNEWT_VAL(LOG_SOFT_RESET) log_reboot(HAL_RESET_REQUESTED); #endif - os_callout_reset(&nmgr_reset_callout, delay_ms * OS_TICKS_PER_SEC / 1000); + os_callout_reset(&mynewt_os_mgmt_reset_callout, delay_ms * OS_TICKS_PER_SEC / 1000); return 0; } diff --git a/cmd/os_mgmt/src/os_mgmt.c b/cmd/os_mgmt/src/os_mgmt.c index a777be09..fa550ffb 100644 --- a/cmd/os_mgmt/src/os_mgmt.c +++ b/cmd/os_mgmt/src/os_mgmt.c @@ -202,3 +202,9 @@ os_mgmt_register_group(void) { mgmt_register_group(&os_mgmt_group); } + +void +os_mgmt_module_init(void) +{ + os_mgmt_register_group(); +} From 06ecd3b62f2eb8388b1a358c14266ee1da8f2975 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 18 Jun 2019 19:20:40 -0700 Subject: [PATCH 09/65] log_mgmt: Add fixes from mynewt-core to log_mgmt - Make sure it builds and works - Make stat_mgmt buildable - Some fixes to img_mgmt --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 2 + cmd/img_mgmt/port/mynewt/pkg.yml | 1 - cmd/img_mgmt/src/img_mgmt.c | 2 - cmd/log_mgmt/include/log_mgmt/log_mgmt.h | 2 + cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h | 2 +- cmd/log_mgmt/pkg.yml | 29 +++++ cmd/log_mgmt/port/mynewt/pkg.yml | 31 ++++++ .../port/mynewt/src/mynewt_log_mgmt.c | 45 ++++---- cmd/log_mgmt/port/mynewt/syscfg.yml | 40 +++++++ cmd/log_mgmt/src/log_mgmt.c | 103 ++++++++++++++---- cmd/stat_mgmt/src/stat_mgmt.c | 4 +- mgmt/include/mgmt/mgmt.h | 1 + 12 files changed, 216 insertions(+), 46 deletions(-) create mode 100644 cmd/log_mgmt/pkg.yml create mode 100644 cmd/log_mgmt/port/mynewt/pkg.yml create mode 100644 cmd/log_mgmt/port/mynewt/syscfg.yml diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index b7cf4a4b..da9ad149 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -62,6 +62,8 @@ extern "C" { #define IMG_MGMT_ID_UPLOAD_STATUS_ONGOING 1 #define IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE 2 +extern int boot_current_slot; + /** * @brief Registers the image management command handler group. */ diff --git a/cmd/img_mgmt/port/mynewt/pkg.yml b/cmd/img_mgmt/port/mynewt/pkg.yml index ea5d8919..b4c9f2cc 100644 --- a/cmd/img_mgmt/port/mynewt/pkg.yml +++ b/cmd/img_mgmt/port/mynewt/pkg.yml @@ -26,7 +26,6 @@ pkg.keywords: pkg.deps: - '@apache-mynewt-mcumgr/cmd/img_mgmt' - #- '@apache-mynewt-core/mgmt/imgmgr' pkg.init: img_mgmt_module_init: 501 diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index d7ae3cbe..2fb02f66 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -30,8 +30,6 @@ #include "img_mgmt_priv.h" #include "img_mgmt_config.h" -extern int boot_current_slot; - #define IMG_MGMT_DATA_SHA_LEN 32 static mgmt_handler_fn img_mgmt_upload; diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h index 01df2e5a..919a7c99 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h @@ -57,6 +57,8 @@ struct log_mgmt_entry { size_t len; uint8_t module; uint8_t level; + uint8_t type; + void *ctxt; }; /** @brief Indicates which log entries to operate on. */ diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h index b3f6b126..d5f9d78a 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h @@ -35,7 +35,7 @@ struct log_mgmt_filter; struct log_mgmt_entry; struct log_mgmt_log; -typedef int log_mgmt_foreach_entry_fn(const struct log_mgmt_entry *entry, +typedef int log_mgmt_foreach_entry_fn(struct log_mgmt_entry *entry, void *arg); /** diff --git a/cmd/log_mgmt/pkg.yml b/cmd/log_mgmt/pkg.yml new file mode 100644 index 00000000..b774840c --- /dev/null +++ b/cmd/log_mgmt/pkg.yml @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/log_mgmt +pkg.description: 'OS management command handlers for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-core/kernel/os' + - '@apache-mynewt-mcumgr/cmd/log_mgmt/port/mynewt' + - '@apache-mynewt-mcumgr/mgmt' diff --git a/cmd/log_mgmt/port/mynewt/pkg.yml b/cmd/log_mgmt/port/mynewt/pkg.yml new file mode 100644 index 00000000..6996e7db --- /dev/null +++ b/cmd/log_mgmt/port/mynewt/pkg.yml @@ -0,0 +1,31 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/log_mgmt/port/mynewt +pkg.description: 'Log management command handlers for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-mcumgr/cmd/log_mgmt' + - '@apache-mynewt-mcumgr/mgmt' + +pkg.init: + log_mgmt_module_init: 501 diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index f81e5917..1d95e417 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -62,7 +62,7 @@ log_mgmt_impl_get_log(int idx, struct log_mgmt_log *out_log) } out_log->name = log->l_name; - out_log->type = log->l_handler->type; + out_log->type = log->l_log->log_type; return 0; } @@ -103,21 +103,16 @@ log_mgmt_impl_get_next_idx(uint32_t *out_idx) static int mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, - const void *desciptor, uint16_t len) + const struct log_entry_hdr *leh, + const void *dptr, uint16_t len) { struct mynewt_log_mgmt_walk_arg *mynewt_log_mgmt_walk_arg; struct log_mgmt_entry entry; - struct log_entry_hdr ueh; int read_len; int rc; mynewt_log_mgmt_walk_arg = log_offset->lo_arg; - - rc = log_read(log, desciptor, &ueh, 0, sizeof ueh); - if (rc != sizeof ueh) { - return MGMT_ERR_EUNKNOWN; - } - + /* If specified timestamp is nonzero, it is the primary criterion, and the * specified index is the secondary criterion. If specified timetsamp is * zero, specified index is the only criterion. @@ -129,27 +124,28 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, */ if (log_offset->lo_ts == 0) { - if (log_offset->lo_index > ueh.ue_index) { + if (log_offset->lo_index > leh->ue_index) { return 0; } - } else if (ueh.ue_ts < log_offset->lo_ts || - (ueh.ue_ts == log_offset->lo_ts && - ueh.ue_index < log_offset->lo_index)) { + } else if (leh->ue_ts < log_offset->lo_ts || + (leh->ue_ts == log_offset->lo_ts && + leh->ue_index < log_offset->lo_index)) { return 0; } - read_len = min(len - sizeof ueh, LOG_MGMT_BODY_LEN - sizeof ueh); - rc = log_read(log, desciptor, mynewt_log_mgmt_walk_arg->body, sizeof ueh, + read_len = min(len - sizeof leh, LOG_MGMT_BODY_LEN - sizeof leh); + rc = log_read(log, dptr, mynewt_log_mgmt_walk_arg->body, sizeof leh, read_len); if (rc < 0) { return MGMT_ERR_EUNKNOWN; } - entry.ts = ueh.ue_ts; - entry.index = ueh.ue_index; - entry.module = ueh.ue_module; - entry.level = ueh.ue_level; + entry.ts = leh->ue_ts; + entry.index = leh->ue_index; + entry.module = leh->ue_module; + entry.level = leh->ue_level; entry.len = rc; + entry.type = leh->ue_etype; entry.data = mynewt_log_mgmt_walk_arg->body; return mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); @@ -180,7 +176,7 @@ log_mgmt_impl_foreach_entry(const char *log_name, offset.lo_index = filter->min_index; offset.lo_data_len = 0; - return log_walk(log, mynewt_log_mgmt_walk_cb, &offset); + return log_walk_body(log, mynewt_log_mgmt_walk_cb, &offset); } return MGMT_ERR_ENOENT; @@ -204,3 +200,12 @@ log_mgmt_impl_clear(const char *log_name) return 0; } + +void +log_mgmt_module_init(void) +{ + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + log_mgmt_register_group(); +} diff --git a/cmd/log_mgmt/port/mynewt/syscfg.yml b/cmd/log_mgmt/port/mynewt/syscfg.yml new file mode 100644 index 00000000..cbc69a90 --- /dev/null +++ b/cmd/log_mgmt/port/mynewt/syscfg.yml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + LOG_MGMT_BODY_LEN: + description: > + Limits the maximum length of log entry bodies, in bytes. If a log + entry's body length exceeds this number, it gets truncated in management + responses. A buffer of this size gets allocated on the stack during + handling of the log show command. + value: 128 + + LOG_MGMT_CHUNK_SIZE: + description: > + Limits the maximum chunk size for log downloads, in bytes. A buffer of + this size gets allocated on the stack during handling of the log show command. + value: 512 + + LOG_MGMT_NAME_LEN: + description: > + Limits the maximum length of log names, in bytes. If a log's name length + exceeds this number, it gets truncated in management responses. A buffer + of this size gets allocated on the stack during handling of all log + management commands. + value: 64 diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index a3c0caca..1d33c707 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -22,18 +22,20 @@ #include "mgmt/mgmt.h" #include "cborattr/cborattr.h" -#include "cbor_cnt_writer.h" +#include "tinycbor/cbor_cnt_writer.h" #include "log_mgmt/log_mgmt.h" #include "log_mgmt/log_mgmt_impl.h" #include "log_mgmt_config.h" +#include "log_common/log_common.h" /** Context used during walks. */ struct log_walk_ctxt { /* The number of bytes encoded to the response so far. */ size_t rsp_len; - /* The encoder to use to write the current log entry. */ struct CborEncoder *enc; + /* Counter per encoder to understand if we are encoding the first chunk */ + uint32_t counter; }; static mgmt_handler_fn log_mgmt_show; @@ -63,36 +65,69 @@ static int log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, size_t *out_len) { + CborError err = CborNoError; + CborEncoder rsp; CborEncoder entry_enc; - CborError err; - - err = 0; - err |= cbor_encoder_create_map(enc, &entry_enc, 5); - err |= cbor_encode_text_stringz(&entry_enc, "msg"); - err |= cbor_encode_byte_string(&entry_enc, entry->data, entry->len); - err |= cbor_encode_text_stringz(&entry_enc, "ts"); - err |= cbor_encode_int(&entry_enc, entry->ts); - err |= cbor_encode_text_stringz(&entry_enc, "level"); - err |= cbor_encode_uint(&entry_enc, entry->level); - err |= cbor_encode_text_stringz(&entry_enc, "index"); - err |= cbor_encode_uint(&entry_enc, entry->index); - err |= cbor_encode_text_stringz(&entry_enc, "module"); - err |= cbor_encode_uint(&entry_enc, entry->module); - err |= cbor_encoder_close_container(enc, &entry_enc); + CborEncoder str_encoder; + int rc; + int off; + + rc = MGMT_ERR_EOK; + + err |= cbor_encoder_create_map(&entry_enc, &rsp, CborIndefiniteLength); + + switch (entry->type) { + case LOG_ETYPE_CBOR: + err |= cbor_encode_text_stringz(&rsp, "type"); + err |= cbor_encode_text_stringz(&rsp, "cbor"); + break; + case LOG_ETYPE_BINARY: + err |= cbor_encode_text_stringz(&rsp, "type"); + err |= cbor_encode_text_stringz(&rsp, "bin"); + break; + case LOG_ETYPE_STRING: + err |= cbor_encode_text_stringz(&rsp, "type"); + err |= cbor_encode_text_stringz(&rsp, "str"); + break; + default: + return MGMT_ERR_ECORRUPT; + } - if (err != 0) { - return MGMT_ERR_ENOMEM; + err |= cbor_encode_text_stringz(&rsp, "msg"); + + /* + * Write entry data as byte string. Since this may not fit into single + * chunk of data we will write as indefinite-length byte string which is + * basically a indefinite-length container with definite-length strings + * inside. + */ + err |= cbor_encoder_create_indef_byte_string(&rsp, &str_encoder); + for (off = 0; off < entry->len && !err; ) { + err |= cbor_encode_byte_string(&str_encoder, entry->data, rc); + off += rc; } + err |= cbor_encoder_close_container(&rsp, &str_encoder); + + err |= cbor_encode_text_stringz(&rsp, "ts"); + err |= cbor_encode_int(&rsp, entry->ts); + err |= cbor_encode_text_stringz(&rsp, "level"); + err |= cbor_encode_uint(&rsp, entry->level); + err |= cbor_encode_text_stringz(&rsp, "index"); + err |= cbor_encode_uint(&rsp, entry->index); + err |= cbor_encode_text_stringz(&rsp, "module"); + err |= cbor_encode_uint(&rsp, entry->module); + err |= cbor_encoder_close_container(&entry_enc, &rsp); + if (out_len != NULL) { - *out_len = cbor_encode_bytes_written(enc); + *out_len = cbor_encode_bytes_written(&entry_enc); } return 0; } static int -log_mgmt_cb_encode(const struct log_mgmt_entry *entry, void *arg) +log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) { struct CborCntWriter cnt_writer; struct log_walk_ctxt *ctxt; @@ -105,14 +140,36 @@ log_mgmt_cb_encode(const struct log_mgmt_entry *entry, void *arg) /*** First, determine if this entry would fit. */ cbor_cnt_writer_init(&cnt_writer); +#ifdef __ZEPHYR__ cbor_encoder_cust_writer_init(&cnt_encoder, &cnt_writer.enc, 0); +#else + cbor_encoder_init(&cnt_encoder, &cnt_writer.enc, 0); +#endif rc = log_mgmt_encode_entry(&cnt_encoder, entry, &entry_len); if (rc != 0) { return rc; } + /* + * Check if the response is too long. If more than one entry is in the + * response we will not add the current one and will return ENOMEM. If this + * is just a single entry we add the generic too long message text. + */ /* `+ 1` to account for the CBOR array terminator. */ if (ctxt->rsp_len + entry_len + 1 > LOG_MGMT_CHUNK_SIZE) { + /* + * Is this just a single entry? If so, encode the generic error + * message in the "msg" field of the response + */ + if (ctxt->counter == 0) { + entry->type = LOG_ETYPE_STRING; + snprintf((char *)entry->data, LOG_MGMT_BODY_LEN, + "error: entry too large (%d bytes)", entry_len); + } else { + rc = OS_ENOMEM; + goto err; + } + return MGMT_ERR_EMSGSIZE; } ctxt->rsp_len += entry_len; @@ -124,7 +181,11 @@ log_mgmt_cb_encode(const struct log_mgmt_entry *entry, void *arg) return rc; } + ctxt->counter++; + return 0; +err: + return rc; } static int diff --git a/cmd/stat_mgmt/src/stat_mgmt.c b/cmd/stat_mgmt/src/stat_mgmt.c index 7eac3f95..4de33999 100644 --- a/cmd/stat_mgmt/src/stat_mgmt.c +++ b/cmd/stat_mgmt/src/stat_mgmt.c @@ -125,7 +125,9 @@ stat_mgmt_list(struct mgmt_ctxt *ctxt) int rc; int i; - err = 0; + err = CborNoError; + err |= cbor_encode_text_stringz(&cb->encoder, "rc"); + err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK); err |= cbor_encode_text_stringz(&ctxt->encoder, "stat_list"); err |= cbor_encoder_create_array(&ctxt->encoder, &arr_enc, CborIndefiniteLength); diff --git a/mgmt/include/mgmt/mgmt.h b/mgmt/include/mgmt/mgmt.h index 068bebb5..3aab5b8f 100644 --- a/mgmt/include/mgmt/mgmt.h +++ b/mgmt/include/mgmt/mgmt.h @@ -63,6 +63,7 @@ extern "C" { #define MGMT_ERR_EBADSTATE 6 /* Current state disallows command. */ #define MGMT_ERR_EMSGSIZE 7 /* Response too large. */ #define MGMT_ERR_ENOTSUP 8 /* Command not supported. */ +#define MGMT_ERR_ECORRUPT 9 /* Corrupt */ #define MGMT_ERR_EPERUSER 256 #define MGMT_HDR_SIZE 8 From 69f7d69cc79e7bf7422a141be147d31a89c9cdd8 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 19 Jun 2019 18:39:21 -0700 Subject: [PATCH 10/65] log_mgmt: log entry encoder needs to be generic --- cmd/log_mgmt/src/log_mgmt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 1d33c707..b9b41d1c 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -67,14 +67,13 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, { CborError err = CborNoError; CborEncoder rsp; - CborEncoder entry_enc; CborEncoder str_encoder; int rc; int off; rc = MGMT_ERR_EOK; - err |= cbor_encoder_create_map(&entry_enc, &rsp, CborIndefiniteLength); + err |= cbor_encoder_create_map(enc, &rsp, CborIndefiniteLength); switch (entry->type) { case LOG_ETYPE_CBOR: @@ -117,10 +116,10 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, err |= cbor_encode_uint(&rsp, entry->index); err |= cbor_encode_text_stringz(&rsp, "module"); err |= cbor_encode_uint(&rsp, entry->module); - err |= cbor_encoder_close_container(&entry_enc, &rsp); + err |= cbor_encoder_close_container(enc, &rsp); if (out_len != NULL) { - *out_len = cbor_encode_bytes_written(&entry_enc); + *out_len = cbor_encode_bytes_written(enc); } return 0; From a0d3a962be099b6360795d920541d0daef8ee420 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 21 Jun 2019 16:10:05 -0700 Subject: [PATCH 11/65] Fix a few bugs with log read handlers --- cmd/log_mgmt/src/log_mgmt.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index b9b41d1c..4f92390a 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -27,6 +27,7 @@ #include "log_mgmt/log_mgmt_impl.h" #include "log_mgmt_config.h" #include "log_common/log_common.h" +#include "log/log.h" /** Context used during walks. */ struct log_walk_ctxt { @@ -68,10 +69,10 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, CborError err = CborNoError; CborEncoder rsp; CborEncoder str_encoder; - int rc; + uint16_t len; int off; - rc = MGMT_ERR_EOK; + len = cbor_encode_bytes_written(enc); err |= cbor_encoder_create_map(enc, &rsp, CborIndefiniteLength); @@ -102,8 +103,8 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, */ err |= cbor_encoder_create_indef_byte_string(&rsp, &str_encoder); for (off = 0; off < entry->len && !err; ) { - err |= cbor_encode_byte_string(&str_encoder, entry->data, rc); - off += rc; + err |= cbor_encode_byte_string(&str_encoder, entry->data, entry->len); + off += entry->len; } err |= cbor_encoder_close_container(&rsp, &str_encoder); @@ -119,10 +120,10 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, err |= cbor_encoder_close_container(enc, &rsp); if (out_len != NULL) { - *out_len = cbor_encode_bytes_written(enc); + *out_len = cbor_encode_bytes_written(enc) - len; } - return 0; + return MGMT_ERR_EOK; } static int @@ -164,9 +165,6 @@ log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) entry->type = LOG_ETYPE_STRING; snprintf((char *)entry->data, LOG_MGMT_BODY_LEN, "error: entry too large (%d bytes)", entry_len); - } else { - rc = OS_ENOMEM; - goto err; } return MGMT_ERR_EMSGSIZE; @@ -183,8 +181,6 @@ log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) ctxt->counter++; return 0; -err: - return rc; } static int From a29e2228fbbb58db38ee33db0668fb576a152dfd Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Mon, 24 Jun 2019 18:34:32 -0700 Subject: [PATCH 12/65] SMP: make multiple registration for same group possible --- mgmt/src/mgmt.c | 51 ++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/mgmt/src/mgmt.c b/mgmt/src/mgmt.c index ec4fe4fa..351f353e 100644 --- a/mgmt/src/mgmt.c +++ b/mgmt/src/mgmt.c @@ -70,29 +70,44 @@ mgmt_streamer_free_buf(struct mgmt_streamer *streamer, void *buf) streamer->cfg->free_buf(buf, streamer->cb_arg); } -void -mgmt_register_group(struct mgmt_group *group) -{ - if (mgmt_group_list_end == NULL) { - mgmt_group_list = group; - } else { - mgmt_group_list_end->mg_next = group; - } - mgmt_group_list_end = group; -} - static struct mgmt_group * -mgmt_find_group(uint16_t group_id) +mgmt_find_group(uint16_t group_id, uint16_t command_id) { struct mgmt_group *group; + /* + * Find the group with the specified group id, if one exists + * check the handler for the command id and make sure + * that is not NULL. If that is not set, look for the group + * with a command id that is set + */ for (group = mgmt_group_list; group != NULL; group = group->mg_next) { if (group->mg_group_id == group_id) { - return group; + if (command_id >= group->mg_handlers_count) { + return NULL; + } + + if (!group->mg_handlers[command_id].mh_read && + !group->mg_handlers[command_id].mh_write) { + continue; + } + + break; } } - return NULL; + return group; +} + +void +mgmt_register_group(struct mgmt_group *group) +{ + if (mgmt_group_list_end == NULL) { + mgmt_group_list = group; + } else { + mgmt_group_list_end->mg_next = group; + } + mgmt_group_list_end = group; } const struct mgmt_handler * @@ -100,12 +115,8 @@ mgmt_find_handler(uint16_t group_id, uint16_t command_id) { const struct mgmt_group *group; - group = mgmt_find_group(group_id); - if (group == NULL) { - return NULL; - } - - if (command_id >= group->mg_handlers_count) { + group = mgmt_find_group(group_id, command_id); + if (!group) { return NULL; } From 5d72448491c713c843f8db3f8619de89acaa03d0 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 26 Jun 2019 16:18:27 -0700 Subject: [PATCH 13/65] stat_mgmt: Add stat_mgmt support for mynewt --- cmd/stat_mgmt/pkg.yml | 29 +++++ cmd/stat_mgmt/port/mynewt/pkg.yml | 31 +++++ .../port/mynewt/src/mynewt_stat_mgmt.c | 109 ++++++++++++++++++ cmd/stat_mgmt/src/stat_mgmt.c | 6 +- cmd/stat_mgmt/syscfg.yml | 26 +++++ 5 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 cmd/stat_mgmt/pkg.yml create mode 100644 cmd/stat_mgmt/port/mynewt/pkg.yml create mode 100644 cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c create mode 100644 cmd/stat_mgmt/syscfg.yml diff --git a/cmd/stat_mgmt/pkg.yml b/cmd/stat_mgmt/pkg.yml new file mode 100644 index 00000000..99bbbbfb --- /dev/null +++ b/cmd/stat_mgmt/pkg.yml @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/stat_mgmt +pkg.description: 'OS management command handlers for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-core/kernel/os' + - '@apache-mynewt-mcumgr/cmd/stat_mgmt/port/mynewt' + - '@apache-mynewt-mcumgr/mgmt' diff --git a/cmd/stat_mgmt/port/mynewt/pkg.yml b/cmd/stat_mgmt/port/mynewt/pkg.yml new file mode 100644 index 00000000..fc9e87d1 --- /dev/null +++ b/cmd/stat_mgmt/port/mynewt/pkg.yml @@ -0,0 +1,31 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/stat_mgmt/port/mynewt +pkg.description: 'Statistics management command handlers for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-mcumgr/cmd/stat_mgmt' + - '@apache-mynewt-mcumgr/mgmt' + +pkg.init: + stat_mgmt_module_init: 501 diff --git a/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c b/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c new file mode 100644 index 00000000..bede2944 --- /dev/null +++ b/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +#include "stats/stats.h" +#include "mgmt/mgmt.h" +#include "sysinit/sysinit.h" +#include "stat_mgmt/stat_mgmt.h" +#include "stat_mgmt/stat_mgmt_impl.h" +#include "../../../src/stat_mgmt_config.h" + +struct mynewt_stat_mgmt_walk_arg { + stat_mgmt_foreach_entry_fn *cb; + void *arg; +}; + +int +stat_mgmt_impl_get_group(int idx, const char **out_name) +{ + const struct stats_hdr *cur; + int i; + + cur = NULL; + i = 0; + STAILQ_FOREACH(cur, &g_stats_registry, s_next) { + if (i > idx) { + break; + } + i++; + } + + *out_name = cur->s_name; + return 0; +} + +static int +mynewt_stat_mgmt_walk_cb(struct stats_hdr *hdr, void *arg, + char *name, uint16_t off) +{ + struct mynewt_stat_mgmt_walk_arg *walk_arg; + struct stat_mgmt_entry entry; + void *stat_val; + + walk_arg = arg; + + stat_val = (uint8_t *)hdr + off; + switch (hdr->s_size) { + case sizeof (uint16_t): + entry.value = *(uint16_t *) stat_val; + break; + case sizeof (uint32_t): + entry.value = *(uint32_t *) stat_val; + break; + case sizeof (uint64_t): + entry.value = *(uint64_t *) stat_val; + break; + default: + return MGMT_ERR_EUNKNOWN; + } + entry.name = name; + + return walk_arg->cb(&entry, walk_arg->arg); +} + +int +stat_mgmt_impl_foreach_entry(const char *group_name, + stat_mgmt_foreach_entry_fn *cb, + void *arg) +{ + struct mynewt_stat_mgmt_walk_arg walk_arg; + struct stats_hdr *hdr; + + hdr = stats_group_find(group_name); + if (hdr == NULL) { + return MGMT_ERR_ENOENT; + } + + walk_arg = (struct mynewt_stat_mgmt_walk_arg) { + .cb = cb, + .arg = arg, + }; + + return stats_walk(hdr, mynewt_stat_mgmt_walk_cb, &walk_arg); +} + +void +stat_mgmt_module_init(void) +{ + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + stat_mgmt_register_group(); +} diff --git a/cmd/stat_mgmt/src/stat_mgmt.c b/cmd/stat_mgmt/src/stat_mgmt.c index 4de33999..e7cec8be 100644 --- a/cmd/stat_mgmt/src/stat_mgmt.c +++ b/cmd/stat_mgmt/src/stat_mgmt.c @@ -68,7 +68,7 @@ stat_mgmt_cb_encode(struct stat_mgmt_entry *entry, void *arg) static int stat_mgmt_show(struct mgmt_ctxt *ctxt) { - char stat_name[CONFIG_STAT_MGMT_MAX_NAME_LEN]; + char stat_name[STAT_MGMT_MAX_NAME_LEN]; CborEncoder map_enc; CborError err; int rc; @@ -126,8 +126,8 @@ stat_mgmt_list(struct mgmt_ctxt *ctxt) int i; err = CborNoError; - err |= cbor_encode_text_stringz(&cb->encoder, "rc"); - err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK); + err |= cbor_encode_text_stringz(&ctxt->encoder, "rc"); + err |= cbor_encode_int(&ctxt->encoder, MGMT_ERR_EOK); err |= cbor_encode_text_stringz(&ctxt->encoder, "stat_list"); err |= cbor_encoder_create_array(&ctxt->encoder, &arr_enc, CborIndefiniteLength); diff --git a/cmd/stat_mgmt/syscfg.yml b/cmd/stat_mgmt/syscfg.yml new file mode 100644 index 00000000..5fd9f061 --- /dev/null +++ b/cmd/stat_mgmt/syscfg.yml @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + STAT_MGMT_MAX_NAME_LEN: + description: > + Limits the maximum stat group name length in mcumgr requests, in bytes. + A buffer of this size gets allocated on the stack during handling of all + stat read commands. If a stat group's name exceeds this limit, it will + be impossible to retrieve its values with a stat show command. + value: 32 From 6496426458574175eb1d0a60178e614ab380a92a Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 26 Jul 2019 17:20:15 -0700 Subject: [PATCH 14/65] img_mgmt: Make img_mgmt_slot_in_use() a public API --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 6 ++++++ cmd/img_mgmt/src/img_mgmt_priv.h | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index da9ad149..6354822e 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -79,6 +79,12 @@ int img_mgmt_read_info(int image_slot, struct image_version *ver, int img_mgmt_my_version(struct image_version *ver); +/** + * @brief Check if the image slot is in use + */ +int +img_mgmt_slot_in_use(int slot); + #ifdef __cplusplus } #endif diff --git a/cmd/img_mgmt/src/img_mgmt_priv.h b/cmd/img_mgmt/src/img_mgmt_priv.h index 80bff9b4..7e6e7840 100644 --- a/cmd/img_mgmt/src/img_mgmt_priv.h +++ b/cmd/img_mgmt/src/img_mgmt_priv.h @@ -77,7 +77,6 @@ int img_mgmt_core_list(struct mgmt_ctxt *); int img_mgmt_core_load(struct mgmt_ctxt *); int img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver); int img_mgmt_find_by_ver(struct image_version *find, uint8_t *hash); -int img_mgmt_slot_in_use(int slot); int img_mgmt_state_read(struct mgmt_ctxt *ctxt); int img_mgmt_state_write(struct mgmt_ctxt *njb); int img_mgmt_ver_str(const struct image_version *ver, char *dst); From 675e39bcf4413c467e792b62d54c261d82891259 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Mon, 29 Jul 2019 22:03:51 +0100 Subject: [PATCH 15/65] Added lazy erase support. --- cmd/img_mgmt/pkg.yml | 3 + .../port/mynewt/src/mynewt_img_mgmt.c | 58 +++++++++++++++++++ cmd/img_mgmt/src/img_mgmt.c | 3 + cmd/img_mgmt/syscfg.yml | 6 ++ 4 files changed, 70 insertions(+) diff --git a/cmd/img_mgmt/pkg.yml b/cmd/img_mgmt/pkg.yml index 82353bd1..cb7e1ffd 100644 --- a/cmd/img_mgmt/pkg.yml +++ b/cmd/img_mgmt/pkg.yml @@ -31,3 +31,6 @@ pkg.deps: - '@apache-mynewt-mcumgr/mgmt' - '@apache-mynewt-mcumgr/cborattr' - '@apache-mynewt-mcumgr/util' + +IMG_MGMT_LAZY_ERASE.cflags: + - "-DUPLOAD_LAZY_ERASE" diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c index 52988f74..423e5c03 100644 --- a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c @@ -26,6 +26,11 @@ #include "sysflash/sysflash.h" #include "img_mgmt/image.h" +static struct { + int sector_id; + uint32_t sector_end; +} upload_state; + int img_mgmt_impl_erase_slot(void) { @@ -162,11 +167,13 @@ img_mgmt_impl_read(int slot, unsigned int offset, void *dst, return 0; } +#if MYNEWT_VAL(IMG_MGMT_LAZY_ERASE) int img_mgmt_impl_write_image_data(unsigned int offset, const void *data, unsigned int num_bytes, bool last) { const struct flash_area *fa; + struct flash_area sector; int rc; rc = flash_area_open(FLASH_AREA_IMAGE_1, &fa); @@ -174,6 +181,25 @@ img_mgmt_impl_write_image_data(unsigned int offset, const void *data, return MGMT_ERR_EUNKNOWN; } + /* Check if there any unerased target sectors, if not clean them. */ + while ((fa->fa_off + offset + num_bytes) > upload_state.sector_end) { + rc = flash_area_getnext_sector(fa->fa_id, &upload_state.sector_id, + §or); + if (rc) { + goto err; + } + rc = flash_area_erase(§or, 0, sector.fa_size); + if (rc) { + goto err; + } + upload_state.sector_end = sector.fa_off + sector.fa_size; + } + + if (last) { + upload_state.sector_id = -1; + upload_state.sector_end = 0; + } + rc = flash_area_write(fa, offset, data, num_bytes); flash_area_close(fa); if (rc != 0) { @@ -181,8 +207,36 @@ img_mgmt_impl_write_image_data(unsigned int offset, const void *data, } return 0; + +err: + upload_state.sector_id = -1; + upload_state.sector_end = 0; + return MGMT_ERR_EUNKNOWN; } +#else +int +img_mgmt_impl_write_image_data(unsigned int offset, const void *data, + unsigned int num_bytes, bool last) +{ + const struct flash_area *fa; + int rc; + + rc = flash_area_open(FLASH_AREA_IMAGE_1, &fa); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + rc = flash_area_write(fa, offset, data, num_bytes); + flash_area_close(fa); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + return 0; +} +#endif + int img_mgmt_impl_swap_type(void) { @@ -215,4 +269,8 @@ img_mgmt_module_init(void) rc = imgr_cli_register(); SYSINIT_PANIC_ASSERT(rc == 0); #endif + + /* setup for lazy sector by sector erase */ + upload_state.sector_id = -1; + upload_state.sector_end = 0; } diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index 2fb02f66..9563eea9 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -349,10 +349,13 @@ img_mgmt_upload_first_chunk(struct mgmt_ctxt *ctxt, const uint8_t *req_data, return MGMT_ERR_ENOMEM; } + /* Don't pre-erase if the underlying implementation does lazy erase. */ +#ifndef UPLOAD_LAZY_ERASE rc = img_mgmt_impl_erase_slot(); if (rc != 0) { return rc; } +#endif img_mgmt_ctxt.uploading = true; img_mgmt_ctxt.off = 0; diff --git a/cmd/img_mgmt/syscfg.yml b/cmd/img_mgmt/syscfg.yml index 92e11dc6..387bd03c 100644 --- a/cmd/img_mgmt/syscfg.yml +++ b/cmd/img_mgmt/syscfg.yml @@ -25,6 +25,12 @@ syscfg.defs: command. value: 512 + IMG_MGMT_LAZY_ERASE: + description: > + During a firmware upgrade, erase flash a sector at a time + prior to writing to it, rather than all at once at start + value: 0 + OS_MGMT_TASKSTAT: description: > Enable support for taskstat command. From 7f034c4592177cd96a2f58e86f1a6613a29facb7 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Mon, 29 Jul 2019 22:15:26 +0100 Subject: [PATCH 16/65] Fix soft reset logging --- cmd/os_mgmt/pkg.yml | 3 +++ cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/os_mgmt/pkg.yml b/cmd/os_mgmt/pkg.yml index 3aa0e3ce..a497f9bf 100644 --- a/cmd/os_mgmt/pkg.yml +++ b/cmd/os_mgmt/pkg.yml @@ -28,5 +28,8 @@ pkg.deps: - '@apache-mynewt-mcumgr/cmd/os_mgmt/port/mynewt' - '@apache-mynewt-mcumgr/mgmt' +pkg.ign_files: + - "stubs.c" + pkg.init: os_mgmt_module_init: 501 diff --git a/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c b/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c index 492427a9..46fd6121 100644 --- a/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c +++ b/cmd/os_mgmt/port/mynewt/src/mynewt_os_mgmt.c @@ -104,13 +104,22 @@ os_mgmt_impl_task_info(int idx, struct os_mgmt_task_info *out_info) int os_mgmt_impl_reset(unsigned int delay_ms) { +#if MYNEWT_VAL(LOG_SOFT_RESET) + struct log_reboot_info info = { + .reason = HAL_RESET_REQUESTED, + .file = NULL, + .line = 0, + .pc = 0, + }; +#endif os_callout_init(&mynewt_os_mgmt_reset_callout, os_eventq_dflt_get(), mynewt_os_mgmt_reset_tmo, NULL); #if MYNEWT_VAL(LOG_SOFT_RESET) - log_reboot(HAL_RESET_REQUESTED); + log_reboot(&info); #endif - os_callout_reset(&mynewt_os_mgmt_reset_callout, delay_ms * OS_TICKS_PER_SEC / 1000); + os_callout_reset(&mynewt_os_mgmt_reset_callout, + delay_ms * OS_TICKS_PER_SEC / 1000); return 0; } From 8914f8755983bf5e08ce30a56e0c0660341978e5 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Mon, 29 Jul 2019 20:23:57 -0700 Subject: [PATCH 17/65] img_mgmt: Mynewt port update - Update mynewt port wrt features from mynewt-core - For flash functions define 'impl' functions - Make sure everything builds --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 126 ++++++ cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h | 54 +++ .../port/mynewt/src/mynewt_img_mgmt.c | 285 ++++++++++++- cmd/img_mgmt/src/img_mgmt.c | 401 +++++++++--------- 4 files changed, 665 insertions(+), 201 deletions(-) diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index 6354822e..e8d86bd6 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -21,12 +21,19 @@ #define H_IMG_MGMT_ #include +#include "../../src/img_mgmt_config.h" +#include "mgmt/mgmt.h" + struct image_version; #ifdef __cplusplus extern "C" { #endif +#define IMG_MGMT_MAX_IMGR 2 +#define IMG_MGMT_HASH_STR 48 +#define IMG_MGMT_DATA_SHA_LEN 32 /* SHA256 */ + /* * Image state flags */ @@ -63,6 +70,49 @@ extern "C" { #define IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE 2 extern int boot_current_slot; +extern struct img_mgmt_state g_img_mgmt_state; + +/** Represents an individual upload request. */ +struct img_mgmt_upload_req { + unsigned long long int off; /* -1 if unspecified */ + unsigned long long int size; /* -1 if unspecified */ + size_t data_len; + size_t data_sha_len; + uint8_t img_data[IMG_MGMT_UL_CHUNK_SIZE]; + uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN]; + bool upgrade; /* Only allow greater version numbers. */ +}; + +/** Global state for upload in progress. */ +struct img_mgmt_state { + /** Flash area being written; -1 if no upload in progress. */ + int area_id; + /** Flash offset of next chunk. */ + uint32_t off; + /** Total size of image data. */ + uint32_t size; + /** Hash of image data; used for resumption of a partial upload. */ + uint8_t data_sha_len; + uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN]; +#ifdef IMG_MGMT_LAZY_ERASE + int sector_id; + uint32_t sector_end; +#endif +}; + +/** Describes what to do during processing of an upload request. */ +struct img_mgmt_upload_action { + /** The total size of the image. */ + unsigned long long size; + /** The number of image bytes to write to flash. */ + int write_bytes; + /** The flash area to write to. */ + int area_id; + /** Whether to process the request; false if offset is wrong. */ + bool proceed; + /** Whether to erase the destination flash area. */ + bool erase; +}; /** * @brief Registers the image management command handler group. @@ -85,6 +135,82 @@ img_mgmt_my_version(struct image_version *ver); int img_mgmt_slot_in_use(int slot); +/** @brief Generic callback function for events */ +typedef void (*img_mgmt_dfu_cb)(void); + +/** Callback function pointers */ +typedef struct +{ + img_mgmt_dfu_cb dfu_started_cb; + img_mgmt_dfu_cb dfu_stopped_cb; + img_mgmt_dfu_cb dfu_pending_cb; + img_mgmt_dfu_cb dfu_confirmed_cb; +} img_mgmt_dfu_callbacks_t; + +/** @typedef img_mgmt_upload_fn + * @brief Application callback that is executed when an image upload request is + * received. + * + * The callback's return code determines whether the upload request is accepted + * or rejected. If the callback returns 0, processing of the upload request + * proceeds. If the callback returns nonzero, the request is rejected with a + * response containing an `rc` value equal to the return code. + * + * @param offset The offset specified by the incoming request. + * @param size The total size of the image being uploaded. + * @param arg Optional argument specified when the callback + * was configured. + * + * @return 0 if the upload request should be accepted; + * nonzero to reject the request with the + * specified status. + */ +typedef int img_mgmt_upload_fn(uint32_t offset, uint32_t size, void *arg); + +/** + * @brief Configures a callback that gets called whenever a valid image upload + * request is received. + * + * The callback's return code determines whether the upload request is accepted + * or rejected. If the callback returns 0, processing of the upload request + * proceeds. If the callback returns nonzero, the request is rejected with a + * response containing an `rc` value equal to the return code. + * + * @param cb The callback to execute on rx of an upload + * request. + * @param arg Optional argument that gets passed to the + * callback. + */ +void imgr_set_upload_cb(img_mgmt_upload_fn *cb, void *arg); +void img_mgmt_register_callbacks(const img_mgmt_dfu_callbacks_t *cb_struct); +void img_mgmt_dfu_stopped(void); +void img_mgmt_dfu_started(void); +void img_mgmt_dfu_pending(void); +void img_mgmt_dfu_confirmed(void); + +#ifdef IMG_MGMT_VERBOSE_ERR +int +img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn); +extern const char *img_mgmt_err_str_app_reject; +extern const char *img_mgmt_err_str_hdr_malformed; +extern const char *img_mgmt_err_str_magic_mismatch; +extern const char *img_mgmt_err_str_no_slot; +extern const char *img_mgmt_err_str_flash_open_failed; +extern const char *img_mgmt_err_str_flash_erase_failed; +extern const char *img_mgmt_err_str_flash_write_failed; +extern const char *img_mgmt_err_str_downgrade; +#else +#define img_mgmt_error_rsp(ctxt, rc, rsn) (rc) +#define img_mgmt_err_str_app_reject NULL +#define img_mgmt_err_str_hdr_malformed NULL +#define img_mgmt_err_str_magic_mismatch NULL +#define img_mgmt_err_str_no_slot NULL +#define img_mgmt_err_str_flash_open_failed NULL +#define img_mgmt_err_str_flash_erase_failed NULL +#define img_mgmt_err_str_flash_write_failed NULL +#define img_mgmt_err_str_downgrade NULL +#endif + #ifdef __cplusplus } #endif diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h index 1c28977c..fa1376cb 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h @@ -29,6 +29,7 @@ #include #include +#include "img_mgmt/img_mgmt.h" #ifdef __cplusplus extern "C" { @@ -110,6 +111,59 @@ int img_mgmt_impl_swap_type(void); */ uint8_t img_mgmt_state_flags(int query_slot); +/** + * Erases image data at given offset + * + * @param offset The offset within slot 1 to erase at. + * @param num_bytes The number of bytes to erase. + * @return 0 on success, MGMT_ERR_[...] code on failure. + */ +int +img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes); + +/** + * Erases a flash sector as image upload crosses a sector boundary. + * Erasing the entire flash size at one time can take significant time, + * causing a bluetooth disconnect or significant battery sag. + * Instead we will erase immediately prior to crossing a sector. + * We could check for empty to increase efficiency, but instead we always erase + * for consistency and simplicity. + * + * @param fa Flash area being traversed + * @param off Offset that is about to be written + * @param len Number of bytes to be written + * + * @return 0 if success + * ERROR_CODE if could not erase sector + */ +int +img_mgmt_impl_erase_if_needed(const void *fa, uint32_t off, uint32_t len); + +/** + * Verifies an upload request and indicates the actions that should be taken + * during processing of the request. This is a "read only" function in the + * sense that it doesn't write anything to flash and doesn't modify any global + * variables. + * + * @param req The upload request to inspect. + * @param action On success, gets populated with information + * about how to process the request. + * + * @return 0 if processing should occur; + * A MGMT_ERR code if an error response should be + * sent instead. + */ +int +img_mgmt_impl_upload_inspect(const struct img_mgmt_upload_req *req, + struct img_mgmt_upload_action *action, + const char **errstr); + +int +img_mgmt_impl_log_upload_start(int status); + +int +img_mgmt_impl_log_upload_done(int status, const uint8_t *hashp); + #ifdef __cplusplus } #endif diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c index 423e5c03..4e063758 100644 --- a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c @@ -31,6 +31,231 @@ static struct { uint32_t sector_end; } upload_state; +static int +img_mgmt_find_best_area_id(void) +{ + struct image_version ver; + int best = -1; + int i; + int rc; + + for (i = 0; i < 2; i++) { + rc = img_mgmt_read_info(i, &ver, NULL, NULL); + if (rc < 0) { + continue; + } + if (rc == 0) { + /* Image in slot is ok. */ + if (img_mgmt_slot_in_use(i)) { + /* Slot is in use; can't use this. */ + continue; + } else { + /* + * Not active slot, but image is ok. Use it if there are + * no better candidates. + */ + best = i; + } + continue; + } + best = i; + break; + } + if (best >= 0) { + best = flash_area_id_from_image_slot(best); + } + return best; +} + +/** + * Compares two image version numbers in a semver-compatible way. + * + * @param a The first version to compare. + * @param b The second version to compare. + * + * @return -1 if a < b + * @return 0 if a = b + * @return 1 if a > b + */ +static int +img_mgmt_vercmp(const struct image_version *a, const struct image_version *b) +{ + if (a->iv_major < b->iv_major) { + return -1; + } else if (a->iv_major > b->iv_major) { + return 1; + } + + if (a->iv_minor < b->iv_minor) { + return -1; + } else if (a->iv_minor > b->iv_minor) { + return 1; + } + + if (a->iv_revision < b->iv_revision) { + return -1; + } else if (a->iv_revision > b->iv_revision) { + return 1; + } + + /* Note: For semver compatibility, don't compare the 32-bit build num. */ + + return 0; +} + + +/** + * Verifies an upload request and indicates the actions that should be taken + * during processing of the request. This is a "read only" function in the + * sense that it doesn't write anything to flash and doesn't modify any global + * variables. + * + * @param req The upload request to inspect. + * @param action On success, gets populated with information + * about how to process the request. + * + * @return 0 if processing should occur; + * A MGMT_ERR code if an error response should be + * sent instead. + */ +int +img_mgmt_impl_upload_inspect(const struct img_mgmt_upload_req *req, + struct img_mgmt_upload_action *action, + const char **errstr) +{ + const struct image_header *hdr; + const struct flash_area *fa; + struct image_version cur_ver; + uint8_t rem_bytes; + bool empty; + int rc; + + memset(action, 0, sizeof *action); + + if (req->off == -1) { + /* Request did not include an `off` field. */ + *errstr = img_mgmt_err_str_hdr_malformed; + return MGMT_ERR_EINVAL; + } + + if (req->off == 0) { + /* First upload chunk. */ + if (req->data_len < sizeof(struct image_header)) { + /* + * Image header is the first thing in the image. + */ + *errstr = img_mgmt_err_str_hdr_malformed; + return MGMT_ERR_EINVAL; + } + + if (req->size == -1) { + /* Request did not include a `len` field. */ + *errstr = img_mgmt_err_str_hdr_malformed; + return MGMT_ERR_EINVAL; + } + action->size = req->size; + + hdr = (struct image_header *)req->img_data; + if (hdr->ih_magic != IMAGE_MAGIC) { + *errstr = img_mgmt_err_str_magic_mismatch; + return MGMT_ERR_EINVAL; + } + + if (req->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 ((req->data_sha_len > 0) && (g_img_mgmt_state.area_id != -1)) { + if ((g_img_mgmt_state.data_sha_len == req->data_sha_len) && + !memcmp(g_img_mgmt_state.data_sha, req->data_sha, + req->data_sha_len)) { + return 0; + } + } + + action->area_id = img_mgmt_find_best_area_id(); + if (action->area_id < 0) { + /* No slot where to upload! */ + *errstr = img_mgmt_err_str_no_slot; + return MGMT_ERR_ENOMEM; + } + + if (req->upgrade) { + /* User specified upgrade-only. Make sure new image version is + * greater than that of the currently running image. + */ + rc = img_mgmt_my_version(&cur_ver); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + if (img_mgmt_vercmp(&cur_ver, &hdr->ih_ver) >= 0) { + *errstr = img_mgmt_err_str_downgrade; + return MGMT_ERR_EBADSTATE; + } + } + +#if MYNEWT_VAL(IMG_MGMT_LAZY_ERASE) + (void) empty; +#else + rc = flash_area_open(action->area_id, &fa); + if (rc) { + *errstr = img_mgmt_err_str_flash_open_failed; + return MGMT_ERR_EUNKNOWN; + } + + rc = flash_area_is_empty(fa, &empty); + flash_area_close(fa); + if (rc) { + return MGMT_ERR_EUNKNOWN; + } + + action->erase = !empty; +#endif + } else { + /* Continuation of upload. */ + action->area_id = g_img_mgmt_state.area_id; + action->size = g_img_mgmt_state.size; + + if (req->off != g_img_mgmt_state.off) { + /* + * Invalid offset. Drop the data, and respond with the offset we're + * expecting data for. + */ + return 0; + } + } + + /* Calculate size of flash write. */ + action->write_bytes = req->data_len; + if (req->off + req->data_len < action->size) { + /* + * Respect flash write alignment if not in the last block + */ + rc = flash_area_open(action->area_id, &fa); + if (rc) { + *errstr = img_mgmt_err_str_flash_open_failed; + return MGMT_ERR_EUNKNOWN; + } + + rem_bytes = req->data_len % flash_area_align(fa); + flash_area_close(fa); + + if (rem_bytes) { + action->write_bytes -= rem_bytes; + } + } + + action->proceed = true; + return 0; +} + int img_mgmt_impl_erase_slot(void) { @@ -237,6 +462,50 @@ img_mgmt_impl_write_image_data(unsigned int offset, const void *data, } #endif +int +img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes) +{ + const struct flash_area *fa; + int rc; + + rc = flash_area_open(FLASH_AREA_IMAGE_1, &fa); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + rc = flash_area_erase(fa, off, num_bytes); + flash_area_close(fa); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + return 0; +} + +#if MYNEWT_VAL(IMGMGR_LAZY_ERASE) +int +img_mgmt_impl_erase_if_needed(const void *fa, uint32_t off, uint32_t len) +{ + int rc = 0; + struct flash_area sector; + const struct flash_area *cfa; + + cfa = (const struct flash_area *)fa; + while ((cfa->fa_off + off + len) > g_img_mgmt_state.sector_end) { + rc = flash_area_getnext_sector(cfa->fa_id, &g_img_mgmt_state.sector_id, §or); + if (rc) { + return rc; + } + rc = flash_area_erase(§or, 0, sector.fa_size); + if (rc) { + return rc; + } + g_img_mgmt_state.sector_end = sector.fa_off + sector.fa_size; + } + return 0; +} +#endif + int img_mgmt_impl_swap_type(void) { @@ -266,7 +535,7 @@ img_mgmt_module_init(void) #if MYNEWT_VAL(IMGMGR_CLI) int rc; - rc = imgr_cli_register(); + rc = img_mgmt_cli_register(); SYSINIT_PANIC_ASSERT(rc == 0); #endif @@ -274,3 +543,17 @@ img_mgmt_module_init(void) upload_state.sector_id = -1; upload_state.sector_end = 0; } + +int +img_mgmt_impl_log_upload_start(int status) +{ + return 0; +} + +int +img_mgmt_impl_log_upload_done(int status, const uint8_t *hashp) +{ + return 0; +} + + diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index 9563eea9..e482da08 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -34,6 +34,12 @@ static mgmt_handler_fn img_mgmt_upload; static mgmt_handler_fn img_mgmt_erase; +static img_mgmt_upload_fn *img_mgmt_upload_cb; +static void *img_mgmt_upload_arg; + +const img_mgmt_dfu_callbacks_t *img_mgmt_dfu_callbacks_fn; + +struct img_mgmt_state g_img_mgmt_state; static const struct mgmt_handler img_mgmt_handlers[] = { [IMG_MGMT_ID_STATE] = { @@ -59,20 +65,16 @@ static struct mgmt_group img_mgmt_group = { .mg_group_id = MGMT_GROUP_ID_IMAGE, }; -static struct { - /* Whether an upload is currently in progress. */ - bool uploading; - - /** Expected offset of next upload request. */ - size_t off; - - /** 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; +#if IMG_MGMT_VERBOSE_ERR +const char *img_mgmt_err_str_app_reject = "app reject"; +const char *img_mgmt_err_str_hdr_malformed = "header malformed"; +const char *img_mgmt_err_str_magic_mismatch = "magic mismatch"; +const char *img_mgmt_err_str_no_slot = "no slot"; +const char *img_mgmt_err_str_flash_open_failed = "fa open fail"; +const char *img_mgmt_err_str_flash_erase_failed = "fa erase fail"; +const char *img_mgmt_err_str_flash_write_failed = "fa write fail"; +const char *img_mgmt_err_str_downgrade = "downgrade"; +#endif /** * Finds the TLVs in the specified image slot, if any. @@ -229,6 +231,22 @@ img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver) return -1; } +#ifdef IMG_MGMT_VERBOSE_ERR +int +img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn) +{ + /* + * This is an error response so returning a different error when failed to + * encode other error probably does not make much sense - just ignore errors + * here. + */ + cbor_encode_text_stringz(&ctxt->encoder, "rsn"); + cbor_encode_text_stringz(&ctxt->encoder, rsn); + + return rc; +} +#endif + /** * Command handler: image erase */ @@ -253,124 +271,62 @@ img_mgmt_erase(struct mgmt_ctxt *ctxt) return MGMT_ERR_ENOMEM; } - /* reset uploading information on erase */ - img_mgmt_ctxt.uploading = false; - return 0; } -/** - * Encodes an image upload response. - */ static int -img_mgmt_encode_upload_rsp(struct mgmt_ctxt *ctxt, int status) +img_mgmt_upload_good_rsp(struct mgmt_ctxt *ctxt) { - CborError err; + CborError err = CborNoError; - err = 0; err |= cbor_encode_text_stringz(&ctxt->encoder, "rc"); - err |= cbor_encode_int(&ctxt->encoder, status); + err |= cbor_encode_int(&ctxt->encoder, MGMT_ERR_EOK); err |= cbor_encode_text_stringz(&ctxt->encoder, "off"); - err |= cbor_encode_int(&ctxt->encoder, img_mgmt_ctxt.off); + err |= cbor_encode_int(&ctxt->encoder, g_img_mgmt_state.off); if (err != 0) { return MGMT_ERR_ENOMEM; } - 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; } /** - * Compares two image version numbers in a semver-compatible way. + * Logs an upload request if necessary. * - * @param a The first version to compare. - * @param b The second version to compare. + * @param is_first Whether the request includes the first chunk of + * the image. + * @param is_last Whether the request includes the last chunk of + * the image. + * @param status The result of processing the upload request + * (MGMT_ERR code). * - * @return -1 if a < b - * @return 0 if a = b - * @return 1 if a > b - */ -static int -imgr_vercmp(const struct image_version *a, const struct image_version *b) -{ - if (a->iv_major < b->iv_major) { - return -1; - } else if (a->iv_major > b->iv_major) { - return 1; - } - - if (a->iv_minor < b->iv_minor) { - return -1; - } else if (a->iv_minor > b->iv_minor) { - return 1; - } - - if (a->iv_revision < b->iv_revision) { - return -1; - } else if (a->iv_revision > b->iv_revision) { - return 1; - } - - /* Note: For semver compativility, don't compare the 32-bit build num. */ - - 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. + * @return 0 on success; nonzero on failure. */ 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) +img_mgmt_upload_log(bool is_first, bool is_last, int status) { + uint8_t hash[IMAGE_HASH_LEN]; + const uint8_t *hashp; int rc; - if (img_mgmt_slot_in_use(1)) { - /* No free slot. */ - return MGMT_ERR_ENOMEM; - } - - /* Don't pre-erase if the underlying implementation does lazy erase. */ -#ifndef UPLOAD_LAZY_ERASE - rc = img_mgmt_impl_erase_slot(); - if (rc != 0) { - return rc; + if (is_first) { + return img_mgmt_impl_log_upload_start(status); } -#endif - img_mgmt_ctxt.uploading = true; - img_mgmt_ctxt.off = 0; - img_mgmt_ctxt.len = 0; + if (is_last || status != 0) { + /* Log the image hash if we know it. */ + rc = img_mgmt_read_info(1, NULL, hash, NULL); + if (rc != 0) { + hashp = NULL; + } else { + hashp = hash; + } - /* - * 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 img_mgmt_impl_log_upload_done(status, hashp); + } + /* Nothing to log. */ return 0; } @@ -380,160 +336,205 @@ img_mgmt_upload_first_chunk(struct mgmt_ctxt *ctxt, const uint8_t *req_data, static int img_mgmt_upload(struct mgmt_ctxt *ctxt) { - struct mgmt_evt_op_cmd_status_arg cmd_status_arg; - 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; - struct image_version cur_ver; - struct image_header new_hdr; - unsigned long long len; - unsigned long long off; - size_t data_len; - size_t new_off; - bool upgrade; - bool last; - int rc; + struct img_mgmt_upload_req req = { + .off = -1, + .size = -1, + .data_len = 0, + .data_sha_len = 0, + .upgrade = false, + }; - const struct cbor_attr_t upload_attr[] = { + const struct cbor_attr_t off_attr[] = { [0] = { .attribute = "data", .type = CborAttrByteStringType, - .addr.bytestring.data = img_mgmt_data, - .addr.bytestring.len = &data_len, - .len = sizeof(img_mgmt_data) + .addr.bytestring.data = req.img_data, + .addr.bytestring.len = &req.data_len, + .len = sizeof(req.img_data) }, [1] = { .attribute = "len", .type = CborAttrUnsignedIntegerType, - .addr.uinteger = &len, + .addr.uinteger = &req.size, .nodefault = true }, [2] = { .attribute = "off", .type = CborAttrUnsignedIntegerType, - .addr.uinteger = &off, + .addr.uinteger = &req.off, .nodefault = true }, [3] = { .attribute = "sha", .type = CborAttrByteStringType, - .addr.bytestring.data = data_sha, - .addr.bytestring.len = &data_sha_len, - .len = sizeof(data_sha) + .addr.bytestring.data = req.data_sha, + .addr.bytestring.len = &req.data_sha_len, + .len = sizeof(req.data_sha) }, [4] = { .attribute = "upgrade", .type = CborAttrBooleanType, - .addr.boolean = &upgrade, + .addr.boolean = &req.upgrade, .dflt.boolean = false, }, [5] = { 0 }, }; + int rc; + const char *errstr = NULL; + struct img_mgmt_upload_action action; - len = ULLONG_MAX; - off = ULLONG_MAX; - data_len = 0; - rc = cbor_read_object(&ctxt->it, upload_attr); - if (rc || off == ULLONG_MAX) { + rc = cbor_read_object(&ctxt->it, off_attr); + if (rc != 0) { return MGMT_ERR_EINVAL; } - if (off == 0) { - /* Total image length is a required field in the first request. */ - if (len == ULLONG_MAX) { - return MGMT_ERR_EINVAL; - } + /* Determine what actions to take as a result of this request. */ + rc = img_mgmt_impl_upload_inspect(&req, &action, &errstr); + if (rc != 0) { + img_mgmt_dfu_stopped(); + return rc; + } - rc = img_mgmt_check_header(img_mgmt_data, data_len); - if (rc) { - return rc; - } + if (!action.proceed) { + /* Request specifies incorrect offset. Respond with a success code and + * the correct offset. + */ + return img_mgmt_upload_good_rsp(ctxt); + } - /* Reject if SHA len is to big */ - if (data_sha_len > IMG_MGMT_DATA_SHA_LEN) { - return MGMT_ERR_EINVAL; + /* Request is valid. Give the application a chance to reject this upload + * request. + */ + if (img_mgmt_upload_cb != NULL) { + rc = img_mgmt_upload_cb(req.off, action.size, img_mgmt_upload_arg); + if (rc != 0) { + errstr = img_mgmt_err_str_app_reject; + goto end; } + } - cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_START; + /* Remember flash area ID and image size for subsequent upload requests. */ + g_img_mgmt_state.area_id = action.area_id; + g_img_mgmt_state.size = action.size; + if (req.off == 0) { /* - * 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. + * New upload. */ - 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)) { - goto done; - } - } - - if (upgrade) { - /* User specified upgrade-only. Make sure new image version is - * greater than that of the currently running image. - */ - rc = img_mgmt_read_info(0, &cur_ver, NULL, NULL); - if (rc != 0) { - return MGMT_ERR_EUNKNOWN; - } + g_img_mgmt_state.off = 0; - memcpy(&new_hdr, img_mgmt_data, sizeof new_hdr); + img_mgmt_dfu_started(); - if (imgr_vercmp(&cur_ver, &new_hdr.ih_ver) >= 0) { - return MGMT_ERR_EBADSTATE; + /* + * 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. + */ + g_img_mgmt_state.data_sha_len = req.data_sha_len; + memcpy(g_img_mgmt_state.data_sha, req.data_sha, req.data_sha_len); + memset(&g_img_mgmt_state.data_sha[req.data_sha_len], 0, + IMG_MGMT_DATA_SHA_LEN - req.data_sha_len); + +#ifdef IMG_MGMT_LAZY_ERASE + /* setup for lazy sector by sector erase */ + g_img_mgmt_state.sector_id = -1; + g_img_mgmt_state.sector_end = 0; +#else + /* erase the entire req.size all at once */ + if (action.erase) { + rc = img_mgmt_impl_erase_image_data(0, req.size); + if (rc != 0) { + rc = MGMT_ERR_EUNKNOWN; + errstr = img_mgmt_err_str_flash_erase_failed; + goto end; } } +#endif + } - rc = img_mgmt_upload_first_chunk(ctxt, img_mgmt_data, data_len, - data_sha, data_sha_len); - if (rc != 0) { - return rc; + /* Write the image data to flash. */ + if (req.data_len != 0) { +#ifdef IMG_MGMT_LAZY_ERASE + /* erase as we cross sector boundaries */ + if (img_mgmt_impl_erase_if_needed(req.off, action.write_bytes) != 0) { + rc = MGMT_ERR_EUNKNOWN; + errstr = img_mgmt_err_str_flash_erase_failed; + goto end; } - img_mgmt_ctxt.len = len; - } else { - if (!img_mgmt_ctxt.uploading) { - return MGMT_ERR_EINVAL; +#endif + rc = img_mgmt_impl_write_image_data(req.off, req.img_data, action.write_bytes, 0); + if (rc != 0) { + rc = MGMT_ERR_EUNKNOWN; + errstr = img_mgmt_err_str_flash_write_failed; + goto end; + } else { + g_img_mgmt_state.off += action.write_bytes; + if (g_img_mgmt_state.off == g_img_mgmt_state.size) { + /* Done */ + img_mgmt_dfu_pending(); + g_img_mgmt_state.area_id = -1; + } } + } - cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_ONGOING; +end: - if (off != img_mgmt_ctxt.off) { - /* Invalid offset. Drop the data and send the expected offset. */ - goto done; - } + img_mgmt_upload_log(req.off == 0, g_img_mgmt_state.off == g_img_mgmt_state.size, rc); + + if (rc != 0) { + img_mgmt_dfu_stopped(); + return img_mgmt_error_rsp(ctxt, rc, errstr); } - new_off = img_mgmt_ctxt.off + data_len; - if (new_off > img_mgmt_ctxt.len) { - /* Data exceeds image length. */ - return MGMT_ERR_EINVAL; + return img_mgmt_upload_good_rsp(ctxt); +} + +void +img_mgmt_dfu_stopped(void) +{ + if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_stopped_cb) { + img_mgmt_dfu_callbacks_fn->dfu_stopped_cb(); } - last = new_off == img_mgmt_ctxt.len; +} - if (data_len > 0) { - rc = img_mgmt_impl_write_image_data(off, img_mgmt_data, data_len, - last); - if (rc != 0) { - return rc; - } +void +img_mgmt_dfu_started(void) +{ + if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_started_cb) { + img_mgmt_dfu_callbacks_fn->dfu_started_cb(); } +} - img_mgmt_ctxt.off = new_off; - if (last) { - /* Upload complete. */ - img_mgmt_ctxt.uploading = false; +void +img_mgmt_dfu_pending(void) +{ + if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_pending_cb) { + img_mgmt_dfu_callbacks_fn->dfu_pending_cb(); + } +} - cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE; +void +img_mgmt_dfu_confirmed(void) +{ + if (img_mgmt_dfu_callbacks_fn && img_mgmt_dfu_callbacks_fn->dfu_confirmed_cb) { + img_mgmt_dfu_callbacks_fn->dfu_confirmed_cb(); } +} -done: - mgmt_evt(MGMT_EVT_OP_CMD_STATUS, MGMT_GROUP_ID_IMAGE, IMG_MGMT_ID_UPLOAD, - &cmd_status_arg); +void +img_mgmt_set_upload_cb(img_mgmt_upload_fn *cb, void *arg) +{ + img_mgmt_upload_cb = cb; + img_mgmt_upload_arg = arg; +} - return img_mgmt_encode_upload_rsp(ctxt, 0); +void +img_mgmt_register_callbacks(const img_mgmt_dfu_callbacks_t *cb_struct) +{ + img_mgmt_dfu_callbacks_fn = cb_struct; } + int img_mgmt_my_version(struct image_version *ver) { From 724c256df1eac1e5d3b4bfd8fc84686bc068c8de Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 31 Jul 2019 15:11:14 -0700 Subject: [PATCH 18/65] img_mgmt: Fix build --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 6 +++--- cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h | 3 +-- .../port/mynewt/src/mynewt_img_mgmt.c | 17 +++++++--------- cmd/img_mgmt/src/img_mgmt.c | 20 ++++++++++++++----- cmd/img_mgmt/src/img_mgmt_config.h | 4 ++++ cmd/img_mgmt/syscfg.yml | 11 +++------- cmd/os_mgmt/syscfg.yml | 10 ++++++++++ 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index e8d86bd6..5570f4fd 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -94,7 +94,7 @@ struct img_mgmt_state { /** Hash of image data; used for resumption of a partial upload. */ uint8_t data_sha_len; uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN]; -#ifdef IMG_MGMT_LAZY_ERASE +#if IMG_MGMT_LAZY_ERASE int sector_id; uint32_t sector_end; #endif @@ -188,7 +188,7 @@ void img_mgmt_dfu_started(void); void img_mgmt_dfu_pending(void); void img_mgmt_dfu_confirmed(void); -#ifdef IMG_MGMT_VERBOSE_ERR +#if IMG_MGMT_VERBOSE_ERR int img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn); extern const char *img_mgmt_err_str_app_reject; @@ -200,7 +200,7 @@ extern const char *img_mgmt_err_str_flash_erase_failed; extern const char *img_mgmt_err_str_flash_write_failed; extern const char *img_mgmt_err_str_downgrade; #else -#define img_mgmt_error_rsp(ctxt, rc, rsn) (rc) +#define img_mgmt_error_rsp(ctxt, rc, rsn) (rc) #define img_mgmt_err_str_app_reject NULL #define img_mgmt_err_str_hdr_malformed NULL #define img_mgmt_err_str_magic_mismatch NULL diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h index fa1376cb..ab5a69ba 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h @@ -129,7 +129,6 @@ img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes); * We could check for empty to increase efficiency, but instead we always erase * for consistency and simplicity. * - * @param fa Flash area being traversed * @param off Offset that is about to be written * @param len Number of bytes to be written * @@ -137,7 +136,7 @@ img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes); * ERROR_CODE if could not erase sector */ int -img_mgmt_impl_erase_if_needed(const void *fa, uint32_t off, uint32_t len); +img_mgmt_impl_erase_if_needed(uint32_t off, uint32_t len); /** * Verifies an upload request and indicates the actions that should be taken diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c index 4e063758..a66c0e4a 100644 --- a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c @@ -482,15 +482,19 @@ img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes) return 0; } -#if MYNEWT_VAL(IMGMGR_LAZY_ERASE) +#if MYNEWT_VAL(IMG_MGMT_LAZY_ERASE) int -img_mgmt_impl_erase_if_needed(const void *fa, uint32_t off, uint32_t len) +img_mgmt_impl_erase_if_needed(uint32_t off, uint32_t len) { int rc = 0; struct flash_area sector; const struct flash_area *cfa; - cfa = (const struct flash_area *)fa; + rc = flash_area_open(FLASH_AREA_IMAGE_1, &cfa); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + while ((cfa->fa_off + off + len) > g_img_mgmt_state.sector_end) { rc = flash_area_getnext_sector(cfa->fa_id, &g_img_mgmt_state.sector_id, §or); if (rc) { @@ -532,13 +536,6 @@ img_mgmt_module_init(void) img_mgmt_register_group(); -#if MYNEWT_VAL(IMGMGR_CLI) - int rc; - - rc = img_mgmt_cli_register(); - SYSINIT_PANIC_ASSERT(rc == 0); -#endif - /* setup for lazy sector by sector erase */ upload_state.sector_id = -1; upload_state.sector_end = 0; diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index e482da08..0141d36c 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -231,7 +231,7 @@ img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver) return -1; } -#ifdef IMG_MGMT_VERBOSE_ERR +#if IMG_MGMT_VERBOSE_ERR int img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn) { @@ -242,7 +242,6 @@ img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn) */ cbor_encode_text_stringz(&ctxt->encoder, "rsn"); cbor_encode_text_stringz(&ctxt->encoder, rsn); - return rc; } #endif @@ -336,6 +335,7 @@ img_mgmt_upload_log(bool is_first, bool is_last, int status) static int img_mgmt_upload(struct mgmt_ctxt *ctxt) { + struct mgmt_evt_op_cmd_status_arg cmd_status_arg; struct img_mgmt_upload_req req = { .off = -1, .size = -1, @@ -382,6 +382,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) int rc; const char *errstr = NULL; struct img_mgmt_upload_action action; + bool last = false; rc = cbor_read_object(&ctxt->it, off_attr); if (rc != 0) { @@ -424,6 +425,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) g_img_mgmt_state.off = 0; img_mgmt_dfu_started(); + cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_START; /* * We accept SHA trimmed to any length by client since it's up to client @@ -435,7 +437,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) memset(&g_img_mgmt_state.data_sha[req.data_sha_len], 0, IMG_MGMT_DATA_SHA_LEN - req.data_sha_len); -#ifdef IMG_MGMT_LAZY_ERASE +#if IMG_MGMT_LAZY_ERASE /* setup for lazy sector by sector erase */ g_img_mgmt_state.sector_id = -1; g_img_mgmt_state.sector_end = 0; @@ -454,7 +456,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) /* Write the image data to flash. */ if (req.data_len != 0) { -#ifdef IMG_MGMT_LAZY_ERASE +#if IMG_MGMT_LAZY_ERASE /* erase as we cross sector boundaries */ if (img_mgmt_impl_erase_if_needed(req.off, action.write_bytes) != 0) { rc = MGMT_ERR_EUNKNOWN; @@ -462,7 +464,12 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) goto end; } #endif - rc = img_mgmt_impl_write_image_data(req.off, req.img_data, action.write_bytes, 0); + /* If this is the last chunk */ + if (g_img_mgmt_state.off + req.data_len == g_img_mgmt_state.size) { + last = true; + } + + rc = img_mgmt_impl_write_image_data(req.off, req.img_data, action.write_bytes, last); if (rc != 0) { rc = MGMT_ERR_EUNKNOWN; errstr = img_mgmt_err_str_flash_write_failed; @@ -472,6 +479,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) if (g_img_mgmt_state.off == g_img_mgmt_state.size) { /* Done */ img_mgmt_dfu_pending(); + cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_ONGOING; g_img_mgmt_state.area_id = -1; } } @@ -480,6 +488,8 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) end: img_mgmt_upload_log(req.off == 0, g_img_mgmt_state.off == g_img_mgmt_state.size, rc); + mgmt_evt(MGMT_EVT_OP_CMD_STATUS, MGMT_GROUP_ID_IMAGE, IMG_MGMT_ID_UPLOAD, + &cmd_status_arg); if (rc != 0) { img_mgmt_dfu_stopped(); diff --git a/cmd/img_mgmt/src/img_mgmt_config.h b/cmd/img_mgmt/src/img_mgmt_config.h index a520372f..66fb2185 100644 --- a/cmd/img_mgmt/src/img_mgmt_config.h +++ b/cmd/img_mgmt/src/img_mgmt_config.h @@ -25,10 +25,14 @@ #include "syscfg/syscfg.h" #define IMG_MGMT_UL_CHUNK_SIZE MYNEWT_VAL(IMG_MGMT_UL_CHUNK_SIZE) +#define IMG_MGMT_VERBOSE_ERR MYNEWT_VAL(IMG_MGMT_VERBOSE_ERR) +#define IMG_MGMT_LAZY_ERASE MYNEWT_VAL(IMG_MGMT_LAZY_ERASE) #elif defined __ZEPHYR__ #define IMG_MGMT_UL_CHUNK_SIZE CONFIG_IMG_MGMT_UL_CHUNK_SIZE +#define IMG_MGMT_VERBOSE_ERR CONFIG_IMG_MGMT_VERBOSE_ERR +#define IMG_MGMT_LAZY_ERASE CONFIG_IMG_MGMT_LAZY_ERASE #else diff --git a/cmd/img_mgmt/syscfg.yml b/cmd/img_mgmt/syscfg.yml index 387bd03c..6bf6129d 100644 --- a/cmd/img_mgmt/syscfg.yml +++ b/cmd/img_mgmt/syscfg.yml @@ -30,13 +30,8 @@ syscfg.defs: During a firmware upgrade, erase flash a sector at a time prior to writing to it, rather than all at once at start value: 0 - - OS_MGMT_TASKSTAT: - description: > - Enable support for taskstat command. - value: 1 - OS_MGMT_ECHO: + IMG_MGMT_VERBOSE_ERR: description: > - Enable support for echo command. - value: 1 + Enable verbose logging during a firmware upgrade + value: 0 diff --git a/cmd/os_mgmt/syscfg.yml b/cmd/os_mgmt/syscfg.yml index 7ecb7c09..ef6bb0bb 100644 --- a/cmd/os_mgmt/syscfg.yml +++ b/cmd/os_mgmt/syscfg.yml @@ -24,3 +24,13 @@ syscfg.defs: milliseconds before performing the reset. This delay allows time for the mcumgr response to be delivered. value: 250 + + OS_MGMT_TASKSTAT: + description: > + Enable support for taskstat command. + value: 1 + + OS_MGMT_ECHO: + description: > + Enable support for echo command. + value: 1 From f7e2f1c77fa18b6c729e88b5543dc03fd8b66821 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 13 Aug 2019 14:31:18 -0700 Subject: [PATCH 19/65] cmd/img_mgmt: Add doxygen comments for img_mgmt --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 61 ++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index 5570f4fd..ff15b1b4 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -118,23 +118,84 @@ struct img_mgmt_upload_action { * @brief Registers the image management command handler group. */ void img_mgmt_register_group(void); + /** * @brief Read info of an image give the slot number + * + * @param image_slot Image slot to read info from + * @param image_version Image version to be filled up + * @param hash Ptr to the read image hash + * @param flags Ptr to flags filled up from the image */ int img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags); + /** * @brief Get the current running image version + * + * @param image_version Given image version + * + * @return 0 on success, non-zero on failure */ int img_mgmt_my_version(struct image_version *ver); +/** + * @brief Get image version in string from image_version + * + * @param image_version Structure filled with image version + * information + * @param dst Destination string created from the given + * in image version + * + * @return 0 on success, non-zero on failure + */ +int +img_mgmt_ver_str(const struct image_version *ver, char *dst); + /** * @brief Check if the image slot is in use + * + * @param slot Slot to check if its in use + * + * @return 0 on success, non-zero on failure */ int img_mgmt_slot_in_use(int slot); +/** + * @brief Collects information about the specified image slot + * + * @param query_slot Slot to read state flags from + * + * @return return the state flags + */ +uint8_t +img_mgmt_state_flags(int query_slot); + +/** + * @brief Sets the pending flag for the specified image slot. That is, the system + * will swap to the specified image on the next reboot. If the permanent + * argument is specified, the system doesn't require a confirm after the swap + * occurs. + * + * @param slot Image slot to set pending + * @param permanent If set no confirm is required after image swap + * + * @return 0 on success, non-zero on failure + */ +int +img_mgmt_state_set_pending(int slot, int permanent); + +/** + * Confirms the current image state. Prevents a fallback from occurring on the + * next reboot if the active image is currently being tested. + * + * @return 0 on success, non -zero on failure + */ +int +img_mgmt_state_confirm(void); + /** @brief Generic callback function for events */ typedef void (*img_mgmt_dfu_cb)(void); From edb23c0855fdd7941dd1e74176e7bf952d9fb998 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 16 Aug 2019 14:23:56 -0700 Subject: [PATCH 20/65] samples/smp_svr: Fix smp_svr for apache-mynewt --- samples/smp_svr/mynewt/pkg.yml | 28 ++-- samples/smp_svr/mynewt/src/gatt_svr.c | 204 ++++++++++++++++++++++++++ samples/smp_svr/mynewt/src/main.c | 3 +- samples/smp_svr/mynewt/src/smp_svr.h | 61 ++++++++ 4 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 samples/smp_svr/mynewt/src/gatt_svr.c create mode 100644 samples/smp_svr/mynewt/src/smp_svr.h diff --git a/samples/smp_svr/mynewt/pkg.yml b/samples/smp_svr/mynewt/pkg.yml index 5ab44e3d..e28e674c 100644 --- a/samples/smp_svr/mynewt/pkg.yml +++ b/samples/smp_svr/mynewt/pkg.yml @@ -23,20 +23,20 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - '@apache-mynewt-core/boot/bootutil' - - '@apache-mynewt-core/mgmt/newtmgr/transport/ble' - - '@apache-mynewt-core/mgmt/newtmgr/transport/nmgr_shell' - - '@apache-mynewt-core/net/nimble/controller' - - '@apache-mynewt-core/net/nimble/host' - - '@apache-mynewt-core/net/nimble/host/services/ans' - - '@apache-mynewt-core/net/nimble/host/services/gap' - - '@apache-mynewt-core/net/nimble/host/services/gatt' - - '@apache-mynewt-core/net/nimble/host/store/config' - - '@apache-mynewt-core/net/nimble/transport/ram' + - '@mcuboot/boot/bootutil' + - '@apache-mynewt-core/mgmt/smp/transport/ble' + - '@apache-mynewt-core/mgmt/smp/transport/smp_shell' + - '@apache-mynewt-nimble/nimble/controller' + - '@apache-mynewt-nimble/nimble/host' + - '@apache-mynewt-nimble/nimble/host/services/ans' + - '@apache-mynewt-nimble/nimble/host/services/gap' + - '@apache-mynewt-nimble/nimble/host/services/gatt' + - '@apache-mynewt-nimble/nimble/host/store/config' + - '@apache-mynewt-nimble/nimble/transport/ram' - '@apache-mynewt-core/sys/console/full' - '@apache-mynewt-core/sys/log/full' - '@apache-mynewt-core/sys/stats/full' - - '@mynewt-mcumgr/cmd/fs_mgmt' - - '@mynewt-mcumgr/cmd/img_mgmt' - - '@mynewt-mcumgr/cmd/os_mgmt' - - '@mynewt-mcumgr/smp' + - '@apache-mynewt-mcumgr/cmd/fs_mgmt' + - '@apache-mynewt-mcumgr/cmd/img_mgmt' + - '@apache-mynewt-mcumgr/cmd/os_mgmt' + - '@apache-mynewt-mcumgr/smp' diff --git a/samples/smp_svr/mynewt/src/gatt_svr.c b/samples/smp_svr/mynewt/src/gatt_svr.c new file mode 100644 index 00000000..5d4fa7ae --- /dev/null +++ b/samples/smp_svr/mynewt/src/gatt_svr.c @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include "bsp/bsp.h" +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "smp_svr.h" + +/** + * The vendor specific security test service consists of two characteristics: + * o random-number-generator: generates a random 32-bit number each time + * it is read. This characteristic can only be read over an encrypted + * connection. + * o static-value: a single-byte characteristic that can always be read, + * but can only be written over an encrypted connection. + */ + +/* 59462f12-9543-9999-12c8-58b459a2712d */ +static const ble_uuid128_t gatt_svr_svc_sec_test_uuid = + BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, + 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); + +/* 5c3a659e-897e-45e1-b016-007107c96df6 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid = + BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +/* 5c3a659e-897e-45e1-b016-007107c96df7 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid = + BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +static uint8_t gatt_svr_sec_test_static_val; + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + /*** Service: Security test. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc_sec_test_uuid.u, + .characteristics = (struct ble_gatt_chr_def[]) { { + /*** Characteristic: Random number generator. */ + .uuid = &gatt_svr_chr_sec_test_rand_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, + }, { + /*** Characteristic: Static value. */ + .uuid = &gatt_svr_chr_sec_test_static_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, + + { + 0, /* No more services. */ + }, +}; + +static int +gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) +{ + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + return 0; +} + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + const ble_uuid_t *uuid; + int rand_num; + int rc; + + uuid = ctxt->chr->uuid; + + /* Determine which characteristic is being accessed by examining its + * 128-bit UUID. + */ + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) { + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + + /* Respond with a 32-bit random number. */ + rand_num = rand(); + rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) { + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + rc = gatt_svr_chr_write(ctxt->om, + sizeof gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val, + &gatt_svr_sec_test_static_val, NULL); + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + } + + /* Unknown characteristic; the nimble stack should not have called this + * function. + */ + assert(0); + return BLE_ATT_ERR_UNLIKELY; +} + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + MODLOG_DFLT(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +int +gatt_svr_init(void) +{ + int rc; + + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/samples/smp_svr/mynewt/src/main.c b/samples/smp_svr/mynewt/src/main.c index 19d5f915..3e6ccacb 100755 --- a/samples/smp_svr/mynewt/src/main.c +++ b/samples/smp_svr/mynewt/src/main.c @@ -34,6 +34,7 @@ #include "nimble/ble.h" #include "host/ble_hs.h" #include "services/gap/ble_svc_gap.h" +#include "smp_svr.h" /* smp_svr uses the first "peruser" log module. */ #define SMP_SVR_LOG_MODULE (LOG_MODULE_PERUSER + 0) @@ -294,8 +295,6 @@ main(void) LOG_SYSLEVEL); /* Initialize the NimBLE host configuration. */ - log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL, - LOG_SYSLEVEL); ble_hs_cfg.reset_cb = smp_svr_on_reset; ble_hs_cfg.sync_cb = smp_svr_on_sync; ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; diff --git a/samples/smp_svr/mynewt/src/smp_svr.h b/samples/smp_svr/mynewt/src/smp_svr.h new file mode 100644 index 00000000..5ec34610 --- /dev/null +++ b/samples/smp_svr/mynewt/src/smp_svr.h @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLEPRPH_ +#define H_BLEPRPH_ + +#include +#include "nimble/ble.h" +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +/** GATT server. */ +#define GATT_SVR_SVC_ALERT_UUID 0x1811 +#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define GATT_SVR_CHR_NEW_ALERT 0x2A46 +#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +/* PHY support */ +#if MYNEWT_VAL(BLEPRPH_LE_PHY_SUPPORT) +#define CONN_HANDLE_INVALID 0xffff + +void phy_init(void); +void phy_conn_changed(uint16_t handle); +void phy_update(uint8_t phy); +#endif + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_addr(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif From a826909611beae963669124dd59737af4cc58b27 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Mon, 19 Aug 2019 16:10:21 -0700 Subject: [PATCH 21/65] smp_srv: Add capability to read UICR - Read UICR to check for a configured address before advertising - Remove the ANS service UUID so that we do not connect to devices running blecent --- samples/smp_svr/mynewt/pkg.yml | 1 + samples/smp_svr/mynewt/src/main.c | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/samples/smp_svr/mynewt/pkg.yml b/samples/smp_svr/mynewt/pkg.yml index e28e674c..f0226406 100644 --- a/samples/smp_svr/mynewt/pkg.yml +++ b/samples/smp_svr/mynewt/pkg.yml @@ -28,6 +28,7 @@ pkg.deps: - '@apache-mynewt-core/mgmt/smp/transport/smp_shell' - '@apache-mynewt-nimble/nimble/controller' - '@apache-mynewt-nimble/nimble/host' + - '@apache-mynewt-nimble/nimble/host/util' - '@apache-mynewt-nimble/nimble/host/services/ans' - '@apache-mynewt-nimble/nimble/host/services/gap' - '@apache-mynewt-nimble/nimble/host/services/gatt' diff --git a/samples/smp_svr/mynewt/src/main.c b/samples/smp_svr/mynewt/src/main.c index 3e6ccacb..3f890d07 100755 --- a/samples/smp_svr/mynewt/src/main.c +++ b/samples/smp_svr/mynewt/src/main.c @@ -35,6 +35,7 @@ #include "host/ble_hs.h" #include "services/gap/ble_svc_gap.h" #include "smp_svr.h" +#include "host/util/util.h" /* smp_svr uses the first "peruser" log module. */ #define SMP_SVR_LOG_MODULE (LOG_MODULE_PERUSER + 0) @@ -93,11 +94,19 @@ smp_svr_print_conn_desc(struct ble_gap_conn_desc *desc) static void smp_svr_advertise(void) { + uint8_t own_addr_type; struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; const char *name; int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } /** * Set the advertisement data included in our advertisements: * o Flags (indicates advertisement type and other general info). @@ -127,12 +136,6 @@ smp_svr_advertise(void) fields.name_len = strlen(name); fields.name_is_complete = 1; - fields.uuids16 = (ble_uuid16_t[]){ - BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID) - }; - fields.num_uuids16 = 1; - fields.uuids16_is_complete = 1; - rc = ble_gap_adv_set_fields(&fields); if (rc != 0) { SMP_SVR_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc); @@ -143,7 +146,7 @@ smp_svr_advertise(void) memset(&adv_params, 0, sizeof adv_params); adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, smp_svr_gap_event, NULL); if (rc != 0) { SMP_SVR_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc); @@ -270,6 +273,12 @@ smp_svr_on_reset(int reason) static void smp_svr_on_sync(void) { + int rc; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + /* Begin advertising. */ smp_svr_advertise(); } From e012ffed30e5f1064f04807a5e9fbcce8eb1d132 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 21 Aug 2019 17:10:24 -0700 Subject: [PATCH 22/65] cboratttr,cmd/img_mgmt: Fix tests --- cborattr/test/pkg.yml | 8 +++++--- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 1 + cmd/img_mgmt/src/img_mgmt.c | 26 ++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/cborattr/test/pkg.yml b/cborattr/test/pkg.yml index 071ca5f5..eb8d5479 100644 --- a/cborattr/test/pkg.yml +++ b/cborattr/test/pkg.yml @@ -23,8 +23,10 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - '@mynewt-mcumgr/ext/tinycbor' - - '@mynewt-mcumgr/cborattr' + - '@apache-mynewt-core/encoding/tinycbor' + - '@apache-mynewt-mcumgr/cborattr' pkg.deps.SELFTEST: - - sys/console/stub + - '@apache-mynewt-core/sys/console/stub' + - '@apache-mynewt-core/sys/log/full' + - '@apache-mynewt-core/test/testutil' diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index ff15b1b4..5b80ba2a 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -32,6 +32,7 @@ extern "C" { #define IMG_MGMT_MAX_IMGR 2 #define IMG_MGMT_HASH_STR 48 +#define IMG_MGMT_HASH_LEN 32 #define IMG_MGMT_DATA_SHA_LEN 32 /* SHA256 */ /* diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index 0141d36c..c95ca61a 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -30,8 +30,6 @@ #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; static img_mgmt_upload_fn *img_mgmt_upload_cb; @@ -110,6 +108,30 @@ int img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags) { + +#if MYNEWT_VAL(IMGMGR_DUMMY_HDR) + uint8_t dummy_hash[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; + + if (!hash && !ver && !flags) { + return 0; + } + + if (hash) { + memcpy(hash, dummy_hash, IMG_MGMT_HASH_LEN); + } + + if (ver) { + memset(ver, 0xff, sizeof *ver); + } + + if (flags) { + *flags = 0; + } + + return 0; +#endif + struct image_header hdr; struct image_tlv tlv; size_t data_off; From fcd690482944f0ebb4bf9cfa267300c2124a0dd1 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 31 Jul 2019 15:11:14 -0700 Subject: [PATCH 23/65] omp: wip - oicmgr + omp_streamer --- omp/include/omp/omp_streamer.h | 94 +++++++++++++ omp/pkg.yml | 35 +++++ omp/src/omp.c | 245 +++++++++++++++++++++++++++++++++ omp/syscfg.yml | 19 +++ 4 files changed, 393 insertions(+) create mode 100644 omp/include/omp/omp_streamer.h create mode 100644 omp/pkg.yml create mode 100644 omp/src/omp.c create mode 100644 omp/syscfg.yml diff --git a/omp/include/omp/omp_streamer.h b/omp/include/omp/omp_streamer.h new file mode 100644 index 00000000..9dc97cec --- /dev/null +++ b/omp/include/omp/omp_streamer.h @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @file + * @brief OMP - OIC Management Protocol. + * XXX: REVIEW THIS + * + * OMP is an OIC implementation of SMP, a basic protocol that sits on top of + * the mgmt layer. SMP requests and responses have the following format: + * + * [Offset 0]: Mgmt header + * [Offset 8]: CBOR map of command-specific key-value pairs. + * + * SMP request packets may contain multiple concatenated requests. Each + * request must start at an offset that is a multiple of 4, so padding should + * be inserted between requests as necessary. Requests are processed + * sequentially from the start of the packet to the end. Each response is sent + * individually in its own packet. If a request elicits an error response, + * processing of the packet is aborted. + */ + +#ifndef H_OMP_ +#define H_OMP_ + +#include "mgmt/mgmt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct omp_streamer; +struct mgmt_hdr; + +/** @typedef smp_tx_rsp_fn + * @brief Transmits an OMP response packet. + * + * @param ss The streamer to transmit via. + * @param buf Buffer containing the response packet. + * @param arg Optional streamer argument. + * + * @return 0 on success, MGMT_ERR_[...] code on failure. + */ +typedef void omp_tx_rsp_fn(struct mgmt_ctxt *ctxt, void *request, int retval); + +/** + * @brief Decodes, encodes, and transmits SMP packets. + */ +struct omp_streamer { + struct mgmt_streamer mgmt_stmr; + omp_tx_rsp_fn *tx_rsp_cb; + struct CborEncoder rsp_encoder; +}; + +/** + * @brief Processes a single OMP request packet and sends all corresponding + * responses. + * + * Processes all OMP requests in an incoming packet. Requests are processed + * sequentially from the start of the packet to the end. Each response is sent + * individually in its own packet. If a request elicits an error response, + * processing of the packet is aborted. This function consumes the supplied + * request buffer regardless of the outcome. + * + * @param streamer The streamer providing the required OMP + * callbacks. + * @param req The request packet to process. + * + * @return 0 on success, MGMT_ERR_[...] code on failure. + */ +int omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, + void *req); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OMP_ */ diff --git a/omp/pkg.yml b/omp/pkg.yml new file mode 100644 index 00000000..415f33f8 --- /dev/null +++ b/omp/pkg.yml @@ -0,0 +1,35 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: omp +pkg.description: Server-side SMP functionality for OIC +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - omp + - oicmgr + - mgmt + +pkg.deps: + - "@apache-mynewt-core/kernel/os" + - mgmt + - "@apache-mynewt-core/mgmt/smp/smp_os" + +pkg.apis: + - smp diff --git a/omp/src/omp.c b/omp/src/omp.c new file mode 100644 index 00000000..34504685 --- /dev/null +++ b/omp/src/omp.c @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +#include "os/mynewt.h" + +#include +#include +#include +#include + +#include "omp/omp_streamer.h" +/* #include */ + +/* struct omgr_ctxt { */ +/* struct mgmt_ctxt ob_mc; */ +/* struct cbor_mbuf_reader ob_reader; */ +/* }; */ + +/* struct omgr_state { */ +/* struct omgr_ctxt os_ctxt; /\* CBOR buffer for MGMT task *\/ */ +/* }; */ + +/* static struct omgr_state omgr_state; */ + +static int +omp_encode_mgmt_hdr(struct CborEncoder *enc, struct mgmt_hdr hdr) +{ + int rc; + + rc = cbor_encode_text_string(enc, "_h", 2); + if (rc != 0) { + return MGMT_ERR_ENOMEM; + } + + hdr.nh_len = htons(hdr.nh_len); + hdr.nh_group = htons(hdr.nh_group); + + /* Encode the MGMT header in the response. */ + rc = cbor_encode_byte_string(enc, (void *)&hdr, sizeof hdr); + if (rc != 0) { + return MGMT_ERR_ENOMEM; + } + + return 0; +} + +static int +omp_send_err_rsp(struct CborEncoder *enc, + const struct mgmt_hdr *hdr, + int mgmt_status) +{ + int rc; + + rc = omp_encode_mgmt_hdr(enc, *hdr); + if (rc != 0) { + return rc; + } + + rc = cbor_encode_text_stringz(enc, "rc"); + if (rc != 0) { + return MGMT_ERR_ENOMEM; + } + + rc = cbor_encode_int(enc, mgmt_status); + if (rc != 0) { + return MGMT_ERR_ENOMEM; + } + + return 0; +} + +static int +omp_read_hdr(struct CborValue *cv, struct mgmt_hdr *out_hdr) +{ + size_t hlen; + int rc; + + struct cbor_attr_t attrs[] = { + [0] = { + .attribute = "_h", + .type = CborAttrByteStringType, + .addr.bytestring.data = (void *)out_hdr, + .addr.bytestring.len = &hlen, + .nodefault = 1, + .len = sizeof *out_hdr, + }, + [1] = { 0 } + }; + + rc = cbor_read_object(cv, attrs); + if (rc != 0 || hlen != sizeof *out_hdr) { + return MGMT_ERR_EINVAL; + } + + out_hdr->nh_len = ntohs(out_hdr->nh_len); + out_hdr->nh_group = ntohs(out_hdr->nh_group); + + return 0; +} + +static int +omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr, + struct mgmt_ctxt *ctxt) +{ + int rc = 0; + bool rsp_hdr_filled = false; + const struct mgmt_handler *handler; + + handler = mgmt_find_handler(req_hdr->nh_group, req_hdr->nh_id); + if (handler == NULL) { + rc = MGMT_ERR_ENOENT; + goto done; + } + + switch (req_hdr->nh_op) { + case MGMT_OP_READ: + if (handler->mh_read == NULL) { + rc = MGMT_ERR_ENOENT; + } else { + rsp_hdr->nh_op = MGMT_OP_READ_RSP; + /* mgmt_evt(MGMT_EVT_OP_CMD_RECV, */ + /* req_hdr->nh_group, */ + /* req_hdr->nh_id, */ + /* NULL); */ + rc = handler->mh_read(ctxt); + } + break; + + case MGMT_OP_WRITE: + if (handler->mh_write == NULL) { + rc = MGMT_ERR_ENOENT; + } else { + rsp_hdr->nh_op = MGMT_OP_WRITE_RSP; + /* mgmt_evt(MGMT_EVT_OP_CMD_RECV, */ + /* req_hdr->nh_group, */ + /* req_hdr->nh_id, */ + /* NULL); */ + rc = handler->mh_write(ctxt); + } + break; + + default: + rc = MGMT_ERR_EINVAL; + break; + } + if (rc != 0) { + goto done; + } else { + rsp_hdr_filled = true; + } + + /* Encode the MGMT header in the response. */ + rc = omp_encode_mgmt_hdr(&ctxt->encoder, *rsp_hdr); + if (rc != 0) { + rc = MGMT_ERR_ENOMEM; + } + +done: + if (rc != 0) { + if (rsp_hdr_filled) { + rc = omp_send_err_rsp(&ctxt->encoder, rsp_hdr, rc); + } + } + return rc; +} + +int +omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, + void *req) +{ + struct mgmt_ctxt ctxt; + struct mgmt_hdr req_hdr, rsp_hdr; + struct os_mbuf *m_rsp; + int rc = 0; + + rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); + assert(rc == 0); + + + rc = cbor_parser_init(streamer->mgmt_stmr.reader, 0, &ctxt.parser, &ctxt.it); + assert(rc == 0); + /* rc = mgmt_ctxt_init(&ctxt, &streamer->mgmt_stmr); */ + /* assert(rc == 0); */ + + rc = omp_read_hdr(&ctxt.it, &req_hdr); + assert(rc == 0); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + + } + + rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); + assert(rc == 0); + rc = cbor_parser_init(streamer->mgmt_stmr.reader, 0, &ctxt.parser, &ctxt.it); + assert(rc == 0); + + + m_rsp = mgmt_streamer_alloc_rsp(&streamer->mgmt_stmr, m); + assert(m_rsp != NULL); + + rc = mgmt_streamer_init_writer(&streamer->mgmt_stmr, m_rsp); + assert(rc == 0); + + cbor_encoder_init(&streamer->rsp_encoder, streamer->mgmt_stmr.writer, 0); + rc = cbor_encoder_create_map(&streamer->rsp_encoder, + &ctxt.encoder, + CborIndefiniteLength); + assert(rc == 0); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + } + + + rc = omp_process_mgmt_hdr(&req_hdr,&rsp_hdr, &ctxt); + assert(rc == 0); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + } + + cbor_encoder_close_container(&streamer->rsp_encoder, &ctxt.encoder); + streamer->tx_rsp_cb(&ctxt, req, rc); + return rc; +} diff --git a/omp/syscfg.yml b/omp/syscfg.yml new file mode 100644 index 00000000..01c2e77f --- /dev/null +++ b/omp/syscfg.yml @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +syscfg.defs: From b5d5f49acebc15b69791030e1652f159483b22f7 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Mon, 26 Aug 2019 17:35:39 -0700 Subject: [PATCH 24/65] omp_svr: Add app for omp_svr --- samples/omp_svr/mynewt/pkg.yml | 43 +++++ samples/omp_svr/mynewt/src/main.c | 301 ++++++++++++++++++++++++++++++ samples/omp_svr/mynewt/syscfg.yml | 39 ++++ 3 files changed, 383 insertions(+) create mode 100644 samples/omp_svr/mynewt/pkg.yml create mode 100644 samples/omp_svr/mynewt/src/main.c create mode 100644 samples/omp_svr/mynewt/syscfg.yml diff --git a/samples/omp_svr/mynewt/pkg.yml b/samples/omp_svr/mynewt/pkg.yml new file mode 100644 index 00000000..f0226406 --- /dev/null +++ b/samples/omp_svr/mynewt/pkg.yml @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +pkg.name: samples/smp_svr/mynewt +pkg.type: app +pkg.description: Simple BLE peripheral running an mcumgr SMP server. +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@mcuboot/boot/bootutil' + - '@apache-mynewt-core/mgmt/smp/transport/ble' + - '@apache-mynewt-core/mgmt/smp/transport/smp_shell' + - '@apache-mynewt-nimble/nimble/controller' + - '@apache-mynewt-nimble/nimble/host' + - '@apache-mynewt-nimble/nimble/host/util' + - '@apache-mynewt-nimble/nimble/host/services/ans' + - '@apache-mynewt-nimble/nimble/host/services/gap' + - '@apache-mynewt-nimble/nimble/host/services/gatt' + - '@apache-mynewt-nimble/nimble/host/store/config' + - '@apache-mynewt-nimble/nimble/transport/ram' + - '@apache-mynewt-core/sys/console/full' + - '@apache-mynewt-core/sys/log/full' + - '@apache-mynewt-core/sys/stats/full' + - '@apache-mynewt-mcumgr/cmd/fs_mgmt' + - '@apache-mynewt-mcumgr/cmd/img_mgmt' + - '@apache-mynewt-mcumgr/cmd/os_mgmt' + - '@apache-mynewt-mcumgr/smp' diff --git a/samples/omp_svr/mynewt/src/main.c b/samples/omp_svr/mynewt/src/main.c new file mode 100644 index 00000000..15755254 --- /dev/null +++ b/samples/omp_svr/mynewt/src/main.c @@ -0,0 +1,301 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "os/mynewt.h" +#include +#include +#include +#include +#include +#include +#include +#if MYNEWT_VAL(SPLIT_LOADER) +#include "split/split.h" +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef ARCH_sim +#include +#endif + +/* Task 1 */ +#define TASK1_PRIO (8) +#define TASK1_STACK_SIZE OS_STACK_ALIGN(192) +#define MAX_CBMEM_BUF 600 +static struct os_task task1; +static volatile int g_task1_loops; + +/* Task 2 */ +#define TASK2_PRIO (9) +#define TASK2_STACK_SIZE OS_STACK_ALIGN(64) +static struct os_task task2; + +static struct log my_log; + +static volatile int g_task2_loops; + +/* Global test semaphore */ +static struct os_sem g_test_sem; + +/* For LED toggling */ +static int g_led_pin; + +STATS_SECT_START(gpio_stats) +STATS_SECT_ENTRY(toggles) +STATS_SECT_END + +static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle; + +static STATS_NAME_START(gpio_stats) +STATS_NAME(gpio_stats, toggles) +STATS_NAME_END(gpio_stats) + +static char *test_conf_get(int argc, char **argv, char *val, int max_len); +static int test_conf_set(int argc, char **argv, char *val); +static int test_conf_commit(void); +static int test_conf_export(void (*export_func)(char *name, char *val), + enum conf_export_tgt tgt); + +static struct conf_handler test_conf_handler = { + .ch_name = "test", + .ch_get = test_conf_get, + .ch_set = test_conf_set, + .ch_commit = test_conf_commit, + .ch_export = test_conf_export +}; + +static uint8_t test8; +static uint8_t test8_shadow; +static char test_str[32]; +static uint32_t cbmem_buf[MAX_CBMEM_BUF]; +static struct cbmem cbmem; + +static char * +test_conf_get(int argc, char **argv, char *buf, int max_len) +{ + if (argc == 1) { + if (!strcmp(argv[0], "8")) { + return conf_str_from_value(CONF_INT8, &test8, buf, max_len); + } else if (!strcmp(argv[0], "str")) { + return test_str; + } + } + return NULL; +} + +static int +test_conf_set(int argc, char **argv, char *val) +{ + if (argc == 1) { + if (!strcmp(argv[0], "8")) { + return CONF_VALUE_SET(val, CONF_INT8, test8_shadow); + } else if (!strcmp(argv[0], "str")) { + return CONF_VALUE_SET(val, CONF_STRING, test_str); + } + } + return OS_ENOENT; +} + +static int +test_conf_commit(void) +{ + test8 = test8_shadow; + + return 0; +} + +static int +test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt) +{ + char buf[4]; + + conf_str_from_value(CONF_INT8, &test8, buf, sizeof(buf)); + func("test/8", buf); + func("test/str", test_str); + return 0; +} + +void +task1_handler(void *arg) +{ + struct os_task *t; + int prev_pin_state, curr_pin_state; + struct image_version ver; + + /* Set the led pin for the E407 devboard */ + g_led_pin = LED_BLINK_PIN; + hal_gpio_init_out(g_led_pin, 1); + + if (imgr_my_version(&ver) == 0) { + console_printf("\nOMP_SVR %u.%u.%u.%u\n", + ver.iv_major, ver.iv_minor, ver.iv_revision, + (unsigned int)ver.iv_build_num); + } else { + console_printf("\nOMP_SVR\n"); + } + + while (1) { + t = os_sched_get_current_task(); + assert(t->t_func == task1_handler); + + ++g_task1_loops; + + /* Wait one second */ + os_time_delay(OS_TICKS_PER_SEC); + + /* Toggle the LED */ + prev_pin_state = hal_gpio_read(g_led_pin); + curr_pin_state = hal_gpio_toggle(g_led_pin); + MODLOG_DFLT(INFO, "GPIO toggle from %u to %u", + prev_pin_state, curr_pin_state); + STATS_INC(g_stats_gpio_toggle, toggles); + + /* Release semaphore to task 2 */ + os_sem_release(&g_test_sem); + } +} + +void +task2_handler(void *arg) +{ + struct os_task *t; + + while (1) { + /* just for debug; task 2 should be the running task */ + t = os_sched_get_current_task(); + assert(t->t_func == task2_handler); + + /* Increment # of times we went through task loop */ + ++g_task2_loops; + + /* Wait for semaphore from ISR */ + os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER); + } +} + +/* + * OIC platform/resource registration. + */ +static void +omgr_app_init(void) +{ + oc_init_platform("MyNewt", NULL, NULL); + /* + oc_add_device("/oic/d", "oic.d.light", "MynewtLed", "1.0", "1.0", NULL, + NULL); + */ +} + +static const oc_handler_t omgr_oc_handler = { + .init = omgr_app_init, +}; + +/** + * init_tasks + * + * Called by main.c after sysinit(). This function performs initializations + * that are required before tasks are running. + * + * @return int 0 success; error otherwise. + */ +static void +init_tasks(void) +{ + os_stack_t *pstack; + /* Initialize global test semaphore */ + os_sem_init(&g_test_sem, 0); + + pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE); + assert(pstack); + + os_task_init(&task1, "task1", task1_handler, NULL, + TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE); + + pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE); + assert(pstack); + + os_task_init(&task2, "task2", task2_handler, NULL, + TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE); + + oc_main_init((oc_handler_t *)&omgr_oc_handler); +} + +/** + * main + * + * The main task for the project. This function initializes the packages, calls + * init_tasks to initialize additional tasks (and possibly other objects), + * then starts serving events from default event queue. + * + * @return int NOTE: this function should never return! + */ +int +main(int argc, char **argv) +{ + int rc; + +#ifdef ARCH_sim + mcu_sim_parse_args(argc, argv); +#endif + + sysinit(); + + rc = conf_register(&test_conf_handler); + assert(rc == 0); + + cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF); + log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL); + + /* Point the default module at the cbmem log just registered. */ + rc = modlog_register(LOG_MODULE_DEFAULT, &my_log, LOG_LEVEL_DEBUG, NULL); + assert(rc == 0); + + stats_init(STATS_HDR(g_stats_gpio_toggle), + STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32), + STATS_NAME_INIT_PARMS(gpio_stats)); + + stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle)); + + reboot_start(hal_reset_cause()); + +#if MYNEWT_VAL(SPLIT_LOADER) + { + void *entry; + rc = split_app_go(&entry, true); + if(rc == 0) { + hal_system_start(entry); + } + } +#endif + + init_tasks(); + + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + /* Never returns */ + + return rc; +} diff --git a/samples/omp_svr/mynewt/syscfg.yml b/samples/omp_svr/mynewt/syscfg.yml new file mode 100644 index 00000000..1445d42c --- /dev/null +++ b/samples/omp_svr/mynewt/syscfg.yml @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Package: apps/omp_svr + +syscfg.vals: + # Disable central and observer roles. + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 1 + + # Log reboot messages to a flash circular buffer. + REBOOT_LOG_FCB: 1 + LOG_FCB: 1 + CONFIG_FCB: 1 + + # OS main/default task + OS_MAIN_STACK_SIZE: 468 + + # Lots of smaller mbufs are required for newtmgr using typical BLE ATT MTU + # values. + MSYS_1_BLOCK_COUNT: 22 + MSYS_1_BLOCK_SIZE: 110 From 8be59d9c27763c2980ba5da870b1cbbe79221ece Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Tue, 27 Aug 2019 15:20:07 +0100 Subject: [PATCH 25/65] write map not breaking anymore --- omp/include/omp/omp_streamer.h | 2 +- omp/src/omp.c | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/omp/include/omp/omp_streamer.h b/omp/include/omp/omp_streamer.h index 9dc97cec..58e89a00 100644 --- a/omp/include/omp/omp_streamer.h +++ b/omp/include/omp/omp_streamer.h @@ -65,7 +65,7 @@ typedef void omp_tx_rsp_fn(struct mgmt_ctxt *ctxt, void *request, int retval); struct omp_streamer { struct mgmt_streamer mgmt_stmr; omp_tx_rsp_fn *tx_rsp_cb; - struct CborEncoder rsp_encoder; + struct CborEncoder *rsp_encoder; }; /** diff --git a/omp/src/omp.c b/omp/src/omp.c index 34504685..d84fde48 100644 --- a/omp/src/omp.c +++ b/omp/src/omp.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "omp/omp_streamer.h" /* #include */ @@ -194,12 +193,8 @@ omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); assert(rc == 0); - - rc = cbor_parser_init(streamer->mgmt_stmr.reader, 0, &ctxt.parser, &ctxt.it); assert(rc == 0); - /* rc = mgmt_ctxt_init(&ctxt, &streamer->mgmt_stmr); */ - /* assert(rc == 0); */ rc = omp_read_hdr(&ctxt.it, &req_hdr); assert(rc == 0); @@ -220,10 +215,10 @@ omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, rc = mgmt_streamer_init_writer(&streamer->mgmt_stmr, m_rsp); assert(rc == 0); - - cbor_encoder_init(&streamer->rsp_encoder, streamer->mgmt_stmr.writer, 0); - rc = cbor_encoder_create_map(&streamer->rsp_encoder, - &ctxt.encoder, + + //cbor_encoder_init(&streamer->rsp_encoder, streamer->mgmt_stmr.writer, 0); + rc = cbor_encoder_create_map(streamer->rsp_encoder, //encoder + &ctxt.encoder, //mapEncoder CborIndefiniteLength); assert(rc == 0); if (rc != 0) { @@ -231,15 +226,15 @@ omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, return rc; } - - rc = omp_process_mgmt_hdr(&req_hdr,&rsp_hdr, &ctxt); + rc = omp_process_mgmt_hdr(&req_hdr, &rsp_hdr, &ctxt); assert(rc == 0); if (rc != 0) { rc = MGMT_ERR_EINVAL; return rc; } - cbor_encoder_close_container(&streamer->rsp_encoder, &ctxt.encoder); + rc = cbor_encoder_close_container(streamer->rsp_encoder, &ctxt.encoder); + assert(rc == 0); streamer->tx_rsp_cb(&ctxt, req, rc); return rc; } From 36ba8d25abb19af39def0b05fb33effb39fbbd24 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Tue, 27 Aug 2019 21:26:24 +0100 Subject: [PATCH 26/65] omp now working propperly --- omp/src/omp.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/omp/src/omp.c b/omp/src/omp.c index d84fde48..14636722 100644 --- a/omp/src/omp.c +++ b/omp/src/omp.c @@ -136,10 +136,6 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr, rc = MGMT_ERR_ENOENT; } else { rsp_hdr->nh_op = MGMT_OP_READ_RSP; - /* mgmt_evt(MGMT_EVT_OP_CMD_RECV, */ - /* req_hdr->nh_group, */ - /* req_hdr->nh_id, */ - /* NULL); */ rc = handler->mh_read(ctxt); } break; @@ -149,10 +145,6 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr, rc = MGMT_ERR_ENOENT; } else { rsp_hdr->nh_op = MGMT_OP_WRITE_RSP; - /* mgmt_evt(MGMT_EVT_OP_CMD_RECV, */ - /* req_hdr->nh_group, */ - /* req_hdr->nh_id, */ - /* NULL); */ rc = handler->mh_write(ctxt); } break; @@ -188,7 +180,6 @@ omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, { struct mgmt_ctxt ctxt; struct mgmt_hdr req_hdr, rsp_hdr; - struct os_mbuf *m_rsp; int rc = 0; rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); @@ -204,19 +195,13 @@ omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, } + memcpy(&rsp_hdr, &req_hdr, sizeof(struct mgmt_hdr)); + rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); assert(rc == 0); rc = cbor_parser_init(streamer->mgmt_stmr.reader, 0, &ctxt.parser, &ctxt.it); assert(rc == 0); - - m_rsp = mgmt_streamer_alloc_rsp(&streamer->mgmt_stmr, m); - assert(m_rsp != NULL); - - rc = mgmt_streamer_init_writer(&streamer->mgmt_stmr, m_rsp); - assert(rc == 0); - - //cbor_encoder_init(&streamer->rsp_encoder, streamer->mgmt_stmr.writer, 0); rc = cbor_encoder_create_map(streamer->rsp_encoder, //encoder &ctxt.encoder, //mapEncoder CborIndefiniteLength); @@ -235,6 +220,7 @@ omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, rc = cbor_encoder_close_container(streamer->rsp_encoder, &ctxt.encoder); assert(rc == 0); + streamer->tx_rsp_cb(&ctxt, req, rc); return rc; } From abc5a1a461f59a53fb5831e6126282df90c465cf Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 27 Aug 2019 15:23:44 -0700 Subject: [PATCH 27/65] Add capability to talkt to the omp_svr over BLE - Add capability to talk to the omp_svr over BLE and shell --- samples/omp_svr/mynewt/pkg.yml | 22 ++- samples/omp_svr/mynewt/src/gatt_svr.c | 204 ++++++++++++++++++++ samples/omp_svr/mynewt/src/main.c | 265 +++++++++++++++++++++++++- samples/omp_svr/mynewt/src/misc.c | 43 +++++ samples/omp_svr/mynewt/src/omp_svr.h | 52 +++++ samples/omp_svr/mynewt/syscfg.yml | 12 ++ 6 files changed, 591 insertions(+), 7 deletions(-) create mode 100644 samples/omp_svr/mynewt/src/gatt_svr.c create mode 100644 samples/omp_svr/mynewt/src/misc.c create mode 100644 samples/omp_svr/mynewt/src/omp_svr.h diff --git a/samples/omp_svr/mynewt/pkg.yml b/samples/omp_svr/mynewt/pkg.yml index f0226406..984855f6 100644 --- a/samples/omp_svr/mynewt/pkg.yml +++ b/samples/omp_svr/mynewt/pkg.yml @@ -15,9 +15,9 @@ # specific language governing permissions and limitations # under the License. # -pkg.name: samples/smp_svr/mynewt +pkg.name: samples/omp_svr/mynewt pkg.type: app -pkg.description: Simple BLE peripheral running an mcumgr SMP server. +pkg.description: Simple BLE peripheral running an mcumgr OMP server. pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: @@ -40,4 +40,22 @@ pkg.deps: - '@apache-mynewt-mcumgr/cmd/fs_mgmt' - '@apache-mynewt-mcumgr/cmd/img_mgmt' - '@apache-mynewt-mcumgr/cmd/os_mgmt' + - "@apache-mynewt-mcumgr/cmd/stat_mgmt" + - "@apache-mynewt-mcumgr/mgmt" - '@apache-mynewt-mcumgr/smp' + - "@apache-mynewt-core/sys/reboot" + - "@apache-mynewt-core/boot/split" + - "@apache-mynewt-core/sys/log/modlog" + - "@apache-mynewt-core/sys/id" + - "@apache-mynewt-core/sys/shell" + - "@apache-mynewt-core/sys/config" + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/mgmt/oicmgr" + - "@apache-mynewt-core/sys/sysinit" + - "@apache-mynewt-core/mgmt/smp/smp_os" + +pkg.deps.CONFIG_NFFS: + - "@apache-mynewt-core/fs/nffs" + +pkg.deps.CONFIG_FCB: + - "@apache-mynewt-core/fs/fcb" diff --git a/samples/omp_svr/mynewt/src/gatt_svr.c b/samples/omp_svr/mynewt/src/gatt_svr.c new file mode 100644 index 00000000..b35a9bf8 --- /dev/null +++ b/samples/omp_svr/mynewt/src/gatt_svr.c @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include "bsp/bsp.h" +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "omp_svr.h" + +/** + * The vendor specific security test service consists of two characteristics: + * o random-number-generator: generates a random 32-bit number each time + * it is read. This characteristic can only be read over an encrypted + * connection. + * o static-value: a single-byte characteristic that can always be read, + * but can only be written over an encrypted connection. + */ + +/* 59462f12-9543-9999-12c8-58b459a2712d */ +static const ble_uuid128_t gatt_svr_svc_sec_test_uuid = + BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, + 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); + +/* 5c3a659e-897e-45e1-b016-007107c96df6 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid = + BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +/* 5c3a659e-897e-45e1-b016-007107c96df7 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid = + BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +static uint8_t gatt_svr_sec_test_static_val; + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + /*** Service: Security test. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc_sec_test_uuid.u, + .characteristics = (struct ble_gatt_chr_def[]) { { + /*** Characteristic: Random number generator. */ + .uuid = &gatt_svr_chr_sec_test_rand_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, + }, { + /*** Characteristic: Static value. */ + .uuid = &gatt_svr_chr_sec_test_static_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, + + { + 0, /* No more services. */ + }, +}; + +static int +gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) +{ + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + return 0; +} + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + const ble_uuid_t *uuid; + int rand_num; + int rc; + + uuid = ctxt->chr->uuid; + + /* Determine which characteristic is being accessed by examining its + * 128-bit UUID. + */ + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) { + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + + /* Respond with a 32-bit random number. */ + rand_num = rand(); + rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) { + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + rc = gatt_svr_chr_write(ctxt->om, + sizeof gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val, + &gatt_svr_sec_test_static_val, NULL); + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + } + + /* Unknown characteristic; the nimble stack should not have called this + * function. + */ + assert(0); + return BLE_ATT_ERR_UNLIKELY; +} + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + MODLOG_DFLT(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +int +gatt_svr_init(void) +{ + int rc; + + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/samples/omp_svr/mynewt/src/main.c b/samples/omp_svr/mynewt/src/main.c index 15755254..72fd9ac8 100644 --- a/samples/omp_svr/mynewt/src/main.c +++ b/samples/omp_svr/mynewt/src/main.c @@ -36,6 +36,15 @@ #include #include +/* BLE */ +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "services/gap/ble_svc_gap.h" + +/* Application-specified header. */ +#include "omp_svr.h" + #ifdef ARCH_sim #include #endif @@ -68,7 +77,7 @@ STATS_SECT_END static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle; -static STATS_NAME_START(gpio_stats) +STATS_NAME_START(gpio_stats) STATS_NAME(gpio_stats, toggles) STATS_NAME_END(gpio_stats) @@ -137,6 +146,243 @@ test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt) return 0; } +static int omp_svr_gap_event(struct ble_gap_event *event, void *arg); + +/** + * Logs information about a connection to the console. + */ +static void +omp_svr_print_conn_desc(struct ble_gap_conn_desc *desc) +{ + MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=", + desc->conn_handle, desc->our_ota_addr.type); + print_addr(desc->our_ota_addr.val); + MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=", + desc->our_id_addr.type); + print_addr(desc->our_id_addr.val); + MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr.type); + print_addr(desc->peer_ota_addr.val); + MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr.type); + print_addr(desc->peer_id_addr.val); + MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d\n", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +omp_svr_advertise(void) +{ + uint8_t own_addr_type; + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + const char *name; + int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /** + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info). + * o Advertising tx power. + * o Device name. + * o 16-bit service UUIDs (alert notifications). + */ + + memset(&fields, 0, sizeof fields); + + /* Advertise two flags: + * o Discoverability in forthcoming advertisement (general) + * o BLE-only (BR/EDR unsupported). + */ + fields.flags = BLE_HS_ADV_F_DISC_GEN | + BLE_HS_ADV_F_BREDR_UNSUP; + + /* Indicate that the TX power level field should be included; have the + * stack fill this value automatically. This is done by assiging the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + + name = ble_svc_gap_device_name(); + fields.name = (uint8_t *)name; + fields.name_len = strlen(name); + fields.name_is_complete = 1; + + fields.uuids16 = (ble_uuid16_t[]){ + BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID) + }; + fields.num_uuids16 = 1; + fields.uuids16_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising. */ + memset(&adv_params, 0, sizeof adv_params); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, + &adv_params, omp_svr_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that forms. + * omp_svr uses the same callback for all connections. + * + * @param event The type of event being signalled. + * @param ctxt Various information pertaining to the event. + * @param arg Application-specified argument; unuesd by + * omp_svr. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +omp_svr_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + MODLOG_DFLT(INFO, "connection %s; status=%d ", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + if (event->connect.status == 0) { + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + omp_svr_print_conn_desc(&desc); + + } + MODLOG_DFLT(INFO, "\n"); + + if (event->connect.status != 0) { + /* Connection failed; resume advertising. */ + omp_svr_advertise(); + } + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason); + omp_svr_print_conn_desc(&event->disconnect.conn); + MODLOG_DFLT(INFO, "\n"); + + /* Connection terminated; resume advertising. */ + omp_svr_advertise(); + return 0; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + MODLOG_DFLT(INFO, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + omp_svr_print_conn_desc(&desc); + MODLOG_DFLT(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_ADV_COMPLETE: + MODLOG_DFLT(INFO, "advertise complete; reason=%d", + event->adv_complete.reason); + omp_svr_advertise(); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + MODLOG_DFLT(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + omp_svr_print_conn_desc(&desc); + MODLOG_DFLT(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_SUBSCRIBE: + MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d\n", + event->subscribe.conn_handle, + event->subscribe.attr_handle, + event->subscribe.reason, + event->subscribe.prev_notify, + event->subscribe.cur_notify, + event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + return 0; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + + case BLE_GAP_EVENT_REPEAT_PAIRING: + /* We already have a bond with the peer, but it is attempting to + * establish a new secure link. This app sacrifices security for + * convenience: just throw away the old bond and accept the new link. + */ + + /* Delete the old bond. */ + rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); + assert(rc == 0); + ble_store_util_delete_peer(&desc.peer_id_addr); + + /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should + * continue with the pairing operation. + */ + return BLE_GAP_REPEAT_PAIRING_RETRY; + } + + return 0; +} + +static void +omp_svr_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +omp_svr_on_sync(void) +{ + int rc; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Begin advertising. */ + omp_svr_advertise(); +} + void task1_handler(void *arg) { @@ -202,10 +448,6 @@ static void omgr_app_init(void) { oc_init_platform("MyNewt", NULL, NULL); - /* - oc_add_device("/oic/d", "oic.d.light", "MynewtLed", "1.0", "1.0", NULL, - NULL); - */ } static const oc_handler_t omgr_oc_handler = { @@ -262,6 +504,19 @@ main(int argc, char **argv) sysinit(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = omp_svr_on_reset; + ble_hs_cfg.sync_cb = omp_svr_on_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + rc = gatt_svr_init(); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("mynewt-omp-svr"); + assert(rc == 0); + rc = conf_register(&test_conf_handler); assert(rc == 0); diff --git a/samples/omp_svr/mynewt/src/misc.c b/samples/omp_svr/mynewt/src/misc.c new file mode 100644 index 00000000..27ab0aa0 --- /dev/null +++ b/samples/omp_svr/mynewt/src/misc.c @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "omp_svr.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} diff --git a/samples/omp_svr/mynewt/src/omp_svr.h b/samples/omp_svr/mynewt/src/omp_svr.h new file mode 100644 index 00000000..69c40e7b --- /dev/null +++ b/samples/omp_svr/mynewt/src/omp_svr.h @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_OMP_SVR_ +#define H_OMP_SVR_ + +#include +#include "nimble/ble.h" +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +/** GATT server. */ +#define GATT_SVR_SVC_ALERT_UUID 0x1811 +#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define GATT_SVR_CHR_NEW_ALERT 0x2A46 +#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +/** Misc **/ +void print_bytes(const uint8_t *bytes, int len); +void print_addr(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/samples/omp_svr/mynewt/syscfg.yml b/samples/omp_svr/mynewt/syscfg.yml index 1445d42c..7bbc8712 100644 --- a/samples/omp_svr/mynewt/syscfg.yml +++ b/samples/omp_svr/mynewt/syscfg.yml @@ -29,6 +29,16 @@ syscfg.vals: REBOOT_LOG_FCB: 1 LOG_FCB: 1 CONFIG_FCB: 1 + + # Enable shell commands. + STATS_CLI: 1 + LOG_CLI: 1 + SHELL_TASK: 1 + + # Enable MCUmgr commands. + STATS_MGMT: 1 + LOG_MGMT: 1 + CONFIG_MGMT: 1 # OS main/default task OS_MAIN_STACK_SIZE: 468 @@ -37,3 +47,5 @@ syscfg.vals: # values. MSYS_1_BLOCK_COUNT: 22 MSYS_1_BLOCK_SIZE: 110 + + OC_SERVER: 1 From 7e13d8cb88587a54569443d5ca46174a17023650 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 27 Aug 2019 16:15:37 -0700 Subject: [PATCH 28/65] omp_svr: remove redundant code and enable GATT - Enabled GATT transport in OIC to talk to the device using BLE --- samples/omp_svr/mynewt/pkg.yml | 2 +- samples/omp_svr/mynewt/src/gatt_svr.c | 146 -------------------------- samples/omp_svr/mynewt/src/main.c | 9 +- samples/omp_svr/mynewt/syscfg.yml | 6 ++ 4 files changed, 12 insertions(+), 151 deletions(-) diff --git a/samples/omp_svr/mynewt/pkg.yml b/samples/omp_svr/mynewt/pkg.yml index 984855f6..3ceacab9 100644 --- a/samples/omp_svr/mynewt/pkg.yml +++ b/samples/omp_svr/mynewt/pkg.yml @@ -29,7 +29,6 @@ pkg.deps: - '@apache-mynewt-nimble/nimble/controller' - '@apache-mynewt-nimble/nimble/host' - '@apache-mynewt-nimble/nimble/host/util' - - '@apache-mynewt-nimble/nimble/host/services/ans' - '@apache-mynewt-nimble/nimble/host/services/gap' - '@apache-mynewt-nimble/nimble/host/services/gatt' - '@apache-mynewt-nimble/nimble/host/store/config' @@ -53,6 +52,7 @@ pkg.deps: - "@apache-mynewt-core/mgmt/oicmgr" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/mgmt/smp/smp_os" + - "@apache-mynewt-core/net/oic" pkg.deps.CONFIG_NFFS: - "@apache-mynewt-core/fs/nffs" diff --git a/samples/omp_svr/mynewt/src/gatt_svr.c b/samples/omp_svr/mynewt/src/gatt_svr.c index b35a9bf8..ec74376b 100644 --- a/samples/omp_svr/mynewt/src/gatt_svr.c +++ b/samples/omp_svr/mynewt/src/gatt_svr.c @@ -25,134 +25,6 @@ #include "host/ble_uuid.h" #include "omp_svr.h" -/** - * The vendor specific security test service consists of two characteristics: - * o random-number-generator: generates a random 32-bit number each time - * it is read. This characteristic can only be read over an encrypted - * connection. - * o static-value: a single-byte characteristic that can always be read, - * but can only be written over an encrypted connection. - */ - -/* 59462f12-9543-9999-12c8-58b459a2712d */ -static const ble_uuid128_t gatt_svr_svc_sec_test_uuid = - BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, - 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); - -/* 5c3a659e-897e-45e1-b016-007107c96df6 */ -static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid = - BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, - 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); - -/* 5c3a659e-897e-45e1-b016-007107c96df7 */ -static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid = - BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, - 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); - -static uint8_t gatt_svr_sec_test_static_val; - -static int -gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); - -static const struct ble_gatt_svc_def gatt_svr_svcs[] = { - { - /*** Service: Security test. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = &gatt_svr_svc_sec_test_uuid.u, - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Characteristic: Random number generator. */ - .uuid = &gatt_svr_chr_sec_test_rand_uuid.u, - .access_cb = gatt_svr_chr_access_sec_test, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, - }, { - /*** Characteristic: Static value. */ - .uuid = &gatt_svr_chr_sec_test_static_uuid.u, - .access_cb = gatt_svr_chr_access_sec_test, - .flags = BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, - - { - 0, /* No more services. */ - }, -}; - -static int -gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, - void *dst, uint16_t *len) -{ - uint16_t om_len; - int rc; - - om_len = OS_MBUF_PKTLEN(om); - if (om_len < min_len || om_len > max_len) { - return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; - } - - rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); - if (rc != 0) { - return BLE_ATT_ERR_UNLIKELY; - } - - return 0; -} - -static int -gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) -{ - const ble_uuid_t *uuid; - int rand_num; - int rc; - - uuid = ctxt->chr->uuid; - - /* Determine which characteristic is being accessed by examining its - * 128-bit UUID. - */ - - if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) { - assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); - - /* Respond with a 32-bit random number. */ - rand_num = rand(); - rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - - if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) { - switch (ctxt->op) { - case BLE_GATT_ACCESS_OP_READ_CHR: - rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val, - sizeof gatt_svr_sec_test_static_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - - case BLE_GATT_ACCESS_OP_WRITE_CHR: - rc = gatt_svr_chr_write(ctxt->om, - sizeof gatt_svr_sec_test_static_val, - sizeof gatt_svr_sec_test_static_val, - &gatt_svr_sec_test_static_val, NULL); - return rc; - - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } - } - - /* Unknown characteristic; the nimble stack should not have called this - * function. - */ - assert(0); - return BLE_ATT_ERR_UNLIKELY; -} - void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) { @@ -184,21 +56,3 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) break; } } - -int -gatt_svr_init(void) -{ - int rc; - - rc = ble_gatts_count_cfg(gatt_svr_svcs); - if (rc != 0) { - return rc; - } - - rc = ble_gatts_add_svcs(gatt_svr_svcs); - if (rc != 0) { - return rc; - } - - return 0; -} diff --git a/samples/omp_svr/mynewt/src/main.c b/samples/omp_svr/mynewt/src/main.c index 72fd9ac8..667ec25f 100644 --- a/samples/omp_svr/mynewt/src/main.c +++ b/samples/omp_svr/mynewt/src/main.c @@ -31,10 +31,12 @@ #include #include #include -#include #include #include #include +#include +#include +#include /* BLE */ #include "nimble/ble.h" @@ -504,15 +506,14 @@ main(int argc, char **argv) sysinit(); + oc_ble_coap_gatt_srv_init(); + /* Initialize the NimBLE host configuration. */ ble_hs_cfg.reset_cb = omp_svr_on_reset; ble_hs_cfg.sync_cb = omp_svr_on_sync; ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; ble_hs_cfg.store_status_cb = ble_store_util_status_rr; - rc = gatt_svr_init(); - assert(rc == 0); - /* Set the default device name. */ rc = ble_svc_gap_device_name_set("mynewt-omp-svr"); assert(rc == 0); diff --git a/samples/omp_svr/mynewt/syscfg.yml b/samples/omp_svr/mynewt/syscfg.yml index 7bbc8712..ee1ecb9c 100644 --- a/samples/omp_svr/mynewt/syscfg.yml +++ b/samples/omp_svr/mynewt/syscfg.yml @@ -49,3 +49,9 @@ syscfg.vals: MSYS_1_BLOCK_SIZE: 110 OC_SERVER: 1 + #Enables OIC transport over nlip serial + OC_TRANSPORT_SERIAL: 1 + # Enables API to send delayed responses + OC_SEPARATE_RESPONSES: '0' + # Enable gatt tranport + OC_TRANSPORT_GATT: 1 From a544bec5241457806d9cfe02b505eaaf69646749 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 27 Aug 2019 18:04:41 -0700 Subject: [PATCH 29/65] omp_svr: Use console for BLE logging and not cbmem --- samples/omp_svr/mynewt/src/main.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/samples/omp_svr/mynewt/src/main.c b/samples/omp_svr/mynewt/src/main.c index 667ec25f..864bbfcb 100644 --- a/samples/omp_svr/mynewt/src/main.c +++ b/samples/omp_svr/mynewt/src/main.c @@ -29,7 +29,7 @@ #include "split/split.h" #endif #include -#include +#include #include #include #include @@ -63,8 +63,6 @@ static volatile int g_task1_loops; #define TASK2_STACK_SIZE OS_STACK_ALIGN(64) static struct os_task task2; -static struct log my_log; - static volatile int g_task2_loops; /* Global test semaphore */ @@ -100,8 +98,6 @@ static struct conf_handler test_conf_handler = { static uint8_t test8; static uint8_t test8_shadow; static char test_str[32]; -static uint32_t cbmem_buf[MAX_CBMEM_BUF]; -static struct cbmem cbmem; static char * test_conf_get(int argc, char **argv, char *buf, int max_len) @@ -391,15 +387,17 @@ task1_handler(void *arg) struct os_task *t; int prev_pin_state, curr_pin_state; struct image_version ver; + char ver_str[IMG_MGMT_VER_MAX_STR_LEN]; + int rc; /* Set the led pin for the E407 devboard */ g_led_pin = LED_BLINK_PIN; hal_gpio_init_out(g_led_pin, 1); - if (imgr_my_version(&ver) == 0) { - console_printf("\nOMP_SVR %u.%u.%u.%u\n", - ver.iv_major, ver.iv_minor, ver.iv_revision, - (unsigned int)ver.iv_build_num); + if (img_mgmt_read_info(0, &ver, NULL, NULL) == 0) { + rc = img_mgmt_ver_str(&ver, ver_str); + assert(rc == 0); + console_printf("\nOMP_SVR %s\n", ver_str); } else { console_printf("\nOMP_SVR\n"); } @@ -416,7 +414,7 @@ task1_handler(void *arg) /* Toggle the LED */ prev_pin_state = hal_gpio_read(g_led_pin); curr_pin_state = hal_gpio_toggle(g_led_pin); - MODLOG_DFLT(INFO, "GPIO toggle from %u to %u", + MODLOG_DFLT(INFO, "GPIO %d: %u to %u\n", g_led_pin, prev_pin_state, curr_pin_state); STATS_INC(g_stats_gpio_toggle, toggles); @@ -521,13 +519,6 @@ main(int argc, char **argv) rc = conf_register(&test_conf_handler); assert(rc == 0); - cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF); - log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL); - - /* Point the default module at the cbmem log just registered. */ - rc = modlog_register(LOG_MODULE_DEFAULT, &my_log, LOG_LEVEL_DEBUG, NULL); - assert(rc == 0); - stats_init(STATS_HDR(g_stats_gpio_toggle), STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32), STATS_NAME_INIT_PARMS(gpio_stats)); From 2ee482847ab43865543c2e4726e337ca8cd64998 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Wed, 28 Aug 2019 23:03:34 +0100 Subject: [PATCH 30/65] Cleanup and rearangemet: added omp/port/mynewt, added struct omp_state, mgmt encoder/parser inited on oicmgr. --- omp/include/omp/{omp_streamer.h => omp.h} | 36 +++++---- omp/include/omp/omp_impl.h | 60 ++++++++++++++ omp/pkg.yml | 3 +- omp/port/mynewt/pkg.yml | 28 +++++++ omp/port/mynewt/src/mynewt_omp.c | 94 ++++++++++++++++++++++ omp/src/omp.c | 96 ++++------------------- omp/syscfg.yml | 7 +- 7 files changed, 226 insertions(+), 98 deletions(-) rename omp/include/omp/{omp_streamer.h => omp.h} (75%) create mode 100644 omp/include/omp/omp_impl.h create mode 100644 omp/port/mynewt/pkg.yml create mode 100644 omp/port/mynewt/src/mynewt_omp.c diff --git a/omp/include/omp/omp_streamer.h b/omp/include/omp/omp.h similarity index 75% rename from omp/include/omp/omp_streamer.h rename to omp/include/omp/omp.h index 58e89a00..aa574f60 100644 --- a/omp/include/omp/omp_streamer.h +++ b/omp/include/omp/omp.h @@ -20,7 +20,6 @@ /** * @file * @brief OMP - OIC Management Protocol. - * XXX: REVIEW THIS * * OMP is an OIC implementation of SMP, a basic protocol that sits on top of * the mgmt layer. SMP requests and responses have the following format: @@ -48,24 +47,33 @@ extern "C" { struct omp_streamer; struct mgmt_hdr; -/** @typedef smp_tx_rsp_fn - * @brief Transmits an OMP response packet. +/** + * @brief Transmits an OMP response. * - * @param ss The streamer to transmit via. - * @param buf Buffer containing the response packet. + * @param stmr The OMP Streamer struct. + * @param retval The return value for the request. * @param arg Optional streamer argument. - * - * @return 0 on success, MGMT_ERR_[...] code on failure. */ -typedef void omp_tx_rsp_fn(struct mgmt_ctxt *ctxt, void *request, int retval); +typedef void omp_tx_rsp_fn(struct omp_streamer *stmr, int retval, void* arg); /** - * @brief Decodes, encodes, and transmits SMP packets. + * @brief Decodes, encodes, and transmits OMP requests and responses. + * Holds the callback pointer and the response CBOR encoder provided by + * underlying OIC implementation. */ struct omp_streamer { struct mgmt_streamer mgmt_stmr; - omp_tx_rsp_fn *tx_rsp_cb; struct CborEncoder *rsp_encoder; + omp_tx_rsp_fn *tx_rsp_cb; +}; + +/** + * @brief Stores the streamer, management context and request. + */ +struct omp_state { + struct omp_streamer omp_stmr; + struct mgmt_ctxt *m_ctxt; + void *request; }; /** @@ -76,16 +84,14 @@ struct omp_streamer { * sequentially from the start of the packet to the end. Each response is sent * individually in its own packet. If a request elicits an error response, * processing of the packet is aborted. This function consumes the supplied - * request buffer regardless of the outcome. + * request buffer regardless of the outcome.//encoder * - * @param streamer The streamer providing the required OMP - * callbacks. + * @param omgr_st The OMP State struct * @param req The request packet to process. * * @return 0 on success, MGMT_ERR_[...] code on failure. */ -int omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, - void *req); +int omp_impl_process_request_packet(struct omp_state *omgr_st, void *req); #ifdef __cplusplus } diff --git a/omp/include/omp/omp_impl.h b/omp/include/omp/omp_impl.h new file mode 100644 index 00000000..09509b57 --- /dev/null +++ b/omp/include/omp/omp_impl.h @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @file + * @brief OMP - OIC Management Protocol. + * + * OMP is an OIC implementation of SMP, a basic protocol that sits on top of + * the mgmt layer. SMP requests and responses have the following format: + * + * [Offset 0]: Mgmt header + * [Offset 8]: CBOR map of command-specific key-value pairs. + * + * SMP request packets may contain multiple concatenated requests. Each + * request must start at an offset that is a multiple of 4, so padding should + * be inserted between requests as necessary. Requests are processed + * sequentially from the start of the packet to the end. Each response is sent + * individually in its own packet. If a request elicits an error response, + * processing of the packet is aborted. + */ + +#ifndef H_OMP_IMPL +#define H_OMP_IMPL + +#include "mgmt/mgmt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int omp_encode_mgmt_hdr(struct CborEncoder *enc, struct mgmt_hdr hdr); +int omp_send_err_rsp(struct CborEncoder *enc, + const struct mgmt_hdr *hdr, + int mgmt_status); +int omp_read_hdr(struct CborValue *cv, struct mgmt_hdr *out_hdr); +int omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, + struct mgmt_hdr *rsp_hdr, + struct mgmt_ctxt *ctxt); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OMP_IMPL */ diff --git a/omp/pkg.yml b/omp/pkg.yml index 415f33f8..ac5a57bc 100644 --- a/omp/pkg.yml +++ b/omp/pkg.yml @@ -28,8 +28,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - mgmt - - "@apache-mynewt-core/mgmt/smp/smp_os" + - "@apache-mynewt-mcumgr/mgmt" pkg.apis: - smp diff --git a/omp/port/mynewt/pkg.yml b/omp/port/mynewt/pkg.yml new file mode 100644 index 00000000..8f7946b1 --- /dev/null +++ b/omp/port/mynewt/pkg.yml @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: omp/port/mynewt +pkg.description: 'OIC Management Protocol.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-mcumgr/omp' + - '@apache-mynewt-mcumgr/mgmt' diff --git a/omp/port/mynewt/src/mynewt_omp.c b/omp/port/mynewt/src/mynewt_omp.c new file mode 100644 index 00000000..34be3821 --- /dev/null +++ b/omp/port/mynewt/src/mynewt_omp.c @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +#include "os/mynewt.h" + +#include +#include +#include + +#include "omp/omp.h" +#include "omp/omp_impl.h" + +int +omp_impl_process_request_packet(struct omp_state *omgr_st, void *req_buf) +{ + struct mgmt_ctxt ctxt; + struct omp_streamer *streamer; + struct mgmt_hdr req_hdr, rsp_hdr; + struct os_mbuf *req_m; + int rc = 0; + + assert(omgr_st); + assert(req_buf); + + streamer = &omgr_st->omp_stmr; + omgr_st->m_ctxt = &ctxt; + + req_m = (struct os_mbuf *) req_buf; + + rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, req_m); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + + } + + rc = omp_read_hdr(&ctxt.it, &req_hdr); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + + } + + memcpy(&rsp_hdr, &req_hdr, sizeof(struct mgmt_hdr)); + + rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, req_m); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + + } + + rc = cbor_encoder_create_map(streamer->rsp_encoder, + &ctxt.encoder, + CborIndefiniteLength); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + } + + rc = omp_process_mgmt_hdr(&req_hdr, &rsp_hdr, &ctxt); + /* if (err != 0) { */ + /* rc = MGMT_ERR_EINVAL; */ + /* } */ + + cbor_encoder_close_container(streamer->rsp_encoder, &ctxt.encoder); + if (rc != 0) { + rc = MGMT_ERR_EINVAL; + return rc; + + } + + streamer->tx_rsp_cb(streamer, rc, NULL); + return 0; +} diff --git a/omp/src/omp.c b/omp/src/omp.c index 14636722..dac2a707 100644 --- a/omp/src/omp.c +++ b/omp/src/omp.c @@ -26,21 +26,9 @@ #include #include -#include "omp/omp_streamer.h" -/* #include */ +#include "omp/omp_impl.h" -/* struct omgr_ctxt { */ -/* struct mgmt_ctxt ob_mc; */ -/* struct cbor_mbuf_reader ob_reader; */ -/* }; */ - -/* struct omgr_state { */ -/* struct omgr_ctxt os_ctxt; /\* CBOR buffer for MGMT task *\/ */ -/* }; */ - -/* static struct omgr_state omgr_state; */ - -static int +int omp_encode_mgmt_hdr(struct CborEncoder *enc, struct mgmt_hdr hdr) { int rc; @@ -62,7 +50,7 @@ omp_encode_mgmt_hdr(struct CborEncoder *enc, struct mgmt_hdr hdr) return 0; } -static int +int omp_send_err_rsp(struct CborEncoder *enc, const struct mgmt_hdr *hdr, int mgmt_status) @@ -87,7 +75,7 @@ omp_send_err_rsp(struct CborEncoder *enc, return 0; } -static int +int omp_read_hdr(struct CborValue *cv, struct mgmt_hdr *out_hdr) { size_t hlen; @@ -116,18 +104,19 @@ omp_read_hdr(struct CborValue *cv, struct mgmt_hdr *out_hdr) return 0; } -static int -omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr, +int +omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, + struct mgmt_hdr *rsp_hdr, struct mgmt_ctxt *ctxt) { int rc = 0; - bool rsp_hdr_filled = false; + bool rsp_hdr_filled = true; const struct mgmt_handler *handler; handler = mgmt_find_handler(req_hdr->nh_group, req_hdr->nh_id); if (handler == NULL) { rc = MGMT_ERR_ENOENT; - goto done; + return rc; } switch (req_hdr->nh_op) { @@ -151,76 +140,23 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr, default: rc = MGMT_ERR_EINVAL; - break; - } - if (rc != 0) { + rsp_hdr_filled = false; goto done; - } else { - rsp_hdr_filled = true; + break; } /* Encode the MGMT header in the response. */ - rc = omp_encode_mgmt_hdr(&ctxt->encoder, *rsp_hdr); - if (rc != 0) { - rc = MGMT_ERR_ENOMEM; - } - done: if (rc != 0) { if (rsp_hdr_filled) { rc = omp_send_err_rsp(&ctxt->encoder, rsp_hdr, rc); } + } else { + rc = omp_encode_mgmt_hdr(&ctxt->encoder, *rsp_hdr); + if (rc != 0) { + rc = MGMT_ERR_ENOMEM; + } } - return rc; -} - -int -omp_process_request_packet(struct omp_streamer *streamer, struct os_mbuf *m, - void *req) -{ - struct mgmt_ctxt ctxt; - struct mgmt_hdr req_hdr, rsp_hdr; - int rc = 0; - - rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); - assert(rc == 0); - rc = cbor_parser_init(streamer->mgmt_stmr.reader, 0, &ctxt.parser, &ctxt.it); - assert(rc == 0); - - rc = omp_read_hdr(&ctxt.it, &req_hdr); - assert(rc == 0); - if (rc != 0) { - rc = MGMT_ERR_EINVAL; - return rc; - - } - - memcpy(&rsp_hdr, &req_hdr, sizeof(struct mgmt_hdr)); - - rc = mgmt_streamer_init_reader(&streamer->mgmt_stmr, m); - assert(rc == 0); - rc = cbor_parser_init(streamer->mgmt_stmr.reader, 0, &ctxt.parser, &ctxt.it); - assert(rc == 0); - - rc = cbor_encoder_create_map(streamer->rsp_encoder, //encoder - &ctxt.encoder, //mapEncoder - CborIndefiniteLength); - assert(rc == 0); - if (rc != 0) { - rc = MGMT_ERR_EINVAL; - return rc; - } - - rc = omp_process_mgmt_hdr(&req_hdr, &rsp_hdr, &ctxt); - assert(rc == 0); - if (rc != 0) { - rc = MGMT_ERR_EINVAL; - return rc; - } - - rc = cbor_encoder_close_container(streamer->rsp_encoder, &ctxt.encoder); - assert(rc == 0); - streamer->tx_rsp_cb(&ctxt, req, rc); return rc; } diff --git a/omp/syscfg.yml b/omp/syscfg.yml index 01c2e77f..0efa3205 100644 --- a/omp/syscfg.yml +++ b/omp/syscfg.yml @@ -6,7 +6,7 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, @@ -16,4 +16,9 @@ # specific language governing permissions and limitations # under the License. # + syscfg.defs: + OMP_OIC_RESOURCE_NAME: + description: > + The OMP OIC Resource name. + value: '"x.mynewt.nmgr"' From 523f08ba2f79ffcaa2dd678e2c86de5aa19b9c0b Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Wed, 28 Aug 2019 23:39:45 +0100 Subject: [PATCH 31/65] Cleanup on samples/smp_svr --- samples/smp_svr/mynewt/src/main.c | 8 -------- samples/smp_svr/mynewt/src/smp_svr.h | 13 ++----------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/samples/smp_svr/mynewt/src/main.c b/samples/smp_svr/mynewt/src/main.c index 3f890d07..170a2dee 100755 --- a/samples/smp_svr/mynewt/src/main.c +++ b/samples/smp_svr/mynewt/src/main.c @@ -185,10 +185,6 @@ smp_svr_gap_event(struct ble_gap_event *event, void *arg) rc = ble_gap_conn_find(event->connect.conn_handle, &desc); assert(rc == 0); smp_svr_print_conn_desc(&desc); - -#if MYNEWT_VAL(SMP_SVR_LE_PHY_SUPPORT) - phy_conn_changed(event->connect.conn_handle); -#endif } SMP_SVR_LOG(INFO, "\n"); @@ -203,10 +199,6 @@ smp_svr_gap_event(struct ble_gap_event *event, void *arg) smp_svr_print_conn_desc(&event->disconnect.conn); SMP_SVR_LOG(INFO, "\n"); -#if MYNEWT_VAL(SMP_SVR_LE_PHY_SUPPORT) - phy_conn_changed(CONN_HANDLE_INVALID); -#endif - /* Connection terminated; resume advertising. */ smp_svr_advertise(); return 0; diff --git a/samples/smp_svr/mynewt/src/smp_svr.h b/samples/smp_svr/mynewt/src/smp_svr.h index 5ec34610..52b7b5e1 100644 --- a/samples/smp_svr/mynewt/src/smp_svr.h +++ b/samples/smp_svr/mynewt/src/smp_svr.h @@ -17,8 +17,8 @@ * under the License. */ -#ifndef H_BLEPRPH_ -#define H_BLEPRPH_ +#ifndef SMP_SVR_ +#define SMP_SVR_ #include #include "nimble/ble.h" @@ -41,15 +41,6 @@ struct ble_gatt_register_ctxt; void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); -/* PHY support */ -#if MYNEWT_VAL(BLEPRPH_LE_PHY_SUPPORT) -#define CONN_HANDLE_INVALID 0xffff - -void phy_init(void); -void phy_conn_changed(uint16_t handle); -void phy_update(uint8_t phy); -#endif - /** Misc. */ void print_bytes(const uint8_t *bytes, int len); void print_addr(const void *addr); From 7fd945cb10b963596d918c5d242cc3a4102650b5 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Thu, 29 Aug 2019 00:06:55 +0100 Subject: [PATCH 32/65] Private omp function prototypes now on omp_priv.h --- omp/include/omp/omp.h | 1 + omp/include/omp/{omp_impl.h => omp_priv.h} | 22 ++-------------------- omp/port/mynewt/src/mynewt_omp.c | 2 +- omp/src/omp.c | 2 +- 4 files changed, 5 insertions(+), 22 deletions(-) rename omp/include/omp/{omp_impl.h => omp_priv.h} (63%) diff --git a/omp/include/omp/omp.h b/omp/include/omp/omp.h index aa574f60..40fd4c90 100644 --- a/omp/include/omp/omp.h +++ b/omp/include/omp/omp.h @@ -76,6 +76,7 @@ struct omp_state { void *request; }; + /** * @brief Processes a single OMP request packet and sends all corresponding * responses. diff --git a/omp/include/omp/omp_impl.h b/omp/include/omp/omp_priv.h similarity index 63% rename from omp/include/omp/omp_impl.h rename to omp/include/omp/omp_priv.h index 09509b57..9f3021b9 100644 --- a/omp/include/omp/omp_impl.h +++ b/omp/include/omp/omp_priv.h @@ -17,26 +17,8 @@ * under the License. */ -/** - * @file - * @brief OMP - OIC Management Protocol. - * - * OMP is an OIC implementation of SMP, a basic protocol that sits on top of - * the mgmt layer. SMP requests and responses have the following format: - * - * [Offset 0]: Mgmt header - * [Offset 8]: CBOR map of command-specific key-value pairs. - * - * SMP request packets may contain multiple concatenated requests. Each - * request must start at an offset that is a multiple of 4, so padding should - * be inserted between requests as necessary. Requests are processed - * sequentially from the start of the packet to the end. Each response is sent - * individually in its own packet. If a request elicits an error response, - * processing of the packet is aborted. - */ - -#ifndef H_OMP_IMPL -#define H_OMP_IMPL +#ifndef H_OMP_PRIV +#define H_OMP_PRIV #include "mgmt/mgmt.h" diff --git a/omp/port/mynewt/src/mynewt_omp.c b/omp/port/mynewt/src/mynewt_omp.c index 34be3821..2cda55e1 100644 --- a/omp/port/mynewt/src/mynewt_omp.c +++ b/omp/port/mynewt/src/mynewt_omp.c @@ -27,7 +27,7 @@ #include #include "omp/omp.h" -#include "omp/omp_impl.h" +#include "omp/omp_priv.h" int omp_impl_process_request_packet(struct omp_state *omgr_st, void *req_buf) diff --git a/omp/src/omp.c b/omp/src/omp.c index dac2a707..615c7984 100644 --- a/omp/src/omp.c +++ b/omp/src/omp.c @@ -26,7 +26,7 @@ #include #include -#include "omp/omp_impl.h" +#include "omp/omp_priv.h" int omp_encode_mgmt_hdr(struct CborEncoder *enc, struct mgmt_hdr hdr) From 92fa6ca2a7a7dad2f747596d1c28c61a2b2e1422 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Thu, 29 Aug 2019 00:29:58 +0100 Subject: [PATCH 33/65] OMP_OIC_RESOURCE_NAME now defined on mynewt-core/oicmgr side --- omp/syscfg.yml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 omp/syscfg.yml diff --git a/omp/syscfg.yml b/omp/syscfg.yml deleted file mode 100644 index 0efa3205..00000000 --- a/omp/syscfg.yml +++ /dev/null @@ -1,24 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - OMP_OIC_RESOURCE_NAME: - description: > - The OMP OIC Resource name. - value: '"x.mynewt.nmgr"' From 436a9d583b15ea1c3c55fdd541a3880841cf7115 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Fri, 30 Aug 2019 00:53:36 +0100 Subject: [PATCH 34/65] Fixed timeout on invalid log show command, omp_process_mgmt_hdr refactored --- cmd/log_mgmt/src/log_mgmt.c | 1 + omp/port/mynewt/src/mynewt_omp.c | 3 --- omp/src/omp.c | 30 +++++++++++++----------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 4f92390a..58ecddb7 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -317,6 +317,7 @@ log_mgmt_show(struct mgmt_ctxt *ctxt) /* Log list fully iterated. */ if (name_len != 0) { /* Client specified log name, but the log wasn't found. */ + cbor_encoder_close_container(&ctxt->encoder, &logs); return MGMT_ERR_ENOENT; } else { break; diff --git a/omp/port/mynewt/src/mynewt_omp.c b/omp/port/mynewt/src/mynewt_omp.c index 2cda55e1..38b1ef4c 100644 --- a/omp/port/mynewt/src/mynewt_omp.c +++ b/omp/port/mynewt/src/mynewt_omp.c @@ -78,9 +78,6 @@ omp_impl_process_request_packet(struct omp_state *omgr_st, void *req_buf) } rc = omp_process_mgmt_hdr(&req_hdr, &rsp_hdr, &ctxt); - /* if (err != 0) { */ - /* rc = MGMT_ERR_EINVAL; */ - /* } */ cbor_encoder_close_container(streamer->rsp_encoder, &ctxt.encoder); if (rc != 0) { diff --git a/omp/src/omp.c b/omp/src/omp.c index 615c7984..f6ae4697 100644 --- a/omp/src/omp.c +++ b/omp/src/omp.c @@ -112,6 +112,7 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, int rc = 0; bool rsp_hdr_filled = true; const struct mgmt_handler *handler; + mgmt_handler_fn *handler_fn = NULL; handler = mgmt_find_handler(req_hdr->nh_group, req_hdr->nh_id); if (handler == NULL) { @@ -121,32 +122,27 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, switch (req_hdr->nh_op) { case MGMT_OP_READ: - if (handler->mh_read == NULL) { - rc = MGMT_ERR_ENOENT; - } else { - rsp_hdr->nh_op = MGMT_OP_READ_RSP; - rc = handler->mh_read(ctxt); - } + rsp_hdr->nh_op = MGMT_OP_READ_RSP; + handler_fn = handler->mh_read; break; case MGMT_OP_WRITE: - if (handler->mh_write == NULL) { - rc = MGMT_ERR_ENOENT; - } else { - rsp_hdr->nh_op = MGMT_OP_WRITE_RSP; - rc = handler->mh_write(ctxt); - } + rsp_hdr->nh_op = MGMT_OP_WRITE_RSP; + handler_fn = handler->mh_write; break; default: rc = MGMT_ERR_EINVAL; - rsp_hdr_filled = false; - goto done; - break; + } + + if (handler_fn) { + rc = handler_fn(ctxt); + } else { + rc = MGMT_ERR_ENOTSUP; } /* Encode the MGMT header in the response. */ -done: + if (rc != 0) { if (rsp_hdr_filled) { rc = omp_send_err_rsp(&ctxt->encoder, rsp_hdr, rc); @@ -158,5 +154,5 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, } } - return rc; + return mgmt_err_from_cbor(rc); } From c998c7486aa41cd973a6537131647c41d42016c6 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Fri, 30 Aug 2019 13:53:11 +0100 Subject: [PATCH 35/65] Fixed timeout on invalid log show command, omp_process_mgmt_hdr refactored --- omp/src/omp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/omp/src/omp.c b/omp/src/omp.c index f6ae4697..fb1cc1e9 100644 --- a/omp/src/omp.c +++ b/omp/src/omp.c @@ -110,7 +110,6 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_ctxt *ctxt) { int rc = 0; - bool rsp_hdr_filled = true; const struct mgmt_handler *handler; mgmt_handler_fn *handler_fn = NULL; @@ -144,7 +143,7 @@ omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, /* Encode the MGMT header in the response. */ if (rc != 0) { - if (rsp_hdr_filled) { + if (handler_fn) { rc = omp_send_err_rsp(&ctxt->encoder, rsp_hdr, rc); } } else { From 1ae7ca5048cd3772cb85b9a37781ab6bc438701c Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 4 Sep 2019 14:09:48 -0700 Subject: [PATCH 36/65] omp, mgmt: Changes for backwards compatibility - Most of is not needed by new APIs but it is needed for old ones to work --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 2 +- mgmt/include/mgmt/mgmt.h | 2 ++ omp/include/omp/omp.h | 8 ++++++++ omp/include/omp/omp_priv.h | 1 - 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index 5b80ba2a..e9d77be2 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -243,7 +243,7 @@ typedef int img_mgmt_upload_fn(uint32_t offset, uint32_t size, void *arg); * @param arg Optional argument that gets passed to the * callback. */ -void imgr_set_upload_cb(img_mgmt_upload_fn *cb, void *arg); +void img_mgmt_set_upload_cb(img_mgmt_upload_fn *cb, void *arg); void img_mgmt_register_callbacks(const img_mgmt_dfu_callbacks_t *cb_struct); void img_mgmt_dfu_stopped(void); void img_mgmt_dfu_started(void); diff --git a/mgmt/include/mgmt/mgmt.h b/mgmt/include/mgmt/mgmt.h index 3aab5b8f..66d8c45e 100644 --- a/mgmt/include/mgmt/mgmt.h +++ b/mgmt/include/mgmt/mgmt.h @@ -91,6 +91,8 @@ struct mgmt_hdr { uint8_t nh_id; /* Message ID within group */ }; +#define nmgr_hdr mgmt_hdr + /* * MGMT_EVT_OP_CMD_STATUS argument */ diff --git a/omp/include/omp/omp.h b/omp/include/omp/omp.h index 40fd4c90..82502af2 100644 --- a/omp/include/omp/omp.h +++ b/omp/include/omp/omp.h @@ -94,6 +94,14 @@ struct omp_state { */ int omp_impl_process_request_packet(struct omp_state *omgr_st, void *req); +/** + * @brief Read the management header out from a cbor value + * + * @param cv Ptr to CoberValue + * @param out_hdr Ptr to management header to be filled in + */ +int omp_read_hdr(struct CborValue *cv, struct mgmt_hdr *out_hdr); + #ifdef __cplusplus } #endif diff --git a/omp/include/omp/omp_priv.h b/omp/include/omp/omp_priv.h index 9f3021b9..4147cb7f 100644 --- a/omp/include/omp/omp_priv.h +++ b/omp/include/omp/omp_priv.h @@ -30,7 +30,6 @@ int omp_encode_mgmt_hdr(struct CborEncoder *enc, struct mgmt_hdr hdr); int omp_send_err_rsp(struct CborEncoder *enc, const struct mgmt_hdr *hdr, int mgmt_status); -int omp_read_hdr(struct CborValue *cv, struct mgmt_hdr *out_hdr); int omp_process_mgmt_hdr(struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr, struct mgmt_ctxt *ctxt); From 2df6c983d2102ffa83131032f30106b7054a3aee Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 4 Sep 2019 14:26:03 -0700 Subject: [PATCH 37/65] img_mgmt: use IMG_MGMT_DUMMY_HDR and add backwards - ..compatibility --- cmd/img_mgmt/src/img_mgmt.c | 2 +- cmd/img_mgmt/syscfg.yml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index c95ca61a..08f0e8ef 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -109,7 +109,7 @@ img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags) { -#if MYNEWT_VAL(IMGMGR_DUMMY_HDR) +#if MYNEWT_VAL(IMG_MGMT_DUMMY_HDR) uint8_t dummy_hash[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; diff --git a/cmd/img_mgmt/syscfg.yml b/cmd/img_mgmt/syscfg.yml index 6bf6129d..250637c7 100644 --- a/cmd/img_mgmt/syscfg.yml +++ b/cmd/img_mgmt/syscfg.yml @@ -35,3 +35,21 @@ syscfg.defs: description: > Enable verbose logging during a firmware upgrade value: 0 + + IMG_MGMT_DUMMY_HDR: + description: 'Returns dummy image header data for imgr functions, + useful when there are no images present, Eg: unit + tests' + value: 0 + +syscfg.vals.IMGMGR_MAX_CHUNK_SIZE: + IMG_MGMT_UL_CHUNK_SIZE: MYNEWT_VAL(IMGMGR_MAX_CHUNK_SIZE) + +syscfg.vals.IMGMGR_LAZY_ERASE: + IMG_MGMT_LAZY_ERASE: MYNEWT_VAL(IMGMGR_LAZY_ERASE) + +syscfg.vals.IMGMGR_VERBOSE_ERR: + IMG_MGMT_VERBOSE_ERR: MYNEWT_VAL(IMGMGR_VERBOSE_ERR) + +syscfg.vals.IMGMGR_DUMMY_HDR: + IMG_MGMT_DUMMY_HDR: MYNEWT_VAL(IMGMGR_DUMMY_HDR) From 7a11126409b6825d903cd84f1449e268b8056af8 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 6 Sep 2019 11:14:17 -0700 Subject: [PATCH 38/65] cborattr: Make mbuf APIs non ZEPHYR specific --- cborattr/include/cborattr/cborattr.h | 5 +++++ cborattr/src/cborattr.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/cborattr/include/cborattr/cborattr.h b/cborattr/include/cborattr/cborattr.h index c0c64d00..941f251e 100644 --- a/cborattr/include/cborattr/cborattr.h +++ b/cborattr/include/cborattr/cborattr.h @@ -27,7 +27,10 @@ #include #include #include "tinycbor/cbor.h" + +#ifndef __ZEPHYR__ #include +#endif #ifdef __cplusplus extern "C" { @@ -145,8 +148,10 @@ int cbor_read_array(struct CborValue *, const struct cbor_array_t *); int cbor_read_flat_attrs(const uint8_t *data, int len, const struct cbor_attr_t *attrs); +#ifndef __ZEPHYR__ int cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, const struct cbor_attr_t *attrs); +#endif #ifdef __cplusplus } diff --git a/cborattr/src/cborattr.c b/cborattr/src/cborattr.c index fc46dbe8..c2ebf3e2 100644 --- a/cborattr/src/cborattr.c +++ b/cborattr/src/cborattr.c @@ -21,8 +21,11 @@ #include "cborattr/cborattr.h" #include "tinycbor/cbor.h" #include "tinycbor/cbor_buf_reader.h" + +#ifndef __ZEPHYR__ #include "tinycbor/cbor_mbuf_reader.h" #include "os/os_mbuf.h" +#endif #define CBORATTR_MAX_SIZE 512 @@ -399,6 +402,7 @@ cbor_read_flat_attrs(const uint8_t *data, int len, return cbor_read_object(&value, attrs); } +#ifndef __ZEPHYR__ /* * Read in cbor key/values from os_mbuf pointed by m, and fill them * into attrs. @@ -426,3 +430,5 @@ cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, } return cbor_read_object(&value, attrs); } +#endif + From 61dd6152367768236c34fd49912505ce0b4e46bd Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 6 Sep 2019 11:30:36 -0700 Subject: [PATCH 39/65] log_mgmt: Add backwards compatibility for log_mgmt --- cmd/log_mgmt/port/mynewt/syscfg.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/log_mgmt/port/mynewt/syscfg.yml b/cmd/log_mgmt/port/mynewt/syscfg.yml index cbc69a90..d397e352 100644 --- a/cmd/log_mgmt/port/mynewt/syscfg.yml +++ b/cmd/log_mgmt/port/mynewt/syscfg.yml @@ -38,3 +38,7 @@ syscfg.defs: of this size gets allocated on the stack during handling of all log management commands. value: 64 + +# For backwards compatibility with log nmgr +syscfg.vals.LOG_NMGR_MAX_RSP_LEN: + LOG_MGMT_CHUNK_SIZE: MYNEWT_VAL(LOG_NMGR_MAX_RSP_LEN) From 542db228b5430e5bcca62b318cfd7902e9385a15 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Tue, 10 Sep 2019 01:55:59 +0100 Subject: [PATCH 40/65] log imghash support added --- cmd/log_mgmt/include/log_mgmt/log_mgmt.h | 13 +++++++- .../port/mynewt/src/mynewt_log_mgmt.c | 31 +++++++++++++------ cmd/log_mgmt/src/log_mgmt.c | 13 +++++--- cmd/log_mgmt/src/log_mgmt_config.h | 1 + 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h index 919a7c99..75e66071 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h @@ -43,6 +43,15 @@ extern "C" { /** @brief Log entries are persisted across reboots. */ #define LOG_MGMT_TYPE_STORAGE 2 +/* @brief Flags used to indicate type of data in reserved payload. */ +#define LOG_MGMT_FLAGS_IMG_HASH (1 << 0) + +/* @brief Log entry types. */ +#define LOG_MGMT_ETYPE_STRING 0 +#define LOG_MGMT_ETYPE_CBOR 1 +#define LOG_MGMT_ETYPE_BINARY 2 + + /** @brief Generic descriptor for an OS-specific log. */ struct log_mgmt_log { const char *name; @@ -57,7 +66,9 @@ struct log_mgmt_entry { size_t len; uint8_t module; uint8_t level; - uint8_t type; + uint8_t type:4; + uint8_t flags:4; + const uint8_t *imghash; void *ctxt; }; diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index 1d95e417..f044f4ad 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -108,11 +108,12 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, { struct mynewt_log_mgmt_walk_arg *mynewt_log_mgmt_walk_arg; struct log_mgmt_entry entry; + int header_len; int read_len; int rc; mynewt_log_mgmt_walk_arg = log_offset->lo_arg; - + /* If specified timestamp is nonzero, it is the primary criterion, and the * specified index is the secondary criterion. If specified timetsamp is * zero, specified index is the only criterion. @@ -122,7 +123,6 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, * Else: encode entries whose timestamp >= specified timestamp and whose * index >= specified index */ - if (log_offset->lo_ts == 0) { if (log_offset->lo_index > leh->ue_index) { return 0; @@ -133,21 +133,32 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, return 0; } - read_len = min(len - sizeof leh, LOG_MGMT_BODY_LEN - sizeof leh); - rc = log_read(log, dptr, mynewt_log_mgmt_walk_arg->body, sizeof leh, + entry.ts = leh->ue_ts; + entry.index = leh->ue_index; + entry.module = leh->ue_module; + entry.level = leh->ue_level; + +#if MYNEWT_VAL(LOG_VERSION) < 3 + entry.type = LOG_ETYPE_STRING; + entry.flags = 0; + header_len = sizeof leh; +#else + entry.type = leh->ue_etype; + entry.flags = leh->ue_flags; + entry.imghash = (leh->ue_flags & LOG_FLAGS_IMG_HASH) ? + leh->ue_imghash : NULL; + header_len = log_hdr_len(leh); +#endif + + read_len = min(len - header_len, LOG_MGMT_BODY_LEN - header_len); + rc = log_read(log, dptr, mynewt_log_mgmt_walk_arg->body, header_len, read_len); if (rc < 0) { return MGMT_ERR_EUNKNOWN; } - entry.ts = leh->ue_ts; - entry.index = leh->ue_index; - entry.module = leh->ue_module; - entry.level = leh->ue_level; entry.len = rc; - entry.type = leh->ue_etype; entry.data = mynewt_log_mgmt_walk_arg->body; - return mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); } diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 58ecddb7..5bb4f5c9 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -77,15 +77,15 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, err |= cbor_encoder_create_map(enc, &rsp, CborIndefiniteLength); switch (entry->type) { - case LOG_ETYPE_CBOR: + case LOG_MGMT_ETYPE_CBOR: err |= cbor_encode_text_stringz(&rsp, "type"); err |= cbor_encode_text_stringz(&rsp, "cbor"); break; - case LOG_ETYPE_BINARY: + case LOG_MGMT_ETYPE_BINARY: err |= cbor_encode_text_stringz(&rsp, "type"); err |= cbor_encode_text_stringz(&rsp, "bin"); break; - case LOG_ETYPE_STRING: + case LOG_MGMT_ETYPE_STRING: err |= cbor_encode_text_stringz(&rsp, "type"); err |= cbor_encode_text_stringz(&rsp, "str"); break; @@ -108,7 +108,7 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, } err |= cbor_encoder_close_container(&rsp, &str_encoder); - + err |= cbor_encode_text_stringz(&rsp, "ts"); err |= cbor_encode_int(&rsp, entry->ts); err |= cbor_encode_text_stringz(&rsp, "level"); @@ -117,6 +117,11 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, err |= cbor_encode_uint(&rsp, entry->index); err |= cbor_encode_text_stringz(&rsp, "module"); err |= cbor_encode_uint(&rsp, entry->module); + if (entry->flags & LOG_MGMT_FLAGS_IMG_HASH) { + err |= cbor_encode_text_stringz(&rsp, "imghash"); + err |= cbor_encode_byte_string(&rsp, entry->imghash, + LOG_MGMT_IMG_HASHLEN); + } err |= cbor_encoder_close_container(enc, &rsp); if (out_len != NULL) { diff --git a/cmd/log_mgmt/src/log_mgmt_config.h b/cmd/log_mgmt/src/log_mgmt_config.h index 572fb00b..058f431e 100644 --- a/cmd/log_mgmt/src/log_mgmt_config.h +++ b/cmd/log_mgmt/src/log_mgmt_config.h @@ -27,6 +27,7 @@ #define LOG_MGMT_CHUNK_SIZE MYNEWT_VAL(LOG_MGMT_CHUNK_SIZE) #define LOG_MGMT_NAME_LEN MYNEWT_VAL(LOG_MGMT_NAME_LEN) #define LOG_MGMT_BODY_LEN MYNEWT_VAL(LOG_MGMT_BODY_LEN) +#define LOG_MGMT_IMG_HASHLEN 4 #elif defined __ZEPHYR__ From 33169b7aa88d6c3e609e8e47503e921a98db531e Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Wed, 11 Sep 2019 00:43:16 +0100 Subject: [PATCH 41/65] Sample apps support native BSP. --- samples/omp_svr/mynewt/pkg.yml | 29 +++++++++++++++++++---------- samples/omp_svr/mynewt/src/main.c | 13 +++++++++---- samples/omp_svr/mynewt/syscfg.yml | 14 ++++++++------ samples/smp_svr/mynewt/pkg.yml | 24 ++++++++++++++++-------- samples/smp_svr/mynewt/src/main.c | 19 +++++++++++++++---- samples/smp_svr/mynewt/syscfg.yml | 22 +++++++++++++++++----- 6 files changed, 84 insertions(+), 37 deletions(-) diff --git a/samples/omp_svr/mynewt/pkg.yml b/samples/omp_svr/mynewt/pkg.yml index 3ceacab9..f9d725e8 100644 --- a/samples/omp_svr/mynewt/pkg.yml +++ b/samples/omp_svr/mynewt/pkg.yml @@ -23,16 +23,7 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - '@mcuboot/boot/bootutil' - - '@apache-mynewt-core/mgmt/smp/transport/ble' - '@apache-mynewt-core/mgmt/smp/transport/smp_shell' - - '@apache-mynewt-nimble/nimble/controller' - - '@apache-mynewt-nimble/nimble/host' - - '@apache-mynewt-nimble/nimble/host/util' - - '@apache-mynewt-nimble/nimble/host/services/gap' - - '@apache-mynewt-nimble/nimble/host/services/gatt' - - '@apache-mynewt-nimble/nimble/host/store/config' - - '@apache-mynewt-nimble/nimble/transport/ram' - '@apache-mynewt-core/sys/console/full' - '@apache-mynewt-core/sys/log/full' - '@apache-mynewt-core/sys/stats/full' @@ -43,7 +34,7 @@ pkg.deps: - "@apache-mynewt-mcumgr/mgmt" - '@apache-mynewt-mcumgr/smp' - "@apache-mynewt-core/sys/reboot" - - "@apache-mynewt-core/boot/split" + # - "@apache-mynewt-core/boot/split" - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/sys/id" - "@apache-mynewt-core/sys/shell" @@ -54,6 +45,24 @@ pkg.deps: - "@apache-mynewt-core/mgmt/smp/smp_os" - "@apache-mynewt-core/net/oic" +pkg.deps.!BSP_SIMULATED: + - '@mcuboot/boot/bootutil' + - '@apache-mynewt-core/mgmt/smp/transport/ble' + - '@apache-mynewt-nimble/nimble/controller' + - '@apache-mynewt-nimble/nimble/host' + - '@apache-mynewt-nimble/nimble/host/util' + - '@apache-mynewt-nimble/nimble/host/services/gap' + - '@apache-mynewt-nimble/nimble/host/services/gatt' + - '@apache-mynewt-nimble/nimble/host/store/config' + - '@apache-mynewt-nimble/nimble/transport/ram' + +pkg.deps.BSP_SIMULATED: + - '@apache-mynewt-core/boot/stub' + +pkg.ign_files.BSP_SIMULATED: + - "misc.c" + - "gatt_svr.c" + pkg.deps.CONFIG_NFFS: - "@apache-mynewt-core/fs/nffs" diff --git a/samples/omp_svr/mynewt/src/main.c b/samples/omp_svr/mynewt/src/main.c index 864bbfcb..5938b478 100644 --- a/samples/omp_svr/mynewt/src/main.c +++ b/samples/omp_svr/mynewt/src/main.c @@ -35,21 +35,23 @@ #include #include #include -#include #include +#ifndef ARCH_sim /* BLE */ #include "nimble/ble.h" #include "host/ble_hs.h" #include "host/util/util.h" #include "services/gap/ble_svc_gap.h" +#include + /* Application-specified header. */ #include "omp_svr.h" -#ifdef ARCH_sim +#else #include -#endif +#endif /* !ARCH_sim */ /* Task 1 */ #define TASK1_PRIO (8) @@ -144,6 +146,7 @@ test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt) return 0; } +#ifndef ARCH_sim static int omp_svr_gap_event(struct ble_gap_event *event, void *arg); /** @@ -380,6 +383,7 @@ omp_svr_on_sync(void) /* Begin advertising. */ omp_svr_advertise(); } +#endif /* ARCH_sim */ void task1_handler(void *arg) @@ -501,9 +505,9 @@ main(int argc, char **argv) #ifdef ARCH_sim mcu_sim_parse_args(argc, argv); #endif - sysinit(); +#ifndef ARCH_sim oc_ble_coap_gatt_srv_init(); /* Initialize the NimBLE host configuration. */ @@ -515,6 +519,7 @@ main(int argc, char **argv) /* Set the default device name. */ rc = ble_svc_gap_device_name_set("mynewt-omp-svr"); assert(rc == 0); +#endif rc = conf_register(&test_conf_handler); assert(rc == 0); diff --git a/samples/omp_svr/mynewt/syscfg.yml b/samples/omp_svr/mynewt/syscfg.yml index ee1ecb9c..8044981d 100644 --- a/samples/omp_svr/mynewt/syscfg.yml +++ b/samples/omp_svr/mynewt/syscfg.yml @@ -19,12 +19,6 @@ # Package: apps/omp_svr syscfg.vals: - # Disable central and observer roles. - BLE_ROLE_BROADCASTER: 1 - BLE_ROLE_CENTRAL: 0 - BLE_ROLE_OBSERVER: 0 - BLE_ROLE_PERIPHERAL: 1 - # Log reboot messages to a flash circular buffer. REBOOT_LOG_FCB: 1 LOG_FCB: 1 @@ -53,5 +47,13 @@ syscfg.vals: OC_TRANSPORT_SERIAL: 1 # Enables API to send delayed responses OC_SEPARATE_RESPONSES: '0' + +syscfg.vals.!BSP_SIMULATED: + # Disable central and observer roles. + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 1 + # Enable gatt tranport OC_TRANSPORT_GATT: 1 diff --git a/samples/smp_svr/mynewt/pkg.yml b/samples/smp_svr/mynewt/pkg.yml index f0226406..f2f8f785 100644 --- a/samples/smp_svr/mynewt/pkg.yml +++ b/samples/smp_svr/mynewt/pkg.yml @@ -23,9 +23,18 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: + - '@apache-mynewt-core/mgmt/smp/transport/smp_shell' + - '@apache-mynewt-core/sys/console/full' + - '@apache-mynewt-core/sys/log/full' + - '@apache-mynewt-core/sys/stats/full' + - '@apache-mynewt-mcumgr/cmd/fs_mgmt' + - '@apache-mynewt-mcumgr/cmd/img_mgmt' + - '@apache-mynewt-mcumgr/cmd/os_mgmt' + - '@apache-mynewt-mcumgr/smp' + +pkg.deps.!BSP_SIMULATED: - '@mcuboot/boot/bootutil' - '@apache-mynewt-core/mgmt/smp/transport/ble' - - '@apache-mynewt-core/mgmt/smp/transport/smp_shell' - '@apache-mynewt-nimble/nimble/controller' - '@apache-mynewt-nimble/nimble/host' - '@apache-mynewt-nimble/nimble/host/util' @@ -34,10 +43,9 @@ pkg.deps: - '@apache-mynewt-nimble/nimble/host/services/gatt' - '@apache-mynewt-nimble/nimble/host/store/config' - '@apache-mynewt-nimble/nimble/transport/ram' - - '@apache-mynewt-core/sys/console/full' - - '@apache-mynewt-core/sys/log/full' - - '@apache-mynewt-core/sys/stats/full' - - '@apache-mynewt-mcumgr/cmd/fs_mgmt' - - '@apache-mynewt-mcumgr/cmd/img_mgmt' - - '@apache-mynewt-mcumgr/cmd/os_mgmt' - - '@apache-mynewt-mcumgr/smp' + +pkg.deps.BSP_SIMULATED: + - '@apache-mynewt-core/boot/stub' + +pkg.ign_files.BSP_SIMULATED: + - "gatt_svr.c" diff --git a/samples/smp_svr/mynewt/src/main.c b/samples/smp_svr/mynewt/src/main.c index 170a2dee..43d75d91 100755 --- a/samples/smp_svr/mynewt/src/main.c +++ b/samples/smp_svr/mynewt/src/main.c @@ -23,13 +23,14 @@ #include #include "sysinit/sysinit.h" #include "bsp/bsp.h" -#include "bsp/bsp.h" #include "config/config.h" #include "console/console.h" #include "hal/hal_gpio.h" #include "hal/hal_system.h" #include "os/os.h" +#include "modlog/modlog.h" +#ifndef ARCH_sim /* BLE */ #include "nimble/ble.h" #include "host/ble_hs.h" @@ -37,6 +38,10 @@ #include "smp_svr.h" #include "host/util/util.h" +#else +#include +#endif /* !ARCH_sim */ + /* smp_svr uses the first "peruser" log module. */ #define SMP_SVR_LOG_MODULE (LOG_MODULE_PERUSER + 0) @@ -47,6 +52,7 @@ /** Log data. */ struct log smp_svr_log; +#ifndef ARCH_sim static int smp_svr_gap_event(struct ble_gap_event *event, void *arg); void @@ -274,6 +280,7 @@ smp_svr_on_sync(void) /* Begin advertising. */ smp_svr_advertise(); } +#endif /* !ARCH_sim */ /** * main @@ -284,10 +291,13 @@ smp_svr_on_sync(void) * @return int NOTE: this function should never return! */ int -main(void) +main(int argc, char **argv) { +#ifndef ARCH_sim int rc; - +#else + mcu_sim_parse_args(argc, argv); +#endif /* Initialize OS */ sysinit(); @@ -295,6 +305,7 @@ main(void) log_register("smp_svr", &smp_svr_log, &log_console_handler, NULL, LOG_SYSLEVEL); +#ifndef ARCH_sim /* Initialize the NimBLE host configuration. */ ble_hs_cfg.reset_cb = smp_svr_on_reset; ble_hs_cfg.sync_cb = smp_svr_on_sync; @@ -307,7 +318,7 @@ main(void) /* Set the default device name. */ rc = ble_svc_gap_device_name_set("smp_svr"); assert(rc == 0); - +#endif conf_load(); /* diff --git a/samples/smp_svr/mynewt/syscfg.yml b/samples/smp_svr/mynewt/syscfg.yml index 99b4dc46..a8f15772 100644 --- a/samples/smp_svr/mynewt/syscfg.yml +++ b/samples/smp_svr/mynewt/syscfg.yml @@ -19,17 +19,22 @@ # Package: apps/bleprph syscfg.vals: - # Disable central and observer roles. - BLE_ROLE_BROADCASTER: 1 - BLE_ROLE_CENTRAL: 0 - BLE_ROLE_OBSERVER: 0 - BLE_ROLE_PERIPHERAL: 1 # Log reboot messages to a flash circular buffer. REBOOT_LOG_FCB: 1 LOG_FCB: 1 CONFIG_FCB: 1 + # Enable shell commands. + STATS_CLI: 1 + LOG_CLI: 1 + SHELL_TASK: 1 + + # Enable MCUmgr commands. + STATS_MGMT: 1 + LOG_MGMT: 1 + CONFIG_MGMT: 1 + # OS main/default task OS_MAIN_STACK_SIZE: 468 @@ -37,3 +42,10 @@ syscfg.vals: # values. MSYS_1_BLOCK_COUNT: 22 MSYS_1_BLOCK_SIZE: 110 + +syscfg.vals.!BSP_SIMULATED: + # Disable central and observer roles. + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 1 From 93e47e5b1be797cbee70ac8a3211516f859aed2a Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 10 Sep 2019 18:36:18 -0700 Subject: [PATCH 42/65] samples: change syscfgs to match mcumgr changes --- samples/omp_svr/mynewt/syscfg.yml | 2 +- samples/smp_svr/mynewt/syscfg.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/omp_svr/mynewt/syscfg.yml b/samples/omp_svr/mynewt/syscfg.yml index 8044981d..1c35a78f 100644 --- a/samples/omp_svr/mynewt/syscfg.yml +++ b/samples/omp_svr/mynewt/syscfg.yml @@ -37,7 +37,7 @@ syscfg.vals: # OS main/default task OS_MAIN_STACK_SIZE: 468 - # Lots of smaller mbufs are required for newtmgr using typical BLE ATT MTU + # Lots of smaller mbufs are required for smp using typical BLE ATT MTU # values. MSYS_1_BLOCK_COUNT: 22 MSYS_1_BLOCK_SIZE: 110 diff --git a/samples/smp_svr/mynewt/syscfg.yml b/samples/smp_svr/mynewt/syscfg.yml index a8f15772..bd482539 100644 --- a/samples/smp_svr/mynewt/syscfg.yml +++ b/samples/smp_svr/mynewt/syscfg.yml @@ -38,7 +38,7 @@ syscfg.vals: # OS main/default task OS_MAIN_STACK_SIZE: 468 - # Lots of smaller mbufs are required for newtmgr using typical BLE ATT MTU + # Lots of smaller mbufs are required for smp using typical BLE ATT MTU # values. MSYS_1_BLOCK_COUNT: 22 MSYS_1_BLOCK_SIZE: 110 From 29473a3380f7906296ea87466d0d62dbff5d82c7 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 11 Sep 2019 11:43:32 -0700 Subject: [PATCH 43/65] cborattr: Add testcases from mynewt-core --- .../test/src/testcases/cborattr_encode_omit.c | 140 +++++++++++++++++ .../src/testcases/cborattr_encode_simple.c | 143 ++++++++++++++++++ 2 files changed, 283 insertions(+) create mode 100644 cborattr/test/src/testcases/cborattr_encode_omit.c create mode 100644 cborattr/test/src/testcases/cborattr_encode_simple.c diff --git a/cborattr/test/src/testcases/cborattr_encode_omit.c b/cborattr/test/src/testcases/cborattr_encode_omit.c new file mode 100644 index 00000000..4b31c6aa --- /dev/null +++ b/cborattr/test/src/testcases/cborattr_encode_omit.c @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include "test_cborattr.h" + +TEST_CASE_SELF(test_cborattr_encode_omit) +{ + /* Omit everything except the "str" value. */ + const struct cbor_out_attr_t attrs[] = { + { + .attribute = "null", + .val = { + .type = CborAttrNullType, + }, + .omit = true, + }, + { + .attribute = "bool", + .val = { + .type = CborAttrBooleanType, + .boolean = true, + }, + .omit = true, + }, + { + .attribute = "int", + .val = { + .type = CborAttrIntegerType, + .integer = -99, + }, + .omit = true, + }, + { + .attribute = "uint", + .val = { + .type = CborAttrUnsignedIntegerType, + .integer = 8442, + }, + .omit = true, + }, + { + .attribute = "float", + .val = { + .type = CborAttrFloatType, + .fval = 8.0, + }, + .omit = true, + }, + { + .attribute = "double", + .val = { + .type = CborAttrDoubleType, + .real = 16.0, + }, + .omit = true, + }, + { + .attribute = "bytes", + .val = { + .type = CborAttrByteStringType, + .bytestring.data = (uint8_t[]) {1, 2, 3}, + .bytestring.len = 3, + }, + .omit = true, + }, + { + .attribute = "str", + .val = { + .type = CborAttrTextStringType, + .string = "mystr", + }, + }, + { + .attribute = "arr", + .val = { + .type = CborAttrArrayType, + .array = { + .elems = (struct cbor_out_val_t[]) { + [0] = { + .type = CborAttrUnsignedIntegerType, + .integer = 4355, + }, + [1] = { + .type = CborAttrBooleanType, + .integer = false, + }, + }, + .len = 2, + }, + }, + .omit = true, + }, + { + .attribute = "obj", + .val = { + .type = CborAttrObjectType, + .obj = (struct cbor_out_attr_t[]) { + { + .attribute = "inner_str", + .val = { + .type = CborAttrTextStringType, + .string = "mystr2", + }, + }, + { + .attribute = "inner_int", + .val = { + .type = CborAttrIntegerType, + .integer = 123, + }, + }, + { 0 } + }, + }, + .omit = true, + }, + { 0 } + }; + const uint8_t exp[] = { + 0xbf, 0x63, 0x73, 0x74, 0x72, 0x65, 0x6d, 0x79, + 0x73, 0x74, 0x72, 0xff, + }; + + cborattr_test_util_encode(attrs, exp, sizeof exp); +} diff --git a/cborattr/test/src/testcases/cborattr_encode_simple.c b/cborattr/test/src/testcases/cborattr_encode_simple.c new file mode 100644 index 00000000..1ddcf3ca --- /dev/null +++ b/cborattr/test/src/testcases/cborattr_encode_simple.c @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include "test_cborattr.h" + +TEST_CASE_SELF(test_cborattr_encode_simple) +{ + const struct cbor_out_attr_t attrs[] = { + { + .attribute = "null", + .val = { + .type = CborAttrNullType, + }, + }, + { + .attribute = "bool", + .val = { + .type = CborAttrBooleanType, + .boolean = true, + }, + }, + { + .attribute = "int", + .val = { + .type = CborAttrIntegerType, + .integer = -99, + }, + }, + { + .attribute = "uint", + .val = { + .type = CborAttrUnsignedIntegerType, + .integer = 8442, + }, + }, + { + .attribute = "float", + .val = { + .type = CborAttrFloatType, + .fval = 8.0, + }, + }, + { + .attribute = "double", + .val = { + .type = CborAttrDoubleType, + .real = 16.0, + }, + }, + { + .attribute = "bytes", + .val = { + .type = CborAttrByteStringType, + .bytestring.data = (uint8_t[]) {1, 2, 3}, + .bytestring.len = 3, + }, + }, + { + .attribute = "str", + .val = { + .type = CborAttrTextStringType, + .string = "mystr", + }, + }, + { + .attribute = "arr", + .val = { + .type = CborAttrArrayType, + .array = { + .elems = (struct cbor_out_val_t[]) { + [0] = { + .type = CborAttrUnsignedIntegerType, + .integer = 4355, + }, + [1] = { + .type = CborAttrBooleanType, + .integer = false, + }, + }, + .len = 2, + }, + }, + }, + { + .attribute = "obj", + .val = { + .type = CborAttrObjectType, + .obj = (struct cbor_out_attr_t[]) { + { + .attribute = "inner_str", + .val = { + .type = CborAttrTextStringType, + .string = "mystr2", + }, + }, + { + .attribute = "inner_int", + .val = { + .type = CborAttrIntegerType, + .integer = 123, + }, + }, + { 0 } + }, + }, + }, + { 0 } + }; + const uint8_t exp[] = { + 0xbf, 0x64, 0x6e, 0x75, 0x6c, 0x6c, 0xf6, 0x64, + 0x62, 0x6f, 0x6f, 0x6c, 0xf5, 0x63, 0x69, 0x6e, + 0x74, 0x38, 0x62, 0x64, 0x75, 0x69, 0x6e, 0x74, + 0x19, 0x20, 0xfa, 0x65, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0xfa, 0x41, 0x00, 0x00, 0x00, 0x66, 0x64, + 0x6f, 0x75, 0x62, 0x6c, 0x65, 0xfb, 0x40, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x43, 0x01, 0x02, 0x03, + 0x63, 0x73, 0x74, 0x72, 0x65, 0x6d, 0x79, 0x73, + 0x74, 0x72, 0x63, 0x61, 0x72, 0x72, 0x82, 0x19, + 0x11, 0x03, 0xf4, 0x63, 0x6f, 0x62, 0x6a, 0xbf, + 0x69, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x73, + 0x74, 0x72, 0x66, 0x6d, 0x79, 0x73, 0x74, 0x72, + 0x32, 0x69, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x6e, 0x74, 0x18, 0x7b, 0xff, 0xff, + }; + + cborattr_test_util_encode(attrs, exp, sizeof exp); +} From 610a3963b4b0256fcf2b3a99c42975d73a99f6e7 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Wed, 11 Sep 2019 23:52:48 +0100 Subject: [PATCH 44/65] cborattr_encode_omit test now runs. --- cborattr/Kconfig | 22 +++ cborattr/include/cborattr/cborattr.h | 61 +++++- cborattr/src/cborattr.c | 185 +++++++++++++++++- cborattr/test/src/test_cborattr.h | 2 + cborattr/test/src/test_cborattr_utils.c | 15 ++ .../test/src/testcases/cborattr_encode_omit.c | 2 +- 6 files changed, 284 insertions(+), 3 deletions(-) create mode 100644 cborattr/Kconfig diff --git a/cborattr/Kconfig b/cborattr/Kconfig new file mode 100644 index 00000000..ed54c7a3 --- /dev/null +++ b/cborattr/Kconfig @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE image +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this image +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this image except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# Under the License. + +config CBORATTR_MAX_SIZE + int "Maximum chunk size for image uploads" + default 512 + help + The maximum size of a CBOR attribute during decoding diff --git a/cborattr/include/cborattr/cborattr.h b/cborattr/include/cborattr/cborattr.h index 941f251e..de1bafe5 100644 --- a/cborattr/include/cborattr/cborattr.h +++ b/cborattr/include/cborattr/cborattr.h @@ -121,6 +121,43 @@ struct cbor_attr_t { bool nodefault; }; +#ifndef __ZEPHYR__ +/** An array value to be encoded as CBOR. */ + struct cbor_out_arr_val_t { + struct cbor_out_val_t *elems; + size_t len; + }; + +/** A single value to be encoded as CBOR. */ + struct cbor_out_val_t { + /** The type of data. */ + CborAttrType type; + + /** The data value. */ + union { + long long int integer; + long long unsigned int uinteger; + double real; + float fval; + const char *string; + bool boolean; + struct { + const uint8_t *data; + size_t len; + } bytestring; + struct cbor_out_arr_val_t array; + struct cbor_out_attr_t *obj; /* Terminated with a type=0 entry. */ + }; + }; + +/** An object key-value pair to be encoded as CBOR. */ +struct cbor_out_attr_t { + const char *attribute; /** The attribute name (key). */ + struct cbor_out_val_t val; /** The attribute value. */ + bool omit; /** Attribute ignored if true. */ +}; +#endif + /* * Use the following macros to declare template initializers for * CborAttrStructObjectType arrays. Writing the equivalents out by hand is @@ -151,8 +188,30 @@ int cbor_read_flat_attrs(const uint8_t *data, int len, #ifndef __ZEPHYR__ int cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, const struct cbor_attr_t *attrs); -#endif +/** + * @brief Encodes a CBOR representation of the specified key-value map. + * + * @param enc The CBOR encoder to write to. + * @param attrs The key-value map to encode. + * + * @return 0 on success; SYS_E[...] error on failure. + */ +int cbor_write_object(struct CborEncoder *enc, + const struct cbor_out_attr_t *attrs); + +/** + * @brief Encodes a CBOR representation of the specified key-value map into an + * msys mbuf chain. + * + * @param attrs The key-value map to encode. + * @param out_om On success, points to the populate mbuf chain. + * + * @return 0 on success; SYS_E[...] error on failure. + */ +int cbor_write_object_msys(const struct cbor_out_attr_t *attrs, + struct os_mbuf **out_om); +#endif #ifdef __cplusplus } #endif diff --git a/cborattr/src/cborattr.c b/cborattr/src/cborattr.c index c2ebf3e2..280b085a 100644 --- a/cborattr/src/cborattr.c +++ b/cborattr/src/cborattr.c @@ -24,10 +24,16 @@ #ifndef __ZEPHYR__ #include "tinycbor/cbor_mbuf_reader.h" +#include "tinycbor/cbor_mbuf_writer.h" #include "os/os_mbuf.h" +#define CBORATTR_MAX_SIZE MYNEWT_VAL(CBORATTR_MAX_SIZE) +#else +#define CBORATTR_MAX_SIZE CONFIG_CBORATTR_MAX_SIZE #endif -#define CBORATTR_MAX_SIZE 512 + +static int cbor_write_val(struct CborEncoder *enc, + const struct cbor_out_val_t *val); /* this maps a CborType to a matching CborAtter Type. The mapping is not * one-to-one because of signedness of integers @@ -185,6 +191,7 @@ cbor_internal_read_object(CborValue *root_value, } } + if (cbor_value_is_map(root_value)) { err |= cbor_value_enter_container(root_value, &cur_value); } else { @@ -430,5 +437,181 @@ cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, } return cbor_read_object(&value, attrs); } + +static int +cbor_write_arr_val(struct CborEncoder *enc, + const struct cbor_out_arr_val_t *arr) +{ + struct CborEncoder arr_enc; + size_t i; + int rc; + + rc = cbor_encoder_create_array(enc, &arr_enc, arr->len); + if (rc != 0) { + return SYS_ENOMEM; + } + + for (i = 0; i < arr->len; i++) { + rc = cbor_write_val(&arr_enc, &arr->elems[i]); + if (rc != 0) { + return SYS_ENOMEM; + } + } + + rc = cbor_encoder_close_container(enc, &arr_enc); + if (rc != 0) { + return SYS_ENOMEM; + } + + return 0; +} + +static int +cbor_write_val(struct CborEncoder *enc, const struct cbor_out_val_t *val) +{ + int len; + int rc; + + switch (val->type) { + case CborAttrNullType: + rc = cbor_encode_null(enc); + break; + + case CborAttrBooleanType: + rc = cbor_encode_boolean(enc, val->boolean); + break; + + case CborAttrIntegerType: + rc = cbor_encode_int(enc, val->integer); + break; + + case CborAttrUnsignedIntegerType: + rc = cbor_encode_uint(enc, val->uinteger); + break; + +#if FLOAT_SUPPORT + case CborAttrFloatType: + rc = cbor_encode_float(enc, val->fval); + break; + + case CborAttrDoubleType: + rc = cbor_encode_double(enc, val->real); + break; #endif + case CborAttrByteStringType: + if (val->bytestring.data == NULL && + val->bytestring.len != 0) { + + return SYS_EINVAL; + } + + rc = cbor_encode_byte_string(enc, val->bytestring.data, + val->bytestring.len); + break; + + case CborAttrTextStringType: + if (val->string == NULL) { + len = 0; + } else { + len = strlen(val->string); + } + rc = cbor_encode_text_string(enc, val->string, len); + break; + + case CborAttrObjectType: + rc = cbor_write_object(enc, val->obj); + break; + + case CborAttrArrayType: + rc = cbor_write_arr_val(enc, &val->array); + break; + + default: + return SYS_ENOTSUP; + } + + if (rc != 0) { + return SYS_ENOMEM; + } + + return 0; +} + +static int +cbor_write_attr(struct CborEncoder *enc, const struct cbor_out_attr_t *attr) +{ + int len; + int rc; + + if (attr->omit) { + return 0; + } + + len = strlen(attr->attribute); + rc = cbor_encode_text_string(enc, attr->attribute, len); + if (rc != 0) { + return rc; + } + + rc = cbor_write_val(enc, &attr->val); + if (rc != 0) { + return rc; + } + + return 0; +} + +int +cbor_write_object(struct CborEncoder *enc, const struct cbor_out_attr_t *attrs) +{ + const struct cbor_out_attr_t *attr; + struct CborEncoder map; + int rc; + + rc = cbor_encoder_create_map(enc, &map, CborIndefiniteLength); + if (rc != 0) { + return SYS_ENOMEM; + } + + for (attr = attrs; attr->val.type != 0; attr++) { + rc = cbor_write_attr(&map, attr); + if (rc != 0) { + return rc; + } + } + + rc = cbor_encoder_close_container(enc, &map); + if (rc != 0) { + return SYS_ENOMEM; + } + + return 0; +} + +int +cbor_write_object_msys(const struct cbor_out_attr_t *attrs, + struct os_mbuf **out_om) +{ + struct cbor_mbuf_writer writer; + struct CborEncoder encoder; + int rc; + + *out_om = os_msys_get_pkthdr(0, 0); + if (*out_om == NULL) { + return SYS_ENOMEM; + } + + cbor_mbuf_writer_init(&writer, *out_om); + cbor_encoder_init(&encoder, &writer.enc, 0); + + rc = cbor_write_object(&encoder, attrs); + if (rc != 0) { + os_mbuf_free_chain(*out_om); + *out_om = NULL; + return rc; + } + + return 0; +} +#endif diff --git a/cborattr/test/src/test_cborattr.h b/cborattr/test/src/test_cborattr.h index 815048f5..1a6012b6 100644 --- a/cborattr/test/src/test_cborattr.h +++ b/cborattr/test/src/test_cborattr.h @@ -35,6 +35,8 @@ extern "C" { */ const uint8_t *test_str1(int *len); +void cborattr_test_util_encode(const struct cbor_out_attr_t *attrs, + const uint8_t *expected, int len); /* * Testcases */ diff --git a/cborattr/test/src/test_cborattr_utils.c b/cborattr/test/src/test_cborattr_utils.c index 0a43766b..d520e069 100644 --- a/cborattr/test/src/test_cborattr_utils.c +++ b/cborattr/test/src/test_cborattr_utils.c @@ -33,3 +33,18 @@ test_str1(int *len) *len = sizeof(test_data1); return (test_data1); } + +void +cborattr_test_util_encode(const struct cbor_out_attr_t *attrs, + const uint8_t *expected, int len) +{ + struct os_mbuf *om; + int rc; + + rc = cbor_write_object_msys(attrs, &om); + TEST_ASSERT_FATAL(rc == 0); + + TEST_ASSERT(os_mbuf_cmpf(om, 0, expected, len) == 0); + + os_mbuf_free_chain(om); +} diff --git a/cborattr/test/src/testcases/cborattr_encode_omit.c b/cborattr/test/src/testcases/cborattr_encode_omit.c index 4b31c6aa..7d6b91fc 100644 --- a/cborattr/test/src/testcases/cborattr_encode_omit.c +++ b/cborattr/test/src/testcases/cborattr_encode_omit.c @@ -21,7 +21,7 @@ TEST_CASE_SELF(test_cborattr_encode_omit) { /* Omit everything except the "str" value. */ - const struct cbor_out_attr_t attrs[] = { + const struct cbor_out_attr_t attrs[11] = { { .attribute = "null", .val = { From 4d8078f30b0c0d48b4592db33aec3c7ae619ae6e Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Thu, 12 Sep 2019 01:21:57 +0100 Subject: [PATCH 45/65] adding cborattr dependency on omp --- omp/pkg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omp/pkg.yml b/omp/pkg.yml index ac5a57bc..af293f4d 100644 --- a/omp/pkg.yml +++ b/omp/pkg.yml @@ -28,7 +28,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-mcumgr/mgmt" + - "@apache-mynewt-mcumgr/cborattr" pkg.apis: - smp From 635d701eaded33b125a69225f85a0df57f7de954 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Fri, 13 Sep 2019 02:24:56 +0100 Subject: [PATCH 46/65] Fix os_mgmt conditional feature enablement --- cmd/os_mgmt/src/os_mgmt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/os_mgmt/src/os_mgmt.c b/cmd/os_mgmt/src/os_mgmt.c index fa550ffb..9a0db2a2 100644 --- a/cmd/os_mgmt/src/os_mgmt.c +++ b/cmd/os_mgmt/src/os_mgmt.c @@ -26,23 +26,23 @@ #include "os_mgmt/os_mgmt_impl.h" #include "os_mgmt_config.h" -#ifdef OS_MGMT_ECHO +#if OS_MGMT_ECHO static mgmt_handler_fn os_mgmt_echo; #endif static mgmt_handler_fn os_mgmt_reset; -#ifdef OS_MGMT_TASKSTAT +#if 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 +#if OS_MGMT_ECHO [OS_MGMT_ID_ECHO] = { os_mgmt_echo, os_mgmt_echo }, #endif -#ifdef OS_MGMT_TASKSTAT +#if OS_MGMT_TASKSTAT [OS_MGMT_ID_TASKSTAT] = { os_mgmt_taskstat_read, NULL }, @@ -64,7 +64,7 @@ static struct mgmt_group os_mgmt_group = { /** * Command handler: os echo */ -#ifdef OS_MGMT_ECHO +#if OS_MGMT_ECHO static int os_mgmt_echo(struct mgmt_ctxt *ctxt) { @@ -102,7 +102,7 @@ os_mgmt_echo(struct mgmt_ctxt *ctxt) } #endif -#ifdef OS_MGMT_TASKSTAT +#if OS_MGMT_TASKSTAT /** * Encodes a single taskstat entry. */ From 3676852950177f39c1f0f9294444e69cb6e42ec7 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 13 Sep 2019 14:32:29 -0700 Subject: [PATCH 47/65] stat_mgmt: fix stat list crash --- cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c b/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c index bede2944..75bb723a 100644 --- a/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c +++ b/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c @@ -35,18 +35,25 @@ stat_mgmt_impl_get_group(int idx, const char **out_name) { const struct stats_hdr *cur; int i; + int rc; + + rc = MGMT_ERR_ENOENT; cur = NULL; i = 0; STAILQ_FOREACH(cur, &g_stats_registry, s_next) { - if (i > idx) { + if (i == idx) { + rc = 0; break; } i++; } - *out_name = cur->s_name; - return 0; + if (!rc) { + *out_name = cur->s_name; + } + + return rc; } static int From 82a11298600de0981ffbdfbcc613a6f1d82ec1d7 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 25 Sep 2019 11:58:46 -0700 Subject: [PATCH 48/65] stat_mgmt: Fix cbor container issues --- cmd/stat_mgmt/src/stat_mgmt.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cmd/stat_mgmt/src/stat_mgmt.c b/cmd/stat_mgmt/src/stat_mgmt.c index e7cec8be..2f03a748 100644 --- a/cmd/stat_mgmt/src/stat_mgmt.c +++ b/cmd/stat_mgmt/src/stat_mgmt.c @@ -100,17 +100,13 @@ stat_mgmt_show(struct mgmt_ctxt *ctxt) rc = stat_mgmt_impl_foreach_entry(stat_name, stat_mgmt_cb_encode, &map_enc); - if (rc != 0) { - return rc; - } err |= cbor_encoder_close_container(&ctxt->encoder, &map_enc); - if (err != 0) { - return MGMT_ERR_ENOMEM; + rc = MGMT_ERR_ENOMEM; } - return 0; + return rc; } /** From bd31d22d727ef9eccd7eb69d0c3a6ac54c9285dc Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Thu, 26 Sep 2019 01:13:25 +0100 Subject: [PATCH 49/65] Fixing log body read size. --- cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index f044f4ad..50bec897 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -142,15 +142,15 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, entry.type = LOG_ETYPE_STRING; entry.flags = 0; header_len = sizeof leh; + read_len = min(len - header_len, LOG_MGMT_BODY_LEN - header_len); #else entry.type = leh->ue_etype; entry.flags = leh->ue_flags; entry.imghash = (leh->ue_flags & LOG_FLAGS_IMG_HASH) ? leh->ue_imghash : NULL; header_len = log_hdr_len(leh); + read_len = LOG_MGMT_BODY_LEN - header_len; #endif - - read_len = min(len - header_len, LOG_MGMT_BODY_LEN - header_len); rc = log_read(log, dptr, mynewt_log_mgmt_walk_arg->body, header_len, read_len); if (rc < 0) { From 63e5fb9dfc9fe9f6c016d5146e99579283fbffd0 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 25 Sep 2019 17:34:49 -0700 Subject: [PATCH 50/65] log_mgmt: Use log max len for reading log entries --- cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index 50bec897..eaeb6eaf 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -25,7 +25,7 @@ struct mynewt_log_mgmt_walk_arg { log_mgmt_foreach_entry_fn *cb; - uint8_t body[LOG_MGMT_BODY_LEN]; + uint8_t body[LOG_MGMT_CHUNK_SIZE]; void *arg; }; @@ -142,14 +142,14 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, entry.type = LOG_ETYPE_STRING; entry.flags = 0; header_len = sizeof leh; - read_len = min(len - header_len, LOG_MGMT_BODY_LEN - header_len); + read_len = min(len - header_len, log->l_max_entry_len - header_len); #else entry.type = leh->ue_etype; entry.flags = leh->ue_flags; entry.imghash = (leh->ue_flags & LOG_FLAGS_IMG_HASH) ? leh->ue_imghash : NULL; header_len = log_hdr_len(leh); - read_len = LOG_MGMT_BODY_LEN - header_len; + read_len = log->l_max_entry_len - header_len; #endif rc = log_read(log, dptr, mynewt_log_mgmt_walk_arg->body, header_len, read_len); From 43e485fda081cf61d828b48c22075bc1dd291a93 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 25 Sep 2019 19:08:15 -0700 Subject: [PATCH 51/65] mynewt_log_mgmt: need to read chunk by chunk - Earlier the entries were read one entry at a time and that is different what we have currently in mynewt, this needs to change so that we read logs hcunk by chunk until we reach the entry length - The encode funtion needs to get fixed which will be in a subsequent PR --- .../port/mynewt/src/mynewt_log_mgmt.c | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index eaeb6eaf..30a3451f 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -25,7 +25,7 @@ struct mynewt_log_mgmt_walk_arg { log_mgmt_foreach_entry_fn *cb; - uint8_t body[LOG_MGMT_CHUNK_SIZE]; + uint8_t chunk[128]; void *arg; }; @@ -108,8 +108,8 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, { struct mynewt_log_mgmt_walk_arg *mynewt_log_mgmt_walk_arg; struct log_mgmt_entry entry; - int header_len; int read_len; + int offset; int rc; mynewt_log_mgmt_walk_arg = log_offset->lo_arg; @@ -141,25 +141,34 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, #if MYNEWT_VAL(LOG_VERSION) < 3 entry.type = LOG_ETYPE_STRING; entry.flags = 0; - header_len = sizeof leh; - read_len = min(len - header_len, log->l_max_entry_len - header_len); #else entry.type = leh->ue_etype; entry.flags = leh->ue_flags; entry.imghash = (leh->ue_flags & LOG_FLAGS_IMG_HASH) ? leh->ue_imghash : NULL; - header_len = log_hdr_len(leh); - read_len = log->l_max_entry_len - header_len; #endif - rc = log_read(log, dptr, mynewt_log_mgmt_walk_arg->body, header_len, - read_len); - if (rc < 0) { - return MGMT_ERR_EUNKNOWN; + + for (offset = 0; offset < len; offset += 128) { + if (len - offset < 128) { + read_len = len - offset; + } else { + read_len = 128; + } + + rc = log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, + read_len); + if (rc < 0) { + return MGMT_ERR_EUNKNOWN; + } + entry.len = rc; + entry.data = mynewt_log_mgmt_walk_arg->chunk; + rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); + if (rc) { + return rc; + } } - entry.len = rc; - entry.data = mynewt_log_mgmt_walk_arg->body; - return mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); + return 0; } int From a2fd55c4b1216e8e416353356ad601f3769495d4 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 26 Sep 2019 11:29:40 -0700 Subject: [PATCH 52/65] log_mgmt: log entry shld get encoded at the end - Log entries get read chunk by chunk and should get encoded at the end --- cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index 30a3451f..f73de8ef 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -112,6 +112,7 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, int offset; int rc; + rc = 0; mynewt_log_mgmt_walk_arg = log_offset->lo_arg; /* If specified timestamp is nonzero, it is the primary criterion, and the @@ -155,17 +156,18 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, read_len = 128; } - rc = log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, - read_len); + rc += log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, + read_len); if (rc < 0) { return MGMT_ERR_EUNKNOWN; } - entry.len = rc; - entry.data = mynewt_log_mgmt_walk_arg->chunk; - rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); - if (rc) { - return rc; - } + } + + entry.len = rc; + entry.data = mynewt_log_mgmt_walk_arg->chunk; + rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); + if (rc) { + return rc; } return 0; From 3ead348ed470b7093bde70a9b6bed77af30716c1 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 26 Sep 2019 11:59:21 -0700 Subject: [PATCH 53/65] mynewt_log_mgmt:syscfg changes chunked log reads - Earlier while reading logs were not chunked and now they are chunked, syscfgs have to match that functional approach --- cmd/log_mgmt/Kconfig | 46 +++++++++++++++++++ .../port/mynewt/src/mynewt_log_mgmt.c | 8 ++-- cmd/log_mgmt/port/mynewt/syscfg.yml | 16 +++---- cmd/log_mgmt/src/log_mgmt.c | 6 +-- cmd/log_mgmt/src/log_mgmt_config.h | 8 ++-- 5 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 cmd/log_mgmt/Kconfig diff --git a/cmd/log_mgmt/Kconfig b/cmd/log_mgmt/Kconfig new file mode 100644 index 00000000..366a85f7 --- /dev/null +++ b/cmd/log_mgmt/Kconfig @@ -0,0 +1,46 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE log +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this log +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this log except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# Under the License. + +menuconfig MCUMGR_CMD_LOG_MGMT + bool "Enable mcumgr handlers for log management" + help + Enables mcumgr handlers for log management + +if MCUMGR_CMD_LOG_MGMT +config LOG_MGMT_MAX_RSP_LEN + int "Maximum MCUmgr response len for log downloads" + default 512 + help + Limits the maximum response len for log downloads, in bytes. + +config LOG_MGMT_NAME_LEN + int "Maximum log name length" + default 64 + help + Limits the maximum length of log names, in bytes. If a log's name length + exceeds this number, it gets truncated in management responses. A buffer + of this size gets allocated on the stack during handling of all log + management commands. + +config LOG_MGMT_CHUNK_LEN + int "Maximum log chunk length" + default 128 + help + Limits the maximum length of log entry bodies chunks, so, every log entry gets + read in chunks upto a point where the entire entry is read. Also, a buffer gets + allocated on the stack with this size. +endif diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index f73de8ef..33b31b90 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -25,7 +25,7 @@ struct mynewt_log_mgmt_walk_arg { log_mgmt_foreach_entry_fn *cb; - uint8_t chunk[128]; + uint8_t chunk[LOG_MGMT_CHUNK_LEN]; void *arg; }; @@ -149,11 +149,11 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, leh->ue_imghash : NULL; #endif - for (offset = 0; offset < len; offset += 128) { - if (len - offset < 128) { + for (offset = 0; offset < len; offset += LOG_MGMT_CHUNK_LEN) { + if (len - offset < LOG_MGMT_CHUNK_LEN) { read_len = len - offset; } else { - read_len = 128; + read_len = LOG_MGMT_CHUNK_LEN; } rc += log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, diff --git a/cmd/log_mgmt/port/mynewt/syscfg.yml b/cmd/log_mgmt/port/mynewt/syscfg.yml index d397e352..7ab39d90 100644 --- a/cmd/log_mgmt/port/mynewt/syscfg.yml +++ b/cmd/log_mgmt/port/mynewt/syscfg.yml @@ -17,18 +17,16 @@ # syscfg.defs: - LOG_MGMT_BODY_LEN: + LOG_MGMT_CHUNK_LEN: description: > - Limits the maximum length of log entry bodies, in bytes. If a log - entry's body length exceeds this number, it gets truncated in management - responses. A buffer of this size gets allocated on the stack during - handling of the log show command. + Limits the maximum length of log entry bodies chunks, so, every log entry gets + read in chunks upto a point where the entire entry is read. Also, a buffer gets + allocated on the stack with this size. value: 128 - LOG_MGMT_CHUNK_SIZE: + LOG_MGMT_MAX_RSP_LEN: description: > - Limits the maximum chunk size for log downloads, in bytes. A buffer of - this size gets allocated on the stack during handling of the log show command. + Limits the maximum chunk len for log downloads, in bytes. value: 512 LOG_MGMT_NAME_LEN: @@ -41,4 +39,4 @@ syscfg.defs: # For backwards compatibility with log nmgr syscfg.vals.LOG_NMGR_MAX_RSP_LEN: - LOG_MGMT_CHUNK_SIZE: MYNEWT_VAL(LOG_NMGR_MAX_RSP_LEN) + LOG_MGMT_MAX_RSP_SIZE: MYNEWT_VAL(LOG_NMGR_MAX_RSP_LEN) diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 5bb4f5c9..a9650cdb 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -161,14 +161,14 @@ log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) * is just a single entry we add the generic too long message text. */ /* `+ 1` to account for the CBOR array terminator. */ - if (ctxt->rsp_len + entry_len + 1 > LOG_MGMT_CHUNK_SIZE) { + if (ctxt->rsp_len + entry_len + 1 > LOG_MGMT_MAX_RSP_LEN) { /* * Is this just a single entry? If so, encode the generic error * message in the "msg" field of the response */ if (ctxt->counter == 0) { entry->type = LOG_ETYPE_STRING; - snprintf((char *)entry->data, LOG_MGMT_BODY_LEN, + snprintf((char *)entry->data, LOG_MGMT_MAX_RSP_LEN, "error: entry too large (%d bytes)", entry_len); } @@ -176,7 +176,7 @@ log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) } ctxt->rsp_len += entry_len; - /*** The entry fits. Now encode it. */ + /*** The entry fits. Now encode it. */ rc = log_mgmt_encode_entry(ctxt->enc, entry, NULL); if (rc != 0) { diff --git a/cmd/log_mgmt/src/log_mgmt_config.h b/cmd/log_mgmt/src/log_mgmt_config.h index 058f431e..914b9b5b 100644 --- a/cmd/log_mgmt/src/log_mgmt_config.h +++ b/cmd/log_mgmt/src/log_mgmt_config.h @@ -24,16 +24,16 @@ #include "syscfg/syscfg.h" -#define LOG_MGMT_CHUNK_SIZE MYNEWT_VAL(LOG_MGMT_CHUNK_SIZE) +#define LOG_MGMT_CHUNK_LEN MYNEWT_VAL(LOG_MGMT_CHUNK_LEN) #define LOG_MGMT_NAME_LEN MYNEWT_VAL(LOG_MGMT_NAME_LEN) -#define LOG_MGMT_BODY_LEN MYNEWT_VAL(LOG_MGMT_BODY_LEN) +#define LOG_MGMT_MAX_RSP_LEN MYNEWT_VAL(LOG_MGMT_MAX_RSP_LEN) #define LOG_MGMT_IMG_HASHLEN 4 #elif defined __ZEPHYR__ -#define LOG_MGMT_CHUNK_SIZE CONFIG_LOG_MGMT_CHUNK_SIZE +#define LOG_MGMT_CHUNK_LEN CONFIG_LOG_MGMT_CHUNK_LEN #define LOG_MGMT_NAME_LEN CONFIG_LOG_MGMT_NAME_LEN -#define LOG_MGMT_BODY_LEN CONFIG_LOG_MGMT_BODY_LEN +#define LOG_MGMT_MAX_RSP_LEN CONFIG_LOG_MGMT_MAX_RSP_LEN #else From dd0178ff3e33f517cc6c75752f31deaa44b52c0d Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Thu, 26 Sep 2019 13:40:20 -0700 Subject: [PATCH 54/65] log_mgmt: fix includes --- cmd/log_mgmt/pkg.yml | 1 + cmd/log_mgmt/src/log_mgmt.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/log_mgmt/pkg.yml b/cmd/log_mgmt/pkg.yml index b774840c..2c6f470f 100644 --- a/cmd/log_mgmt/pkg.yml +++ b/cmd/log_mgmt/pkg.yml @@ -25,5 +25,6 @@ pkg.keywords: pkg.deps: - '@apache-mynewt-core/kernel/os' + - '@apache-mynewt-core/sys/log/full' - '@apache-mynewt-mcumgr/cmd/log_mgmt/port/mynewt' - '@apache-mynewt-mcumgr/mgmt' diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index a9650cdb..9af2548c 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -26,7 +26,6 @@ #include "log_mgmt/log_mgmt.h" #include "log_mgmt/log_mgmt_impl.h" #include "log_mgmt_config.h" -#include "log_common/log_common.h" #include "log/log.h" /** Context used during walks. */ From a181f391ab239f0e782513bfdc8483e92a46e579 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 27 Sep 2019 15:34:25 -0700 Subject: [PATCH 55/65] log_mgmt: errors should be caught per chunk --- cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index 33b31b90..d973bb2a 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -110,9 +110,9 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, struct log_mgmt_entry entry; int read_len; int offset; - int rc; + int rc, entrylen; - rc = 0; + entrylen = 0; mynewt_log_mgmt_walk_arg = log_offset->lo_arg; /* If specified timestamp is nonzero, it is the primary criterion, and the @@ -156,14 +156,15 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, read_len = LOG_MGMT_CHUNK_LEN; } - rc += log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, - read_len); + rc = log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, + read_len); if (rc < 0) { return MGMT_ERR_EUNKNOWN; } + entrylen += rc; } - entry.len = rc; + entry.len = entrylen; entry.data = mynewt_log_mgmt_walk_arg->chunk; rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); if (rc) { From 3d9943f0eab2a188b821e8e66724495fd0bbbe69 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Fri, 27 Sep 2019 17:45:32 -0700 Subject: [PATCH 56/65] img_mgmt: add img_mgmt logging from mynewt-core --- cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h | 6 + cmd/img_mgmt/port/mynewt/pkg.yml | 1 + .../port/mynewt/src/mynewt_img_mgmt.c | 14 -- .../port/mynewt/src/mynewt_img_mgmt_log.c | 141 ++++++++++++++++++ cmd/img_mgmt/port/mynewt/syscfg.yml | 30 ++++ cmd/img_mgmt/src/img_mgmt_state.c | 30 +++- 6 files changed, 202 insertions(+), 20 deletions(-) create mode 100644 cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt_log.c create mode 100644 cmd/img_mgmt/port/mynewt/syscfg.yml diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h index ab5a69ba..ef249ac6 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h @@ -163,6 +163,12 @@ img_mgmt_impl_log_upload_start(int status); int img_mgmt_impl_log_upload_done(int status, const uint8_t *hashp); +int +img_mgmt_impl_log_pending(int status, const uint8_t *hash); + +int +img_mgmt_impl_log_confirm(int status, const uint8_t *hash); + #ifdef __cplusplus } #endif diff --git a/cmd/img_mgmt/port/mynewt/pkg.yml b/cmd/img_mgmt/port/mynewt/pkg.yml index b4c9f2cc..abe4c811 100644 --- a/cmd/img_mgmt/port/mynewt/pkg.yml +++ b/cmd/img_mgmt/port/mynewt/pkg.yml @@ -26,6 +26,7 @@ pkg.keywords: pkg.deps: - '@apache-mynewt-mcumgr/cmd/img_mgmt' + - '@apache-mynewt-core/sys/log/modlog' pkg.init: img_mgmt_module_init: 501 diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c index a66c0e4a..6a1208e1 100644 --- a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c @@ -540,17 +540,3 @@ img_mgmt_module_init(void) upload_state.sector_id = -1; upload_state.sector_end = 0; } - -int -img_mgmt_impl_log_upload_start(int status) -{ - return 0; -} - -int -img_mgmt_impl_log_upload_done(int status, const uint8_t *hashp) -{ - return 0; -} - - diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt_log.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt_log.c new file mode 100644 index 00000000..ad4cfd8b --- /dev/null +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt_log.c @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "os/mynewt.h" +#include "modlog/modlog.h" +#include "cborattr/cborattr.h" +#include "img_mgmt/img_mgmt.h" + +/** + * Log event types (all events are CBOR-encoded): + * + * upstart: + * When: upon receiving an upload request with an offset of 0. + * Structure: + * { + * "ev": "upstart", + * "rc": + * } + * + * updone: + * When: upon receiving an upload request containing the final chunk of an + * image OR a failed upload request with a non-zero offset. + * Structure: + * { + * "ev": "updone", + * "rc": + * "hs": (only present on success) + * } + * + * pend: + * When: upon receiving a non-permanent `set-pending` request. + * Structure: + * { + * "ev": "pend", + * "rc": , + * "hs": + * } + * + * conf: + * When: upon receiving a `confirm` request OR a permanent `set-pending` + * request. + * Structure: + * { + * "ev": "conf", + * "rc": , + * "hs": (only present for `set-pending`) + * } + */ + +#define IMG_MGMT_LOG_EV_UPSTART "upstart" +#define IMG_MGMT_LOG_EV_UPDONE "updone" +#define IMG_MGMT_LOG_EV_PEND "pend" +#define IMG_MGMT_LOG_EV_CONF "conf" + +static int +img_mgmt_log_gen(const char *ev, int status, const uint8_t *hash) +{ +#if MYNEWT_VAL(LOG_VERSION) > 2 && \ + LOG_MOD_LEVEL_IS_ACTIVE(MYNEWT_VAL(IMG_MGMT_LOG_LVL), LOG_LEVEL_INFO) + + struct os_mbuf *om; + int rc; + + const struct cbor_out_attr_t attrs[] = { + { + .attribute = "ev", + .val = { + .type = CborAttrTextStringType, + .string = ev, + }, + }, + { + .attribute = "rc", + .val = { + .type = CborAttrIntegerType, + .integer = status, + }, + }, + { + .attribute = "hs", + .val = { + .type = CborAttrByteStringType, + .bytestring.data = hash, + .bytestring.len = IMG_MGMT_HASH_LEN, + }, + .omit = hash == NULL, + }, + { 0 } + }; + + rc = cbor_write_object_msys(attrs, &om); + if (rc != 0) { + return rc; + } + + modlog_append_mbuf(MYNEWT_VAL(IMG_MGMT_LOG_MOD), LOG_LEVEL_INFO, + LOG_ETYPE_CBOR, om); +#endif + + return 0; +} + +int +img_mgmt_impl_log_upload_start(int status) +{ + return img_mgmt_log_gen(IMG_MGMT_LOG_EV_UPSTART, status, NULL); +} + +int +img_mgmt_impl_log_upload_done(int status, const uint8_t *hash) +{ + return img_mgmt_log_gen(IMG_MGMT_LOG_EV_UPDONE, 0, hash); +} + +int +img_mgmt_impl_log_pending(int status, const uint8_t *hash) +{ + return img_mgmt_log_gen(IMG_MGMT_LOG_EV_PEND, status, hash); +} + +int +img_mgmt_impl_log_confirm(int status, const uint8_t *hash) +{ + return img_mgmt_log_gen(IMG_MGMT_LOG_EV_CONF, status, hash); +} diff --git a/cmd/img_mgmt/port/mynewt/syscfg.yml b/cmd/img_mgmt/port/mynewt/syscfg.yml new file mode 100644 index 00000000..4d09eba3 --- /dev/null +++ b/cmd/img_mgmt/port/mynewt/syscfg.yml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + IMG_MGMT_LOG_MOD: + description: 'Module ID for the image management structured log.' + value: 176 + IMG_MGMT_LOG_LVL: + description: 'Minimum level for the image management structured log.' + value: 15 # Log disabled by default. + +syscfg.logs: + IMG_MGMT_LOG: + module: MYNEWT_VAL(IMG_MGMT_LOG_MOD) + level: MYNEWT_VAL(IMG_MGMT_LOG_LVL) diff --git a/cmd/img_mgmt/src/img_mgmt_state.c b/cmd/img_mgmt/src/img_mgmt_state.c index 16d0a3ae..05798a82 100644 --- a/cmd/img_mgmt/src/img_mgmt_state.c +++ b/cmd/img_mgmt/src/img_mgmt_state.c @@ -120,7 +120,9 @@ img_mgmt_slot_in_use(int slot) int img_mgmt_state_set_pending(int slot, int permanent) { + uint8_t hash[IMAGE_HASH_LEN]; uint8_t state_flags; + const uint8_t *hashp; int rc; state_flags = img_mgmt_state_flags(slot); @@ -129,15 +131,29 @@ img_mgmt_state_set_pending(int slot, int permanent) * run if it is a loader in a split image setup. */ if (state_flags & IMG_MGMT_STATE_F_CONFIRMED && slot != 0) { - return MGMT_ERR_EBADSTATE; + rc = MGMT_ERR_EBADSTATE; + goto done; } rc = img_mgmt_impl_write_pending(slot, permanent); if (rc != 0) { - return MGMT_ERR_EUNKNOWN; + rc = MGMT_ERR_EUNKNOWN; } - return 0; +done: + /* Log the image hash if we know it. */ + rc = img_mgmt_read_info(slot, NULL, hash, NULL); + if (rc != 0) { + hashp = NULL; + } else { + hashp = hash; + } + + if (permanent) { + return img_mgmt_impl_log_confirm(rc, hashp); + } else { + return img_mgmt_impl_log_pending(rc, hashp); + } } /** @@ -151,15 +167,17 @@ img_mgmt_state_confirm(void) /* Confirm disallowed if a test is pending. */ if (img_mgmt_state_any_pending()) { - return MGMT_ERR_EBADSTATE; + rc = MGMT_ERR_EBADSTATE; + goto err; } rc = img_mgmt_impl_write_confirmed(); if (rc != 0) { - return MGMT_ERR_EUNKNOWN; + rc = MGMT_ERR_EUNKNOWN; } - return 0; +err: + return img_mgmt_impl_log_confirm(rc, NULL); } /** From ee7c1ac8a8c6baab11f50485cdcf37279ade0dc0 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Mon, 30 Sep 2019 18:51:40 +0100 Subject: [PATCH 57/65] Closing CBOR containers on error situations before returning. --- cmd/log_mgmt/src/log_mgmt.c | 8 ++++++++ cmd/os_mgmt/src/os_mgmt.c | 1 + cmd/stat_mgmt/src/stat_mgmt.c | 1 + 3 files changed, 10 insertions(+) diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 9af2548c..dc7731aa 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -89,6 +89,7 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, err |= cbor_encode_text_stringz(&rsp, "str"); break; default: + cbor_encoder_close_container(&rsp, &str_encoder); return MGMT_ERR_ECORRUPT; } @@ -213,6 +214,7 @@ log_encode_entries(const struct log_mgmt_log *log, CborEncoder *enc, rc = log_mgmt_impl_foreach_entry(log->name, &filter, log_mgmt_cb_encode, &ctxt); if (rc != 0 && rc != MGMT_ERR_EMSGSIZE) { + cbor_encoder_close_container(enc, &entries); return rc; } @@ -242,6 +244,7 @@ log_encode(const struct log_mgmt_log *log, CborEncoder *ctxt, rc = log_encode_entries(log, &logs, timestamp, index); if (rc != 0) { + cbor_encoder_close_container(ctxt, &logs); return rc; } @@ -327,6 +330,7 @@ log_mgmt_show(struct mgmt_ctxt *ctxt) break; } } else if (rc != 0) { + cbor_encoder_close_container(&ctxt->encoder, &logs); return rc; } @@ -335,6 +339,7 @@ log_mgmt_show(struct mgmt_ctxt *ctxt) if (name_len == 0 || strcmp(name, log.name) == 0) { rc = log_encode(&log, &logs, timestamp, index); if (rc != 0) { + cbor_encoder_close_container(&ctxt->encoder, &logs); return rc; } @@ -384,6 +389,7 @@ log_mgmt_module_list(struct mgmt_ctxt *ctxt) break; } if (rc != 0) { + cbor_encoder_close_container(&ctxt->encoder, &modules); return rc; } @@ -427,6 +433,7 @@ log_mgmt_logs_list(struct mgmt_ctxt *ctxt) break; } if (rc != 0) { + cbor_encoder_close_container(&ctxt->encoder, &log_list); return rc; } @@ -469,6 +476,7 @@ log_mgmt_level_list(struct mgmt_ctxt *ctxt) break; } if (rc != 0) { + cbor_encoder_close_container(&ctxt->encoder, &level_map); return rc; } diff --git a/cmd/os_mgmt/src/os_mgmt.c b/cmd/os_mgmt/src/os_mgmt.c index 9a0db2a2..03d3dabc 100644 --- a/cmd/os_mgmt/src/os_mgmt.c +++ b/cmd/os_mgmt/src/os_mgmt.c @@ -175,6 +175,7 @@ os_mgmt_taskstat_read(struct mgmt_ctxt *ctxt) rc = os_mgmt_taskstat_encode_one(&tasks_map, &task_info); if (rc != 0) { + cbor_encoder_close_container(&ctxt->encoder, &tasks_map); return rc; } } diff --git a/cmd/stat_mgmt/src/stat_mgmt.c b/cmd/stat_mgmt/src/stat_mgmt.c index 2f03a748..994d7c88 100644 --- a/cmd/stat_mgmt/src/stat_mgmt.c +++ b/cmd/stat_mgmt/src/stat_mgmt.c @@ -138,6 +138,7 @@ stat_mgmt_list(struct mgmt_ctxt *ctxt) break; } else if (rc != 0) { /* Error. */ + cbor_encoder_close_container(&ctxt->encoder, &arr_enc); return rc; } From d6a7bcb89c4e0ef85c567ab5df2d91f932c04e72 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 1 Oct 2019 14:25:23 -0700 Subject: [PATCH 58/65] log_mgmt: Add watermark support --- cmd/log_mgmt/Kconfig | 6 ++++ cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h | 11 ++++++ .../port/mynewt/src/mynewt_log_mgmt.c | 17 ++++++++++ cmd/log_mgmt/src/log_mgmt.c | 34 ++++++++++++++----- cmd/log_mgmt/src/log_mgmt_config.h | 2 ++ 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/cmd/log_mgmt/Kconfig b/cmd/log_mgmt/Kconfig index 366a85f7..14c56148 100644 --- a/cmd/log_mgmt/Kconfig +++ b/cmd/log_mgmt/Kconfig @@ -43,4 +43,10 @@ config LOG_MGMT_CHUNK_LEN Limits the maximum length of log entry bodies chunks, so, every log entry gets read in chunks upto a point where the entire entry is read. Also, a buffer gets allocated on the stack with this size. + +config LOG_READ_WATERMARK_UPDATE + bool "Enable reading of log watermark update" + help + Enables reading of log watermark update + endif diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h index d5f9d78a..0a626521 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h @@ -113,6 +113,17 @@ int log_mgmt_impl_foreach_entry(const char *log_name, */ int log_mgmt_impl_clear(const char *log_name); +/** + * @brief set watermark for specified log index + * + * @param log Log pointer + * @param index Log ndex + * + * @return 0 on success, non-zero on failure + */ +int +log_mgmt_impl_set_watermark(struct log_mgmt_log *log, int index); + #ifdef __cplusplus } #endif diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index d973bb2a..9421c920 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -47,6 +47,23 @@ mynewt_log_mgmt_find_log(const char *log_name) } } +int +log_mgmt_impl_set_watermark(struct log_mgmt_log *log, int index) +{ + struct log *tmplog; + int i; + + tmplog = NULL; + for (i = 0; i <= index; i++) { + tmplog = log_list_get_next(tmplog); + if (tmplog == NULL) { + return MGMT_ERR_ENOENT; + } + } + + return log_set_watermark(tmplog, index); +} + int log_mgmt_impl_get_log(int idx, struct log_mgmt_log *out_log) { diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index dc7731aa..84e699b8 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -74,7 +74,7 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, len = cbor_encode_bytes_written(enc); err |= cbor_encoder_create_map(enc, &rsp, CborIndefiniteLength); - +#if MYNEWT_VAL(LOG_VERSION) > 2 switch (entry->type) { case LOG_MGMT_ETYPE_CBOR: err |= cbor_encode_text_stringz(&rsp, "type"); @@ -108,7 +108,10 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, } err |= cbor_encoder_close_container(&rsp, &str_encoder); - +#else + err |= cbor_encode_text_stringz(&rsp, "msg"); + err |= cbor_encode_text_stringz(&rsp, (char *)data); +#endif err |= cbor_encode_text_stringz(&rsp, "ts"); err |= cbor_encode_int(&rsp, entry->ts); err |= cbor_encode_text_stringz(&rsp, "level"); @@ -122,8 +125,13 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, err |= cbor_encode_byte_string(&rsp, entry->imghash, LOG_MGMT_IMG_HASHLEN); } + err |= cbor_encoder_close_container(enc, &rsp); + if (err != 0) { + return MGMT_ERR_ENOMEM; + } + if (out_len != NULL) { *out_len = cbor_encode_bytes_written(enc) - len; } @@ -167,7 +175,9 @@ log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) * message in the "msg" field of the response */ if (ctxt->counter == 0) { +#if MYNEWT_VAL(LOG_VERSION) > 2 entry->type = LOG_ETYPE_STRING; +#endif snprintf((char *)entry->data, LOG_MGMT_MAX_RSP_LEN, "error: entry too large (%d bytes)", entry_len); } @@ -330,29 +340,37 @@ log_mgmt_show(struct mgmt_ctxt *ctxt) break; } } else if (rc != 0) { - cbor_encoder_close_container(&ctxt->encoder, &logs); - return rc; + goto err; } /* Stream logs cannot be read. */ if (log.type != LOG_MGMT_TYPE_STREAM) { if (name_len == 0 || strcmp(name, log.name) == 0) { rc = log_encode(&log, &logs, timestamp, index); - if (rc != 0) { - cbor_encoder_close_container(&ctxt->encoder, &logs); - return rc; + +#if LOG_MGMT_READ_WATERMARK_UPDATE + if (rc == 0 || rc == OS_ENOMEM) { + log_mgmt_impl_set_watermark(&log, index); + } +#endif + if (rc) { + goto err; } +#if LOG_MGMT_READ_WATERMARK_UPDATE + log_mgmt_impl_set_watermark(&log, index); +#endif /* If the client specified this log, he isn't interested in the * remaining ones. */ - if (name_len != 0) { + if (name_len > 0) { break; } } } } +err: err |= cbor_encoder_close_container(&ctxt->encoder, &logs); err |= cbor_encode_text_stringz(&ctxt->encoder, "rc"); err |= cbor_encode_int(&ctxt->encoder, rc); diff --git a/cmd/log_mgmt/src/log_mgmt_config.h b/cmd/log_mgmt/src/log_mgmt_config.h index 914b9b5b..844d92f6 100644 --- a/cmd/log_mgmt/src/log_mgmt_config.h +++ b/cmd/log_mgmt/src/log_mgmt_config.h @@ -27,6 +27,7 @@ #define LOG_MGMT_CHUNK_LEN MYNEWT_VAL(LOG_MGMT_CHUNK_LEN) #define LOG_MGMT_NAME_LEN MYNEWT_VAL(LOG_MGMT_NAME_LEN) #define LOG_MGMT_MAX_RSP_LEN MYNEWT_VAL(LOG_MGMT_MAX_RSP_LEN) +#define LOG_MGMT_WATERMARK_UPDATE MYNEWT_VAL(LOG_READ_WATERMARK_UPDATE) #define LOG_MGMT_IMG_HASHLEN 4 #elif defined __ZEPHYR__ @@ -34,6 +35,7 @@ #define LOG_MGMT_CHUNK_LEN CONFIG_LOG_MGMT_CHUNK_LEN #define LOG_MGMT_NAME_LEN CONFIG_LOG_MGMT_NAME_LEN #define LOG_MGMT_MAX_RSP_LEN CONFIG_LOG_MGMT_MAX_RSP_LEN +#define LOG_MGMT_WATERMARK_UPDATE CONFIG_LOG_READ_WATERMARK_UPDATE #else From a6adcb20964d3b2b9b2931bb5074d8c97cb0d833 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Tue, 1 Oct 2019 18:03:04 -0700 Subject: [PATCH 59/65] log_mgmt: entries need to be encoded chunk by chunk - entries were encoded together earlier which caused issues, encoding them chunk by chunk fixes it. --- cmd/log_mgmt/include/log_mgmt/log_mgmt.h | 2 + .../port/mynewt/src/mynewt_log_mgmt.c | 19 +- cmd/log_mgmt/src/log_mgmt.c | 219 ++++++++++-------- 3 files changed, 138 insertions(+), 102 deletions(-) diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h index 75e66071..0229e202 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h @@ -69,6 +69,8 @@ struct log_mgmt_entry { uint8_t type:4; uint8_t flags:4; const uint8_t *imghash; + size_t offset; + size_t chunklen; void *ctxt; }; diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index 9421c920..cbf4c16f 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -127,9 +127,8 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, struct log_mgmt_entry entry; int read_len; int offset; - int rc, entrylen; + int rc; - entrylen = 0; mynewt_log_mgmt_walk_arg = log_offset->lo_arg; /* If specified timestamp is nonzero, it is the primary criterion, and the @@ -165,6 +164,8 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, entry.imghash = (leh->ue_flags & LOG_FLAGS_IMG_HASH) ? leh->ue_imghash : NULL; #endif + entry.len = len; + entry.data = mynewt_log_mgmt_walk_arg->chunk; for (offset = 0; offset < len; offset += LOG_MGMT_CHUNK_LEN) { if (len - offset < LOG_MGMT_CHUNK_LEN) { @@ -172,20 +173,18 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, } else { read_len = LOG_MGMT_CHUNK_LEN; } + entry.offset = offset; + entry.chunklen = read_len; rc = log_read_body(log, dptr, mynewt_log_mgmt_walk_arg->chunk, offset, read_len); if (rc < 0) { return MGMT_ERR_EUNKNOWN; } - entrylen += rc; - } - - entry.len = entrylen; - entry.data = mynewt_log_mgmt_walk_arg->chunk; - rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); - if (rc) { - return rc; + rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); + if (rc) { + return rc; + } } return 0; diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 84e699b8..42bc98a6 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -28,6 +28,12 @@ #include "log_mgmt_config.h" #include "log/log.h" +struct log_mgmt_enc_ctxt +{ + CborEncoder mapenc; + CborEncoder msgenc; +}; + /** Context used during walks. */ struct log_walk_ctxt { /* The number of bytes encoded to the response so far. */ @@ -36,6 +42,8 @@ struct log_walk_ctxt { struct CborEncoder *enc; /* Counter per encoder to understand if we are encoding the first chunk */ uint32_t counter; + /* Log management encode context containing map and msg encoder */ + struct log_mgmt_enc_ctxt lmec; }; static mgmt_handler_fn log_mgmt_show; @@ -60,135 +68,162 @@ static struct mgmt_group log_mgmt_group = { .mg_handlers_count = LOG_MGMT_HANDLER_CNT, .mg_group_id = MGMT_GROUP_ID_LOG, }; - + static int log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, - size_t *out_len) + size_t *out_len, struct log_mgmt_enc_ctxt *lmec) { CborError err = CborNoError; - CborEncoder rsp; - CborEncoder str_encoder; + uint16_t chunklen; uint16_t len; int off; + uint16_t bytes_encoded; len = cbor_encode_bytes_written(enc); - err |= cbor_encoder_create_map(enc, &rsp, CborIndefiniteLength); + bytes_encoded = 0; + if (entry->offset == 0) { + err |= cbor_encoder_create_map(enc, &lmec->mapenc, CborIndefiniteLength); + #if MYNEWT_VAL(LOG_VERSION) > 2 - switch (entry->type) { - case LOG_MGMT_ETYPE_CBOR: - err |= cbor_encode_text_stringz(&rsp, "type"); - err |= cbor_encode_text_stringz(&rsp, "cbor"); - break; - case LOG_MGMT_ETYPE_BINARY: - err |= cbor_encode_text_stringz(&rsp, "type"); - err |= cbor_encode_text_stringz(&rsp, "bin"); - break; - case LOG_MGMT_ETYPE_STRING: - err |= cbor_encode_text_stringz(&rsp, "type"); - err |= cbor_encode_text_stringz(&rsp, "str"); - break; - default: - cbor_encoder_close_container(&rsp, &str_encoder); - return MGMT_ERR_ECORRUPT; - } - - err |= cbor_encode_text_stringz(&rsp, "msg"); - - /* - * Write entry data as byte string. Since this may not fit into single - * chunk of data we will write as indefinite-length byte string which is - * basically a indefinite-length container with definite-length strings - * inside. - */ - err |= cbor_encoder_create_indef_byte_string(&rsp, &str_encoder); - for (off = 0; off < entry->len && !err; ) { - err |= cbor_encode_byte_string(&str_encoder, entry->data, entry->len); - off += entry->len; - } + switch (entry->type) { + case LOG_MGMT_ETYPE_CBOR: + err |= cbor_encode_text_stringz(&lmec->mapenc, "type"); + err |= cbor_encode_text_stringz(&lmec->mapenc, "cbor"); + break; + case LOG_MGMT_ETYPE_BINARY: + err |= cbor_encode_text_stringz(&lmec->mapenc, "type"); + err |= cbor_encode_text_stringz(&lmec->mapenc, "bin"); + break; + case LOG_MGMT_ETYPE_STRING: + err |= cbor_encode_text_stringz(&lmec->mapenc, "type"); + err |= cbor_encode_text_stringz(&lmec->mapenc, "str"); + break; + default: + return MGMT_ERR_ECORRUPT; + } +#endif + err |= cbor_encode_text_stringz(&lmec->mapenc, "ts"); + err |= cbor_encode_int(&lmec->mapenc, entry->ts); + err |= cbor_encode_text_stringz(&lmec->mapenc, "level"); + err |= cbor_encode_uint(&lmec->mapenc, entry->level); + err |= cbor_encode_text_stringz(&lmec->mapenc, "index"); + err |= cbor_encode_uint(&lmec->mapenc, entry->index); + err |= cbor_encode_text_stringz(&lmec->mapenc, "module"); + err |= cbor_encode_uint(&lmec->mapenc, entry->module); + if (entry->flags & LOG_MGMT_FLAGS_IMG_HASH) { + err |= cbor_encode_text_stringz(&lmec->mapenc, "imghash"); + err |= cbor_encode_byte_string(&lmec->mapenc, entry->imghash, + LOG_MGMT_IMG_HASHLEN); + } - err |= cbor_encoder_close_container(&rsp, &str_encoder); +#if MYNEWT_VAL(LOG_VERSION) > 2 + err |= cbor_encode_text_stringz(&lmec->mapenc, "msg"); + + /* + * Write entry data as byte string. Since this may not fit into single + * chunk of data we will write as indefinite-length byte string which is + * basically a indefinite-length container with definite-length strings + * inside. + */ + err |= cbor_encoder_create_indef_byte_string(&lmec->mapenc, &lmec->msgenc); + if (out_len != NULL) { + for (off = 0; off < entry->len; off += entry->chunklen) { + chunklen = entry->chunklen; + if (entry->chunklen > entry->len - off) { + chunklen = entry->len - off; + } + err |= cbor_encode_byte_string(&lmec->msgenc, entry->data, chunklen); + bytes_encoded += chunklen; + } + } else { + err |= cbor_encode_byte_string(&lmec->msgenc, entry->data, entry->chunklen); + bytes_encoded = entry->chunklen; + } #else - err |= cbor_encode_text_stringz(&rsp, "msg"); - err |= cbor_encode_text_stringz(&rsp, (char *)data); + err |= cbor_encode_text_stringz(&lmec->mapenc, "msg"); + err |= cbor_encode_text_stringz(&lmec->mapenc, (char *)data); #endif - err |= cbor_encode_text_stringz(&rsp, "ts"); - err |= cbor_encode_int(&rsp, entry->ts); - err |= cbor_encode_text_stringz(&rsp, "level"); - err |= cbor_encode_uint(&rsp, entry->level); - err |= cbor_encode_text_stringz(&rsp, "index"); - err |= cbor_encode_uint(&rsp, entry->index); - err |= cbor_encode_text_stringz(&rsp, "module"); - err |= cbor_encode_uint(&rsp, entry->module); - if (entry->flags & LOG_MGMT_FLAGS_IMG_HASH) { - err |= cbor_encode_text_stringz(&rsp, "imghash"); - err |= cbor_encode_byte_string(&rsp, entry->imghash, - LOG_MGMT_IMG_HASHLEN); - } - - err |= cbor_encoder_close_container(enc, &rsp); - - if (err != 0) { - return MGMT_ERR_ENOMEM; - } - - if (out_len != NULL) { - *out_len = cbor_encode_bytes_written(enc) - len; - } - - return MGMT_ERR_EOK; + } else { + /* + * Write entry data as byte string. Since this may not fit into single + * chunk of data we will write as indefinite-length byte string which is + * basically a indefinite-length container with definite-length strings + * inside. + */ + err |= cbor_encode_byte_string(&lmec->msgenc, entry->data, entry->chunklen); + bytes_encoded = entry->chunklen; + } + + if (entry->offset + bytes_encoded >= entry->len) { + err |= cbor_encoder_close_container(&lmec->mapenc, &lmec->msgenc); + err |= cbor_encoder_close_container(enc, &lmec->mapenc); + } + + if (out_len) { + *out_len = cbor_encode_bytes_written(enc) - len; + } + + if (err != 0) { + return MGMT_ERR_ENOMEM; + } + + return MGMT_ERR_EOK; } static int log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) { struct CborCntWriter cnt_writer; + struct log_mgmt_enc_ctxt *lmec; struct log_walk_ctxt *ctxt; CborEncoder cnt_encoder; size_t entry_len; int rc; ctxt = arg; + lmec = &ctxt->lmec; - /*** First, determine if this entry would fit. */ - - cbor_cnt_writer_init(&cnt_writer); + if (entry->offset == 0) { + /*** First, determine if this entry would fit. */ + + cbor_cnt_writer_init(&cnt_writer); #ifdef __ZEPHYR__ - cbor_encoder_cust_writer_init(&cnt_encoder, &cnt_writer.enc, 0); + cbor_encoder_cust_writer_init(&cnt_encoder, &cnt_writer.enc, 0); #else - cbor_encoder_init(&cnt_encoder, &cnt_writer.enc, 0); + cbor_encoder_init(&cnt_encoder, &cnt_writer.enc, 0); #endif - rc = log_mgmt_encode_entry(&cnt_encoder, entry, &entry_len); - if (rc != 0) { - return rc; - } - - /* - * Check if the response is too long. If more than one entry is in the - * response we will not add the current one and will return ENOMEM. If this - * is just a single entry we add the generic too long message text. - */ - /* `+ 1` to account for the CBOR array terminator. */ - if (ctxt->rsp_len + entry_len + 1 > LOG_MGMT_MAX_RSP_LEN) { + rc = log_mgmt_encode_entry(&cnt_encoder, entry, &entry_len, lmec); + if (rc != 0) { + return rc; + } + /* - * Is this just a single entry? If so, encode the generic error - * message in the "msg" field of the response + * Check if the response is too long. If more than one entry is in the + * response we will not add the current one and will return ENOMEM. If this + * is just a single entry we add the generic too long message text. */ - if (ctxt->counter == 0) { + /* `+ 1` to account for the CBOR array terminator. */ + if (ctxt->rsp_len + entry_len + 1 > LOG_MGMT_MAX_RSP_LEN) { + /* + * Is this just a single entry? If so, encode the generic error + * message in the "msg" field of the response + */ + if (ctxt->counter == 0) { #if MYNEWT_VAL(LOG_VERSION) > 2 - entry->type = LOG_ETYPE_STRING; + entry->type = LOG_ETYPE_STRING; #endif - snprintf((char *)entry->data, LOG_MGMT_MAX_RSP_LEN, - "error: entry too large (%d bytes)", entry_len); + snprintf((char *)entry->data, LOG_MGMT_MAX_RSP_LEN, + "error: entry too large (%d bytes)", entry_len); + } + + return MGMT_ERR_EMSGSIZE; } - - return MGMT_ERR_EMSGSIZE; + ctxt->rsp_len += entry_len; } - ctxt->rsp_len += entry_len; /*** The entry fits. Now encode it. */ - - rc = log_mgmt_encode_entry(ctxt->enc, entry, NULL); + rc = log_mgmt_encode_entry(ctxt->enc, entry, NULL, lmec); if (rc != 0) { return rc; } From 59576c133af7f6ae06258450938819bc7ee5977a Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 2 Oct 2019 13:23:41 -0700 Subject: [PATCH 60/65] log_mgmt: add some comments --- cmd/log_mgmt/src/log_mgmt.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 42bc98a6..f650e20d 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -28,6 +28,11 @@ #include "log_mgmt_config.h" #include "log/log.h" +/* Log mgmt encoder context used for multiple calls of the + * entry encode function since the function gets called twice, + * once for counter encoder and the second time for the actual + * encoding + */ struct log_mgmt_enc_ctxt { CborEncoder mapenc; @@ -82,6 +87,10 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, len = cbor_encode_bytes_written(enc); bytes_encoded = 0; + /* If offset is 0, we encode the keys for maps and other fields which are + * necessary per entry since only the keys need to be encoded only in the + * for the first offset + */ if (entry->offset == 0) { err |= cbor_encoder_create_map(enc, &lmec->mapenc, CborIndefiniteLength); @@ -146,6 +155,8 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, #endif } else { /* + * The else case is executed for non-first chunks of data to be encoded + * * Write entry data as byte string. Since this may not fit into single * chunk of data we will write as indefinite-length byte string which is * basically a indefinite-length container with definite-length strings @@ -155,6 +166,11 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, bytes_encoded = entry->chunklen; } + /* + * Containers need to get closed when encoding is done, the only way to know at + * this point in the code that encoding is done is using the number of bytes + * that got encoded and comparing it to the length of the entry + */ if (entry->offset + bytes_encoded >= entry->len) { err |= cbor_encoder_close_container(&lmec->mapenc, &lmec->msgenc); err |= cbor_encoder_close_container(enc, &lmec->mapenc); @@ -185,7 +201,10 @@ log_mgmt_cb_encode(struct log_mgmt_entry *entry, void *arg) lmec = &ctxt->lmec; if (entry->offset == 0) { - /*** First, determine if this entry would fit. */ + /* + * First, determine if this entry would fit using + * a counter encoder + */ cbor_cnt_writer_init(&cnt_writer); #ifdef __ZEPHYR__ From 081cad724eca03860af4ed0c4e3438b4ac7dfd22 Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Wed, 2 Oct 2019 21:36:08 +0100 Subject: [PATCH 61/65] cmd/fs fixing package dependency chain --- cmd/fs_mgmt/port/mynewt/pkg.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 cmd/fs_mgmt/port/mynewt/pkg.yml diff --git a/cmd/fs_mgmt/port/mynewt/pkg.yml b/cmd/fs_mgmt/port/mynewt/pkg.yml new file mode 100644 index 00000000..10e2dbe1 --- /dev/null +++ b/cmd/fs_mgmt/port/mynewt/pkg.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: cmd/fs_mgmt/port/mynewt +pkg.description: 'File system command handlers for mcumgr.' +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - '@apache-mynewt-mcumgr/cmd/fs' From 8478dcba8c308b6fb9366e6575d5b27c7289fdfb Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 2 Oct 2019 14:28:28 -0700 Subject: [PATCH 62/65] cmd: move config headers to include directory - Move config headers to include directory and general clean up and address review comments --- cborattr/src/cborattr.c | 7 +++++- .../{src => include/fs_mgmt}/fs_mgmt_config.h | 0 cmd/fs_mgmt/src/fs_mgmt.c | 2 +- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 6 ++--- .../img_mgmt}/img_mgmt_config.h | 0 cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h | 25 +++++++------------ cmd/img_mgmt/pkg.yml | 3 --- .../port/mynewt/src/mynewt_img_mgmt.c | 9 ++++--- cmd/img_mgmt/src/img_mgmt.c | 2 +- .../log_mgmt}/log_mgmt_config.h | 0 .../port/mynewt/src/mynewt_log_mgmt.c | 6 ++--- .../port/zephyr/src/zephyr_log_mgmt.c | 2 +- cmd/log_mgmt/src/log_mgmt.c | 2 +- .../{src => include/os_mgmt}/os_mgmt_config.h | 0 cmd/os_mgmt/src/os_mgmt.c | 2 +- .../stat_mgmt}/stat_mgmt_config.h | 0 cmd/stat_mgmt/pkg.yml | 2 +- .../port/mynewt/src/mynewt_stat_mgmt.c | 2 +- cmd/stat_mgmt/src/stat_mgmt.c | 2 +- util/pkg.yml | 6 ++++- 20 files changed, 39 insertions(+), 39 deletions(-) rename cmd/fs_mgmt/{src => include/fs_mgmt}/fs_mgmt_config.h (100%) rename cmd/img_mgmt/{src => include/img_mgmt}/img_mgmt_config.h (100%) rename cmd/log_mgmt/{src => include/log_mgmt}/log_mgmt_config.h (100%) rename cmd/os_mgmt/{src => include/os_mgmt}/os_mgmt_config.h (100%) rename cmd/stat_mgmt/{src => include/stat_mgmt}/stat_mgmt_config.h (100%) diff --git a/cborattr/src/cborattr.c b/cborattr/src/cborattr.c index 280b085a..fcbd3821 100644 --- a/cborattr/src/cborattr.c +++ b/cborattr/src/cborattr.c @@ -22,7 +22,7 @@ #include "tinycbor/cbor.h" #include "tinycbor/cbor_buf_reader.h" -#ifndef __ZEPHYR__ +#ifdef MYNEWT #include "tinycbor/cbor_mbuf_reader.h" #include "tinycbor/cbor_mbuf_writer.h" #include "os/os_mbuf.h" @@ -548,6 +548,11 @@ cbor_write_attr(struct CborEncoder *enc, const struct cbor_out_attr_t *attr) return 0; } + if (!attr->attribute) { + rc = SYS_EINVAL; + return rc; + } + len = strlen(attr->attribute); rc = cbor_encode_text_string(enc, attr->attribute, len); if (rc != 0) { diff --git a/cmd/fs_mgmt/src/fs_mgmt_config.h b/cmd/fs_mgmt/include/fs_mgmt/fs_mgmt_config.h similarity index 100% rename from cmd/fs_mgmt/src/fs_mgmt_config.h rename to cmd/fs_mgmt/include/fs_mgmt/fs_mgmt_config.h diff --git a/cmd/fs_mgmt/src/fs_mgmt.c b/cmd/fs_mgmt/src/fs_mgmt.c index 2d43ac18..0904795f 100644 --- a/cmd/fs_mgmt/src/fs_mgmt.c +++ b/cmd/fs_mgmt/src/fs_mgmt.c @@ -23,7 +23,7 @@ #include "mgmt/mgmt.h" #include "fs_mgmt/fs_mgmt.h" #include "fs_mgmt/fs_mgmt_impl.h" -#include "fs_mgmt_config.h" +#include "fs_mgmt/fs_mgmt_config.h" static mgmt_handler_fn fs_mgmt_file_download; static mgmt_handler_fn fs_mgmt_file_upload; diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index e9d77be2..17131fa7 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -21,7 +21,7 @@ #define H_IMG_MGMT_ #include -#include "../../src/img_mgmt_config.h" +#include "img_mgmt_config.h" #include "mgmt/mgmt.h" struct image_version; @@ -30,7 +30,6 @@ struct image_version; extern "C" { #endif -#define IMG_MGMT_MAX_IMGR 2 #define IMG_MGMT_HASH_STR 48 #define IMG_MGMT_HASH_LEN 32 #define IMG_MGMT_DATA_SHA_LEN 32 /* SHA256 */ @@ -201,8 +200,7 @@ img_mgmt_state_confirm(void); typedef void (*img_mgmt_dfu_cb)(void); /** Callback function pointers */ -typedef struct -{ +typedef struct { img_mgmt_dfu_cb dfu_started_cb; img_mgmt_dfu_cb dfu_stopped_cb; img_mgmt_dfu_cb dfu_pending_cb; diff --git a/cmd/img_mgmt/src/img_mgmt_config.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_config.h similarity index 100% rename from cmd/img_mgmt/src/img_mgmt_config.h rename to cmd/img_mgmt/include/img_mgmt/img_mgmt_config.h diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h index ef249ac6..0cb91a97 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt_impl.h @@ -118,8 +118,7 @@ uint8_t img_mgmt_state_flags(int query_slot); * @param num_bytes The number of bytes to erase. * @return 0 on success, MGMT_ERR_[...] code on failure. */ -int -img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes); +int img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes); /** * Erases a flash sector as image upload crosses a sector boundary. @@ -135,8 +134,7 @@ img_mgmt_impl_erase_image_data(unsigned int off, unsigned int num_bytes); * @return 0 if success * ERROR_CODE if could not erase sector */ -int -img_mgmt_impl_erase_if_needed(uint32_t off, uint32_t len); +int img_mgmt_impl_erase_if_needed(uint32_t off, uint32_t len); /** * Verifies an upload request and indicates the actions that should be taken @@ -152,22 +150,17 @@ img_mgmt_impl_erase_if_needed(uint32_t off, uint32_t len); * A MGMT_ERR code if an error response should be * sent instead. */ -int -img_mgmt_impl_upload_inspect(const struct img_mgmt_upload_req *req, - struct img_mgmt_upload_action *action, - const char **errstr); +int img_mgmt_impl_upload_inspect(const struct img_mgmt_upload_req *req, + struct img_mgmt_upload_action *action, + const char **errstr); -int -img_mgmt_impl_log_upload_start(int status); +int img_mgmt_impl_log_upload_start(int status); -int -img_mgmt_impl_log_upload_done(int status, const uint8_t *hashp); +int img_mgmt_impl_log_upload_done(int status, const uint8_t *hashp); -int -img_mgmt_impl_log_pending(int status, const uint8_t *hash); +int img_mgmt_impl_log_pending(int status, const uint8_t *hash); -int -img_mgmt_impl_log_confirm(int status, const uint8_t *hash); +int img_mgmt_impl_log_confirm(int status, const uint8_t *hash); #ifdef __cplusplus } diff --git a/cmd/img_mgmt/pkg.yml b/cmd/img_mgmt/pkg.yml index cb7e1ffd..82353bd1 100644 --- a/cmd/img_mgmt/pkg.yml +++ b/cmd/img_mgmt/pkg.yml @@ -31,6 +31,3 @@ pkg.deps: - '@apache-mynewt-mcumgr/mgmt' - '@apache-mynewt-mcumgr/cborattr' - '@apache-mynewt-mcumgr/util' - -IMG_MGMT_LAZY_ERASE.cflags: - - "-DUPLOAD_LAZY_ERASE" diff --git a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c index 6a1208e1..20b07e4a 100644 --- a/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c +++ b/cmd/img_mgmt/port/mynewt/src/mynewt_img_mgmt.c @@ -498,15 +498,18 @@ img_mgmt_impl_erase_if_needed(uint32_t off, uint32_t len) while ((cfa->fa_off + off + len) > g_img_mgmt_state.sector_end) { rc = flash_area_getnext_sector(cfa->fa_id, &g_img_mgmt_state.sector_id, §or); if (rc) { - return rc; + goto done; } rc = flash_area_erase(§or, 0, sector.fa_size); if (rc) { - return rc; + goto done; } g_img_mgmt_state.sector_end = sector.fa_off + sector.fa_size; } - return 0; + +done: + flash_area_close(cfa); + return rc; } #endif diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index 08f0e8ef..edaa1f86 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -28,7 +28,7 @@ #include "img_mgmt/img_mgmt.h" #include "img_mgmt/img_mgmt_impl.h" #include "img_mgmt_priv.h" -#include "img_mgmt_config.h" +#include "img_mgmt/img_mgmt_config.h" static mgmt_handler_fn img_mgmt_upload; static mgmt_handler_fn img_mgmt_erase; diff --git a/cmd/log_mgmt/src/log_mgmt_config.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt_config.h similarity index 100% rename from cmd/log_mgmt/src/log_mgmt_config.h rename to cmd/log_mgmt/include/log_mgmt/log_mgmt_config.h diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index cbf4c16f..e62ae569 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -21,7 +21,7 @@ #include "mgmt/mgmt.h" #include "log_mgmt/log_mgmt.h" #include "log_mgmt/log_mgmt_impl.h" -#include "../../../src/log_mgmt_config.h" +#include "log_mgmt/log_mgmt_config.h" struct mynewt_log_mgmt_walk_arg { log_mgmt_foreach_entry_fn *cb; @@ -183,11 +183,11 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, } rc = mynewt_log_mgmt_walk_arg->cb(&entry, mynewt_log_mgmt_walk_arg->arg); if (rc) { - return rc; + break; } } - return 0; + return rc; } int diff --git a/cmd/log_mgmt/port/zephyr/src/zephyr_log_mgmt.c b/cmd/log_mgmt/port/zephyr/src/zephyr_log_mgmt.c index 94e49dba..8ddc0123 100644 --- a/cmd/log_mgmt/port/zephyr/src/zephyr_log_mgmt.c +++ b/cmd/log_mgmt/port/zephyr/src/zephyr_log_mgmt.c @@ -22,7 +22,7 @@ #include #include #include -#include "../../../src/log_mgmt_config.h" +#include "log_mgmt/log_mgmt_config.h" struct zephyr_log_mgmt_walk_arg { log_mgmt_foreach_entry_fn *cb; diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index f650e20d..4d3f88f9 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -25,7 +25,7 @@ #include "tinycbor/cbor_cnt_writer.h" #include "log_mgmt/log_mgmt.h" #include "log_mgmt/log_mgmt_impl.h" -#include "log_mgmt_config.h" +#include "log_mgmt/log_mgmt_config.h" #include "log/log.h" /* Log mgmt encoder context used for multiple calls of the diff --git a/cmd/os_mgmt/src/os_mgmt_config.h b/cmd/os_mgmt/include/os_mgmt/os_mgmt_config.h similarity index 100% rename from cmd/os_mgmt/src/os_mgmt_config.h rename to cmd/os_mgmt/include/os_mgmt/os_mgmt_config.h diff --git a/cmd/os_mgmt/src/os_mgmt.c b/cmd/os_mgmt/src/os_mgmt.c index 03d3dabc..9b17e0b5 100644 --- a/cmd/os_mgmt/src/os_mgmt.c +++ b/cmd/os_mgmt/src/os_mgmt.c @@ -24,7 +24,7 @@ #include "mgmt/mgmt.h" #include "os_mgmt/os_mgmt.h" #include "os_mgmt/os_mgmt_impl.h" -#include "os_mgmt_config.h" +#include "os_mgmt/os_mgmt_config.h" #if OS_MGMT_ECHO static mgmt_handler_fn os_mgmt_echo; diff --git a/cmd/stat_mgmt/src/stat_mgmt_config.h b/cmd/stat_mgmt/include/stat_mgmt/stat_mgmt_config.h similarity index 100% rename from cmd/stat_mgmt/src/stat_mgmt_config.h rename to cmd/stat_mgmt/include/stat_mgmt/stat_mgmt_config.h diff --git a/cmd/stat_mgmt/pkg.yml b/cmd/stat_mgmt/pkg.yml index 99bbbbfb..2b43f56e 100644 --- a/cmd/stat_mgmt/pkg.yml +++ b/cmd/stat_mgmt/pkg.yml @@ -18,7 +18,7 @@ # pkg.name: cmd/stat_mgmt -pkg.description: 'OS management command handlers for mcumgr.' +pkg.description: 'Stat management command handlers for mcumgr.' pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: diff --git a/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c b/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c index 75bb723a..d9231ae5 100644 --- a/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c +++ b/cmd/stat_mgmt/port/mynewt/src/mynewt_stat_mgmt.c @@ -23,7 +23,7 @@ #include "sysinit/sysinit.h" #include "stat_mgmt/stat_mgmt.h" #include "stat_mgmt/stat_mgmt_impl.h" -#include "../../../src/stat_mgmt_config.h" +#include "stat_mgmt/stat_mgmt_config.h" struct mynewt_stat_mgmt_walk_arg { stat_mgmt_foreach_entry_fn *cb; diff --git a/cmd/stat_mgmt/src/stat_mgmt.c b/cmd/stat_mgmt/src/stat_mgmt.c index 994d7c88..57ef216e 100644 --- a/cmd/stat_mgmt/src/stat_mgmt.c +++ b/cmd/stat_mgmt/src/stat_mgmt.c @@ -24,7 +24,7 @@ #include "cborattr/cborattr.h" #include "stat_mgmt/stat_mgmt.h" #include "stat_mgmt/stat_mgmt_impl.h" -#include "stat_mgmt_config.h" +#include "stat_mgmt/stat_mgmt_config.h" static mgmt_handler_fn stat_mgmt_show; static mgmt_handler_fn stat_mgmt_list; diff --git a/util/pkg.yml b/util/pkg.yml index 86c0f85b..c0ce5b6d 100644 --- a/util/pkg.yml +++ b/util/pkg.yml @@ -18,7 +18,11 @@ # pkg.name: util -pkg.description: Image management utility library +pkg.description: > + Library containing utility functions including + but not limited to convert integer to strings pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: + - lltos + - ultos From bde1003ec72caeedea7af0b19e180e45d0bc9852 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 2 Oct 2019 14:47:24 -0700 Subject: [PATCH 63/65] cborattr: APIs & structs need to be MYNEWT specific - mbuf APIs and structs containing mbuf ptrs need to be MYNEWT specific --- cborattr/include/cborattr/cborattr.h | 50 ++++++++++++++-------------- cborattr/src/cborattr.c | 2 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cborattr/include/cborattr/cborattr.h b/cborattr/include/cborattr/cborattr.h index de1bafe5..30e26121 100644 --- a/cborattr/include/cborattr/cborattr.h +++ b/cborattr/include/cborattr/cborattr.h @@ -28,7 +28,7 @@ #include #include "tinycbor/cbor.h" -#ifndef __ZEPHYR__ +#ifdef MYNEWT #include #endif @@ -123,32 +123,32 @@ struct cbor_attr_t { #ifndef __ZEPHYR__ /** An array value to be encoded as CBOR. */ - struct cbor_out_arr_val_t { - struct cbor_out_val_t *elems; - size_t len; - }; +struct cbor_out_arr_val_t { + struct cbor_out_val_t *elems; + size_t len; +}; /** A single value to be encoded as CBOR. */ - struct cbor_out_val_t { - /** The type of data. */ - CborAttrType type; - - /** The data value. */ - union { - long long int integer; - long long unsigned int uinteger; - double real; - float fval; - const char *string; - bool boolean; - struct { - const uint8_t *data; - size_t len; - } bytestring; - struct cbor_out_arr_val_t array; - struct cbor_out_attr_t *obj; /* Terminated with a type=0 entry. */ - }; +struct cbor_out_val_t { + /** The type of data. */ + CborAttrType type; + + /** The data value. */ + union { + long long int integer; + long long unsigned int uinteger; + double real; + float fval; + const char *string; + bool boolean; + struct { + const uint8_t *data; + size_t len; + } bytestring; + struct cbor_out_arr_val_t array; + struct cbor_out_attr_t *obj; /* Terminated with a type=0 entry. */ }; +}; /** An object key-value pair to be encoded as CBOR. */ struct cbor_out_attr_t { @@ -185,7 +185,7 @@ int cbor_read_array(struct CborValue *, const struct cbor_array_t *); int cbor_read_flat_attrs(const uint8_t *data, int len, const struct cbor_attr_t *attrs); -#ifndef __ZEPHYR__ +#ifdef MYNEWT int cbor_read_mbuf_attrs(struct os_mbuf *m, uint16_t off, uint16_t len, const struct cbor_attr_t *attrs); diff --git a/cborattr/src/cborattr.c b/cborattr/src/cborattr.c index fcbd3821..68c18a8b 100644 --- a/cborattr/src/cborattr.c +++ b/cborattr/src/cborattr.c @@ -409,7 +409,7 @@ cbor_read_flat_attrs(const uint8_t *data, int len, return cbor_read_object(&value, attrs); } -#ifndef __ZEPHYR__ +#ifdef MYNEWT /* * Read in cbor key/values from os_mbuf pointed by m, and fill them * into attrs. From ebf9d6e3677ca22eb446ebd4d7fc360533bcaa58 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Wed, 2 Oct 2019 15:10:37 -0700 Subject: [PATCH 64/65] img_mgmt: coding style changes --- cmd/img_mgmt/include/img_mgmt/img_mgmt.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h index 17131fa7..333cacad 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt.h @@ -137,8 +137,7 @@ int img_mgmt_read_info(int image_slot, struct image_version *ver, * * @return 0 on success, non-zero on failure */ -int -img_mgmt_my_version(struct image_version *ver); +int img_mgmt_my_version(struct image_version *ver); /** * @brief Get image version in string from image_version @@ -150,8 +149,7 @@ img_mgmt_my_version(struct image_version *ver); * * @return 0 on success, non-zero on failure */ -int -img_mgmt_ver_str(const struct image_version *ver, char *dst); +int img_mgmt_ver_str(const struct image_version *ver, char *dst); /** * @brief Check if the image slot is in use @@ -160,8 +158,7 @@ img_mgmt_ver_str(const struct image_version *ver, char *dst); * * @return 0 on success, non-zero on failure */ -int -img_mgmt_slot_in_use(int slot); +int img_mgmt_slot_in_use(int slot); /** * @brief Collects information about the specified image slot @@ -170,8 +167,7 @@ img_mgmt_slot_in_use(int slot); * * @return return the state flags */ -uint8_t -img_mgmt_state_flags(int query_slot); +uint8_t img_mgmt_state_flags(int query_slot); /** * @brief Sets the pending flag for the specified image slot. That is, the system @@ -184,8 +180,7 @@ img_mgmt_state_flags(int query_slot); * * @return 0 on success, non-zero on failure */ -int -img_mgmt_state_set_pending(int slot, int permanent); +int img_mgmt_state_set_pending(int slot, int permanent); /** * Confirms the current image state. Prevents a fallback from occurring on the @@ -193,8 +188,7 @@ img_mgmt_state_set_pending(int slot, int permanent); * * @return 0 on success, non -zero on failure */ -int -img_mgmt_state_confirm(void); +int img_mgmt_state_confirm(void); /** @brief Generic callback function for events */ typedef void (*img_mgmt_dfu_cb)(void); @@ -249,8 +243,7 @@ void img_mgmt_dfu_pending(void); void img_mgmt_dfu_confirmed(void); #if IMG_MGMT_VERBOSE_ERR -int -img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn); +int img_mgmt_error_rsp(struct mgmt_ctxt *ctxt, int rc, const char *rsn); extern const char *img_mgmt_err_str_app_reject; extern const char *img_mgmt_err_str_hdr_malformed; extern const char *img_mgmt_err_str_magic_mismatch; From 7fcdfa72438a6972066571e26082c9ea21235e9a Mon Sep 17 00:00:00 2001 From: Miguel Azevedo Date: Fri, 4 Oct 2019 01:14:17 +0100 Subject: [PATCH 65/65] Added a few first test scripts. --- ci-tests/mynewt/scripts/config_mgmt.py | 23 +++++++++++ ci-tests/mynewt/scripts/fs_mgmt.py | 16 +++++++ ci-tests/mynewt/scripts/img_mgmt.py | 46 +++++++++++++++++++++ ci-tests/mynewt/scripts/log_mgmt.py | 34 +++++++++++++++ ci-tests/mynewt/scripts/mcumgr_test.py | 55 +++++++++++++++++++++++++ ci-tests/mynewt/scripts/newt_install.sh | 39 ++++++++++++++++++ ci-tests/mynewt/scripts/os_mgmt.py | 45 ++++++++++++++++++++ ci-tests/mynewt/scripts/test_all.sh | 30 ++++++++++++++ ci-tests/mynewt/scripts/util.py | 28 +++++++++++++ 9 files changed, 316 insertions(+) create mode 100644 ci-tests/mynewt/scripts/config_mgmt.py create mode 100644 ci-tests/mynewt/scripts/fs_mgmt.py create mode 100644 ci-tests/mynewt/scripts/img_mgmt.py create mode 100644 ci-tests/mynewt/scripts/log_mgmt.py create mode 100644 ci-tests/mynewt/scripts/mcumgr_test.py create mode 100755 ci-tests/mynewt/scripts/newt_install.sh create mode 100644 ci-tests/mynewt/scripts/os_mgmt.py create mode 100644 ci-tests/mynewt/scripts/test_all.sh create mode 100644 ci-tests/mynewt/scripts/util.py diff --git a/ci-tests/mynewt/scripts/config_mgmt.py b/ci-tests/mynewt/scripts/config_mgmt.py new file mode 100644 index 00000000..a5b20e3b --- /dev/null +++ b/ci-tests/mynewt/scripts/config_mgmt.py @@ -0,0 +1,23 @@ +from util import* +from shlex import split + +def config_read(var_name="test/str", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr config") + cmd.append(var_name) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def config_write(var_name="test/str", + val="hello world", + type_str=true, + conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr config") + cmd.append(var_name) + cmd.append("\"" + val + "\"") + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def config_save(conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr config save") + cmd.extend(split(conn_name)) + return run_cmd(cmd) diff --git a/ci-tests/mynewt/scripts/fs_mgmt.py b/ci-tests/mynewt/scripts/fs_mgmt.py new file mode 100644 index 00000000..b832bdaf --- /dev/null +++ b/ci-tests/mynewt/scripts/fs_mgmt.py @@ -0,0 +1,16 @@ +from util import* +from shlex import split + +def fs_upload(path="file_up", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr fs upload") + cmd.append(path) + cmd.extend(split(conn_name)) + out, err = run_cmd(cmd) + return out == data + +def fs_download(path="file_down", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr fs download") + cmd.append(path) + cmd.extend(split(conn_name)) + out, err = run_cmd(cmd) + return out == data diff --git a/ci-tests/mynewt/scripts/img_mgmt.py b/ci-tests/mynewt/scripts/img_mgmt.py new file mode 100644 index 00000000..510053f5 --- /dev/null +++ b/ci-tests/mynewt/scripts/img_mgmt.py @@ -0,0 +1,46 @@ +from util import * + +def img_list(conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr image list") + cmd.extend(split(conn_name)) + out, err = run_cmd(cmd) + + '''Extracting image hashes.''' + out_lst = out.decode("utf-8").strip('\\').split() + try: + hash0_idx = out_lst.index("hash:") + 1 + except ValueError: + return None, out, err + + try: + hash1_idx = out_lst.index("hash:", hash0_idx + 1) + 1 + except ValueError: + return [out_lst[hash0_idx]], out, err + + return [out_lst[hash0_idx], out_lst[hash1_idx]], out, err + +def img_upload(img_path, lazy=False, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr image upload") + cmd.append(img_path) + if lazy: + cmd.append("-e") + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def img_settest(img_hash, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr image test") + cmd.append(img_hash) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def img_setconfirm(img_hash, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr image confirm") + cmd.append(img_hash) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def img_erase(img_hash, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr image erase") + cmd.append(img_hash) + cmd.extend(split(conn_name)) + return run_cmd(cmd) diff --git a/ci-tests/mynewt/scripts/log_mgmt.py b/ci-tests/mynewt/scripts/log_mgmt.py new file mode 100644 index 00000000..28ccf34e --- /dev/null +++ b/ci-tests/mynewt/scripts/log_mgmt.py @@ -0,0 +1,34 @@ +from util import* +from shlex import split + +def log_clear(log_name="log", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr log clear") + cmd.append(log_name) + cmd.extend(split(conn_name)) + out, err = run_cmd(cmd) + return out == data + +def log_lvl_list(log_name="log", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr log level_list") + cmd.append(log_name) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def log_list(conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr log list") + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def log_module_list(log_name="log", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr log module_list") + cmd.append(log_name) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def log_show(data = "", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr log show") + if (data != ""): + cmd.append(data) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + diff --git a/ci-tests/mynewt/scripts/mcumgr_test.py b/ci-tests/mynewt/scripts/mcumgr_test.py new file mode 100644 index 00000000..4e4fea52 --- /dev/null +++ b/ci-tests/mynewt/scripts/mcumgr_test.py @@ -0,0 +1,55 @@ +from img_mgmt import * +from os_mgmt import * +from util import * +from time import sleep + +def main(): + out, err = nrf52_clean_device() + out, err = load_img("0.0.1", "mcuboot_nrf52dk") + out, err = create_img() + out, err = load_img() + sleep(1) #let the device boot before anything else + + if not test_echo(): + print("echo failed") + + hashes, out, err = img_list() + + '''Testing image upload with pre-erase.''' + out, err = create_img(img_ver="0.0.2") + path = "bin/targets/slinky_nrf52dk/app/apps/slinky/slinky.img" + out, err = img_upload(path) + hashes, out, err = img_list() + print(hashes) + + img_settest(hashes[1]) + reset() + sleep(5) + hashes, out, err = img_list() + print(hashes) + + img_setconfirm(hashes[0]) + img_erase(hashes[1], conn_name="-c conn_ttyusb0") + hashes, out, err = img_list() + print(hashes) + + '''Testing image upload with lazy-erase.''' + out, err = create_img(img_ver="0.0.3") + out, err = img_upload(path, True) + hashes, out, err = img_list() + print(hashes) + + img_settest(hashes[1]) + reset() + sleep(5) + hashes, out, err = img_list() + print(hashes) + + img_setconfirm(hashes[0]) + img_erase(hashes[1], conn_name="-c conn_ttyusb0") + hashes, out, err = img_list() + print(hashes) + + +if __name__ == "__main__": + main() diff --git a/ci-tests/mynewt/scripts/newt_install.sh b/ci-tests/mynewt/scripts/newt_install.sh new file mode 100755 index 00000000..ac717e9f --- /dev/null +++ b/ci-tests/mynewt/scripts/newt_install.sh @@ -0,0 +1,39 @@ +#!/bin/bash -x + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +export GOPATH=$HOME/gopath + +mkdir -p $HOME/bin $GOPATH || true + +go version + +for i in 1 2 3 +do + go get mynewt.apache.org/newt/newt + [[ $? -eq 0 ]] && break + [[ $i -eq 3 ]] && exit 1 + sleep 30 +done + +rm -rf $GOPATH/bin $GOPATH/pkg + +go install mynewt.apache.org/newt/newt +[[ $? -ne 0 ]] && exit 1 + +cp $GOPATH/bin/newt $HOME/bin diff --git a/ci-tests/mynewt/scripts/os_mgmt.py b/ci-tests/mynewt/scripts/os_mgmt.py new file mode 100644 index 00000000..3a912bae --- /dev/null +++ b/ci-tests/mynewt/scripts/os_mgmt.py @@ -0,0 +1,45 @@ +from util import* +from shlex import split + +def test_echo(data = "hello world", conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr echo") + cmd.append(data) + cmd.extend(split(conn_name)) + out, err = run_cmd(cmd) + return out == data + +def test_console_echo(data, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr echo") + cmd.append(data) + cmd.extend(split(conn_name)) + out, err = run_cmd(cmd) + return out == dat + +def task_info(task_idx=0, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr task info") + cmd.append(task_idx) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def mpstat_read(conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr task info") + cmd.append(task_idx) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def datetime_get(conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr task info") + cmd.append(task_idx) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def datetime_set(datetime, conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr datetime set") + cmd.append(datetime) + cmd.extend(split(conn_name)) + return run_cmd(cmd) + +def reset(conn_name="-c conn_ttyusb0"): + cmd = split("newtmgr reset") + cmd.extend(split(conn_name)) + return run_cmd(cmd) diff --git a/ci-tests/mynewt/scripts/test_all.sh b/ci-tests/mynewt/scripts/test_all.sh new file mode 100644 index 00000000..dd916af6 --- /dev/null +++ b/ci-tests/mynewt/scripts/test_all.sh @@ -0,0 +1,30 @@ +#!/bin/bash -x + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +EXIT_CODE=0 + +TARGETS=$(cat ${TRAVIS_BUILD_DIR}/targets.txt) + + echo "Running all tests." + newt test all + + rc=$? + [[ $rc -ne 0 ]] && EXIT_CODE=$rc + +exit $EXIT_CODE diff --git a/ci-tests/mynewt/scripts/util.py b/ci-tests/mynewt/scripts/util.py new file mode 100644 index 00000000..5be8fb46 --- /dev/null +++ b/ci-tests/mynewt/scripts/util.py @@ -0,0 +1,28 @@ +from subprocess import Popen, PIPE +from shlex import split + +def run_cmd(cmd): + proc = Popen(cmd, stdout=PIPE, stderr=PIPE) + out, err = proc.communicate() + + if proc.returncode: + print(str(err)) + exit(-1) + + return out, err + +def nrf52_clean_device(): + cmd = split("nrfjprog -e -f NRF52") + return run_cmd(cmd) + +def create_img(img_ver="0.0.1", tgt_name="slinky_nrf52dk"): + cmd = split("newt create-image") + cmd.append(tgt_name) + cmd.append(img_ver) + return run_cmd(cmd) + +def load_img(img_ver="0.0.1", tgt_name="slinky_nrf52dk"): + cmd = split("newt load") + cmd.append(tgt_name) + cmd.append(img_ver) + return run_cmd(cmd)