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