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