| Index: device/bluetooth/test/bluetooth_test_win.cc
|
| diff --git a/device/bluetooth/test/bluetooth_test_win.cc b/device/bluetooth/test/bluetooth_test_win.cc
|
| index 7a8f8f8ac51d184230bc8e715219b1be59bd5019..0bd28a3f6a847894bbd7a7b65464d87f515af179 100644
|
| --- a/device/bluetooth/test/bluetooth_test_win.cc
|
| +++ b/device/bluetooth/test/bluetooth_test_win.cc
|
| @@ -8,6 +8,8 @@
|
| #include "base/strings/sys_string_conversions.h"
|
| #include "device/bluetooth/bluetooth_adapter_win.h"
|
| #include "device/bluetooth/bluetooth_low_energy_win.h"
|
| +#include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h"
|
| +#include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
|
|
|
| namespace {
|
|
|
| @@ -25,16 +27,56 @@ BLUETOOTH_ADDRESS CanonicalStringToBLUETOOTH_ADDRESS(
|
| return win_addr;
|
| }
|
|
|
| +// The canonical UUID string format is device::BluetoothUUID.value().
|
| +BTH_LE_UUID CanonicalStringToBTH_LE_UUID(std::string uuid) {
|
| + BTH_LE_UUID win_uuid = {0};
|
| + if (uuid.size() == 4) {
|
| + win_uuid.IsShortUuid = TRUE;
|
| + unsigned int data[1];
|
| + int result = sscanf_s(uuid.c_str(), "%04x", &data[0]);
|
| + CHECK(result == 1);
|
| + win_uuid.Value.ShortUuid = data[0];
|
| + } else if (uuid.size() == 36) {
|
| + win_uuid.IsShortUuid = FALSE;
|
| + unsigned int data[11];
|
| + int result = sscanf_s(
|
| + uuid.c_str(), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
| + &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6],
|
| + &data[7], &data[8], &data[9], &data[10]);
|
| + CHECK(result == 11);
|
| + win_uuid.Value.LongUuid.Data1 = data[0];
|
| + win_uuid.Value.LongUuid.Data2 = data[1];
|
| + win_uuid.Value.LongUuid.Data3 = data[2];
|
| + win_uuid.Value.LongUuid.Data4[0] = data[3];
|
| + win_uuid.Value.LongUuid.Data4[1] = data[4];
|
| + win_uuid.Value.LongUuid.Data4[2] = data[5];
|
| + win_uuid.Value.LongUuid.Data4[3] = data[6];
|
| + win_uuid.Value.LongUuid.Data4[4] = data[7];
|
| + win_uuid.Value.LongUuid.Data4[5] = data[8];
|
| + win_uuid.Value.LongUuid.Data4[6] = data[9];
|
| + win_uuid.Value.LongUuid.Data4[7] = data[10];
|
| + } else {
|
| + CHECK(false);
|
| + }
|
| +
|
| + return win_uuid;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace device {
|
| BluetoothTestWin::BluetoothTestWin()
|
| : ui_task_runner_(new base::TestSimpleTaskRunner()),
|
| - bluetooth_task_runner_(new base::TestSimpleTaskRunner()) {}
|
| + bluetooth_task_runner_(new base::TestSimpleTaskRunner()),
|
| + adapter_win_(nullptr),
|
| + fake_bt_classic_wrapper_(nullptr),
|
| + fake_bt_le_wrapper_(nullptr) {}
|
| BluetoothTestWin::~BluetoothTestWin() {}
|
|
|
| bool BluetoothTestWin::PlatformSupportsLowEnergy() {
|
| - return win::IsBluetoothLowEnergySupported();
|
| + if (fake_bt_le_wrapper_)
|
| + return fake_bt_le_wrapper_->IsBluetoothLowEnergySupported();
|
| + return true;
|
| }
|
|
|
| void BluetoothTestWin::AdapterInitCallback() {}
|
| @@ -110,12 +152,16 @@ BluetoothDevice* BluetoothTestWin::DiscoverLowEnergyDevice(int device_ordinal) {
|
| win::BLEDevice* simulated_device = fake_bt_le_wrapper_->SimulateBLEDevice(
|
| device_name, CanonicalStringToBLUETOOTH_ADDRESS(device_address));
|
| if (simulated_device != nullptr) {
|
| - if (!service_uuid_1.empty())
|
| - fake_bt_le_wrapper_->SimulateBLEGattService(simulated_device,
|
| - service_uuid_1);
|
| - if (!service_uuid_2.empty())
|
| - fake_bt_le_wrapper_->SimulateBLEGattService(simulated_device,
|
| - service_uuid_2);
|
| + if (!service_uuid_1.empty()) {
|
| + fake_bt_le_wrapper_->SimulateBLEGattService(
|
| + simulated_device, nullptr,
|
| + CanonicalStringToBTH_LE_UUID(service_uuid_1));
|
| + }
|
| + if (!service_uuid_2.empty()) {
|
| + fake_bt_le_wrapper_->SimulateBLEGattService(
|
| + simulated_device, nullptr,
|
| + CanonicalStringToBTH_LE_UUID(service_uuid_2));
|
| + }
|
| }
|
| bluetooth_task_runner_->RunPendingTasks();
|
| ui_task_runner_->RunPendingTasks();
|
| @@ -148,9 +194,140 @@ void BluetoothTestWin::SimulateGattServicesDiscovered(
|
| CHECK(simulated_device);
|
|
|
| for (auto uuid : uuids) {
|
| - fake_bt_le_wrapper_->SimulateBLEGattService(simulated_device, uuid);
|
| + fake_bt_le_wrapper_->SimulateBLEGattService(
|
| + simulated_device, nullptr, CanonicalStringToBTH_LE_UUID(uuid));
|
| + }
|
| +
|
| + bluetooth_task_runner_->RunPendingTasks();
|
| + ui_task_runner_->RunPendingTasks();
|
| +}
|
| +
|
| +void BluetoothTestWin::SimulateGattServiceRemoved(
|
| + BluetoothGattService* service) {
|
| + std::string device_address = service->GetDevice()->GetAddress();
|
| + win::BLEDevice* target_device =
|
| + fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address);
|
| + CHECK(target_device);
|
| +
|
| + BluetoothRemoteGattServiceWin* win_service =
|
| + static_cast<BluetoothRemoteGattServiceWin*>(service);
|
| + std::string service_att_handle =
|
| + std::to_string(win_service->GetAttributeHandle());
|
| + if (service->IsPrimary()) {
|
| + fake_bt_le_wrapper_->SimulateBLEGattServiceRemoved(target_device, nullptr,
|
| + service_att_handle);
|
| + } else {
|
| + win::BLEGattService* target_service =
|
| + GetSimulatedService(target_device, win_service->GetParentService());
|
| + fake_bt_le_wrapper_->SimulateBLEGattServiceRemoved(
|
| + target_device, target_service, service_att_handle);
|
| + }
|
| +
|
| + ForceRefreshDevice();
|
| +}
|
| +
|
| +void BluetoothTestWin::SimulateGattCharacteristic(BluetoothGattService* service,
|
| + const std::string& uuid,
|
| + int properties) {
|
| + std::string device_address = service->GetDevice()->GetAddress();
|
| + win::BLEDevice* target_device =
|
| + fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address);
|
| + CHECK(target_device);
|
| + win::BLEGattService* target_service =
|
| + GetSimulatedService(target_device, service);
|
| + CHECK(target_service);
|
| +
|
| + BTH_LE_GATT_CHARACTERISTIC win_cha_info;
|
| + win_cha_info.CharacteristicUuid = CanonicalStringToBTH_LE_UUID(uuid);
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_BROADCAST)
|
| + win_cha_info.IsBroadcastable = TRUE;
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_READ)
|
| + win_cha_info.IsReadable = TRUE;
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE)
|
| + win_cha_info.IsWritableWithoutResponse = TRUE;
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_WRITE)
|
| + win_cha_info.IsWritable = TRUE;
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_NOTIFY)
|
| + win_cha_info.IsNotifiable = TRUE;
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_INDICATE)
|
| + win_cha_info.IsIndicatable = TRUE;
|
| + if (properties &
|
| + BluetoothGattCharacteristic::PROPERTY_AUTHENTICATED_SIGNED_WRITES)
|
| + win_cha_info.IsSignedWritable = TRUE;
|
| + if (properties & BluetoothGattCharacteristic::PROPERTY_EXTENDED_PROPERTIES)
|
| + win_cha_info.HasExtendedProperties = TRUE;
|
| + fake_bt_le_wrapper_->SimulateBLEGattCharacterisc(
|
| + device_address, target_service, win_cha_info);
|
| +
|
| + ForceRefreshDevice();
|
| +}
|
| +
|
| +void BluetoothTestWin::SimulateGattCharacteristicRemoved(
|
| + BluetoothGattService* service,
|
| + BluetoothGattCharacteristic* characteristic) {
|
| + CHECK(service);
|
| + CHECK(characteristic);
|
| +
|
| + std::string device_address = service->GetDevice()->GetAddress();
|
| + win::BLEGattService* target_service = GetSimulatedService(
|
| + fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address), service);
|
| + CHECK(target_service);
|
| +
|
| + std::string characteristic_att_handle = std::to_string(
|
| + static_cast<BluetoothRemoteGattCharacteristicWin*>(characteristic)
|
| + ->GetAttributeHandle());
|
| + fake_bt_le_wrapper_->SimulateBLEGattCharacteriscRemove(
|
| + target_service, characteristic_att_handle);
|
| +
|
| + ForceRefreshDevice();
|
| +}
|
| +
|
| +void BluetoothTestWin::SimulateIncludedGattServicesDiscovered(
|
| + BluetoothGattService* service,
|
| + const std::vector<std::string>& uuids) {
|
| + std::string device_address = service->GetDevice()->GetAddress();
|
| + win::BLEDevice* target_device =
|
| + fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address);
|
| + CHECK(target_device);
|
| + win::BLEGattService* target_service =
|
| + GetSimulatedService(target_device, service);
|
| + CHECK(target_service);
|
| +
|
| + for (const auto& uuid : uuids) {
|
| + fake_bt_le_wrapper_->SimulateBLEGattService(
|
| + target_device, target_service, CanonicalStringToBTH_LE_UUID(uuid));
|
| + }
|
| +
|
| + ForceRefreshDevice();
|
| +}
|
| +
|
| +win::BLEGattService* BluetoothTestWin::GetSimulatedService(
|
| + win::BLEDevice* device,
|
| + BluetoothGattService* service) {
|
| + CHECK(device);
|
| + CHECK(service);
|
| +
|
| + std::vector<std::string> chain_of_att_handles;
|
| + BluetoothRemoteGattServiceWin* win_service =
|
| + static_cast<BluetoothRemoteGattServiceWin*>(service);
|
| + while (!win_service->IsPrimary()) {
|
| + chain_of_att_handles.insert(
|
| + chain_of_att_handles.begin(),
|
| + std::to_string(win_service->GetAttributeHandle()));
|
| + win_service = win_service->GetParentService();
|
| }
|
| + chain_of_att_handles.insert(
|
| + chain_of_att_handles.begin(),
|
| + std::to_string(win_service->GetAttributeHandle()));
|
| + win::BLEGattService* simulated_service =
|
| + fake_bt_le_wrapper_->GetSimulatedGattService(device,
|
| + chain_of_att_handles);
|
| + CHECK(simulated_service);
|
| + return simulated_service;
|
| +}
|
|
|
| +void BluetoothTestWin::ForceRefreshDevice() {
|
| + adapter_win_->force_update_device_for_test_ = true;
|
| bluetooth_task_runner_->RunPendingTasks();
|
| ui_task_runner_->RunPendingTasks();
|
| }
|
|
|