You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2021/11/09 16:21:54 UTC

[GitHub] [mynewt-nimble] michal-narajowski commented on a change in pull request #1062: Mesh sync

michal-narajowski commented on a change in pull request #1062:
URL: https://github.com/apache/mynewt-nimble/pull/1062#discussion_r745774930



##########
File path: nimble/host/mesh/src/access.c
##########
@@ -431,32 +484,75 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
 {
 	uint16_t index;
 
+	if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
+		return NULL;
+	}
+
+	index = addr - dev_comp->elem[0].addr;
+	if (index >= dev_comp->elem_count) {
+		return NULL;
+	}
+
+	return &dev_comp->elem[index];
+}
+
+bool bt_mesh_has_addr(uint16_t addr)
+{
+	uint16_t index;
+
 	if (BT_MESH_ADDR_IS_UNICAST(addr)) {
-		index = (addr - dev_comp->elem[0].addr);
-		if (index < dev_comp->elem_count) {
-			return &dev_comp->elem[index];
-		} else {
-			return NULL;
-		}
+		return bt_mesh_elem_find(addr) != NULL;
+	}
+
+	if (MYNEWT_VAL(BLE_MESH_ACCESS_LAYER_MSG) && msg_cb) {
+		return true;
 	}
 
 	for (index = 0; index < dev_comp->elem_count; index++) {
 		struct bt_mesh_elem *elem = &dev_comp->elem[index];
 
 		if (bt_mesh_elem_find_group(elem, addr)) {
-			return elem;
+			return true;
 		}
 	}
 
-	return NULL;
+	return false;
+}
+
+#if MYNEWT_VAL(BLE_MESH_ACCESS_LAYER_MSG)
+void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx,
+			struct os_mbuf *buf))
+{
+	msg_cb = cb;

Review comment:
       Indentation.

##########
File path: nimble/host/mesh/syscfg.yml
##########
@@ -879,3 +975,8 @@ syscfg.vals.BLE_MESH_PB_GATT:
 
 syscfg.vals.BLE_MESH_PB_ADV:
     BLE_MESH_PROV: 1
+
+syscfg.vals.'BLE_MESH_PB_GATT':
+    BLE_MESH_PROXY_MSG_LEN: 66
+syscfg.vals.'BLE_MESH_GATT_PROXY':
+    BLE_MESH_PROXY_MSG_LEN: 33

Review comment:
       Newline.

##########
File path: nimble/host/mesh/src/app_keys.c
##########
@@ -498,10 +629,89 @@ uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid,
 void bt_mesh_app_keys_reset(void)
 {
 	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
-		struct bt_mesh_app_key *app = &apps[i];
+		struct app_key *app = &apps[i];
 
 		if (app->app_idx != BT_MESH_KEY_UNUSED) {
 			app_key_del(app);
 		}
 	}
 }
+
+#if MYNEWT_VAL(BLE_MESH_SETTINGS)
+static int app_key_set(int argc, char **argv, char *val)
+{
+	struct app_key_val key;
+	uint16_t app_idx;
+	int len_rd, err;
+
+	BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)");
+
+	app_idx = strtol(argv[0], NULL, 16);
+	len_rd = strtol(argv[1], NULL, 16);
+
+
+	if (!len_rd) {
+		return 0;
+	}
+
+	err = settings_bytes_from_str(val, &key, &len_rd);
+	if (err) {
+		BT_ERR("Failed to decode value %s (err %d)", val, err);
+		return err;
+	}
+
+	err = bt_mesh_app_key_set(app_idx, key.net_idx, key.val[0],
+				  key.updated ? key.val[1] : NULL);
+	if (err) {
+		BT_ERR("Failed to set \'app-key\'");
+		return err;
+	}
+
+	BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx);
+
+	return 0;
+}
+#endif
+
+void bt_mesh_app_key_pending_store(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(app_key_updates); i++) {
+		struct app_key_update *update = &app_key_updates[i];
+
+		if (!update->valid) {
+			continue;
+		}
+
+		if (update->clear) {
+			clear_app_key(update->key_idx);
+		} else {
+			store_app_key(update->key_idx);
+		}
+
+		update->valid = 0U;
+	}
+}
+
+#if MYNEWT_VAL(BLE_MESH_SETTINGS)
+static struct conf_handler bt_mesh_app_key_conf_handler = {
+	.ch_name = "bt_mesh",
+	.ch_get = NULL,
+	.ch_set = app_key_set,
+	.ch_commit = NULL,
+	.ch_export = NULL,
+};
+#endif
+
+void bt_mesh_app_key_init(void)
+{
+#if MYNEWT_VAL(BLE_MESH_SETTINGS)
+	int rc;
+
+	rc = conf_register(&bt_mesh_app_key_conf_handler);
+
+	SYSINIT_PANIC_ASSERT_MSG(rc == 0,
+				 "Failed to register bt_mesh_app_key conf");
+#endif
+}

