From 9f1260b4a63bd8af511ca62c7adc739888efca3b Mon Sep 17 00:00:00 2001 From: Seungyoun Ju Date: Wed, 23 Jan 2019 15:52:15 +0900 Subject: [PATCH] Support getting LE Local OOB Data [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 --- plugins/dbusoob.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/adapter.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/adapter.h | 5 +++++ 3 files changed, 111 insertions(+) diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c index f8f3551..bb37d99 100755 --- a/plugins/dbusoob.c +++ b/plugins/dbusoob.c @@ -139,6 +139,63 @@ static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg, 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) { @@ -223,6 +280,8 @@ static const GDBusMethodTable oob_methods[] = { {"hash192", "ay" }, { "randomizer192", "ay" }, {"hash256", "ay" }, { "randomizer256", "ay" }), read_local_data) }, + { GDBUS_ASYNC_METHOD("LEReadLocalData", + NULL, GDBUS_ARGS({"eir", "ay" }), le_read_local_data) }, { } }; diff --git a/src/adapter.c b/src/adapter.c index a6249e8..0cf6c10 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -12962,6 +12962,53 @@ int btd_adapter_read_local_oob_data(struct btd_adapter *adapter) 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) diff --git a/src/adapter.h b/src/adapter.h index 4dd060c..b7e9e70 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -93,6 +93,8 @@ typedef void (*oob_ext_read_local_cb_t) (struct btd_adapter *adapter, 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, @@ -105,6 +107,7 @@ typedef void (*oob_bonding_cb_t) (struct btd_adapter *adapter, 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 @@ -266,6 +269,8 @@ int adapter_set_io_capability(struct btd_adapter *adapter, uint8_t io_cap); 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); -- 2.7.4