diff --git a/include/bluetooth/bluetooth.h b/include/bluetooth/bluetooth.h index ef33a7e4819..4445bbb825a 100644 --- a/include/bluetooth/bluetooth.h +++ b/include/bluetooth/bluetooth.h @@ -87,5 +87,7 @@ struct bt_eir { int bt_start_advertising(uint8_t type, const struct bt_eir *ad, const struct bt_eir *sd); +int bt_start_scanning(uint8_t scan_type, uint8_t scan_filter); +int bt_stop_scanning(); #endif /* __BT_BLUETOOTH_H */ diff --git a/include/bluetooth/hci.h b/include/bluetooth/hci.h index 89c8ba6161e..9b8aca298ff 100644 --- a/include/bluetooth/hci.h +++ b/include/bluetooth/hci.h @@ -202,6 +202,30 @@ struct bt_hci_cp_le_set_adv_enable { uint8_t enable; } PACK_STRUCT; +/* Scan types */ +#define BT_HCI_OP_LE_SET_SCAN_PARAMS BT_OP(BT_OGF_LE, 0x000b) +#define BT_LE_SCAN_PASSIVE 0x00 +#define BT_LE_SCAN_ACTIVE 0x01 + +struct bt_hci_cp_le_set_scan_params { + uint8_t scan_type; + uint16_t interval; + uint16_t window; + uint8_t addr_type; + uint8_t filter_policy; +} PACK_STRUCT; + +#define BT_HCI_OP_LE_SET_SCAN_ENABLE BT_OP(BT_OGF_LE, 0x000c) +#define BT_LE_SCAN_DISABLE 0x00 +#define BT_LE_SCAN_ENABLE 0x01 +#define BT_LE_SCAN_FILTER_DUP_DISABLE 0x00 +#define BT_LE_SCAN_FILTER_DUP_ENABLE 0x01 + +struct bt_hci_cp_le_set_scan_enable { + uint8_t enable; + uint8_t filter_dup; +} PACK_STRUCT; + #define BT_HCI_OP_LE_ENCRYPT BT_OP(BT_OGF_LE, 0x0017) struct bt_hci_cp_le_encrypt { uint8_t key[16]; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 51b11e925a8..d592af6d389 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -828,3 +828,92 @@ send_set_param: return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); } + +int bt_start_scanning(uint8_t scan_type, uint8_t scan_filter) +{ + struct bt_buf *buf, *rsp; + struct bt_hci_cp_le_set_scan_params *set_param; + struct bt_hci_cp_le_set_scan_enable *scan_enable; + int err; + + if (dev.scan_enable == BT_LE_SCAN_ENABLE) { + return -EALREADY; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_PARAMS, sizeof(*set_param)); + if (!buf) { + return -ENOBUFS; + } + + set_param = (void *)bt_buf_add(buf, sizeof(*set_param)); + memset(set_param, 0, sizeof(*set_param)); + set_param->scan_type = scan_type; + + /* for the rest parameters apply default values according to + * spec 4.2, vol2, part E, 7.8.10 + */ + set_param->interval = sys_cpu_to_le16(0x0010); + set_param->window = sys_cpu_to_le16(0x0010); + set_param->filter_policy = 0x00; + set_param->addr_type = 0x00; + + bt_hci_cmd_send(BT_HCI_OP_LE_SET_SCAN_PARAMS, buf); + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE, sizeof(*scan_enable)); + if (!buf) { + return -ENOBUFS; + } + + scan_enable = (void *)bt_buf_add(buf, sizeof(*scan_enable)); + memset(scan_enable, 0, sizeof(*scan_enable)); + scan_enable->filter_dup = scan_filter; + scan_enable->enable = BT_LE_SCAN_ENABLE; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_SCAN_ENABLE, buf, &rsp); + if (err) { + return err; + } + + /* Update scan state in case of success (0) status */ + if (!rsp->data[0]) { + dev.scan_enable = BT_LE_SCAN_ENABLE; + } + + bt_buf_put(rsp); + + return 0; +} + +int bt_stop_scanning() +{ + struct bt_buf *buf, *rsp; + struct bt_hci_cp_le_set_scan_enable *scan_enable; + int err; + + if (dev.scan_enable == BT_LE_SCAN_DISABLE) { + return -EALREADY; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE, sizeof(*scan_enable)); + if (!buf) { + return -ENOBUFS; + } + + scan_enable = (void *)bt_buf_add(buf, sizeof(*scan_enable)); + memset(scan_enable, 0x0, sizeof(*scan_enable)); + scan_enable->filter_dup = 0x00; + scan_enable->enable = BT_LE_SCAN_DISABLE; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_SCAN_ENABLE, buf, &rsp); + if (err) { + return err; + } + + /* Update scan state in case of success (0) status */ + if (!rsp->data[0]) { + dev.scan_enable = BT_LE_SCAN_DISABLE; + } + + bt_buf_put(rsp); + + return 0; +} diff --git a/net/bluetooth/hci_core.h b/net/bluetooth/hci_core.h index c525160f3ed..3553cd3f16a 100644 --- a/net/bluetooth/hci_core.h +++ b/net/bluetooth/hci_core.h @@ -53,6 +53,9 @@ struct bt_dev { /* Advertising state */ uint8_t adv_enable; + /* Scanning state */ + uint8_t scan_enable; + /* Controller buffer information */ uint8_t le_pkts; uint16_t le_mtu;