Review comment:
       Newline.

##########
File path: nimble/host/mesh/src/pb_gatt.c
##########
@@ -155,4 +171,5 @@ const struct prov_bearer pb_gatt = {
 	.link_accept = link_accept,
 	.send = buf_send,
 	.clear_tx = clear_tx,
-};
\ No newline at end of file
+};
+#endif

Review comment:
       Newline.

##########
File path: nimble/host/mesh/src/pb_gatt_srv.h
##########
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ * Copyright (c) 2021 Lingao Meng
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __PB_GATT_SRV_H__
+#define __PB_GATT_SRV_H__
+
+int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf);
+
+int bt_mesh_pb_gatt_enable(void);
+int bt_mesh_pb_gatt_disable(void);
+
+int prov_ccc_write(uint16_t conn_handle, uint8_t type);
+void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t err);
+void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err);
+void resolve_svc_handles(void);
+
+int bt_mesh_pb_gatt_adv_start(void);
+
+extern struct svc_handles {
+	uint16_t proxy_h;
+	uint16_t proxy_data_out_h;
+	uint16_t prov_h;
+	uint16_t prov_data_in_h;
+	uint16_t prov_data_out_h;
+} svc_handles;
+
+#endif /* __PB_GATT_SRV_H__ */

Review comment:
       Newline.

##########
File path: nimble/host/mesh/src/access.c
##########
@@ -171,67 +194,68 @@ static int publish_retransmit(struct bt_mesh_model *mod)
 	net_buf_simple_init(sdu, 0);
 	net_buf_simple_add_mem(sdu, pub->msg->om_data, pub->msg->om_len);
 
-	pub->count--;
-
 	err = bt_mesh_trans_send(&tx, sdu, &pub_sent_cb, mod);
 
 	os_mbuf_free_chain(sdu);
 	return err;
 }
 
