summaryrefslogtreecommitdiff
path: root/mesh/mesh-io-generic.c
diff options
context:
space:
mode:
authorBrian Gix <brian.gix@intel.com>2018-12-14 13:58:26 -0800
committerBrian Gix <brian.gix@intel.com>2019-01-08 08:26:22 -0800
commitc42fd5bd6be940848b8c2104197fd549b5eeb7ff (patch)
tree3a1d290dc93c655e05d6ee268be30605348ceda1 /mesh/mesh-io-generic.c
parent37c060790950cb3a1c1243426dc9f1f63bb8a8ae (diff)
downloadbluez-c42fd5bd6be940848b8c2104197fd549b5eeb7ff.tar.gz
mesh: Rewrite Controler interface for full init
Functionaility has been added to allow a BT 4.0 or later controller to be used for Advertising based Mesh usage, regardless of how it was previously initialized.
Diffstat (limited to 'mesh/mesh-io-generic.c')
-rw-r--r--mesh/mesh-io-generic.c149
1 files changed, 138 insertions, 11 deletions
diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c
index 52514e280..48e47e7a4 100644
--- a/mesh/mesh-io-generic.c
+++ b/mesh/mesh-io-generic.c
@@ -30,7 +30,6 @@
#include "monitor/bt.h"
#include "src/shared/hci.h"
-#include "mesh/display.h"
#include "mesh/mesh-io.h"
#include "mesh/mesh-io-api.h"
@@ -177,6 +176,116 @@ static void event_callback(const void *buf, uint8_t size, void *user_data)
}
}
+static void local_commands_callback(const void *data, uint8_t size,
+ void *user_data)
+{
+ const struct bt_hci_rsp_read_local_commands *rsp = data;
+
+ if (rsp->status)
+ l_error("Failed to read local commands");
+}
+
+static void local_features_callback(const void *data, uint8_t size,
+ void *user_data)
+{
+ const struct bt_hci_rsp_read_local_features *rsp = data;
+
+ if (rsp->status)
+ l_error("Failed to read local features");
+}
+
+static void hci_generic_callback(const void *data, uint8_t size,
+ void *user_data)
+{
+ uint8_t status = l_get_u8(data);
+
+ if (status)
+ l_error("Failed to initialize HCI");
+}
+
+static void configure_hci(struct mesh_io_private *io)
+{
+ struct bt_hci_cmd_le_set_scan_parameters cmd;
+ struct bt_hci_cmd_set_event_mask cmd_sem;
+ struct bt_hci_cmd_le_set_event_mask cmd_slem;
+
+ /* Set scan parameters */
+ cmd.type = 0x00; /* Passive Scanning. No scanning PDUs shall be sent */
+ cmd.interval = 0x0030; /* Scan Interval = N * 0.625ms */
+ cmd.window = 0x0030; /* Scan Window = N * 0.625ms */
+ cmd.own_addr_type = 0x00; /* Public Device Address */
+ /* Accept all advertising packets except directed advertising packets
+ * not addressed to this device (default).
+ */
+ cmd.filter_policy = 0x00;
+
+ /* Set event mask
+ *
+ * Mask: 0x2000800002008890
+ * Disconnection Complete
+ * Encryption Change
+ * Read Remote Version Information Complete
+ * Hardware Error
+ * Data Buffer Overflow
+ * Encryption Key Refresh Complete
+ * LE Meta
+ */
+ cmd_sem.mask[0] = 0x90;
+ cmd_sem.mask[1] = 0x88;
+ cmd_sem.mask[2] = 0x00;
+ cmd_sem.mask[3] = 0x02;
+ cmd_sem.mask[4] = 0x00;
+ cmd_sem.mask[5] = 0x80;
+ cmd_sem.mask[6] = 0x00;
+ cmd_sem.mask[7] = 0x20;
+
+ /* Set LE event mask
+ *
+ * Mask: 0x000000000000087f
+ * LE Connection Complete
+ * LE Advertising Report
+ * LE Connection Update Complete
+ * LE Read Remote Used Features Complete
+ * LE Long Term Key Request
+ * LE Remote Connection Parameter Request
+ * LE Data Length Change
+ * LE PHY Update Complete
+ */
+ cmd_slem.mask[0] = 0x7f;
+ cmd_slem.mask[1] = 0x08;
+ cmd_slem.mask[2] = 0x00;
+ cmd_slem.mask[3] = 0x00;
+ cmd_slem.mask[4] = 0x00;
+ cmd_slem.mask[5] = 0x00;
+ cmd_slem.mask[6] = 0x00;
+ cmd_slem.mask[7] = 0x00;
+
+ /* 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);
+
+ /* Read local supported commands */
+ bt_hci_send(io->hci, BT_HCI_CMD_READ_LOCAL_COMMANDS, NULL, 0,
+ local_commands_callback, NULL, NULL);
+
+ /* Read local supported features */
+ bt_hci_send(io->hci, BT_HCI_CMD_READ_LOCAL_FEATURES, NULL, 0,
+ local_features_callback, NULL, NULL);
+
+ /* Set event mask */
+ bt_hci_send(io->hci, BT_HCI_CMD_SET_EVENT_MASK, &cmd_sem,
+ sizeof(cmd_sem), hci_generic_callback, NULL, NULL);
+
+ /* Set LE event mask */
+ bt_hci_send(io->hci, BT_HCI_CMD_LE_SET_EVENT_MASK, &cmd_slem,
+ sizeof(cmd_slem), hci_generic_callback, NULL, NULL);
+
+ /* Scan Params */
+ bt_hci_send(io->hci, BT_HCI_CMD_LE_SET_SCAN_PARAMETERS, &cmd,
+ sizeof(cmd), hci_generic_callback, NULL, NULL);
+}
+
static bool dev_init(uint16_t index, struct mesh_io *io)
{
struct mesh_io_private *tmp;
@@ -198,6 +307,8 @@ static bool dev_init(uint16_t index, struct mesh_io *io)
if (!tmp->hci)
goto fail;
+ configure_hci(tmp);
+
bt_hci_register(tmp->hci, BT_HCI_EVT_LE_META_EVENT,
event_callback, io, NULL);
@@ -480,7 +591,6 @@ static bool send_tx(struct mesh_io *io, struct mesh_io_send_info *info,
if (!info || !data || !len || len > sizeof(tx->pkt))
return false;
-
tx = l_new(struct tx_pkt, 1);
if (!tx)
return false;
@@ -524,7 +634,7 @@ static bool find_by_pattern(const void *a, const void *b)
return (!memcmp(tx->pkt, pattern->data, pattern->len));
}
-static bool tx_cancel(struct mesh_io *io, uint8_t *data, uint8_t len)
+static bool tx_cancel(struct mesh_io *io, const uint8_t *data, uint8_t len)
{
struct mesh_io_private *pvt = io->pvt;
struct tx_pkt *tx;
@@ -568,13 +678,25 @@ static bool find_by_filter_id(const void *a, const void *b)
return rx_reg->filter_id == filter_id;
}
+static void set_recv_scan_enable(const void *buf, uint8_t size,
+ void *user_data)
+{
+ struct mesh_io_private *pvt = user_data;
+ struct bt_hci_cmd_le_set_scan_enable cmd;
+
+ 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);
+}
+
static bool recv_register(struct mesh_io *io, uint8_t filter_id,
mesh_io_recv_func_t cb, void *user_data)
{
- struct bt_hci_cmd_le_set_scan_enable cmd;
+ struct bt_hci_cmd_le_set_scan_parameters cmd;
struct mesh_io_private *pvt = io->pvt;
struct pvt_rx_reg *rx_reg;
- bool scanning;
+ bool already_scanning;
l_info("%s %d", __func__, filter_id);
if (!cb || !filter_id || filter_id > sizeof(pvt->filters))
@@ -593,15 +715,20 @@ static bool recv_register(struct mesh_io *io, uint8_t filter_id,
rx_reg->cb = cb;
rx_reg->user_data = user_data;
- scanning = !l_queue_isempty(pvt->rx_regs);
+ already_scanning = !l_queue_isempty(pvt->rx_regs);
l_queue_push_head(pvt->rx_regs, rx_reg);
- if (!scanning) {
- 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);
+ if (!already_scanning) {
+ cmd.type = 0x00; /* Passive scanning */
+ cmd.interval = L_CPU_TO_LE16(0x0010); /* 10 ms */
+ cmd.window = L_CPU_TO_LE16(0x0010); /* 10 ms */
+ cmd.own_addr_type = 0x01; /* ADDR_TYPE_RANDOM */
+ cmd.filter_policy = 0x00; /* Accept all */
+
+ bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_PARAMETERS,
+ &cmd, sizeof(cmd),
+ set_recv_scan_enable, pvt, NULL);
}
return true;