Chromium Code Reviews| Index: device/bluetooth/bluetooth_low_energy_win_fake.cc |
| diff --git a/device/bluetooth/bluetooth_low_energy_win_fake.cc b/device/bluetooth/bluetooth_low_energy_win_fake.cc |
| index d1ef1df5148e3d248fe2b29ba8e0337248f6b25a..594f980fa7daa40041476b9a6599b863c2eccaab 100644 |
| --- a/device/bluetooth/bluetooth_low_energy_win_fake.cc |
| +++ b/device/bluetooth/bluetooth_low_energy_win_fake.cc |
| @@ -4,33 +4,197 @@ |
| #include "device/bluetooth/bluetooth_low_energy_win_fake.h" |
| +#include "base/strings/stringprintf.h" |
| + |
| +namespace { |
| +const char kPlatformNotSupported[] = |
| + "Bluetooth Low energy is only supported on Windows 8 and later."; |
| +} // namespace |
| + |
| namespace device { |
| namespace win { |
| -BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() {} |
| +BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() { |
| + simulated_devices_.clear(); |
|
scheib
2016/02/07 02:24:08
At constructor, shouldn't it already be empty()?
gogerald1
2016/02/08 19:23:50
Done.
|
| +} |
| BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {} |
| bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyDevices( |
| ScopedVector<BluetoothLowEnergyDeviceInfo>* devices, |
| std::string* error) { |
| - NOTIMPLEMENTED(); |
| - return false; |
| + if (!IsBluetoothLowEnergySupported()) { |
| + *error = kPlatformNotSupported; |
| + return false; |
| + } |
| + |
| + for (auto device : simulated_devices_) { |
| + BluetoothLowEnergyDeviceInfo* device_info = |
| + new BluetoothLowEnergyDeviceInfo(); |
| + *device_info = *(device.second->device_info); |
| + devices->push_back(device_info); |
| + } |
| + return true; |
| } |
| bool BluetoothLowEnergyWrapperFake:: |
| EnumerateKnownBluetoothLowEnergyGattServiceDevices( |
| ScopedVector<BluetoothLowEnergyDeviceInfo>* devices, |
| std::string* error) { |
| - NOTIMPLEMENTED(); |
| - return false; |
| + if (!IsBluetoothLowEnergySupported()) { |
| + *error = kPlatformNotSupported; |
| + return false; |
| + } |
| + |
| + for (auto device : simulated_devices_) { |
| + for (auto service : device.second->primary_services) { |
| + BluetoothLowEnergyDeviceInfo* device_info = |
| + new BluetoothLowEnergyDeviceInfo(); |
| + *device_info = *(device.second->device_info); |
| + // Fake file path of a GATT service device is |
| + // "device_file_path/service_attribute_handle". |
| + base::string16 path = |
| + device.second->device_info->path.value() + L"/" + |
| + std::to_wstring(service.second->service_info->AttributeHandle); |
| + device_info->path = base::FilePath(path); |
| + devices->push_back(device_info); |
| + } |
| + } |
| + return true; |
| } |
| bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyServices( |
| const base::FilePath& device_path, |
| ScopedVector<BluetoothLowEnergyServiceInfo>* services, |
| std::string* error) { |
| - NOTIMPLEMENTED(); |
| - return false; |
| + if (!IsBluetoothLowEnergySupported()) { |
| + *error = kPlatformNotSupported; |
| + return false; |
| + } |
| + |
| + base::string16 device_address; |
| + base::string16 service_attribute_handle; |
| + base::string16 path = device_path.value(); |
| + std::size_t found = path.find('/'); |
|
scheib
2016/02/07 02:24:08
Comment to reference above the expected format of
gogerald1
2016/02/08 19:23:50
Done.
|
| + if (found != base::string16::npos) { |
| + device_address = path.substr(0, found - 1); |
| + service_attribute_handle = path.substr(found + 1); |
| + } else { |
| + device_address = path; |
| + } |
| + |
| + BLEDevicesMap::iterator it_d = simulated_devices_.find( |
| + std::string(device_address.begin(), device_address.end())); |
| + CHECK(it_d != simulated_devices_.end()); |
| + |
| + if (!service_attribute_handle.empty()) { |
|
scheib
2016/02/07 02:24:08
Comment explaining what's going on when no service
gogerald1
2016/02/08 19:23:50
Done.
|
| + BLEGattServicesMap::iterator it_s = |
| + it_d->second->primary_services.find(std::string( |
| + service_attribute_handle.begin(), service_attribute_handle.end())); |
| + CHECK(it_s != it_d->second->primary_services.end()); |
| + BluetoothLowEnergyServiceInfo* service_info = |
| + new BluetoothLowEnergyServiceInfo(); |
| + service_info->uuid = it_s->second->service_info->ServiceUuid; |
| + service_info->attribute_handle = |
| + it_s->second->service_info->AttributeHandle; |
| + services->push_back(service_info); |
| + } else { |
| + for (auto primary_service : it_d->second->primary_services) { |
| + BluetoothLowEnergyServiceInfo* service_info = |
| + new BluetoothLowEnergyServiceInfo(); |
| + service_info->uuid = primary_service.second->service_info->ServiceUuid; |
| + service_info->attribute_handle = |
| + primary_service.second->service_info->AttributeHandle; |
| + services->push_back(service_info); |
| + } |
| + } |
| + |
| + return true; |
| +} |
| + |
| +BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice( |
| + std::string device_name, |
| + BLUETOOTH_ADDRESS device_address) { |
| + BLEDevice* device = new BLEDevice(); |
| + BluetoothLowEnergyDeviceInfo* device_info = |
| + new BluetoothLowEnergyDeviceInfo(); |
| + // Use string of device address as fake file path of the device. |
| + std::string string_device_address = |
| + BluetoothAddressToCanonicalString(device_address); |
| + device_info->path = base::FilePath(base::string16( |
| + string_device_address.begin(), string_device_address.end())); |
| + device_info->friendly_name = device_name; |
| + device_info->address = device_address; |
| + device->device_info.reset(device_info); |
| + simulated_devices_.set(string_device_address, scoped_ptr<BLEDevice>(device)); |
| + return device; |
| +} |
| + |
| +BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService( |
| + BLEDevice* device, |
| + std::string uuid) { |
| + CHECK(device); |
| + |
| + BLEGattService* service = new BLEGattService(); |
| + PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1]; |
| + std::string string_device_address = |
| + BluetoothAddressToCanonicalString(device->device_info->address); |
| + service_info->AttributeHandle = |
| + GenerateAnUniqueAttributeHandle(string_device_address); |
| + service_info->ServiceUuid = CanonicalStringToBTH_LE_UUID(uuid); |
| + service->service_info.reset(service_info); |
| + device->primary_services.set(std::to_string(service_info->AttributeHandle), |
| + scoped_ptr<BLEGattService>(service)); |
| + return service; |
| +} |
| + |
| +USHORT BluetoothLowEnergyWrapperFake::GenerateAnUniqueAttributeHandle( |
| + std::string device_address) { |
| + BLEAttributeHandleTable::iterator it = |
| + attribute_handle_table_.find(device_address); |
| + if (it != attribute_handle_table_.end()) { |
| + USHORT max_attribute_handle = *(it->second->rbegin()); |
|
scheib
2016/02/07 02:24:08
it->second is reference a few times in this method
gogerald1
2016/02/08 19:23:51
It seems base::ScopedPtrHashMap does not implement
|
| + if (max_attribute_handle < 0xFFFF) { |
| + USHORT new_attribute_handle = max_attribute_handle + 1; |
| + it->second->insert(new_attribute_handle); |
| + return new_attribute_handle; |
| + } else { |
| + USHORT i = 1; |
| + for (; i < 0xFFFF; i++) { |
| + if (it->second->find(i) == it->second->end()) |
| + break; |
| + } |
| + if (i >= 0xFFFF) |
| + return 0; |
| + it->second->insert(i); |
| + return i; |
| + } |
| + } |
| + |
| + USHORT smallest_att_handle = 1; |
| + std::set<USHORT>* new_set = new std::set<USHORT>(); |
| + new_set->insert(smallest_att_handle); |
| + attribute_handle_table_.set(device_address, |
| + scoped_ptr<std::set<USHORT>>(new_set)); |
| + return smallest_att_handle; |
| +} |
| + |
| +BTH_LE_UUID BluetoothLowEnergyWrapperFake::CanonicalStringToBTH_LE_UUID( |
| + std::string uuid) { |
| + BTH_LE_UUID win_uuid; |
| + win_uuid.IsShortUuid = true; |
| + unsigned int data[1]; |
| + int result = sscanf_s(uuid.c_str(), "%04x", &data[0]); |
|
scheib
2016/02/07 02:24:08
The device::BluetoothUUID.value() isn't always 4 h
gogerald1
2016/02/08 19:23:50
Yes.
gogerald1
2016/02/08 19:23:50
Done.
|
| + CHECK(result == 1); |
| + win_uuid.Value.ShortUuid = data[0]; |
| + return win_uuid; |
| +} |
| + |
| +std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( |
| + const BLUETOOTH_ADDRESS& btha) { |
| + std::string result = base::StringPrintf( |
| + "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4], |
| + btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]); |
| + return result; |
| } |
| } // namespace win |