1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
//
// 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/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#if BASE_VER < 930627
#include <base/single_thread_task_runner.h>
#else
#include <base/task/single_thread_task_runner.h>
#endif
#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(const HeartRateServer&) = delete;
HeartRateServer& operator=(const HeartRateServer&) = delete;
~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_;
};
} // namespace heart_rate
|