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 "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
6
7#include "base/bind.h"
8#include "base/logging.h"
9#include "base/strings/stringprintf.h"
10#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
11#include "chromeos/dbus/dbus_thread_manager.h"
12#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
13#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
14
15namespace chromeos {
16
17namespace {
18
19// Stream operator for logging vector<uint8>.
20std::ostream& operator<<(std::ostream& out, const std::vector<uint8> bytes) {
21  out << "[";
22  for (std::vector<uint8>::const_iterator iter = bytes.begin();
23       iter != bytes.end(); ++iter) {
24    out << base::StringPrintf("%02X", *iter);
25  }
26  return out << "]";
27}
28
29}  // namespace
30
31BluetoothRemoteGattDescriptorChromeOS::BluetoothRemoteGattDescriptorChromeOS(
32    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
33    const dbus::ObjectPath& object_path)
34    : object_path_(object_path),
35      characteristic_(characteristic),
36      weak_ptr_factory_(this) {
37  VLOG(1) << "Creating remote GATT descriptor with identifier: "
38          << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
39}
40
41BluetoothRemoteGattDescriptorChromeOS::
42    ~BluetoothRemoteGattDescriptorChromeOS() {
43}
44
45std::string BluetoothRemoteGattDescriptorChromeOS::GetIdentifier() const {
46  return object_path_.value();
47}
48
49device::BluetoothUUID BluetoothRemoteGattDescriptorChromeOS::GetUUID() const {
50  BluetoothGattDescriptorClient::Properties* properties =
51      DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
52          GetProperties(object_path_);
53  DCHECK(properties);
54  return device::BluetoothUUID(properties->uuid.value());
55}
56
57bool BluetoothRemoteGattDescriptorChromeOS::IsLocal() const {
58  return false;
59}
60
61const std::vector<uint8>&
62BluetoothRemoteGattDescriptorChromeOS::GetValue() const {
63  return cached_value_;
64}
65
66device::BluetoothGattCharacteristic*
67BluetoothRemoteGattDescriptorChromeOS::GetCharacteristic() const {
68  return characteristic_;
69}
70
71device::BluetoothGattCharacteristic::Permissions
72BluetoothRemoteGattDescriptorChromeOS::GetPermissions() const {
73  // TODO(armansito): Once BlueZ defines the permissions, return the correct
74  // values here.
75  return device::BluetoothGattCharacteristic::kPermissionNone;
76}
77
78void BluetoothRemoteGattDescriptorChromeOS::ReadRemoteDescriptor(
79    const ValueCallback& callback,
80    const ErrorCallback& error_callback) {
81  VLOG(1) << "Sending GATT characteristic descriptor read request to "
82          << "descriptor: " << GetIdentifier() << ", UUID: "
83          << GetUUID().canonical_value();
84
85  DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue(
86      object_path_,
87      base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnValueSuccess,
88                 weak_ptr_factory_.GetWeakPtr(),
89                 callback),
90      base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
91                 weak_ptr_factory_.GetWeakPtr(),
92                 error_callback));
93}
94
95void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor(
96    const std::vector<uint8>& new_value,
97    const base::Closure& callback,
98    const ErrorCallback& error_callback) {
99  VLOG(1) << "Sending GATT characteristic descriptor write request to "
100          << "characteristic: " << GetIdentifier() << ", UUID: "
101          << GetUUID().canonical_value() << ", with value: "
102          << new_value << ".";
103
104  DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->WriteValue(
105      object_path_,
106      new_value,
107      callback,
108      base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
109                 weak_ptr_factory_.GetWeakPtr(),
110                 error_callback));
111}
112
113void BluetoothRemoteGattDescriptorChromeOS::OnValueSuccess(
114    const ValueCallback& callback,
115    const std::vector<uint8>& value) {
116  VLOG(1) << "Descriptor value read: " << value;
117  cached_value_ = value;
118
119  DCHECK(characteristic_);
120  BluetoothRemoteGattServiceChromeOS* service =
121      static_cast<BluetoothRemoteGattServiceChromeOS*>(
122          characteristic_->GetService());
123  DCHECK(service);
124  service->NotifyDescriptorValueChanged(characteristic_, this, value);
125  callback.Run(value);
126}
127
128void BluetoothRemoteGattDescriptorChromeOS::OnError(
129    const ErrorCallback& error_callback,
130    const std::string& error_name,
131    const std::string& error_message) {
132  VLOG(1) << "Operation failed: " << error_name
133          << ", message: " << error_message;
134  error_callback.Run();
135}
136
137}  // namespace chromeos
138