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