From b685cb0419b8e559332a9317d066b1f1e7bf16b0 Mon Sep 17 00:00:00 2001 From: Abhay Agarwal Date: Mon, 15 Jun 2020 14:10:47 +0530 Subject: [PATCH] mesh: Add support for meshd to use RAW channel This patch adds an option to launch meshd with HCI RAW channel instead of HCI user channel. This will enable simultaneous operation of meshd with bluetoothd when HCI user channel can not be created due to non-availability of independent HCI controller. Change-Id: I484c478208376ad0e1f1bd8a7b648494ae3f71fb Signed-off-by: Abhay Agarwal --- mesh/bluetooth-mesh.service.in | 2 +- mesh/main.c | 25 ++++++++++++++++++++++-- mesh/mesh-io-generic.c | 35 ++++++++++++++++++++++++++++++++++ mesh/mesh-io.h | 7 +++++++ mesh/mesh-mgmt.c | 43 ++++++++++++++++++++++++++++++++++++++++++ mesh/mesh-mgmt.h | 4 ++++ 6 files changed, 113 insertions(+), 3 deletions(-) diff --git a/mesh/bluetooth-mesh.service.in b/mesh/bluetooth-mesh.service.in index c2585ef..0dded0a 100644 --- a/mesh/bluetooth-mesh.service.in +++ b/mesh/bluetooth-mesh.service.in @@ -6,7 +6,7 @@ User=network_fw Group=network_fw Type=dbus BusName=org.bluez.mesh -ExecStart=@pkglibexecdir@/bluetooth-meshd --nodetach --debug +ExecStart=@pkglibexecdir@/bluetooth-meshd --nodetach --debug --use_raw Capabilities=cap_net_admin,cap_net_bind_service,cap_dac_override=eip SecureBits=keep-caps SmackProcessLabel=System diff --git a/mesh/main.c b/mesh/main.c index f80fe2f..aecb8bf 100644 --- a/mesh/main.c +++ b/mesh/main.c @@ -41,6 +41,9 @@ static const char *config_dir; static const char *mesh_conf_fname; static enum mesh_io_type io_type; static void *io_opts; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +bool use_raw = false; +#endif static const struct option main_options[] = { { "io", required_argument, NULL, 'i' }, @@ -48,6 +51,9 @@ static const struct option main_options[] = { { "nodetach", no_argument, NULL, 'n' }, { "debug", no_argument, NULL, 'd' }, { "dbus-debug", no_argument, NULL, 'b' }, +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + { "use_raw", no_argument, NULL, 'r' }, +#endif { "help", no_argument, NULL, 'h' }, { } }; @@ -142,10 +148,16 @@ static void signal_handler(uint32_t signo, void *user_data) static bool parse_io(const char *optarg, enum mesh_io_type *type, void **opts) { if (strstr(optarg, "generic") == optarg) { +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + struct mesh_io_opts *m_io_opts = l_new(struct mesh_io_opts, 1); + int *index = &(m_io_opts->index); + m_io_opts->use_raw = use_raw; + *opts = m_io_opts; +#else int *index = l_new(int, 1); - - *type = MESH_IO_TYPE_GENERIC; *opts = index; +#endif + *type = MESH_IO_TYPE_GENERIC; optarg += strlen("generic"); if (!*optarg) { @@ -193,7 +205,11 @@ int main(int argc, char *argv[]) for (;;) { int opt; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + opt = getopt_long(argc, argv, "i:c:f:ndbhr", main_options, NULL); +#else opt = getopt_long(argc, argv, "i:c:f:ndbh", main_options, NULL); +#endif if (opt < 0) break; @@ -220,6 +236,11 @@ int main(int argc, char *argv[]) case 'b': dbus_debug = true; break; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + case 'r': + use_raw = true; + break; +#endif case 'h': usage(); status = EXIT_SUCCESS; diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c index 3ad1305..593d5a4 100644 --- a/mesh/mesh-io-generic.c +++ b/mesh/mesh-io-generic.c @@ -49,6 +49,9 @@ struct mesh_io_private { uint16_t interval; bool sending; bool active; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + bool use_raw; +#endif }; struct pvt_rx_reg { @@ -261,10 +264,18 @@ static void configure_hci(struct mesh_io_private *io) cmd_slem.mask[6] = 0x00; cmd_slem.mask[7] = 0x00; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + if (!(io->use_raw)) { + /* Reset Command in case of user channel */ + bt_hci_send(io->hci, BT_HCI_CMD_RESET, NULL, 0, hci_generic_callback, + NULL, NULL); + } +#else /* TODO: Move to suitable place. Set suitable masks */ /* Reset Command */ bt_hci_send(io->hci, BT_HCI_CMD_RESET, NULL, 0, hci_generic_callback, NULL, NULL); +#endif /* Read local supported commands */ bt_hci_send(io->hci, BT_HCI_CMD_READ_LOCAL_COMMANDS, NULL, 0, @@ -368,7 +379,24 @@ static void hci_init(void *user_data) bt_hci_unref(io->pvt->hci); } +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + if (io->pvt->use_raw) { + l_debug("Use HCI RAW channel"); + + /* Power up HCI device */ + uint16_t mode = 0x01; + if (!set_powered(mode, io->pvt->index)) + return; + + io->pvt->hci = bt_hci_new_raw_device(io->pvt->index); + } else { + l_debug("Use HCI USER channel"); + io->pvt->hci = bt_hci_new_user_channel(io->pvt->index); + } +#else io->pvt->hci = bt_hci_new_user_channel(io->pvt->index); +#endif + if (!io->pvt->hci) { l_error("Failed to start mesh io (hci %u): %s", io->pvt->index, strerror(errno)); @@ -412,7 +440,14 @@ static bool dev_init(struct mesh_io *io, void *opts, return false; io->pvt = l_new(struct mesh_io_private, 1); +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + struct mesh_io_opts *io_opts; + io_opts = (struct mesh_io_opts *)opts; + io->pvt->index = io_opts->index; + io->pvt->use_raw = io_opts->use_raw; +#else io->pvt->index = *(int *)opts; +#endif io->pvt->rx_regs = l_queue_new(); io->pvt->tx_pkts = l_queue_new(); diff --git a/mesh/mesh-io.h b/mesh/mesh-io.h index fc04220..8cf1fe4 100644 --- a/mesh/mesh-io.h +++ b/mesh/mesh-io.h @@ -39,6 +39,13 @@ struct mesh_io_recv_info { int8_t rssi; }; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +struct mesh_io_opts { + int index; + bool use_raw; +}; +#endif + struct mesh_io_send_info { enum mesh_io_timing_type type; union { diff --git a/mesh/mesh-mgmt.c b/mesh/mesh-mgmt.c index 2cf2eba..d0fabd8 100644 --- a/mesh/mesh-mgmt.c +++ b/mesh/mesh-mgmt.c @@ -52,6 +52,47 @@ static void process_read_info_req(void *data, void *user_data) reg->cb(index, reg->user_data); } +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +static void set_powered_complete(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + int index = L_PTR_TO_UINT(user_data); + uint32_t settings; + + if (status != MGMT_STATUS_SUCCESS) { + l_error("Failed to set powered: %s (0x%02x)", + mgmt_errstr(status), status); + return; + } + + settings = l_get_le32(param); + + if (!(settings & MGMT_SETTING_POWERED)) { + l_error("Controller is not powered"); + return; + } + + l_debug("set powered success on index %d", index); + /** update current settings of adapter */ +} + +bool set_powered(uint16_t mode, int index) +{ + struct mgmt_mode cp; + + memset(&cp, 0, sizeof(cp)); + cp.val = mode; + + /** check current settings of adapter */ + if (mgmt_send(mgmt_mesh, MGMT_OP_SET_POWERED, index, sizeof(cp), &cp, + set_powered_complete, L_UINT_TO_PTR(index), NULL) > 0) + + return true; + + return false; +} +#endif + static void read_info_cb(uint8_t status, uint16_t length, const void *param, void *user_data) { @@ -80,7 +121,9 @@ static void read_info_cb(uint8_t status, uint16_t length, if (current_settings & MGMT_SETTING_POWERED) { l_info("Controller hci %u is in use", index); +#ifndef TIZEN_FEATURE_BLUEZ_MODIFY return; +#endif } if (!(supported_settings & MGMT_SETTING_LE)) { diff --git a/mesh/mesh-mgmt.h b/mesh/mesh-mgmt.h index 93ad799..cf11347 100644 --- a/mesh/mesh-mgmt.h +++ b/mesh/mesh-mgmt.h @@ -21,3 +21,7 @@ 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); + +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +bool set_powered(uint16_t mode, int index); +#endif -- 2.7.4