From dab11d0f6ef0732f00b21c63e43ed49f1d892274 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 15 Apr 2022 23:40:14 +0100 Subject: [PATCH] Part of #113. MESH advertising broken by CONFIG_BT_CENTRAL=y Signed off by: Adam Fowler --- config/zephyr/receiver.conf | 14 +- herald-mesh-relay/CMakeLists.txt | 2 +- .../include/lb_service_handler.h | 25 --- herald-mesh-relay/prj.conf | 26 ++- herald-mesh-relay/src/herald_handler.cpp | 138 +++++++------- herald-mesh-relay/src/lb_service_handler.c | 134 ------------- herald-mesh-relay/src/main.cpp | 13 +- herald-mesh-relay/src/model_handler.c | 176 +++++++++--------- herald/include/herald/mesh/mesh.h | 59 ++++-- herald/include/herald/mesh/presence_server.h | 18 +- herald/src/mesh/presence_client.c | 6 + herald/src/mesh/presence_server.c | 20 +- 12 files changed, 272 insertions(+), 359 deletions(-) delete mode 100644 herald-mesh-relay/include/lb_service_handler.h delete mode 100644 herald-mesh-relay/src/lb_service_handler.c diff --git a/config/zephyr/receiver.conf b/config/zephyr/receiver.conf index b3f6acc..a474d5c 100644 --- a/config/zephyr/receiver.conf +++ b/config/zephyr/receiver.conf @@ -1,12 +1,13 @@ # Receiver (i.e. scanner, central) settings CONFIG_BT_CENTRAL=y +# ^^^ The above causes MESH advertising to fail if ANY connections are open (E.g. Herald beacon payload reading) -# GATT Client settings -CONFIG_BT_GATT_CLIENT=y -CONFIG_BT_GATT_DM=y +# # GATT Client settings +# CONFIG_BT_GATT_CLIENT=y +# CONFIG_BT_GATT_DM=y -# Scanning -CONFIG_BT_SCAN=y +# # Scanning +# CONFIG_BT_SCAN=y # Issue #50 to prevent stack overflow in CPU (was 8192, defaults to 2200 in Zephyr) CONFIG_BT_RX_STACK_SIZE=6144 @@ -14,3 +15,6 @@ CONFIG_BT_RX_STACK_SIZE=6144 # Since v2.1 Required for NUS Service alongside BT Scanning - too high in testing # CONFIG_BT_RX_STACK_SIZE=8192 + + +# TODO figure out what in this file causes MESH to fail immediately \ No newline at end of file diff --git a/herald-mesh-relay/CMakeLists.txt b/herald-mesh-relay/CMakeLists.txt index 68aa22a..a68e148 100644 --- a/herald-mesh-relay/CMakeLists.txt +++ b/herald-mesh-relay/CMakeLists.txt @@ -112,7 +112,7 @@ target_sources(app PRIVATE #${HERALD_SOURCES_MBEDTLS} ${HERALD_SOURCES_MESH} src/main.cpp - src/lb_service_handler.c + # src/lb_service_handler.c src/model_handler.c src/herald_handler.cpp ) diff --git a/herald-mesh-relay/include/lb_service_handler.h b/herald-mesh-relay/include/lb_service_handler.h deleted file mode 100644 index ebb5427..0000000 --- a/herald-mesh-relay/include/lb_service_handler.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -/** - * @file - * @brief LED Button service handler - */ - -#ifndef LB_SERVICE_HANDLER_H__ -#define LB_SERVICE_HANDLER_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -void lbs_handler_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LB_SERVICE_HANDLER_H__ */ diff --git a/herald-mesh-relay/prj.conf b/herald-mesh-relay/prj.conf index 7865ae9..a3117b0 100644 --- a/herald-mesh-relay/prj.conf +++ b/herald-mesh-relay/prj.conf @@ -110,7 +110,9 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_SETTINGS=y CONFIG_BT_EXT_ADV=y -CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 +# This defaults to 1! +CONFIG_BT_EXT_ADV_MAX_ADV_SET=5 +# CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 CONFIG_BT_MAX_CONN=3 # Disable unused Bluetooth features @@ -122,6 +124,10 @@ CONFIG_BT_CTLR_CHAN_SEL_2=n CONFIG_BT_CTLR_MIN_USED_CHAN=n CONFIG_BT_CTLR_PRIVACY=n +# Use the BLE 5.0 2M phy for more ADV_EXT throughput +# TODO verify it's actually being used +CONFIG_BT_CTLR_PHY_2M=y + # Bluetooth mesh configuration CONFIG_BT_MESH=y CONFIG_BT_MESH_RELAY=y @@ -129,15 +135,21 @@ CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_ADV_BUF_COUNT=13 CONFIG_BT_MESH_TX_SEG_MAX=10 CONFIG_BT_MESH_PB_GATT=y +# The following is needed to set mesh model and publishing config from a phone CONFIG_BT_MESH_GATT_PROXY=y + +# TODO replace the below with a Herald NFC provisioner instead CONFIG_BT_MESH_DK_PROV=y +# The following is separate from BT_EXT_ADV +CONFIG_BT_MESH_ADV_EXT=y + # Bluetooth mesh models CONFIG_BT_MESH_ONOFF_SRV=y # Enable the LBS service -CONFIG_BT_LBS=y -CONFIG_BT_LBS_POLL_BUTTON=y +CONFIG_BT_LBS=n +CONFIG_BT_LBS_POLL_BUTTON=n # CONFIG_USE_SEGGER_RTT=y CONFIG_RTT_CONSOLE=y @@ -154,4 +166,10 @@ CONFIG_BT_MESH_DEBUG_ACCESS=y CONFIG_BT_MESH_DEBUG_MODEL=y CONFIG_BT_MESH_DEBUG_TRANS=n CONFIG_BT_MESH_DEBUG_NET=n -CONFIG_BT_MESH_DEBUG_CRYPTO=n \ No newline at end of file +CONFIG_BT_MESH_DEBUG_CRYPTO=n + + +# For issues with advertising failing:- +# CONFIG_BT_DEBUG_HCI_DRIVER=y +# CONFIG_BT_DEBUG_HCI_CORE=y +CONFIG_BT_DEBUG_CONN=y diff --git a/herald-mesh-relay/src/herald_handler.cpp b/herald-mesh-relay/src/herald_handler.cpp index 460adb8..dd2507a 100644 --- a/herald-mesh-relay/src/herald_handler.cpp +++ b/herald-mesh-relay/src/herald_handler.cpp @@ -8,9 +8,9 @@ // #include "../../herald/herald.h" // This is convenient, but leads to large // binaries! #include "herald/ble/ble_sensor_configuration.h" -#include "herald/ble/zephyr/concrete_ble_receiver.h" -#include "herald/ble/zephyr/concrete_ble_transmitter.h" -#include "herald/ble/zephyr/nordic_uart/nordic_uart_sensor_delegate.h" +// #include "herald/ble/zephyr/concrete_ble_receiver.h" +// #include "herald/ble/zephyr/concrete_ble_transmitter.h" +// #include "herald/ble/zephyr/nordic_uart/nordic_uart_sensor_delegate.h" #include "herald/datatype/date.h" #include "herald/datatype/immediate_send_data.h" #include "herald/datatype/location.h" @@ -107,72 +107,72 @@ void herald_entry() { using namespace herald::payload::extended; // Create Herald sensor array - ZephyrContextProvider zcp; - Context ctx(zcp, zcp.getLoggingSink(), zcp.getBluetoothStateManager()); - // using CT = - // Context; - - // Disable receiver / scanning mode - we're just transmitting our value - BLESensorConfiguration config = ctx.getSensorConfiguration(); // copy ctor - config.scanningEnabled = true; // To see other nearby BLE devices - // config.advertisingEnabled = true; // default - ctx.setSensorConfiguration(config); - - ConcreteExtendedDataV1 extendedData; - extendedData.addSection(ExtendedDataSegmentCodesV1::TextPremises, - erinsStakehouse.name); - - // TODO get this from configuration of the MESH element (Nav beacon model) - payload::beacon::ConcreteBeaconPayloadDataSupplierV1 pds( - erinsStakehouse.country, erinsStakehouse.state, erinsStakehouse.code, - extendedData); - - // this is unusual, but required. Really we should log activity to serial BLE - // or similar - DummyDelegate appDelegate; - SensorDelegateSet sensorDelegates(appDelegate); - - ConcreteBLESensor ble(ctx, ctx.getBluetoothStateManager(), pds, - sensorDelegates); - SensorArray sa(ctx, pds, ble); - - // Start array (and thus start advertising) - sa.start(); - - int iter = 0; - // APP_DBG("got iter!"); - // k_sleep(K_SECONDS(2)); - Date last; - // APP_DBG("got last!"); - // k_sleep(K_SECONDS(2)); - int delay = 250; // KEEP THIS SMALL!!! This is how often we check to see if - // anything needs to happen over a connection. - - APP_DBG("Entering herald iteration loop"); - k_sleep(K_SECONDS(2)); - while (1) { - k_sleep(K_MSEC(delay)); - Date now; - if (iter > 40 /* && iter < 44 */) { // some delay to allow us to see - // advertising output - // You could only do first 3 iterations so we can see the older log - // messages without continually scrolling through log messages - APP_DBG("Calling Sensor Array iteration"); - // k_sleep(K_SECONDS(2)); - sa.iteration(now - last); - } - - if (0 == iter % (5000 / delay)) { - APP_DBG("herald thread still running. Iteration: %d", iter); - // runner.run(Date()); // Note: You may want to do this less or more - // regularly depending on your requirements - APP_ERR("Memory pages free in Data Arena: %d", - herald::datatype::Data::getArena().pagesFree()); - } - - last = now; - ++iter; - } +// ZephyrContextProvider zcp; +// Context ctx(zcp, zcp.getLoggingSink(), zcp.getBluetoothStateManager()); +// // using CT = +// // Context; + +// // Disable receiver / scanning mode - we're just transmitting our value +// BLESensorConfiguration config = ctx.getSensorConfiguration(); // copy ctor +// config.scanningEnabled = true; // To see other nearby BLE devices +// // config.advertisingEnabled = true; // default +// ctx.setSensorConfiguration(config); + +// ConcreteExtendedDataV1 extendedData; +// extendedData.addSection(ExtendedDataSegmentCodesV1::TextPremises, +// erinsStakehouse.name); + +// // TODO get this from configuration of the MESH element (Nav beacon model) +// payload::beacon::ConcreteBeaconPayloadDataSupplierV1 pds( +// erinsStakehouse.country, erinsStakehouse.state, erinsStakehouse.code, +// extendedData); + +// // this is unusual, but required. Really we should log activity to serial BLE +// // or similar +// DummyDelegate appDelegate; +// SensorDelegateSet sensorDelegates(appDelegate); + +// ConcreteBLESensor ble(ctx, ctx.getBluetoothStateManager(), pds, +// sensorDelegates); +// SensorArray sa(ctx, pds, ble); + +// // Start array (and thus start advertising) +// sa.start(); + +// int iter = 0; +// // APP_DBG("got iter!"); +// // k_sleep(K_SECONDS(2)); +// Date last; +// // APP_DBG("got last!"); +// // k_sleep(K_SECONDS(2)); +// int delay = 250; // KEEP THIS SMALL!!! This is how often we check to see if +// // anything needs to happen over a connection. + +// APP_DBG("Entering herald iteration loop"); +// k_sleep(K_SECONDS(2)); +// while (1) { +// k_sleep(K_MSEC(delay)); +// Date now; +// if (iter > 40 /* && iter < 44 */) { // some delay to allow us to see +// // advertising output +// // You could only do first 3 iterations so we can see the older log +// // messages without continually scrolling through log messages +// APP_DBG("Calling Sensor Array iteration"); +// // k_sleep(K_SECONDS(2)); +// sa.iteration(now - last); +// } + +// if (0 == iter % (5000 / delay)) { +// APP_DBG("herald thread still running. Iteration: %d", iter); +// // runner.run(Date()); // Note: You may want to do this less or more +// // regularly depending on your requirements +// APP_ERR("Memory pages free in Data Arena: %d", +// herald::datatype::Data::getArena().pagesFree()); +// } + +// last = now; +// ++iter; +// } } /** MARK: HERALD HANDLER PUBLIC HEADER METHODS **/ diff --git a/herald-mesh-relay/src/lb_service_handler.c b/herald-mesh-relay/src/lb_service_handler.c deleted file mode 100644 index c6d1074..0000000 --- a/herald-mesh-relay/src/lb_service_handler.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#if !DT_NODE_EXISTS(DT_ALIAS(sw0)) -#error "Unsupported board: sw0 devicetree alias is not defined" -#endif - -#if !DT_NODE_EXISTS(DT_ALIAS(led1)) -#error "Unsupported board: led1 devicetree alias is not defined" -#endif - -#define LBS_LED DK_LED2 -#define LBS_BUTTON DK_BTN1_MSK - -static const struct bt_data ad[] = { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, (sizeof(CONFIG_BT_DEVICE_NAME) - 1)), -}; - -static const struct bt_data sd[] = { - BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_LBS_VAL), -}; - -static bool ble_button_state; - -static void connected(struct bt_conn *conn, uint8_t err) -{ - if (err) { - printk("Connection failed (err %u)\n", err); - return; - } - - // TODO fire mesh message with presence observed - - printk("Connected\n"); -} - -static void disconnected(struct bt_conn *conn, uint8_t reason) -{ - printk("Disconnected (reason %u)\n", reason); - - // TODO fire mesh message with presence vanished -} - -static struct bt_conn_cb conn_callbacks = { - .connected = connected, - .disconnected = disconnected, -}; - -static void app_led_cb(bool led_state) -{ - dk_set_led(LBS_LED, led_state); -} - -static bool app_button_cb(void) -{ - return ble_button_state; -} - -static struct bt_lbs_cb lbs_callbacs = { - .led_cb = app_led_cb, - .button_cb = app_button_cb, -}; - -static void button_changed(uint32_t button_state, uint32_t has_changed) -{ - if (has_changed & LBS_BUTTON) { - uint32_t user_button_state = button_state & LBS_BUTTON; - - bt_lbs_send_button_state(user_button_state); - ble_button_state = user_button_state ? true : false; - } -} - -static void lbs_adv_start(void) -{ - int err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); - - if (err) { - printk("Advertising failed to start (err %d)\n", err); - return; - } - - printk("Advertising successfully started\n"); -} - -static void lbs_init(void) -{ - static struct button_handler button_handler = { - .cb = button_changed, - }; - - dk_button_handler_add(&button_handler); - bt_conn_cb_register(&conn_callbacks); - - int err = bt_lbs_init(&lbs_callbacs); - - if (err) { - printk("Failed to init LBS (err:%d)\n", err); - return; - } -} - -void lbs_handler_init(void) -{ - /** Initiate and add LBS to the device service list. */ - lbs_init(); - - /** Start separate advertiser instance. This will allow two simountanious GATT - * connections to the device, one for Mesh and one for the LBS. - */ - lbs_adv_start(); -} diff --git a/herald-mesh-relay/src/main.cpp b/herald-mesh-relay/src/main.cpp index ccf7edc..c524d07 100644 --- a/herald-mesh-relay/src/main.cpp +++ b/herald-mesh-relay/src/main.cpp @@ -4,11 +4,11 @@ */ #include "herald_handler.h" -#include "lb_service_handler.h" +// #include "lb_service_handler.h" #include "model_handler.h" #include -#include +#include // TODO replace this with a new herald mesh provisioning configuration rather than the dev kit one #include #include @@ -50,6 +50,9 @@ static void bt_ready(int err) { dk_leds_init(); dk_buttons_init(NULL); + // Note: The following model_handler_init will initialise Herald + // once the mesh beacon has been correctly provisioned. + // This is done via the init() callback of bt_mesh_model_cb. err = bt_mesh_init(bt_mesh_dk_prov_init(), model_handler_init()); if (err) { APP_DBG("Initializing mesh failed (err %d)", err); @@ -60,7 +63,7 @@ static void bt_ready(int err) { settings_load(); } - // To reset provisioning status + // To reset provisioning status -> You have to do a full Erase & Write // bt_mesh_prov_reset(); // prov.h - NOT accessible from an app // bt_mesh_reset(); @@ -70,7 +73,7 @@ static void bt_ready(int err) { APP_DBG("Mesh started"); - lbs_handler_init(); + // lbs_handler_init(); } void main(void) { @@ -103,7 +106,7 @@ void main(void) { // Start herald entry on a new thread in case of errors, or needing to do // something on the main thread - herald_initialise(); + // herald_initialise(); uint8_t dummyMac[6] = {0, 1, 2, 3, 4, 5}; diff --git a/herald-mesh-relay/src/model_handler.c b/herald-mesh-relay/src/model_handler.c index 43b10bf..c47bfc2 100644 --- a/herald-mesh-relay/src/model_handler.c +++ b/herald-mesh-relay/src/model_handler.c @@ -19,29 +19,29 @@ LOG_MODULE_REGISTER(meshmodel, CONFIG_APP_LOG_LEVEL); #error "Unsupported board: led0 devicetree alias is not defined" #endif -#define MESH_LED DK_LED1 +// #define MESH_LED DK_LED1 -static void led_set(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, - const struct bt_mesh_onoff_set *set, struct bt_mesh_onoff_status *rsp); +// static void led_set(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, +// const struct bt_mesh_onoff_set *set, struct bt_mesh_onoff_status *rsp); -static void led_get(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, - struct bt_mesh_onoff_status *rsp); +// static void led_get(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, +// struct bt_mesh_onoff_status *rsp); -static const struct bt_mesh_onoff_srv_handlers onoff_handlers = { - .set = led_set, - .get = led_get, -}; +// static const struct bt_mesh_onoff_srv_handlers onoff_handlers = { +// .set = led_set, +// .get = led_get, +// }; -struct led_ctx { - struct bt_mesh_onoff_srv server; - struct k_work_delayable work; - uint32_t remaining; - bool value; -}; +// struct led_ctx { +// struct bt_mesh_onoff_srv server; +// struct k_work_delayable work; +// uint32_t remaining; +// bool value; +// }; -static struct led_ctx led_ctx = { - .server = BT_MESH_ONOFF_SRV_INIT(&onoff_handlers), -}; +// static struct led_ctx led_ctx = { +// .server = BT_MESH_ONOFF_SRV_INIT(&onoff_handlers), +// }; // Define herald location services server handlers static int presence_updated(struct bt_mesh_herald_presence_server* srv, @@ -59,74 +59,74 @@ static int presence_updated(struct bt_mesh_herald_presence_server* srv, return 0; } -static void led_transition_start(void) -{ - /* As long as the transition is in progress, the onoff - * state is "on": - */ - dk_set_led(MESH_LED, true); - k_work_reschedule(&led_ctx.work, K_MSEC(led_ctx.remaining)); - led_ctx.remaining = 0; -} - -static void led_status(struct bt_mesh_onoff_status *status) -{ - status->remaining_time = - k_ticks_to_ms_ceil32(k_work_delayable_remaining_get(&led_ctx.work)) + - led_ctx.remaining; - status->target_on_off = led_ctx.value; - /* As long as the transition is in progress, the onoff state is "on": */ - status->present_on_off = led_ctx.value || status->remaining_time; -} - -static void led_set(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, - const struct bt_mesh_onoff_set *set, struct bt_mesh_onoff_status *rsp) -{ - if (set->on_off == led_ctx.value) { - goto respond; - } - - led_ctx.value = set->on_off; - if (!bt_mesh_model_transition_time(set->transition)) { - led_ctx.remaining = 0; - dk_set_led(MESH_LED, set->on_off); - goto respond; - } - - led_ctx.remaining = set->transition->time; - - if (set->transition->delay) { - k_work_reschedule(&led_ctx.work, K_MSEC(set->transition->delay)); - } else { - led_transition_start(); - } - -respond: - if (rsp) { - led_status(rsp); - } -} - -static void led_get(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, - struct bt_mesh_onoff_status *rsp) -{ - led_status(rsp); -} - -static void led_work(struct k_work *work) -{ - if (led_ctx.remaining) { - led_transition_start(); - } else { - dk_set_led(MESH_LED, led_ctx.value); - - /* Publish the new value at the end of the transition */ - struct bt_mesh_onoff_status status; - - led_status(&status); - bt_mesh_onoff_srv_pub(&led_ctx.server, NULL, &status); - } -} +// static void led_transition_start(void) +// { +// /* As long as the transition is in progress, the onoff +// * state is "on": +// */ +// dk_set_led(MESH_LED, true); +// k_work_reschedule(&led_ctx.work, K_MSEC(led_ctx.remaining)); +// led_ctx.remaining = 0; +// } + +// static void led_status(struct bt_mesh_onoff_status *status) +// { +// status->remaining_time = +// k_ticks_to_ms_ceil32(k_work_delayable_remaining_get(&led_ctx.work)) + +// led_ctx.remaining; +// status->target_on_off = led_ctx.value; +// /* As long as the transition is in progress, the onoff state is "on": */ +// status->present_on_off = led_ctx.value || status->remaining_time; +// } + +// static void led_set(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, +// const struct bt_mesh_onoff_set *set, struct bt_mesh_onoff_status *rsp) +// { +// if (set->on_off == led_ctx.value) { +// goto respond; +// } + +// led_ctx.value = set->on_off; +// if (!bt_mesh_model_transition_time(set->transition)) { +// led_ctx.remaining = 0; +// dk_set_led(MESH_LED, set->on_off); +// goto respond; +// } + +// led_ctx.remaining = set->transition->time; + +// if (set->transition->delay) { +// k_work_reschedule(&led_ctx.work, K_MSEC(set->transition->delay)); +// } else { +// led_transition_start(); +// } + +// respond: +// if (rsp) { +// led_status(rsp); +// } +// } + +// static void led_get(struct bt_mesh_onoff_srv *srv, struct bt_mesh_msg_ctx *ctx, +// struct bt_mesh_onoff_status *rsp) +// { +// led_status(rsp); +// } + +// static void led_work(struct k_work *work) +// { +// if (led_ctx.remaining) { +// led_transition_start(); +// } else { +// dk_set_led(MESH_LED, led_ctx.value); + +// /* Publish the new value at the end of the transition */ +// struct bt_mesh_onoff_status status; + +// led_status(&status); +// bt_mesh_onoff_srv_pub(&led_ctx.server, NULL, &status); +// } +// } /* Set up a repeating delayed work to blink the DK's LEDs when attention is * requested. @@ -178,7 +178,7 @@ static struct bt_mesh_elem elements[] = {BT_MESH_ELEM( 1, BT_MESH_MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_HEALTH_SRV(&health_server, &health_pub), - BT_MESH_MODEL_ONOFF_SRV(&led_ctx.server), + // BT_MESH_MODEL_ONOFF_SRV(&led_ctx.server), // TODO reconfigure this for beaconing, presence BT_MESH_MODEL_HERALD_PRESENCE_SERVER( &presence_server, &presence_pub)), @@ -193,7 +193,7 @@ static const struct bt_mesh_comp comp = { const struct bt_mesh_comp *model_handler_init(void) { k_work_init_delayable(&attention_blink_work, attention_blink); - k_work_init_delayable(&led_ctx.work, led_work); + // k_work_init_delayable(&led_ctx.work, led_work); return ∁ } diff --git a/herald/include/herald/mesh/mesh.h b/herald/include/herald/mesh/mesh.h index aadd24c..9c80de3 100644 --- a/herald/include/herald/mesh/mesh.h +++ b/herald/include/herald/mesh/mesh.h @@ -20,18 +20,25 @@ extern "C" { /// MARK: BEGIN LINUX FOUNDATION COMMON REUSABLE OP CODE SECTION -/** \brief Get a model's whole data **/ +// TODO Verify that having the same opp in multiple models in the same +// element is allowed. Some Zephyr documentation indicates it is not. + +/** \brief Get a server model's whole data **/ #define BT_MESH_LINUX_FOUNDATION_OP_GET BT_MESH_MODEL_OP_3(0x01, \ BT_MESH_LINUX_FOUNDATION_VENDOR_COMPANY_ID) -/** \brief Set a model's whole data **/ +/** \brief Set a server model's whole data **/ #define BT_MESH_LINUX_FOUNDATION_OP_SET BT_MESH_MODEL_OP_3(0x02, \ BT_MESH_LINUX_FOUNDATION_VENDOR_COMPANY_ID) -/** \brief Set a model's whole data without acknowledgement **/ +/** \brief Set a server model's whole data without acknowledgement **/ #define BT_MESH_LINUX_FOUNDATION_OP_SET_UNACK BT_MESH_MODEL_OP_3(0x03, \ BT_MESH_LINUX_FOUNDATION_VENDOR_COMPANY_ID) -/** \brief Get the status of a whole model Set operation **/ +/** + * \brief Publish the status of a whole server model + * \note Also used as the Ack message to the SET command. + **/ #define BT_MESH_LINUX_FOUNDATION_OP_STATUS BT_MESH_MODEL_OP_3(0x04, \ BT_MESH_LINUX_FOUNDATION_VENDOR_COMPANY_ID) +// TODO determine if the next line is just a duplicate of the STATUS line /** Send a message containing the full model **/ #define BT_MESH_LINUX_FOUNDATION_OP_MESSAGE BT_MESH_MODEL_OP_3(0x05, \ BT_MESH_LINUX_FOUNDATION_VENDOR_COMPANY_ID) @@ -46,37 +53,55 @@ extern "C" { /// MARK: BEGIN HERALD PROJECT SECTION /** - * @brief A Herald MESH Relay beacon can publish presence information of - * nearby BLE devices as messages to the mesh. This helps collate presence - * and density information (E.g. for COVID gathering safety monitoring). - */ + * @brief A Herald MESH Relay Beacon can also advertise location + * information to nearby Herald Venue Beacon Bluetooth LE clients. + * This includes ownership, section, area information. + * This is useful to maintain your own 'venue diary', which you + * may later choose to share. (E.g. with a disease contact tracing team) + * \note Allows the Herald Beacon to be programmed via MESH. + **/ -#define BT_MESH_HERALD_PRESENCE_CLI_VENDOR_MODEL_ID 0x2001 +#define BT_MESH_HERALD_VENUE_BEACON_VENDOR_MODEL_ID 0x2001 -/** \brief Presence message length - 6 byte Mac address, 1 int8_t Last RSSI, 1 uint8_t presence flag. Does not include mesh header sizes **/ -#define BT_MESH_HERALD_PRESENCE_MSG_LEN 8 +/** \brief Beacon message length. Country (2), State(2), Venue (4), BeaconID + * (2), url(0-2048) **/ +#define BT_MESH_HERALD_VENUE_BEACON_MSG_MINLEN_SET 10 +#define BT_MESH_HERALD_VENUE_BEACON_MSG_MAXLEN_SET 2058 +// TODO verify that MESH itself and Zephyr and the nRF Mesh app don't crash with such a potentially big message +// TODO consider \x16 (https) as the first character in the above // Note we re-use the generic get,set,status op codes from the Linux Foundation + + + + + + + /** - * @brief A Herald MESH Relay Beacon can also advertise location - * information to nearby Herald Venue Beacon Bluetooth LE clients. - * This includes ownership, section, area information. - * This is useful to maintain your own 'venue diary', which you - * may later choose to share. (E.g. with a disease contact tracing team) + * @brief A Herald MESH Relay beacon can publish presence information of + * nearby BLE devices as messages to the mesh. This helps collate presence + * and density information (E.g. for COVID gathering safety monitoring). */ -/** Location Services / Herald Venue Beacon interlink **/ +/** \brief The model ID for Herald presence server information **/ #define BT_MESH_HERALD_PRESENCE_SERVER_VENDOR_MODEL_ID 0x2002 // Note we re-use the generic get,set,status op codes from the Linux Foundation // Now set the minimum/maximum lengths for various operations // Fetch status length #define BT_MESH_HERALD_PRESENCE_MSG_LEN_GET 0 + + // Set status message min/max length #define BT_MESH_HERALD_PRESENCE_MSG_MINLEN_SET 3 #define BT_MESH_HERALD_PRESENCE_MSG_MAXLEN_SET 5 // Get status (model) response / published message length +/** + * \brief Presence message length - 6 byte Mac address, 1 int8_t Last RSSI, 1 + * uint8_t presence flag. Does not include mesh header sizes. + **/ #define BT_MESH_HERALD_PRESENCE_MSG_MINLEN_STATUS 2 // just mesh overhead #define BT_MESH_HERALD_PRESENCE_MSG_MAXLEN_STATUS 11 // 8 bytes message + operation overhead (2) + tail (1) diff --git a/herald/include/herald/mesh/presence_server.h b/herald/include/herald/mesh/presence_server.h index 7a1a0f0..d27c223 100644 --- a/herald/include/herald/mesh/presence_server.h +++ b/herald/include/herald/mesh/presence_server.h @@ -41,17 +41,17 @@ struct bt_mesh_herald_presence_server { /** Publication message. */ struct net_buf_simple pub_msg; /** Publication message buffer. */ - uint8_t buf[BT_MESH_MODEL_BUF_LEN(BT_MESH_LINUX_FOUNDATION_OP_SET, - BT_MESH_HERALD_PRESENCE_MSG_LEN)]; - const struct bt_mesh_herald_presence_server_cb *cb; + uint8_t buf[BT_MESH_MODEL_BUF_LEN( + BT_MESH_LINUX_FOUNDATION_OP_SET, + BT_MESH_HERALD_PRESENCE_MSG_MAXLEN_STATUS)]; + const struct bt_mesh_herald_presence_server_cb* cb; }; - - -#define BT_MESH_MODEL_HERALD_PRESENCE_SERVER(srv, _pub) \ - BT_MESH_MODEL_CB(BT_MESH_HERALD_PRESENCE_SERVER_VENDOR_MODEL_ID, \ - bt_mesh_herald_presence_server_op, _pub, srv, &bt_mesh_herald_presence_server_cb) - +#define BT_MESH_MODEL_HERALD_PRESENCE_SERVER(srv, _pub) \ + BT_MESH_MODEL_VND_CB(BT_MESH_LINUX_FOUNDATION_VENDOR_COMPANY_ID, \ + BT_MESH_HERALD_PRESENCE_SERVER_VENDOR_MODEL_ID, \ + bt_mesh_herald_presence_server_op, _pub, srv, \ + &bt_mesh_herald_presence_server_cb) /** @cond INTERNAL_HIDDEN */ extern const struct bt_mesh_model_op bt_mesh_herald_presence_server_op[]; diff --git a/herald/src/mesh/presence_client.c b/herald/src/mesh/presence_client.c index 48bc8a8..72d3b17 100644 --- a/herald/src/mesh/presence_client.c +++ b/herald/src/mesh/presence_client.c @@ -16,6 +16,12 @@ #include LOG_MODULE_DECLARE(presence); +/** + * @file Herald Presence MESH Model Client. Used by the Modem to communicate + * with the Herald Presence Servers (herald-mesh-relay app instances) + */ + + // BUILD_ASSERT(BT_MESH_MODEL_BUF_LEN(BT_MESH_HERALD_PRESENCE_CLI_OP_MESSAGE, // BT_MESH_HERALD_PRESENCE_CLI_MSG_MAXLEN_MESSAGE) <= // BT_MESH_RX_SDU_MAX, diff --git a/herald/src/mesh/presence_server.c b/herald/src/mesh/presence_server.c index c2eb484..deaadc4 100644 --- a/herald/src/mesh/presence_server.c +++ b/herald/src/mesh/presence_server.c @@ -10,6 +10,12 @@ #include "herald/mesh/presence.h" #include "herald/mesh/presence_server.h" +/** + * @file Herald Presence MESH Model Server. Used by Herald Presence + * Servers (herald-mesh-relay app instances) to provide a Herald + * Presence reporting function via MESH message publishing. + */ + /* Location Services Server context of the primary element */ struct bt_mesh_herald_presence_server *herald_presence_server; @@ -88,8 +94,15 @@ const struct bt_mesh_model_op bt_mesh_herald_presence_server_op[] = { BT_MESH_MODEL_OP_END, }; +static int herald_presence_server_start(struct bt_mesh_model *model) +{ + BT_DBG("herald_presence_server_start called"); + return 0; +} + static int herald_presence_server_init(struct bt_mesh_model *model) { + BT_DBG("herald_presence_server_init called"); struct bt_mesh_herald_presence_server *srv = (struct bt_mesh_herald_presence_server*)model->user_data; @@ -118,12 +131,15 @@ static int herald_presence_server_init(struct bt_mesh_model *model) const struct bt_mesh_model_cb bt_mesh_herald_presence_server_cb = { .init = herald_presence_server_init, + .start = herald_presence_server_start, }; -// MARK: Server side API for Herald to/from MESH Gateway to call. +/** + * MARK: Server side API for a Herald Presence Server app to call. + **/ int bt_mesh_herald_presence_share(uint8_t *macOfSix, int8_t rssi, enum bt_mesh_model_herald_presence_status status) { // Ensure our server handle has been initialised @@ -137,7 +153,7 @@ int bt_mesh_herald_presence_share(uint8_t *macOfSix, int8_t rssi, enum bt_mesh_m // Ensure we've been bound to a publishing destination by our provisioner if (mdl->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - BT_DBG("Does not have publication address"); + BT_ERR("Does not have publication address"); return -2; }