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 v5 15/30] mesh: Re-architect for DBus API
Date: Tue, 18 Dec 2018 20:20:01 -0800 [thread overview]
Message-ID: <20181219042016.25538-16-brian.gix@intel.com> (raw)
In-Reply-To: <20181219042016.25538-1-brian.gix@intel.com>
From: Inga Stotland <inga.stotland@intel.com>
---
mesh/mesh.c | 624 ++++++++++++++++++++++++++++++++++++++++++++++--------------
mesh/mesh.h | 27 ++-
2 files changed, 502 insertions(+), 149 deletions(-)
diff --git a/mesh/mesh.c b/mesh/mesh.c
index d1d409672..9ab8d3bf1 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -23,7 +23,6 @@
#endif
#define _GNU_SOURCE
-#include <time.h>
#include <ell/ell.h>
#include "lib/bluetooth.h"
@@ -31,14 +30,25 @@
#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);
+}
+
+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;
- mesh_net_attach(mesh->net, io);
- mesh_net_set_window_accuracy(mesh->net, caps.window_accuracy);
- mesh->io = io;
- mesh->index = index;
+ mesh.prov_rx = cb;
+ mesh.prov_data = user_data;
- current = NULL;
+ 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;
- l_debug("Started mesh (io %p) on hci %u", mesh->io, index);
+ 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_mesh())
- return NULL;
+ if (!init_mgmt()) {
+ l_error("Failed to initialize mesh management");
+ return false;
+ }
- mesh = l_new(struct bt_mesh, 1);
- if (!mesh)
- return NULL;
+ mesh.req_index = index;
- mesh->req_index = index;
- mesh->index = MGMT_INDEX_NONE;
+ mesh_model_init();
+ mesh_agent_init();
- mesh->net = mesh_net_new(index);
- if (!mesh->net) {
- l_free(mesh);
- return NULL;
- }
+ /* TODO: read mesh.conf */
+ mesh.prov_timeout = DEFAULT_PROV_TIMEOUT;
+ mesh.algorithms = DEFAULT_ALGORITHMS;
- if (!load_config(mesh, config_file)) {
- l_error("Failed to load mesh configuration: %s", config_file);
- l_free(mesh);
- return NULL;
- }
+ if (!config_dir)
+ config_dir = MESH_STORAGEDIR;
+
+ 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;
+ struct l_dbus_message *reply;
+ struct attach_data *pending = data;
- __sync_fetch_and_add(&mesh->ref_count, 1);
-
- 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)
{
- return mesh->net;
+ 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)
+{
+ 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..1189f8276 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -18,15 +18,24 @@
*
*/
-struct bt_mesh;
-struct mesh_net;
+#define BLUEZ_MESH_NAME "org.bluez.mesh"
-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);
+#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"
+
+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
next prev parent reply other threads:[~2018-12-19 4:21 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-19 4:19 [PATCH BlueZ v5 00/30] Major rewrite for Multi-Node and DBus Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 01/30] mesh: Staging for Mesh DBus API rewrite Brian Gix
2018-12-24 20:56 ` Marcel Holtmann
2018-12-19 4:19 ` [PATCH BlueZ v5 02/30] mesh: Delete obsolete files Brian Gix
2018-12-24 20:57 ` Marcel Holtmann
2018-12-19 4:19 ` [PATCH BlueZ v5 03/30] mesh: Utilities for DBus support Brian Gix
2018-12-24 21:01 ` Marcel Holtmann
2018-12-19 4:19 ` [PATCH BlueZ v5 04/30] mesh: Internal errors Brian Gix
2018-12-24 21:03 ` Marcel Holtmann
2018-12-19 4:19 ` [PATCH BlueZ v5 05/30] mesh: Rewrite storage for Multiple Nodes Brian Gix
2018-12-24 21:05 ` Marcel Holtmann
2018-12-19 4:19 ` [PATCH BlueZ v5 06/30] mesh: Rewrite Node handling for multiple nodes Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 07/30] mesh: Rewrite Network layer " Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 08/30] mesh: Direction agnostic PB-Adv implementation Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 09/30] mesh: Acceptor side provisioning implementation Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 10/30] mesh: Initiator " Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 11/30] mesh: Rewrite Controler interface for full init Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 12/30] mesh: Unchanged variables set to const Brian Gix
2018-12-19 4:19 ` [PATCH BlueZ v5 13/30] mesh: centralize generic utilities Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 14/30] mesh: re-arrange provisioning for DBus API Brian Gix
2018-12-19 4:20 ` Brian Gix [this message]
2018-12-19 4:20 ` [PATCH BlueZ v5 16/30] mesh: Make config model handle multiple nodes Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 18/30] mesh: restructure I/O for " Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 19/30] mesh: Restructure DB to support " Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 20/30] mesh: restructure model services for " Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 21/30] mesh: DBUS interface for Provisioning Agent Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 22/30] mesh: restructure App Key storage Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 23/30] mesh: Clean-up Comment style Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 24/30] mesh: Update for DBus API and multi-node support Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 25/30] mesh: Add default location for Mesh Node storage Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 26/30] mesh: Add structural changes for mesh Brian Gix
2018-12-19 4:20 ` [PATCH BlueZ v5 27/30] mesh: Sample Provisioning Agent Brian Gix
2018-12-24 21:09 ` Marcel Holtmann
2018-12-27 19:22 ` Gix, Brian
2018-12-19 4:20 ` [PATCH BlueZ v5 28/30] mesh: Sample On/Off Client and Server Brian Gix
2018-12-24 21:10 ` Marcel Holtmann
2018-12-19 4:20 ` [PATCH BlueZ v5 30/30] mesh: Enable building Mesh Daemon Brian Gix
2018-12-24 21:12 ` Marcel Holtmann
2018-12-23 17:54 ` [PATCH BlueZ v5 00/30] Major rewrite for Multi-Node and DBus Gix, Brian
[not found] ` <20181219042016.25538-30-brian.gix@intel.com>
2018-12-24 21:10 ` [PATCH BlueZ v5 29/30] mesh: Sample Mesh Joiner (provision acceptor) Marcel Holtmann
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=20181219042016.25538-16-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.