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#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
6#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
7
8#include <map>
9#include <queue>
10#include <string>
11#include <utility>
12#include <vector>
13
14#include "base/memory/weak_ptr.h"
15#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
16#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
17#include "dbus/object_path.h"
18#include "device/bluetooth/bluetooth_gatt_characteristic.h"
19#include "device/bluetooth/bluetooth_uuid.h"
20
21namespace device {
22
23class BluetoothGattDescriptor;
24class BluetoothGattService;
25
26}  // namespace device
27
28namespace chromeos {
29
30class BluetoothRemoteGattDescriptorChromeOS;
31class BluetoothRemoteGattServiceChromeOS;
32
33// The BluetoothRemoteGattCharacteristicChromeOS class implements
34// BluetoothGattCharacteristic for remote GATT characteristics on the Chrome OS
35// platform.
36class BluetoothRemoteGattCharacteristicChromeOS
37    : public device::BluetoothGattCharacteristic,
38      public BluetoothGattCharacteristicClient::Observer,
39      public BluetoothGattDescriptorClient::Observer {
40 public:
41  // device::BluetoothGattCharacteristic overrides.
42  virtual std::string GetIdentifier() const OVERRIDE;
43  virtual device::BluetoothUUID GetUUID() const OVERRIDE;
44  virtual bool IsLocal() const OVERRIDE;
45  virtual const std::vector<uint8>& GetValue() const OVERRIDE;
46  virtual device::BluetoothGattService* GetService() const OVERRIDE;
47  virtual Properties GetProperties() const OVERRIDE;
48  virtual Permissions GetPermissions() const OVERRIDE;
49  virtual bool IsNotifying() const OVERRIDE;
50  virtual std::vector<device::BluetoothGattDescriptor*>
51      GetDescriptors() const OVERRIDE;
52  virtual device::BluetoothGattDescriptor* GetDescriptor(
53      const std::string& identifier) const OVERRIDE;
54  virtual bool AddDescriptor(
55      device::BluetoothGattDescriptor* descriptor) OVERRIDE;
56  virtual bool UpdateValue(const std::vector<uint8>& value) OVERRIDE;
57  virtual void ReadRemoteCharacteristic(
58      const ValueCallback& callback,
59      const ErrorCallback& error_callback) OVERRIDE;
60  virtual void WriteRemoteCharacteristic(
61      const std::vector<uint8>& new_value,
62      const base::Closure& callback,
63      const ErrorCallback& error_callback) OVERRIDE;
64  virtual void StartNotifySession(const NotifySessionCallback& callback,
65                                  const ErrorCallback& error_callback) OVERRIDE;
66
67  // Removes one value update session and invokes |callback| on completion. This
68  // decrements the session reference count by 1 and if the number reaches 0,
69  // makes a call to the subsystem to stop notifications from this
70  // characteristic.
71  void RemoveNotifySession(const base::Closure& callback);
72
73  // Object path of the underlying D-Bus characteristic.
74  const dbus::ObjectPath& object_path() const { return object_path_; }
75
76 private:
77  friend class BluetoothRemoteGattServiceChromeOS;
78
79  BluetoothRemoteGattCharacteristicChromeOS(
80      BluetoothRemoteGattServiceChromeOS* service,
81      const dbus::ObjectPath& object_path);
82  virtual ~BluetoothRemoteGattCharacteristicChromeOS();
83
84  // BluetoothGattCharacteristicClient::Observer overrides.
85  virtual void GattCharacteristicValueUpdated(
86      const dbus::ObjectPath& object_path,
87      const std::vector<uint8>& value) OVERRIDE;
88
89  // BluetoothGattDescriptorClient::Observer overrides.
90  virtual void GattDescriptorAdded(
91      const dbus::ObjectPath& object_path) OVERRIDE;
92  virtual void GattDescriptorRemoved(
93      const dbus::ObjectPath& object_path) OVERRIDE;
94
95  // Called by dbus:: on successful completion of a request to read
96  // the characteristic value.
97  void OnValueSuccess(const ValueCallback& callback,
98                      const std::vector<uint8>& value);
99
100  // Called by dbus:: on unsuccessful completion of a request to read or write
101  // the characteristic value.
102  void OnError(const ErrorCallback& error_callback,
103               const std::string& error_name,
104               const std::string& error_message);
105
106  // Called by dbus:: on successful completion of a request to start
107  // notifications.
108  void OnStartNotifySuccess(const NotifySessionCallback& callback);
109
110  // Called by dbus:: on unsuccessful completion of a request to start
111  // notifications.
112  void OnStartNotifyError(const ErrorCallback& error_callback,
113                          const std::string& error_name,
114                          const std::string& error_message);
115
116  // Called by dbus:: on successful completion of a request to stop
117  // notifications.
118  void OnStopNotifySuccess(const base::Closure& callback);
119
120  // Called by dbus:: on unsuccessful completion of a request to stop
121  // notifications.
122  void OnStopNotifyError(const base::Closure& callback,
123                         const std::string& error_name,
124                         const std::string& error_message);
125
126  // Calls StartNotifySession for each queued request.
127  void ProcessStartNotifyQueue();
128
129  // Object path of the D-Bus characteristic object.
130  dbus::ObjectPath object_path_;
131
132  // The GATT service this GATT characteristic belongs to.
133  BluetoothRemoteGattServiceChromeOS* service_;
134
135  // The cached characteristic value based on the most recent read or
136  // notification.
137  std::vector<uint8> cached_value_;
138
139  // The total number of currently active value update sessions.
140  size_t num_notify_sessions_;
141
142  // Calls to StartNotifySession that are pending. This can happen during the
143  // first remote call to start notifications.
144  typedef std::pair<NotifySessionCallback, ErrorCallback>
145      PendingStartNotifyCall;
146  std::queue<PendingStartNotifyCall> pending_start_notify_calls_;
147
148  // True, if a Start or Stop notify call to bluetoothd is currently pending.
149  bool notify_call_pending_;
150
151  // Mapping from GATT descriptor object paths to descriptor objects owned by
152  // this characteristic. Since the Chrome OS implementation uses object paths
153  // as unique identifiers, we also use this mapping to return descriptors by
154  // identifier.
155  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattDescriptorChromeOS*>
156      DescriptorMap;
157  DescriptorMap descriptors_;
158
159  // Note: This should remain the last member so it'll be destroyed and
160  // invalidate its weak pointers before any other members are destroyed.
161  base::WeakPtrFactory<BluetoothRemoteGattCharacteristicChromeOS>
162      weak_ptr_factory_;
163
164  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicChromeOS);
165};
166
167}  // namespace chromeos
168
169#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
170