-static void publish_retransmit_end(int err, struct bt_mesh_model_pub *pub)
+static int pub_period_start(struct bt_mesh_model_pub *pub)
 {
-	/* Cancel all retransmits for this publish attempt */
-	pub->count = 0U;
-	/* Make sure the publish timer gets reset */
-	publish_sent(err, pub->mod);
+	int err;
+
+	pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit);
+
+	if (!pub->update) {
+		return 0;
+	}
+
+	err = pub->update(pub->mod);
+	if (err) {
+		/* Skip this publish attempt. */
+		BT_DBG("Update failed, skipping publish (err: %d)", err);
+		pub->count = 0;
+		pub->period_start = k_uptime_get_32();
+		publish_sent(err, pub->mod);
+		return err;
+	}
+
+	return 0;
 }
 
 static void mod_publish(struct ble_npl_event *work)
 {
 	struct bt_mesh_model_pub *pub = ble_npl_event_get_arg(work);
-	int32_t period_ms;
 	int err;
 
-	BT_DBG("");
+	if (pub->addr == BT_MESH_ADDR_UNASSIGNED ||
+	atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {

Review comment:
       Indetntation?

##########
File path: nimble/host/mesh/src/transport.h
##########
@@ -102,12 +95,12 @@ void bt_mesh_trans_init(void);
 
 void bt_mesh_trans_reset(void);
 
-struct bt_mesh_va *bt_mesh_va_get(uint16_t index);
-
-struct bt_mesh_va *bt_mesh_va_find(uint8_t uuid[16]);
-
 uint8_t bt_mesh_va_add(const uint8_t uuid[16], uint16_t *addr);
 
 uint8_t bt_mesh_va_del(const uint8_t uuid[16], uint16_t *addr);
 
-uint8_t *bt_mesh_va_label_get(uint16_t addr);
\ No newline at end of file
+uint8_t *bt_mesh_va_label_get(uint16_t addr);
+
+void bt_mesh_va_pending_store(void);
+
+void bt_mesh_va_init(void);

Review comment:
       Newline.

##########
File path: nimble/host/mesh/src/pb_gatt_srv.c
##########
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ * Copyright (c) 2021 Lingao Meng
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define MESH_LOG_MODULE BLE_MESH_PROV_LOG
+
+#include "mesh_priv.h"
+#include "adv.h"
+#include "net.h"
+#include "rpl.h"
+#include "transport.h"
+#include "prov.h"
+#include "beacon.h"
+#include "foundation.h"
+#include "access.h"
+#include "proxy.h"
+#include "proxy_msg.h"
+#include "pb_gatt_srv.h"
+#include "syscfg/syscfg.h"
+#include "services/gatt/ble_svc_gatt.h"
+#include "../../host/src/ble_hs_priv.h"
+
+#if defined(CONFIG_BT_MESH_PB_GATT_USE_DEVICE_NAME)
+#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME
+#else
+#define ADV_OPT_USE_NAME 0
+#endif
+
+#define ADV_OPT_PROV                                                           \
+.conn_mode = (BLE_GAP_CONN_MODE_UND),                                  \
+.disc_mode = (BLE_GAP_DISC_MODE_GEN),
+
+#if MYNEWT_VAL(BLE_MESH_PB_GATT)
+/** @def BT_UUID_MESH_PROV
+ *  @brief Mesh Provisioning Service
+ */
+ble_uuid16_t BT_UUID_MESH_PROV                 = BLE_UUID16_INIT(0x1827);
+#define BT_UUID_MESH_PROV_VAL             0x1827
+/** @def BT_UUID_MESH_PROXY
+ *  @brief Mesh Proxy Service
+ */
+ble_uuid16_t BT_UUID_MESH_PROXY                = BLE_UUID16_INIT(0x1828);
+#define BT_UUID_MESH_PROXY_VAL            0x1828
+/** @def BT_UUID_GATT_CCC
+ *  @brief GATT Client Characteristic Configuration
+ */
+ble_uuid16_t BT_UUID_GATT_CCC                  = BLE_UUID16_INIT(0x2902);
+#define BT_UUID_GATT_CCC_VAL              0x2902
+/** @def BT_UUID_MESH_PROV_DATA_IN
+ *  @brief Mesh Provisioning Data In
+ */
+ble_uuid16_t BT_UUID_MESH_PROV_DATA_IN         = BLE_UUID16_INIT(0x2adb);
+#define BT_UUID_MESH_PROV_DATA_IN_VAL     0x2adb
+/** @def BT_UUID_MESH_PROV_DATA_OUT
+ *  @brief Mesh Provisioning Data Out
+ */
+ble_uuid16_t BT_UUID_MESH_PROV_DATA_OUT        = BLE_UUID16_INIT(0x2adc);
+#define BT_UUID_MESH_PROV_DATA_OUT_VAL    0x2adc
+/** @def BT_UUID_MESH_PROXY_DATA_IN
+ *  @brief Mesh Proxy Data In
+ */
+ble_uuid16_t BT_UUID_MESH_PROXY_DATA_IN        = BLE_UUID16_INIT(0x2add);
+#define BT_UUID_MESH_PROXY_DATA_IN_VAL    0x2add
+/** @def BT_UUID_MESH_PROXY_DATA_OUT
+ *  @brief Mesh Proxy Data Out
+ */
+ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT       = BLE_UUID16_INIT(0x2ade);
+#define BT_UUID_MESH_PROXY_DATA_OUT_VAL   0x2ade
+#define BT_UUID_16_ENCODE(w16)  \
+	(((w16) >>  0) & 0xFF), \
+	(((w16) >>  8) & 0xFF)
+
+static bool prov_fast_adv;
+
+struct svc_handles svc_handles;
+static atomic_t pending_notifications;
+
+static int gatt_send(uint16_t conn_handle,
+		     const void *data, uint16_t len);
+
+static struct bt_mesh_proxy_role *cli;
+
+static void proxy_msg_recv(struct bt_mesh_proxy_role *role)
+{
+	switch (role->msg_type) {
+	case BT_MESH_PROXY_PROV:
+		BT_DBG("Mesh Provisioning PDU");
+		bt_mesh_pb_gatt_recv(role->conn_handle, role->buf);
+		break;
+	default:
+		BT_WARN("Unhandled Message Type 0x%02x", role->msg_type);
+		break;
+	}
+}
+
+static bool service_registered;
+
+static int gatt_recv_proxy(uint16_t conn_handle, uint16_t attr_handle,
+			 struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+	const uint8_t *data = ctxt->om->om_data;
+	uint16_t len = ctxt->om->om_len;
+	struct bt_mesh_proxy_client *client = find_client(conn_handle);
+
+	if (len < 1) {
+		BT_WARN("Too small Proxy PDU");
+		return -EINVAL;
+	}
+
+	if (PDU_TYPE(data) == BT_MESH_PROXY_PROV) {
+		BT_WARN("Proxy PDU type doesn't match GATT service");
+		return -EINVAL;
+	}
+
+	return bt_mesh_proxy_msg_recv(client->cli, data, len);
+}
+
+static int gatt_recv_prov(uint16_t conn_handle, uint16_t attr_handle,
+		     struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+	const uint8_t *data = ctxt->om->om_data;
+	uint16_t len = ctxt->om->om_len;
+
+	if (conn_handle != cli->conn_handle) {
+		BT_WARN("conn_handle != cli->conn_handle");
+		return -ENOTCONN;
+	}
+
+	if (len < 1) {
+		BT_WARN("Too small Proxy PDU");
+		return -EINVAL;
+	}
+
+	if (PDU_TYPE(data) != BT_MESH_PROXY_PROV) {
+		BT_WARN("Proxy PDU type doesn't match GATT service");
+		return -EINVAL;
+	}
+
+	return bt_mesh_proxy_msg_recv(cli, data, len);
+}
+
+void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err)
+{
+	struct ble_gap_conn_desc info;
+	struct ble_hs_conn *conn;
+
+	conn = ble_hs_conn_find(conn_handle);
+	bt_conn_get_info(conn, &info);
+	if (info.role != BLE_GAP_ROLE_SLAVE ||
+	    !service_registered || bt_mesh_is_provisioned()) {
+		return;
+	}
+
+	cli = bt_mesh_proxy_role_setup(conn_handle, gatt_send, proxy_msg_recv);
+
+	BT_DBG("conn %p err 0x%02x", (void *)conn, err);
+}
+
+void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason)
+{
+	struct ble_gap_conn_desc info;
+
+	struct ble_hs_conn *conn;
+
+	conn = ble_hs_conn_find(conn_handle);
+	bt_conn_get_info(conn, &info);
+	if (info.role != BLE_GAP_ROLE_SLAVE ||
+	    !service_registered) {
+		return;
+	}
+
+	if (cli) {
+		bt_mesh_proxy_role_cleanup(cli);
+		cli = NULL;
+	}
+
+	BT_DBG("conn %p reason 0x%02x", (void *)conn, reason);
+
+	bt_mesh_pb_gatt_close(conn_handle);
+
+	if (bt_mesh_is_provisioned()) {
+		(void)bt_mesh_pb_gatt_disable();
+	}
+}
+
+int prov_ccc_write(uint16_t conn_handle, uint8_t type)
+{
+	if (cli->conn_handle != conn_handle) {
+		BT_ERR("No PB-GATT Client found");
+		return -ENOTCONN;
+	}
+
+	if (type != BLE_GAP_EVENT_SUBSCRIBE) {
+		BT_WARN("Client wrote instead enabling notify");
+		return BT_GATT_ERR(EINVAL);
+	}
+
+	bt_mesh_pb_gatt_open(conn_handle);
+
+	return 0;
+}
+
+/* Mesh Provisioning Service Declaration */
+
+static int
+dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle,
+		struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+	/*
+	 * We should never never enter this callback - it's attached to notify-only
+	 * characteristic which are notified directly from mbuf. And we can't pass
+	 * NULL as access_cb because gatts will assert on init...
+	 */
+	BLE_HS_DBG_ASSERT(0);
+	return 0;
+}
+
+static const struct ble_gatt_svc_def svc_defs [] = {
+	{
+		.type = BLE_GATT_SVC_TYPE_PRIMARY,
+		.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL),
+		.characteristics = (struct ble_gatt_chr_def[]) { {
+				.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL),
+				.access_cb = gatt_recv_proxy,
+				.flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
+			}, {
+				.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL),
+				.access_cb = dummy_access_cb,
+				.flags = BLE_GATT_CHR_F_NOTIFY,
+			}, {
+			0, /* No more characteristics in this service. */
+		} },
+	}, {
+		.type = BLE_GATT_SVC_TYPE_PRIMARY,
+		.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
+		.characteristics = (struct ble_gatt_chr_def[]) { {
+				.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL),
+				.access_cb = gatt_recv_prov,
+				.flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
+			}, {
+				.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL),
+				.access_cb = dummy_access_cb,
+				.flags = BLE_GATT_CHR_F_NOTIFY,
+			}, {
+				0, /* No more characteristics in this service. */
+		} },
+	}, {
+		0, /* No more services. */
+	},
+};
+
+void resolve_svc_handles(void)
+{
+	int rc;
+
+	/* Either all handles are already resolved, or none of them */
+	if (svc_handles.prov_data_out_h) {
+		return;
+	}
+
+	/*
+	 * We assert if attribute is not found since at this stage all attributes
+	 * shall be already registered and thus shall be found.
+	 */
+
+	rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL),
+				&svc_handles.proxy_h);
+	assert(rc == 0);
+
+	rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL),
+				BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL),
+				NULL, &svc_handles.proxy_data_out_h);
+	assert(rc == 0);
+
+	rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
+				&svc_handles.prov_h);
+	assert(rc == 0);
+
+	rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
+				BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL),
+				NULL, &svc_handles.prov_data_in_h);
+	assert(rc == 0);
+
+	rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
+				BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL),
+				NULL, &svc_handles.prov_data_out_h);
+	assert(rc == 0);
+}
+
+
+int bt_mesh_proxy_svcs_register(void)
+{
+	int rc;
+
+	rc = ble_gatts_count_cfg(svc_defs);
+	assert(rc == 0);
+
+	rc = ble_gatts_add_svcs(svc_defs);
+	assert(rc == 0);
+
+	return 0;
+}
+
+int bt_mesh_pb_gatt_enable(void)
+{
+	int rc;
+	uint16_t handle;
+	BT_DBG("");
+
+	if (bt_mesh_is_provisioned()) {
+		return -ENOTSUP;
+	}
+
+	if (service_registered) {
+		return -EBUSY;
+	}
+
+	rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle);
+	assert(rc == 0);
+	ble_gatts_svc_set_visibility(handle, 1);
+	/* FIXME: figure out end handle */
+	ble_svc_gatt_changed(svc_handles.prov_h, 0xffff);
+
+	service_registered = true;
+	prov_fast_adv = true;
+
+	return 0;
+}
+
+int bt_mesh_pb_gatt_disable(void)
+{
+	uint16_t handle;
+	int rc;
+
+	BT_DBG("");
+
+	if (!service_registered) {
+		return -EALREADY;
+	}
+
+	rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle);
+	assert(rc == 0);
+	ble_gatts_svc_set_visibility(handle, 0);
+	/* FIXME: figure out end handle */
+	ble_svc_gatt_changed(svc_handles.prov_h, 0xffff);
+	service_registered = false;
+
+	bt_mesh_adv_update();
+
+	return 0;
+}
+
+static uint8_t prov_svc_data[20] = {
+	BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL),
+};
+
+static const struct bt_data prov_ad[] = {
+	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
+	BT_DATA_BYTES(BT_DATA_UUID16_ALL,
+		      BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL)),
+		      BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)),
+};
+
+int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf)
+{
+	if (!cli || cli->conn_handle != conn_handle) {
+		BT_ERR("No PB-GATT Client found");
+		return -ENOTCONN;
+	}
+
+	return bt_mesh_proxy_msg_send(cli, BT_MESH_PROXY_PROV, buf);
+}
+
+static size_t gatt_prov_adv_create(struct bt_data prov_sd[1])
+{
+	const struct bt_mesh_prov *prov = bt_mesh_prov_get();
+	size_t uri_len;
+
+	memcpy(prov_svc_data + 2, prov->uuid, 16);
+	sys_put_be16(prov->oob_info, prov_svc_data + 18);
+
+	if (!prov->uri) {
+		return 0;
+	}
+
+	uri_len = strlen(prov->uri);
+	if (uri_len > 29) {
+		/* There's no way to shorten an URI */
+		BT_WARN("Too long URI to fit advertising packet");
+		return 0;
+	}
+
+	prov_sd[0].type = BT_DATA_URI;
+	prov_sd[0].data_len = uri_len;
+	prov_sd[0].data = (const uint8_t *)prov->uri;
+
+	return 1;
+}
+
+static int gatt_send(uint16_t conn_handle,
+	const void *data, uint16_t len)
+{
+	struct os_mbuf *om;
+	int err = 0;
+
+	BT_DBG("%u bytes: %s", len, bt_hex(data, len));
+	om = ble_hs_mbuf_from_flat(data, len);
+	assert(om);
+	err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om);
+	notify_complete();
+
+	if (!err) {
+		atomic_inc(&pending_notifications);
+	}
+
+	return err;
+}
+
+int bt_mesh_pb_gatt_adv_start(void)
+{
+	BT_DBG("");
+
+	if (!service_registered || bt_mesh_is_provisioned()) {
+		return -ENOTSUP;
+	}
+
+	struct ble_gap_adv_params fast_adv_param = {
+		ADV_OPT_PROV
+		ADV_FAST_INT
+	};
+#if ADV_OPT_USE_NAME
+	const char *name = CONFIG_BT_DEVICE_NAME;
+	size_t name_len = strlen(name);
+	struct bt_data prov_sd = {
+		.type = BT_DATA_NAME_COMPLETE,
+		.data_len = name_len,
+		.data = (void *)name
+	};
+#else
+	struct bt_data *prov_sd = NULL;
+#endif
+
+	size_t prov_sd_len;
+	int err;
+
+	prov_sd_len = gatt_prov_adv_create(prov_sd);
+
+	if (!prov_fast_adv) {
+		struct ble_gap_adv_params slow_adv_param = {
+			ADV_OPT_PROV
+			ADV_SLOW_INT
+		};
+
+		return bt_mesh_adv_start(&slow_adv_param, K_FOREVER, prov_ad,
+					 ARRAY_SIZE(prov_ad), prov_sd, prov_sd_len);
+	}
+
+	/* Advertise 60 seconds using fast interval */
+	err = bt_mesh_adv_start(&fast_adv_param, (60 * MSEC_PER_SEC),
+				prov_ad, ARRAY_SIZE(prov_ad),
+				prov_sd, prov_sd_len);
+	if (!err) {
+		prov_fast_adv = false;
+	}
+
+	return err;
+}
+#endif

