| Index: chromeos/dbus/bluetooth_gatt_characteristic_client.cc
|
| diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_client.cc b/chromeos/dbus/bluetooth_gatt_characteristic_client.cc
|
| index e2e7c746ab00b055376749ef976ed322f2ffc918..a510b91059b9caabec14a53fc4fea2a7c464e771 100644
|
| --- a/chromeos/dbus/bluetooth_gatt_characteristic_client.cc
|
| +++ b/chromeos/dbus/bluetooth_gatt_characteristic_client.cc
|
| @@ -13,6 +13,13 @@
|
|
|
| namespace chromeos {
|
|
|
| +// static
|
| +const char BluetoothGattCharacteristicClient::kNoResponseError[] =
|
| + "org.chromium.Error.NoResponse";
|
| +// static
|
| +const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError[] =
|
| + "org.chromium.Error.UnknownCharacteristic";
|
| +
|
| BluetoothGattCharacteristicClient::Properties::Properties(
|
| dbus::ObjectProxy* object_proxy,
|
| const std::string& interface_name,
|
| @@ -20,7 +27,6 @@ BluetoothGattCharacteristicClient::Properties::Properties(
|
| : dbus::PropertySet(object_proxy, interface_name, callback) {
|
| RegisterProperty(bluetooth_gatt_characteristic::kUUIDProperty, &uuid);
|
| RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty, &service);
|
| - RegisterProperty(bluetooth_gatt_characteristic::kValueProperty, &value);
|
| RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty, &flags);
|
| }
|
|
|
| @@ -74,6 +80,61 @@ class BluetoothGattCharacteristicClientImpl
|
| kBluetoothGattCharacteristicInterface));
|
| }
|
|
|
| + // BluetoothGattCharacteristicClient override.
|
| + virtual void ReadValue(const dbus::ObjectPath& object_path,
|
| + const ValueCallback& callback,
|
| + const ErrorCallback& error_callback) OVERRIDE {
|
| + dbus::ObjectProxy* object_proxy =
|
| + object_manager_->GetObjectProxy(object_path);
|
| + if (!object_proxy) {
|
| + error_callback.Run(kUnknownCharacteristicError, "");
|
| + return;
|
| + }
|
| +
|
| + dbus::MethodCall method_call(
|
| + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
|
| + bluetooth_gatt_characteristic::kReadValue);
|
| +
|
| + object_proxy->CallMethodWithErrorCallback(
|
| + &method_call,
|
| + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + callback),
|
| + base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + error_callback));
|
| + }
|
| +
|
| + // BluetoothGattCharacteristicClient override.
|
| + virtual void WriteValue(const dbus::ObjectPath& object_path,
|
| + const std::vector<uint8>& value,
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) OVERRIDE {
|
| + dbus::ObjectProxy* object_proxy =
|
| + object_manager_->GetObjectProxy(object_path);
|
| + if (!object_proxy) {
|
| + error_callback.Run(kUnknownCharacteristicError, "");
|
| + return;
|
| + }
|
| +
|
| + dbus::MethodCall method_call(
|
| + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
|
| + bluetooth_gatt_characteristic::kWriteValue);
|
| + dbus::MessageWriter writer(&method_call);
|
| + writer.AppendArrayOfBytes(value.data(), value.size());
|
| +
|
| + object_proxy->CallMethodWithErrorCallback(
|
| + &method_call,
|
| + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + callback),
|
| + base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + error_callback));
|
| + }
|
| +
|
| // dbus::ObjectManager::Interface override.
|
| virtual dbus::PropertySet* CreateProperties(
|
| dbus::ObjectProxy *object_proxy,
|
| @@ -94,6 +155,21 @@ class BluetoothGattCharacteristicClientImpl
|
| VLOG(2) << "Remote GATT characteristic added: " << object_path.value();
|
| FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
|
| GattCharacteristicAdded(object_path));
|
| +
|
| + // Connect the "ValueUpdated" signal.
|
| + dbus::ObjectProxy* object_proxy =
|
| + object_manager_->GetObjectProxy(object_path);
|
| + DCHECK(object_proxy);
|
| +
|
| + object_proxy->ConnectToSignal(
|
| + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
|
| + bluetooth_gatt_characteristic::kValueUpdatedSignal,
|
| + base::Bind(&BluetoothGattCharacteristicClientImpl::ValueUpdatedReceived,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + object_path),
|
| + base::Bind(
|
| + &BluetoothGattCharacteristicClientImpl::ValueUpdatedConnected,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| }
|
|
|
| // dbus::ObjectManager::Interface override.
|
| @@ -129,6 +205,78 @@ class BluetoothGattCharacteristicClientImpl
|
| property_name));
|
| }
|
|
|
| + // Called by dbus:: when a "ValueUpdated" signal is received.
|
| + void ValueUpdatedReceived(const dbus::ObjectPath& object_path,
|
| + dbus::Signal* signal) {
|
| + DCHECK(signal);
|
| + const uint8* bytes = NULL;
|
| + size_t length = 0;
|
| + dbus::MessageReader reader(signal);
|
| + if (!reader.PopArrayOfBytes(&bytes, &length)) {
|
| + LOG(WARNING) << "ValueUpdated signal has incorrect parameters: "
|
| + << signal->ToString();
|
| + return;
|
| + }
|
| +
|
| + std::vector<uint8> value;
|
| + if (bytes)
|
| + value.assign(bytes, bytes + length);
|
| +
|
| + FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer,
|
| + observers_,
|
| + GattCharacteristicValueUpdated(object_path, value));
|
| + }
|
| +
|
| + // Called by dbus:: when the "ValueUpdated" signal is initially connected.
|
| + void ValueUpdatedConnected(const std::string& interface_name,
|
| + const std::string& signal_name,
|
| + bool success) {
|
| + LOG_IF(WARNING, !success) << "Failed to connect to the ValueUpdated signal";
|
| + }
|
| +
|
| + // Called when a response for successful method call is received.
|
| + void OnSuccess(const base::Closure& callback, dbus::Response* response) {
|
| + DCHECK(response);
|
| + callback.Run();
|
| + }
|
| +
|
| + // Called when a characteristic value response for a successful method call
|
| + // is received.
|
| + void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) {
|
| + DCHECK(response);
|
| + dbus::MessageReader reader(response);
|
| +
|
| + const uint8* bytes = NULL;
|
| + size_t length = 0;
|
| +
|
| + if (!reader.PopArrayOfBytes(&bytes, &length))
|
| + VLOG(2) << "Error reading array of bytes in ValueCallback";
|
| +
|
| + std::vector<uint8> value;
|
| +
|
| + if (bytes)
|
| + value.assign(bytes, bytes + length);
|
| +
|
| + callback.Run(value);
|
| + }
|
| +
|
| + // Called when a response for a failed method call is received.
|
| + void OnError(const ErrorCallback& error_callback,
|
| + dbus::ErrorResponse* response) {
|
| + // Error response has optional error message argument.
|
| + std::string error_name;
|
| + std::string error_message;
|
| + if (response) {
|
| + dbus::MessageReader reader(response);
|
| + error_name = response->GetErrorName();
|
| + reader.PopString(&error_message);
|
| + } else {
|
| + error_name = kNoResponseError;
|
| + error_message = "";
|
| + }
|
| + error_callback.Run(error_name, error_message);
|
| + }
|
| +
|
| dbus::ObjectManager* object_manager_;
|
|
|
| // List of observers interested in event notifications from us.
|
|
|