mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-16 08:44:38 +08:00
Add BR/EDR LE interleaved discovery
According to the general discovery procedure should interleave the general discovery procedure over BR/EDR with the general discovery procedure over LE. LE Scanning is reporting found remote devices using DeviceFound signals. Currently, only the Bluetooth address is extracted from the Advertising event. Step 1: BR/EDR discovery for TGAP(100)/2 sec Step 2: LE discovery for TGAP(100)/2 sec
This commit is contained in:
parent
70cd37db7c
commit
e0e4bd6e26
@ -577,7 +577,7 @@ static int hciops_start_discovery(int index, gboolean periodic)
|
||||
memcpy(&cp.lap, lap, 3);
|
||||
cp.max_period = htobs(24);
|
||||
cp.min_period = htobs(16);
|
||||
cp.length = 0x08;
|
||||
cp.length = 0x04;
|
||||
cp.num_rsp = 0x00;
|
||||
|
||||
err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY,
|
||||
@ -587,7 +587,7 @@ static int hciops_start_discovery(int index, gboolean periodic)
|
||||
|
||||
memset(&inq_cp, 0, sizeof(inq_cp));
|
||||
memcpy(&inq_cp.lap, lap, 3);
|
||||
inq_cp.length = 0x08;
|
||||
inq_cp.length = 0x04;
|
||||
inq_cp.num_rsp = 0x00;
|
||||
|
||||
err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY,
|
||||
|
@ -1232,9 +1232,32 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
|
||||
return adapter_create_device(conn, adapter, address);
|
||||
}
|
||||
|
||||
static int adapter_start_inquiry(struct btd_adapter *adapter)
|
||||
static gboolean stop_inquiry(gpointer user_data)
|
||||
{
|
||||
struct btd_adapter *adapter = user_data;
|
||||
|
||||
DBG("");
|
||||
|
||||
adapter_ops->stop_discovery(adapter->dev_id);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean stop_scanning(gpointer user_data)
|
||||
{
|
||||
struct btd_adapter *adapter = user_data;
|
||||
|
||||
adapter_ops->stop_scanning(adapter->dev_id);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int start_discovery(struct btd_adapter *adapter)
|
||||
{
|
||||
struct hci_dev *dev = &adapter->dev;
|
||||
gboolean periodic = TRUE;
|
||||
GSourceFunc stop;
|
||||
int err;
|
||||
|
||||
/* Do not start if suspended */
|
||||
if (adapter->state & SUSPENDED_INQUIRY)
|
||||
@ -1245,7 +1268,23 @@ static int adapter_start_inquiry(struct btd_adapter *adapter)
|
||||
|
||||
pending_remote_name_cancel(adapter);
|
||||
|
||||
return adapter_ops->start_discovery(adapter->dev_id, periodic);
|
||||
/* BR/EDR only? */
|
||||
if (!(dev->features[4] & LMP_LE))
|
||||
return adapter_ops->start_discovery(adapter->dev_id, periodic);
|
||||
|
||||
/* Dual mode or LE only */
|
||||
if (dev->features[4] & LMP_NO_BREDR) {
|
||||
err = adapter_ops->start_scanning(adapter->dev_id);
|
||||
stop = stop_scanning;
|
||||
} else {
|
||||
err = adapter_ops->start_discovery(adapter->dev_id, FALSE);
|
||||
stop = stop_inquiry;
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
g_timeout_add(5120, stop, adapter);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static DBusMessage *adapter_start_discovery(DBusConnection *conn,
|
||||
@ -1271,7 +1310,7 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
|
||||
if (main_opts.name_resolv)
|
||||
adapter->state |= RESOLVE_NAME;
|
||||
|
||||
err = adapter_start_inquiry(adapter);
|
||||
err = start_discovery(adapter);
|
||||
if (err < 0)
|
||||
return failed_strerror(msg, -err);
|
||||
|
||||
@ -1376,7 +1415,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
|
||||
DBUS_TYPE_UINT32, &adapter->pairable_timeout);
|
||||
|
||||
|
||||
if (adapter->state & PERIODIC_INQUIRY || adapter->state & STD_INQUIRY)
|
||||
if (adapter->state & (PERIODIC_INQUIRY | STD_INQUIRY | LE_SCAN))
|
||||
value = TRUE;
|
||||
else
|
||||
value = FALSE;
|
||||
@ -2391,12 +2430,6 @@ static void reply_pending_requests(struct btd_adapter *adapter)
|
||||
device_cancel_bonding(device,
|
||||
HCI_OE_USER_ENDED_CONNECTION);
|
||||
}
|
||||
|
||||
if (adapter->state & STD_INQUIRY || adapter->state & PERIODIC_INQUIRY) {
|
||||
/* Cancel inquiry initiated by D-Bus client */
|
||||
if (adapter->disc_sessions)
|
||||
adapter_ops->stop_discovery(adapter->dev_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void unload_drivers(struct btd_adapter *adapter)
|
||||
@ -2626,18 +2659,24 @@ void adapter_set_state(struct btd_adapter *adapter, int state)
|
||||
if (adapter->state == state)
|
||||
return;
|
||||
|
||||
if (state & PERIODIC_INQUIRY || state & STD_INQUIRY)
|
||||
discov_active = TRUE;
|
||||
if (adapter->state & STD_INQUIRY) {
|
||||
if (adapter_ops->start_scanning(adapter->dev_id) < 0)
|
||||
return;
|
||||
|
||||
g_timeout_add(5120, stop_scanning, adapter);
|
||||
}
|
||||
|
||||
discov_active = state & (PERIODIC_INQUIRY | STD_INQUIRY | LE_SCAN)
|
||||
? TRUE : FALSE;
|
||||
|
||||
if (discov_active == FALSE)
|
||||
adapter_update_oor_devices(adapter);
|
||||
else if (adapter->disc_sessions && main_opts.discov_interval)
|
||||
adapter->scheduler_id = g_timeout_add_seconds(
|
||||
main_opts.discov_interval,
|
||||
(GSourceFunc) adapter_start_inquiry,
|
||||
(GSourceFunc) start_discovery,
|
||||
adapter);
|
||||
|
||||
/* Send out of range */
|
||||
if (!discov_active)
|
||||
adapter_update_oor_devices(adapter);
|
||||
|
||||
emit_property_changed(connection, path,
|
||||
ADAPTER_INTERFACE, "Discovering",
|
||||
DBUS_TYPE_BOOLEAN, &discov_active);
|
||||
@ -3146,7 +3185,7 @@ void adapter_resume_discovery(struct btd_adapter *adapter)
|
||||
DBG("Resuming discovery");
|
||||
|
||||
adapter->state &= ~SUSPENDED_INQUIRY;
|
||||
adapter_start_inquiry(adapter);
|
||||
start_discovery(adapter);
|
||||
}
|
||||
|
||||
int btd_register_adapter_driver(struct btd_adapter_driver *driver)
|
||||
|
@ -35,7 +35,8 @@
|
||||
#define DISCOVER_TYPE_NONE 0x00
|
||||
#define STD_INQUIRY 0x01
|
||||
#define PERIODIC_INQUIRY 0x02
|
||||
#define SUSPENDED_INQUIRY 0x04
|
||||
#define LE_SCAN 0x04
|
||||
#define SUSPENDED_INQUIRY 0x08
|
||||
|
||||
/* Actions executed after inquiry complete */
|
||||
#define RESOLVE_NAME 0x10
|
||||
|
@ -388,7 +388,9 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
struct remote_dev_info *dev, match;
|
||||
uint8_t name_type = 0x00;
|
||||
name_status_t name_status;
|
||||
#if 0
|
||||
int state;
|
||||
#endif
|
||||
dbus_bool_t legacy;
|
||||
unsigned char features[8];
|
||||
|
||||
@ -404,7 +406,8 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
|
||||
if (data)
|
||||
write_remote_eir(local, peer, data);
|
||||
|
||||
#if 0
|
||||
/* FIXME: Use HCI flags to identify this scenario */
|
||||
/*
|
||||
* workaround to identify situation when the daemon started and
|
||||
* a standard inquiry or periodic inquiry was already running
|
||||
@ -415,7 +418,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
state |= PERIODIC_INQUIRY;
|
||||
adapter_set_state(adapter, state);
|
||||
}
|
||||
|
||||
#endif
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, peer);
|
||||
match.name_status = NAME_SENT;
|
||||
@ -730,6 +733,33 @@ void hcid_dbus_setscan_enable_complete(bdaddr_t *local)
|
||||
btd_adapter_read_scan_enable(adapter);
|
||||
}
|
||||
|
||||
void hcid_dbus_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status)
|
||||
{
|
||||
struct btd_adapter *adapter;
|
||||
int state;
|
||||
|
||||
adapter = manager_find_adapter(local);
|
||||
if (!adapter) {
|
||||
error("No matching adapter found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
error("Can't enabled/disable LE scan");
|
||||
return;
|
||||
}
|
||||
|
||||
state = adapter_get_state(adapter);
|
||||
|
||||
/* Enabling or disabling ? */
|
||||
if (state == LE_SCAN)
|
||||
state &= ~LE_SCAN;
|
||||
else
|
||||
state |= LE_SCAN;
|
||||
|
||||
adapter_set_state(adapter, state);
|
||||
}
|
||||
|
||||
void hcid_dbus_read_simple_pairing_mode_complete(bdaddr_t *local, void *ptr)
|
||||
{
|
||||
read_simple_pairing_mode_rp *rp = ptr;
|
||||
|
@ -32,6 +32,7 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle
|
||||
void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
|
||||
void hcid_dbus_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
|
||||
void hcid_dbus_setscan_enable_complete(bdaddr_t *local);
|
||||
void hcid_dbus_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status);
|
||||
void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local);
|
||||
void hcid_dbus_read_simple_pairing_mode_complete(bdaddr_t *local, void *ptr);
|
||||
void hcid_dbus_returned_link_key(bdaddr_t *local, bdaddr_t *peer);
|
||||
|
@ -586,6 +586,8 @@ static void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic)
|
||||
|
||||
state = adapter_get_state(adapter);
|
||||
|
||||
DBG("adapter->state %#x", state);
|
||||
|
||||
/* Disable name resolution for non D-Bus clients */
|
||||
if (!adapter_has_discov_sessions(adapter))
|
||||
state &= ~RESOLVE_NAME;
|
||||
@ -638,17 +640,22 @@ static void inquiry_complete(bdaddr_t *local, uint8_t status, gboolean periodic)
|
||||
*
|
||||
* Keep in mind that non D-Bus requests can arrive.
|
||||
*/
|
||||
|
||||
state = adapter_get_state(adapter);
|
||||
DBG("adapter->state %#x", state);
|
||||
|
||||
if (periodic) {
|
||||
state = adapter_get_state(adapter);
|
||||
state &= ~PERIODIC_INQUIRY;
|
||||
adapter_set_state(adapter, state);
|
||||
return;
|
||||
}
|
||||
|
||||
state &= ~STD_INQUIRY;
|
||||
adapter_set_state(adapter, state);
|
||||
|
||||
if (adapter_resolve_names(adapter) == 0)
|
||||
return;
|
||||
|
||||
state = adapter_get_state(adapter);
|
||||
/*
|
||||
* workaround to identify situation when there is no devices around
|
||||
* but periodic inquiry is active.
|
||||
@ -718,6 +725,9 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)
|
||||
case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL):
|
||||
inquiry_complete(sba, status, FALSE);
|
||||
break;
|
||||
case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE):
|
||||
hcid_dbus_le_set_scan_enable_complete(sba, status);
|
||||
break;
|
||||
case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):
|
||||
adapter_setname_complete(sba, status);
|
||||
break;
|
||||
@ -986,7 +996,7 @@ static inline void le_metaevent(int dev, bdaddr_t *sba, void *ptr)
|
||||
|
||||
info = (le_advertising_info *) (meta->data + 1);
|
||||
ba2str(&info->bdaddr, addr);
|
||||
DBG("%s\n", addr);
|
||||
hcid_dbus_inquiry_result(sba, &info->bdaddr, 0, 0, NULL);
|
||||
}
|
||||
|
||||
static void delete_channel(GIOChannel *chan)
|
||||
|
Loading…
Reference in New Issue
Block a user