[Problem] There is no interface to get LE local OOB Data
[Cause & Measure] Send MGMT_OP_READ_LOCAL_OOB_EXT_DATA to kernel to get
LE local OOB Data.
Result:
$ dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.bluez.OutOfBand.LEReadLocalData
method return time=
1548225479.022260 sender=:1.392 -> destination=:1.400 serial=94 reply_serial=2
array of bytes [
08 1b 86 a6 6a d6 ae 08 00 02 1c 01 11 22 71 05 07 3e 23 98 9b 54 c4 56
c4 b0 af 35 12 30 11 23 c4 3c 10 96 94 ad 99 19 9f 58 03 57 e7 5a ac 33
02 01 00
]
< ACL Data TX: Handle 65 flags 0x00 dlen 11
SMP: Pairing Request (0x01) len 6
IO capability: KeyboardDisplay (0x04)
OOB data: Authentication data from remote device present (0x01)
Authentication requirement: Bonding, MITM, SC, No Keypresses (0x0d)
Max encryption key size: 16
Initiator key distribution: EncKey IdKey Sign (0x07)
Responder key distribution: EncKey IdKey Sign (0x07)
> ACL Data RX: Handle 65 flags 0x02 dlen 11
SMP: Pairing Response (0x02) len 6
IO capability: DisplayOnly (0x00)
OOB data: Authentication data not present (0x00)
Authentication requirement: Bonding, MITM, SC, No Keypresses (0x0d)
Max encryption key size: 16
Initiator key distribution: EncKey IdKey Sign (0x07)
Responder key distribution: EncKey IdKey Sign (0x07)
< ACL Data TX: Handle 65 flags 0x00 dlen 69
SMP: Pairing Public Key (0x0c) len 64
X: cfb9cf0a6922f4c5368c7025f15193e183e895a7ba354d6283cbb6c9ac34aafc
Y: 9c0a76d625852440b0ccc08d56587f38f3f22a11950e3f2824e4ccc2505fd70f
> HCI Event: Number of Completed Packets (0x13) plen 5
Num handles: 1
Handle: 65
Count: 2
> ACL Data RX: Handle 65 flags 0x02 dlen 27
> ACL Data RX: Handle 65 flags 0x01 dlen 27
> ACL Data RX: Handle 65 flags 0x01 dlen 15
SMP: Pairing Public Key (0x0c) len 64
X: acec5a11f457c40138809e618865b8ead2ea1c5f71b38deb8e3bb76c64b219a8
Y: 9bc8d28c0f96d175c9661ec012af89b5b34f936a9a8ec6c39b75e12540eeaf76
< ACL Data TX: Handle 65 flags 0x00 dlen 21
SMP: Pairing Random (0x04) len 16
Random value:
a307ddd44443bfbba384cc26bd51012f
> ACL Data RX: Handle 65 flags 0x02 dlen 21
SMP: Pairing Random (0x04) len 16
Random value:
36bd1b4d18a5a3dfcdaefeae72cb380e
< ACL Data TX: Handle 65 flags 0x00 dlen 21
SMP: Pairing DHKey Check (0x0d) len 16
E:
02cb188687306cd5a10cd3788bd317f3
> HCI Event: Number of Completed Packets (0x13) plen 5
Num handles: 1
Handle: 65
Count: 2
> ACL Data RX: Handle 65 flags 0x02 dlen 21
SMP: Pairing DHKey Check (0x0d) len 16
E:
1970e360950cc322587d322f0c4e333a
< HCI Command: LE Start Encryption (0x08|0x0019) plen 28
Handle: 65
Random number: 0x0000000000000000
Encrypted diversifier: 0x0000
Long term key:
a818945751ab5c2e10c6de92ed1c9130
> HCI Event: Command Status (0x0f) plen 4
LE Start Encryption (0x08|0x0019) ncmd 1
Status: Success (0x00)
> HCI Event: Encryption Change (0x08) plen 4
Status: Success (0x00)
Handle: 65
Encryption: Enabled with AES-CCM (0x01)
Change-Id: I9e8e9bbc6c06b20938c653b71066d4f27a4028ad
return NULL;
}
+static void le_read_local_data_complete(struct btd_adapter *adapter,
+ const uint16_t eir_len, const uint8_t *eir, void *user_data)
+{
+ struct DBusMessage *reply;
+ struct oob_request *oob_request;
+
+ oob_request = find_oob_request(adapter);
+ if (!oob_request)
+ return;
+
+ if (eir_len > 0 && eir) {
+ reply = g_dbus_create_reply(oob_request->msg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &eir, eir_len, DBUS_TYPE_INVALID);
+ } else {
+ reply = btd_error_failed(oob_request->msg,
+ "Failed to le read local OOB data.");
+ }
+
+ oob_requests = g_slist_remove(oob_requests, oob_request);
+ dbus_message_unref(oob_request->msg);
+ g_free(oob_request);
+
+ if (!reply) {
+ error("Couldn't allocate D-Bus message");
+ return;
+ }
+
+ if (!g_dbus_send_message(connection, reply))
+ error("D-Bus send failed");
+}
+
+static DBusMessage *le_read_local_data(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ struct btd_adapter *adapter = data;
+ struct oob_request *oob_request;
+ struct oob_handler *handler;
+
+ if (find_oob_request(adapter))
+ return btd_error_in_progress(msg);
+
+ if (btd_adapter_le_read_local_oob_data(adapter))
+ return btd_error_failed(msg, "Request failed.");
+
+ oob_request = g_new(struct oob_request, 1);
+ oob_request->adapter = adapter;
+ oob_requests = g_slist_append(oob_requests, oob_request);
+ oob_request->msg = dbus_message_ref(msg);
+
+ handler = g_new0(struct oob_handler, 1);
+ handler->le_read_local_cb = le_read_local_data_complete;
+
+ btd_adapter_set_oob_handler(oob_request->adapter, handler);
+
+ return NULL;
+}
+
static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
void *data)
{
{"hash192", "ay" }, { "randomizer192", "ay" },
{"hash256", "ay" }, { "randomizer256", "ay" }),
read_local_data) },
+ { GDBUS_ASYNC_METHOD("LEReadLocalData",
+ NULL, GDBUS_ARGS({"eir", "ay" }), le_read_local_data) },
{ }
};
return -EIO;
}
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static void le_read_local_oob_data_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_local_oob_ext_data *rp = param;
+ struct btd_adapter *adapter = user_data;
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ btd_error(adapter->dev_id, "LE Read local OOB data failed: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ } else if (length < sizeof(struct mgmt_rp_read_local_oob_ext_data)) {
+ btd_error(adapter->dev_id,
+ "Too small read local OOB ext data response");
+ return;
+ }
+
+ if (!adapter->oob_handler || !adapter->oob_handler->le_read_local_cb) {
+ btd_error(adapter->dev_id, "oob_handler is not valid : %p",
+ adapter->oob_handler);
+ return;
+ }
+
+ adapter->oob_handler->le_read_local_cb(adapter, rp->eir_len, rp->eir,
+ adapter->oob_handler->user_data);
+
+ g_free(adapter->oob_handler);
+ adapter->oob_handler = NULL;
+}
+
+int btd_adapter_le_read_local_oob_data(struct btd_adapter *adapter)
+{
+ struct mgmt_cp_read_local_oob_ext_data cp;
+
+ DBG("hci%u", adapter->dev_id);
+
+ memset(&cp, 0, sizeof(cp));
+ cp.type = (1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM);
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
+ adapter->dev_id, sizeof(cp), &cp, le_read_local_oob_data_complete,
+ adapter, NULL) > 0)
+ return 0;
+
+ return -EIO;
+}
+#endif
+
void btd_adapter_for_each_device(struct btd_adapter *adapter,
void (*cb)(struct btd_device *device, void *data),
void *data)
const uint8_t *hash256,
const uint8_t *randomizer256,
void *user_data);
+typedef void (*le_oob_read_local_cb_t) (struct btd_adapter *adapter,
+ const uint16_t eir_len, const uint8_t *eir, void *user_data);
#endif
typedef void (*oob_read_local_cb_t) (struct btd_adapter *adapter,
const uint8_t *hash,
struct oob_handler {
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
oob_ext_read_local_cb_t read_local_cb;
+ le_oob_read_local_cb_t le_read_local_cb;
#else
oob_read_local_cb_t read_local_cb;
#endif
int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
+int btd_adapter_le_read_local_oob_data(struct btd_adapter *adapter);
+
int btd_adapter_add_remote_oob_data(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t *hash, uint8_t *randomizer);