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 548286d3a2335deda27fa714774a568b128feae5..b5f039fa063f71370018be895b6425c3845d9cd7 100644 |
| --- a/device/bluetooth/bluetooth_low_energy_win_fake.cc |
| +++ b/device/bluetooth/bluetooth_low_energy_win_fake.cc |
| @@ -27,6 +27,9 @@ GattCharacteristic::~GattCharacteristic() {} |
| GattDescriptor::GattDescriptor() {} |
| GattDescriptor::~GattDescriptor() {} |
| +GattServiceObserver::GattServiceObserver() {} |
| +GattServiceObserver::~GattServiceObserver() {} |
| + |
| BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() |
| : observer_(nullptr) {} |
| BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {} |
| @@ -204,6 +207,8 @@ HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicValue( |
| for (ULONG i = 0; i < ret_value->DataSize; i++) |
| ret_value->Data[i] = target_characteristic->value->Data[i]; |
| out_value->reset(ret_value); |
| + if (observer_) |
| + observer_->OnReadGattCharacteristicValue(); |
| return S_OK; |
| } |
| @@ -214,7 +219,7 @@ HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue( |
| GattCharacteristic* target_characteristic = |
| GetSimulatedGattCharacteristic(service_path, characteristic); |
| if (target_characteristic == nullptr) |
| - return ERROR_NOT_FOUND; |
| + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| // Return error simulated by SimulateGattCharacteristicWriteError. |
| if (target_characteristic->write_errors.size()) { |
| @@ -232,7 +237,86 @@ HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue( |
| win_value->DataSize = new_value->DataSize; |
| target_characteristic->value.reset(win_value); |
| if (observer_) |
| - observer_->onWriteGattCharacteristicValue(win_value); |
| + observer_->OnWriteGattCharacteristicValue(win_value); |
| + return S_OK; |
| +} |
| + |
| +HRESULT BluetoothLowEnergyWrapperFake::RegisterGattEvents( |
|
ortuno
2016/03/14 01:37:37
I hope that from the description of the tests it b
gogerald1
2016/03/15 00:48:19
Done. until now I don't see specific error needs t
|
| + base::FilePath& service_path, |
| + BTH_LE_GATT_EVENT_TYPE type, |
| + PVOID event_parameter, |
| + PFNBLUETOOTH_GATT_EVENT_CALLBACK callback, |
| + PVOID context, |
| + BLUETOOTH_GATT_EVENT_HANDLE* out_handle) { |
| + base::string16 device_address = |
| + ExtractDeviceAddressFromDevicePath(service_path.value()); |
| + BLEDevice* target_device = GetSimulatedBLEDevice( |
| + std::string(device_address.begin(), device_address.end())); |
| + if (target_device == nullptr) |
| + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| + const std::vector<std::string> service_att_handles = |
| + ExtractServiceAttributeHandlesFromDevicePath(service_path.value()); |
| + GattService* target_service = |
| + GetSimulatedGattService(target_device, service_att_handles); |
| + if (target_service == nullptr) |
| + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| + |
| + PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION parameter = |
| + (PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION)event_parameter; |
| + for (USHORT i = 0; i < parameter->NumCharacteristics; i++) { |
| + GattCharacteristic* target_characteristic = GetSimulatedGattCharacteristic( |
| + target_service, |
| + std::to_string(parameter->Characteristics[i].AttributeHandle)); |
| + CHECK(target_characteristic); |
| + |
| + // Return error simulated by SimulateGattCharacteristicSetNotifyError. |
| + if (target_characteristic->notify_errors.size()) { |
| + HRESULT error = target_characteristic->notify_errors[0]; |
| + target_characteristic->notify_errors.erase( |
| + target_characteristic->notify_errors.begin()); |
| + return error; |
| + } |
| + |
| + // Get CCC descriptor. |
| + GattDescriptor* target_descriptor = GetCCCDescriptor(target_characteristic); |
| + if (target_descriptor == nullptr) |
| + return E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED; |
| + if (observer_) |
| + observer_->OnStartCharacteristicNotification(); |
| + |
| + // Return error simualted by SimulateGattDescriptorWriteError. |
| + if (target_descriptor->write_errors.size()) { |
| + HRESULT error = target_descriptor->write_errors[0]; |
| + target_descriptor->write_errors.erase( |
| + target_descriptor->write_errors.begin()); |
| + return error; |
| + } |
| + |
| + // Write CCC descriptor. |
| + std::vector<uint8_t> new_value; |
| + if (target_characteristic->characteristic_info->IsNotifiable) |
| + new_value.push_back(1); |
| + else if (target_characteristic->characteristic_info->IsIndicatable) |
| + new_value.push_back(2); |
| + else |
| + return E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED; |
| + new_value.push_back(0); |
| + SimulateGattDescriptorWrite(target_descriptor, new_value); |
| + } |
| + |
| + scoped_ptr<GattServiceObserver> observer(new GattServiceObserver()); |
| + observer->callback = callback; |
| + observer->context = context; |
| + *out_handle = (BLUETOOTH_GATT_EVENT_HANDLE)observer.get(); |
| + gatt_service_observers_[*out_handle] = std::move(observer); |
| + target_service->observers.push_back(*out_handle); |
| + |
| + return S_OK; |
| +} |
| + |
| +HRESULT BluetoothLowEnergyWrapperFake::UnregisterGattEvent( |
| + BLUETOOTH_GATT_EVENT_HANDLE event_handle) { |
| + gatt_service_observers_.erase(event_handle); |
| return S_OK; |
| } |
| @@ -377,6 +461,27 @@ void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicValue( |
| characteristic->value.reset(win_value); |
| } |
| +void BluetoothLowEnergyWrapperFake:: |
| + SimulateCharacteristicValueChangeNotification( |
| + GattService* parent_service, |
| + GattCharacteristic* characteristic) { |
| + for (auto observer : parent_service->observers) { |
|
ortuno
2016/03/14 01:37:37
Here you are making copies of the "BLUETOOTH_GATT_
gogerald1
2016/03/15 00:48:19
Done.
|
| + GattServiceObserverTable::iterator it = |
|
ortuno
2016/03/14 01:37:37
nit: You can use auto for iterators.
gogerald1
2016/03/15 00:48:19
Acknowledged. Here use GattServiceObserverTable::i
|
| + gatt_service_observers_.find(observer); |
| + // Check if |observer| has been unregistered by UnregisterGattEvent. |
| + if (it != gatt_service_observers_.end()) { |
| + BLUETOOTH_GATT_VALUE_CHANGED_EVENT event; |
| + event.ChangedAttributeHandle = |
| + characteristic->characteristic_info->AttributeHandle; |
| + event.CharacteristicValueDataSize = |
| + characteristic->value->DataSize + (ULONG)sizeof(ULONG); |
|
ortuno
2016/03/14 01:37:37
Why do you add the (ULONG)sizeof(ULONG)?
gogerald1
2016/03/15 00:48:19
Done. Mistake
|
| + event.CharacteristicValue = characteristic->value.get(); |
| + it->second->callback(CharacteristicValueChangedEvent, &event, |
| + it->second->context); |
| + } |
| + } |
| +} |
| + |
| void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicReadError( |
| GattCharacteristic* characteristic, |
| HRESULT error) { |
| @@ -391,6 +496,13 @@ void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicWriteError( |
| characteristic->write_errors.push_back(error); |
| } |
| +void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicSetNotifyError( |
| + GattCharacteristic* characteristic, |
| + HRESULT error) { |
| + CHECK(characteristic); |
| + characteristic->notify_errors.push_back(error); |
| +} |
| + |
| void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor( |
| std::string device_address, |
| GattCharacteristic* characteristic, |
| @@ -404,6 +516,34 @@ void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor( |
| descriptor->descriptor_info->AttributeHandle)] = std::move(descriptor); |
| } |
| +GattDescriptor* BluetoothLowEnergyWrapperFake::GetSimulatedDescriptor( |
| + GattCharacteristic* parent_characteristic, |
| + std::string attribute_handle) { |
| + GattDescriptorsMap::const_iterator it = |
| + parent_characteristic->included_descriptors.find(attribute_handle); |
| + if (it != parent_characteristic->included_descriptors.end()) |
| + return it->second.get(); |
| + return nullptr; |
| +} |
| + |
| +void BluetoothLowEnergyWrapperFake::SimulateGattDescriptorWrite( |
| + GattDescriptor* descriptor, |
| + const std::vector<uint8_t>& value) { |
| + ULONG length = (ULONG)(sizeof(BTH_LE_GATT_DESCRIPTOR_VALUE) + value.size()); |
| + descriptor->value.reset((BTH_LE_GATT_DESCRIPTOR_VALUE*)(new UCHAR[length])); |
| + descriptor->value->DataSize = (ULONG)value.size(); |
| + for (size_t i = 0; i < value.size(); i++) |
| + descriptor->value->Data[i] = value[i]; |
| + if (observer_) |
| + observer_->OnWriteGattDescriptorValue(descriptor->value.get()); |
| +} |
| + |
| +void BluetoothLowEnergyWrapperFake::SimulateGattDescriptorWriteError( |
| + GattDescriptor* descriptor, |
| + HRESULT error) { |
| + descriptor->write_errors.push_back(error); |
| +} |
| + |
| void BluetoothLowEnergyWrapperFake::AddObserver(Observer* observer) { |
| observer_ = observer; |
| } |
| @@ -513,5 +653,29 @@ std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( |
| return result; |
| } |
| +GattDescriptor* BluetoothLowEnergyWrapperFake::GetCCCDescriptor( |
| + GattCharacteristic* characteristic) { |
| + for (const auto& d : characteristic->included_descriptors) { |
| + const BTH_LE_UUID* uuid = &(d.second->descriptor_info->DescriptorUuid); |
| + if (uuid->IsShortUuid) |
| + continue; |
| + |
| + std::string uuid_string = base::StringPrintf( |
| + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
| + uuid->Value.LongUuid.Data1, uuid->Value.LongUuid.Data2, |
| + uuid->Value.LongUuid.Data3, uuid->Value.LongUuid.Data4[0], |
| + uuid->Value.LongUuid.Data4[1], uuid->Value.LongUuid.Data4[2], |
| + uuid->Value.LongUuid.Data4[3], uuid->Value.LongUuid.Data4[4], |
| + uuid->Value.LongUuid.Data4[5], uuid->Value.LongUuid.Data4[6], |
| + uuid->Value.LongUuid.Data4[7]); |
| + if (uuid_string != "00002902-0000-1000-8000-00805f9b34fb") |
| + continue; |
| + |
| + return d.second.get(); |
| + } |
| + |
| + return nullptr; |
| +} |
| + |
| } // namespace win |
| } // namespace device |