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..629c1a3fe93150d2bf2c6b0481509d92e3626152 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() {} |
| +GattCharacteristicObserver::GattCharacteristicObserver() {} |
| +GattCharacteristicObserver::~GattCharacteristicObserver() {} |
| + |
| BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() |
| : observer_(nullptr) {} |
| BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {} |
| @@ -186,8 +189,12 @@ HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicValue( |
| scoped_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE>* out_value) { |
| GattCharacteristic* target_characteristic = |
| GetSimulatedGattCharacteristic(service_path, characteristic); |
| - if (target_characteristic == nullptr) |
| - return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| + if (target_characteristic == nullptr) { |
| + target_characteristic = remembered_characteristic_.get(); |
| + DCHECK(target_characteristic); |
| + DCHECK(target_characteristic->characteristic_info->AttributeHandle == |
| + characteristic->AttributeHandle); |
| + } |
| // Return error simulated by SimulateGattCharacteristicReadError. |
| if (target_characteristic->read_errors.size()) { |
| @@ -204,6 +211,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; |
| } |
| @@ -213,8 +222,12 @@ HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue( |
| PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value) { |
| GattCharacteristic* target_characteristic = |
| GetSimulatedGattCharacteristic(service_path, characteristic); |
| - if (target_characteristic == nullptr) |
| - return ERROR_NOT_FOUND; |
| + if (target_characteristic == nullptr) { |
| + target_characteristic = remembered_characteristic_.get(); |
| + DCHECK(target_characteristic); |
| + DCHECK(target_characteristic->characteristic_info->AttributeHandle == |
| + characteristic->AttributeHandle); |
| + } |
| // Return error simulated by SimulateGattCharacteristicWriteError. |
| if (target_characteristic->write_errors.size()) { |
| @@ -232,7 +245,66 @@ 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( |
| + 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) { |
| + // Right now, only CharacteristicValueChangedEvent is supported. |
| + CHECK(CharacteristicValueChangedEvent == type); |
| + |
| + scoped_ptr<GattCharacteristicObserver> observer( |
| + new GattCharacteristicObserver()); |
| + observer->callback = callback; |
| + observer->context = context; |
| + *out_handle = (BLUETOOTH_GATT_EVENT_HANDLE)observer.get(); |
| + gatt_characteristic_observers_[*out_handle] = std::move(observer); |
| + |
| + 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( |
| + service_path, ¶meter->Characteristics[i]); |
| + CHECK(target_characteristic); |
| + target_characteristic->observers.push_back(*out_handle); |
| + } |
| + |
| + if (observer_) |
| + observer_->OnStartCharacteristicNotification(); |
| + |
| + return S_OK; |
| +} |
| + |
| +HRESULT BluetoothLowEnergyWrapperFake::UnregisterGattEvent( |
| + BLUETOOTH_GATT_EVENT_HANDLE event_handle) { |
| + gatt_characteristic_observers_.erase(event_handle); |
| + return S_OK; |
| +} |
| + |
| +HRESULT BluetoothLowEnergyWrapperFake::WriteDescriptorValue( |
| + base::FilePath& service_path, |
| + const PBTH_LE_GATT_DESCRIPTOR descriptor, |
| + PBTH_LE_GATT_DESCRIPTOR_VALUE new_value) { |
| + if (new_value->DescriptorType == ClientCharacteristicConfiguration) { |
| + // Simulate the value the OS will write. |
| + std::vector<UCHAR> write_value; |
| + if (new_value->ClientCharacteristicConfiguration |
| + .IsSubscribeToNotification) { |
| + write_value.push_back(1); |
| + } else if (new_value->ClientCharacteristicConfiguration |
| + .IsSubscribeToIndication) { |
| + write_value.push_back(2); |
| + } |
| + write_value.push_back(0); |
| + if (observer_) |
| + observer_->OnWriteGattDescriptorValue(write_value); |
| + } |
| return S_OK; |
| } |
| @@ -342,6 +414,11 @@ GattCharacteristic* BluetoothLowEnergyWrapperFake::SimulateGattCharacterisc( |
| parent_service->included_characteristics[std::to_string( |
| win_characteristic->characteristic_info->AttributeHandle)] = |
| make_scoped_ptr(win_characteristic); |
| + // Set default empty value. |
| + PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value = |
| + (PBTH_LE_GATT_CHARACTERISTIC_VALUE)(new UCHAR[sizeof(ULONG)]); |
|
scheib
2016/04/05 22:44:02
sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE)
gogerald1
2016/04/06 22:54:48
Done.
|
| + win_value->DataSize = 0; |
| + win_characteristic->value.reset(win_value); |
| return win_characteristic; |
| } |
| @@ -367,14 +444,42 @@ BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic( |
| void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicValue( |
| GattCharacteristic* characteristic, |
| const std::vector<uint8_t>& value) { |
| - CHECK(characteristic); |
| + GattCharacteristic* target_characteristic = characteristic; |
| + if (target_characteristic == nullptr) |
| + target_characteristic = remembered_characteristic_.get(); |
| + CHECK(target_characteristic); |
| + |
| PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value = |
| (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( |
| new UCHAR[value.size() + sizeof(ULONG)]); |
| win_value->DataSize = (ULONG)value.size(); |
| for (std::size_t i = 0; i < value.size(); i++) |
| win_value->Data[i] = value[i]; |
| - characteristic->value.reset(win_value); |
| + target_characteristic->value.reset(win_value); |
| +} |
| + |
| +void BluetoothLowEnergyWrapperFake:: |
| + SimulateCharacteristicValueChangeNotification( |
| + GattCharacteristic* characteristic) { |
| + GattCharacteristic* target_characteristic = characteristic; |
| + if (target_characteristic == nullptr) |
| + target_characteristic = remembered_characteristic_.get(); |
| + CHECK(target_characteristic); |
| + for (const auto& observer : target_characteristic->observers) { |
| + GattCharacteristicObserverTable::const_iterator it = |
| + gatt_characteristic_observers_.find(observer); |
| + // Check if |observer| has been unregistered by UnregisterGattEvent. |
| + if (it != gatt_characteristic_observers_.end()) { |
| + BLUETOOTH_GATT_VALUE_CHANGED_EVENT event; |
| + event.ChangedAttributeHandle = |
| + target_characteristic->characteristic_info->AttributeHandle; |
| + event.CharacteristicValueDataSize = |
| + target_characteristic->value->DataSize + sizeof(ULONG); |
| + event.CharacteristicValue = target_characteristic->value.get(); |
| + it->second->callback(CharacteristicValueChangedEvent, &event, |
| + it->second->context); |
| + } |
| + } |
| } |
| void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicReadError( |
| @@ -391,6 +496,16 @@ void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicWriteError( |
| characteristic->write_errors.push_back(error); |
| } |
| +void BluetoothLowEnergyWrapperFake::RememberCharacteristicForSubsequentAction( |
| + GattService* parent_service, |
| + std::string attribute_handle) { |
| + CHECK(parent_service); |
| + GattCharacteristicsMap::iterator it = |
| + parent_service->included_characteristics.find(attribute_handle); |
| + DCHECK(it != parent_service->included_characteristics.end()); |
| + remembered_characteristic_ = std::move(it->second); |
|
scheib
2016/04/05 22:44:02
Are you intending to move the characteristic out o
gogerald1
2016/04/06 22:54:48
Done.
|
| +} |
| + |
| void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor( |
| std::string device_address, |
| GattCharacteristic* characteristic, |