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