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 <unordered_map> 20 21#include <base/macros.h> 22#include <base/memory/ref_counted.h> 23#include <base/memory/weak_ptr.h> 24#include <base/single_thread_task_runner.h> 25 26#include <bluetooth/binder/IBluetooth.h> 27#include <bluetooth/binder/IBluetoothGattServerCallback.h> 28#include <bluetooth/gatt_identifier.h> 29 30namespace heart_rate { 31 32// Implements an example GATT Heart Rate service. This class emulates the 33// behavior of a heart rate service by sending fake heart-rate pulses. 34class HeartRateServer : public ipc::binder::BnBluetoothGattServerCallback { 35 public: 36 HeartRateServer( 37 android::sp<ipc::binder::IBluetooth> bluetooth, 38 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 39 bool advertise); 40 ~HeartRateServer() override; 41 42 // Set up the server and register the GATT services with the stack. This 43 // initiates a set of asynchronous procedures. Invokes |callback| 44 // asynchronously with the result of the operation. 45 using RunCallback = std::function<void(bool success)>; 46 bool Run(const RunCallback& callback); 47 48 private: 49 // Helpers for posting heart rate measurement notifications. 50 void ScheduleNextMeasurement(); 51 void SendHeartRateMeasurement(); 52 void BuildHeartRateMeasurementValue(std::vector<uint8_t>* out_value); 53 54 // ipc::binder::IBluetoothGattServerCallback override: 55 void OnServerRegistered(int status, int server_if) override; 56 void OnServiceAdded( 57 int status, 58 const bluetooth::GattIdentifier& service_id) override; 59 void OnCharacteristicReadRequest( 60 const std::string& device_address, 61 int request_id, int offset, bool is_long, 62 const bluetooth::GattIdentifier& characteristic_id) override; 63 void OnDescriptorReadRequest( 64 const std::string& device_address, 65 int request_id, int offset, bool is_long, 66 const bluetooth::GattIdentifier& descriptor_id) override; 67 void OnCharacteristicWriteRequest( 68 const std::string& device_address, 69 int request_id, int offset, bool is_prepare_write, bool need_response, 70 const std::vector<uint8_t>& value, 71 const bluetooth::GattIdentifier& characteristic_id) override; 72 void OnDescriptorWriteRequest( 73 const std::string& device_address, 74 int request_id, int offset, bool is_prepare_write, bool need_response, 75 const std::vector<uint8_t>& value, 76 const bluetooth::GattIdentifier& descriptor_id) override; 77 void OnExecuteWriteRequest( 78 const std::string& device_address, 79 int request_id, bool is_execute) override; 80 void OnNotificationSent(const std::string& device_address, 81 int status) override; 82 83 // Single mutex to protect all variables below. 84 std::mutex mutex_; 85 86 // This stores whether or not at least one remote device has written to the 87 // CCC descriptor. 88 bool simulation_started_; 89 90 // The IBluetooth and IBluetoothGattServer binders that we use to communicate 91 // with the Bluetooth daemon's GATT server features. 92 android::sp<ipc::binder::IBluetooth> bluetooth_; 93 android::sp<ipc::binder::IBluetoothGattServer> gatt_; 94 95 // ID assigned to us by the daemon to operate on our dedicated GATT server 96 // instance. 97 int server_if_; 98 99 // Callback passed to Run(). We use this to tell main that all attributes have 100 // been registered with the daemon. 101 RunCallback pending_run_cb_; 102 103 // Stores whether or not an outgoing notification is still pending. We use 104 // this to throttle notifications so that we don't accidentally congest the 105 // connection. 106 std::unordered_map<std::string, bool> pending_notification_map_; 107 108 // The current HR notification count. 109 int hr_notification_count_; 110 111 // The Energy Expended value we use in our notifications. 112 uint16_t energy_expended_; 113 114 // The unique IDs that refer to each of the Heart Rate Service GATT objects. 115 // These returned to us from the Bluetooth daemon as we populate the database. 116 bluetooth::GattIdentifier hr_service_id_; 117 bluetooth::GattIdentifier hr_measurement_id_; 118 bluetooth::GattIdentifier hr_measurement_cccd_id_; 119 bluetooth::GattIdentifier body_sensor_loc_id_; 120 bluetooth::GattIdentifier hr_control_point_id_; 121 122 // The daemon itself doesn't maintain a Client Characteristic Configuration 123 // mapping, so we do it ourselves here. 124 std::unordered_map<std::string, uint8_t> device_ccc_map_; 125 126 // Wether we should also start advertising 127 bool advertise_; 128 129 // libchrome task runner that we use to post heart rate measurement 130 // notifications on the main thread. 131 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 132 133 // We use this to pass weak_ptr's to base::Bind, which won't execute if the 134 // HeartRateServer object gets deleted. This is a convenience utility from 135 // libchrome and we use it here since base::TaskRunner uses base::Callback. 136 // Note: This should remain the last member so that it'll be destroyed and 137 // invalidate its weak pointers before any other members are destroyed. 138 base::WeakPtrFactory<HeartRateServer> weak_ptr_factory_; 139 140 DISALLOW_COPY_AND_ASSIGN(HeartRateServer); 141}; 142 143} // namespace heart_rate 144