core: Fix BR/EDR pairing for dual mode devices
For dual mode devices we need to pass address type used in pairing
events to reply with correct one on agent reply. Otherwise reply for
BR/EDR pairing of dual mode device would use address type (which is
valid only for LE address) resulting in reply being ignored by kernel
and eventually pairing timeout.
diff --git a/src/adapter.c b/src/adapter.c
index 11f9394..5d7a9a9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -6302,7 +6302,7 @@
return;
}
- err = device_confirm_passkey(device, btohl(ev->value),
+ err = device_confirm_passkey(device, ev->addr.type, btohl(ev->value),
ev->confirm_hint);
if (err < 0) {
btd_error(adapter->dev_id,
@@ -6376,7 +6376,7 @@
return;
}
- err = device_request_passkey(device);
+ err = device_request_passkey(device, ev->addr.type);
if (err < 0) {
btd_error(adapter->dev_id,
"device_request_passkey: %s", strerror(-err));
@@ -6415,7 +6415,8 @@
DBG("passkey %06u entered %u", passkey, ev->entered);
- err = device_notify_passkey(device, passkey, ev->entered);
+ err = device_notify_passkey(device, ev->addr.type, passkey,
+ ev->entered);
if (err < 0)
btd_error(adapter->dev_id,
"device_notify_passkey: %s", strerror(-err));
diff --git a/src/device.c b/src/device.c
index 8f78b98..99454a7 100644
--- a/src/device.c
+++ b/src/device.c
@@ -127,6 +127,7 @@
auth_type_t type;
struct agent *agent;
struct btd_device *device;
+ uint8_t addr_type;
uint32_t passkey;
char *pincode;
gboolean secure;
@@ -5624,7 +5625,7 @@
return;
btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
- device->bdaddr_type,
+ auth->addr_type,
err ? FALSE : TRUE);
agent_unref(device->authr->agent);
@@ -5645,7 +5646,7 @@
passkey = INVALID_PASSKEY;
btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
- device->bdaddr_type, passkey);
+ auth->addr_type, passkey);
agent_unref(device->authr->agent);
device->authr->agent = NULL;
@@ -5663,7 +5664,9 @@
}
static struct authentication_req *new_auth(struct btd_device *device,
- auth_type_t type, gboolean secure)
+ uint8_t addr_type,
+ auth_type_t type,
+ gboolean secure)
{
struct authentication_req *auth;
struct agent *agent;
@@ -5691,6 +5694,7 @@
auth->agent = agent;
auth->device = device;
auth->type = type;
+ auth->addr_type = addr_type;
auth->secure = secure;
device->authr = auth;
@@ -5702,7 +5706,7 @@
struct authentication_req *auth;
int err;
- auth = new_auth(device, AUTH_TYPE_PINCODE, secure);
+ auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure);
if (!auth)
return -EPERM;
@@ -5716,12 +5720,12 @@
return err;
}
-int device_request_passkey(struct btd_device *device)
+int device_request_passkey(struct btd_device *device, uint8_t type)
{
struct authentication_req *auth;
int err;
- auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE);
+ auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE);
if (!auth)
return -EPERM;
@@ -5735,14 +5739,13 @@
return err;
}
-int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
- uint8_t confirm_hint)
-
+int device_confirm_passkey(struct btd_device *device, uint8_t type,
+ int32_t passkey, uint8_t confirm_hint)
{
struct authentication_req *auth;
int err;
- auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE);
+ auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE);
if (!auth)
return -EPERM;
@@ -5763,8 +5766,8 @@
return err;
}
-int device_notify_passkey(struct btd_device *device, uint32_t passkey,
- uint8_t entered)
+int device_notify_passkey(struct btd_device *device, uint8_t type,
+ uint32_t passkey, uint8_t entered)
{
struct authentication_req *auth;
int err;
@@ -5774,7 +5777,7 @@
if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
return -EPERM;
} else {
- auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
+ auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
if (!auth)
return -EPERM;
}
@@ -5794,7 +5797,7 @@
struct authentication_req *auth;
int err;
- auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure);
+ auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure);
if (!auth)
return -EPERM;
diff --git a/src/device.h b/src/device.h
index 93a159a..3cab366 100644
--- a/src/device.h
+++ b/src/device.h
@@ -111,11 +111,11 @@
long device_bonding_last_duration(struct btd_device *device);
void device_bonding_restart_timer(struct btd_device *device);
int device_request_pincode(struct btd_device *device, gboolean secure);
-int device_request_passkey(struct btd_device *device);
-int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
- uint8_t confirm_hint);
-int device_notify_passkey(struct btd_device *device, uint32_t passkey,
- uint8_t entered);
+int device_request_passkey(struct btd_device *device, uint8_t type);
+int device_confirm_passkey(struct btd_device *device, uint8_t type,
+ int32_t passkey, uint8_t confirm_hint);
+int device_notify_passkey(struct btd_device *device, uint8_t type,
+ uint32_t passkey, uint8_t entered);
int device_notify_pincode(struct btd_device *device, gboolean secure,
const char *pincode);
void device_cancel_authentication(struct btd_device *device, gboolean aborted);