diff options
author | Vipul Rahane <vipul@runtime.io> | 2016-07-12 16:22:39 -0700 |
---|---|---|
committer | Vipul Rahane <vipul@runtime.io> | 2016-07-18 11:46:41 -0700 |
commit | f1ff4abfe63c88dcd599fcea2743c3739cc32661 (patch) | |
tree | 80b21ec8f40ac2f97cfe149e15335aed6e0b54c9 | |
parent | 8e930a76dfb515e0c08a8000a1bb418a1528a829 (diff) |
MYNEWT-266 Newtmgr over BLE
- Enable remote configuration, remote soft reset,
firmware upgrade
- Adding a seperate package for BLE newtmgr transport
- Adding BLE_HOST feature
- Moving logs constants from source file to header file; Were causing
issues while testing
- Increasing imgmgr max msg size to 400; Can be increased further when
we support higher MTUs with BLE
- Increasing stack size and number of mbufs for bleprph
- Creating a separate library for newtmgr over BLE
-rw-r--r-- | apps/bleprph/pkg.yml | 2 | ||||
-rwxr-xr-x | apps/bleprph/src/main.c | 25 | ||||
-rw-r--r-- | libs/imgmgr/include/imgmgr/imgmgr.h | 2 | ||||
-rw-r--r-- | libs/newtmgr/pkg.yml | 5 | ||||
-rw-r--r-- | libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h | 28 | ||||
-rw-r--r-- | libs/newtmgr/transport/ble/pkg.yml | 30 | ||||
-rw-r--r-- | libs/newtmgr/transport/ble/src/newtmgr_ble.c | 218 | ||||
-rw-r--r-- | net/nimble/host/pkg.yml | 3 | ||||
-rw-r--r-- | sys/log/include/log/log.h | 8 | ||||
-rw-r--r-- | sys/log/src/log_nmgr.c | 8 |
10 files changed, 317 insertions, 12 deletions
diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml index 4b0c0b34..ec753592 100644 --- a/apps/bleprph/pkg.yml +++ b/apps/bleprph/pkg.yml @@ -31,6 +31,8 @@ pkg.deps: - net/nimble/host/store/ram - libs/console/full - libs/baselibc + - libs/newtmgr + - libs/newtmgr/transport/ble pkg.cflags: # Use INFO log level to reduce code size. DEBUG is too large for nRF51. diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c index 6bf79edd..f7ccf827 100755 --- a/apps/bleprph/src/main.c +++ b/apps/bleprph/src/main.c @@ -27,6 +27,7 @@ #include "hal/hal_gpio.h" #include "hal/hal_cputime.h" #include "console/console.h" +#include <imgmgr/imgmgr.h> /* BLE */ #include "nimble/ble.h" @@ -40,6 +41,9 @@ #include "host/ble_l2cap.h" #include "host/ble_sm.h" #include "controller/ble_ll.h" +/* Newtmgr include */ +#include "newtmgr/newtmgr.h" +#include "nmgrble/newtmgr_ble.h" /* RAM persistence layer. */ #include "store/ram/ble_store_ram.h" @@ -52,7 +56,7 @@ #include "bleprph.h" /** Mbuf settings. */ -#define MBUF_NUM_MBUFS (12) +#define MBUF_NUM_MBUFS (24) #define MBUF_BUF_SIZE OS_ALIGN(BLE_MBUF_PAYLOAD_SIZE, 4) #define MBUF_MEMBLOCK_SIZE (MBUF_BUF_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD) #define MBUF_MEMPOOL_SIZE OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE) @@ -70,7 +74,11 @@ struct log bleprph_log; /** bleprph task settings. */ #define BLEPRPH_TASK_PRIO 1 -#define BLEPRPH_STACK_SIZE (OS_STACK_ALIGN(336)) +#define BLEPRPH_STACK_SIZE (OS_STACK_ALIGN(512)) + +#define NEWTMGR_TASK_PRIO (4) +#define NEWTMGR_TASK_STACK_SIZE (OS_STACK_ALIGN(1024)) +os_stack_t newtmgr_stack[NEWTMGR_TASK_STACK_SIZE]; struct os_eventq bleprph_evq; struct os_task bleprph_task; @@ -277,6 +285,13 @@ bleprph_task_handler(void *unused) while (1) { ev = os_eventq_get(&bleprph_evq); + + /* Check if the event is a nmgr ble mqueue event */ + rc = nmgr_ble_proc_mq_evt(ev); + if (!rc) { + continue; + } + switch (ev->ev_type) { case OS_EVENT_T_TIMER: cf = (struct os_callout_func *)ev; @@ -387,6 +402,9 @@ main(void) rc = console_init(NULL); assert(rc == 0); + nmgr_task_init(NEWTMGR_TASK_PRIO, newtmgr_stack, NEWTMGR_TASK_STACK_SIZE); + imgmgr_module_init(); + /* Register GATT attributes (services, characteristics, and * descriptors). */ @@ -403,6 +421,9 @@ main(void) rc = ble_svc_gap_device_name_set("nimble-bleprph"); assert(rc == 0); + /* Register nmgr ble GATT service and characteristic */ + nmgr_ble_gatt_svr_init(&bleprph_evq); + /* Start the OS */ os_start(); diff --git a/libs/imgmgr/include/imgmgr/imgmgr.h b/libs/imgmgr/include/imgmgr/imgmgr.h index d007e7f2..17c9e7f4 100644 --- a/libs/imgmgr/include/imgmgr/imgmgr.h +++ b/libs/imgmgr/include/imgmgr/imgmgr.h @@ -29,7 +29,7 @@ #define IMGMGR_NMGR_OP_CORELIST 6 #define IMGMGR_NMGR_OP_CORELOAD 7 -#define IMGMGR_NMGR_MAX_MSG 120 +#define IMGMGR_NMGR_MAX_MSG 400 #define IMGMGR_NMGR_MAX_NAME 64 #define IMGMGR_NMGR_MAX_VER 25 /* 255.255.65535.4294967295\0 */ diff --git a/libs/newtmgr/pkg.yml b/libs/newtmgr/pkg.yml index 6b8435d9..a0e75a23 100644 --- a/libs/newtmgr/pkg.yml +++ b/libs/newtmgr/pkg.yml @@ -32,5 +32,8 @@ pkg.deps: - libs/shell - sys/reboot +pkg.deps.BLE_HOST: + - libs/newtmgr/transport/ble + pkg.features: - - NEWTMGR + - NEWTMGR diff --git a/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h b/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h new file mode 100644 index 00000000..5bbd6773 --- /dev/null +++ b/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h @@ -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. + */ + +#ifndef _NEWTMGR_BLE_H_ +#define _NEWTMGR_BLE_H_ + +int +nmgr_ble_proc_mq_evt(struct os_event *ev); +void +nmgr_ble_gatt_svr_init(struct os_eventq *evq); + +#endif /* _NETMGR_H */ diff --git a/libs/newtmgr/transport/ble/pkg.yml b/libs/newtmgr/transport/ble/pkg.yml new file mode 100644 index 00000000..9ab9d4e5 --- /dev/null +++ b/libs/newtmgr/transport/ble/pkg.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. +# + +pkg.name: libs/newtmgr/transport/ble +pkg.description: BLE transport newtmgr functionality. +pkg.author: "Apache Mynewt <dev@mynewt.incubator.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + +pkg.deps: + - libs/os + - net/nimble diff --git a/libs/newtmgr/transport/ble/src/newtmgr_ble.c b/libs/newtmgr/transport/ble/src/newtmgr_ble.c new file mode 100644 index 00000000..37a0012d --- /dev/null +++ b/libs/newtmgr/transport/ble/src/newtmgr_ble.c @@ -0,0 +1,218 @@ +/** + * 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 "host/ble_hs.h" +#include <newtmgr/newtmgr.h> +#include <os/endian.h> + +#define BLE_ATT_MTU_MAX 240 + +/* nmgr ble mqueue */ +struct os_mqueue ble_nmgr_mq; + +/* ble nmgr transport */ +struct nmgr_transport ble_nt; + +/* ble nmgr attr handle */ +uint16_t g_ble_nmgr_attr_handle; + +/* ble nmgr response buffer */ +char ble_nmgr_resp_buf[BLE_ATT_MTU_MAX]; + +struct os_eventq *app_evq; +/** + * The vendor specific "newtmgr" service consists of one write no-rsp characteristic + * for newtmgr requests + * o "write no-rsp": a single-byte characteristic that can always be read, but + * can only be written over an encrypted connection. + */ + +/* 59462f12-9543-9999-12c8-58b459a27120 */ +const uint8_t gatt_svr_svc_newtmgr[16] = { + 0x20, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, + 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59 +}; + +/* 5c3a659e-897e-45e1-b016-007107c96d00 */ +const uint8_t gatt_svr_chr_newtmgr[16] = { + 0x00, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c +}; + +static int +gatt_svr_chr_access_newtmgr(uint16_t conn_handle, uint16_t attr_handle, + uint8_t op, union 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, + .uuid128 = (void *)gatt_svr_svc_newtmgr, + .characteristics = (struct ble_gatt_chr_def[]) { { + /* Characteristic: Write No Rsp */ + .uuid128 = (void *)gatt_svr_chr_newtmgr, + .access_cb = gatt_svr_chr_access_newtmgr, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + 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, + uint8_t op, union ble_gatt_access_ctxt *ctxt, + void *arg) +{ + int rc; + struct os_mbuf *m_req; + + switch (op) { + case BLE_GATT_ACCESS_OP_WRITE_CHR: + m_req = os_msys_get_pkthdr(ctxt->chr_access.len, sizeof(conn_handle)); + if (!m_req) { + goto err; + } + rc = os_mbuf_copyinto(m_req, OS_MBUF_PKTHDR(m_req)->omp_len, + ctxt->chr_access.data, ctxt->chr_access.len); + if (rc) { + goto err; + } + memcpy(OS_MBUF_USRHDR(m_req), &conn_handle, sizeof(conn_handle)); + + rc = nmgr_rx_req(&ble_nt, m_req); + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + + /* Unknown characteristic; the nimble stack should not have called this + * function. + */ + assert(0); +err: + return BLE_ATT_ERR_UNLIKELY; +} + +static void +gatt_svr_register_cb(uint8_t op, union ble_gatt_register_ctxt *ctxt, void *arg) +{ + + switch (op) { + case BLE_GATT_REGISTER_OP_DSC: + case BLE_GATT_REGISTER_OP_SVC: + break; + case BLE_GATT_REGISTER_OP_CHR: + /* Searching for the newtmgr characteristic */ + if (!memcmp(ctxt->chr_reg.chr->uuid128, gatt_svr_chr_newtmgr, 16)) { + g_ble_nmgr_attr_handle = ctxt->chr_reg.val_handle; + } + break; + + default: + assert(0); + break; + } +} + +int +nmgr_ble_proc_mq_evt(struct os_event *ev) +{ + struct os_mbuf *m_resp; + uint16_t conn_handle; + uint16_t max_pktlen; + int rc; + + rc = 0; + switch (ev->ev_type) { + + case OS_EVENT_T_MQUEUE_DATA: + if (ev->ev_arg != &ble_nmgr_mq) { + rc = -1; + goto done; + } + + while (1) { + m_resp = os_mqueue_get(&ble_nmgr_mq); + if (!m_resp) { + break; + } + memcpy(&conn_handle, OS_MBUF_USRHDR(m_resp), + sizeof(conn_handle)); + max_pktlen = min(OS_MBUF_PKTLEN(m_resp), sizeof(ble_nmgr_resp_buf)); + rc = os_mbuf_copydata(m_resp, 0, max_pktlen, ble_nmgr_resp_buf); + assert(rc == 0); + rc = os_mbuf_free_chain(m_resp); + assert(rc == 0); + ble_gattc_notify_custom(conn_handle, g_ble_nmgr_attr_handle, + ble_nmgr_resp_buf, max_pktlen); + } + break; + default: + rc = -1; + goto done; + } + +done: + return rc; +} + +static int +nmgr_ble_out(struct nmgr_transport *nt, struct os_mbuf *m) +{ + int rc; + + rc = os_mqueue_put(&ble_nmgr_mq, app_evq, m); + if (rc != 0) { + goto err; + } + + return (0); +err: + return (rc); +} + +void +nmgr_ble_gatt_svr_init(struct os_eventq *evq) +{ + int rc; + + assert(evq != NULL); + + rc = ble_gatts_register_svcs(gatt_svr_svcs, gatt_svr_register_cb, NULL); + assert(rc == 0); + + app_evq = evq; + + os_mqueue_init(&ble_nmgr_mq, &ble_nmgr_mq); + + nmgr_transport_init(&ble_nt, &nmgr_ble_out); + +} + diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml index f597f344..0edea58e 100644 --- a/net/nimble/host/pkg.yml +++ b/net/nimble/host/pkg.yml @@ -42,6 +42,9 @@ pkg.deps: pkg.req_apis: - console +pkg.features: + - BLE_HOST + # Satisfy capability dependencies for the self-contained test executable. pkg.deps.SELFTEST: libs/console/stub pkg.cflags.SELFTEST: diff --git a/sys/log/include/log/log.h b/sys/log/include/log/log.h index 3bd2c73c..f5772aab 100644 --- a/sys/log/include/log/log.h +++ b/sys/log/include/log/log.h @@ -157,6 +157,14 @@ struct log { STAILQ_ENTRY(log) l_next; }; +/* Newtmgr Log opcodes */ +#define LOGS_NMGR_OP_READ (0) +#define LOGS_NMGR_OP_CLEAR (1) +#define LOGS_NMGR_OP_APPEND (2) +#define LOGS_NMGR_OP_MODULE_LIST (3) +#define LOGS_NMGR_OP_LEVEL_LIST (4) +#define LOGS_NMGR_OP_LOGS_LIST (5) + /* Log system level functions (for all logs.) */ int log_init(void); struct log *log_list_get_next(struct log *); diff --git a/sys/log/src/log_nmgr.c b/sys/log/src/log_nmgr.c index dcb0f6ed..b1e90a0c 100644 --- a/sys/log/src/log_nmgr.c +++ b/sys/log/src/log_nmgr.c @@ -41,14 +41,6 @@ static int log_nmgr_logs_list(struct nmgr_jbuf *njb); static struct nmgr_group log_nmgr_group; -/* Newtmgr Log opcodes */ -#define LOGS_NMGR_OP_READ (0) -#define LOGS_NMGR_OP_CLEAR (1) -#define LOGS_NMGR_OP_APPEND (2) -#define LOGS_NMGR_OP_MODULE_LIST (3) -#define LOGS_NMGR_OP_LEVEL_LIST (4) -#define LOGS_NMGR_OP_LOGS_LIST (5) - /* ORDER MATTERS HERE. * Each element represents the command ID, referenced from newtmgr. */ |