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