| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "chromeos/dbus/bluetooth_gatt_characteristic_client.h" | |
| 10 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 11 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 12 | |
| 13 namespace chromeos { | |
| 14 | |
| 15 const char FakeBluetoothGattDescriptorClient:: | |
| 16 kClientCharacteristicConfigurationPathComponent[] = "desc0000"; | |
| 17 const char FakeBluetoothGattDescriptorClient:: | |
| 18 kClientCharacteristicConfigurationUUID[] = | |
| 19 "00002902-0000-1000-8000-00805f9b34fb"; | |
| 20 | |
| 21 FakeBluetoothGattDescriptorClient::Properties::Properties( | |
| 22 const PropertyChangedCallback& callback) | |
| 23 : BluetoothGattDescriptorClient::Properties( | |
| 24 NULL, | |
| 25 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, | |
| 26 callback) { | |
| 27 } | |
| 28 | |
| 29 FakeBluetoothGattDescriptorClient::Properties::~Properties() { | |
| 30 } | |
| 31 | |
| 32 void FakeBluetoothGattDescriptorClient::Properties::Get( | |
| 33 dbus::PropertyBase* property, | |
| 34 dbus::PropertySet::GetCallback callback) { | |
| 35 VLOG(1) << "Get " << property->name(); | |
| 36 callback.Run(true); | |
| 37 } | |
| 38 | |
| 39 void FakeBluetoothGattDescriptorClient::Properties::GetAll() { | |
| 40 VLOG(1) << "GetAll"; | |
| 41 } | |
| 42 | |
| 43 void FakeBluetoothGattDescriptorClient::Properties::Set( | |
| 44 dbus::PropertyBase* property, | |
| 45 dbus::PropertySet::SetCallback callback) { | |
| 46 VLOG(1) << "Set " << property->name(); | |
| 47 callback.Run(false); | |
| 48 } | |
| 49 | |
| 50 FakeBluetoothGattDescriptorClient::DescriptorData::DescriptorData() { | |
| 51 } | |
| 52 | |
| 53 FakeBluetoothGattDescriptorClient::DescriptorData::~DescriptorData() { | |
| 54 } | |
| 55 | |
| 56 FakeBluetoothGattDescriptorClient::FakeBluetoothGattDescriptorClient() | |
| 57 : weak_ptr_factory_(this) { | |
| 58 } | |
| 59 | |
| 60 FakeBluetoothGattDescriptorClient::~FakeBluetoothGattDescriptorClient() { | |
| 61 for(PropertiesMap::iterator iter = properties_.begin(); iter != | |
| 62 properties_.end(); iter++) | |
| 63 delete iter->second; | |
| 64 } | |
| 65 | |
| 66 void FakeBluetoothGattDescriptorClient::Init(dbus::Bus* bus) { | |
| 67 } | |
| 68 | |
| 69 void FakeBluetoothGattDescriptorClient::AddObserver(Observer* observer) { | |
| 70 observers_.AddObserver(observer); | |
| 71 } | |
| 72 | |
| 73 void FakeBluetoothGattDescriptorClient::RemoveObserver(Observer* observer) { | |
| 74 observers_.RemoveObserver(observer); | |
| 75 } | |
| 76 | |
| 77 std::vector<dbus::ObjectPath> | |
| 78 FakeBluetoothGattDescriptorClient::GetDescriptors() { | |
| 79 std::vector<dbus::ObjectPath> descriptors; | |
| 80 for (PropertiesMap::const_iterator iter = properties_.begin(); | |
| 81 iter != properties_.end(); ++iter) { | |
| 82 descriptors.push_back(iter->first); | |
| 83 } | |
| 84 return descriptors; | |
| 85 } | |
| 86 | |
| 87 FakeBluetoothGattDescriptorClient::Properties* | |
| 88 FakeBluetoothGattDescriptorClient::GetProperties( | |
| 89 const dbus::ObjectPath& object_path) { | |
| 90 PropertiesMap::const_iterator iter = properties_.find(object_path); | |
| 91 if (iter == properties_.end()) | |
| 92 return NULL; | |
| 93 return iter->second->properties.get(); | |
| 94 } | |
| 95 | |
| 96 void FakeBluetoothGattDescriptorClient::ReadValue( | |
| 97 const dbus::ObjectPath& object_path, | |
| 98 const ValueCallback& callback, | |
| 99 const ErrorCallback& error_callback) { | |
| 100 PropertiesMap::iterator iter = properties_.find(object_path); | |
| 101 if (iter == properties_.end()) { | |
| 102 error_callback.Run(kUnknownDescriptorError, ""); | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 // Assign the value of the descriptor as necessary | |
| 107 Properties* properties = iter->second->properties.get(); | |
| 108 if (properties->uuid.value() == kClientCharacteristicConfigurationUUID) { | |
| 109 BluetoothGattCharacteristicClient::Properties* chrc_props = | |
| 110 DBusThreadManager::Get() | |
| 111 ->GetBluetoothGattCharacteristicClient() | |
| 112 ->GetProperties(properties->characteristic.value()); | |
| 113 DCHECK(chrc_props); | |
| 114 | |
| 115 uint8_t value_byte = chrc_props->notifying.value() ? 0x01 : 0x00; | |
| 116 const std::vector<uint8_t>& cur_value = properties->value.value(); | |
| 117 | |
| 118 if (!cur_value.size() || cur_value[0] != value_byte) { | |
| 119 std::vector<uint8_t> value = {value_byte, 0x00}; | |
| 120 properties->value.ReplaceValue(value); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 callback.Run(iter->second->properties->value.value()); | |
| 125 } | |
| 126 | |
| 127 void FakeBluetoothGattDescriptorClient::WriteValue( | |
| 128 const dbus::ObjectPath& object_path, | |
| 129 const std::vector<uint8>& value, | |
| 130 const base::Closure& callback, | |
| 131 const ErrorCallback& error_callback) { | |
| 132 if (properties_.find(object_path) == properties_.end()) { | |
| 133 error_callback.Run(kUnknownDescriptorError, ""); | |
| 134 return; | |
| 135 } | |
| 136 | |
| 137 // Since the only fake descriptor is "Client Characteristic Configuration" | |
| 138 // and BlueZ doesn't allow writing to it, return failure. | |
| 139 error_callback.Run("org.bluez.Error.NotPermitted", | |
| 140 "Writing to the Client Characteristic Configuration " | |
| 141 "descriptor not allowed"); | |
| 142 } | |
| 143 | |
| 144 dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor( | |
| 145 const dbus::ObjectPath& characteristic_path, | |
| 146 const std::string& uuid) { | |
| 147 if (uuid != kClientCharacteristicConfigurationUUID) { | |
| 148 VLOG(2) << "Unsupported UUID: " << uuid; | |
| 149 return dbus::ObjectPath(); | |
| 150 } | |
| 151 | |
| 152 // CCC descriptor is the only one supported at the moment. | |
| 153 DCHECK(characteristic_path.IsValid()); | |
| 154 dbus::ObjectPath object_path( | |
| 155 characteristic_path.value() + "/" + | |
| 156 kClientCharacteristicConfigurationPathComponent); | |
| 157 DCHECK(object_path.IsValid()); | |
| 158 PropertiesMap::const_iterator iter = properties_.find(object_path); | |
| 159 if (iter != properties_.end()) { | |
| 160 VLOG(1) << "Descriptor already exposed: " << object_path.value(); | |
| 161 return dbus::ObjectPath(); | |
| 162 } | |
| 163 | |
| 164 Properties* properties = new Properties(base::Bind( | |
| 165 &FakeBluetoothGattDescriptorClient::OnPropertyChanged, | |
| 166 weak_ptr_factory_.GetWeakPtr(), | |
| 167 object_path)); | |
| 168 properties->uuid.ReplaceValue(uuid); | |
| 169 properties->characteristic.ReplaceValue(characteristic_path); | |
| 170 | |
| 171 DescriptorData* data = new DescriptorData(); | |
| 172 data->properties.reset(properties); | |
| 173 | |
| 174 properties_[object_path] = data; | |
| 175 | |
| 176 NotifyDescriptorAdded(object_path); | |
| 177 | |
| 178 return object_path; | |
| 179 } | |
| 180 | |
| 181 void FakeBluetoothGattDescriptorClient::HideDescriptor( | |
| 182 const dbus::ObjectPath& descriptor_path) { | |
| 183 PropertiesMap::iterator iter = properties_.find(descriptor_path); | |
| 184 if (iter == properties_.end()) { | |
| 185 VLOG(1) << "Descriptor not exposed: " << descriptor_path.value(); | |
| 186 return; | |
| 187 } | |
| 188 | |
| 189 NotifyDescriptorRemoved(descriptor_path); | |
| 190 | |
| 191 delete iter->second; | |
| 192 properties_.erase(iter); | |
| 193 } | |
| 194 | |
| 195 void FakeBluetoothGattDescriptorClient::OnPropertyChanged( | |
| 196 const dbus::ObjectPath& object_path, | |
| 197 const std::string& property_name) { | |
| 198 VLOG(2) << "Descriptor property changed: " << object_path.value() | |
| 199 << ": " << property_name; | |
| 200 | |
| 201 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, | |
| 202 GattDescriptorPropertyChanged(object_path, property_name)); | |
| 203 } | |
| 204 | |
| 205 void FakeBluetoothGattDescriptorClient::NotifyDescriptorAdded( | |
| 206 const dbus::ObjectPath& object_path) { | |
| 207 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, | |
| 208 GattDescriptorAdded(object_path)); | |
| 209 } | |
| 210 | |
| 211 void FakeBluetoothGattDescriptorClient::NotifyDescriptorRemoved( | |
| 212 const dbus::ObjectPath& object_path) { | |
| 213 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, | |
| 214 GattDescriptorRemoved(object_path)); | |
| 215 } | |
| 216 | |
| 217 } // namespace chromeos | |
| OLD | NEW |