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 <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 
     30 namespace 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.
     34 class 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