This is an automated email from the ASF dual-hosted git repository. ccollins pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-mcumgr.git
commit 63166fd4cea4b98dea110185a5467a9612dc15f0 Author: Christopher Collins <ccoll...@apache.org> AuthorDate: Thu Dec 7 12:41:12 2017 -0800 initial commit --- .gitignore | 37 ++ mgmt/mgmt/include/mgmt/mgmt.h | 139 ++++++++ mgmt/mgmt/pkg.yml | 28 ++ mgmt/mgmt/src/mgmt.c | 112 ++++++ mgmt/mgmt/syscfg.yml | 18 + mgmt/newtmgr/include/newtmgr/newtmgr.h | 74 ++++ mgmt/newtmgr/nmgr_os/include/nmgr_os/nmgr_os.h | 43 +++ mgmt/newtmgr/nmgr_os/pkg.yml | 38 ++ mgmt/newtmgr/nmgr_os/src/newtmgr_os.c | 346 ++++++++++++++++++ mgmt/newtmgr/nmgr_os/syscfg.yml | 23 ++ mgmt/newtmgr/pkg.yml | 40 +++ mgmt/newtmgr/src/mynewt_nmgr.c | 182 ++++++++++ mgmt/newtmgr/src/newtmgr.c | 205 +++++++++++ .../transport/ble/include/nmgrble/newtmgr_ble.h | 42 +++ mgmt/newtmgr/transport/ble/pkg.yml | 35 ++ mgmt/newtmgr/transport/ble/src/newtmgr_ble.c | 242 +++++++++++++ mgmt/newtmgr/transport/nmgr_shell/pkg.yml | 34 ++ mgmt/newtmgr/transport/nmgr_shell/src/nmgr_shell.c | 71 ++++ mgmt/newtmgr/transport/nmgr_uart/pkg.yml | 35 ++ mgmt/newtmgr/transport/nmgr_uart/src/nmgr_uart.c | 389 +++++++++++++++++++++ mgmt/newtmgr/transport/nmgr_uart/syscfg.yml | 28 ++ 21 files changed, 2161 insertions(+) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91be3d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# +# 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. +# + +.app.db +.app +bin +obj +tags +.gdb_history +.gdb_out +.gdb_cmds +.gdbinit +*~ +.DS_Store +*.swp +*.swo +*.bak +docs/html +docs/latex +cscope.* +*.tags diff --git a/mgmt/mgmt/include/mgmt/mgmt.h b/mgmt/mgmt/include/mgmt/mgmt.h new file mode 100644 index 0000000..0313736 --- /dev/null +++ b/mgmt/mgmt/include/mgmt/mgmt.h @@ -0,0 +1,139 @@ +/* + * 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 _MGMT_MGMT_H_ +#define _MGMT_MGMT_H_ + +#include <inttypes.h> + +#include <os/queue.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* MTU for newtmgr responses */ +#define MGMT_MAX_MTU 1024 + +#ifndef STR +/* Stringification of constants */ +#define STR(x) #x +#endif + +#define NMGR_OP_READ (0) +#define NMGR_OP_READ_RSP (1) +#define NMGR_OP_WRITE (2) +#define NMGR_OP_WRITE_RSP (3) + +/* First 64 groups are reserved for system level newtmgr commands. + * Per-user commands are then defined after group 64. + */ +#define MGMT_GROUP_ID_DEFAULT (0) +#define MGMT_GROUP_ID_IMAGE (1) +#define MGMT_GROUP_ID_STATS (2) +#define MGMT_GROUP_ID_CONFIG (3) +#define MGMT_GROUP_ID_LOGS (4) +#define MGMT_GROUP_ID_CRASH (5) +#define MGMT_GROUP_ID_SPLIT (6) +#define MGMT_GROUP_ID_RUN (7) +#define MGMT_GROUP_ID_FS (8) +#define MGMT_GROUP_ID_PERUSER (64) + +/** + * Newtmgr error codes + */ +#define MGMT_ERR_EOK (0) +#define MGMT_ERR_EUNKNOWN (1) +#define MGMT_ERR_ENOMEM (2) +#define MGMT_ERR_EINVAL (3) +#define MGMT_ERR_ETIMEOUT (4) +#define MGMT_ERR_ENOENT (5) +#define MGMT_ERR_EBADSTATE (6) /* Current state disallows command. */ +#define MGMT_ERR_EMSGSIZE (7) /* Response too large. */ +#define MGMT_ERR_EPERUSER (256) + +#define NMGR_HDR_SIZE (8) + +struct nmgr_hdr { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t nh_op:3; /* NMGR_OP_XXX */ + uint8_t _res1:5; +#endif +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + uint8_t _res1:5; + uint8_t nh_op:3; /* NMGR_OP_XXX */ +#endif + uint8_t nh_flags; /* XXX reserved for future flags */ + uint16_t nh_len; /* length of the payload */ + uint16_t nh_group; /* NMGR_GROUP_XXX */ + uint8_t nh_seq; /* sequence number */ + uint8_t nh_id; /* message ID within group */ +}; + +typedef int mgmt_reader_trim_front_fn(struct cbor_decoder_reader *reader, + int len); +typedef int mgmt_writer_write_at_fn(struct cbor_encoder_writer *writer, + int offset, const void *data, int len); + +/* XXX: Bad name */ +struct mgmt_cbor_cfg { + mgmt_reader_trim_front_fn *trim_front; + mgmt_writer_write_at_fn *write_at; + + struct cbor_decoder_reader *reader; + struct cbor_encoder_writer *writer; +}; + +struct mgmt_cbuf { + struct CborEncoder encoder; + struct CborParser parser; + struct CborValue it; +}; + +typedef int (*mgmt_handler_func_t)(struct mgmt_cbuf *); + +struct mgmt_handler { + mgmt_handler_func_t mh_read; + mgmt_handler_func_t mh_write; +}; + +struct mgmt_group { + const struct mgmt_handler *mg_handlers; + uint16_t mg_handlers_count; + uint16_t mg_group_id; + struct mgmt_group *mg_next; +}; + +#define MGMT_GROUP_SET_HANDLERS(__group, __handlers) \ + (__group)->mg_handlers = (__handlers); \ + (__group)->mg_handlers_count = (sizeof((__handlers)) / \ + sizeof(struct mgmt_handler)); + +int mgmt_group_register(struct mgmt_group *group); +int mgmt_cbuf_setoerr(struct mgmt_cbuf *njb, int errcode); +const struct mgmt_handler *mgmt_find_handler(uint16_t group_id, + uint16_t handler_id); +int mgmt_err_from_cbor(int cbor_status); +int mgmt_cbuf_init(struct mgmt_cbuf *cbuf, struct mgmt_cbor_cfg *cfg); + +#ifdef __cplusplus +} +#endif + +#endif /* _MGMT_MGMT_H_ */ diff --git a/mgmt/mgmt/pkg.yml b/mgmt/mgmt/pkg.yml new file mode 100644 index 0000000..2361166 --- /dev/null +++ b/mgmt/mgmt/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: mgmt/mgmt +pkg.description: System-wide management interfaces. +pkg.author: "Apache Mynewt <d...@mynewt.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - kernel/os + - encoding/tinycbor diff --git a/mgmt/mgmt/src/mgmt.c b/mgmt/mgmt/src/mgmt.c new file mode 100644 index 0000000..ab0cb8a --- /dev/null +++ b/mgmt/mgmt/src/mgmt.c @@ -0,0 +1,112 @@ +/* + * 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 <string.h> + +#include <os/os.h> +#include <tinycbor/cbor.h> +#include "mgmt/mgmt.h" + +static struct mgmt_group *mgmt_group_list; +static struct mgmt_group *mgmt_group_list_end; + +void +mgmt_group_register(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) +{ + struct mgmt_group *group; + + for (group = mgmt_group_list; group != NULL; group = group->mg_next) { + if (group->mg_group_id == group_id) { + return group; + } + } + + return NULL; +} + +const struct mgmt_handler * +mgmt_find_handler(uint16_t group_id, uint16_t handler_id) +{ + struct mgmt_group *group; + const struct mgmt_handler *handler; + + group = mgmt_find_group(group_id); + if (group == NULL) { + return NULL; + } + + if (handler_id >= group->mg_handlers_count) { + return NULL; + } + + return &group->mg_handlers[handler_id]; +} + +int +mgmt_cbuf_setoerr(struct CborEncoder *encoder, int errcode) +{ + int rc; + + rc = cbor_encode_text_stringz(encoder, "rc"); + if (rc != 0) { + return rc; + } + + rc = cbor_encode_int(encoder, errcode); + if (rc != 0) { + return rc; + } + + return 0; +} + +int +mgmt_err_from_cbor(int cbor_status) +{ + switch (cbor_status) { + case CborNoError: return MGMT_ERR_EOK; + case CborErrorOutOfMemory: return MGMT_ERR_ENOMEM; + default: return MGMT_ERR_EUNKNOWN; + } +} + +int +mgmt_cbuf_init(struct mgmt_cbuf *cbuf, struct mgmt_cbor_cfg *cfg) +{ + int rc; + + rc = cbor_parser_init(cfg->reader, 0, &cbuf->parser, &cbuf->it); + if (rc != CborNoError) { + return mgmt_err_from_cbor(rc); + } + + cbor_encoder_init(&cbuf->encoder, cfg->writer, 0); + + return 0; +} diff --git a/mgmt/mgmt/syscfg.yml b/mgmt/mgmt/syscfg.yml new file mode 100644 index 0000000..30ccc02 --- /dev/null +++ b/mgmt/mgmt/syscfg.yml @@ -0,0 +1,18 @@ +# +# 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. +# diff --git a/mgmt/newtmgr/include/newtmgr/newtmgr.h b/mgmt/newtmgr/include/newtmgr/newtmgr.h new file mode 100644 index 0000000..b01d962 --- /dev/null +++ b/mgmt/newtmgr/include/newtmgr/newtmgr.h @@ -0,0 +1,74 @@ +/* + * 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 _NEWTMGR_H_ +#define _NEWTMGR_H_ + +#include <tinycbor/cbor.h> +#include <inttypes.h> +#include <os/os.h> +#include <os/endian.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nmgr_transport; +struct mgmt_cbor_cfg; + +/** + * Transmit function. The supplied mbuf is always consumed, regardless of + * return code. + */ +typedef int (*nmgr_transport_out_func_t)(struct nmgr_transport *nt, + struct os_mbuf *m); + +/** + * MTU query function. The supplied mbuf should contain a request received + * from the peer whose MTU is being queried. This function takes an mbuf + * parameter because some transports store connection-specific information in + * the mbuf user header (e.g., the BLE transport stores the connection handle). + * + * @return The transport's MTU; + * 0 if transmission is currently not possible. + */ +//typedef uint16_t (*nmgr_transport_get_mtu_func_t)(struct os_mbuf *m); + +struct nmgr_transport { + nmgr_transport_out_func_t nt_output; +}; + +struct mynewt_nmgr_transport { + struct nmgr_transport mnt_xport; + struct os_mqueue mnt_imq; +}; + +int mynewt_nmgr_transport_init(struct mynewt_nmgr_transport *mnt, + nmgr_transport_out_func_t output_func); + +int nmgr_build_err_rsp(struct mgmt_cbor_cfg *cfg, + const struct nmgr_hdr *req_hdr, + int status); +int nmgr_handle_single_req(struct mgmt_cbor_cfg *cfg); + +#ifdef __cplusplus +} +#endif + +#endif /* _NETMGR_H */ diff --git a/mgmt/newtmgr/nmgr_os/include/nmgr_os/nmgr_os.h b/mgmt/newtmgr/nmgr_os/include/nmgr_os/nmgr_os.h new file mode 100644 index 0000000..6c3460f --- /dev/null +++ b/mgmt/newtmgr/nmgr_os/include/nmgr_os/nmgr_os.h @@ -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. + */ + +#ifndef _NMGR_OS_H_ +#define _NMGR_OS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Id's for OS group commands + */ +#define NMGR_ID_ECHO 0 +#define NMGR_ID_CONS_ECHO_CTRL 1 +#define NMGR_ID_TASKSTATS 2 +#define NMGR_ID_MPSTATS 3 +#define NMGR_ID_DATETIME_STR 4 +#define NMGR_ID_RESET 5 + +int nmgr_os_groups_register(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _NMGR_OS_H_ */ diff --git a/mgmt/newtmgr/nmgr_os/pkg.yml b/mgmt/newtmgr/nmgr_os/pkg.yml new file mode 100644 index 0000000..6c39c16 --- /dev/null +++ b/mgmt/newtmgr/nmgr_os/pkg.yml @@ -0,0 +1,38 @@ +# +# 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: mgmt/newtmgr/nmgr_os +pkg.description: Default newtmgr command. +pkg.author: "Apache Mynewt <d...@mynewt.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - hw/hal + - time/datetime + - kernel/os + - mgmt/mgmt + - encoding/tinycbor + - encoding/cborattr + +pkg.deps.LOG_SOFT_RESET: + - sys/reboot + +pkg.req_apis: + - newtmgr diff --git a/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c b/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c new file mode 100644 index 0000000..b2ebc37 --- /dev/null +++ b/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c @@ -0,0 +1,346 @@ +/* + * 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 <syscfg/syscfg.h> + +#include <os/os.h> +#include <os/endian.h> + +#include <assert.h> +#include <string.h> + +#include <hal/hal_system.h> +#include <hal/hal_watchdog.h> + +#include <mgmt/mgmt.h> + +#include <console/console.h> +#include <datetime/datetime.h> + +#if MYNEWT_VAL(LOG_SOFT_RESET) +#include <reboot/log_reboot.h> +#endif + +#include "nmgr_os/nmgr_os.h" + +#include <tinycbor/cbor.h> +#include <cborattr/cborattr.h> + +static struct os_callout nmgr_reset_callout; + +static int nmgr_def_echo(struct mgmt_cbuf *); +static int nmgr_def_console_echo(struct mgmt_cbuf *); +static int nmgr_def_taskstat_read(struct mgmt_cbuf *njb); +static int nmgr_def_mpstat_read(struct mgmt_cbuf *njb); +static int nmgr_datetime_get(struct mgmt_cbuf *njb); +static int nmgr_datetime_set(struct mgmt_cbuf *njb); +static int nmgr_reset(struct mgmt_cbuf *njb); + +static const struct mgmt_handler nmgr_def_group_handlers[] = { + [NMGR_ID_ECHO] = { + nmgr_def_echo, nmgr_def_echo + }, + [NMGR_ID_CONS_ECHO_CTRL] = { + nmgr_def_console_echo, nmgr_def_console_echo + }, + [NMGR_ID_TASKSTATS] = { + nmgr_def_taskstat_read, NULL + }, + [NMGR_ID_MPSTATS] = { + nmgr_def_mpstat_read, NULL + }, + [NMGR_ID_DATETIME_STR] = { + nmgr_datetime_get, nmgr_datetime_set + }, + [NMGR_ID_RESET] = { + NULL, nmgr_reset + }, +}; + +#define NMGR_DEF_GROUP_SZ \ + (sizeof(nmgr_def_group_handlers) / sizeof(nmgr_def_group_handlers[0])) + +static struct mgmt_group nmgr_def_group = { + .mg_handlers = (struct mgmt_handler *)nmgr_def_group_handlers, + .mg_handlers_count = NMGR_DEF_GROUP_SZ, + .mg_group_id = MGMT_GROUP_ID_DEFAULT +}; + +static int +nmgr_def_echo(struct mgmt_cbuf *cb) +{ + char echo_buf[128] = {'\0'}; + CborError g_err = CborNoError; + + struct cbor_attr_t attrs[2] = { + [0] = { + .attribute = "d", + .type = CborAttrTextStringType, + .addr.string = echo_buf, + .nodefault = 1, + .len = sizeof(echo_buf), + }, + [1] = { + .attribute = NULL + } + }; + + g_err |= cbor_encode_text_stringz(&cb->encoder, "r"); + g_err |= cbor_read_object(&cb->it, attrs); + g_err |= cbor_encode_text_string(&cb->encoder, echo_buf, strlen(echo_buf)); + + if (g_err) { + return MGMT_ERR_ENOMEM; + } + return (0); +} + +static int +nmgr_def_console_echo(struct mgmt_cbuf *cb) +{ + long long int echo_on = 1; + int rc; + struct cbor_attr_t attrs[2] = { + [0] = { + .attribute = "echo", + .type = CborAttrIntegerType, + .addr.integer = &echo_on, + .nodefault = 1 + }, + [1] = { 0 }, + }; + + rc = cbor_read_object(&cb->it, attrs); + if (rc) { + return MGMT_ERR_EINVAL; + } + + if (echo_on) { + console_echo(1); + } else { + console_echo(0); + } + return (0); +} + +static int +nmgr_def_taskstat_read(struct mgmt_cbuf *cb) +{ + struct os_task *prev_task; + struct os_task_info oti; + CborError g_err = CborNoError; + CborEncoder tasks; + CborEncoder task; + + g_err |= cbor_encode_text_stringz(&cb->encoder, "rc"); + g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK); + g_err |= cbor_encode_text_stringz(&cb->encoder, "tasks"); + g_err |= cbor_encoder_create_map(&cb->encoder, &tasks, + CborIndefiniteLength); + + prev_task = NULL; + while (1) { + prev_task = os_task_info_get_next(prev_task, &oti); + if (prev_task == NULL) { + break; + } + + g_err |= cbor_encode_text_stringz(&tasks, oti.oti_name); + g_err |= cbor_encoder_create_map(&tasks, &task, CborIndefiniteLength); + g_err |= cbor_encode_text_stringz(&task, "prio"); + g_err |= cbor_encode_uint(&task, oti.oti_prio); + g_err |= cbor_encode_text_stringz(&task, "tid"); + g_err |= cbor_encode_uint(&task, oti.oti_taskid); + g_err |= cbor_encode_text_stringz(&task, "state"); + g_err |= cbor_encode_uint(&task, oti.oti_state); + g_err |= cbor_encode_text_stringz(&task, "stkuse"); + g_err |= cbor_encode_uint(&task, oti.oti_stkusage); + g_err |= cbor_encode_text_stringz(&task, "stksiz"); + g_err |= cbor_encode_uint(&task, oti.oti_stksize); + g_err |= cbor_encode_text_stringz(&task, "cswcnt"); + g_err |= cbor_encode_uint(&task, oti.oti_cswcnt); + g_err |= cbor_encode_text_stringz(&task, "runtime"); + g_err |= cbor_encode_uint(&task, oti.oti_runtime); + g_err |= cbor_encode_text_stringz(&task, "last_checkin"); + g_err |= cbor_encode_uint(&task, oti.oti_last_checkin); + g_err |= cbor_encode_text_stringz(&task, "next_checkin"); + g_err |= cbor_encode_uint(&task, oti.oti_next_checkin); + g_err |= cbor_encoder_close_container(&tasks, &task); + } + g_err |= cbor_encoder_close_container(&cb->encoder, &tasks); + + if (g_err) { + return MGMT_ERR_ENOMEM; + } + return (0); +} + +static int +nmgr_def_mpstat_read(struct mgmt_cbuf *cb) +{ + struct os_mempool *prev_mp; + struct os_mempool_info omi; + CborError g_err = CborNoError; + CborEncoder pools; + CborEncoder pool; + + g_err |= cbor_encode_text_stringz(&cb->encoder, "rc"); + g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK); + g_err |= cbor_encode_text_stringz(&cb->encoder, "mpools"); + g_err |= cbor_encoder_create_map(&cb->encoder, &pools, + CborIndefiniteLength); + + prev_mp = NULL; + while (1) { + prev_mp = os_mempool_info_get_next(prev_mp, &omi); + if (prev_mp == NULL) { + break; + } + + g_err |= cbor_encode_text_stringz(&pools, omi.omi_name); + g_err |= cbor_encoder_create_map(&pools, &pool, CborIndefiniteLength); + g_err |= cbor_encode_text_stringz(&pool, "blksiz"); + g_err |= cbor_encode_uint(&pool, omi.omi_block_size); + g_err |= cbor_encode_text_stringz(&pool, "nblks"); + g_err |= cbor_encode_uint(&pool, omi.omi_num_blocks); + g_err |= cbor_encode_text_stringz(&pool, "nfree"); + g_err |= cbor_encode_uint(&pool, omi.omi_num_free); + g_err |= cbor_encode_text_stringz(&pool, "min"); + g_err |= cbor_encode_uint(&pool, omi.omi_min_free); + g_err |= cbor_encoder_close_container(&pools, &pool); + } + + g_err |= cbor_encoder_close_container(&cb->encoder, &pools); + + if (g_err) { + return MGMT_ERR_ENOMEM; + } + return (0); +} + +static int +nmgr_datetime_get(struct mgmt_cbuf *cb) +{ + struct os_timeval tv; + struct os_timezone tz; + char buf[DATETIME_BUFSIZE]; + int rc; + CborError g_err = CborNoError; + + g_err |= cbor_encode_text_stringz(&cb->encoder, "rc"); + g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK); + + /* Display the current datetime */ + rc = os_gettimeofday(&tv, &tz); + assert(rc == 0); + rc = datetime_format(&tv, &tz, buf, DATETIME_BUFSIZE); + if (rc) { + rc = MGMT_ERR_EINVAL; + goto err; + } + g_err |= cbor_encode_text_stringz(&cb->encoder, "datetime"); + g_err |= cbor_encode_text_stringz(&cb->encoder, buf); + + if (g_err) { + return MGMT_ERR_ENOMEM; + } + return 0; + +err: + return (rc); +} + +static int +nmgr_datetime_set(struct mgmt_cbuf *cb) +{ + struct os_timeval tv; + struct os_timezone tz; + char buf[DATETIME_BUFSIZE]; + int rc = 0; + const struct cbor_attr_t datetime_write_attr[] = { + [0] = { + .attribute = "datetime", + .type = CborAttrTextStringType, + .addr.string = buf, + .len = sizeof(buf), + }, + { 0 }, + }; + + rc = cbor_read_object(&cb->it, datetime_write_attr); + if (rc) { + return MGMT_ERR_EINVAL; + } + + /* Set the current datetime */ + rc = datetime_parse(buf, &tv, &tz); + if (!rc) { + rc = os_settimeofday(&tv, &tz); + if (rc) { + return MGMT_ERR_EINVAL; + } + } else { + return MGMT_ERR_EINVAL; + } + + rc = mgmt_cbuf_setoerr(cb, 0); + if (rc != 0) { + return rc; + } + + return 0; +} + +static void +nmgr_reset_tmo(struct os_event *ev) +{ + /* + * Tickle watchdog just before re-entering bootloader. + * Depending on what system has been doing lately, watchdog + * timer might be close to firing. + */ + hal_watchdog_tickle(); + hal_system_reset(); +} + +static int +nmgr_reset(struct mgmt_cbuf *cb) +{ + int rc; + + os_callout_init(&nmgr_reset_callout, mgmt_evq_get(), nmgr_reset_tmo, NULL); + +#if MYNEWT_VAL(LOG_SOFT_RESET) + log_reboot(HAL_RESET_REQUESTED); +#endif + os_callout_reset(&nmgr_reset_callout, OS_TICKS_PER_SEC / 4); + + rc = mgmt_cbuf_setoerr(cb, 0); + if (rc != 0) { + return rc; + } + + return 0; +} + +int +nmgr_os_groups_register(void) +{ + return mgmt_group_register(&nmgr_def_group); +} + diff --git a/mgmt/newtmgr/nmgr_os/syscfg.yml b/mgmt/newtmgr/nmgr_os/syscfg.yml new file mode 100644 index 0000000..78caaf0 --- /dev/null +++ b/mgmt/newtmgr/nmgr_os/syscfg.yml @@ -0,0 +1,23 @@ +# +# 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_SOFT_RESET: + description: 'Log soft restarts' + value: 1 diff --git a/mgmt/newtmgr/pkg.yml b/mgmt/newtmgr/pkg.yml new file mode 100644 index 0000000..6f73873 --- /dev/null +++ b/mgmt/newtmgr/pkg.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. +# + +pkg.name: mgmt/newtmgr +pkg.description: Server-side newtmgr functionality. +pkg.author: "Apache Mynewt <d...@mynewt.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - encoding/cborattr + - kernel/os + - mgmt/mgmt + - mgmt/newtmgr/nmgr_os + - util/mem + +pkg.deps.NEWTMGR_BLE_HOST: + - mgmt/newtmgr/transport/ble + +pkg.apis: + - newtmgr + +pkg.init: + nmgr_pkg_init: 500 diff --git a/mgmt/newtmgr/src/mynewt_nmgr.c b/mgmt/newtmgr/src/mynewt_nmgr.c new file mode 100644 index 0000000..cdd9eac --- /dev/null +++ b/mgmt/newtmgr/src/mynewt_nmgr.c @@ -0,0 +1,182 @@ +#include "os/os.h" +#include "mgmt/mgmt.h" +#include "mem/mem.h" + +static mgmt_reader_trim_front_fn mynewt_nmgr_trim_front; +static mgmt_reader_trim_back_fn mynewt_nmgr_trim_back; +static mgmt_reader_write_at_fn mynewt_nmgr_write_at; + +static struct mgmt_cbor_cfg mynewt_nmgr_cbor_cfg = { + .mr.trim_front = mynewt_nmgr_trim_front, + .mw.trim_back = mynewt_nmgr_trim_back, + .mw.write_at = mynewt_nmgr_write_at, +}; + +/** + * Allocates an mbuf to contain an outgoing response fragment. + */ +static struct os_mbuf * +mynewt_nmgr_rsp_frag_alloc(uint16_t frag_size, void *arg) +{ + struct os_mbuf *src_rsp; + struct os_mbuf *frag; + + /* We need to duplicate the user header from the source response, as that + * is where transport-specific information is stored. + */ + src_rsp = arg; + + frag = os_msys_get_pkthdr(frag_size, OS_MBUF_USRHDR_LEN(src_rsp)); + if (frag != NULL) { + /* Copy the user header from the response into the fragment mbuf. */ + memcpy(OS_MBUF_USRHDR(frag), OS_MBUF_USRHDR(src_rsp), + OS_MBUF_USRHDR_LEN(src_rsp)); + } + + return frag; +} + +/** + * Sends a newtmgr response, fragmenting it as needed. The supplied response + * mbuf is consumed on success and in some failure cases. If the mbuf is + * consumed, the supplied pointer is set to NULL. + * + * This function prefers not to consume the supplied mbuf on failure. The + * reason for this is to allow the caller to reuse the mbuf for an error + * response. + */ +static int +mynewt_nmgr_rsp_tx(struct mynewt_nmgr_transport *mnt, struct os_mbuf **rsp, + uint16_t mtu) +{ + struct os_mbuf *frag; + int rc; + + while (*rsp != NULL) { + frag = mem_split_frag(rsp, mtu, nmgr_rsp_frag_alloc, *rsp); + if (frag == NULL) { + return MGMT_ERR_ENOMEM; + } + + rc = mnt->mnt_xport.nt_output(&mnt->mnt_xport, frag); + if (rc != 0) { + /* Output function already freed mbuf. */ + return MGMT_ERR_EUNKNOWN; + } + } + + return MGMT_ERR_EOK; +} + +static int +mynewt_nmgr_process_single_packet(struct mynewt_nmgr_transport *mnt, + struct os_mbuf *req) +{ + struct nmgr_hdr req_hdr; + struct os_mbuf *rsp; + int err_rc; + int rc; + + cbor_mbuf_reader_init(mynewt_nmgr_cbor_cfg.reader, req, 0); + + while (1) { + rc = nmgr_read_hdr(&mynewt_nmgr_cbor_cfg, &req_hdr); + if (rc != 0) { + rc = 0; + goto done; + } + + rsp = os_msys_get_pkthdr(512, OS_MBUF_USRHDR_LEN(req)); + if (rsp == NULL) { + rc = MGMT_ERR_ENOMEM; + goto done; + } + + cbor_mbuf_writer_init(mynewt_nmgr_cbor_cfg.writer, rsp); + + rc = nmgr_handle_single_req(&mynewt_nmgr_cbor_cfg, &req_hdr) + if (rc != 0) { + goto done; + } + + os_mbuf_adj(req, sizeof *req_hdr + OS_ALIGN(req_hdr.nh_len, 4)); + + if (OS_MBUF_PKTLEN(rsp) > 0) { + rc = mynewt_nmgr_rsp_tx(mnt, &rsp, 65535 /* XXX */); + if (rc != 0) { + goto done; + } + } + } + + rc = 0; + +done: + if (rc != 0) { + if (rsp == NULL) { + rsp = req; + req = NULL; + } + + os_mbuf_adj(rsp, OS_MBUF_PKTLEN(rsp)); + cbor_mbuf_writer_init(mynewt_nmgr_cbor_cfg.writer, rsp); + + err_rc = nmgr_build_err_rsp(&mynewt_nmgr_cbor_cfg, &req_hdr, rc); + if (err_rc == 0) { + err_rc = mynewt_nmgr_rsp_tx(mnt, &rsp, 65535 /* XXX */); + rsp = NULL; + } + } + + os_mbuf_free_chain(req); + os_mbuf_free_chain(rsp); + + return rc; +} + +static void +mynewt_nmgr_process(struct mynewt_nmgr_transport *mnt) +{ + struct cbor_mbuf_reader reader; + struct cbor_mbuf_writer writer; + struct os_mbuf *rsp; + struct os_mbuf *req; + int rc; + + mynewt_nmgr_cbor_cfg.reader = &reader; + mynewt_nmgr_cbor_cfg.writer = &writer; + + while (1) { + req = os_mqueue_get(&mnt->mnt_imq); + if (req == NULL) { + break; + } + + rc = mynewt_nmgr_process_single_packet(mnt, req) + if (rc != 0) { + break; + } + } +} + +static void +mynewt_nmgr_event_data_in(struct os_event *ev) +{ + mynewt_nmgr_process(ev->ev_arg); +} + +int +mynewt_nmgr_transport_init(struct mynewt_nmgr_transport *mnt, + nmgr_transport_out_func_t output_func) +{ + int rc; + + mnt->mnt_xport.nt_output = output_func; + + rc = os_mqueue_init(&mnt->nt_imq, mynewt_nmgr_event_data_in, mnt); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/mgmt/newtmgr/src/newtmgr.c b/mgmt/newtmgr/src/newtmgr.c new file mode 100644 index 0000000..cdd1c22 --- /dev/null +++ b/mgmt/newtmgr/src/newtmgr.c @@ -0,0 +1,205 @@ +/* + * 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 <assert.h> +#include <string.h> + +#include "syscfg/syscfg.h" +#include "sysinit/sysinit.h" +#include "os/os.h" +#include "os/endian.h" /* XXX */ + +#include "mgmt/mgmt.h" + +#include "newtmgr/newtmgr.h" + +#include "tinycbor/cbor.h" +#include "tinycbor/cbor_mbuf_writer.h" +#include "tinycbor/cbor_mbuf_reader.h" + +static uint8_t +nmgr_rsp_op(uint8_t req_op) +{ + if (req_op == NMGR_OP_READ) { + return NMGR_OP_READ_RSP; + } else { + return NMGR_OP_WRITE_RSP; + } +} + +static void +nmgr_ntoh_hdr(struct nmgr_hdr *hdr) +{ + hdr.nh_len = ntohs(hdr.nh_len); + hdr.nh_group = ntohs(hdr.nh_group); +} + +static void +nmgr_hton_hdr(struct nmgr_hdr *hdr) +{ + hdr.nh_len = htons(hdr.nh_len); + hdr.nh_group = htons(hdr.nh_group); +} + +static void +nmgr_init_rsp_hdr(const struct nmgr_hdr *req_hdr, struct nmgr_hdr *rsp_hdr) +{ + rsp_hdr->nh_len = 0; + rsp_hdr->nh_flags = 0; + rsp_hdr->nh_op = nmgr_rsp_op(req_hdr->nh_op); + rsp_hdr->nh_group = req_hdr->nh_group; + rsp_hdr->nh_seq = req_hdr->nh_seq; + rsp_hdr->nh_id = req_hdr->nh_id; +} + +static int +nmgr_read_hdr(struct mgmt_cbor_cfg *cfg, struct nmgr_hdr *hdr) +{ + if (cfg->reader->message_size < sizeof *hdr) { + return MGMT_ERR_EINVAL; + } + + cfg->reader->cpy(cfg->reader, (char *)hdr, 0, sizeof *hdr); + return 0; +} + +static int +nmgr_write_hdr(struct mgmt_cbor_cfg *cfg, const struct nmgr_hdr *hdr) +{ + rc = cfg->write_at(cfg->writer, 0, hdr, sizeof *hdr); + return mgmt_err_from_cbor(rc); +} + +int +nmgr_build_err_rsp(struct mgmt_cbor_cfg *cfg, const struct nmgr_hdr *req_hdr, + int status) +{ + struct CborEncoder map; + struct mgmt_cbuf cbuf; + struct nmgr_hdr rsp_hdr; + int rc; + + rc = mgmt_cbuf_init(&cbuf, cfg); + if (rc != 0) { + return rc; + } + + nmgr_init_rsp_hdr(req_hdr, &rsp_hdr); + rc = nmgr_write_hdr(cfg, &rsp_hdr); + if (rc != 0) { + return rc; + } + + rc = cbor_encoder_create_map(encoder, &map, CborIndefiniteLength); + if (rc != 0) { + return rc; + } + + rc = mgmt_cbuf_setoerr(encoder, status); + if (rc != 0) { + return rc; + } + + rc = cbor_encoder_close_container(encoder, &map); + if (rc != 0) { + return rc; + } + + rsp_hdr.nh_len = htons(cbor_encode_bytes_written(encoder)); + rc = nmgr_write_hdr(cfg, &rsp_hdr); + if (rc != 0) { + return rc; + } + + return 0; +} + +int +nmgr_handle_single_req(struct mgmt_cbor_cfg *cfg, + const struct nmgr_hdr *req_hdr) +{ + struct CborEncoder payload_encoder; + struct mgmt_cbuf cbuf; + struct nmgr_hdr rsp_hdr; + int rc; + + rc = mgmt_cbuf_init(&cbuf, cfg); + if (rc != 0) { + return rc; + } + + handler = mgmt_find_handler(req_hdr->nh_group, req_hdr->nh_id); + if (!handler) { + return MGMT_ERR_ENOENT; + } + + /* Build response header a priori, then pass to the handlers to fill out + * the response data and adjust length and flags. + */ + nmgr_init_rsp_hdr(req_hdr, &rsp_hdr); + rc = nmgr_write_hdr(cfg, &rsp_hdr); + if (rc != 0) { + return rc; + } + + /* Begin response payload. Response fields are inserted into the root + * map as key value pairs. + */ + rc = cbor_encoder_create_map(&cbuf.encoder, &payload_encoder, + CborIndefiniteLength); + rc = mgmt_err_from_cbor(rc); + if (rc != 0) { + return rc; + } + + if (req_hdr->nh_op == NMGR_OP_READ) { + if (handler->mh_read) { + rc = handler->mh_read(&cbuf); + } else { + rc = MGMT_ERR_ENOENT; + } + } else if (req_hdr->nh_op == NMGR_OP_WRITE) { + if (handler->mh_write) { + rc = handler->mh_write(&cbuf); + } else { + rc = MGMT_ERR_ENOENT; + } + } else { + rc = MGMT_ERR_EINVAL; + } + if (rc != 0) { + return rc; + } + + /* End response payload. */ + rc = cbor_encoder_close_container(&cbuf.encoder, &payload_encoder); + rc = mgmt_err_from_cbor(rc); + if (rc != 0) { + return rc; + } + + rsp_hdr.nh_len = cbor_encode_bytes_written(&cbuf.encoder); + nmgr_hton_hdr(&rsp_hdr); + rc = nmgr_write_hdr(cfg, &rsp_hdr); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/mgmt/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h b/mgmt/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h new file mode 100644 index 0000000..4666d04 --- /dev/null +++ b/mgmt/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h @@ -0,0 +1,42 @@ +/* + * 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 _NEWTMGR_BLE_H_ +#define _NEWTMGR_BLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct nmgr_hdr; + +int +nmgr_ble_proc_mq_evt(struct os_event *ev); + +int +nmgr_ble_gatt_svr_init(void); + +void +nmgr_ble_update_rsp_len(struct os_mbuf *req, uint16_t *len, uint8_t *flags); + +#ifdef __cplusplus +} +#endif + +#endif /* _NETMGR_H */ diff --git a/mgmt/newtmgr/transport/ble/pkg.yml b/mgmt/newtmgr/transport/ble/pkg.yml new file mode 100644 index 0000000..af3dc32 --- /dev/null +++ b/mgmt/newtmgr/transport/ble/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: mgmt/newtmgr/transport/ble +pkg.description: BLE transport newtmgr functionality. +pkg.author: "Apache Mynewt <d...@mynewt.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + +pkg.deps: + - kernel/os + - mgmt/mgmt + - mgmt/newtmgr + - net/nimble/host + +pkg.init: + newtmgr_ble_pkg_init: 501 diff --git a/mgmt/newtmgr/transport/ble/src/newtmgr_ble.c b/mgmt/newtmgr/transport/ble/src/newtmgr_ble.c new file mode 100644 index 0000000..907e1c7 --- /dev/null +++ b/mgmt/newtmgr/transport/ble/src/newtmgr_ble.c @@ -0,0 +1,242 @@ +/* + * 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 <assert.h> +#include <stdio.h> +#include <string.h> +#include "sysinit/sysinit.h" +#include "host/ble_hs.h" +#include "mgmt/mgmt.h" +#include "newtmgr/newtmgr.h" +#include "os/endian.h" +#include "console/console.h" + +/* nmgr ble mqueue */ +struct os_mqueue nmgr_ble_mq; + +/* ble nmgr transport */ +struct nmgr_transport ble_nt; + +/* ble nmgr attr handle */ +uint16_t g_ble_nmgr_attr_handle; + +/** + * The vendor specific "newtmgr" service consists of one write no-rsp + * characteristic for newtmgr requests: a single-byte characteristic that can + * only accepts write-without-response commands. The contents of each write + * command contains an NMP request. NMP responses are sent back in the form of + * unsolicited notifications from the same characteristic. + */ + +/* {8D53DC1D-1DB7-4CD3-868B-8A527460AA84} */ +static const ble_uuid128_t gatt_svr_svc_newtmgr = + BLE_UUID128_INIT(0x84, 0xaa, 0x60, 0x74, 0x52, 0x8a, 0x8b, 0x86, + 0xd3, 0x4c, 0xb7, 0x1d, 0x1d, 0xdc, 0x53, 0x8d); + +/* {DA2E7828-FBCE-4E01-AE9E-261174997C48} */ +static const ble_uuid128_t gatt_svr_chr_newtmgr = + BLE_UUID128_INIT(0x48, 0x7c, 0x99, 0x74, 0x11, 0x26, 0x9e, 0xae, + 0x01, 0x4e, 0xce, 0xfb, 0x28, 0x78, 0x2e, 0xda); + +static int +gatt_svr_chr_access_newtmgr(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: newtmgr */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc_newtmgr.u, + .characteristics = (struct ble_gatt_chr_def[]) { { + /* Characteristic: Write No Rsp */ + .uuid = &gatt_svr_chr_newtmgr.u, + .access_cb = gatt_svr_chr_access_newtmgr, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_NOTIFY, + .val_handle = &g_ble_nmgr_attr_handle, + }, { + 0, /* No more characteristics in this service */ + } }, + }, + + { + 0, /* No more services */ + }, +}; + +static int +gatt_svr_chr_access_newtmgr(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + int rc; + struct os_mbuf *m_req; + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_WRITE_CHR: + /* Try to reuse the BLE packet mbuf as the newtmgr request. This + * requires a two-byte usrhdr to hold the BLE connection handle so + * that the newtmgr response can be sent to the correct peer. If + * it is not possible to reuse the mbuf, then allocate a new one + * and copy the request contents. + */ + if (OS_MBUF_USRHDR_LEN(ctxt->om) >= sizeof (conn_handle)) { + /* Sufficient usrhdr space already present. */ + m_req = ctxt->om; + ctxt->om = NULL; + } else if (OS_MBUF_LEADINGSPACE(ctxt->om) >= + sizeof (conn_handle)) { + + /* Usrhdr isn't present, but there is enough leading space to + * add one. + */ + m_req = ctxt->om; + ctxt->om = NULL; + + m_req->om_pkthdr_len += sizeof (conn_handle); + } else { + /* The mbuf can't be reused. Allocate a new one and perform a + * copy. Don't set ctxt->om to NULL; let the NimBLE host free + * it. + */ + m_req = os_msys_get_pkthdr(OS_MBUF_PKTLEN(ctxt->om), + sizeof (conn_handle)); + if (!m_req) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + rc = os_mbuf_appendfrom(m_req, ctxt->om, 0, + OS_MBUF_PKTLEN(ctxt->om)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + } + + /* Write the connection handle to the newtmgr request usrhdr. This + * is necessary so that we later know who to send the newtmgr + * response to. + */ + memcpy(OS_MBUF_USRHDR(m_req), &conn_handle, sizeof(conn_handle)); + + rc = nmgr_rx_req(&ble_nt, m_req); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + return 0; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + +uint16_t +nmgr_ble_get_mtu(struct os_mbuf *req) { + + uint16_t conn_handle; + uint16_t mtu; + + memcpy(&conn_handle, OS_MBUF_USRHDR(req), sizeof (conn_handle)); + mtu = ble_att_mtu(conn_handle); + if (!mtu) { + /* No longer connected. */ + return 0; + } + + /* 3 is the number of bytes for ATT notification base */ + mtu = mtu - 3; + + return (mtu); +} + +/** + * Nmgr ble process mqueue event + * Gets an event from the nmgr mqueue and does a notify with the response + * + * @param eventq + * @return 0 on success; non-zero on failure + */ + +static void +nmgr_ble_event_data_in(struct os_event *ev) +{ + struct os_mbuf *m_resp; + uint16_t conn_handle; + + while ((m_resp = os_mqueue_get(&nmgr_ble_mq)) != NULL) { + assert(OS_MBUF_USRHDR_LEN(m_resp) >= sizeof (conn_handle)); + memcpy(&conn_handle, OS_MBUF_USRHDR(m_resp), sizeof (conn_handle)); + ble_gattc_notify_custom(conn_handle, g_ble_nmgr_attr_handle, + m_resp); + } +} + +static int +nmgr_ble_out(struct nmgr_transport *nt, struct os_mbuf *om) +{ + int rc; + + rc = os_mqueue_put(&nmgr_ble_mq, mgmt_evq_get(), om); + if (rc != 0) { + goto err; + } + + return (0); +err: + os_mbuf_free_chain(om); + return (rc); +} + +/** + * Nmgr ble GATT server initialization + * + * @param eventq + * @return 0 on success; non-zero on failure + */ +int +nmgr_ble_gatt_svr_init(void) +{ + int rc; + + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + goto err; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + os_mqueue_init(&nmgr_ble_mq, &nmgr_ble_event_data_in, NULL); + + rc = nmgr_transport_init(&ble_nt, nmgr_ble_out, nmgr_ble_get_mtu); + +err: + return rc; +} + +void +newtmgr_ble_pkg_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = nmgr_ble_gatt_svr_init(); + SYSINIT_PANIC_ASSERT(rc == 0); +} diff --git a/mgmt/newtmgr/transport/nmgr_shell/pkg.yml b/mgmt/newtmgr/transport/nmgr_shell/pkg.yml new file mode 100644 index 0000000..2a859cb --- /dev/null +++ b/mgmt/newtmgr/transport/nmgr_shell/pkg.yml @@ -0,0 +1,34 @@ +# +# 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: mgmt/newtmgr/transport/nmgr_shell +pkg.description: Newtmgr transport over shell +pkg.author: "Apache Mynewt <d...@mynewt.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - newtmgr + - shell + +pkg.deps: + - kernel/os + - sys/shell + - mgmt/newtmgr + +pkg.init: + nmgr_shell_pkg_init: 501 diff --git a/mgmt/newtmgr/transport/nmgr_shell/src/nmgr_shell.c b/mgmt/newtmgr/transport/nmgr_shell/src/nmgr_shell.c new file mode 100644 index 0000000..c57e9b1 --- /dev/null +++ b/mgmt/newtmgr/transport/nmgr_shell/src/nmgr_shell.c @@ -0,0 +1,71 @@ +/* + * 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 <inttypes.h> +#include <assert.h> + +#include <sysinit/sysinit.h> +#include <shell/shell.h> +#include <mgmt/mgmt.h> +#include <newtmgr/newtmgr.h> + +static struct nmgr_transport nmgr_shell_transport; + +static uint16_t +nmgr_shell_get_mtu(struct os_mbuf *m) +{ + return MGMT_MAX_MTU; +} + +static int +nmgr_shell_out(struct nmgr_transport *nt, struct os_mbuf *m) +{ + int rc; + + rc = shell_nlip_output(m); + if (rc != 0) { + goto err; + } + + return (0); +err: + os_mbuf_free_chain(m); + return (rc); +} + +static int +nmgr_shell_in(struct os_mbuf *m, void *arg) +{ + return nmgr_rx_req(&nmgr_shell_transport, m); +} + +void +nmgr_shell_pkg_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = nmgr_transport_init(&nmgr_shell_transport, nmgr_shell_out, + nmgr_shell_get_mtu); + assert(rc == 0); + + rc = shell_nlip_input_register(nmgr_shell_in, &nmgr_shell_transport); + assert(rc == 0); +} diff --git a/mgmt/newtmgr/transport/nmgr_uart/pkg.yml b/mgmt/newtmgr/transport/nmgr_uart/pkg.yml new file mode 100644 index 0000000..9e62a32 --- /dev/null +++ b/mgmt/newtmgr/transport/nmgr_uart/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: mgmt/newtmgr/transport/nmgr_uart +pkg.description: Newtmgr transport over raw UART +pkg.author: "Apache Mynewt <d...@mynewt.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - newtmgr + - uart + +pkg.deps: + - kernel/os + - hw/drivers/uart + - mgmt/newtmgr + - util/crc + +pkg.init: + nmgr_uart_pkg_init: 501 diff --git a/mgmt/newtmgr/transport/nmgr_uart/src/nmgr_uart.c b/mgmt/newtmgr/transport/nmgr_uart/src/nmgr_uart.c new file mode 100644 index 0000000..4465079 --- /dev/null +++ b/mgmt/newtmgr/transport/nmgr_uart/src/nmgr_uart.c @@ -0,0 +1,389 @@ +/* + * 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 <inttypes.h> +#include <assert.h> + +#include <syscfg/syscfg.h> +#include <sysinit/sysinit.h> +#include <bsp/bsp.h> + +#include <os/os.h> +#include <mgmt/mgmt.h> +#include <newtmgr/newtmgr.h> +#include <uart/uart.h> + +#include <crc/crc16.h> +#include <base64/base64.h> + +#define SHELL_NLIP_PKT 0x0609 +#define SHELL_NLIP_DATA 0x0414 +#define SHELL_NLIP_MAX_FRAME 128 + +#define NUS_EV_TO_STATE(ptr) \ + (struct nmgr_uart_state *)((uint8_t *)ptr - \ + (int)&(((struct nmgr_uart_state *)0)->nus_cb_ev)) + +struct nmgr_uart_state { + struct nmgr_transport nus_transport; /* keep first in struct */ + struct os_event nus_cb_ev; + struct uart_dev *nus_dev; + struct os_mbuf *nus_tx; + int nus_tx_off; + struct os_mbuf_pkthdr *nus_rx_pkt; + struct os_mbuf_pkthdr *nus_rx_q; + struct os_mbuf_pkthdr *nus_rx; +}; + +/* + * Header for frames arriving over serial. + */ +struct nmgr_ser_hdr { + uint16_t nsh_seq; + uint16_t nsh_len; +}; + +static struct nmgr_uart_state nmgr_uart_state; + +static uint16_t +nmgr_uart_mtu(struct os_mbuf *m) +{ + return MGMT_MAX_MTU; +} + +/* + * Called by mgmt to queue packet out to UART. + */ +static int +nmgr_uart_out(struct nmgr_transport *nt, struct os_mbuf *m) +{ + struct nmgr_uart_state *nus = (struct nmgr_uart_state *)nt; + struct os_mbuf_pkthdr *mpkt; + struct os_mbuf *n; + uint16_t tmp_buf[6]; + char *dst; + int off; + int boff; + int slen; + int sr; + int rc; + int last; + int tx_sz; + + assert(OS_MBUF_IS_PKTHDR(m)); + mpkt = OS_MBUF_PKTHDR(m); + + /* + * Compute CRC-16 and append it to end. + */ + off = 0; + tmp_buf[0] = CRC16_INITIAL_CRC; + for (n = m; n; n = SLIST_NEXT(n, om_next)) { + tmp_buf[0] = crc16_ccitt(tmp_buf[0], n->om_data, n->om_len); + } + tmp_buf[0] = htons(tmp_buf[0]); + dst = os_mbuf_extend(m, sizeof(uint16_t)); + if (!dst) { + goto err; + } + memcpy(dst, tmp_buf, sizeof(uint16_t)); + + /* + * Create another mbuf chain with base64 encoded data. + */ + n = os_msys_get(SHELL_NLIP_MAX_FRAME, 0); + if (!n || OS_MBUF_TRAILINGSPACE(n) < 32) { + goto err; + } + + while (off < mpkt->omp_len) { + /* + * First fragment has a different header, and length of the full frame + * (need to base64 encode that). + */ + if (off == 0) { + tmp_buf[0] = htons(SHELL_NLIP_PKT); + } else { + tmp_buf[0] = htons(SHELL_NLIP_DATA); + } + rc = os_mbuf_append(n, tmp_buf, sizeof(uint16_t)); + if (rc) { + goto err; + } + tx_sz = 2; + + if (off == 0) { + tmp_buf[0] = htons(mpkt->omp_len); + boff = sizeof(uint16_t); + } else { + boff = 0; + } + + while (off < mpkt->omp_len) { + slen = mpkt->omp_len - off; + last = 1; + if (slen > sizeof(tmp_buf) + boff) { + slen = sizeof(tmp_buf) - boff; + last = 0; + } + if (tx_sz + BASE64_ENCODE_SIZE(slen + boff) >= 124) { + break; + } + rc = os_mbuf_copydata(m, off, slen, (uint8_t *)tmp_buf + boff); + assert(rc == 0); + + off += slen; + slen += boff; + + dst = os_mbuf_extend(n, BASE64_ENCODE_SIZE(slen)); + if (!dst) { + goto err; + } + tx_sz += base64_encode(tmp_buf, slen, dst, last); + boff = 0; + } + + if (os_mbuf_append(n, "\n", 1)) { + goto err; + } + } + + os_mbuf_free_chain(m); + OS_ENTER_CRITICAL(sr); + if (!nus->nus_tx) { + nus->nus_tx = n; + uart_start_tx(nus->nus_dev); + } else { + os_mbuf_concat(nus->nus_tx, n); + } + OS_EXIT_CRITICAL(sr); + + return 0; +err: + os_mbuf_free_chain(m); + os_mbuf_free_chain(n); + return -1; +} + +/* + * Called by UART driver to send out next character. + * + * Interrupts disabled when nmgr_uart_tx_char/nmgr_uart_rx_char are called. + */ +static int +nmgr_uart_tx_char(void *arg) +{ + struct nmgr_uart_state *nus = (struct nmgr_uart_state *)arg; + struct os_mbuf *m; + uint8_t ch; + + if (!nus->nus_tx) { + /* + * Out of data. Return -1 makes UART stop asking for more. + */ + return -1; + } + while (nus->nus_tx->om_len == nus->nus_tx_off) { + /* + * If no active mbuf, move to next one. + */ + m = SLIST_NEXT(nus->nus_tx, om_next); + os_mbuf_free(nus->nus_tx); + nus->nus_tx = m; + + nus->nus_tx_off = 0; + if (!nus->nus_tx) { + return -1; + } + } + + os_mbuf_copydata(nus->nus_tx, nus->nus_tx_off++, 1, &ch); + + return ch; +} + +/* + * Check for full packet. If frame is not right, free the mbuf. + */ +static void +nmgr_uart_rx_pkt(struct nmgr_uart_state *nus, struct os_mbuf_pkthdr *rxm) +{ + struct os_mbuf *m; + struct nmgr_ser_hdr *nsh; + uint16_t crc; + int rc; + + m = OS_MBUF_PKTHDR_TO_MBUF(rxm); + + if (rxm->omp_len <= sizeof(uint16_t) + sizeof(crc)) { + goto err; + } + + nsh = (struct nmgr_ser_hdr *)m->om_data; + switch (nsh->nsh_seq) { + case htons(SHELL_NLIP_PKT): + if (nus->nus_rx_pkt) { + os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx_pkt)); + nus->nus_rx_pkt = NULL; + } + break; + case htons(SHELL_NLIP_DATA): + if (!nus->nus_rx_pkt) { + goto err; + } + break; + default: + goto err; + } + + if (os_mbuf_append(m, "\0", 1)) { + /* + * Null-terminate the line for base64_decode's sake. + */ + goto err; + } + m = os_mbuf_pullup(m, rxm->omp_len); + if (!m) { + /* + * Make data contiguous for base64_decode's sake. + */ + goto err; + } + rxm = OS_MBUF_PKTHDR(m); + rc = base64_decode((char *)m->om_data + 2, (char *)m->om_data + 2); + if (rc < 0) { + goto err; + } + rxm->omp_len = m->om_len = rc + 2; + if (nus->nus_rx_pkt) { + os_mbuf_adj(m, 2); + os_mbuf_concat(OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx_pkt), m); + } else { + nus->nus_rx_pkt = rxm; + } + + m = OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx_pkt); + nsh = (struct nmgr_ser_hdr *)m->om_data; + if (nus->nus_rx_pkt->omp_len - sizeof(*nsh) == ntohs(nsh->nsh_len)) { + os_mbuf_adj(m, 4); + os_mbuf_adj(m, -2); + nmgr_rx_req(&nus->nus_transport, m); + nus->nus_rx_pkt = NULL; + } + return; +err: + os_mbuf_free_chain(m); +} + +/* + * Callback from mgmt task context. + */ +static void +nmgr_uart_rx_frame(struct os_event *ev) +{ + struct nmgr_uart_state *nus = NUS_EV_TO_STATE(ev); + struct os_mbuf_pkthdr *m; + int sr; + + OS_ENTER_CRITICAL(sr); + m = nus->nus_rx_q; + nus->nus_rx_q = NULL; + OS_EXIT_CRITICAL(sr); + if (m) { + nmgr_uart_rx_pkt(nus, m); + } +} + +/* + * Receive a character from UART. + */ +static int +nmgr_uart_rx_char(void *arg, uint8_t data) +{ + struct nmgr_uart_state *nus = (struct nmgr_uart_state *)arg; + struct os_mbuf *m; + int rc; + + if (!nus->nus_rx) { + m = os_msys_get_pkthdr(SHELL_NLIP_MAX_FRAME, 0); + if (!m) { + return 0; + } + nus->nus_rx = OS_MBUF_PKTHDR(m); + if (OS_MBUF_TRAILINGSPACE(m) < SHELL_NLIP_MAX_FRAME) { + /* + * mbuf is too small. + */ + os_mbuf_free_chain(m); + nus->nus_rx = NULL; + return 0; + } + } + + m = OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx); + if (data == '\n') { + /* + * Full line of input. Process it outside interrupt context. + */ + assert(!nus->nus_rx_q); + nus->nus_rx_q = nus->nus_rx; + nus->nus_rx = NULL; + os_eventq_put(mgmt_evq_get(), &nus->nus_cb_ev); + return 0; + } else { + rc = os_mbuf_append(m, &data, 1); + if (rc == 0) { + return 0; + } + } + /* failed */ + nus->nus_rx->omp_len = 0; + m->om_len = 0; + os_mbuf_free_chain(SLIST_NEXT(m, om_next)); + SLIST_NEXT(m, om_next) = NULL; + return 0; +} + +void +nmgr_uart_pkg_init(void) +{ + struct nmgr_uart_state *nus = &nmgr_uart_state; + int rc; + struct uart_conf uc = { + .uc_speed = MYNEWT_VAL(NMGR_UART_SPEED), + .uc_databits = 8, + .uc_stopbits = 1, + .uc_parity = UART_PARITY_NONE, + .uc_flow_ctl = UART_FLOW_CTL_NONE, + .uc_tx_char = nmgr_uart_tx_char, + .uc_rx_char = nmgr_uart_rx_char, + .uc_cb_arg = nus + }; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = nmgr_transport_init(&nus->nus_transport, nmgr_uart_out, nmgr_uart_mtu); + assert(rc == 0); + + nus->nus_dev = + (struct uart_dev *)os_dev_open(MYNEWT_VAL(NMGR_UART), 0, &uc); + assert(nus->nus_dev); + + nus->nus_cb_ev.ev_cb = nmgr_uart_rx_frame; +} diff --git a/mgmt/newtmgr/transport/nmgr_uart/syscfg.yml b/mgmt/newtmgr/transport/nmgr_uart/syscfg.yml new file mode 100644 index 0000000..2d9d15e --- /dev/null +++ b/mgmt/newtmgr/transport/nmgr_uart/syscfg.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. +# + +syscfg.defs: + NMGR_UART: + description: 'UART port number to use for newtmgr' + value: '"uart0"' + + NMGR_UART_SPEED: + description: 'Baudrate for newtmgr UART' + value: 115200 + -- To stop receiving notification emails like this one, please contact "commits@mynewt.apache.org" <commits@mynewt.apache.org>.