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..38daa70bc54ebd49cdbba1cfcd9f35b700d5dae1 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,15 @@ 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) { |
| + if (remembered_characteristic_ && |
|
ortuno
2016/03/21 17:00:53
I don't think you need all this logic and the erro
gogerald1
2016/03/21 22:09:16
Done.
|
| + remembered_characteristic_->characteristic_info->AttributeHandle == |
| + characteristic->AttributeHandle) { |
| + target_characteristic = remembered_characteristic_.get(); |
| + } else { |
| + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| + } |
| + } |
| // Return error simulated by SimulateGattCharacteristicReadError. |
| if (target_characteristic->read_errors.size()) { |
| @@ -204,6 +214,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 +225,15 @@ 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) { |
| + if (remembered_characteristic_ && |
|
ortuno
2016/03/21 17:00:53
Same as above. No need for the logic and the error
gogerald1
2016/03/21 22:09:16
Done.
|
| + remembered_characteristic_->characteristic_info->AttributeHandle == |
| + characteristic->AttributeHandle) { |
| + target_characteristic = remembered_characteristic_.get(); |
| + } else { |
| + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| + } |
| + } |
| // Return error simulated by SimulateGattCharacteristicWriteError. |
| if (target_characteristic->write_errors.size()) { |
| @@ -232,7 +251,45 @@ 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; |
| } |
| @@ -367,14 +424,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 +476,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); |
| + if (it != parent_service->included_characteristics.end()) |
|
ortuno
2016/03/21 17:00:53
DCHECK this. If someone passes in an non existing
gogerald1
2016/03/21 22:09:16
Done.
|
| + remembered_characteristic_ = std::move(it->second); |
| +} |
| + |
| void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor( |
| std::string device_address, |
| GattCharacteristic* characteristic, |