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 } 60 61 void FakeBluetoothGattDescriptorClient::Init(dbus::Bus* bus) { 62 } 63 64 void FakeBluetoothGattDescriptorClient::AddObserver(Observer* observer) { 65 observers_.AddObserver(observer); 66 } 67 68 void FakeBluetoothGattDescriptorClient::RemoveObserver(Observer* observer) { 69 observers_.RemoveObserver(observer); 70 } 71 72 std::vector<dbus::ObjectPath> 73 FakeBluetoothGattDescriptorClient::GetDescriptors() { 74 std::vector<dbus::ObjectPath> descriptors; 75 for (PropertiesMap::const_iterator iter = properties_.begin(); 76 iter != properties_.end(); ++iter) { 77 descriptors.push_back(iter->first); 78 } 79 return descriptors; 80 } 81 82 FakeBluetoothGattDescriptorClient::Properties* 83 FakeBluetoothGattDescriptorClient::GetProperties( 84 const dbus::ObjectPath& object_path) { 85 PropertiesMap::const_iterator iter = properties_.find(object_path); 86 if (iter == properties_.end()) 87 return NULL; 88 return iter->second->properties.get(); 89 } 90 91 void FakeBluetoothGattDescriptorClient::ReadValue( 92 const dbus::ObjectPath& object_path, 93 const ValueCallback& callback, 94 const ErrorCallback& error_callback) { 95 PropertiesMap::iterator iter = properties_.find(object_path); 96 if (iter == properties_.end()) { 97 error_callback.Run(kUnknownDescriptorError, ""); 98 return; 99 } 100 101 callback.Run(iter->second->value); 102 } 103 104 void FakeBluetoothGattDescriptorClient::WriteValue( 105 const dbus::ObjectPath& object_path, 106 const std::vector<uint8>& value, 107 const base::Closure& callback, 108 const ErrorCallback& error_callback) { 109 if (properties_.find(object_path) == properties_.end()) { 110 error_callback.Run(kUnknownDescriptorError, ""); 111 return; 112 } 113 114 // Since the only fake descriptor is "Client Characteristic Configuration" 115 // and BlueZ doesn't allow writing to it, return failure. 116 error_callback.Run("org.bluez.Error.Failed", 117 "Writing to the Client Characteristic Configuration " 118 "descriptor not allowed"); 119 } 120 121 dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor( 122 const dbus::ObjectPath& characteristic_path, 123 const std::string& uuid) { 124 if (uuid != kClientCharacteristicConfigurationUUID) { 125 VLOG(2) << "Unsupported UUID: " << uuid; 126 return dbus::ObjectPath(); 127 } 128 129 // CCC descriptor is the only one supported at the moment. 130 DCHECK(characteristic_path.IsValid()); 131 dbus::ObjectPath object_path( 132 characteristic_path.value() + "/" + 133 kClientCharacteristicConfigurationPathComponent); 134 DCHECK(object_path.IsValid()); 135 PropertiesMap::const_iterator iter = properties_.find(object_path); 136 if (iter != properties_.end()) { 137 VLOG(1) << "Descriptor already exposed: " << object_path.value(); 138 return dbus::ObjectPath(); 139 } 140 141 Properties* properties = new Properties(base::Bind( 142 &FakeBluetoothGattDescriptorClient::OnPropertyChanged, 143 weak_ptr_factory_.GetWeakPtr(), 144 object_path)); 145 properties->uuid.ReplaceValue(uuid); 146 properties->characteristic.ReplaceValue(characteristic_path); 147 148 DescriptorData* data = new DescriptorData(); 149 data->properties.reset(properties); 150 151 data->value.push_back(1); // Notifications enabled. 152 data->value.push_back(0); 153 154 properties_[object_path] = data; 155 156 NotifyDescriptorAdded(object_path); 157 158 return object_path; 159 } 160 161 void FakeBluetoothGattDescriptorClient::HideDescriptor( 162 const dbus::ObjectPath& descriptor_path) { 163 PropertiesMap::iterator iter = properties_.find(descriptor_path); 164 if (iter == properties_.end()) { 165 VLOG(1) << "Descriptor not exposed: " << descriptor_path.value(); 166 return; 167 } 168 169 NotifyDescriptorRemoved(descriptor_path); 170 171 delete iter->second; 172 properties_.erase(iter); 173 } 174 175 void FakeBluetoothGattDescriptorClient::OnPropertyChanged( 176 const dbus::ObjectPath& object_path, 177 const std::string& property_name) { 178 VLOG(2) << "Descriptor property changed: " << object_path.value() 179 << ": " << property_name; 180 181 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, 182 GattDescriptorPropertyChanged(object_path, property_name)); 183 } 184 185 void FakeBluetoothGattDescriptorClient::NotifyDescriptorAdded( 186 const dbus::ObjectPath& object_path) { 187 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, 188 GattDescriptorAdded(object_path)); 189 } 190 191 void FakeBluetoothGattDescriptorClient::NotifyDescriptorRemoved( 192 const dbus::ObjectPath& object_path) { 193 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, 194 GattDescriptorRemoved(object_path)); 195 } 196 197 } // namespace chromeos 198