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
149
150
151
152
153
154
155
156
157
158
159
|
/*
* Copyright 2020 The Android Open Source Project
*
* 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 <map>
#include <mutex>
#include <set>
#include "common/callback.h"
#include "hci/address_with_type.h"
#include "hci/hci_layer.h"
#include "os/alarm.h"
namespace bluetooth {
namespace hci {
constexpr std::chrono::milliseconds kUnregisterSyncTimeoutInMs = std::chrono::milliseconds(10);
class LeAddressManagerCallback {
public:
virtual ~LeAddressManagerCallback() = default;
virtual void OnPause() = 0;
virtual void OnResume() = 0;
};
class LeAddressManager {
public:
LeAddressManager(
common::Callback<void(std::unique_ptr<CommandBuilder>)> enqueue_command,
os::Handler* handler,
Address public_address,
uint8_t connect_list_size,
uint8_t resolving_list_size);
virtual ~LeAddressManager();
enum AddressPolicy {
POLICY_NOT_SET,
USE_PUBLIC_ADDRESS,
USE_STATIC_ADDRESS,
USE_NON_RESOLVABLE_ADDRESS,
USE_RESOLVABLE_ADDRESS
};
// Aborts if called more than once
void SetPrivacyPolicyForInitiatorAddress(
AddressPolicy address_policy,
AddressWithType fixed_address,
crypto_toolbox::Octet16 rotation_irk,
bool supports_ble_privacy,
std::chrono::milliseconds minimum_rotation_time,
std::chrono::milliseconds maximum_rotation_time);
// TODO(jpawlowski): remove once we have config file abstraction in cert tests
void SetPrivacyPolicyForInitiatorAddressForTest(
AddressPolicy address_policy,
AddressWithType fixed_address,
crypto_toolbox::Octet16 rotation_irk,
std::chrono::milliseconds minimum_rotation_time,
std::chrono::milliseconds maximum_rotation_time);
AddressPolicy GetAddressPolicy();
void AckPause(LeAddressManagerCallback* callback);
void AckResume(LeAddressManagerCallback* callback);
virtual AddressPolicy Register(LeAddressManagerCallback* callback);
virtual void Unregister(LeAddressManagerCallback* callback);
virtual bool UnregisterSync(
LeAddressManagerCallback* callback, std::chrono::milliseconds timeout = kUnregisterSyncTimeoutInMs);
virtual AddressWithType GetCurrentAddress(); // What was set in SetRandomAddress()
virtual AddressWithType GetAnotherAddress(); // A new random address without rotating.
uint8_t GetFilterAcceptListSize();
uint8_t GetResolvingListSize();
void AddDeviceToFilterAcceptList(FilterAcceptListAddressType connect_list_address_type, Address address);
void AddDeviceToResolvingList(
PeerAddressType peer_identity_address_type,
Address peer_identity_address,
const std::array<uint8_t, 16>& peer_irk,
const std::array<uint8_t, 16>& local_irk);
void RemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType connect_list_address_type, Address address);
void RemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type, Address peer_identity_address);
void ClearFilterAcceptList();
void ClearResolvingList();
void OnCommandComplete(CommandCompleteView view);
std::chrono::milliseconds GetNextPrivateAddressIntervalMs();
private:
enum ClientState {
WAITING_FOR_PAUSE,
PAUSED,
WAITING_FOR_RESUME,
RESUMED,
};
enum CommandType {
ROTATE_RANDOM_ADDRESS,
ADD_DEVICE_TO_CONNECT_LIST,
REMOVE_DEVICE_FROM_CONNECT_LIST,
CLEAR_CONNECT_LIST,
ADD_DEVICE_TO_RESOLVING_LIST,
REMOVE_DEVICE_FROM_RESOLVING_LIST,
CLEAR_RESOLVING_LIST,
SET_ADDRESS_RESOLUTION_ENABLE,
LE_SET_PRIVACY_MODE
};
struct Command {
CommandType command_type;
std::unique_ptr<CommandBuilder> command_packet;
};
void pause_registered_clients();
void push_command(Command command);
void ack_pause(LeAddressManagerCallback* callback);
void resume_registered_clients();
void ack_resume(LeAddressManagerCallback* callback);
void register_client(LeAddressManagerCallback* callback);
void unregister_client(LeAddressManagerCallback* callback);
void prepare_to_rotate();
void rotate_random_address();
void schedule_rotate_random_address();
void set_random_address();
hci::Address generate_rpa();
hci::Address generate_nrpa();
void handle_next_command();
void check_cached_commands();
template <class View>
void on_command_complete(CommandCompleteView view);
common::Callback<void(std::unique_ptr<CommandBuilder>)> enqueue_command_;
os::Handler* handler_;
std::map<LeAddressManagerCallback*, ClientState> registered_clients_;
AddressPolicy address_policy_ = AddressPolicy::POLICY_NOT_SET;
AddressWithType le_address_;
AddressWithType cached_address_;
Address public_address_;
std::unique_ptr<os::Alarm> address_rotation_alarm_;
crypto_toolbox::Octet16 rotation_irk_;
std::chrono::milliseconds minimum_rotation_time_;
std::chrono::milliseconds maximum_rotation_time_;
uint8_t connect_list_size_;
uint8_t resolving_list_size_;
std::queue<Command> cached_commands_;
bool supports_ble_privacy_{false};
};
} // namespace hci
} // namespace bluetooth
|