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