"android/bluetooth/IBluetoothGattCallback.aidl",
"android/bluetooth/IBluetoothMetadataListener.aidl",
"android/bluetooth/IBluetoothGattServerCallback.aidl",
+ "android/bluetooth/IBluetoothOobDataCallback.aidl",
"android/bluetooth/le/IAdvertisingSetCallback.aidl",
"android/bluetooth/le/IPeriodicAdvertisingCallback.aidl",
"android/bluetooth/le/IScannerCallback.aidl"
"android/bluetooth/IBluetoothGattCallback.aidl",
"android/bluetooth/IBluetoothMetadataListener.aidl",
"android/bluetooth/IBluetoothGattServerCallback.aidl",
+ "android/bluetooth/IBluetoothOobDataCallback.aidl",
"android/bluetooth/le/IAdvertisingSetCallback.aidl",
"android/bluetooth/le/IPeriodicAdvertisingCallback.aidl",
"android/bluetooth/le/IScannerCallback.aidl",
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
import android.bluetooth.IBluetoothMetadataListener;
+import android.bluetooth.IBluetoothOobDataCallback;
import android.bluetooth.IBluetoothSocketManager;
import android.bluetooth.IBluetoothStateChangeCallback;
import android.bluetooth.BluetoothActivityEnergyInfo;
boolean unregisterBluetoothConnectionCallback(in IBluetoothConnectionCallback callback);
boolean canBondWithoutDialog(in BluetoothDevice device);
+ void generateLocalOobData(in int transport, IBluetoothOobDataCallback callback);
}
--- /dev/null
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.IBluetooth;
+import android.bluetooth.OobData;
+
+/**
+ * API for receiving OobData from the host stack
+ *
+ * {@hide}
+ */
+oneway interface IBluetoothOobDataCallback {
+ void onOobData(int transport, in OobData oobData);
+ void onError(int errorCode);
+}
void invoke_ssp_request_cb(RawAddress bd_addr, bt_bdname_t bd_name,
uint32_t cod, bt_ssp_variant_t pairing_variant,
uint32_t pass_key);
+void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c,
+ Octet16 r);
void invoke_bond_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_bond_state_t state);
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
void btif_dm_proc_loc_oob(bool valid, const Octet16& c, const Octet16& r);
bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, Octet16* p_c,
Octet16* p_r);
+void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport);
#endif /* BTIF_DM_OOB_TEST */
/*callout for reading SMP properties from Text file*/
return BT_STATUS_SUCCESS;
}
+static int generate_local_oob_data(tBT_TRANSPORT transport) {
+ LOG_INFO("%s", __func__);
+ if (!interface_ready()) return BT_STATUS_NOT_READY;
+
+ return do_in_main_thread(
+ FROM_HERE, base::BindOnce(btif_dm_generate_local_oob_data, transport));
+}
+
static int cancel_bond(const RawAddress* bd_addr) {
if (!interface_ready()) return BT_STATUS_NOT_READY;
obfuscate_address,
get_metric_id,
set_dynamic_audio_buffer_size,
-};
+ generate_local_oob_data};
// callback reporting helpers
bd_addr, bd_name, cod, pairing_variant, pass_key));
}
+void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c,
+ Octet16 r) {
+ LOG_INFO("%s", __func__);
+ bt_oob_data_t oob_data;
+ // Each value (for C and R) is 16 octets in length
+ bool c_empty = true;
+ for (int i = 0; i < 16; i++) {
+ // C cannot be all 0s, if so then we want to fail
+ if (c[i] != 0) c_empty = false;
+ oob_data.c[i] = c[i];
+ // R is optional and may be empty
+ oob_data.r[i] = r[i];
+ }
+ oob_data.is_valid = valid && !c_empty;
+ // The oob_data_length is 2 octects in length. The value includes the length
+ // of itself. 16 + 16 + 2 = 34 Data 0x0022 Little Endian order 0x2200
+ oob_data.oob_data_length[0] = 0;
+ oob_data.oob_data_length[1] = 34;
+ bt_status_t status = do_in_jni_thread(
+ FROM_HERE, base::BindOnce(
+ [](tBT_TRANSPORT t, bt_oob_data_t oob_data) {
+ HAL_CBACK(bt_hal_cbacks, generate_local_oob_data_cb, t,
+ oob_data);
+ },
+ t, oob_data));
+ if (status != BT_STATUS_SUCCESS) {
+ LOG_ERROR("%s: Failed to call callback!", __func__);
+ }
+}
+
void invoke_bond_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_bond_state_t state) {
do_in_jni_thread(
}
}
-void btif_dm_proc_loc_oob(bool valid, const Octet16& c, const Octet16& r) {
- FILE* fp;
- const char* path_a = "/data/misc/bluedroid/LOCAL/a.key";
- const char* path_b = "/data/misc/bluedroid/LOCAL/b.key";
- const char* path = NULL;
- char prop_oob[PROPERTY_VALUE_MAX];
- BTIF_TRACE_DEBUG("%s: valid=%d", __func__, valid);
- if (is_empty_128bit(oob_cb.p192_data.c) && valid) {
- BTIF_TRACE_DEBUG("save local OOB data in memory");
- memcpy(oob_cb.p192_data.c, c.data(), OCTET16_LEN);
- memcpy(oob_cb.p192_data.r, r.data(), OCTET16_LEN);
- osi_property_get("service.brcm.bt.oob", prop_oob, "3");
- BTIF_TRACE_DEBUG("%s: prop_oob = %s", __func__, prop_oob);
- if (prop_oob[0] == '1')
- path = path_a;
- else if (prop_oob[0] == '2')
- path = path_b;
- if (path) {
- fp = fopen(path, "wb+");
- if (fp == NULL) {
- BTIF_TRACE_DEBUG("%s: failed to save local OOB data to %s", __func__,
- path);
- } else {
- BTIF_TRACE_DEBUG("%s: save local OOB data into file %s", __func__,
- path);
- fwrite(c.data(), 1, OCTET16_LEN, fp);
- fwrite(r.data(), 1, OCTET16_LEN, fp);
- fclose(fp);
- }
- }
+/*******************************************************************************
+ *
+ * Function btif_dm_generate_local_oob_data
+ *
+ * Description Initiate oob data fetch from controller
+ *
+ * Parameters transport; Classic or LE
+ *
+ ******************************************************************************/
+void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport) {
+ if (transport == BT_TRANSPORT_BR_EDR) {
+ BTM_ReadLocalOobData();
+ } else if (transport == BT_TRANSPORT_LE) {
+ // TODO(184377951): Call LE Implementation (not yet implemented?)
+ } else {
+ BTIF_TRACE_ERROR("Bad transport type! %d", transport);
}
}
+void btif_dm_proc_loc_oob(bool valid, const Octet16& c, const Octet16& r) {
+ invoke_oob_data_request_cb(BT_TRANSPORT_BR_EDR, valid, c, r);
+}
+
/*******************************************************************************
*
* Function btif_dm_get_smp_config
#include "avrcp/avrcp.h"
#include "bluetooth/uuid.h"
+#include "bt_transport.h"
#include "raw_address.h"
/**
/** Represents the actual Out of Band data itself */
typedef struct {
// Both
+ bool is_valid = false; /* Default to invalid data; force caller to verify */
uint8_t address[7]; /* Bluetooth Device Address (6) plus Address Type (1) */
uint8_t c[16]; /* Simple Pairing Hash C-192/256 (Classic or LE) */
uint8_t r[16]; /* Simple Pairing Randomizer R-192/256 (Classic or LE) */
typedef void (*energy_info_callback)(bt_activity_energy_info* energy_info,
bt_uid_traffic_t* uid_data);
+/** Callback invoked when OOB data is returned from the controller */
+typedef void (*generate_local_oob_data_callback)(tBT_TRANSPORT transport,
+ bt_oob_data_t oob_data);
+
/** TODO: Add callbacks for Link Up/Down and other generic
* notifications/callbacks */
le_test_mode_callback le_test_mode_cb;
energy_info_callback energy_info_cb;
link_quality_report_callback link_quality_report_cb;
+ generate_local_oob_data_callback generate_local_oob_data_cb;
} bt_callbacks_t;
typedef void (*alarm_cb)(void* data);
* Set the dynamic audio buffer size to the Controller
*/
int (*set_dynamic_audio_buffer_size)(int codec, int size);
+
+ /**
+ * Fetches the local Out of Band data.
+ */
+ int (*generate_local_oob_data)(tBT_TRANSPORT transport);
} bt_interface_t;
#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"
return false;
}
-void btif_dm_proc_loc_oob(bool valid, const Octet16& c, const Octet16& r) {
+void btif_dm_proc_loc_oob(const Octet16& c, const Octet16& r) {
mock_function_count_map[__func__]++;
}
nullptr, /* dut_mode_recv_cb */
nullptr, /* le_test_mode_cb */
nullptr, /* energy_info_cb */
- LinkQualityReportCallback
+ LinkQualityReportCallback,
+ nullptr /* generate_local_oob_data_cb */
};
bt_os_callouts_t bt_os_callouts = {sizeof(bt_os_callouts_t),
nullptr, /* obfuscate_address */
nullptr, /* get_metric_id */
nullptr, /* set_dynamic_audio_buffer_size */
+ nullptr, /* generate_local_oob_data */
};
} // namespace