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 6baf3fa61aa8e836ffe017035c488a4bba059429 Author: Christopher Collins <ccoll...@apache.org> AuthorDate: Wed Jan 17 17:18:13 2018 -0800 Sample app - smp_svr --- samples/smp_svr/README.md | 64 +++++++ samples/smp_svr/mynewt/pkg.yml | 43 +++++ samples/smp_svr/mynewt/src/main.c | 320 ++++++++++++++++++++++++++++++++++ samples/smp_svr/mynewt/syscfg.yml | 39 +++++ samples/smp_svr/zephyr/CMakeLists.txt | 42 +++++ samples/smp_svr/zephyr/README.rst | 41 +++++ samples/smp_svr/zephyr/dts.overlay | 13 ++ samples/smp_svr/zephyr/prj.conf | 30 ++++ samples/smp_svr/zephyr/src/main.c | 108 ++++++++++++ 9 files changed, 700 insertions(+) diff --git a/samples/smp_svr/README.md b/samples/smp_svr/README.md new file mode 100644 index 0000000..cb9d3e7 --- /dev/null +++ b/samples/smp_svr/README.md @@ -0,0 +1,64 @@ +# smp_svr + +This sample application implements a simple SMP server with the following +transports: + * Shell + * Bluetooth + +`smp_svr` enables support for the following command groups: + * fs_mgmt + * img_mgmt + * os_mgmt + +## Mynewt + +The Mynewt port of `smp_svr` is a regular Mynewt app. The below example uses the nRF52dk as the BSP, so you may need to adjust accordingly if you are using different hardware. + +0. Create a Mynewt project and upload the Apache mynewt boot loader to your +board as described here: http://mynewt.apache.org/latest/os/tutorials/nRF52/ + +1. Add the mcumgr repo to your `project.yml` file: + +``` +repository.mynewt-mcumgr: + type: git + vers: 0-latest + url: 'g...@github.com:apache/mynewt-mcumgr.git' +``` + +2. Create a target that ties the `smp_svr` app to your BSP of choice (nRF52dk in this example): + +``` +$ newt target create smp_svr-nrf52dk +$ newt target set smp_svr-nrf52dk app=@mynewt-mcumgr/samples/smp_svr/apache \ + bsp=@apache-mynewt-core/hw/bsp/nrf52dk \ + build_profile=debug +``` + +3. Build, upload, and run the application on your board: + +``` +$ newt run smp_svr-nrf52dk +``` + +## Zephyr + +The Zephyr port of `smp_svr` is configured to run on an nRF52 MCU. The +application should build and run for other platforms without modification, but +the file system management commands will not work. To enable file system +management for a different platform, adjust the `CONFIG_FS_NFFS_FLASH_DEV_NAME` +setting in `prj.conf` accordingly. + +In addition, the MCUBoot boot loader (https://github.com/runtimeco/mcuboot) is +required for img_mgmt to function properly. + +### Building + +The Zephyr port of `smp_svr` can be built using the usual procedure: + +``` +$ cd samples/smp_svr/zephyr +$ mkdir build && cd build +$ cmake -DBOARD=<board> .. +$ make +``` diff --git a/samples/smp_svr/mynewt/pkg.yml b/samples/smp_svr/mynewt/pkg.yml new file mode 100644 index 0000000..83d38d5 --- /dev/null +++ b/samples/smp_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 <d...@mynewt.apache.org>" +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' + - '@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/mgmt' + - '@mynewt-mcumgr/smp' diff --git a/samples/smp_svr/mynewt/src/main.c b/samples/smp_svr/mynewt/src/main.c new file mode 100755 index 0000000..19d5f91 --- /dev/null +++ b/samples/smp_svr/mynewt/src/main.c @@ -0,0 +1,320 @@ +/* + * 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 <stdio.h> +#include <errno.h> +#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" + +/* BLE */ +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "services/gap/ble_svc_gap.h" + +/* smp_svr uses the first "peruser" log module. */ +#define SMP_SVR_LOG_MODULE (LOG_MODULE_PERUSER + 0) + +/* Convenience macro for logging to the smp_svr module. */ +#define SMP_SVR_LOG(lvl, ...) \ + LOG_ ## lvl(&smp_svr_log, SMP_SVR_LOG_MODULE, __VA_ARGS__) + +/** Log data. */ +struct log smp_svr_log; + +static int smp_svr_gap_event(struct ble_gap_event *event, void *arg); + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + SMP_SVR_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} + +/** + * Logs information about a connection to the console. + */ +static void +smp_svr_print_conn_desc(struct ble_gap_conn_desc *desc) +{ + SMP_SVR_LOG(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); + SMP_SVR_LOG(INFO, " our_id_addr_type=%d our_id_addr=", + desc->our_id_addr.type); + print_addr(desc->our_id_addr.val); + SMP_SVR_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr.type); + print_addr(desc->peer_ota_addr.val); + SMP_SVR_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr.type); + print_addr(desc->peer_id_addr.val); + SMP_SVR_LOG(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 +smp_svr_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + const char *name; + int rc; + + /** + * 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) { + SMP_SVR_LOG(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(BLE_OWN_ADDR_PUBLIC, 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); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that forms. + * smp_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 + * smp_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 +smp_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. */ + SMP_SVR_LOG(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); + 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"); + + if (event->connect.status != 0) { + /* Connection failed; resume advertising. */ + smp_svr_advertise(); + } + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + SMP_SVR_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason); + 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; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + SMP_SVR_LOG(INFO, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + smp_svr_print_conn_desc(&desc); + SMP_SVR_LOG(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_ADV_COMPLETE: + SMP_SVR_LOG(INFO, "advertise complete; reason=%d", + event->adv_complete.reason); + smp_svr_advertise(); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + SMP_SVR_LOG(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + smp_svr_print_conn_desc(&desc); + SMP_SVR_LOG(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_MTU: + SMP_SVR_LOG(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 +smp_svr_on_reset(int reason) +{ + SMP_SVR_LOG(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +smp_svr_on_sync(void) +{ + /* Begin advertising. */ + smp_svr_advertise(); +} + +/** + * main + * + * The main task for the project. This function initializes the packages, + * then starts serving events from default event queue. + * + * @return int NOTE: this function should never return! + */ +int +main(void) +{ + int rc; + + /* Initialize OS */ + sysinit(); + + /* Initialize the smp_svr log. */ + log_register("smp_svr", &smp_svr_log, &log_console_handler, NULL, + 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; + 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("smp_svr"); + assert(rc == 0); + + conf_load(); + + /* + * As the last thing, process events from default event queue. + */ + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + return 0; +} diff --git a/samples/smp_svr/mynewt/syscfg.yml b/samples/smp_svr/mynewt/syscfg.yml new file mode 100644 index 0000000..99b4dc4 --- /dev/null +++ b/samples/smp_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/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 + + # 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 diff --git a/samples/smp_svr/zephyr/CMakeLists.txt b/samples/smp_svr/zephyr/CMakeLists.txt new file mode 100644 index 0000000..30a4ebd --- /dev/null +++ b/samples/smp_svr/zephyr/CMakeLists.txt @@ -0,0 +1,42 @@ +# Top-level CMakeLists.txt for the skeleton application. +# +# Copyright (c) 2017 Open Source Foundries Limited +# +# SPDX-License-Identifier: Apache-2.0 +# +# This provides a basic application structure suitable for communication using +# mcumgr. It can be used as a starting point for new applications. + +# The default top-level application configuration is prj.conf. You can place +# additional board-specific files in boards/${BOARD}.conf, and they will be +# merged into the configuration along with prj.conf. +macro(set_conf_file) + if(EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf) + set(CONF_FILE "prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf") + else() + set(CONF_FILE "prj.conf") + endif() +endmacro() + +# Zephyr uses Device Tree (DT) to describe some board hardware configuration. +# +# See the Zephyr documentation for more information on DT: +# http://docs.zephyrproject.org/devices/dts/device_tree.html +set(DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dts.overlay") + +# Standard Zephyr application boilerplate. +include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) +project(NONE) + +assert_exists(DTC_OVERLAY_FILE) + +# This string ends up getting printed in the device console +if (NOT DEFINED FROM_WHO) + set(FROM_WHO Zephyr) +endif() + +target_sources(app PRIVATE + src/main.c +) + +zephyr_link_libraries(MCUMGR NFFS) diff --git a/samples/smp_svr/zephyr/README.rst b/samples/smp_svr/zephyr/README.rst new file mode 100644 index 0000000..00218b0 --- /dev/null +++ b/samples/smp_svr/zephyr/README.rst @@ -0,0 +1,41 @@ +.. _hello_world: + +Hello World +########### + +Overview +******** +A simple Hello World example that can be used with any supported board and +prints 'Hello World' to the console. This application can be built into modes: + +* single thread +* multi threading + +Building and Running +******************** + +This project outputs 'Hello World' to the console. It can be built and executed +on QEMU as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: qemu_x86 + :goals: run + :compact: + +To build the single thread version, use the supplied configuration file for +single thread: :file:`prj_single.conf`: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: qemu_x86 + :conf: prj_single.conf + :goals: run + :compact: + +Sample Output +============= + +.. code-block:: console + + Hello World! x86 diff --git a/samples/smp_svr/zephyr/dts.overlay b/samples/smp_svr/zephyr/dts.overlay new file mode 100644 index 0000000..5a3a7f3 --- /dev/null +++ b/samples/smp_svr/zephyr/dts.overlay @@ -0,0 +1,13 @@ +/* + * Basic Device Tree overlay file. + */ + +/ { + chosen { + /* Required by mcuboot. */ + zephyr,code-partition = &slot0_partition; + + /* Use uart0 for the mcumgr UART transport. */ + zephyr,uart-mcumgr = &uart0; + }; +}; diff --git a/samples/smp_svr/zephyr/prj.conf b/samples/smp_svr/zephyr/prj.conf new file mode 100644 index 0000000..50e8ff1 --- /dev/null +++ b/samples/smp_svr/zephyr/prj.conf @@ -0,0 +1,30 @@ +# Required by file management command handlers. +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_NFFS=y +CONFIG_FS_NFFS_FLASH_DEV_NAME="NRF5_FLASH" + +# Required by tinycbor (math.h). +CONFIG_NEWLIB_LIBC=y + +# Some command handlers require a large stack. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# Allow room for the mcuboot image header. +CONFIG_TEXT_SECTION_OFFSET=0x200 + +# Increase the number of transmit buffers to avoid the Bluetooth stack buffer +# leak. +CONFIG_BT_L2CAP_TX_BUF_COUNT=8 + +# Allow for large Bluetooth data packets. +CONFIG_BT_L2CAP_TX_MTU=260 +CONFIG_BT_RX_BUF_LEN=260 + +# Enable the Bluetooth and shell mcumgr transports. +CONFIG_MCUMGR_SMP_BT=y +CONFIG_MCUMGR_SMP_SHELL=y + +# Enable all core commands. +CONFIG_MCUMGR_CMD_FS_MGMT=y +CONFIG_MCUMGR_CMD_IMG_MGMT=y +CONFIG_MCUMGR_CMD_OS_MGMT=y diff --git a/samples/smp_svr/zephyr/src/main.c b/samples/smp_svr/zephyr/src/main.c new file mode 100644 index 0000000..757725f --- /dev/null +++ b/samples/smp_svr/zephyr/src/main.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <assert.h> +#include <zephyr.h> +#include <string.h> +#include <stdlib.h> +#include <bluetooth/bluetooth.h> +#include <bluetooth/conn.h> +#include <bluetooth/gatt.h> +#include "fs_mgmt/fs_mgmt.h" +#include "os_mgmt/os_mgmt.h" +#include "img_mgmt/img_mgmt.h" +#include "mgmt/smp_bt.h" +#include "mgmt/buf.h" + +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) + +static const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID128_ALL, + 0x84, 0xaa, 0x60, 0x74, 0x52, 0x8a, 0x8b, 0x86, + 0xd3, 0x4c, 0xb7, 0x1d, 0x1d, 0xdc, 0x53, 0x8d), +}; + +static const struct bt_data sd[] = { + BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +}; + +static void advertise(void) +{ + int rc; + + bt_le_adv_stop(); + + rc = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), + sd, ARRAY_SIZE(sd)); + if (rc) { + printk("Advertising failed to start (rc %d)\n", rc); + return; + } + + printk("Advertising successfully started\n"); +} + +static void connected(struct bt_conn *conn, u8_t err) +{ + if (err) { + printk("Connection failed (err %u)\n", err); + } else { + printk("Connected\n"); + } +} + +static void disconnected(struct bt_conn *conn, u8_t reason) +{ + printk("Disconnected (reason %u)\n", reason); + advertise(); +} + +static struct bt_conn_cb conn_callbacks = { + .connected = connected, + .disconnected = disconnected, +}; + +static void bt_ready(int err) +{ + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + advertise(); +} + +void main(void) +{ + int rc; + + /* Register the built-in mcumgr command handlers. */ + os_mgmt_register_group(); + img_mgmt_register_group(); + fs_mgmt_register_group(); + + /* Enable Bluetooth. */ + rc = bt_enable(bt_ready); + if (rc != 0) { + printk("Bluetooth init failed (err %d)\n", rc); + return; + } + bt_conn_cb_register(&conn_callbacks); + + /* Initialize the Bluetooth mcumgr transport. */ + smp_bt_register(); + + /* The system work queue handles all incoming mcumgr requests. Let the + * main thread idle while the mcumgr server runs. + */ + while (1) { + k_sleep(INT32_MAX); + } +} -- To stop receiving notification emails like this one, please contact "commits@mynewt.apache.org" <commits@mynewt.apache.org>.