linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Brian Gix <brian.gix@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: johan.hedberg@gmail.com, inga.stotland@intel.com,
	marcel@holtmann.org, brian.gix@intel.com
Subject: [PATCH BlueZ v6 14/26] mesh: Re-architect for DBus API
Date: Fri, 28 Dec 2018 14:07:33 -0800	[thread overview]
Message-ID: <20181228220745.25147-15-brian.gix@intel.com> (raw)
In-Reply-To: <20181228220745.25147-1-brian.gix@intel.com>

From: Inga Stotland <inga.stotland@intel.com>

The mesh code controls how the main functionalities of the daemon
(Provisioning and Mesh Network Messaging) interact with the
bluetooth controllers that are available. Restructured so that
multiple nodes, on multiple networks, can share the same controllers.
---
 mesh/mesh.c | 626 ++++++++++++++++++++++++++++++++++++++++++++++--------------
 mesh/mesh.h |  28 ++-
 2 files changed, 503 insertions(+), 151 deletions(-)

diff --git a/mesh/mesh.c b/mesh/mesh.c
index d1d409672..169e6f42c 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -15,7 +15,6 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  *  Lesser General Public License for more details.
  *
- *
  */
 
 #ifdef HAVE_CONFIG_H
@@ -23,22 +22,33 @@
 #endif
 
 #define _GNU_SOURCE
-#include <time.h>
 #include <ell/ell.h>
+#include <json-c/json.h>
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
 
 #include "src/shared/mgmt.h"
 
-#include "mesh/mesh-defs.h"
 #include "mesh/mesh-io.h"
 #include "mesh/node.h"
 #include "mesh/net.h"
 #include "mesh/storage.h"
-#include "mesh/cfgmod.h"
+#include "mesh/provision.h"
 #include "mesh/model.h"
+#include "mesh/dbus.h"
+#include "mesh/error.h"
 #include "mesh/mesh.h"
