1 /*
2 * Copyright 2020 The Android Open Source Project
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 #pragma once
17
18 #include "hci/address_with_type.h"
19
20 #include "gd/common/init_flags.h"
21 #include "gd/packet/raw_builder.h"
22 #include "osi/include/allocator.h"
23 #include "stack/include/bt_types.h"
24 #include "stack/include/hci_error_code.h"
25 #include "stack/include/hcidefs.h"
26 #include "types/ble_address_with_type.h"
27 #include "types/hci_role.h"
28
29 namespace bluetooth {
30
ToRawAddress(const hci::Address & address)31 inline RawAddress ToRawAddress(const hci::Address& address) {
32 RawAddress ret;
33 ret.address[0] = address.address[5];
34 ret.address[1] = address.address[4];
35 ret.address[2] = address.address[3];
36 ret.address[3] = address.address[2];
37 ret.address[4] = address.address[1];
38 ret.address[5] = address.address[0];
39 return ret;
40 }
41
ToGdAddress(const RawAddress & address)42 inline hci::Address ToGdAddress(const RawAddress& address) {
43 hci::Address ret;
44 ret.address[0] = address.address[5];
45 ret.address[1] = address.address[4];
46 ret.address[2] = address.address[3];
47 ret.address[3] = address.address[2];
48 ret.address[4] = address.address[1];
49 ret.address[5] = address.address[0];
50 return ret;
51 }
52
ToAddressWithType(const RawAddress & legacy_address,const tBLE_ADDR_TYPE & legacy_type)53 inline hci::AddressWithType ToAddressWithType(
54 const RawAddress& legacy_address, const tBLE_ADDR_TYPE& legacy_type) {
55 hci::Address address = ToGdAddress(legacy_address);
56
57 hci::AddressType type;
58 if (legacy_type == BLE_ADDR_PUBLIC)
59 type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
60 else if (legacy_type == BLE_ADDR_RANDOM)
61 type = hci::AddressType::RANDOM_DEVICE_ADDRESS;
62 else if (legacy_type == BLE_ADDR_PUBLIC_ID)
63 type = hci::AddressType::PUBLIC_IDENTITY_ADDRESS;
64 else if (legacy_type == BLE_ADDR_RANDOM_ID)
65 type = hci::AddressType::RANDOM_IDENTITY_ADDRESS;
66 else {
67 LOG_ALWAYS_FATAL("Bad address type %02x", legacy_type);
68 return hci::AddressWithType{address,
69 hci::AddressType::PUBLIC_DEVICE_ADDRESS};
70 }
71
72 return hci::AddressWithType{address, type};
73 }
74
ToAddressWithTypeFromLegacy(const tBLE_BD_ADDR & legacy_address_with_type)75 inline hci::AddressWithType ToAddressWithTypeFromLegacy(
76 const tBLE_BD_ADDR& legacy_address_with_type) {
77 return ToAddressWithType(legacy_address_with_type.bda,
78 legacy_address_with_type.type);
79 }
80
ToLegacyAddressWithType(const hci::AddressWithType & address_with_type)81 inline tBLE_BD_ADDR ToLegacyAddressWithType(
82 const hci::AddressWithType& address_with_type) {
83 tBLE_BD_ADDR legacy_address_with_type;
84 legacy_address_with_type.bda = ToRawAddress(address_with_type.GetAddress());
85
86 if (address_with_type.GetAddressType() ==
87 hci::AddressType::PUBLIC_DEVICE_ADDRESS) {
88 legacy_address_with_type.type = BLE_ADDR_PUBLIC;
89 } else if (address_with_type.GetAddressType() ==
90 hci::AddressType::RANDOM_DEVICE_ADDRESS) {
91 legacy_address_with_type.type = BLE_ADDR_RANDOM;
92 } else if (address_with_type.GetAddressType() ==
93 hci::AddressType::PUBLIC_IDENTITY_ADDRESS) {
94 legacy_address_with_type.type = BLE_ADDR_PUBLIC_ID;
95 } else if (address_with_type.GetAddressType() ==
96 hci::AddressType::RANDOM_IDENTITY_ADDRESS) {
97 legacy_address_with_type.type = BLE_ADDR_RANDOM_ID;
98 } else {
99 LOG_ALWAYS_FATAL("%s Bad address type %02x", __func__,
100 static_cast<uint8_t>(address_with_type.GetAddressType()));
101 legacy_address_with_type.type = BLE_ADDR_PUBLIC;
102 }
103 return legacy_address_with_type;
104 }
105
MakeUniquePacket(const uint8_t * data,size_t len,bool is_flushable)106 inline std::unique_ptr<bluetooth::packet::RawBuilder> MakeUniquePacket(
107 const uint8_t* data, size_t len, bool is_flushable) {
108 bluetooth::packet::RawBuilder builder;
109 std::vector<uint8_t> bytes(data, data + len);
110 auto payload = std::make_unique<bluetooth::packet::RawBuilder>();
111 payload->AddOctets(bytes);
112 payload->SetFlushable(is_flushable);
113 return payload;
114 }
115
MakeLegacyBtHdrPacket(std::unique_ptr<bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian>> packet,const std::vector<uint8_t> & preamble)116 inline BT_HDR* MakeLegacyBtHdrPacket(
117 std::unique_ptr<bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian>>
118 packet,
119 const std::vector<uint8_t>& preamble) {
120 std::vector<uint8_t> packet_vector(packet->begin(), packet->end());
121 BT_HDR* buffer = static_cast<BT_HDR*>(
122 osi_calloc(packet_vector.size() + preamble.size() + sizeof(BT_HDR)));
123 std::copy(preamble.begin(), preamble.end(), buffer->data);
124 std::copy(packet_vector.begin(), packet_vector.end(),
125 buffer->data + preamble.size());
126 buffer->len = preamble.size() + packet_vector.size();
127 return buffer;
128 }
129
ToLegacyRole(hci::Role role)130 inline tHCI_ROLE ToLegacyRole(hci::Role role) {
131 return to_hci_role(static_cast<uint8_t>(role));
132 }
133
ToHciRole(const hci_role_t & role)134 inline hci::Role ToHciRole(const hci_role_t& role) {
135 switch (role) {
136 case HCI_ROLE_CENTRAL:
137 return hci::Role::CENTRAL;
138 case HCI_ROLE_PERIPHERAL:
139 return hci::Role::PERIPHERAL;
140 default:
141 ASSERT_LOG(false, "Unable to determine legacy role:%u", role);
142 }
143 }
144
ToLegacyHciErrorCode(const hci::ErrorCode & reason)145 inline tHCI_STATUS ToLegacyHciErrorCode(const hci::ErrorCode& reason) {
146 switch (reason) {
147 case hci::ErrorCode::SUCCESS:
148 return HCI_SUCCESS;
149 case hci::ErrorCode::UNKNOWN_HCI_COMMAND:
150 return HCI_ERR_ILLEGAL_COMMAND;
151 case hci::ErrorCode::UNKNOWN_CONNECTION:
152 return HCI_ERR_NO_CONNECTION;
153 case hci::ErrorCode::HARDWARE_FAILURE:
154 return HCI_ERR_HW_FAILURE;
155 case hci::ErrorCode::PAGE_TIMEOUT:
156 return HCI_ERR_PAGE_TIMEOUT;
157 case hci::ErrorCode::AUTHENTICATION_FAILURE:
158 return HCI_ERR_AUTH_FAILURE;
159 case hci::ErrorCode::PIN_OR_KEY_MISSING:
160 return HCI_ERR_KEY_MISSING;
161 case hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED:
162 return HCI_ERR_MEMORY_FULL;
163 case hci::ErrorCode::CONNECTION_TIMEOUT:
164 return HCI_ERR_CONNECTION_TOUT;
165 case hci::ErrorCode::CONNECTION_LIMIT_EXCEEDED:
166 return HCI_ERR_MAX_NUM_OF_CONNECTIONS;
167 case hci::ErrorCode::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED:
168 return HCI_ERR_MAX_NUM_OF_SCOS;
169 case hci::ErrorCode::CONNECTION_ALREADY_EXISTS:
170 return HCI_ERR_CONNECTION_EXISTS;
171 case hci::ErrorCode::COMMAND_DISALLOWED:
172 return HCI_ERR_COMMAND_DISALLOWED;
173 case hci::ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES:
174 return HCI_ERR_HOST_REJECT_RESOURCES;
175 case hci::ErrorCode::CONNECTION_REJECTED_SECURITY_REASONS:
176 return HCI_ERR_HOST_REJECT_SECURITY;
177 case hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR:
178 return HCI_ERR_HOST_REJECT_DEVICE;
179 case hci::ErrorCode::CONNECTION_ACCEPT_TIMEOUT:
180 return HCI_ERR_HOST_TIMEOUT;
181 case hci::ErrorCode::UNSUPORTED_FEATURE_OR_PARAMETER_VALUE:
182 return static_cast<tHCI_STATUS>(
183 hci::ErrorCode::UNSUPORTED_FEATURE_OR_PARAMETER_VALUE);
184 case hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS:
185 return HCI_ERR_ILLEGAL_PARAMETER_FMT;
186 case hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION:
187 return HCI_ERR_PEER_USER;
188 case hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES:
189 return static_cast<tHCI_STATUS>(
190 hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES);
191 case hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF:
192 return static_cast<tHCI_STATUS>(
193 hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF);
194 case hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST:
195 return HCI_ERR_CONN_CAUSE_LOCAL_HOST;
196 case hci::ErrorCode::REPEATED_ATTEMPTS:
197 return HCI_ERR_REPEATED_ATTEMPTS;
198 case hci::ErrorCode::PAIRING_NOT_ALLOWED:
199 return HCI_ERR_PAIRING_NOT_ALLOWED;
200 case hci::ErrorCode::UNKNOWN_LMP_PDU:
201 return static_cast<tHCI_STATUS>(hci::ErrorCode::UNKNOWN_LMP_PDU);
202 case hci::ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE:
203 return HCI_ERR_UNSUPPORTED_REM_FEATURE;
204 case hci::ErrorCode::SCO_OFFSET_REJECTED:
205 return static_cast<tHCI_STATUS>(hci::ErrorCode::SCO_OFFSET_REJECTED);
206 case hci::ErrorCode::SCO_INTERVAL_REJECTED:
207 return static_cast<tHCI_STATUS>(hci::ErrorCode::SCO_INTERVAL_REJECTED);
208 case hci::ErrorCode::SCO_AIR_MODE_REJECTED:
209 return static_cast<tHCI_STATUS>(hci::ErrorCode::SCO_AIR_MODE_REJECTED);
210 case hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS:
211 return static_cast<tHCI_STATUS>(
212 hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
213 case hci::ErrorCode::UNSPECIFIED_ERROR:
214 return HCI_ERR_UNSPECIFIED;
215 case hci::ErrorCode::UNSUPPORTED_LMP_OR_LL_PARAMETER:
216 return static_cast<tHCI_STATUS>(
217 hci::ErrorCode::UNSUPPORTED_LMP_OR_LL_PARAMETER);
218 case hci::ErrorCode::ROLE_CHANGE_NOT_ALLOWED:
219 return static_cast<tHCI_STATUS>(hci::ErrorCode::ROLE_CHANGE_NOT_ALLOWED);
220 case hci::ErrorCode::LINK_LAYER_COLLISION:
221 return HCI_ERR_LMP_ERR_TRANS_COLLISION;
222 case hci::ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE:
223 return HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE;
224 case hci::ErrorCode::ROLE_SWITCH_FAILED:
225 return static_cast<tHCI_STATUS>(hci::ErrorCode::ROLE_SWITCH_FAILED);
226 case hci::ErrorCode::CONTROLLER_BUSY:
227 return static_cast<tHCI_STATUS>(hci::ErrorCode::CONTROLLER_BUSY);
228 case hci::ErrorCode::CONNECTION_FAILED_ESTABLISHMENT:
229 return static_cast<tHCI_STATUS>(
230 hci::ErrorCode::CONNECTION_FAILED_ESTABLISHMENT);
231 case hci::ErrorCode::STATUS_UNKNOWN:
232 return HCI_ERR_UNDEFINED;
233 default:
234 return static_cast<tHCI_REASON>(reason);
235 }
236 }
237
ToLegacyHciMode(const hci::Mode & mode)238 inline tHCI_MODE ToLegacyHciMode(const hci::Mode& mode) {
239 return static_cast<tHCI_MODE>(mode);
240 }
241
ToDisconnectReasonFromLegacy(const tHCI_STATUS & reason)242 inline hci::DisconnectReason ToDisconnectReasonFromLegacy(
243 const tHCI_STATUS& reason) {
244 return static_cast<hci::DisconnectReason>(reason);
245 }
246
IsPacketFlushable(const BT_HDR * p_buf)247 inline bool IsPacketFlushable(const BT_HDR* p_buf) {
248 ASSERT(p_buf != nullptr);
249 return ToPacketData<const HciDataPreamble>(p_buf)->IsFlushable();
250 }
251
252 namespace debug {
253
DumpBtHdr(const BT_HDR * p_buf,const char * token)254 inline void DumpBtHdr(const BT_HDR* p_buf, const char* token) {
255 uint16_t len = p_buf->len;
256 char buf[255];
257 const uint8_t* data = p_buf->data + p_buf->offset;
258 int cnt = 0;
259 while (len > 0) {
260 memset(buf, 0, sizeof(buf));
261 char* pbuf = buf;
262 pbuf += sprintf(pbuf, "len:%5u %5d: ", p_buf->len, cnt);
263 for (int j = 0; j < 16; j++, --len, data++, cnt++) {
264 if (len == 0) break;
265 pbuf += sprintf(pbuf, "0x%02x ", *data);
266 }
267 LOG_DEBUG("%s %s", token, buf);
268 }
269 }
270
271 } // namespace debug
272 } // namespace bluetooth
273