You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
5.9 KiB
145 lines
5.9 KiB
//
|
|
// 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 <mutex>
|
|
#include <unordered_map>
|
|
|
|
#include <base/macros.h>
|
|
#include <base/memory/ref_counted.h>
|
|
#include <base/memory/weak_ptr.h>
|
|
#include <base/single_thread_task_runner.h>
|
|
|
|
#include <android/bluetooth/BnBluetoothGattServerCallback.h>
|
|
#include <android/bluetooth/IBluetooth.h>
|
|
|
|
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<android::bluetooth::IBluetooth> bluetooth,
|
|
scoped_refptr<base::SingleThreadTaskRunner> 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<void(bool success)>;
|
|
bool Run(const RunCallback& callback);
|
|
|
|
private:
|
|
// Helpers for posting heart rate measurement notifications.
|
|
void ScheduleNextMeasurement();
|
|
void SendHeartRateMeasurement();
|
|
void BuildHeartRateMeasurementValue(std::vector<uint8_t>* 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<uint8_t>& 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<uint8_t>& 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<android::bluetooth::IBluetooth> bluetooth_;
|
|
android::sp<android::bluetooth::IBluetoothGattServer> 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<std::string, bool> 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<std::string, uint8_t> 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<base::SingleThreadTaskRunner> 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<HeartRateServer> weak_ptr_factory_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(HeartRateServer);
|
|
};
|
|
|
|
} // namespace heart_rate
|