+#include "mesh/agent.h"
+
+/*
+ * The default values for mesh configuration. Can be
+ * overwritten by values from mesh.conf
+ */
+#define DEFAULT_PROV_TIMEOUT 60
+#define DEFAULT_ALGORITHMS 0x0001
+
+/* TODO: add more default values */
 
 struct scan_filter {
 	uint8_t id;
@@ -46,42 +56,49 @@ struct scan_filter {
 };
 
 struct bt_mesh {
-	struct mesh_net *net;
 	struct mesh_io *io;
 	struct l_queue *filters;
-	int ref_count;
-	uint16_t index;
+	prov_rx_cb_t prov_rx;
+	void *prov_data;
+	uint32_t prov_timeout;
+	uint16_t algorithms;
 	uint16_t req_index;
 	uint8_t max_filters;
 };
 
+struct join_data{
+	struct l_dbus_message *msg;
+	struct mesh_agent *agent;
+	const char *sender;
+	const char *app_path;
+	struct mesh_node *node;
+	uint32_t disc_watch;
+	uint8_t uuid[16];
+};
+
+struct attach_data {
+	uint64_t token;
+	struct l_dbus_message *msg;
+	const char *app;
+};
+
+static struct bt_mesh mesh;
 static struct l_queue *controllers;
-static struct l_queue *mesh_list;
 static struct mgmt *mgmt_mesh;
 static bool initialized;
-static struct bt_mesh *current;
+
+/* We allow only one outstanding Join request */
+static struct join_data *join_pending;
+
+/* Pending Attach requests */
+static struct l_queue *attach_queue;
 
 static bool simple_match(const void *a, const void *b)
 {
 	return a == b;
 }
 
-static void save_exit_config(struct bt_mesh *mesh)
-{
-	const char *cfg_filename;
-
-	if (!mesh_net_cfg_file_get(mesh->net, &cfg_filename) || !cfg_filename)
-		return;
-
-	/* Preserve the last sequence number before saving configuration */
-	storage_local_write_sequence_number(mesh->net,
-					mesh_net_get_seq_num(mesh->net));
-
-	if (storage_save_config(mesh->net, cfg_filename, true, NULL, NULL))
-		l_info("Saved final configuration to %s", cfg_filename);
-}
-
-static void start_io(struct bt_mesh *mesh, uint16_t index)
+static void start_io(uint16_t index)
 {
 	struct mesh_io *io;
 	struct mesh_io_caps caps;
@@ -91,21 +108,70 @@ static void start_io(struct bt_mesh *mesh, uint16_t index)
 	io = mesh_io_new(index, MESH_IO_TYPE_GENERIC);
 	if (!io) {
 		l_error("Failed to start mesh io (hci %u)", index);
-		current = NULL;
 		return;
 	}
 
 	mesh_io_get_caps(io, &caps);
-	mesh->max_filters = caps.max_num_filters;
+	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(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,
+					uint8_t *data, uint16_t len)
+{
+	struct mesh_io_send_info info = {
+		.type = MESH_IO_TIMING_TYPE_GENERAL,
+		.u.gen.cnt = count,
+		.u.gen.interval = interval,
+		.u.gen.max_delay = 0,
+		.u.gen.min_delay = 0,
+	};
+
+	return mesh_io_send(mesh.io, &info, data, len);
+}
+
+bool mesh_send_cancel(const uint8_t *filter, uint8_t len)
+{
+	return mesh_io_send_cancel(mesh.io, filter, len);
+}
 
-	mesh_net_attach(mesh->net, io);
-	mesh_net_set_window_accuracy(mesh->net, caps.window_accuracy);
-	mesh->io = io;
-	mesh->index = index;
+static void prov_rx(void *user_data, struct mesh_io_recv_info *info,
+					const uint8_t *data, uint16_t len)
+{
+	if (user_data != &mesh)
+		return;
+
+	if (mesh.prov_rx)
+		mesh.prov_rx(mesh.prov_data, data, len);
+}
+
+bool mesh_reg_prov_rx(prov_rx_cb_t cb, void *user_data)
+{
+	if (mesh.prov_rx && mesh.prov_rx != cb)
+		return false;
 
-	current = NULL;
+	mesh.prov_rx = cb;
+	mesh.prov_data = user_data;
 
-	l_debug("Started mesh (io %p) on hci %u", mesh->io, index);
+	return mesh_io_register_recv_cb(mesh.io, MESH_IO_FILTER_PROV,
+							prov_rx, &mesh);
+}
+
+void mesh_unreg_prov_rx(prov_rx_cb_t cb)
+{
+	if (mesh.prov_rx != cb)
+		return;
+
+	mesh.prov_rx = NULL;
+	mesh.prov_data = NULL;
+	mesh_io_deregister_recv_cb(mesh.io, MESH_IO_FILTER_PROV);
 }
 
 static void read_info_cb(uint8_t status, uint16_t length,
@@ -115,7 +181,7 @@ static void read_info_cb(uint8_t status, uint16_t length,
 	const struct mgmt_rp_read_info *rp = param;
 	uint32_t current_settings, supported_settings;
 
-	if (!current)
+	if (mesh.io)
 		/* Already initialized */
 		return;
 
@@ -148,7 +214,7 @@ static void read_info_cb(uint8_t status, uint16_t length,
 		return;
 	}
 
-	start_io(current, index);
+	start_io(index);
 }
 
 static void index_added(uint16_t index, uint16_t length, const void *param,
@@ -156,11 +222,8 @@ static void index_added(uint16_t index, uint16_t length, const void *param,
 {
 	l_debug("hci device %u", index);
 
-	if (!current)
-		return;
-
-	if (current->req_index != MGMT_INDEX_NONE &&
-					index != current->req_index) {
+	if (mesh.req_index != MGMT_INDEX_NONE &&
+					index != mesh.req_index) {
 		l_debug("Ignore index %d", index);
 		return;
 	}
@@ -219,145 +282,100 @@ static void read_index_list_cb(uint8_t status, uint16_t length,
 	}
 }
 
-static bool load_config(struct bt_mesh *mesh, const char *in_config_name)
+static bool init_mgmt(void)
 {
-	if (!mesh->net)
-		return false;
-
-	if (!storage_parse_config(mesh->net, in_config_name))
+	mgmt_mesh = mgmt_new_default();
+	if (!mgmt_mesh)
 		return false;
 
-	/* Register foundational models */
-	mesh_config_srv_init(mesh->net, PRIMARY_ELE_IDX);
-
-	return true;
-}
-
-static bool init_mesh(void)
-{
-	if (initialized)
-		return true;
-
 	controllers = l_queue_new();
 	if (!controllers)
 		return false;
 
-	mesh_list = l_queue_new();
-	if (!mesh_list)
-		return false;
-
-	mgmt_mesh = mgmt_new_default();
-	if (!mgmt_mesh)
-		goto fail;
-
 	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);
-
-	initialized = true;
 	return true;
-
-fail:
-	l_error("Failed to initialize mesh management");
-
-	l_queue_destroy(controllers, NULL);
-
-	return false;
 }
 
-struct bt_mesh *mesh_new(uint16_t index, const char *config_file)
+bool mesh_init(uint16_t index, const char *config_dir)
 {
-	struct bt_mesh *mesh;
+	if (initialized)
+		return true;
+
+	if (!init_mgmt()) {
+		l_error("Failed to initialize mesh management");
+		return false;
+	}
 
-	if (!init_mesh())
-		return NULL;
+	mesh.req_index = index;
 
-	mesh = l_new(struct bt_mesh, 1);
-	if (!mesh)
-		return NULL;
+	mesh_model_init();
+	mesh_agent_init();
 
-	mesh->req_index = index;
-	mesh->index = MGMT_INDEX_NONE;
+	/* TODO: read mesh.conf */
+	mesh.prov_timeout = DEFAULT_PROV_TIMEOUT;
+	mesh.algorithms = DEFAULT_ALGORITHMS;
 
-	mesh->net = mesh_net_new(index);
-	if (!mesh->net) {
-		l_free(mesh);
-		return NULL;
-	}
+	if (!config_dir)
+		config_dir = MESH_STORAGEDIR;
 
-	if (!load_config(mesh, config_file)) {
-		l_error("Failed to load mesh configuration: %s", config_file);
-		l_free(mesh);
-		return NULL;
-	}
+	l_info("Loading node configuration from %s", config_dir);
+
+	if (!storage_load_nodes(config_dir))
+		return false;
 
-	/*
-	 * TODO: Check if another mesh is searching for io.
-	 * If so, add to pending list and return.
-	 */
 	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, mesh, NULL) > 0) {
-		current = mesh;
-		l_queue_push_tail(mesh_list, mesh);
-		return mesh_ref(mesh);
-	}
-
-	l_free(mesh);
+				read_index_list_cb, NULL, NULL) <= 0)
+		return false;
 
-	return NULL;
+	return true;
 }
 
-struct bt_mesh *mesh_ref(struct bt_mesh *mesh)
+static void attach_exit(void *data)
 {
-	if (!mesh)
-		return NULL;
-
-	__sync_fetch_and_add(&mesh->ref_count, 1);
+	struct l_dbus_message *reply;
+	struct attach_data *pending = data;
 
-	return mesh;
+	reply = dbus_error(pending->msg, MESH_ERROR_FAILED, "Failed. Exiting");
+	l_dbus_send(dbus_get_bus(), reply);
+	l_free(pending);
 }
 
-void mesh_unref(struct bt_mesh *mesh)
+void mesh_cleanup(void)
 {
-	struct mesh_io *io;
+	struct l_dbus_message *reply;
 
-	if (!mesh)
-		return;
+	mesh_io_destroy(mesh.io);
+	mgmt_unref(mgmt_mesh);
 
-	if (__sync_sub_and_fetch(&mesh->ref_count, 1))
-		return;
+	if (join_pending) {
+		reply = dbus_error(join_pending->msg, MESH_ERROR_FAILED,
+							"Failed. Exiting");
+		l_dbus_send(dbus_get_bus(), reply);
 
-	if (mesh_net_provisioned_get(mesh->net))
-		save_exit_config(mesh);
+		if (join_pending->disc_watch)
+			l_dbus_remove_watch(dbus_get_bus(),
+						join_pending->disc_watch);
 
-	node_cleanup(mesh->net);
+		if (join_pending->node)
+			node_free(join_pending->node);
 
-	storage_release(mesh->net);
-	io = mesh_net_detach(mesh->net);
-	if (io)
-		mesh_io_destroy(io);
+		l_free(join_pending);
+		join_pending = NULL;
+	}
 
-	mesh_net_unref(mesh->net);
-	l_queue_remove(mesh_list, mesh);
-	l_free(mesh);
-}
+	l_queue_destroy(attach_queue, attach_exit);
+	node_cleanup_all();
+	mesh_model_cleanup();
 
-void mesh_cleanup(void)
-{
 	l_queue_destroy(controllers, NULL);
-	l_queue_destroy(mesh_list, NULL);
-	mgmt_unref(mgmt_mesh);
-}
-
-bool mesh_set_output(struct bt_mesh *mesh, const char *config_name)
-{
-	if (!config_name)
-		return false;
-
-	return mesh_net_cfg_file_set(mesh->net, config_name);
+	l_dbus_object_remove_interface(dbus_get_bus(), BLUEZ_MESH_PATH,
+							MESH_NETWORK_INTERFACE);
+	l_dbus_unregister_interface(dbus_get_bus(), MESH_NETWORK_INTERFACE);
 }
 
 const char *mesh_status_str(uint8_t err)
@@ -386,7 +404,333 @@ const char *mesh_status_str(uint8_t err)
 	}
 }
 
