From: Brian Gix <brian.gix@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: brian.gix@intel.com, inga.stotland@intel.com
Subject: [PATCH 3/7] mesh: Add common MGMT command accessors
Date: Wed, 23 Feb 2022 18:06:20 -0800 [thread overview]
Message-ID: <20220224020624.159247-4-brian.gix@intel.com> (raw)
In-Reply-To: <20220224020624.159247-1-brian.gix@intel.com>
While mesh-io-mgmt is the main consumer of MGMT services, we also use
MGMT to identify controllers and their capabilities, when determining
the appropriate Mesh IO carrier. This centralizes all MGMT access to
a single socket, shared accross all consumers.
Also fixes the Controller added/removed handling so that a controller
disappearing or reappearing gets handled rationally.
---
mesh/mesh-mgmt.c | 149 ++++++++++++++++++++++++++++++++++++-----------
mesh/mesh-mgmt.h | 12 +++-
2 files changed, 125 insertions(+), 36 deletions(-)
diff --git a/mesh/mesh-mgmt.c b/mesh/mesh-mgmt.c
index 754093dbc..e878a4f11 100644
--- a/mesh/mesh-mgmt.c
+++ b/mesh/mesh-mgmt.c
@@ -12,35 +12,63 @@
#include <config.h>
#endif
+#include <ell/ell.h>
+
#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;
+struct mesh_controler {
+ int index;
+ bool mesh_support;
+ bool powered;
};
+static mesh_mgmt_read_info_func_t ctl_info;
static struct mgmt *mgmt_mesh;
-static struct l_queue *read_info_regs;
+static struct l_queue *ctl_list;
+static void *list_user_data;
+static bool mesh_detected;
+
+static bool by_index(const void *a, const void *b)
+{
+ const struct mesh_controler *ctl = a;
+ int index = L_PTR_TO_UINT(b);
-static void process_read_info_req(void *data, void *user_data)
+ return ctl->index == index;
+}
+
+static void index_removed(uint16_t index, uint16_t length, const void *param,
+ void *user_data);
+static void features_cb(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
{
- struct read_info_reg *reg = data;
int index = L_PTR_TO_UINT(user_data);
+ struct mesh_controler *ctl;
+
- reg->cb(index, reg->user_data);
+ ctl = l_queue_find(ctl_list, by_index, L_UINT_TO_PTR(index));
+ if (!ctl)
+ return;
+
+ l_debug("Status: %d, Length: %d", status, length);
+ if (status != MGMT_STATUS_NOT_SUPPORTED &&
+ status != MGMT_STATUS_UNKNOWN_COMMAND) {
+ ctl->mesh_support = true;
+ if (!mesh_detected) {
+ mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED,
+ MGMT_INDEX_NONE, index_removed,
+ NULL, NULL);
+ }
+ mesh_detected = true;
+ } else
+ l_debug("Kernel mesh not supported for hci%u", index);
+
+ if (ctl_info)
+ ctl_info(index, true, ctl->powered, ctl->mesh_support,
+ list_user_data);
}
static void read_info_cb(uint8_t status, uint16_t length,
@@ -49,12 +77,25 @@ static void read_info_cb(uint8_t status, uint16_t length,
int index = L_PTR_TO_UINT(user_data);
const struct mgmt_rp_read_info *rp = param;
uint32_t current_settings, supported_settings;
+ struct mesh_controler *ctl;
l_debug("hci %u status 0x%02x", index, status);
+ ctl = l_queue_find(ctl_list, by_index, L_UINT_TO_PTR(index));
+ if (!ctl)
+ return;
+
if (status != MGMT_STATUS_SUCCESS) {
+ ctl = l_queue_remove_if(ctl_list, by_index,
+ L_UINT_TO_PTR(index));
l_error("Failed to read info for hci index %u: %s (0x%02x)",
index, mgmt_errstr(status), status);
+
+ l_warn("Hci dev %d removal detected", index);
+ if (ctl && ctl_info)
+ ctl_info(index, false, false, false, list_user_data);
+
+ l_free(ctl);
return;
}
@@ -69,23 +110,34 @@ static void read_info_cb(uint8_t status, uint16_t length,
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);
+ l_queue_remove(ctl_list, ctl);
+ l_free(ctl);
return;
}
- l_queue_foreach(read_info_regs, process_read_info_req,
- L_UINT_TO_PTR(index));
+ if (current_settings & MGMT_SETTING_POWERED)
+ ctl->powered = true;
+
+ mesh_mgmt_send(MGMT_OP_MESH_READ_FEATURES, index, 0, NULL,
+ features_cb, L_UINT_TO_PTR(index), NULL);
}
static void index_added(uint16_t index, uint16_t length, const void *param,
void *user_data)
{
+ struct mesh_controler *ctl = l_queue_find(ctl_list, by_index,
+ L_UINT_TO_PTR(index));
+
+ if (!ctl) {
+ ctl = l_new(struct mesh_controler, 1);
+ ctl->index = index;
+ l_queue_push_head(ctl_list, ctl);
+ } else {
+ ctl->mesh_support = ctl->powered = false;
+ }
+
mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
read_info_cb, L_UINT_TO_PTR(index), NULL);
}
@@ -93,7 +145,9 @@ static void index_added(uint16_t index, uint16_t length, const void *param,
static void index_removed(uint16_t index, uint16_t length, const void *param,
void *user_data)
{
- l_warn("Hci dev %4.4x removed", index);
+ mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_cb, L_UINT_TO_PTR(index), NULL);
+
}
static void read_index_list_cb(uint8_t status, uint16_t length,
@@ -133,8 +187,8 @@ static void read_index_list_cb(uint8_t status, uint16_t length,
static bool mesh_mgmt_init(void)
{
- if (!read_info_regs)
- read_info_regs = l_queue_new();
+ if (!ctl_list)
+ ctl_list = l_queue_new();
if (!mgmt_mesh) {
mgmt_mesh = mgmt_new_default();
@@ -146,8 +200,6 @@ static bool mesh_mgmt_init(void)
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;
@@ -155,16 +207,11 @@ static bool mesh_mgmt_init(void)
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);
+ ctl_info = cb;
+ list_user_data = user_data;
/* Use MGMT to find a candidate controller */
l_debug("send read index_list");
@@ -175,3 +222,35 @@ bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data)
return true;
}
+
+void mesh_mgmt_destroy()
+{
+ mgmt_unref(mgmt_mesh);
+ mgmt_mesh = NULL;
+ ctl_info = NULL;
+ list_user_data = NULL;
+ l_queue_destroy(ctl_list, l_free);
+ ctl_list = NULL;
+}
+
+unsigned int mesh_mgmt_send(uint16_t opcode, uint16_t index,
+ uint16_t length, const void *param,
+ mgmt_request_func_t callback,
+ void *user_data, mgmt_destroy_func_t destroy)
+{
+ return mgmt_send_timeout(mgmt_mesh, opcode, index, length, param,
+ callback, user_data, destroy, 0);
+}
+
+unsigned int mesh_mgmt_register(uint16_t event, uint16_t index,
+ mgmt_notify_func_t callback,
+ void *user_data, mgmt_destroy_func_t destroy)
+{
+ return mgmt_register(mgmt_mesh, event, index, callback,
+ user_data, destroy);
+}
+
+bool mesh_mgmt_unregister(unsigned int id)
+{
+ return mgmt_unregister(mgmt_mesh, id);
+}
diff --git a/mesh/mesh-mgmt.h b/mesh/mesh-mgmt.h
index 90ac14e73..a3cd72faf 100644
--- a/mesh/mesh-mgmt.h
+++ b/mesh/mesh-mgmt.h
@@ -9,6 +9,16 @@
*/
#include <stdbool.h>
-typedef void (*mesh_mgmt_read_info_func_t)(int index, void *user_data);
+typedef void (*mesh_mgmt_read_info_func_t)(int index, bool added, bool powered,
+ bool mesh, void *user_data);
bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data);
+unsigned int mesh_mgmt_send(uint16_t opcode, uint16_t index,
+ uint16_t length, const void *param,
+ mgmt_request_func_t callback,
+ void *user_data, mgmt_destroy_func_t destroy);
+unsigned int mesh_mgmt_register(uint16_t event, uint16_t index,
+ mgmt_notify_func_t callback,
+ void *user_data, mgmt_destroy_func_t destroy);
+bool mesh_mgmt_unregister(unsigned int id);
+void mesh_mgmt_destroy(void);
--
2.35.1
next prev parent reply other threads:[~2022-02-24 2:06 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-24 2:06 [PATCH 0/7] Kernel based mesh functionality Brian Gix
2022-02-24 2:06 ` [PATCH 1/7] mgmt: Add support for Mesh in the kernel Brian Gix
2022-02-26 9:38 ` Kernel based mesh functionality bluez.test.bot
2022-02-24 2:06 ` [PATCH 2/7] mgmt: Mesh specific structures and defines Brian Gix
2022-02-24 2:06 ` Brian Gix [this message]
2022-02-24 2:06 ` [PATCH 4/7] mesh: rework Mesh-IO for multiple transports Brian Gix
2022-02-24 2:06 ` [PATCH 5/7] mesh: Added default "auto" to command line parsing Brian Gix
2022-02-24 2:06 ` [PATCH 6/7] mesh: Add new MGMT based IO transport Brian Gix
2022-02-24 2:06 ` [PATCH 7/7] mesh: Make Provisioning requests more IO compatible 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=20220224020624.159247-4-brian.gix@intel.com \
--to=brian.gix@intel.com \
--cc=inga.stotland@intel.com \
--cc=linux-bluetooth@vger.kernel.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.