Diff between d64f6c885580ef23eb28e53edf1a007bb3628804 and dcc46d4cee21a711e781e493ca50cf70b74bd020

Changed Files

File Additions Deletions Status
mesh/main.c +29 -13 modified
mesh/mesh-io-api.h +2 -1 modified
mesh/mesh-io-generic.c +36 -12 modified
mesh/mesh-io.c +3 -2 modified
mesh/mesh-io.h +5 -1 modified
mesh/mesh.c +28 -5 modified
mesh/mesh.h +4 -1 modified

Full Patch

diff --git a/mesh/main.c b/mesh/main.c
index 6ea210c..3c41acb 100644
--- a/mesh/main.c
+++ b/mesh/main.c
@@ -38,6 +38,9 @@
 #include "mesh/dbus.h"
 #include "mesh/mesh-io.h"
 
+static const char *config_dir;
+static int ctlr_index = MGMT_INDEX_NONE;
+
 static const struct option main_options[] = {
 	{ "index",	required_argument,	NULL, 'i' },
 	{ "config",	optional_argument,	NULL, 'c' },
@@ -69,16 +72,38 @@ static void do_debug(const char *str, void *user_data)
 	l_info("%s%s", prefix, str);
 }
 
+static void mesh_ready_callback(void *user_data, bool success)
+{
+	struct l_dbus *dbus = user_data;
+
+	if (!success) {
+		l_error("Failed to start mesh");
+		l_main_quit();
+		return;
+	}
+
+	if (!dbus_init(dbus)) {
+		l_error("Failed to initialize mesh D-Bus resources");
+		l_main_quit();
+	}
+}
+
 static void request_name_callback(struct l_dbus *dbus, bool success,
 					bool queued, void *user_data)
 {
 	l_info("Request name %s",
 		success ? "success": "failed");
 
-	if (success)
-		dbus_init(dbus);
-	else
+	if (!success) {
 		l_main_quit();
+		return;
+	}
+
+	if (!mesh_init(config_dir, MESH_IO_TYPE_GENERIC, &ctlr_index,
+					mesh_ready_callback, dbus)) {
+		l_error("Failed to initialize mesh");
+		l_main_quit();
+	}
 }
 
 static void ready_callback(void *user_data)
@@ -88,7 +113,6 @@ static void ready_callback(void *user_data)
 	l_info("D-Bus ready");
 	l_dbus_name_acquire(dbus, BLUEZ_MESH_NAME, false, false, false,
 						request_name_callback, NULL);
-
 }
 
 static void disconnect_callback(void *user_data)
@@ -114,8 +138,6 @@ int main(int argc, char *argv[])
 	bool detached = true;
 	bool dbus_debug = false;
 	struct l_dbus *dbus = NULL;
-	const char *config_dir = NULL;
-	int index = MGMT_INDEX_NONE;
 
 	if (!l_main_init())
 		return -1;
@@ -148,7 +170,7 @@ int main(int argc, char *argv[])
 				goto done;
 			}
 
-			index = atoi(str);
+			ctlr_index = atoi(str);
 
 			break;
 		case 'n':
@@ -175,12 +197,6 @@ int main(int argc, char *argv[])
 	}
 
 
-	if (!mesh_init(config_dir, MESH_IO_TYPE_GENERIC, &index)) {
-		l_error("Failed to initialize mesh");
-		status = EXIT_FAILURE;
-		goto done;
-	}
-
 	if (!detached)
 		umask(0077);
 
diff --git a/mesh/mesh-io-api.h b/mesh/mesh-io-api.h
index 4cdf1f8..75b8818 100644
--- a/mesh/mesh-io-api.h
+++ b/mesh/mesh-io-api.h
@@ -19,7 +19,8 @@
 
 struct mesh_io_private;
 
-typedef bool (*mesh_io_init_t)(struct mesh_io *io, void *opts);
+typedef bool (*mesh_io_init_t)(struct mesh_io *io, void *opts,
+				mesh_io_ready_func_t cb, void *user_data);
 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,
diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c
index 42bf64a..b42fb4f 100644
--- a/mesh/mesh-io-generic.c
+++ b/mesh/mesh-io-generic.c
@@ -37,14 +37,16 @@
 #include "mesh/mesh-io-generic.h"
 
 struct mesh_io_private {
-	uint16_t index;
 	struct bt_hci *hci;
+	void *user_data;
+	mesh_io_ready_func_t ready_callback;
 	struct l_timeout *tx_timeout;
 	struct l_queue *rx_regs;
 	struct l_queue *tx_pkts;
+	struct tx_pkt *tx;
 	uint8_t filters[4];
 	bool sending;
-	struct tx_pkt *tx;
+	uint16_t index;
 	uint16_t interval;
 };
 
@@ -283,22 +285,29 @@ static void configure_hci(struct mesh_io_private *io)
 				sizeof(cmd), hci_generic_callback, NULL, NULL);
 }
 
-static bool hci_init(struct mesh_io *io)
+static void hci_init(void *user_data)
 {
+	struct mesh_io *io = user_data;
+	bool result = true;
+
 	io->pvt->hci = bt_hci_new_user_channel(io->pvt->index);
 	if (!io->pvt->hci) {
 		l_error("Failed to start mesh io (hci %u): %s", io->pvt->index,
 							strerror(errno));
-		return false;
+		result = false;
 	}
 
-	configure_hci(io->pvt);
+	if (result) {
+		configure_hci(io->pvt);
 
-	bt_hci_register(io->pvt->hci, BT_HCI_EVT_LE_META_EVENT,
+		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;
+		l_debug("Started mesh on hci %u", io->pvt->index);
+	}
+
+	if (io->pvt->ready_callback)
+		io->pvt->ready_callback(io->pvt->user_data, result);
 }
 
 static void read_info(int index, void *user_data)
@@ -315,7 +324,8 @@ static void read_info(int index, void *user_data)
 	hci_init(io);
 }
 