-struct mesh_net *mesh_get_net(struct bt_mesh *mesh)
+static void free_pending_join_call(bool failed)
+{
+	if (!join_pending)
+		return;
+
+	if (join_pending->disc_watch)
+		l_dbus_remove_watch(dbus_get_bus(),
+						join_pending->disc_watch);
+
+	mesh_agent_remove(join_pending->agent);
+
+	if (failed) {
+		storage_remove_node_config(join_pending->node);
+		mesh_agent_remove(join_pending->agent);
+	}
+
+	l_free(join_pending);
+	join_pending = NULL;
+}
+
+/* This is being called if the app exits unexpectedly */
+static void prov_disc_cb(struct l_dbus *bus, void *user_data)
+{
+	if (!join_pending)
+		return;
+
+	if (join_pending->msg)
+		l_dbus_message_unref(join_pending->msg);
+
+	acceptor_cancel(&mesh);
+
+	join_pending->disc_watch = 0;
+
+	free_pending_join_call(true);
+}
+
+static const char *prov_status_str(uint8_t status)
+{
+	switch (status) {
+	case PROV_ERR_SUCCESS:
+		return "success";
+	case PROV_ERR_INVALID_PDU:
+	case PROV_ERR_INVALID_FORMAT:
+	case PROV_ERR_UNEXPECTED_PDU:
+		return "bad-pdu";
+	case PROV_ERR_CONFIRM_FAILED:
+		return "confirmation-failed";
+	case PROV_ERR_INSUF_RESOURCE:
+		return "out-of-resources";
+	case PROV_ERR_DECRYPT_FAILED:
+		return "decryption-error";
+	case PROV_ERR_CANT_ASSIGN_ADDR:
+		return "cannot-assign-addresses";
+	case PROV_ERR_TIMEOUT:
+		return "timeout";
+	case PROV_ERR_UNEXPECTED_ERR:
+	default:
+		return "unexpected-error";
+	}
+}
+
+static void send_join_failed(const char *owner, const char *path,
+							uint8_t status)
+{
+	struct l_dbus_message *msg;
+	struct l_dbus *dbus = dbus_get_bus();
+
+	msg = l_dbus_message_new_method_call(dbus, owner, path,
+						MESH_APPLICATION_INTERFACE,
+						"JoinFailed");
+
+	l_dbus_message_set_arguments(msg, "s", prov_status_str(status));
+	l_dbus_send(dbus_get_bus(), msg);
+
+	free_pending_join_call(true);
+}
+
+static bool prov_complete_cb(void *user_data, uint8_t status,
+					struct mesh_prov_node_info *info)
+{
+	struct l_dbus *dbus = dbus_get_bus();
+	struct l_dbus_message *msg;
+	const char *owner;
+	const char *path;
+	const uint8_t *dev_key;
+
+	l_debug("Provisioning complete %s", prov_status_str(status));
+
+	if (!join_pending)
+		return false;
+
+	owner = join_pending->sender;
+	path = join_pending->app_path;
+
+	if (status == PROV_ERR_SUCCESS &&
+	    !node_add_pending_local(join_pending->node, info, mesh.io))
+		status = PROV_ERR_UNEXPECTED_ERR;
+
+	if (status != PROV_ERR_SUCCESS) {
+		send_join_failed(owner, path, status);
+		return false;
+	}
+
+	dev_key = node_get_device_key(join_pending->node);
+
+	msg = l_dbus_message_new_method_call(dbus, owner, path,
+						MESH_APPLICATION_INTERFACE,
+						"JoinComplete");
+
+	l_dbus_message_set_arguments(msg, "t", l_get_u64(dev_key));
+
+	l_dbus_send(dbus_get_bus(), msg);
+
+	free_pending_join_call(false);
+
+	return true;
+}
+
+static void node_init_cb(struct mesh_node *node, struct mesh_agent *agent)
+{
+	struct l_dbus_message *reply;
+	uint8_t num_ele;
+
+	if (!node) {
+		reply = dbus_error(join_pending->msg, MESH_ERROR_FAILED,
+				"Failed to create node from application");
+		goto fail;
+	}
+
+	join_pending->node = node;
+	num_ele = node_get_num_elements(node);
+
+	if (!acceptor_start(num_ele, join_pending->uuid, mesh.algorithms,
+				mesh.prov_timeout, agent, prov_complete_cb,
+				&mesh))
+	{
+		reply = dbus_error(join_pending->msg, MESH_ERROR_FAILED,
+				"Failed to start provisioning acceptor");
+		goto fail;
+	}
+
+	reply = l_dbus_message_new_method_return(join_pending->msg);
+	l_dbus_send(dbus_get_bus(), reply);
+	join_pending->msg = NULL;
+
+	return;
+
+fail:
+	l_dbus_send(dbus_get_bus(), reply);
+	mesh_agent_remove(join_pending->agent);
+	l_free(join_pending);
+	join_pending = NULL;
+}
+
+static struct l_dbus_message *join_network_call(struct l_dbus *dbus,
+						struct l_dbus_message *msg,
+						void *user_data)
 {
-	return mesh->net;
+	const char *app_path, *sender;
+	struct l_dbus_message_iter iter_uuid;
+	uint32_t n;
+
+	l_debug("Join network request");
+
+	if (join_pending)
+		return dbus_error(msg, MESH_ERROR_BUSY,
+						"Provisioning in progress");
+
+	if (!l_dbus_message_get_arguments(msg, "oay", &app_path,
+								&iter_uuid))
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	join_pending = l_new(struct join_data, 1);
+
+	l_dbus_message_iter_get_fixed_array(&iter_uuid, join_pending->uuid, &n);
+
+	if (n != 16) {
+		l_free(join_pending);
+		join_pending = NULL;
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
+							"Bad device UUID");
+	}
+
+	sender = l_dbus_message_get_sender(msg);
+
+	join_pending->sender = l_strdup(sender);
+	join_pending->disc_watch = l_dbus_add_disconnect_watch(dbus, sender,
+						prov_disc_cb, NULL, NULL);
+	join_pending->msg = l_dbus_message_ref(msg);
+	join_pending->app_path = app_path;
+
+	/* Try to create a temporary node */
+	node_join(app_path, sender, join_pending->uuid, node_init_cb);
+
+	return NULL;
+}
+
+static struct l_dbus_message *cancel_join_call(struct l_dbus *dbus,
+						struct l_dbus_message *msg,
+						void *user_data)
+{
+	struct l_dbus_message *reply;
+
+	l_debug("Cancel Join");
+
+	if (!join_pending) {
+		reply = dbus_error(msg, MESH_ERROR_DOES_NOT_EXIST,
+							"No join in progress");
+		goto done;
+	}
+
+	acceptor_cancel(&mesh);
+
+	/* Return error to the original Join call */
+	if (join_pending->msg) {
+		reply = dbus_error(join_pending->msg, MESH_ERROR_FAILED, NULL);
+		l_dbus_send(dbus_get_bus(), reply);
+	}
+
+	reply = l_dbus_message_new_method_return(msg);
+	l_dbus_message_set_arguments(reply, "");
+
+	free_pending_join_call(true);
+done:
+	return reply;
+}
+
+static bool match_attach_request(const void *a, const void *b)
+{
+	const struct attach_data *pending = a;
+	const uint64_t *token = b;
+
+	return *token == pending->token;
+}
+
+static void attach_ready_cb(int status, char *node_path, uint64_t token)
+{
+	struct l_dbus_message *reply;
+	struct attach_data *pending;
+
+	pending = l_queue_find(attach_queue, match_attach_request, &token);
+	if (!pending)
+		return;
+
+	if (status != MESH_ERROR_NONE) {
+		const char *desc = (status == MESH_ERROR_NOT_FOUND) ?
+				"Node match not found" : "Attach failed";
+		reply = dbus_error(pending->msg, status, desc);
+		goto done;
+	}
+
+	reply = l_dbus_message_new_method_return(pending->msg);
+
+	node_build_attach_reply(reply, token);
+
+done:
+	l_dbus_send(dbus_get_bus(), reply);
+	l_queue_remove(attach_queue, pending);
+	l_free(pending);
+}
+
+static struct l_dbus_message *attach_call(struct l_dbus *dbus,
+						struct l_dbus_message *msg,
+						void *user_data)
+{
+	uint64_t token = 1;
+	const char *app_path, *sender;
+	struct attach_data *pending;
+
+	l_debug("Attach");
+
+	if (!l_dbus_message_get_arguments(msg, "ot", &app_path, &token))
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	sender = l_dbus_message_get_sender(msg);
+
+	if (node_attach(app_path, sender, token, attach_ready_cb) !=
+								MESH_ERROR_NONE)
+		return dbus_error(msg, MESH_ERROR_NOT_FOUND,
+						"Matching node not found");
+
+	pending = l_new(struct attach_data, 1);
+
+	pending->token = token;
+	pending->msg = l_dbus_message_ref(msg);
+
+	if (!attach_queue)
+		attach_queue = l_queue_new();
+
+	l_queue_push_tail(attach_queue, pending);
+
+	return NULL;
+}
+
+static void setup_network_interface(struct l_dbus_interface *iface)
+{
+	l_dbus_interface_method(iface, "Join", 0, join_network_call, "",
+				"oay", "app", "uuid");
+
+	l_dbus_interface_method(iface, "Cancel", 0, cancel_join_call, "", "");
+
+	l_dbus_interface_method(iface, "Attach", 0, attach_call,
+				"oa(ya(qa{sv}))", "ot", "node", "configuration",
+				"app", "token");
+
+	/* TODO: Implement Leave method */
+}
+
+bool mesh_dbus_init(struct l_dbus *dbus)
+{
+	if (!l_dbus_register_interface(dbus, MESH_NETWORK_INTERFACE,
+						setup_network_interface,
+						NULL, false)) {
+		l_info("Unable to register %s interface",
+			       MESH_NETWORK_INTERFACE);
+		return false;
+	}
+
+	if (!l_dbus_object_add_interface(dbus, BLUEZ_MESH_PATH,
+						MESH_NETWORK_INTERFACE, NULL)) {
+		l_info("Unable to register the mesh object on '%s'",
+							MESH_NETWORK_INTERFACE);
+		l_dbus_unregister_interface(dbus, MESH_NETWORK_INTERFACE);
+		return false;
+	}
+
+	l_info("Added Network Interface on %s", BLUEZ_MESH_PATH);
+
+	return true;
 }
