Home | History | Annotate | Download | only in heart_rate
      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