-static bool dev_init(struct mesh_io *io, void *opts)
+static bool dev_init(struct mesh_io *io, void *opts,
+				mesh_io_ready_func_t cb, void *user_data)
 {
 	if (!io || io->pvt)
 		return false;
@@ -326,10 +336,15 @@ static bool dev_init(struct mesh_io *io, void *opts)
 	io->pvt->rx_regs = l_queue_new();
 	io->pvt->tx_pkts = l_queue_new();
 
+	io->pvt->ready_callback = cb;
+	io->pvt->user_data = user_data;
+
 	if (io->pvt->index == MGMT_INDEX_NONE)
 		return mesh_mgmt_list(read_info, io);
-	else
-		return hci_init(io);
+
+	l_idle_oneshot(hci_init, io, NULL);
+
+	return true;
 }
 
 static bool dev_destroy(struct mesh_io *io)
@@ -696,6 +711,15 @@ static bool find_by_filter_id(const void *a, const void *b)
 	return rx_reg->filter_id == filter_id;
 }
 
+static void scan_enable_rsp(const void *buf, uint8_t size,
+							void *user_data)
+{
+	uint8_t status = *((uint8_t *) buf);
+
+	if (status)
+		l_error("LE Scan enable failed (0x%02x)", status);
+}
+
 static void set_recv_scan_enable(const void *buf, uint8_t size,
 							void *user_data)
 {
@@ -705,7 +729,7 @@ static void set_recv_scan_enable(const void *buf, uint8_t size,
 	cmd.enable = 0x01;	/* Enable scanning */
 	cmd.filter_dup = 0x00;	/* Report duplicates */
 	bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
-			&cmd, sizeof(cmd), NULL, NULL, NULL);
+			&cmd, sizeof(cmd), scan_enable_rsp, pvt, NULL);
 }
 
 static bool recv_register(struct mesh_io *io, uint8_t filter_id,
diff --git a/mesh/mesh-io.c b/mesh/mesh-io.c
index 94a92e8..95a99b6 100644
--- a/mesh/mesh-io.c
+++ b/mesh/mesh-io.c
@@ -52,7 +52,8 @@ static bool match_by_type(const void *a, const void *b)
 	return io->type == type;
 }
 
-struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts)
+struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts,
+				mesh_io_ready_func_t cb, void *user_data)
 {
 	const struct mesh_io_api *api = NULL;
 	struct mesh_io *io;
@@ -78,7 +79,7 @@ struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts)
 	io->type = type;
 
 	io->api = api;
-	if (!api->init(io, opts))
+	if (!api->init(io, opts, cb, user_data))
 		goto fail;
 
 	if (!io_list)
diff --git a/mesh/mesh-io.h b/mesh/mesh-io.h
index 1c10779..45ff00a 100644
--- a/mesh/mesh-io.h
+++ b/mesh/mesh-io.h
@@ -81,7 +81,11 @@ 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(enum mesh_io_type type, void *opts);
+typedef void (*mesh_io_ready_func_t)(void *user_data, bool result);
+
+
+struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts,
+				mesh_io_ready_func_t cb, void *user_data);
 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.c b/mesh/mesh.c
index 9b2b207..55204da 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -70,6 +70,11 @@ struct join_data{
 	uint8_t *uuid;
 };
 
+struct mesh_init_request {
+	mesh_ready_func_t cb;
+	void *user_data;
+};
+
 static struct bt_mesh mesh;
 
 /* We allow only one outstanding Join request */
@@ -138,9 +143,23 @@ void mesh_unreg_prov_rx(prov_rx_cb_t cb)
 	mesh_io_deregister_recv_cb(mesh.io, MESH_IO_FILTER_PROV);
 }
 
-bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
+static void io_ready_callback(void *user_data, bool result)
+{
+	struct mesh_init_request *req = user_data;
+
+	if (result)
+		node_attach_io_all(mesh.io);
+
+	req->cb(req->user_data, result);
+
+	l_free(req);
+}
+
+bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts,
+					mesh_ready_func_t cb, void *user_data)
 {
 	struct mesh_io_caps caps;
+	struct mesh_init_request *req;
 
 	if (mesh.io)
 		return true;
@@ -159,16 +178,20 @@ bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
 	if (!node_load_from_storage(storage_dir))
 		return false;
 
-	mesh.io = mesh_io_new(type, opts);
-	if (!mesh.io)
+	req = l_new(struct mesh_init_request, 1);
+	req->cb = cb;
+	req->user_data = user_data;
+
+	mesh.io = mesh_io_new(type, opts, io_ready_callback, req);
+	if (!mesh.io) {
+		l_free(req);
 		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;
 }
 
diff --git a/mesh/mesh.h b/mesh/mesh.h
index e0a3e1b..c72632b 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -30,9 +30,12 @@
 
 enum mesh_io_type;
 
+typedef void (*mesh_ready_func_t)(void *user_data, bool success);
 typedef void (*prov_rx_cb_t)(void *user_data, const uint8_t *data,
 								uint16_t len);
-bool mesh_init(const char *in_config_name, enum mesh_io_type type, void *opts);
+
+bool mesh_init(const char *in_config_name, enum mesh_io_type type, void *opts,
+					mesh_ready_func_t cb, void *user_data);
 void mesh_cleanup(void);
 bool mesh_dbus_init(struct l_dbus *dbus);