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 <string>
21 
22 /*
23  *  Definitions for HCI Error Codes that are passed in the events
24  */
25 typedef enum : uint8_t {
26   HCI_SUCCESS = 0x00,
27   HCI_ERR_ILLEGAL_COMMAND = 0x01,
28   HCI_ERR_NO_CONNECTION = 0x02,
29   HCI_ERR_HW_FAILURE = 0x03,
30   HCI_ERR_PAGE_TIMEOUT = 0x04,
31   HCI_ERR_AUTH_FAILURE = 0x05,
32   HCI_ERR_KEY_MISSING = 0x06,
33   HCI_ERR_MEMORY_FULL = 0x07,
34   HCI_ERR_CONNECTION_TOUT = 0x08,
35   HCI_ERR_MAX_NUM_OF_CONNECTIONS = 0x09,
36   HCI_ERR_MAX_NUM_OF_SCOS = 0x0A,
37   HCI_ERR_CONNECTION_EXISTS = 0x0B,
38   HCI_ERR_COMMAND_DISALLOWED = 0x0C,
39   HCI_ERR_HOST_REJECT_RESOURCES = 0x0D,
40   HCI_ERR_HOST_REJECT_SECURITY = 0x0E,
41   HCI_ERR_HOST_REJECT_DEVICE = 0x0F,
42   HCI_ERR_HOST_TIMEOUT = 0x10,  // stack/btm/btm_ble_gap,
43   HCI_ERR_ILLEGAL_PARAMETER_FMT = 0x12,
44   HCI_ERR_PEER_USER = 0x13,
45   HCI_ERR_CONN_CAUSE_LOCAL_HOST = 0x16,
46   HCI_ERR_REPEATED_ATTEMPTS = 0x17,
47   HCI_ERR_PAIRING_NOT_ALLOWED = 0x18,
48   HCI_ERR_UNSUPPORTED_REM_FEATURE = 0x1A,  // stack/btm/btm_ble_gap
49   HCI_ERR_UNSPECIFIED = 0x1F,
50   HCI_ERR_LMP_RESPONSE_TIMEOUT = 0x22,     // GATT_CONN_LMP_TIMEOUT
51   HCI_ERR_LMP_ERR_TRANS_COLLISION = 0x23,  // TODO remove
52   HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE = 0x25,
53   HCI_ERR_UNIT_KEY_USED = 0x26,
54   HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
55   HCI_ERR_DIFF_TRANSACTION_COLLISION = 0x2A,  // stack/btm/btm_sec
56   HCI_ERR_INSUFFCIENT_SECURITY = 0x2F,        // btif/btu
57   HCI_ERR_ROLE_SWITCH_PENDING = 0x32,         // stack/btm/btm_sco
58   HCI_ERR_ROLE_SWITCH_FAILED = 0x35,
59   HCI_ERR_HOST_BUSY_PAIRING = 0x38,          // stack/btm/btm_sec
60   HCI_ERR_UNACCEPT_CONN_INTERVAL = 0x3B,     // stack/l2cap/l2c_ble
61   HCI_ERR_ADVERTISING_TIMEOUT = 0x3C,        // stack/btm/btm_ble
62   HCI_ERR_CONN_FAILED_ESTABLISHMENT = 0x3E,  // GATT_CONN_FAIL_ESTABLISH
63   HCI_ERR_LIMIT_REACHED = 0x43,              // stack/btm/btm_ble_multi_adv.cc
64 
65   _HCI_ERR_MAX_ERR = 0x43,
66   HCI_ERR_UNDEFINED = 0xff,
67 } tHCI_ERROR_CODE;
68 
69 #define HCI_ERR_MAX_ERR _HCI_ERR_MAX_ERR  // HACK for now for SMP
70 
hci_error_code_text(const tHCI_ERROR_CODE & error_code)71 inline std::string hci_error_code_text(const tHCI_ERROR_CODE& error_code) {
72   switch (error_code) {
73     case HCI_SUCCESS:
74       return std::string("Success");
75     case HCI_ERR_ILLEGAL_COMMAND:
76       return std::string("Illegal Command");
77     case HCI_ERR_NO_CONNECTION:
78       return std::string("Unknown Connection");
79     case HCI_ERR_HW_FAILURE:
80       return std::string("Hardware Failure");
81     case HCI_ERR_PAGE_TIMEOUT:
82       return std::string("Page Timeout");
83     case HCI_ERR_AUTH_FAILURE:
84       return std::string("Authentication Failure");
85     case HCI_ERR_KEY_MISSING:
86       return std::string("Pin or Key Missing");
87     case HCI_ERR_MEMORY_FULL:
88       return std::string("Memory Capacity Exceeded");
89     case HCI_ERR_CONNECTION_TOUT:
90       return std::string("Connection Timeout");
91     case HCI_ERR_MAX_NUM_OF_CONNECTIONS:
92       return std::string("Connection Limit Exceeded");
93     case HCI_ERR_MAX_NUM_OF_SCOS:
94       return std::string("Synchronous Connection Limit Exceeded");
95     case HCI_ERR_CONNECTION_EXISTS:
96       return std::string("Connection Already Exists");
97     case HCI_ERR_COMMAND_DISALLOWED:
98       return std::string("Command Disallowed");
99     case HCI_ERR_HOST_REJECT_RESOURCES:
100       return std::string("Connection Rejected Limited Resources");
101     case HCI_ERR_HOST_REJECT_SECURITY:
102       return std::string("Connection Rejected Security Reasons");
103     case HCI_ERR_HOST_REJECT_DEVICE:
104       return std::string("Connection Rejected Unacceptable BdAddr");
105     case HCI_ERR_HOST_TIMEOUT:
106       return std::string("Connection Accept Timeout");
107     case HCI_ERR_ILLEGAL_PARAMETER_FMT:
108       return std::string("Unsupported Feature or Parameter Value");
109     case HCI_ERR_PEER_USER:
110       return std::string("Remote Terminated Connection");
111     case HCI_ERR_CONN_CAUSE_LOCAL_HOST:
112       return std::string("Local Terminated Connection");
113     case HCI_ERR_REPEATED_ATTEMPTS:
114       return std::string("Repeated Attempts");
115     case HCI_ERR_PAIRING_NOT_ALLOWED:
116       return std::string("Pairing not Allowed");
117     case HCI_ERR_UNSUPPORTED_REM_FEATURE:
118       return std::string("Unsupported Remote or Lmp Feature");
119     case HCI_ERR_UNSPECIFIED:
120       return std::string("Unspecified Error");
121     case HCI_ERR_LMP_RESPONSE_TIMEOUT:
122       return std::string("Gatt Connection Lmp Timeout");
123     case HCI_ERR_LMP_ERR_TRANS_COLLISION:
124       return std::string("Link Layer Collision");
125     case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE:
126       return std::string("Encryption Mode not Acceptable");
127     case HCI_ERR_UNIT_KEY_USED:
128       return std::string("Unit Key Used");
129     case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED:
130       return std::string("Pairing with Unit Key Unsupported");
131     case HCI_ERR_DIFF_TRANSACTION_COLLISION:
132       return std::string("Diff Transaction Collision");
133     case HCI_ERR_INSUFFCIENT_SECURITY:
134       return std::string("Insufficient Security");
135     case HCI_ERR_ROLE_SWITCH_PENDING:
136       return std::string("Role Switch Pending");
137     case HCI_ERR_HOST_BUSY_PAIRING:
138       return std::string("Host Busy Pairing");
139     case HCI_ERR_UNACCEPT_CONN_INTERVAL:
140       return std::string("Unacceptable Connection Interval");
141     case HCI_ERR_ADVERTISING_TIMEOUT:
142       return std::string("Advertising Timeout");
143     case HCI_ERR_CONN_FAILED_ESTABLISHMENT:
144       return std::string("Connection Failed Establishment");
145     case HCI_ERR_LIMIT_REACHED:
146       return std::string("Limit Reached");
147     default:
148       return base::StringPrintf("Unknown Error[%02hx]", error_code);
149   }
150 }
151 
152 // Context equivalence
153 using tHCI_STATUS = tHCI_ERROR_CODE;
hci_status_code_text(const tHCI_STATUS & status_code)154 inline std::string hci_status_code_text(const tHCI_STATUS& status_code) {
155   return hci_error_code_text(status_code);
156 }
157 
158 using tHCI_REASON = tHCI_ERROR_CODE;
hci_reason_code_text(const tHCI_REASON & reason_code)159 inline std::string hci_reason_code_text(const tHCI_REASON& reason_code) {
160   return hci_error_code_text(reason_code);
161 }
162 
163 // Conversion from raw packet value
to_hci_error_code(const uint8_t & error_code)164 inline tHCI_ERROR_CODE to_hci_error_code(const uint8_t& error_code) {
165   if (error_code > _HCI_ERR_MAX_ERR) return HCI_ERR_UNDEFINED;
166   return static_cast<tHCI_ERROR_CODE>(error_code);
167 }
168 
to_hci_status_code(const uint8_t & status_code)169 inline tHCI_STATUS to_hci_status_code(const uint8_t& status_code) {
170   if (status_code > _HCI_ERR_MAX_ERR) return HCI_ERR_UNDEFINED;
171   return static_cast<tHCI_STATUS>(status_code);
172 }
173 
to_hci_reason_code(const uint8_t & reason_code)174 inline tHCI_REASON to_hci_reason_code(const uint8_t& reason_code) {
175   if (reason_code > _HCI_ERR_MAX_ERR) return HCI_ERR_UNDEFINED;
176   return static_cast<tHCI_REASON>(reason_code);
177 }
178