linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ v3 0/2] mesh: Move HCI handling to mesh-io-generic
@ 2019-06-24  7:32 Michał Lowas-Rzechonek
  2019-06-24  7:32 ` [PATCH BlueZ v3 1/2] " Michał Lowas-Rzechonek
  2019-06-24  7:32 ` [PATCH BlueZ v3 2/2] mesh: Added --io option Michał Lowas-Rzechonek
  0 siblings, 2 replies; 5+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-06-24  7:32 UTC (permalink / raw)
  To: linux-bluetooth

This version of the patchset addresses Brian's comments.
Thanks for the review!

First patch has a few style/convention corrections.

Second patch now introduces --io option, but leaves --index working as
it used to.

Michał Lowas-Rzechonek (2):
  mesh: Move HCI handling to mesh-io-generic
  mesh: Added --io option

 Makefile.mesh          |   1 +
 mesh/main.c            |  96 +++++++++++++++----
 mesh/mesh-io-api.h     |   3 +-
 mesh/mesh-io-generic.c |  63 ++++++++-----
 mesh/mesh-io.c         |  15 ++-
 mesh/mesh-io.h         |   2 +-
 mesh/mesh-mgmt.c       | 204 +++++++++++++++++++++++++++++++++++++++++
 mesh/mesh-mgmt.h       |  23 +++++
 mesh/mesh.c            | 189 +++-----------------------------------
 mesh/mesh.h            |   4 +-
 10 files changed, 370 insertions(+), 230 deletions(-)
 create mode 100644 mesh/mesh-mgmt.c
 create mode 100644 mesh/mesh-mgmt.h

-- 
2.19.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH BlueZ v3 1/2] mesh: Move HCI handling to mesh-io-generic
  2019-06-24  7:32 [PATCH BlueZ v3 0/2] mesh: Move HCI handling to mesh-io-generic Michał Lowas-Rzechonek
