// // Copyright 2015 Google, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #pragma once #include #include #include #include #include #include #include #include using android::binder::Status; using android::String16; namespace heart_rate { // Implements an example GATT Heart Rate service. This class emulates the // behavior of a heart rate service by sending fake heart-rate pulses. class HeartRateServer : public android::bluetooth::BnBluetoothGattServerCallback { public: HeartRateServer(android::sp bluetooth, scoped_refptr main_task_runner, bool advertise); ~HeartRateServer() override; // Set up the server and register the GATT services with the stack. This // initiates a set of asynchronous procedures. Invokes |callback| // asynchronously with the result of the operation. using RunCallback = std::function; bool Run(const RunCallback& callback); private: // Helpers for posting heart rate measurement notifications. void ScheduleNextMeasurement(); void SendHeartRateMeasurement(); void BuildHeartRateMeasurementValue(std::vector* out_value); // ipc::binder::IBluetoothGattServerCallback override: Status OnServerRegistered(int status, int server_id) override; Status OnServiceAdded( int status, const android::bluetooth::BluetoothGattService& service) override; Status OnCharacteristicReadRequest(const String16& device_address, int request_id, int offset, bool is_long, int handle) override; Status OnDescriptorReadRequest(const String16& device_address, int request_id, int offset, bool is_long, int handle) override; Status OnCharacteristicWriteRequest(const String16& device_address, int request_id, int offset, bool is_prepare_write, bool need_response, const std::vector& value, int handle) override; Status OnDescriptorWriteRequest(const String16& device_address, int request_id, int offset, bool is_prepare_write, bool need_response, const std::vector& value, int handle) override; Status OnExecuteWriteRequest(const String16& device_address, int request_id, bool is_execute) override; Status OnNotificationSent(const String16& device_address, int status) override; Status OnConnectionStateChanged(const String16& device_address, bool connected) override; // Single mutex to protect all variables below. std::mutex mutex_; // This stores whether or not at least one remote device has written to the // CCC descriptor. bool simulation_started_; // The IBluetooth and IBluetoothGattServer binders that we use to communicate // with the Bluetooth daemon's GATT server features. android::sp bluetooth_; android::sp gatt_; // ID assigned to us by the daemon to operate on our dedicated GATT server // instance. int server_if_; // Callback passed to Run(). We use this to tell main that all attributes have // been registered with the daemon. RunCallback pending_run_cb_; // Stores whether or not an outgoing notification is still pending. We use // this to throttle notifications so that we don't accidentally congest the // connection. std::unordered_map pending_notification_map_; // The current HR notification count. int hr_notification_count_; // The Energy Expended value we use in our notifications. uint16_t energy_expended_; // Handles that refer to Heart Rate Service GATT objects. // These returned to us from the Bluetooth daemon as we populate the database. uint16_t hr_service_handle_; uint16_t hr_measurement_handle_; uint16_t hr_measurement_cccd_handle_; uint16_t body_sensor_loc_handle_; uint16_t hr_control_point_handle_; // The daemon itself doesn't maintain a Client Characteristic Configuration // mapping, so we do it ourselves here. std::unordered_map device_ccc_map_; // Wether we should also start advertising bool advertise_; // libchrome task runner that we use to post heart rate measurement // notifications on the main thread. scoped_refptr main_task_runner_; // We use this to pass weak_ptr's to base::Bind, which won't execute if the // HeartRateServer object gets deleted. This is a convenience utility from // libchrome and we use it here since base::TaskRunner uses base::Callback. // Note: This should remain the last member so that it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(HeartRateServer); }; } // namespace heart_rate