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
17 #pragma once
18
19 #include <base/strings/stringprintf.h>
20 #include <bluetooth/log.h>
21 #include <hardware/bluetooth.h>
22
23 #include <cstdint>
24 #include <string>
25
26 #include "macros.h"
27
28 /*
29 * Definitions for HCI Error Codes that are passed in the events
30 */
31 typedef enum : uint8_t {
32 HCI_SUCCESS = 0x00,
33 HCI_ERR_ILLEGAL_COMMAND = 0x01,
34 HCI_ERR_NO_CONNECTION = 0x02,
35 HCI_ERR_HW_FAILURE = 0x03,
36 HCI_ERR_PAGE_TIMEOUT = 0x04,
37 HCI_ERR_AUTH_FAILURE = 0x05,
38 HCI_ERR_KEY_MISSING = 0x06,
39 HCI_ERR_MEMORY_FULL = 0x07,
40 HCI_ERR_CONNECTION_TOUT = 0x08,
41 HCI_ERR_MAX_NUM_OF_CONNECTIONS = 0x09,
42 HCI_ERR_MAX_NUM_OF_SCOS = 0x0A,
43 HCI_ERR_CONNECTION_EXISTS = 0x0B,
44 HCI_ERR_COMMAND_DISALLOWED = 0x0C,
45 HCI_ERR_HOST_REJECT_RESOURCES = 0x0D,
46 HCI_ERR_HOST_REJECT_SECURITY = 0x0E,
47 HCI_ERR_HOST_REJECT_DEVICE = 0x0F,
48 HCI_ERR_HOST_TIMEOUT = 0x10, // stack/btm/btm_ble_gap,
49 HCI_ERR_ILLEGAL_PARAMETER_FMT = 0x12,
50 HCI_ERR_PEER_USER = 0x13,
51 HCI_ERR_REMOTE_LOW_RESOURCE = 0x14,
52 HCI_ERR_REMOTE_POWER_OFF = 0x15,
53 HCI_ERR_CONN_CAUSE_LOCAL_HOST = 0x16,
54 HCI_ERR_REPEATED_ATTEMPTS = 0x17,
55 HCI_ERR_PAIRING_NOT_ALLOWED = 0x18,
56 HCI_ERR_UNSUPPORTED_REM_FEATURE = 0x1A, // stack/btm/btm_ble_gap
57 HCI_ERR_UNSPECIFIED = 0x1F,
58 HCI_ERR_LMP_RESPONSE_TIMEOUT = 0x22, // GATT_CONN_LMP_TIMEOUT
59 HCI_ERR_LMP_ERR_TRANS_COLLISION = 0x23, // TODO remove
60 HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE = 0x25,
61 HCI_ERR_UNIT_KEY_USED = 0x26,
62 HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
63 HCI_ERR_DIFF_TRANSACTION_COLLISION = 0x2A, // stack/btm/btm_sec
64 HCI_ERR_INSUFFCIENT_SECURITY = 0x2F, // btif/btu
65 HCI_ERR_ROLE_SWITCH_PENDING = 0x32, // stack/btm/btm_sco
66 HCI_ERR_ROLE_SWITCH_FAILED = 0x35,
67 HCI_ERR_HOST_BUSY_PAIRING = 0x38, // stack/btm/btm_sec
68 HCI_ERR_UNACCEPT_CONN_INTERVAL = 0x3B, // stack/l2cap/l2c_ble
69 HCI_ERR_ADVERTISING_TIMEOUT = 0x3C, // stack/btm/btm_ble
70 HCI_ERR_CONN_FAILED_ESTABLISHMENT = 0x3E, // GATT_CONN_FAIL_ESTABLISH
71 HCI_ERR_LIMIT_REACHED = 0x43, // stack/btm/btm_ble_multi_adv.cc
72 HCI_ERR_CANCELLED_BY_LOCAL_HOST = 0x44, // stack/btm/btm_iso_impl.h
73
74 _HCI_ERR_MAX_ERR = 0x44,
75 HCI_ERR_UNDEFINED = 0xff,
76 } tHCI_ERROR_CODE;
77
78 #define HCI_ERR_MAX_ERR _HCI_ERR_MAX_ERR // HACK for now for SMP
79
hci_error_code_text(const tHCI_ERROR_CODE & error_code)80 inline std::string hci_error_code_text(const tHCI_ERROR_CODE& error_code) {
81 switch (error_code) {
82 CASE_RETURN_TEXT(HCI_SUCCESS);
83 CASE_RETURN_TEXT(HCI_ERR_ILLEGAL_COMMAND);
84 CASE_RETURN_TEXT(HCI_ERR_NO_CONNECTION);
85 CASE_RETURN_TEXT(HCI_ERR_HW_FAILURE);
86 CASE_RETURN_TEXT(HCI_ERR_PAGE_TIMEOUT);
87 CASE_RETURN_TEXT(HCI_ERR_AUTH_FAILURE);
88 CASE_RETURN_TEXT(HCI_ERR_KEY_MISSING);
89 CASE_RETURN_TEXT(HCI_ERR_MEMORY_FULL);
90 CASE_RETURN_TEXT(HCI_ERR_CONNECTION_TOUT);
91 CASE_RETURN_TEXT(HCI_ERR_MAX_NUM_OF_CONNECTIONS);
92 CASE_RETURN_TEXT(HCI_ERR_MAX_NUM_OF_SCOS);
93 CASE_RETURN_TEXT(HCI_ERR_CONNECTION_EXISTS);
94 CASE_RETURN_TEXT(HCI_ERR_COMMAND_DISALLOWED);
95 CASE_RETURN_TEXT(HCI_ERR_HOST_REJECT_RESOURCES);
96 CASE_RETURN_TEXT(HCI_ERR_HOST_REJECT_SECURITY);
97 CASE_RETURN_TEXT(HCI_ERR_HOST_REJECT_DEVICE);
98 CASE_RETURN_TEXT(HCI_ERR_HOST_TIMEOUT);
99 CASE_RETURN_TEXT(HCI_ERR_ILLEGAL_PARAMETER_FMT);
100 CASE_RETURN_TEXT(HCI_ERR_PEER_USER);
101 CASE_RETURN_TEXT(HCI_ERR_REMOTE_LOW_RESOURCE);
102 CASE_RETURN_TEXT(HCI_ERR_REMOTE_POWER_OFF);
103 CASE_RETURN_TEXT(HCI_ERR_CONN_CAUSE_LOCAL_HOST);
104 CASE_RETURN_TEXT(HCI_ERR_REPEATED_ATTEMPTS);
105 CASE_RETURN_TEXT(HCI_ERR_PAIRING_NOT_ALLOWED);
106 CASE_RETURN_TEXT(HCI_ERR_UNSUPPORTED_REM_FEATURE);
107 CASE_RETURN_TEXT(HCI_ERR_UNSPECIFIED);
108 CASE_RETURN_TEXT(HCI_ERR_LMP_RESPONSE_TIMEOUT);
109 CASE_RETURN_TEXT(HCI_ERR_LMP_ERR_TRANS_COLLISION);
110 CASE_RETURN_TEXT(HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE);
111 CASE_RETURN_TEXT(HCI_ERR_UNIT_KEY_USED);
112 CASE_RETURN_TEXT(HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED);
113 CASE_RETURN_TEXT(HCI_ERR_DIFF_TRANSACTION_COLLISION);
114 CASE_RETURN_TEXT(HCI_ERR_INSUFFCIENT_SECURITY);
115 CASE_RETURN_TEXT(HCI_ERR_ROLE_SWITCH_PENDING);
116 CASE_RETURN_TEXT(HCI_ERR_ROLE_SWITCH_FAILED);
117 CASE_RETURN_TEXT(HCI_ERR_HOST_BUSY_PAIRING);
118 CASE_RETURN_TEXT(HCI_ERR_UNACCEPT_CONN_INTERVAL);
119 CASE_RETURN_TEXT(HCI_ERR_ADVERTISING_TIMEOUT);
120 CASE_RETURN_TEXT(HCI_ERR_CONN_FAILED_ESTABLISHMENT);
121 CASE_RETURN_TEXT(HCI_ERR_LIMIT_REACHED);
122 CASE_RETURN_TEXT(HCI_ERR_CANCELLED_BY_LOCAL_HOST);
123 default:
124 return base::StringPrintf("UNKNOWN[0x%02hx]", error_code);
125 }
126 }
127
hci_error_to_bt_status(const tHCI_ERROR_CODE & error_code)128 inline bt_status_t hci_error_to_bt_status(const tHCI_ERROR_CODE& error_code) {
129 switch (error_code) {
130 case HCI_SUCCESS: /* 0x00 */
131 return BT_STATUS_SUCCESS;
132 case HCI_ERR_ILLEGAL_COMMAND: /* 0x01 */
133 return BT_STATUS_UNSUPPORTED;
134 case HCI_ERR_NO_CONNECTION: /* 0x02 */
135 return BT_STATUS_NOT_READY;
136 case HCI_ERR_HW_FAILURE: /* 0x03 */
137 return BT_STATUS_FAIL;
138 case HCI_ERR_PAGE_TIMEOUT: /* 0x04 */
139 return BT_STATUS_TIMEOUT;
140 case HCI_ERR_AUTH_FAILURE: /* 0x05 */
141 return BT_STATUS_AUTH_FAILURE;
142 case HCI_ERR_KEY_MISSING: /* 0x06 */
143 return BT_STATUS_AUTH_FAILURE;
144 case HCI_ERR_MEMORY_FULL: /* 0x07 */
145 return BT_STATUS_NOMEM;
146 case HCI_ERR_CONNECTION_TOUT: /* 0x08 */
147 return BT_STATUS_TIMEOUT;
148 case HCI_ERR_MAX_NUM_OF_CONNECTIONS: /* 0x09 */
149 return BT_STATUS_FAIL;
150 case HCI_ERR_MAX_NUM_OF_SCOS: /* 0x0A */
151 return BT_STATUS_FAIL;
152 case HCI_ERR_CONNECTION_EXISTS: /* 0x0B */
153 return BT_STATUS_BUSY;
154 case HCI_ERR_COMMAND_DISALLOWED: /* 0x0C */
155 return BT_STATUS_UNSUPPORTED;
156 case HCI_ERR_HOST_REJECT_RESOURCES: /* 0x0D */
157 return BT_STATUS_BUSY;
158 case HCI_ERR_HOST_REJECT_SECURITY: /* 0x0E */
159 return BT_STATUS_AUTH_REJECTED;
160 case HCI_ERR_HOST_REJECT_DEVICE: /* 0x0F */
161 return BT_STATUS_AUTH_REJECTED;
162 case HCI_ERR_HOST_TIMEOUT: /* 0x10 */
163 return BT_STATUS_TIMEOUT;
164 case HCI_ERR_ILLEGAL_PARAMETER_FMT: /* 0x12 */
165 return BT_STATUS_PARM_INVALID;
166 case HCI_ERR_PEER_USER: /* 0x13 */
167 return BT_STATUS_RMT_DEV_DOWN;
168 case HCI_ERR_REMOTE_LOW_RESOURCE: /* 0x14 */
169 return BT_STATUS_RMT_DEV_DOWN;
170 case HCI_ERR_REMOTE_POWER_OFF: /* 0x15 */
171 return BT_STATUS_RMT_DEV_DOWN;
172 case HCI_ERR_CONN_CAUSE_LOCAL_HOST: /* 0x16 */
173 return BT_STATUS_DONE;
174 case HCI_ERR_REPEATED_ATTEMPTS: /* 0x17 */
175 return BT_STATUS_FAIL;
176 case HCI_ERR_PAIRING_NOT_ALLOWED: /* 0x18 */
177 return BT_STATUS_AUTH_REJECTED;
178 case HCI_ERR_UNSUPPORTED_REM_FEATURE: /* 0x1A */
179 return BT_STATUS_UNSUPPORTED;
180 case HCI_ERR_UNSPECIFIED: /* 0x1F */
181 return BT_STATUS_FAIL;
182 case HCI_ERR_LMP_RESPONSE_TIMEOUT: /* 0x22 */
183 return BT_STATUS_TIMEOUT;
184 case HCI_ERR_LMP_ERR_TRANS_COLLISION: /* 0x23 */
185 return BT_STATUS_FAIL;
186 case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE: /* 0x25 */
187 return BT_STATUS_AUTH_REJECTED;
188 case HCI_ERR_UNIT_KEY_USED: /* 0x26 */
189 return BT_STATUS_AUTH_FAILURE;
190 case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED: /* 0x29 */
191 return BT_STATUS_UNSUPPORTED;
192 case HCI_ERR_DIFF_TRANSACTION_COLLISION: /* 0x2A */
193 return BT_STATUS_FAIL;
194 case HCI_ERR_INSUFFCIENT_SECURITY: /* 0x2F */
195 return BT_STATUS_AUTH_REJECTED;
196 case HCI_ERR_ROLE_SWITCH_PENDING: /* 0x32 */
197 return BT_STATUS_BUSY;
198 case HCI_ERR_ROLE_SWITCH_FAILED: /* 0x35 */
199 return BT_STATUS_FAIL;
200 case HCI_ERR_HOST_BUSY_PAIRING: /* 0x38 */
201 return BT_STATUS_BUSY;
202 case HCI_ERR_UNACCEPT_CONN_INTERVAL: /* 0x3B */
203 return BT_STATUS_PARM_INVALID;
204 case HCI_ERR_ADVERTISING_TIMEOUT: /* 0x3C */
205 return BT_STATUS_TIMEOUT;
206 case HCI_ERR_CONN_FAILED_ESTABLISHMENT: /* 0x3E */
207 return BT_STATUS_FAIL;
208 case HCI_ERR_LIMIT_REACHED: /* 0x43 */
209 return BT_STATUS_FAIL;
210 case HCI_ERR_CANCELLED_BY_LOCAL_HOST: /* 0x44 */
211 return BT_STATUS_DONE;
212 default:
213 return BT_STATUS_FAIL;
214 }
215 }
216
217 // Context equivalence
218 using tHCI_STATUS = tHCI_ERROR_CODE;
hci_status_code_text(const tHCI_STATUS & status_code)219 inline std::string hci_status_code_text(const tHCI_STATUS& status_code) {
220 return hci_error_code_text(status_code);
221 }
222
223 using tHCI_REASON = tHCI_ERROR_CODE;
hci_reason_code_text(const tHCI_REASON & reason_code)224 inline std::string hci_reason_code_text(const tHCI_REASON& reason_code) {
225 return hci_error_code_text(reason_code);
226 }
227
228 // Conversion from raw packet value
to_hci_error_code(const uint8_t & error_code)229 inline tHCI_ERROR_CODE to_hci_error_code(const uint8_t& error_code) {
230 if (error_code > _HCI_ERR_MAX_ERR) {
231 return HCI_ERR_UNDEFINED;
232 }
233 return static_cast<tHCI_ERROR_CODE>(error_code);
234 }
235
to_hci_status_code(const uint8_t & status_code)236 inline tHCI_STATUS to_hci_status_code(const uint8_t& status_code) {
237 if (status_code > _HCI_ERR_MAX_ERR) {
238 return HCI_ERR_UNDEFINED;
239 }
240 return static_cast<tHCI_STATUS>(status_code);
241 }
242
to_hci_reason_code(const uint8_t & reason_code)243 inline tHCI_REASON to_hci_reason_code(const uint8_t& reason_code) {
244 if (reason_code > _HCI_ERR_MAX_ERR) {
245 return HCI_ERR_UNDEFINED;
246 }
247 return static_cast<tHCI_REASON>(reason_code);
248 }
249
250 namespace std {
251 template <>
252 struct formatter<tHCI_ERROR_CODE> : enum_formatter<tHCI_ERROR_CODE> {};
253 } // namespace std
254