@ 2019-06-24  7:32 ` Michał Lowas-Rzechonek
  2019-06-24 16:47   ` Gix, Brian
  2019-06-24  7:32 ` [PATCH BlueZ v3 2/2] mesh: Added --io option Michał Lowas-Rzechonek
  1 sibling, 1 reply; 5+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-06-24  7:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland, Brian Gix

This patch separates 'mesh' module from 'mesh_io', particularly
regarding configuration and initialization.

Main code is no longer aware of MGMT and HCI usage - querying available
HCI interfaces now happens in mesh-io-generic.

MGMT code is now extracted into mesh-mgmt module, which mesh-io-generic
uses to query interfaces.
---
 Makefile.mesh          |   1 +
 mesh/main.c            |   4 +-
 mesh/mesh-io-api.h     |   3 +-
 mesh/mesh-io-generic.c |  63 ++++++++-----
 mesh/mesh-io.c         |  15 ++-
 mesh/mesh-io.h         |   2 +-
 mesh/mesh-mgmt.c       | 204 +++++++++++++++++++++++++++++++++++++++++
 mesh/mesh-mgmt.h       |  23 +++++
 mesh/mesh.c            | 189 +++-----------------------------------
 mesh/mesh.h            |   4 +-
 10 files changed, 294 insertions(+), 214 deletions(-)
 create mode 100644 mesh/mesh-mgmt.c
 create mode 100644 mesh/mesh-mgmt.h

diff --git a/Makefile.mesh b/Makefile.mesh
index b1f14e477..1ace507af 100644
--- a/Makefile.mesh
+++ b/Makefile.mesh
@@ -12,6 +12,7 @@ endif
 mesh_sources = mesh/mesh.h mesh/mesh.c \
 				mesh/net-keys.h mesh/net-keys.c \
 				mesh/mesh-io.h mesh/mesh-io.c \
+				mesh/mesh-mgmt.c mesh/mesh-mgmt.h \
 				mesh/error.h mesh/mesh-io-api.h \
 				mesh/mesh-io-generic.h \
 				mesh/mesh-io-generic.c \
diff --git a/mesh/main.c b/mesh/main.c
index 3cecd8fbf..262e3da48 100644
--- a/mesh/main.c
+++ b/mesh/main.c
@@ -35,6 +35,7 @@
 
 #include "mesh/mesh.h"
 #include "mesh/dbus.h"
+#include "mesh/mesh-io.h"
 
 static const struct option main_options[] = {
 	{ "index",	required_argument,	NULL, 'i' },
@@ -166,7 +167,8 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	if (!mesh_init(index, config_dir)) {
+
+	if (!mesh_init(config_dir, MESH_IO_TYPE_GENERIC, &index)) {
 		l_error("Failed to initialize mesh");
 		status = EXIT_FAILURE;
 		goto done;
diff --git a/mesh/mesh-io-api.h b/mesh/mesh-io-api.h
index acf12445d..4cdf1f80a 100644
--- a/mesh/mesh-io-api.h
+++ b/mesh/mesh-io-api.h
@@ -19,7 +19,7 @@
 
 struct mesh_io_private;
 
-typedef bool (*mesh_io_init_t)(uint16_t index, struct mesh_io *io);
+typedef bool (*mesh_io_init_t)(struct mesh_io *io, void *opts);
 typedef bool (*mesh_io_destroy_t)(struct mesh_io *io);
 typedef bool (*mesh_io_caps_t)(struct mesh_io *io, struct mesh_io_caps *caps);
 typedef bool (*mesh_io_send_t)(struct mesh_io *io,
@@ -47,7 +47,6 @@ struct mesh_io_api {
 
 struct mesh_io {
 	enum mesh_io_type		type;
-	uint16_t			index;
 	const struct mesh_io_api	*api;
 	struct mesh_io_private		*pvt;
 };
diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c
index 756dceabc..42aaa0947 100644
--- a/mesh/mesh-io-generic.c
+++ b/mesh/mesh-io-generic.c
@@ -26,7 +26,10 @@
 
 #include "monitor/bt.h"
 #include "src/shared/hci.h"
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
 
+#include "mesh/mesh-mgmt.h"
 #include "mesh/mesh-io.h"
 #include "mesh/mesh-io-api.h"
 #include "mesh/mesh-io-generic.h"
@@ -278,40 +281,52 @@ static void configure_hci(struct mesh_io_private *io)
 				sizeof(cmd), hci_generic_callback, NULL, NULL);
 }
 
-static bool dev_init(uint16_t index, struct mesh_io *io)
+static bool hci_init(struct mesh_io *io)
 {
-	struct mesh_io_private *tmp;
-
-	if (!io || io->pvt)
+	io->pvt->hci = bt_hci_new_user_channel(io->pvt->index);
+	if (!io->pvt->hci) {
+		l_error("Failed to start mesh io (hci %u)", io->pvt->index);
 		return false;
+	}
 
-	tmp = l_new(struct mesh_io_private, 1);
+	configure_hci(io->pvt);
 
-	if (tmp == NULL)
-		return false;
+	bt_hci_register(io->pvt->hci, BT_HCI_EVT_LE_META_EVENT,
+						event_callback, io, NULL);
+
+	l_debug("Started mesh on hci %u", io->pvt->index);
+	return true;
+}
+
+static void read_info(int index, void *user_data)
+{
+	struct mesh_io *io = user_data;
 
-	tmp->rx_regs = l_queue_new();
-	tmp->tx_pkts = l_queue_new();
-	if (!tmp->rx_regs || !tmp->tx_pkts)
-		goto fail;
+	if (io->pvt->index != MGMT_INDEX_NONE &&
+					index != io->pvt->index) {
+		l_debug("Ignore index %d", index);
+		return;
+	}
 
-	tmp->hci = bt_hci_new_user_channel(index);
-	if (!tmp->hci)
-		goto fail;
+	io->pvt->index = index;
+	hci_init(io);
+}
 
-	configure_hci(tmp);
+static bool dev_init(struct mesh_io *io, void *opts)
+{
+	if (!io || io->pvt)
+		return false;
 
-	bt_hci_register(tmp->hci, BT_HCI_EVT_LE_META_EVENT,
-						event_callback, io, NULL);
+	io->pvt = l_new(struct mesh_io_private, 1);
+	io->pvt->index = *(int *)opts;
 
-	io->pvt = tmp;
-	return true;
+	io->pvt->rx_regs = l_queue_new();
+	io->pvt->tx_pkts = l_queue_new();
 
-fail:
-	l_queue_destroy(tmp->rx_regs, l_free);
-	l_queue_destroy(tmp->tx_pkts, l_free);
-	l_free(tmp);
-	return false;
+	if (io->pvt->index == MGMT_INDEX_NONE)
+		return mesh_mgmt_list(read_info, io);
+	else
+		return hci_init(io);
 }
 
 static bool dev_destroy(struct mesh_io *io)
diff --git a/mesh/mesh-io.c b/mesh/mesh-io.c
index 37153ea9d..62a8c0e2c 100644
--- a/mesh/mesh-io.c
+++ b/mesh/mesh-io.c
@@ -44,21 +44,20 @@ static bool match_by_io(const void *a, const void *b)
 	return a == b;
 }
 
-static bool match_by_index(const void *a, const void *b)
+static bool match_by_type(const void *a, const void *b)
 {
 	const struct mesh_io *io = a;
+	const enum mesh_io_type type = L_PTR_TO_UINT(b);
 
-	return io->index == L_PTR_TO_UINT(b);
+	return io->type == type;
 }
 
-struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type)
+struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts)
 {
 	const struct mesh_io_api *api = NULL;
 	struct mesh_io *io;
 	uint16_t i;
 
-	l_info("%s %d\n", __func__, type);
-
 	for (i = 0; i < L_ARRAY_SIZE(table); i++) {
 		if (table[i].type == type) {
 			api = table[i].api;
@@ -66,7 +65,7 @@ struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type)
 		}
 	}
 
-	io = l_queue_find(io_list, match_by_index, L_UINT_TO_PTR(index));
+	io = l_queue_find(io_list, match_by_type, L_UINT_TO_PTR(type));
 
 	if (!api || !api->init || io)
 		return NULL;
@@ -77,9 +76,9 @@ struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type)
 		return NULL;
 
 	io->type = type;
-	io->index = index;
+
 	io->api = api;
-	if (!api->init(index, io))
+	if (!api->init(io, opts))
 		goto fail;
 
 	if (!io_list)
diff --git a/mesh/mesh-io.h b/mesh/mesh-io.h
index 71d3cb980..6585205c7 100644
--- a/mesh/mesh-io.h
+++ b/mesh/mesh-io.h
@@ -80,7 +80,7 @@ typedef void (*mesh_io_recv_func_t)(void *user_data,
 typedef void (*mesh_io_status_func_t)(void *user_data, int status,
 							uint8_t filter_id);
 
-struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type);
+struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts);
 void mesh_io_destroy(struct mesh_io *io);
 
 bool mesh_io_get_caps(struct mesh_io *io, struct mesh_io_caps *caps);
diff --git a/mesh/mesh-mgmt.c b/mesh/mesh-mgmt.c
new file mode 100644
index 000000000..27272d4d2
--- /dev/null
+++ b/mesh/mesh-mgmt.c
@@ -0,0 +1,204 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2019  SILVAIR sp. z o.o. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
+
+#include "ell/queue.h"
+#include "ell/log.h"
+#include "ell/util.h"
+
+#include "mesh/mesh-mgmt.h"
+
+struct read_info_reg {
+	mesh_mgmt_read_info_func_t cb;
+	void *user_data;
+};
+
+struct read_info_req {
+	int index;
+	struct mesh_io *io;
+};
+
+static struct mgmt *mgmt_mesh;
+static struct l_queue *controllers;
+static struct l_queue *read_info_regs;
+
+static bool simple_match(const void *a, const void *b)
+{
+	return a == b;
+}
+
+static void process_read_info_req(void *data, void *user_data)
+{
+	struct read_info_reg *reg = data;
+	int index = L_PTR_TO_UINT(user_data);
+
+	reg->cb(index, reg->user_data);
+}
+
+static void read_info_cb(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	int index = L_PTR_TO_UINT(user_data);
+	const struct mgmt_rp_read_info *rp = param;
+	uint32_t current_settings, supported_settings;
+
+	l_debug("hci %u status 0x%02x", index, status);
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		l_error("Failed to read info for hci index %u: %s (0x%02x)",
+				index, mgmt_errstr(status), status);
+		return;
+	}
+
+	if (length < sizeof(*rp)) {
+		l_error("Read info response too short");
+		return;
+	}
+
+	current_settings = btohl(rp->current_settings);
+	supported_settings = btohl(rp->supported_settings);
+
+	l_debug("settings: supp %8.8x curr %8.8x",
+					supported_settings, current_settings);
+
+	if (current_settings & MGMT_SETTING_POWERED) {
+		l_info("Controller hci %u is in use", index);
+		return;
+	}
+
+	if (!(supported_settings & MGMT_SETTING_LE)) {
+		l_info("Controller hci %u does not support LE", index);
+		return;
+	}
+
+	l_queue_foreach(read_info_regs, process_read_info_req,
+							L_UINT_TO_PTR(index));
+}
+
+static void index_added(uint16_t index, uint16_t length, const void *param,
+							void *user_data)
+{
+	if (l_queue_find(controllers, simple_match, L_UINT_TO_PTR(index)))
+		return;
+
+	l_queue_push_tail(controllers, L_UINT_TO_PTR(index));
+
+	if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
+			read_info_cb, L_UINT_TO_PTR(index), NULL) != 0)
+		return;
+
+	l_queue_remove(controllers, L_UINT_TO_PTR(index));
+}
+
+static void index_removed(uint16_t index, uint16_t length, const void *param,
+							void *user_data)
+{
+	l_warn("Hci dev %4.4x removed", index);
+	l_queue_remove(controllers, L_UINT_TO_PTR(index));
+}
+
+static void read_index_list_cb(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_read_index_list *rp = param;
+	uint16_t num;
+	int i;
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		l_error("Failed to read index list: %s (0x%02x)",
+						mgmt_errstr(status), status);
+		return;
+	}
+
+	if (length < sizeof(*rp)) {
+		l_error("Read index list response sixe too short");
+		return;
+	}
+
+	num = btohs(rp->num_controllers);
+
+	l_debug("Number of controllers: %u", num);
+
+	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+		l_error("Incorrect packet size for index list response");
+		return;
+	}
+
+	for (i = 0; i < num; i++) {
+		uint16_t index;
+
+		index = btohs(rp->index[i]);
+		index_added(index, 0, NULL, user_data);
+	}
+}
+
+static bool mesh_mgmt_init(void)
+{
+	if (!controllers)
+		controllers = l_queue_new();
+
+	if (!read_info_regs)
+		read_info_regs = l_queue_new();
+
+	if (!mgmt_mesh) {
+		mgmt_mesh = mgmt_new_default();
+
+		if (!mgmt_mesh) {
+			l_error("Failed to initialize mesh management");
+			return false;
+		}
+
+		mgmt_register(mgmt_mesh, MGMT_EV_INDEX_ADDED,
+				MGMT_INDEX_NONE, index_added, NULL, NULL);
+		mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED,
+				MGMT_INDEX_NONE, index_removed, NULL, NULL);
+	}
+
+	return true;
+}
+
+bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data)
+{
+	struct read_info_reg *reg;
+
+	if (!mesh_mgmt_init())
+		return false;
+
+	reg = l_new(struct read_info_reg, 1);
+	reg->cb = cb;
+	reg->user_data = user_data;
+
+	l_queue_push_tail(read_info_regs, reg);
+
+	/* Use MGMT to find a candidate controller */
+	l_debug("send read index_list");
+	if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INDEX_LIST,
+					MGMT_INDEX_NONE, 0, NULL,
+					read_index_list_cb, NULL, NULL) <= 0)
+		return false;
+
+	return true;
+}
diff --git a/mesh/mesh-mgmt.h b/mesh/mesh-mgmt.h
new file mode 100644
index 000000000..93ad7995e
--- /dev/null
+++ b/mesh/mesh-mgmt.h
@@ -0,0 +1,23 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2019  SILVAIR sp. z o.o. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ */
+#include <stdbool.h>
+
+typedef void (*mesh_mgmt_read_info_func_t)(int index, void *user_data);
+
+bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data);
diff --git a/mesh/mesh.c b/mesh/mesh.c
index 231a6bca4..26acfd4dc 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -24,11 +24,6 @@
 #define _GNU_SOURCE
 #include <ell/ell.h>
 
-#include "lib/bluetooth.h"
-#include "lib/mgmt.h"
-
-#include "src/shared/mgmt.h"
-
 #include "mesh/mesh-io.h"
 #include "mesh/node.h"
 #include "mesh/net.h"
@@ -76,9 +71,6 @@ struct join_data{
 };
 
 static struct bt_mesh mesh;
-static struct l_queue *controllers;
-static struct mgmt *mgmt_mesh;
-static bool initialized;
 
 /* We allow only one outstanding Join request */
 static struct join_data *join_pending;
@@ -91,29 +83,6 @@ static bool simple_match(const void *a, const void *b)
 	return a == b;
 }
 
-static void start_io(uint16_t index)
-{
-	struct mesh_io *io;
-	struct mesh_io_caps caps;
-
-	l_debug("Starting mesh on hci %u", index);
-
-	io = mesh_io_new(index, MESH_IO_TYPE_GENERIC);
-	if (!io) {
-		l_error("Failed to start mesh io (hci %u)", index);
-		return;
-	}
-
-	mesh_io_get_caps(io, &caps);
-	mesh.max_filters = caps.max_num_filters;
-
-	mesh.io = io;
-
-	l_debug("Started mesh (io %p) on hci %u", mesh.io, index);
-
-	node_attach_io_all(io);
-}
-
 /* Used for any outbound traffic that doesn't have Friendship Constraints */
 /* This includes Beacons, Provisioning and unrestricted Network Traffic */
 bool mesh_send_pkt(uint8_t count, uint16_t interval,
@@ -167,143 +136,13 @@ void mesh_unreg_prov_rx(prov_rx_cb_t cb)
 	mesh_io_deregister_recv_cb(mesh.io, MESH_IO_FILTER_PROV);
 }
 
-static void read_info_cb(uint8_t status, uint16_t length,
-					const void *param, void *user_data)
+bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
 {
-	uint16_t index = L_PTR_TO_UINT(user_data);
-	const struct mgmt_rp_read_info *rp = param;
-	uint32_t current_settings, supported_settings;
+	struct mesh_io_caps caps;
 
 	if (mesh.io)
-		/* Already initialized */
-		return;
-
-	l_debug("hci %u status 0x%02x", index, status);
-
-	if (status != MGMT_STATUS_SUCCESS) {
-		l_error("Failed to read info for hci index %u: %s (0x%02x)",
-					index, mgmt_errstr(status), status);
-		return;
-	}
-
-	if (length < sizeof(*rp)) {
-		l_error("Read info response too short");
-		return;
-	}
-
-	current_settings = btohl(rp->current_settings);
-	supported_settings = btohl(rp->supported_settings);
-
-	l_debug("settings: supp %8.8x curr %8.8x",
-					supported_settings, current_settings);
-
-	if (current_settings & MGMT_SETTING_POWERED) {
-		l_info("Controller hci %u is in use", index);
-		return;
-	}
-
-	if (!(supported_settings & MGMT_SETTING_LE)) {
-		l_info("Controller hci %u does not support LE", index);
-		return;
-	}
-
-	start_io(index);
-}
-
-static void index_added(uint16_t index, uint16_t length, const void *param,
-							void *user_data)
-{
-	l_debug("hci device %u", index);
-
-	if (mesh.req_index != MGMT_INDEX_NONE &&
-					index != mesh.req_index) {
-		l_debug("Ignore index %d", index);
-		return;
-	}
-
-	if (l_queue_find(controllers, simple_match, L_UINT_TO_PTR(index)))
-		return;
-
-	l_queue_push_tail(controllers, L_UINT_TO_PTR(index));
-
-	if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
-			read_info_cb, L_UINT_TO_PTR(index), NULL) > 0)
-		return;
-
-	l_queue_remove(controllers, L_UINT_TO_PTR(index));
-}
-
-static void index_removed(uint16_t index, uint16_t length, const void *param,
-							void *user_data)
-{
-	l_warn("Hci dev %4.4x removed", index);
-	l_queue_remove(controllers, L_UINT_TO_PTR(index));
-}
-
-static void read_index_list_cb(uint8_t status, uint16_t length,
-					const void *param, void *user_data)
-{
-	const struct mgmt_rp_read_index_list *rp = param;
-	uint16_t num;
-	int i;
-
-	if (status != MGMT_STATUS_SUCCESS) {
-		l_error("Failed to read index list: %s (0x%02x)",
-						mgmt_errstr(status), status);
-		return;
-	}
-
-	if (length < sizeof(*rp)) {
-		l_error("Read index list response sixe too short");
-		return;
-	}
-
-	num = btohs(rp->num_controllers);
-
-	l_debug("Number of controllers: %u", num);
-
-	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
-		l_error("Incorrect packet size for index list response");
-		return;
-	}
-
-	for (i = 0; i < num; i++) {
-		uint16_t index;
-
-		index = btohs(rp->index[i]);
-		index_added(index, 0, NULL, user_data);
-	}
-}
-
-static bool init_mgmt(void)
-{
-	mgmt_mesh = mgmt_new_default();
-	if (!mgmt_mesh)
-		return false;
-
-	controllers = l_queue_new();
-	if (!controllers)
-		return false;
-
-	mgmt_register(mgmt_mesh, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
-						index_added, NULL, NULL);
-	mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
-						index_removed, NULL, NULL);
-	return true;
-}
-
-bool mesh_init(uint16_t index, const char *config_dir)
-{
-	if (initialized)
 		return true;
 
-	if (index == MGMT_INDEX_NONE && !init_mgmt()) {
-		l_error("Failed to initialize mesh management");
-		return false;
-	}
-
-	mesh.req_index = index;
-
 	mesh_model_init();
 	mesh_agent_init();
 
@@ -319,18 +158,16 @@ bool mesh_init(uint16_t index, const char *config_dir)
 	if (!storage_load_nodes(config_dir))
 		return false;
 
-	if (index == MGMT_INDEX_NONE) {
-		/* Use MGMT to find a candidate controller */
-		l_debug("send read index_list");
-		if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INDEX_LIST,
-					MGMT_INDEX_NONE, 0, NULL,
-					read_index_list_cb, NULL, NULL) <= 0)
-			return false;
-	} else {
-		/* Open specified controller without searching */
-		start_io(mesh.req_index);
-		return mesh.io != NULL;
-	}
+	mesh.io = mesh_io_new(type, opts);
+	if (!mesh.io)
+		return false;
+
+	l_debug("io %p", mesh.io);
+	mesh_io_get_caps(mesh.io, &caps);
+	mesh.max_filters = caps.max_num_filters;
+
+	node_attach_io_all(mesh.io);
+
 	return true;
 }
 
@@ -366,7 +203,6 @@ void mesh_cleanup(void)
 	struct l_dbus_message *reply;
 
 	mesh_io_destroy(mesh.io);
-	mgmt_unref(mgmt_mesh);
 
 	if (join_pending) {
 
@@ -384,7 +220,6 @@ void mesh_cleanup(void)
 	node_cleanup_all();
 	mesh_model_cleanup();
 
-	l_queue_destroy(controllers, NULL);
 	l_dbus_object_remove_interface(dbus_get_bus(), BLUEZ_MESH_PATH,
 							MESH_NETWORK_INTERFACE);
 	l_dbus_unregister_interface(dbus_get_bus(), MESH_NETWORK_INTERFACE);
diff --git a/mesh/mesh.h b/mesh/mesh.h
index 320a108ed..14b1fb517 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -28,9 +28,11 @@
 #define MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
 #define ERROR_INTERFACE "org.bluez.mesh.Error"
 
+enum mesh_io_type;
+
 typedef void (*prov_rx_cb_t)(void *user_data, const uint8_t *data,
 								uint16_t len);
-bool mesh_init(uint16_t index, const char *in_config_name);
+bool mesh_init(const char *in_config_name, enum mesh_io_type type, void *opts);
 void mesh_cleanup(void);
 bool mesh_dbus_init(struct l_dbus *dbus);
 
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ v3 2/2] mesh: Added --io option
  2019-06-24  7:32 [PATCH BlueZ v3 0/2] mesh: Move HCI handling to mesh-io-generic Michał Lowas-Rzechonek
  2019-06-24  7:32 ` [PATCH BlueZ v3 1/2] " Michał Lowas-Rzechonek
