Bluetooth: BR/EDR: Add basic SCAN support

Adds capability to stack to make controller discoverable and
connectable.

Change-Id: Iffe380d2bde0c193f806b76cce3933914c9a4796
Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
This commit is contained in:
Arkadiusz Lichwa 2015-11-26 14:47:11 +01:00 committed by Anas Nashif
commit 2ebf636fe2
4 changed files with 110 additions and 0 deletions

View file

@ -240,4 +240,32 @@ static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str,
addr->val[5], addr->val[4], addr->val[3],
addr->val[2], addr->val[1], addr->val[0], type);
}
#if defined(CONFIG_BLUETOOTH_BREDR)
/** @brief Enable/disable set controller in discoverable state.
*
* Allows make local controller to listen on INQUIRY SCAN channel and responds
* to devices making general inquiry. To enable this state it's mandatory
* to first be in connectable state.
*
* @param enable Value allowing/disallowing controller to become discoverable.
*
* @return Negative if fail set to requested state or requested state has been
* already set. Zero if done successfully.
*/
int bt_bredr_set_discoverable(bool enable);
/** @brief Enable/disable set controller in connectable state.
*
* Allows make local controller to be connectable. It means the controller
* start listen to devices requests on PAGE SCAN channel. If disabled also
* resets discoverability if was set.
*
* @param enable Value allowing/disallowing controller to be connectable.
*
* @return Negative if fail set to requested state or requested state has been
* already set. Zero if done successfully.
*/
int bt_bredr_set_connectable(bool enable);
#endif
#endif /* __BT_BLUETOOTH_H */

View file

@ -122,6 +122,11 @@ struct bt_hci_cp_set_event_mask {
#define BT_HCI_OP_RESET BT_OP(BT_OGF_BASEBAND, 0x0003)
#define BT_HCI_OP_WRITE_SCAN_ENABLE BT_OP(BT_OGF_BASEBAND, 0x001a)
#define BT_BREDR_SCAN_DISABLED 0x00
#define BT_BREDR_SCAN_INQUIRY 0x01
#define BT_BREDR_SCAN_PAGE 0x02
#define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031)
#define BT_HCI_OP_HOST_BUFFER_SIZE BT_OP(BT_OGF_BASEBAND, 0x0033)

View file

@ -2105,3 +2105,78 @@ struct net_buf *bt_buf_get_acl(void)
return NULL;
#endif /* CONFIG_BLUETOOTH_CONN */
}
#if defined(CONFIG_BLUETOOTH_BREDR)
static int bt_bredr_hci_write_scan(uint8_t scan)
{
struct net_buf *buf;
int err;
BT_DBG("type %u", scan);
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SCAN_ENABLE, 1);
if (!buf) {
return -ENOBUFS;
}
memcpy(net_buf_add(buf, 1), &scan, 1);
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SCAN_ENABLE, buf, NULL);
if (err) {
return err;
}
if (scan & BT_BREDR_SCAN_INQUIRY) {
atomic_set_bit(bt_dev.flags, BT_DEV_ISCAN);
} else {
atomic_clear_bit(bt_dev.flags, BT_DEV_ISCAN);
}
if (scan & BT_BREDR_SCAN_PAGE) {
atomic_set_bit(bt_dev.flags, BT_DEV_PSCAN);
} else {
atomic_clear_bit(bt_dev.flags, BT_DEV_PSCAN);
}
return 0;
}
int bt_bredr_set_connectable(bool enable)
{
if (enable) {
if (atomic_test_bit(bt_dev.flags, BT_DEV_PSCAN)) {
return -EALREADY;
} else {
return bt_bredr_hci_write_scan(BT_BREDR_SCAN_PAGE);
}
} else {
if (!atomic_test_bit(bt_dev.flags, BT_DEV_PSCAN)) {
return -EALREADY;
} else {
return bt_bredr_hci_write_scan(BT_BREDR_SCAN_DISABLED);
}
}
}
int bt_bredr_set_discoverable(bool enable)
{
if (enable) {
if (atomic_test_bit(bt_dev.flags, BT_DEV_ISCAN)) {
return -EALREADY;
}
if (!atomic_test_bit(bt_dev.flags, BT_DEV_PSCAN)) {
return -EPERM;
}
return bt_bredr_hci_write_scan(BT_BREDR_SCAN_INQUIRY |
BT_BREDR_SCAN_PAGE);
} else {
if (!atomic_test_bit(bt_dev.flags, BT_DEV_ISCAN)) {
return -EALREADY;
}
return bt_bredr_hci_write_scan(BT_BREDR_SCAN_PAGE);
}
}
#endif

View file

@ -44,6 +44,8 @@ enum {
BT_DEV_SCANNING,
BT_DEV_SCAN_FILTER_DUP,
BT_DEV_ISCAN,
BT_DEV_PSCAN,
};
struct bt_dev_le {