mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-02 08:34:26 +08:00
android/bluetooth: Track device last connected bearer
This allows to correctly choose address type when pairing dual mode devices.
This commit is contained in:
parent
2c2262cf66
commit
8911e43cb0
@ -104,7 +104,8 @@ struct device {
|
||||
uint32_t class;
|
||||
int32_t rssi;
|
||||
|
||||
uint32_t timestamp;
|
||||
time_t bredr_seen;
|
||||
time_t le_seen;
|
||||
|
||||
GSList *uuids;
|
||||
|
||||
@ -263,7 +264,12 @@ static void store_device_info(struct device *dev, const char *path)
|
||||
else
|
||||
g_key_file_remove_key(key_file, addr, "Class", NULL);
|
||||
|
||||
g_key_file_set_integer(key_file, addr, "Timestamp", dev->timestamp);
|
||||
if (dev->bredr_seen > dev->le_seen)
|
||||
g_key_file_set_integer(key_file, addr, "Timestamp",
|
||||
dev->bredr_seen);
|
||||
else
|
||||
g_key_file_set_integer(key_file, addr, "Timestamp",
|
||||
dev->le_seen);
|
||||
|
||||
if (dev->uuids) {
|
||||
GSList *l;
|
||||
@ -374,7 +380,6 @@ static void cache_device(struct device *new_dev)
|
||||
|
||||
cache:
|
||||
cached_devices = g_slist_prepend(cached_devices, new_dev);
|
||||
new_dev->timestamp = time(NULL);
|
||||
store_device_info(new_dev, CACHE_FILE);
|
||||
}
|
||||
|
||||
@ -392,13 +397,14 @@ static struct device *create_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type)
|
||||
|
||||
if (bdaddr_type == BDADDR_BREDR) {
|
||||
dev->bredr = true;
|
||||
dev->bredr_seen = time(NULL);
|
||||
} else {
|
||||
dev->le = true;
|
||||
dev->bdaddr_type = bdaddr_type;
|
||||
dev->le_seen = time(NULL);
|
||||
}
|
||||
|
||||
dev->bond_state = HAL_BOND_STATE_NONE;
|
||||
dev->timestamp = time(NULL);
|
||||
|
||||
/*
|
||||
* Use address for name, will be change if one is present
|
||||
@ -1400,6 +1406,11 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
|
||||
|
||||
dev = get_device(bdaddr, bdaddr_type);
|
||||
|
||||
if (bdaddr_type == BDADDR_BREDR)
|
||||
dev->bredr_seen = time(NULL);
|
||||
else
|
||||
dev->le_seen = time(NULL);
|
||||
|
||||
/*
|
||||
* Device found event needs to be send also for known device if this is
|
||||
* new discovery session. Otherwise framework will ignore it.
|
||||
@ -2178,8 +2189,13 @@ static struct device *create_device_from_info(GKeyFile *key_file,
|
||||
|
||||
dev->class = g_key_file_get_integer(key_file, peer, "Class", NULL);
|
||||
|
||||
dev->timestamp = g_key_file_get_integer(key_file, peer, "Timestamp",
|
||||
NULL);
|
||||
if (dev->bredr)
|
||||
dev->bredr_seen = g_key_file_get_integer(key_file, peer,
|
||||
"Timestamp",
|
||||
NULL);
|
||||
else
|
||||
dev->le_seen = g_key_file_get_integer(key_file, peer,
|
||||
"Timestamp", NULL);
|
||||
|
||||
uuids = g_key_file_get_string_list(key_file, peer, "Services", NULL,
|
||||
NULL);
|
||||
@ -2279,12 +2295,27 @@ failed:
|
||||
return info;
|
||||
}
|
||||
|
||||
static time_t device_timestamp(const struct device *dev)
|
||||
{
|
||||
if (dev->bredr && dev->le) {
|
||||
if (dev->le_seen > dev->bredr_seen)
|
||||
return dev->le_seen;
|
||||
|
||||
return dev->bredr_seen;
|
||||
}
|
||||
|
||||
if (dev->bredr)
|
||||
return dev->bredr_seen;
|
||||
|
||||
return dev->le_seen;
|
||||
}
|
||||
|
||||
static int device_timestamp_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct device *deva = a;
|
||||
const struct device *devb = b;
|
||||
|
||||
return deva->timestamp < devb->timestamp;
|
||||
return device_timestamp(deva) < device_timestamp(devb);
|
||||
}
|
||||
|
||||
static void load_devices_cache(void)
|
||||
@ -3211,6 +3242,18 @@ static void pair_device_complete(uint8_t status, uint16_t length,
|
||||
HAL_BOND_STATE_NONE);
|
||||
}
|
||||
|
||||
static uint8_t select_device_bearer(struct device *dev)
|
||||
{
|
||||
if (dev->bredr && dev->le) {
|
||||
if (dev->le_seen > dev->bredr_seen)
|
||||
return dev->bdaddr_type;
|
||||
|
||||
return BDADDR_BREDR;
|
||||
}
|
||||
|
||||
return dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
|
||||
}
|
||||
|
||||
static void handle_create_bond_cmd(const void *buf, uint16_t len)
|
||||
{
|
||||
const struct hal_cmd_create_bond *cmd = buf;
|
||||
@ -3229,7 +3272,7 @@ static void handle_create_bond_cmd(const void *buf, uint16_t len)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
|
||||
cp.addr.type = select_device_bearer(dev);
|
||||
|
||||
if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter.index, sizeof(cp),
|
||||
&cp, pair_device_complete, NULL, NULL) == 0) {
|
||||
@ -3261,8 +3304,7 @@ static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cp.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
|
||||
|
||||
cp.type = select_device_bearer(dev);
|
||||
|
||||
if (mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE,
|
||||
adapter.index, sizeof(cp), &cp,
|
||||
@ -3312,7 +3354,7 @@ static void handle_remove_bond_cmd(const void *buf, uint16_t len)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
|
||||
cp.addr.type = select_device_bearer(dev);
|
||||
|
||||
if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
|
||||
sizeof(cp), &cp, unpair_device_complete,
|
||||
@ -3550,8 +3592,12 @@ static uint8_t get_device_version_info(struct device *dev)
|
||||
|
||||
static uint8_t get_device_timestamp(struct device *dev)
|
||||
{
|
||||
uint32_t timestamp;
|
||||
|
||||
timestamp = device_timestamp(dev);
|
||||
|
||||
send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_TIMESTAMP,
|
||||
sizeof(dev->timestamp), &dev->timestamp);
|
||||
sizeof(timestamp), ×tamp);
|
||||
|
||||
return HAL_STATUS_SUCCESS;
|
||||
}
|
||||
@ -3562,6 +3608,7 @@ static void get_remote_device_props(struct device *dev)
|
||||
struct hal_ev_remote_device_props *ev = (void *) buf;
|
||||
uint128_t uuids[g_slist_length(dev->uuids)];
|
||||
uint8_t android_type;
|
||||
uint32_t timestamp;
|
||||
int size, i;
|
||||
GSList *l;
|
||||
|
||||
@ -3606,8 +3653,10 @@ static void get_remote_device_props(struct device *dev)
|
||||
uuids);
|
||||
ev->num_props++;
|
||||
|
||||
timestamp = get_device_timestamp(dev);
|
||||
|
||||
size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TIMESTAMP,
|
||||
sizeof(dev->timestamp), &dev->timestamp);
|
||||
sizeof(timestamp), ×tamp);
|
||||
ev->num_props++;
|
||||
|
||||
ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
|
||||
|
Loading…
Reference in New Issue
Block a user