Review comment:
       Newline.

##########
File path: nimble/host/mesh/src/msg.c
##########
@@ -0,0 +1,84 @@
+/*  Bluetooth Mesh */
+
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "mesh/mesh.h"
+
+void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode)
+{
+	net_buf_simple_init(msg, 0);
+
+	switch (BT_MESH_MODEL_OP_LEN(opcode)) {
+	case 1:
+		net_buf_simple_add_u8(msg, opcode);
+		break;
+	case 2:
+		net_buf_simple_add_be16(msg, opcode);
+		break;
+	case 3:
+		net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff));
+		/* Using LE for the CID since the model layer is defined as
+		 * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
+		 * will declare the opcode in this way.
+		 */
+		net_buf_simple_add_le16(msg, opcode & 0xffff);
+		break;
+	default:
+		BT_WARN("Unknown opcode format");
+		break;
+	}
+}
+
+void bt_mesh_msg_ack_ctx_clear(struct bt_mesh_msg_ack_ctx *ack)
+{
+	ack->op = 0U;
+	ack->user_data = NULL;
+	ack->dst = BT_MESH_ADDR_UNASSIGNED;
+}
+
+int bt_mesh_msg_ack_ctx_prepare(struct bt_mesh_msg_ack_ctx *ack,
+	uint32_t op, uint16_t dst, void *user_data)
+{
+	if (ack->op) {
+		BT_WARN("Another synchronous operation pending");
+		return -EBUSY;
+	}
+
+	ack->op = op;
+	ack->user_data = user_data;
+	ack->dst = dst;
+
+	return 0;
+}
+
+int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, int32_t timeout)
+{
+	int err;
+
+	err = k_sem_take(&ack->sem, timeout);
+	bt_mesh_msg_ack_ctx_clear(ack);
+
+	if (err == -EAGAIN) {
+		return -ETIMEDOUT;
+	}
+
+	return err;
+}
+
+bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack,
+	uint32_t op, uint16_t addr, void **user_data)
+{
+	if (ack->op != op || (BT_MESH_ADDR_IS_UNICAST(ack->dst) && ack->dst != addr)) {
+		return false;
+	}
+
+	if (user_data != NULL) {
+		*user_data = ack->user_data;
+	}
+
+	return true;
+}