@ 2019-06-24  7:32 ` Michał Lowas-Rzechonek
  2019-06-24 20:05   ` Michał Lowas-Rzechonek
  1 sibling, 1 reply; 5+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-06-24  7:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Inga Stotland

This allows specifying io type and options when invoking the daemon.

By default, meshd runs with MESH_IO_TYPE_GENERIC and tries to attach to
the first available HCI interface.

Option "--index=<n>" is now just a shortcut for "--io=generic:<n>"
---
 mesh/main.c | 94 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 77 insertions(+), 17 deletions(-)

diff --git a/mesh/main.c b/mesh/main.c
index 262e3da48..c9bf850f6 100644
--- a/mesh/main.c
+++ b/mesh/main.c
@@ -39,6 +39,7 @@
 
 static const struct option main_options[] = {
 	{ "index",	required_argument,	NULL, 'i' },
+	{ "io",		required_argument,	NULL, 'I' },
 	{ "config",	optional_argument,	NULL, 'c' },
 	{ "nodetach",	no_argument,		NULL, 'n' },
 	{ "debug",	no_argument,		NULL, 'd' },
@@ -49,16 +50,23 @@ static const struct option main_options[] = {
 
 static void usage(void)
 {
-	l_info("");
-	l_info("Usage:\n"
+	fprintf(stderr,
+		"Usage:\n"
 	       "\tbluetooth-meshd [options]\n");
-	l_info("Options:\n"
-	       "\t--index <hcinum>  Use specified controller\n"
+	fprintf(stderr,
+		"Options:\n"
+	       "\t--index <hcinum>  Equivalent of `--io=generic:<hcinum>`\n"
+	       "\t--io <io>         Use specified io (default: generic)\n"
 	       "\t--config          Configuration directory\n"
 	       "\t--nodetach        Run in foreground\n"
 	       "\t--debug           Enable debug output\n"
 	       "\t--dbus-debug      Enable D-Bus debugging\n"
 	       "\t--help            Show %s information\n", __func__);
+	fprintf(stderr,
+	       "io:\n"
+	       "\tgeneric[:<index>]\n"
+	       "\t\tUse generic HCI io on interface hci<index>, or the first\n"
+	       "\t\tavailable one\n");
 }
 
 static void do_debug(const char *str, void *user_data)
@@ -107,6 +115,37 @@ static void signal_handler(uint32_t signo, void *user_data)
 	terminated = true;
 }
 
+static bool parse_io(const char *optarg, enum mesh_io_type *type, void **opts)
+{
+	if (strstr(optarg, "generic") == optarg) {
+		int *index = l_new(int, 1);
+
+		*type = MESH_IO_TYPE_GENERIC;
+		*opts = index;
+
+		optarg += strlen("generic");
+		if (!*optarg) {
+			*index = MGMT_INDEX_NONE;
+			return true;
+		}
+
+		if (*optarg != ':')
+			return false;
+
+		optarg++;
+
+		if (sscanf(optarg, "hci%d", index) == 1)
+			return true;
+
+		if (sscanf(optarg, "%d", index) == 1)
+			return true;
+
+		return false;
+	}
+
+	return false;
+}
+
 int main(int argc, char *argv[])
 {
 	int status;
@@ -114,7 +153,9 @@ int main(int argc, char *argv[])
 	bool dbus_debug = false;
 	struct l_dbus *dbus = NULL;
 	const char *config_dir = NULL;
-	int index = MGMT_INDEX_NONE;
+	enum mesh_io_type io_type = MESH_IO_TYPE_NONE;
+	char *io = NULL;
+	void *io_opts = NULL;
 
 	if (!l_main_init())
 		return -1;
@@ -123,7 +164,6 @@ int main(int argc, char *argv[])
 
 	for (;;) {
 		int opt;
-		const char *str;
 
 		opt = getopt_long(argc, argv, "i:c:ndbh", main_options, NULL);
 		if (opt < 0)
@@ -131,18 +171,20 @@ int main(int argc, char *argv[])
 
 		switch (opt) {
 		case 'i':
-			if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
-				str = optarg + 3;
-			else
-				str = optarg;
-			if (!isdigit(*str)) {
-				l_error("Invalid controller index value");
-				status = EXIT_FAILURE;
+			if (io) {
+				l_error("Use either --index or --io, not both");
+				status = EXIT_SUCCESS;
 				goto done;
 			}
-
-			index = atoi(str);
-
+			io = l_strdup_printf("generic:%s", optarg);
+			break;
+		case 'I':
+			if (io) {
+				l_error("Use either --index or --io, not both");
+				status = EXIT_SUCCESS;
+				goto done;
+			}
+			io = l_strdup(optarg);
 			break;
 		case 'n':
 			detached = false;
@@ -167,8 +209,20 @@ int main(int argc, char *argv[])
 		}
 	}
 
+	if (!parse_io(io, &io_type, &io_opts)) {
+		l_error("Invalid io: %s", io);
+		status = EXIT_FAILURE;
+		goto done;
+	}
+
+	if ((io_type == MESH_IO_TYPE_NONE) && !io_opts) {
+		int *index = l_new(int, 1);
+		*index = MGMT_INDEX_NONE;
+		io_type = MESH_IO_TYPE_GENERIC;
+		io_opts = index;
+	}
 
-	if (!mesh_init(config_dir, MESH_IO_TYPE_GENERIC, &index)) {
+	if (!mesh_init(config_dir, io_type, io_opts)) {
 		l_error("Failed to initialize mesh");
 		status = EXIT_FAILURE;
 		goto done;
@@ -198,6 +252,12 @@ int main(int argc, char *argv[])
 	status = l_main_run_with_signal(signal_handler, NULL);
 
 done:
+	if (io)
+		l_free(io);
+
+	if (io_opts)
+		l_free(io_opts);
+
 	mesh_cleanup();
 	l_dbus_destroy(dbus);
 	l_main_exit();
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH BlueZ v3 1/2] mesh: Move HCI handling to mesh-io-generic
  2019-06-24  7:32 ` [PATCH BlueZ v3 1/2] " Michał Lowas-Rzechonek
@ 2019-06-24 16:47   ` Gix, Brian
  0 siblings, 0 replies; 5+ messages in thread
From: Gix, Brian @ 2019-06-24 16:47 UTC (permalink / raw)
  To: michal.lowas-rzechonek, linux-bluetooth; +Cc: Stotland, Inga

Applied, Thanks.

On Mon, 2019-06-24 at 09:32 +0200, Michał Lowas-Rzechonek wrote:
> This patch separates 'mesh' module from 'mesh_io', particularly
> regarding configuration and initialization.
> 
> Main code is no longer aware of MGMT and HCI usage - querying
> available
> HCI interfaces now happens in mesh-io-generic.
> 
> MGMT code is now extracted into mesh-mgmt module, which mesh-io-
> generic
> uses to query interfaces.
> ---
>  Makefile.mesh          |   1 +
>  mesh/main.c            |   4 +-
>  mesh/mesh-io-api.h     |   3 +-
>  mesh/mesh-io-generic.c |  63 ++++++++-----
>  mesh/mesh-io.c         |  15 ++-
>  mesh/mesh-io.h         |   2 +-
>  mesh/mesh-mgmt.c       | 204
> +++++++++++++++++++++++++++++++++++++++++
>  mesh/mesh-mgmt.h       |  23 +++++
>  mesh/mesh.c            | 189 +++-----------------------------------
>  mesh/mesh.h            |   4 +-
>  10 files changed, 294 insertions(+), 214 deletions(-)
>  create mode 100644 mesh/mesh-mgmt.c
>  create mode 100644 mesh/mesh-mgmt.h
> 
> diff --git a/Makefile.mesh b/Makefile.mesh
> index b1f14e477..1ace507af 100644
> --- a/Makefile.mesh
> +++ b/Makefile.mesh
> @@ -12,6 +12,7 @@ endif
>  mesh_sources = mesh/mesh.h mesh/mesh.c \
>  				mesh/net-keys.h mesh/net-keys.c \
>  				mesh/mesh-io.h mesh/mesh-io.c \
> +				mesh/mesh-mgmt.c mesh/mesh-mgmt.h \
>  				mesh/error.h mesh/mesh-io-api.h \
>  				mesh/mesh-io-generic.h \
>  				mesh/mesh-io-generic.c \
> diff --git a/mesh/main.c b/mesh/main.c
> index 3cecd8fbf..262e3da48 100644
> --- a/mesh/main.c
> +++ b/mesh/main.c
> @@ -35,6 +35,7 @@
>  
>  #include "mesh/mesh.h"
>  #include "mesh/dbus.h"
> +#include "mesh/mesh-io.h"
>  
>  static const struct option main_options[] = {
>  	{ "index",	required_argument,	NULL, 'i' },
> @@ -166,7 +167,8 @@ int main(int argc, char *argv[])
>  		}
>  	}
>  
> -	if (!mesh_init(index, config_dir)) {
> +
> +	if (!mesh_init(config_dir, MESH_IO_TYPE_GENERIC, &index)) {
>  		l_error("Failed to initialize mesh");
>  		status = EXIT_FAILURE;
>  		goto done;
> diff --git a/mesh/mesh-io-api.h b/mesh/mesh-io-api.h
> index acf12445d..4cdf1f80a 100644
> --- a/mesh/mesh-io-api.h
> +++ b/mesh/mesh-io-api.h
> @@ -19,7 +19,7 @@
>  
>  struct mesh_io_private;
>  
> -typedef bool (*mesh_io_init_t)(uint16_t index, struct mesh_io *io);
> +typedef bool (*mesh_io_init_t)(struct mesh_io *io, void *opts);
>  typedef bool (*mesh_io_destroy_t)(struct mesh_io *io);
>  typedef bool (*mesh_io_caps_t)(struct mesh_io *io, struct
> mesh_io_caps *caps);
>  typedef bool (*mesh_io_send_t)(struct mesh_io *io,
> @@ -47,7 +47,6 @@ struct mesh_io_api {
>  
>  struct mesh_io {
>  	enum mesh_io_type		type;
> -	uint16_t			index;
>  	const struct mesh_io_api	*api;
>  	struct mesh_io_private		*pvt;
>  };
> diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c
> index 756dceabc..42aaa0947 100644
> --- a/mesh/mesh-io-generic.c
> +++ b/mesh/mesh-io-generic.c
> @@ -26,7 +26,10 @@
>  
>  #include "monitor/bt.h"
>  #include "src/shared/hci.h"
> +#include "lib/bluetooth.h"
> +#include "lib/mgmt.h"
>  
> +#include "mesh/mesh-mgmt.h"
>  #include "mesh/mesh-io.h"
>  #include "mesh/mesh-io-api.h"
>  #include "mesh/mesh-io-generic.h"
> @@ -278,40 +281,52 @@ static void configure_hci(struct
> mesh_io_private *io)
>  				sizeof(cmd), hci_generic_callback,
> NULL, NULL);
>  }
>  
> -static bool dev_init(uint16_t index, struct mesh_io *io)
> +static bool hci_init(struct mesh_io *io)
>  {
> -	struct mesh_io_private *tmp;
> -
> -	if (!io || io->pvt)
> +	io->pvt->hci = bt_hci_new_user_channel(io->pvt->index);
> +	if (!io->pvt->hci) {
> +		l_error("Failed to start mesh io (hci %u)", io->pvt-
> >index);
>  		return false;
> +	}
>  
> -	tmp = l_new(struct mesh_io_private, 1);
> +	configure_hci(io->pvt);
>  
> -	if (tmp == NULL)
> -		return false;
> +	bt_hci_register(io->pvt->hci, BT_HCI_EVT_LE_META_EVENT,
> +						event_callback, io,
> NULL);
> +
> +	l_debug("Started mesh on hci %u", io->pvt->index);
> +	return true;
> +}
> +
> +static void read_info(int index, void *user_data)
> +{
> +	struct mesh_io *io = user_data;
>  
> -	tmp->rx_regs = l_queue_new();
> -	tmp->tx_pkts = l_queue_new();
> -	if (!tmp->rx_regs || !tmp->tx_pkts)
> -		goto fail;
> +	if (io->pvt->index != MGMT_INDEX_NONE &&
> +					index != io->pvt->index) {
> +		l_debug("Ignore index %d", index);
> +		return;
> +	}
>  
> -	tmp->hci = bt_hci_new_user_channel(index);
> -	if (!tmp->hci)
> -		goto fail;
> +	io->pvt->index = index;
> +	hci_init(io);
> +}
>  
> -	configure_hci(tmp);
> +static bool dev_init(struct mesh_io *io, void *opts)
> +{
> +	if (!io || io->pvt)
> +		return false;
>  
> -	bt_hci_register(tmp->hci, BT_HCI_EVT_LE_META_EVENT,
> -						event_callback, io,
> NULL);
> +	io->pvt = l_new(struct mesh_io_private, 1);
> +	io->pvt->index = *(int *)opts;
>  
> -	io->pvt = tmp;
> -	return true;
> +	io->pvt->rx_regs = l_queue_new();
> +	io->pvt->tx_pkts = l_queue_new();
>  
> -fail:
> -	l_queue_destroy(tmp->rx_regs, l_free);
> -	l_queue_destroy(tmp->tx_pkts, l_free);
> -	l_free(tmp);
> -	return false;
> +	if (io->pvt->index == MGMT_INDEX_NONE)
> +		return mesh_mgmt_list(read_info, io);
> +	else
> +		return hci_init(io);
>  }
>  
>  static bool dev_destroy(struct mesh_io *io)
> diff --git a/mesh/mesh-io.c b/mesh/mesh-io.c
> index 37153ea9d..62a8c0e2c 100644
> --- a/mesh/mesh-io.c
> +++ b/mesh/mesh-io.c
> @@ -44,21 +44,20 @@ static bool match_by_io(const void *a, const void
> *b)
>  	return a == b;
>  }
>  
> -static bool match_by_index(const void *a, const void *b)
> +static bool match_by_type(const void *a, const void *b)
>  {
>  	const struct mesh_io *io = a;
> +	const enum mesh_io_type type = L_PTR_TO_UINT(b);
>  
> -	return io->index == L_PTR_TO_UINT(b);
> +	return io->type == type;
>  }
>  
> -struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type)
> +struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts)
>  {
>  	const struct mesh_io_api *api = NULL;
>  	struct mesh_io *io;
>  	uint16_t i;
>  
> -	l_info("%s %d\n", __func__, type);
> -
>  	for (i = 0; i < L_ARRAY_SIZE(table); i++) {
>  		if (table[i].type == type) {
>  			api = table[i].api;
> @@ -66,7 +65,7 @@ struct mesh_io *mesh_io_new(uint16_t index, enum
> mesh_io_type type)
>  		}
>  	}
>  
> -	io = l_queue_find(io_list, match_by_index,
> L_UINT_TO_PTR(index));
> +	io = l_queue_find(io_list, match_by_type, L_UINT_TO_PTR(type));
>  
>  	if (!api || !api->init || io)
>  		return NULL;
> @@ -77,9 +76,9 @@ struct mesh_io *mesh_io_new(uint16_t index, enum
> mesh_io_type type)
>  		return NULL;
>  
>  	io->type = type;
> -	io->index = index;
> +
>  	io->api = api;
> -	if (!api->init(index, io))
> +	if (!api->init(io, opts))
>  		goto fail;
>  
>  	if (!io_list)
> diff --git a/mesh/mesh-io.h b/mesh/mesh-io.h
> index 71d3cb980..6585205c7 100644
> --- a/mesh/mesh-io.h
> +++ b/mesh/mesh-io.h
> @@ -80,7 +80,7 @@ typedef void (*mesh_io_recv_func_t)(void
> *user_data,
>  typedef void (*mesh_io_status_func_t)(void *user_data, int status,
>  							uint8_t
> filter_id);
>  
> -struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type);
> +struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts);
>  void mesh_io_destroy(struct mesh_io *io);
>  
>  bool mesh_io_get_caps(struct mesh_io *io, struct mesh_io_caps
> *caps);
> diff --git a/mesh/mesh-mgmt.c b/mesh/mesh-mgmt.c
> new file mode 100644
> index 000000000..27272d4d2
> --- /dev/null
> +++ b/mesh/mesh-mgmt.c
> @@ -0,0 +1,204 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2019  SILVAIR sp. z o.o. All rights reserved.
> + *
> + *
> + *  This library is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU Lesser General Public
> + *  License as published by the Free Software Foundation; either
> + *  version 2.1 of the License, or (at your option) any later
> version.
> + *
> + *  This library is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> GNU
> + *  Lesser General Public License for more details.
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include "lib/bluetooth.h"
> +#include "lib/mgmt.h"
> +#include "src/shared/mgmt.h"
> +
> +#include "ell/queue.h"
> +#include "ell/log.h"
> +#include "ell/util.h"
> +
> +#include "mesh/mesh-mgmt.h"
> +
> +struct read_info_reg {
> +	mesh_mgmt_read_info_func_t cb;
> +	void *user_data;
> +};
> +
> +struct read_info_req {
> +	int index;
> +	struct mesh_io *io;
> +};
> +
> +static struct mgmt *mgmt_mesh;
> +static struct l_queue *controllers;
> +static struct l_queue *read_info_regs;
> +
> +static bool simple_match(const void *a, const void *b)
> +{
> +	return a == b;
> +}
> +
> +static void process_read_info_req(void *data, void *user_data)
> +{
> +	struct read_info_reg *reg = data;
> +	int index = L_PTR_TO_UINT(user_data);
> +
> +	reg->cb(index, reg->user_data);
> +}
> +
> +static void read_info_cb(uint8_t status, uint16_t length,
> +					const void *param, void
> *user_data)
> +{
> +	int index = L_PTR_TO_UINT(user_data);
> +	const struct mgmt_rp_read_info *rp = param;
> +	uint32_t current_settings, supported_settings;
> +
> +	l_debug("hci %u status 0x%02x", index, status);
> +
> +	if (status != MGMT_STATUS_SUCCESS) {
> +		l_error("Failed to read info for hci index %u: %s
> (0x%02x)",
> +				index, mgmt_errstr(status), status);
> +		return;
> +	}
> +
> +	if (length < sizeof(*rp)) {
> +		l_error("Read info response too short");
> +		return;
> +	}
> +
> +	current_settings = btohl(rp->current_settings);
> +	supported_settings = btohl(rp->supported_settings);
> +
> +	l_debug("settings: supp %8.8x curr %8.8x",
> +					supported_settings,
> current_settings);
> +
> +	if (current_settings & MGMT_SETTING_POWERED) {
> +		l_info("Controller hci %u is in use", index);
> +		return;
> +	}
> +
> +	if (!(supported_settings & MGMT_SETTING_LE)) {
> +		l_info("Controller hci %u does not support LE", index);
> +		return;
> +	}
> +
> +	l_queue_foreach(read_info_regs, process_read_info_req,
> +							L_UINT_TO_PTR(i
> ndex));
> +}
> +
> +static void index_added(uint16_t index, uint16_t length, const void
> *param,
> +							void
> *user_data)
> +{
> +	if (l_queue_find(controllers, simple_match,
> L_UINT_TO_PTR(index)))
> +		return;
> +
> +	l_queue_push_tail(controllers, L_UINT_TO_PTR(index));
> +
> +	if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
> +			read_info_cb, L_UINT_TO_PTR(index), NULL) != 0)
> +		return;
> +
> +	l_queue_remove(controllers, L_UINT_TO_PTR(index));
> +}
> +
> +static void index_removed(uint16_t index, uint16_t length, const
> void *param,
> +							void
> *user_data)
> +{
> +	l_warn("Hci dev %4.4x removed", index);
> +	l_queue_remove(controllers, L_UINT_TO_PTR(index));
> +}
> +
> +static void read_index_list_cb(uint8_t status, uint16_t length,
> +					const void *param, void
> *user_data)
> +{
> +	const struct mgmt_rp_read_index_list *rp = param;
> +	uint16_t num;
> +	int i;
> +
> +	if (status != MGMT_STATUS_SUCCESS) {
> +		l_error("Failed to read index list: %s (0x%02x)",
> +						mgmt_errstr(status),
> status);
> +		return;
> +	}
> +
> +	if (length < sizeof(*rp)) {
> +		l_error("Read index list response sixe too short");
> +		return;
> +	}
> +
> +	num = btohs(rp->num_controllers);
> +
> +	l_debug("Number of controllers: %u", num);
> +
> +	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
> +		l_error("Incorrect packet size for index list
> response");
> +		return;
> +	}
> +
> +	for (i = 0; i < num; i++) {
> +		uint16_t index;
> +
> +		index = btohs(rp->index[i]);
> +		index_added(index, 0, NULL, user_data);
> +	}
> +}
> +
> +static bool mesh_mgmt_init(void)
> +{
> +	if (!controllers)
> +		controllers = l_queue_new();
> +
> +	if (!read_info_regs)
> +		read_info_regs = l_queue_new();
> +
> +	if (!mgmt_mesh) {
> +		mgmt_mesh = mgmt_new_default();
> +
> +		if (!mgmt_mesh) {
> +			l_error("Failed to initialize mesh
> management");
> +			return false;
> +		}
> +
> +		mgmt_register(mgmt_mesh, MGMT_EV_INDEX_ADDED,
> +				MGMT_INDEX_NONE, index_added, NULL,
> NULL);
> +		mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED,
> +				MGMT_INDEX_NONE, index_removed, NULL,
> NULL);
> +	}
> +
> +	return true;
> +}
> +
> +bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data)
> +{
> +	struct read_info_reg *reg;
> +
> +	if (!mesh_mgmt_init())
> +		return false;
> +
> +	reg = l_new(struct read_info_reg, 1);
> +	reg->cb = cb;
> +	reg->user_data = user_data;
> +
> +	l_queue_push_tail(read_info_regs, reg);
> +
> +	/* Use MGMT to find a candidate controller */
> +	l_debug("send read index_list");
> +	if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INDEX_LIST,
> +					MGMT_INDEX_NONE, 0, NULL,
> +					read_index_list_cb, NULL, NULL)
> <= 0)
> +		return false;
> +
> +	return true;
> +}
> diff --git a/mesh/mesh-mgmt.h b/mesh/mesh-mgmt.h
> new file mode 100644
> index 000000000..93ad7995e
> --- /dev/null
> +++ b/mesh/mesh-mgmt.h
> @@ -0,0 +1,23 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2019  SILVAIR sp. z o.o. All rights reserved.
> + *
> + *
> + *  This library is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU Lesser General Public
> + *  License as published by the Free Software Foundation; either
> + *  version 2.1 of the License, or (at your option) any later
> version.
> + *
> + *  This library is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> GNU
> + *  Lesser General Public License for more details.
> + *
> + */
> +#include <stdbool.h>
> +
> +typedef void (*mesh_mgmt_read_info_func_t)(int index, void
> *user_data);
> +
> +bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data);
> diff --git a/mesh/mesh.c b/mesh/mesh.c
> index 231a6bca4..26acfd4dc 100644
> --- a/mesh/mesh.c
> +++ b/mesh/mesh.c
> @@ -24,11 +24,6 @@
>  #define _GNU_SOURCE
>  #include <ell/ell.h>
>  
> -#include "lib/bluetooth.h"
> -#include "lib/mgmt.h"
> -
> -#include "src/shared/mgmt.h"
> -
>  #include "mesh/mesh-io.h"
>  #include "mesh/node.h"
>  #include "mesh/net.h"
> @@ -76,9 +71,6 @@ struct join_data{
>  };
>  
>  static struct bt_mesh mesh;
> -static struct l_queue *controllers;
> -static struct mgmt *mgmt_mesh;
> -static bool initialized;
>  
>  /* We allow only one outstanding Join request */
>  static struct join_data *join_pending;
> @@ -91,29 +83,6 @@ static bool simple_match(const void *a, const void
> *b)
>  	return a == b;
>  }
>  
> -static void start_io(uint16_t index)
> -{
> -	struct mesh_io *io;
> -	struct mesh_io_caps caps;
> -
> -	l_debug("Starting mesh on hci %u", index);
> -
> -	io = mesh_io_new(index, MESH_IO_TYPE_GENERIC);
> -	if (!io) {
> -		l_error("Failed to start mesh io (hci %u)", index);
> -		return;
> -	}
> -
> -	mesh_io_get_caps(io, &caps);
> -	mesh.max_filters = caps.max_num_filters;
> -
> -	mesh.io = io;
> -
> -	l_debug("Started mesh (io %p) on hci %u", mesh.io, index);
> -
> -	node_attach_io_all(io);
> -}
> -
>  /* Used for any outbound traffic that doesn't have Friendship
> Constraints */
>  /* This includes Beacons, Provisioning and unrestricted Network
> Traffic */
>  bool mesh_send_pkt(uint8_t count, uint16_t interval,
> @@ -167,143 +136,13 @@ void mesh_unreg_prov_rx(prov_rx_cb_t cb)
>  	mesh_io_deregister_recv_cb(mesh.io, MESH_IO_FILTER_PROV);
>  }
>  
> -static void read_info_cb(uint8_t status, uint16_t length,
> -					const void *param, void
> *user_data)
> +bool mesh_init(const char *config_dir, enum mesh_io_type type, void
> *opts)
>  {
> -	uint16_t index = L_PTR_TO_UINT(user_data);
> -	const struct mgmt_rp_read_info *rp = param;
> -	uint32_t current_settings, supported_settings;
> +	struct mesh_io_caps caps;
>  
>  	if (mesh.io)
> -		/* Already initialized */
> -		return;
> -
> -	l_debug("hci %u status 0x%02x", index, status);
> -
> -	if (status != MGMT_STATUS_SUCCESS) {
> -		l_error("Failed to read info for hci index %u: %s
> (0x%02x)",
> -					index, mgmt_errstr(status),
> status);
> -		return;
> -	}
> -
> -	if (length < sizeof(*rp)) {
> -		l_error("Read info response too short");
> -		return;
> -	}
> -
> -	current_settings = btohl(rp->current_settings);
> -	supported_settings = btohl(rp->supported_settings);
> -
> -	l_debug("settings: supp %8.8x curr %8.8x",
> -					supported_settings,
> current_settings);
> -
> -	if (current_settings & MGMT_SETTING_POWERED) {
> -		l_info("Controller hci %u is in use", index);
> -		return;
> -	}
> -
> -	if (!(supported_settings & MGMT_SETTING_LE)) {
> -		l_info("Controller hci %u does not support LE", index);
> -		return;
> -	}
> -
> -	start_io(index);
> -}
> -
> -static void index_added(uint16_t index, uint16_t length, const void
> *param,
> -							void
> *user_data)
> -{
> -	l_debug("hci device %u", index);
> -
> -	if (mesh.req_index != MGMT_INDEX_NONE &&
> -					index != mesh.req_index) {
> -		l_debug("Ignore index %d", index);
> -		return;
> -	}
> -
> -	if (l_queue_find(controllers, simple_match,
> L_UINT_TO_PTR(index)))
> -		return;
> -
> -	l_queue_push_tail(controllers, L_UINT_TO_PTR(index));
> -
> -	if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
> -			read_info_cb, L_UINT_TO_PTR(index), NULL) > 0)
> -		return;
> -
> -	l_queue_remove(controllers, L_UINT_TO_PTR(index));
> -}
> -
> -static void index_removed(uint16_t index, uint16_t length, const
> void *param,
> -							void
> *user_data)
> -{
> -	l_warn("Hci dev %4.4x removed", index);
> -	l_queue_remove(controllers, L_UINT_TO_PTR(index));
> -}
> -
> -static void read_index_list_cb(uint8_t status, uint16_t length,
> -					const void *param, void
> *user_data)
> -{
> -	const struct mgmt_rp_read_index_list *rp = param;
> -	uint16_t num;
> -	int i;
> -
> -	if (status != MGMT_STATUS_SUCCESS) {
> -		l_error("Failed to read index list: %s (0x%02x)",
> -						mgmt_errstr(status),
> status);
> -		return;
> -	}
> -
> -	if (length < sizeof(*rp)) {
> -		l_error("Read index list response sixe too short");
> -		return;
> -	}
> -
> -	num = btohs(rp->num_controllers);
> -
> -	l_debug("Number of controllers: %u", num);
> -
> -	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
> -		l_error("Incorrect packet size for index list
> response");
> -		return;
> -	}
> -
> -	for (i = 0; i < num; i++) {
> -		uint16_t index;
> -
> -		index = btohs(rp->index[i]);
> -		index_added(index, 0, NULL, user_data);
> -	}
> -}
> -
> -static bool init_mgmt(void)
> -{
> -	mgmt_mesh = mgmt_new_default();
> -	if (!mgmt_mesh)
> -		return false;
> -
> -	controllers = l_queue_new();
> -	if (!controllers)
> -		return false;
> -
> -	mgmt_register(mgmt_mesh, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
> -						index_added, NULL,
> NULL);
> -	mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED,
> MGMT_INDEX_NONE,
> -						index_removed, NULL,
> NULL);
> -	return true;
> -}
> -
> -bool mesh_init(uint16_t index, const char *config_dir)
> -{
> -	if (initialized)
>  		return true;
>  
> -	if (index == MGMT_INDEX_NONE && !init_mgmt()) {
> -		l_error("Failed to initialize mesh management");
> -		return false;
> -	}
> -
> -	mesh.req_index = index;
> -
>  	mesh_model_init();
>  	mesh_agent_init();
>  
> @@ -319,18 +158,16 @@ bool mesh_init(uint16_t index, const char
> *config_dir)
>  	if (!storage_load_nodes(config_dir))
>  		return false;
>  
> -	if (index == MGMT_INDEX_NONE) {
> -		/* Use MGMT to find a candidate controller */
> -		l_debug("send read index_list");
> -		if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INDEX_LIST,
> -					MGMT_INDEX_NONE, 0, NULL,
> -					read_index_list_cb, NULL, NULL)
> <= 0)
> -			return false;
> -	} else {
> -		/* Open specified controller without searching */
> -		start_io(mesh.req_index);
> -		return mesh.io != NULL;
> -	}
> +	mesh.io = mesh_io_new(type, opts);
> +	if (!mesh.io)
> +		return false;
> +
> +	l_debug("io %p", mesh.io);
> +	mesh_io_get_caps(mesh.io, &caps);
> +	mesh.max_filters = caps.max_num_filters;
> +
> +	node_attach_io_all(mesh.io);
> +
>  	return true;
>  }
>  
> @@ -366,7 +203,6 @@ void mesh_cleanup(void)
>  	struct l_dbus_message *reply;
>  
>  	mesh_io_destroy(mesh.io);
> -	mgmt_unref(mgmt_mesh);
>  
>  	if (join_pending) {
>  
> @@ -384,7 +220,6 @@ void mesh_cleanup(void)
>  	node_cleanup_all();
>  	mesh_model_cleanup();
>  
> -	l_queue_destroy(controllers, NULL);
>  	l_dbus_object_remove_interface(dbus_get_bus(), BLUEZ_MESH_PATH,
>  							MESH_NETWORK_IN
> TERFACE);
>  	l_dbus_unregister_interface(dbus_get_bus(),
> MESH_NETWORK_INTERFACE);
> diff --git a/mesh/mesh.h b/mesh/mesh.h
> index 320a108ed..14b1fb517 100644
> --- a/mesh/mesh.h
> +++ b/mesh/mesh.h
> @@ -28,9 +28,11 @@
>  #define MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
>  #define ERROR_INTERFACE "org.bluez.mesh.Error"
>  
> +enum mesh_io_type;
> +
>  typedef void (*prov_rx_cb_t)(void *user_data, const uint8_t *data,
>  								uint16_
> t len);
> -bool mesh_init(uint16_t index, const char *in_config_name);
> +bool mesh_init(const char *in_config_name, enum mesh_io_type type,
> void *opts);
>  void mesh_cleanup(void);
>  bool mesh_dbus_init(struct l_dbus *dbus);
>  

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH BlueZ v3 2/2] mesh: Added --io option
  2019-06-24  7:32 ` [PATCH BlueZ v3 2/2] mesh: Added --io option Michał Lowas-Rzechonek
@ 2019-06-24 20:05   ` Michał Lowas-Rzechonek
  0 siblings, 0 replies; 5+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-06-24 20:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

Hi Brian,

On 06/24, Michał Lowas-Rzechonek wrote:
> This allows specifying io type and options when invoking the daemon.
> 
> By default, meshd runs with MESH_IO_TYPE_GENERIC and tries to attach to
> the first available HCI interface.
> 
> Option "--index=<n>" is now just a shortcut for "--io=generic:<n>"

Thanks for applying the first patch, but how about this one? :)

cheers
-- 
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-06-24 20:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-24  7:32 [PATCH BlueZ v3 0/2] mesh: Move HCI handling to mesh-io-generic Michał Lowas-Rzechonek
2019-06-24  7:32 ` [PATCH BlueZ v3 1/2] " Michał Lowas-Rzechonek
2019-06-24 16:47   ` Gix, Brian
2019-06-24  7:32 ` [PATCH BlueZ v3 2/2] mesh: Added --io option Michał Lowas-Rzechonek
2019-06-24 20:05   ` Michał Lowas-Rzechonek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).