diff --git a/mesh/mesh.h b/mesh/mesh.h
index 8d389883b..ff4e04fa1 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -15,18 +15,26 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  *  Lesser General Public License for more details.
  *
- *
  */
 
-struct bt_mesh;
-struct mesh_net;
+#define BLUEZ_MESH_NAME "org.bluez.mesh"
+
+#define MESH_NETWORK_INTERFACE "org.bluez.mesh.Network1"
+#define MESH_NODE_INTERFACE "org.bluez.mesh.Node1"
+#define MESH_ELEMENT_INTERFACE "org.bluez.mesh.Element1"
+#define MESH_APPLICATION_INTERFACE "org.bluez.mesh.Application1"
+#define MESH_PROVISION_AGENT_INTERFACE "org.bluez.mesh.ProvisionAgent1"
+#define ERROR_INTERFACE "org.bluez.mesh.Error"
 
-struct bt_mesh *mesh_new(uint16_t index, const char *in_config_name);
-struct bt_mesh *mesh_ref(struct bt_mesh *mesh);
-void mesh_unref(struct bt_mesh *mesh);
-bool mesh_set_output(struct bt_mesh *mesh, const char *out_config_name);
+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);
 void mesh_cleanup(void);
-const char *mesh_status_str(uint8_t err);
+bool mesh_dbus_init(struct l_dbus *dbus);
 