Review comment:
       Newline.

##########
File path: nimble/host/mesh/include/mesh/health_cli.h
##########
@@ -29,9 +29,7 @@ struct bt_mesh_health_cli {
 			       uint8_t test_id, uint16_t cid, uint8_t *faults,
 			       size_t fault_count);
 
-	struct k_sem          op_sync;
-	uint32_t                 op_pending;
-	void                 *op_param;
+	struct bt_mesh_msg_ack_ctx ack_ctx;

Review comment:
       Indentation.

##########
File path: nimble/host/mesh/src/adv_legacy.c
##########
@@ -0,0 +1,245 @@
+/*  Bluetooth Mesh */
+
+/*
+ * Copyright (c) 2018 Nordic Semiconductor ASA
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define MESH_LOG_MODULE BLE_MESH_ADV_LOG
+
+#include "adv.h"
+#include "net.h"
+#include "foundation.h"
+#include "beacon.h"
+#include "prov.h"
+#include "proxy.h"
+#include "mesh/glue.h"
+#include "pb_gatt_srv.h"
+
+#if MYNEWT_VAL(BLE_MESH_ADV_LEGACY)
+/* Convert from ms to 0.625ms units */
+#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
+
+#if (MYNEWT_VAL(BSP_NRF51) && !MYNEWT_VAL(BLE_CONTROLLER))
+#define CONFIG_BT_CTLR_LOW_LAT 1
+#else
+#define CONFIG_BT_CTLR_LOW_LAT 0
+#endif
+
+/* Pre-5.0 controllers enforce a minimum interval of 100ms
+ * whereas 5.0+ controllers can go down to 20ms.
+ */
+#define ADV_INT_DEFAULT_MS 100
+#define ADV_INT_FAST_MS    20
+
+static int32_t adv_int_min =  ADV_INT_DEFAULT_MS;
+
+static int adv_initialized = false;
+/* TinyCrypt PRNG consumes a lot of stack space, so we need to have
+ * an increased call stack whenever it's used.
+ */
+#if MYNEWT
+OS_TASK_STACK_DEFINE(g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE));
+struct os_task adv_task;
+#endif
+
+static int32_t adv_timeout;
+
+static inline void adv_send(struct os_mbuf *buf)
+{
+	static const uint8_t adv_type[] = {
+			[BT_MESH_ADV_PROV]   = BLE_HS_ADV_TYPE_MESH_PROV,
+			[BT_MESH_ADV_DATA]   = BLE_HS_ADV_TYPE_MESH_MESSAGE,
+			[BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON,
+			[BT_MESH_ADV_URI]    = BLE_HS_ADV_TYPE_URI,
+	};
+
+	struct ble_gap_adv_params param = { 0 };
+	uint16_t duration, adv_int;
+	struct bt_data ad;
+	int err;
+
+	adv_int = max(adv_int_min,
+		      BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit));
+#if MYNEWT_VAL(BLE_CONTROLLER)
+	duration = ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) *
+				(adv_int + 10));
+#else
+	/* Zephyr Bluetooth Low Energy Controller for mesh stack uses
+	 * pre-emptible continuous scanning, allowing advertising events to be
+	 * transmitted without delay when advertising is enabled. No need to
+	 * compensate with scan window duration.
+	 * An advertising event could be delayed by upto one interval when
+	 * advertising is stopped and started in quick succession, hence add
+	 * advertising interval to the total advertising duration.
+	 */
+	duration = (adv_int +
+		    ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) *
+		     (adv_int + 10)));
+
+	/* Zephyr Bluetooth Low Energy Controller built for nRF51x SoCs use
+	 * CONFIG_BT_CTLR_LOW_LAT=y, and continuous scanning cannot be
+	 * pre-empted, hence, scanning will block advertising events from
+	 * being transmitted. Increase the advertising duration by the
+	 * amount of scan window duration to compensate for the blocked
+	 * advertising events.
+	 */
+	if (CONFIG_BT_CTLR_LOW_LAT) {
+		duration += BT_MESH_SCAN_WINDOW_MS;
+	}
+#endif
+
+	BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type,
+	       buf->om_len, bt_hex(buf->om_data, buf->om_len));
+	BT_DBG("count %u interval %ums duration %ums",
+	       BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int,
+	       duration);
+
+	ad.type = adv_type[BT_MESH_ADV(buf)->type];
+	ad.data_len = buf->om_len;
+	ad.data = buf->om_data;
+
+	param.itvl_min = ADV_SCAN_UNIT(adv_int);
+	param.itvl_max = param.itvl_min;
+	param.conn_mode = BLE_GAP_CONN_MODE_NON;
+
+	int64_t time = k_uptime_get();
+
+	err = bt_le_adv_start(&param, duration, &ad, 1, NULL, 0);
+
+
+	bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf));
+	if (err) {
+		BT_ERR("Advertising failed: err %d", err);
+		return;
+	}
+
+	BT_DBG("Advertising started. Sleeping %u ms", duration);
+
+	k_sleep(K_MSEC(duration));
+
+	err = bt_le_adv_stop();
+	if (err) {
+		BT_ERR("Stopping advertising failed: err %d", err);
+		return;
+	}
+
+	BT_DBG("Advertising stopped (%u ms)", (uint32_t) k_uptime_delta(&time));
+}
+
+void
+mesh_adv_thread(void *args)
+{
+	static struct ble_npl_event *ev;
+	struct os_mbuf *buf;
+
+	BT_DBG("started");
+
+	while (1) {
+		if (MYNEWT_VAL(BLE_MESH_GATT_SERVER)) {
+			ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0);
+			while (!ev) {
+				/* Adv timeout may be set by a call from proxy
+				 * to bt_mesh_adv_start:
+				 */
+				adv_timeout = K_FOREVER;
+				if (bt_mesh_is_provisioned()) {
+					if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
+						bt_mesh_proxy_adv_start();
+						BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout);
+					}
+				} else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
+					bt_mesh_pb_gatt_adv_start();
+					BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout);
+				}
+
+				ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout);
+				bt_le_adv_stop();
+			}
+		} else {
+			ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER);
+		}
+		if (!ev || !ble_npl_event_get_arg(ev)) {
+			continue;
+		}
+
+		buf = ble_npl_event_get_arg(ev);
+
+		/* busy == 0 means this was canceled */
+		if (BT_MESH_ADV(buf)->busy) {
+			BT_MESH_ADV(buf)->busy = 0;
+			adv_send(buf);
+		}
+
+		net_buf_unref(buf);
+
+		/* os_sched(NULL); */
+	}
+}
+
+void bt_mesh_adv_update(void)
+{
+	static struct ble_npl_event ev = { };
+
+	BT_DBG("");
+
+	ble_npl_eventq_put(&bt_mesh_adv_queue, &ev);
+}
+
+void bt_mesh_adv_buf_ready(void)
+{
+	/* Will be handled automatically */
+}
+
+void bt_mesh_adv_init(void)
+{
+	int rc;
+
+	/* Advertising should only be initialized once. Calling
+	 * os_task init the second time will result in an assert. */
+	if (adv_initialized) {
+		return;
+	}
+
+	rc = os_mempool_init(&adv_buf_mempool, MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT),
+			     BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE,
+			     adv_buf_mem, "adv_buf_pool");
+	assert(rc == 0);
+
+	rc = os_mbuf_pool_init(&adv_os_mbuf_pool, &adv_buf_mempool,
+			       BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE,
+			       MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT));
+	assert(rc == 0);
+
+	ble_npl_eventq_init(&bt_mesh_adv_queue);
+
+#if MYNEWT
+	os_task_init(&adv_task, "mesh_adv", mesh_adv_thread, NULL,
+	             MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER,
+	             g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE));
+#endif
+
+	/* For BT5 controllers we can have fast advertising interval */
+	if (ble_hs_hci_get_hci_version() >= BLE_HCI_VER_BCS_5_0) {
+	    adv_int_min = ADV_INT_FAST_MS;
+	}
+
+	adv_initialized = true;
+}
+
+int bt_mesh_adv_enable(void)
+{
+	/* Dummy function - in legacy adv thread is started on init*/
+	return 0;
+}
+
+int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration,
+		      const struct bt_data *ad, size_t ad_len,
+		      const struct bt_data *sd, size_t sd_len)
+{
+	adv_timeout = duration;
+	return bt_le_adv_start(param, duration, ad, ad_len, sd, sd_len);
+}
+#endif

Review comment:
       Newline.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org