1 //
2 //  Copyright (C) 2015 Google, Inc.
3 //
4 //  Licensed under the Apache License, Version 2.0 (the "License");
5 //  you may not use this file except in compliance with the License.
6 //  You may obtain a copy of the License at:
7 //
8 //  http://www.apache.org/licenses/LICENSE-2.0
9 //
10 //  Unless required by applicable law or agreed to in writing, software
11 //  distributed under the License is distributed on an "AS IS" BASIS,
12 //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 //  See the License for the specific language governing permissions and
14 //  limitations under the License.
15 //
16 
17 #pragma once
18 
19 #include <mutex>
20 #include <unordered_map>
21 
22 #include <base/macros.h>
23 #include <base/memory/ref_counted.h>
24 #include <base/memory/weak_ptr.h>
25 #include <base/single_thread_task_runner.h>
26 
27 #include <android/bluetooth/BnBluetoothGattServerCallback.h>
28 #include <android/bluetooth/IBluetooth.h>
29 
30 using android::binder::Status;
31 using android::String16;
32 
33 namespace heart_rate {
34 
35 // Implements an example GATT Heart Rate service. This class emulates the
36 // behavior of a heart rate service by sending fake heart-rate pulses.
37 class HeartRateServer
38     : public android::bluetooth::BnBluetoothGattServerCallback {
39  public:
40   HeartRateServer(android::sp<android::bluetooth::IBluetooth> bluetooth,
41                   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
42                   bool advertise);
43   ~HeartRateServer() override;
44 
45   // Set up the server and register the GATT services with the stack. This
46   // initiates a set of asynchronous procedures. Invokes |callback|
47   // asynchronously with the result of the operation.
48   using RunCallback = std::function<void(bool success)>;
49   bool Run(const RunCallback& callback);
50 
51  private:
52   // Helpers for posting heart rate measurement notifications.
53   void ScheduleNextMeasurement();
54   void SendHeartRateMeasurement();
55   void BuildHeartRateMeasurementValue(std::vector<uint8_t>* out_value);
56 
57   // ipc::binder::IBluetoothGattServerCallback override:
58   Status OnServerRegistered(int status, int server_id) override;
59   Status OnServiceAdded(
60       int status,
61       const android::bluetooth::BluetoothGattService& service) override;
62   Status OnCharacteristicReadRequest(const String16& device_address,
63                                      int request_id, int offset, bool is_long,
64                                      int handle) override;
65   Status OnDescriptorReadRequest(const String16& device_address, int request_id,
66                                  int offset, bool is_long, int handle) override;
67   Status OnCharacteristicWriteRequest(const String16& device_address,
68                                       int request_id, int offset,
69                                       bool is_prepare_write, bool need_response,
70                                       const std::vector<uint8_t>& value,
71                                       int handle) override;
72   Status OnDescriptorWriteRequest(const String16& device_address,
73                                   int request_id, int offset,
74                                   bool is_prepare_write, bool need_response,
75                                   const std::vector<uint8_t>& value,
76                                   int handle) override;
77   Status OnExecuteWriteRequest(const String16& device_address, int request_id,
78                                bool is_execute) override;
79   Status OnNotificationSent(const String16& device_address,
80                             int status) override;
81   Status OnConnectionStateChanged(const String16& device_address,
82                                   bool connected) override;
83 
84   // Single mutex to protect all variables below.
85   std::mutex mutex_;
86 
87   // This stores whether or not at least one remote device has written to the
88   // CCC descriptor.
89   bool simulation_started_;
90 
91   // The IBluetooth and IBluetoothGattServer binders that we use to communicate
92   // with the Bluetooth daemon's GATT server features.
93   android::sp<android::bluetooth::IBluetooth> bluetooth_;
94   android::sp<android::bluetooth::IBluetoothGattServer> gatt_;
95 
96   // ID assigned to us by the daemon to operate on our dedicated GATT server
97   // instance.
98   int server_if_;
99 
100   // Callback passed to Run(). We use this to tell main that all attributes have
101   // been registered with the daemon.
102   RunCallback pending_run_cb_;
103 
104   // Stores whether or not an outgoing notification is still pending. We use
105   // this to throttle notifications so that we don't accidentally congest the
106   // connection.
107   std::unordered_map<std::string, bool> pending_notification_map_;
108 
109   // The current HR notification count.
110   int hr_notification_count_;
111 
112   // The Energy Expended value we use in our notifications.
113   uint16_t energy_expended_;
114 
115   // Handles that refer to Heart Rate Service GATT objects.
116   // These returned to us from the Bluetooth daemon as we populate the database.
117   uint16_t hr_service_handle_;
118   uint16_t hr_measurement_handle_;
119   uint16_t hr_measurement_cccd_handle_;
120   uint16_t body_sensor_loc_handle_;
121   uint16_t hr_control_point_handle_;
122 
123   // The daemon itself doesn't maintain a Client Characteristic Configuration
124   // mapping, so we do it ourselves here.
125   std::unordered_map<std::string, uint8_t> device_ccc_map_;
126 
127   // Wether we should also start advertising
128   bool advertise_;
129 
130   // libchrome task runner that we use to post heart rate measurement
131   // notifications on the main thread.
132   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
133 
134   // We use this to pass weak_ptr's to base::Bind, which won't execute if the
135   // HeartRateServer object gets deleted. This is a convenience utility from
136   // libchrome and we use it here since base::TaskRunner uses base::Callback.
137   // Note: This should remain the last member so that it'll be destroyed and
138   // invalidate its weak pointers before any other members are destroyed.
139   base::WeakPtrFactory<HeartRateServer> weak_ptr_factory_;
140 
141   DISALLOW_COPY_AND_ASSIGN(HeartRateServer);
142 };
143 
144 }  // namespace heart_rate
145