-/* Command line testing */
-struct mesh_net *mesh_get_net(struct bt_mesh *mesh);
+const char *mesh_status_str(uint8_t err);
+bool mesh_send_pkt(uint8_t count, uint16_t interval, uint8_t *data,
+								uint16_t len);
+bool mesh_send_cancel(const uint8_t *filter, uint8_t len);
+bool mesh_reg_prov_rx(prov_rx_cb_t cb, void *user_data);
+void mesh_unreg_prov_rx(prov_rx_cb_t cb);
-- 
2.14.5


  parent reply	other threads:[~2018-12-28 22:08 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-28 22:07 [PATCH BlueZ v6 00/26] Major rewrite for Multi-Node and DBus Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 01/26] mesh: Structural changes for mesh Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 02/26] mesh: Utilities for DBus support Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 03/26] mesh: Internal errors Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 04/26] mesh: Rewrite storage for Multiple Nodes Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 05/26] mesh: Rewrite Node handling for multiple nodes Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 06/26] mesh: Rewrite Network layer " Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 07/26] mesh: Direction agnostic PB-ADV implementation Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 08/26] mesh: Acceptor side provisioning implementation Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 09/26] mesh: Initiator " Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 10/26] mesh: Rewrite Controler interface for full init Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 11/26] mesh: Unchanged variables set to const Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 12/26] mesh: Hex-String manipulation, and debug logging Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 13/26] mesh: re-arrange provisioning for DBus API Brian Gix
2018-12-28 22:07 ` Brian Gix [this message]
2018-12-28 22:07 ` [PATCH BlueZ v6 15/26] mesh: Multi node Config Server model Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 16/26] mesh: restructure I/O for multiple nodes Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 17/26] mesh: Restructure DB to support " Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 18/26] mesh: Restructure model services for " Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 19/26] mesh: DBUS interface for Provisioning Agent Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 20/26] mesh: restructure App Key storage Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 21/26] mesh: Clean-up Comment style Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 22/26] mesh: Update for DBus API and multi-node support Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 23/26] mesh: Add default location for Mesh Node storage Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 24/26] mesh: Sample Provisioning Agent Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 25/26] mesh: Sample On/Off Client and Server Brian Gix
2018-12-28 22:07 ` [PATCH BlueZ v6 26/26] mesh: Sample Mesh Joiner (provision acceptor) Brian Gix

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181228220745.25147-15-brian.gix@intel.com \
    --to=brian.gix@intel.com \
    --cc=inga.stotland@intel.com \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).