3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2018-2019 Intel Corporation. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
29 #include "monitor/bt.h"
30 #include "src/shared/hci.h"
31 #include "lib/bluetooth.h"
34 #include "mesh/mesh-defs.h"
35 #include "mesh/mesh-mgmt.h"
36 #include "mesh/mesh-io.h"
37 #include "mesh/mesh-io-api.h"
38 #include "mesh/mesh-io-generic.h"
40 struct mesh_io_private {
43 mesh_io_ready_func_t ready_callback;
44 struct l_timeout *tx_timeout;
45 struct l_queue *rx_regs;
46 struct l_queue *tx_pkts;
52 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
58 mesh_io_recv_func_t cb;
65 struct mesh_io_private *pvt;
68 struct mesh_io_recv_info info;
72 struct mesh_io_send_info info;
83 static uint32_t get_instant(void)
88 gettimeofday(&tm, NULL);
89 instant = tm.tv_sec * 1000;
90 instant += tm.tv_usec / 1000;
95 static uint32_t instant_remaining_ms(uint32_t instant)
97 instant -= get_instant();
101 static void process_rx_callbacks(void *v_reg, void *v_rx)
103 struct pvt_rx_reg *rx_reg = v_reg;
104 struct process_data *rx = v_rx;
106 if (!memcmp(rx->data, rx_reg->filter, rx_reg->len))
107 rx_reg->cb(rx_reg->user_data, &rx->info, rx->data, rx->len);
110 static void process_rx(struct mesh_io_private *pvt, int8_t rssi,
111 uint32_t instant, const uint8_t *addr,
112 const uint8_t *data, uint8_t len)
114 struct process_data rx = {
118 .info.instant = instant,
124 l_queue_foreach(pvt->rx_regs, process_rx_callbacks, &rx);
127 static void event_adv_report(struct mesh_io *io, const void *buf, uint8_t size)
129 const struct bt_hci_evt_le_adv_report *evt = buf;
137 if (evt->event_type != 0x03)
140 instant = get_instant();
142 adv_len = evt->data_len;
145 /* rssi is just beyond last byte of data */
146 rssi = (int8_t) adv[adv_len];
148 while (len < adv_len - 1) {
149 uint8_t field_len = adv[0];
151 /* Check for the end of advertising data */
155 len += field_len + 1;
157 /* Do not continue data parsing if got incorrect length */
161 /* TODO: Create an Instant to use */
162 process_rx(io->pvt, rssi, instant, addr, adv + 1, adv[0]);
164 adv += field_len + 1;
168 static void event_callback(const void *buf, uint8_t size, void *user_data)
170 uint8_t event = l_get_u8(buf);
171 struct mesh_io *io = user_data;
174 case BT_HCI_EVT_LE_ADV_REPORT:
175 event_adv_report(io, buf + 1, size - 1);
179 l_info("Other Meta Evt - %d", event);
183 static void local_commands_callback(const void *data, uint8_t size,
186 const struct bt_hci_rsp_read_local_commands *rsp = data;
189 l_error("Failed to read local commands");
192 static void local_features_callback(const void *data, uint8_t size,
195 const struct bt_hci_rsp_read_local_features *rsp = data;
198 l_error("Failed to read local features");
201 static void hci_generic_callback(const void *data, uint8_t size,
204 uint8_t status = l_get_u8(data);
207 l_error("Failed to initialize HCI");
210 static void configure_hci(struct mesh_io_private *io)
212 struct bt_hci_cmd_le_set_scan_parameters cmd;
213 struct bt_hci_cmd_set_event_mask cmd_sem;
214 struct bt_hci_cmd_le_set_event_mask cmd_slem;
216 /* Set scan parameters */
217 cmd.type = 0x00; /* Passive Scanning. No scanning PDUs shall be sent */
218 cmd.interval = 0x0030; /* Scan Interval = N * 0.625ms */
219 cmd.window = 0x0030; /* Scan Window = N * 0.625ms */
220 cmd.own_addr_type = 0x00; /* Public Device Address */
221 /* Accept all advertising packets except directed advertising packets
222 * not addressed to this device (default).
224 cmd.filter_policy = 0x00;
228 * Mask: 0x2000800002008890
229 * Disconnection Complete
231 * Read Remote Version Information Complete
233 * Data Buffer Overflow
234 * Encryption Key Refresh Complete
237 cmd_sem.mask[0] = 0x90;
238 cmd_sem.mask[1] = 0x88;
239 cmd_sem.mask[2] = 0x00;
240 cmd_sem.mask[3] = 0x02;
241 cmd_sem.mask[4] = 0x00;
242 cmd_sem.mask[5] = 0x80;
243 cmd_sem.mask[6] = 0x00;
244 cmd_sem.mask[7] = 0x20;
248 * Mask: 0x000000000000087f
249 * LE Connection Complete
250 * LE Advertising Report
251 * LE Connection Update Complete
252 * LE Read Remote Used Features Complete
253 * LE Long Term Key Request
254 * LE Remote Connection Parameter Request
255 * LE Data Length Change
256 * LE PHY Update Complete
258 cmd_slem.mask[0] = 0x7f;
259 cmd_slem.mask[1] = 0x08;
260 cmd_slem.mask[2] = 0x00;
261 cmd_slem.mask[3] = 0x00;
262 cmd_slem.mask[4] = 0x00;
263 cmd_slem.mask[5] = 0x00;
264 cmd_slem.mask[6] = 0x00;
265 cmd_slem.mask[7] = 0x00;
267 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
268 if (!(io->use_raw)) {
269 /* Reset Command in case of user channel */
270 bt_hci_send(io->hci, BT_HCI_CMD_RESET, NULL, 0, hci_generic_callback,
274 /* TODO: Move to suitable place. Set suitable masks */
276 bt_hci_send(io->hci, BT_HCI_CMD_RESET, NULL, 0, hci_generic_callback,
280 /* Read local supported commands */
281 bt_hci_send(io->hci, BT_HCI_CMD_READ_LOCAL_COMMANDS, NULL, 0,
282 local_commands_callback, NULL, NULL);
284 /* Read local supported features */
285 bt_hci_send(io->hci, BT_HCI_CMD_READ_LOCAL_FEATURES, NULL, 0,
286 local_features_callback, NULL, NULL);
289 bt_hci_send(io->hci, BT_HCI_CMD_SET_EVENT_MASK, &cmd_sem,
290 sizeof(cmd_sem), hci_generic_callback, NULL, NULL);
292 /* Set LE event mask */
293 bt_hci_send(io->hci, BT_HCI_CMD_LE_SET_EVENT_MASK, &cmd_slem,
294 sizeof(cmd_slem), hci_generic_callback, NULL, NULL);
297 bt_hci_send(io->hci, BT_HCI_CMD_LE_SET_SCAN_PARAMETERS, &cmd,
298 sizeof(cmd), hci_generic_callback, NULL, NULL);
301 static void scan_enable_rsp(const void *buf, uint8_t size,
304 uint8_t status = *((uint8_t *) buf);
307 l_error("LE Scan enable failed (0x%02x)", status);
310 static void set_recv_scan_enable(const void *buf, uint8_t size,
313 struct mesh_io_private *pvt = user_data;
314 struct bt_hci_cmd_le_set_scan_enable cmd;
316 cmd.enable = 0x01; /* Enable scanning */
317 cmd.filter_dup = 0x00; /* Report duplicates */
318 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
319 &cmd, sizeof(cmd), scan_enable_rsp, pvt, NULL);
322 static void scan_disable_rsp(const void *buf, uint8_t size,
325 struct bt_hci_cmd_le_set_scan_parameters cmd;
326 struct mesh_io_private *pvt = user_data;
327 uint8_t status = *((uint8_t *) buf);
330 l_error("LE Scan disable failed (0x%02x)", status);
332 cmd.type = pvt->active ? 0x01 : 0x00; /* Passive/Active scanning */
333 cmd.interval = L_CPU_TO_LE16(0x0010); /* 10 ms */
334 cmd.window = L_CPU_TO_LE16(0x0010); /* 10 ms */
335 cmd.own_addr_type = 0x01; /* ADDR_TYPE_RANDOM */
336 cmd.filter_policy = 0x00; /* Accept all */
338 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_PARAMETERS,
340 set_recv_scan_enable, pvt, NULL);
343 static bool find_active(const void *a, const void *b)
345 const struct pvt_rx_reg *rx_reg = a;
347 /* Mesh specific AD types do *not* require active scanning,
348 * so do not turn on Active Scanning on their account.
350 if (rx_reg->filter[0] < MESH_AD_TYPE_PROVISION ||
351 rx_reg->filter[0] > MESH_AD_TYPE_BEACON)
357 static void restart_scan(struct mesh_io_private *pvt)
359 struct bt_hci_cmd_le_set_scan_enable cmd;
361 if (l_queue_isempty(pvt->rx_regs))
364 pvt->active = l_queue_find(pvt->rx_regs, find_active, NULL);
365 cmd.enable = 0x00; /* Disable scanning */
366 cmd.filter_dup = 0x00; /* Report duplicates */
367 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
368 &cmd, sizeof(cmd), scan_disable_rsp, pvt, NULL);
371 static void hci_init(void *user_data)
373 struct mesh_io *io = user_data;
375 bool restarted = false;
379 bt_hci_unref(io->pvt->hci);
382 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
383 if (io->pvt->use_raw) {
384 l_debug("Use HCI RAW channel");
386 /* Power up HCI device */
387 uint16_t mode = 0x01;
388 if (!set_powered(mode, io->pvt->index))
391 io->pvt->hci = bt_hci_new_raw_device(io->pvt->index);
393 l_debug("Use HCI USER channel");
394 io->pvt->hci = bt_hci_new_user_channel(io->pvt->index);
397 io->pvt->hci = bt_hci_new_user_channel(io->pvt->index);
401 l_error("Failed to start mesh io (hci %u): %s", io->pvt->index,
407 configure_hci(io->pvt);
409 bt_hci_register(io->pvt->hci, BT_HCI_EVT_LE_META_EVENT,
410 event_callback, io, NULL);
412 l_debug("Started mesh on hci %u", io->pvt->index);
415 restart_scan(io->pvt);
418 if (io->pvt->ready_callback)
419 io->pvt->ready_callback(io->pvt->user_data, result);
422 static void read_info(int index, void *user_data)
424 struct mesh_io *io = user_data;
426 if (io->pvt->index != MGMT_INDEX_NONE &&
427 index != io->pvt->index) {
428 l_debug("Ignore index %d", index);
432 io->pvt->index = index;
436 static bool dev_init(struct mesh_io *io, void *opts,
437 mesh_io_ready_func_t cb, void *user_data)
442 io->pvt = l_new(struct mesh_io_private, 1);
443 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
444 struct mesh_io_opts *io_opts;
445 io_opts = (struct mesh_io_opts *)opts;
446 io->pvt->index = io_opts->index;
447 io->pvt->use_raw = io_opts->use_raw;
449 io->pvt->index = *(int *)opts;
452 io->pvt->rx_regs = l_queue_new();
453 io->pvt->tx_pkts = l_queue_new();
455 io->pvt->ready_callback = cb;
456 io->pvt->user_data = user_data;
458 if (io->pvt->index == MGMT_INDEX_NONE)
459 return mesh_mgmt_list(read_info, io);
461 l_idle_oneshot(hci_init, io, NULL);
466 static bool dev_destroy(struct mesh_io *io)
468 struct mesh_io_private *pvt = io->pvt;
473 bt_hci_unref(pvt->hci);
474 l_timeout_remove(pvt->tx_timeout);
475 l_queue_destroy(pvt->rx_regs, l_free);
476 l_queue_destroy(pvt->tx_pkts, l_free);
483 static bool dev_caps(struct mesh_io *io, struct mesh_io_caps *caps)
485 struct mesh_io_private *pvt = io->pvt;
490 caps->max_num_filters = 255;
491 caps->window_accuracy = 50;
496 static void send_cancel_done(const void *buf, uint8_t size,
499 struct mesh_io_private *pvt = user_data;
500 struct bt_hci_cmd_le_set_random_address cmd;
505 pvt->sending = false;
507 /* At end of any burst of ADVs, change random address */
508 l_getrandom(cmd.addr, 6);
510 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_RANDOM_ADDRESS,
511 &cmd, sizeof(cmd), NULL, NULL, NULL);
514 static void send_cancel(struct mesh_io_private *pvt)
516 struct bt_hci_cmd_le_set_adv_enable cmd;
522 send_cancel_done(NULL, 0, pvt);
526 cmd.enable = 0x00; /* Disable advertising */
527 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_ADV_ENABLE,
529 send_cancel_done, pvt, NULL);
532 static void set_send_adv_enable(const void *buf, uint8_t size,
535 struct mesh_io_private *pvt = user_data;
536 struct bt_hci_cmd_le_set_adv_enable cmd;
542 cmd.enable = 0x01; /* Enable advertising */
543 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_ADV_ENABLE,
544 &cmd, sizeof(cmd), NULL, NULL, NULL);
547 static void set_send_adv_data(const void *buf, uint8_t size,
550 struct mesh_io_private *pvt = user_data;
552 struct bt_hci_cmd_le_set_adv_data cmd;
554 if (!pvt || !pvt->tx)
558 if (tx->len >= sizeof(cmd.data))
561 memset(&cmd, 0, sizeof(cmd));
563 cmd.len = tx->len + 1;
564 cmd.data[0] = tx->len;
565 memcpy(cmd.data + 1, tx->pkt, tx->len);
567 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_ADV_DATA,
569 set_send_adv_enable, pvt, NULL);
577 static void set_send_adv_params(const void *buf, uint8_t size,
580 struct mesh_io_private *pvt = user_data;
581 struct bt_hci_cmd_le_set_adv_parameters cmd;
582 uint16_t hci_interval;
587 hci_interval = (pvt->interval * 16) / 10;
588 cmd.min_interval = L_CPU_TO_LE16(hci_interval);
589 cmd.max_interval = L_CPU_TO_LE16(hci_interval);
590 cmd.type = 0x03; /* ADV_NONCONN_IND */
591 cmd.own_addr_type = 0x01; /* ADDR_TYPE_RANDOM */
592 cmd.direct_addr_type = 0x00;
593 memset(cmd.direct_addr, 0, 6);
594 cmd.channel_map = 0x07;
595 cmd.filter_policy = 0x03;
597 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_ADV_PARAMETERS,
599 set_send_adv_data, pvt, NULL);
602 static void send_pkt(struct mesh_io_private *pvt, struct tx_pkt *tx,
605 struct bt_hci_cmd_le_set_adv_enable cmd;
608 pvt->interval = interval;
611 set_send_adv_params(NULL, 0, pvt);
615 cmd.enable = 0x00; /* Disable advertising */
616 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_ADV_ENABLE,
618 set_send_adv_params, pvt, NULL);
621 static void tx_timeout(struct l_timeout *timeout, void *user_data)
623 struct mesh_io_private *pvt = user_data;
631 tx = l_queue_pop_head(pvt->tx_pkts);
633 l_timeout_remove(timeout);
634 pvt->tx_timeout = NULL;
639 if (tx->info.type == MESH_IO_TIMING_TYPE_GENERAL) {
640 ms = tx->info.u.gen.interval;
641 count = tx->info.u.gen.cnt;
642 if (count != MESH_IO_TX_COUNT_UNLIMITED)
643 tx->info.u.gen.cnt--;
649 tx->delete = !!(count == 1);
651 send_pkt(pvt, tx, ms);
654 /* send_pkt will delete when done */
655 tx = l_queue_peek_head(pvt->tx_pkts);
656 if (tx && tx->info.type == MESH_IO_TIMING_TYPE_POLL_RSP) {
657 ms = instant_remaining_ms(tx->info.u.poll_rsp.instant +
658 tx->info.u.poll_rsp.delay);
661 l_queue_push_tail(pvt->tx_pkts, tx);
664 pvt->tx_timeout = timeout;
665 l_timeout_modify_ms(timeout, ms);
667 pvt->tx_timeout = l_timeout_create_ms(ms, tx_timeout,
671 static void tx_worker(void *user_data)
673 struct mesh_io_private *pvt = user_data;
677 tx = l_queue_peek_head(pvt->tx_pkts);
681 switch (tx->info.type) {
682 case MESH_IO_TIMING_TYPE_GENERAL:
683 if (tx->info.u.gen.min_delay == tx->info.u.gen.max_delay)
684 delay = tx->info.u.gen.min_delay;
686 l_getrandom(&delay, sizeof(delay));
687 delay %= tx->info.u.gen.max_delay -
688 tx->info.u.gen.min_delay;
689 delay += tx->info.u.gen.min_delay;
693 case MESH_IO_TIMING_TYPE_POLL:
694 if (tx->info.u.poll.min_delay == tx->info.u.poll.max_delay)
695 delay = tx->info.u.poll.min_delay;
697 l_getrandom(&delay, sizeof(delay));
698 delay %= tx->info.u.poll.max_delay -
699 tx->info.u.poll.min_delay;
700 delay += tx->info.u.poll.min_delay;
704 case MESH_IO_TIMING_TYPE_POLL_RSP:
705 /* Delay until Instant + Delay */
706 delay = instant_remaining_ms(tx->info.u.poll_rsp.instant +
707 tx->info.u.poll_rsp.delay);
717 tx_timeout(pvt->tx_timeout, pvt);
718 else if (pvt->tx_timeout)
719 l_timeout_modify_ms(pvt->tx_timeout, delay);
721 pvt->tx_timeout = l_timeout_create_ms(delay, tx_timeout,
725 static bool send_tx(struct mesh_io *io, struct mesh_io_send_info *info,
726 const uint8_t *data, uint16_t len)
728 struct mesh_io_private *pvt = io->pvt;
730 bool sending = false;
732 if (!info || !data || !len || len > sizeof(tx->pkt))
735 tx = l_new(struct tx_pkt, 1);
739 memcpy(&tx->info, info, sizeof(tx->info));
740 memcpy(&tx->pkt, data, len);
743 if (info->type == MESH_IO_TIMING_TYPE_POLL_RSP)
744 l_queue_push_head(pvt->tx_pkts, tx);
746 sending = !l_queue_isempty(pvt->tx_pkts);
747 l_queue_push_tail(pvt->tx_pkts, tx);
751 l_timeout_remove(pvt->tx_timeout);
752 pvt->tx_timeout = NULL;
753 l_idle_oneshot(tx_worker, pvt, NULL);
759 static bool find_by_ad_type(const void *a, const void *b)
761 const struct tx_pkt *tx = a;
762 uint8_t ad_type = L_PTR_TO_UINT(b);
764 return !ad_type || ad_type == tx->pkt[0];
767 static bool find_by_pattern(const void *a, const void *b)
769 const struct tx_pkt *tx = a;
770 const struct tx_pattern *pattern = b;
772 if (tx->len < pattern->len)
775 return (!memcmp(tx->pkt, pattern->data, pattern->len));
778 static bool tx_cancel(struct mesh_io *io, const uint8_t *data, uint8_t len)
780 struct mesh_io_private *pvt = io->pvt;
788 tx = l_queue_remove_if(pvt->tx_pkts, find_by_ad_type,
789 L_UINT_TO_PTR(data[0]));
797 struct tx_pattern pattern = {
803 tx = l_queue_remove_if(pvt->tx_pkts, find_by_pattern,
813 if (l_queue_isempty(pvt->tx_pkts)) {
815 l_timeout_remove(pvt->tx_timeout);
816 pvt->tx_timeout = NULL;
822 static bool find_by_filter(const void *a, const void *b)
824 const struct pvt_rx_reg *rx_reg = a;
825 const uint8_t *filter = b;
827 return !memcmp(rx_reg->filter, filter, rx_reg->len);
830 static bool recv_register(struct mesh_io *io, const uint8_t *filter,
831 uint8_t len, mesh_io_recv_func_t cb, void *user_data)
833 struct bt_hci_cmd_le_set_scan_enable cmd;
834 struct mesh_io_private *pvt = io->pvt;
835 struct pvt_rx_reg *rx_reg;
836 bool already_scanning;
839 if (!cb || !filter || !len)
842 l_info("%s %2.2x", __func__, filter[0]);
843 rx_reg = l_queue_remove_if(pvt->rx_regs, find_by_filter, filter);
846 rx_reg = l_malloc(sizeof(*rx_reg) + len);
848 memcpy(rx_reg->filter, filter, len);
851 rx_reg->user_data = user_data;
853 already_scanning = !l_queue_isempty(pvt->rx_regs);
855 l_queue_push_head(pvt->rx_regs, rx_reg);
857 /* Look for any AD types requiring Active Scanning */
858 if (l_queue_find(pvt->rx_regs, find_active, NULL))
861 if (!already_scanning || pvt->active != active) {
862 pvt->active = active;
863 cmd.enable = 0x00; /* Disable scanning */
864 cmd.filter_dup = 0x00; /* Report duplicates */
865 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
866 &cmd, sizeof(cmd), scan_disable_rsp, pvt, NULL);
873 static bool recv_deregister(struct mesh_io *io, const uint8_t *filter,
876 struct bt_hci_cmd_le_set_scan_enable cmd = {0, 0};
877 struct mesh_io_private *pvt = io->pvt;
878 struct pvt_rx_reg *rx_reg;
881 rx_reg = l_queue_remove_if(pvt->rx_regs, find_by_filter, filter);
886 /* Look for any AD types requiring Active Scanning */
887 if (l_queue_find(pvt->rx_regs, find_active, NULL))
890 if (l_queue_isempty(pvt->rx_regs)) {
891 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
892 &cmd, sizeof(cmd), NULL, NULL, NULL);
894 } else if (active != pvt->active) {
895 pvt->active = active;
896 bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
897 &cmd, sizeof(cmd), scan_disable_rsp, pvt, NULL);
903 const struct mesh_io_api mesh_io_generic = {
905 .destroy = dev_destroy,
908 .reg = recv_register,
909 .dereg = recv_deregister,