• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package android.bluetooth;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.RequiresNoPermission;
24 
25 import java.io.IOException;
26 import java.lang.annotation.Retention;
27 
28 /**
29  * Thrown when an error occurs during a Bluetooth Socket related exception.
30  *
31  * <p>This is currently intended to be thrown for a failure during {@link BluetoothSocket}
32  * operations.
33  */
34 public class BluetoothSocketException extends IOException {
35 
36     @Retention(SOURCE)
37     @IntDef({
38         UNSPECIFIED,
39         L2CAP_UNKNOWN,
40         L2CAP_ACL_FAILURE,
41         L2CAP_CLIENT_SECURITY_FAILURE,
42         L2CAP_INSUFFICIENT_AUTHENTICATION,
43         L2CAP_INSUFFICIENT_AUTHORIZATION,
44         L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE,
45         L2CAP_INSUFFICIENT_ENCRYPTION,
46         L2CAP_INVALID_SOURCE_CID,
47         L2CAP_SOURCE_CID_ALREADY_ALLOCATED,
48         L2CAP_UNACCEPTABLE_PARAMETERS,
49         L2CAP_INVALID_PARAMETERS,
50         L2CAP_NO_RESOURCES,
51         L2CAP_NO_PSM_AVAILABLE,
52         L2CAP_TIMEOUT,
53         BLUETOOTH_OFF_FAILURE,
54         SOCKET_MANAGER_FAILURE,
55         SOCKET_CLOSED,
56         SOCKET_CONNECTION_FAILURE,
57         NULL_DEVICE,
58         RPC_FAILURE,
59         UNIX_FILE_SOCKET_CREATION_FAILURE,
60     })
61     private @interface ErrorCode {}
62 
63     /**
64      * Error code representing a failure during {@link BluetoothSocket}. The reason for failure
65      * isn't specified.
66      */
67     public static final int UNSPECIFIED = 0;
68 
69     /**
70      * Error code returned by {@link BluetoothSocket} during a L2CAP-related socket operation that
71      * failed for an unknown reason.
72      */
73     public static final int L2CAP_UNKNOWN = 1;
74 
75     /** Error code during connect when there is an ACL connection failure. */
76     public static final int L2CAP_ACL_FAILURE = 2;
77 
78     /**
79      * Error code during connect when security clearance fails on the client during L2CAP
80      * connection.
81      */
82     public static final int L2CAP_CLIENT_SECURITY_FAILURE = 3;
83 
84     /**
85      * Error code during connect when authentication fails on the peer device during L2CAP
86      * connection.
87      */
88     public static final int L2CAP_INSUFFICIENT_AUTHENTICATION = 4;
89 
90     /**
91      * Error code during connect when authorization fails on the peer device during L2CAP
92      * connection.
93      */
94     public static final int L2CAP_INSUFFICIENT_AUTHORIZATION = 5;
95 
96     /**
97      * Error code during connect indicating insufficient encryption key size on the peer device
98      * during L2CAP connection.
99      */
100     public static final int L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE = 6;
101 
102     /**
103      * Error code during connect for insufficient encryption from the peer device during L2CAP
104      * connection.
105      */
106     public static final int L2CAP_INSUFFICIENT_ENCRYPTION = 7;
107 
108     /**
109      * Error code during connect for invalid Channel ID from the peer device during L2CAP
110      * connection.
111      */
112     public static final int L2CAP_INVALID_SOURCE_CID = 8;
113 
114     /**
115      * Error code during connect for already allocated Channel ID from the peer device during L2CAP
116      * connection.
117      */
118     public static final int L2CAP_SOURCE_CID_ALREADY_ALLOCATED = 9;
119 
120     /**
121      * Error code during connect for unacceptable Parameters from the peer device during L2CAP
122      * connection.
123      */
124     public static final int L2CAP_UNACCEPTABLE_PARAMETERS = 10;
125 
126     /**
127      * Error code during connect for invalid parameters from the peer device during L2CAP
128      * connection.
129      */
130     public static final int L2CAP_INVALID_PARAMETERS = 11;
131 
132     /** Error code during connect when no resources are available for L2CAP connection. */
133     public static final int L2CAP_NO_RESOURCES = 12;
134 
135     /** Error code during connect when no PSM is available for L2CAP connection. */
136     public static final int L2CAP_NO_PSM_AVAILABLE = 13;
137 
138     /** Error code during connect when L2CAP connection timeout. */
139     public static final int L2CAP_TIMEOUT = 14;
140 
141     /**
142      * Error code returned by {@link BluetoothSocket} during a socket operation that failed because
143      * Bluetooth is turned off.
144      */
145     public static final int BLUETOOTH_OFF_FAILURE = 15;
146 
147     /**
148      * Error code returned by {@link BluetoothSocket} during a socket operation that failed because
149      * socket manager is not available.
150      */
151     public static final int SOCKET_MANAGER_FAILURE = 16;
152 
153     /**
154      * Error code returned by {@link BluetoothSocket} during a socket operation that failed because
155      * the socket has been closed.
156      */
157     public static final int SOCKET_CLOSED = 17;
158 
159     /** Error code during connect for generic socket connection failures. */
160     public static final int SOCKET_CONNECTION_FAILURE = 18;
161 
162     /** Error code during connect when null device attempts to do socket connection. */
163     public static final int NULL_DEVICE = 19;
164 
165     /** Error code during connect when a Runtime RPC exception occurs. */
166     public static final int RPC_FAILURE = 20;
167 
168     /** Error code during connect when the UNIX socket connection creation fails. */
169     public static final int UNIX_FILE_SOCKET_CREATION_FAILURE = 21;
170 
171     /* Corresponding messages for respective error codes. */
172     private static final String UNSPECIFIED_MSG = "A Bluetooth Socket failure occurred";
173     private static final String L2CAP_UNKNOWN_MSG = "Connection failed for unknown reason";
174     private static final String L2CAP_ACL_FAILURE_MSG = "ACL connection failed";
175     private static final String L2CAP_CLIENT_SECURITY_FAILURE_MSG =
176             "Client security clearance failed";
177     private static final String L2CAP_INSUFFICIENT_AUTHENTICATION_MSG =
178             "Insufficient authentication";
179     private static final String L2CAP_INSUFFICIENT_AUTHORIZATION_MSG = "Insufficient authorization";
180     private static final String L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE_MSG =
181             "Insufficient encryption key size";
182     private static final String L2CAP_INSUFFICIENT_ENCRYPTION_MSG = "Insufficient encryption";
183     private static final String L2CAP_INVALID_SOURCE_CID_MSG = "Invalid source CID";
184     private static final String L2CAP_SOURCE_CID_ALREADY_ALLOCATED_MSG =
185             "Source CID already allocated";
186     private static final String L2CAP_UNACCEPTABLE_PARAMETERS_MSG = "Unacceptable Parameters";
187     private static final String L2CAP_INVALID_PARAMETERS_MSG = "Invalid Parameters";
188     private static final String L2CAP_NO_RESOURCES_MSG = "No resources Available";
189     private static final String L2CAP_NO_PSM_AVAILABLE_MSG = "No PSM available";
190     private static final String L2CAP_TIMEOUT_MSG = "Connection Timeout";
191     private static final String BLUETOOTH_OFF_FAILURE_MSG = "Bluetooth is off";
192     private static final String SOCKET_MANAGER_FAILURE_MSG = "bt get socket manager failed";
193     private static final String SOCKET_CLOSED_MSG = "socket closed";
194     private static final String SOCKET_CONNECTION_FAILURE_MSG = "bt socket connect failed";
195     private static final String NULL_DEVICE_MSG = "Connect is called on null device";
196     private static final String UNIX_FILE_SOCKET_CREATION_FAILURE_MSG =
197             "Null file descriptor returned";
198 
199     @ErrorCode private final int mErrorCode;
200 
201     /**
202      * Create a {@link BluetoothSocketException} with an error code and custom error message.
203      *
204      * @param code : error code representing the reason for failure.
205      * @param msg : Custom error message associated to the failure.
206      */
BluetoothSocketException(@rrorCode int code, @NonNull String msg)207     public BluetoothSocketException(@ErrorCode int code, @NonNull String msg) {
208         super(msg);
209         this.mErrorCode = code;
210     }
211 
212     /**
213      * Create a {@link BluetoothSocketException} with an error code. A generic error message is
214      * generated based on the {@code code} provided.
215      *
216      * @param code : error code representing the reason for failure.
217      */
BluetoothSocketException(@rrorCode int code)218     public BluetoothSocketException(@ErrorCode int code) {
219         this(code, getMessage(code));
220     }
221 
222     /** Returns the error code associated to this failure. */
223     @RequiresNoPermission
getErrorCode()224     public @ErrorCode int getErrorCode() {
225         return mErrorCode;
226     }
227 
getMessage(@rrorCode int code)228     private static String getMessage(@ErrorCode int code) {
229         switch (code) {
230             case BLUETOOTH_OFF_FAILURE:
231                 return BLUETOOTH_OFF_FAILURE_MSG;
232             case SOCKET_MANAGER_FAILURE:
233                 return SOCKET_MANAGER_FAILURE_MSG;
234             case SOCKET_CLOSED:
235                 return SOCKET_CLOSED_MSG;
236             case SOCKET_CONNECTION_FAILURE:
237                 return SOCKET_CONNECTION_FAILURE_MSG;
238             case NULL_DEVICE:
239                 return NULL_DEVICE_MSG;
240             case UNIX_FILE_SOCKET_CREATION_FAILURE:
241                 return UNIX_FILE_SOCKET_CREATION_FAILURE_MSG;
242             case L2CAP_ACL_FAILURE:
243                 return L2CAP_ACL_FAILURE_MSG;
244             case L2CAP_CLIENT_SECURITY_FAILURE:
245                 return L2CAP_CLIENT_SECURITY_FAILURE_MSG;
246             case L2CAP_INSUFFICIENT_AUTHENTICATION:
247                 return L2CAP_INSUFFICIENT_AUTHENTICATION_MSG;
248             case L2CAP_INSUFFICIENT_AUTHORIZATION:
249                 return L2CAP_INSUFFICIENT_AUTHORIZATION_MSG;
250             case L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE:
251                 return L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE_MSG;
252             case L2CAP_INSUFFICIENT_ENCRYPTION:
253                 return L2CAP_INSUFFICIENT_ENCRYPTION_MSG;
254             case L2CAP_INVALID_SOURCE_CID:
255                 return L2CAP_INVALID_SOURCE_CID_MSG;
256             case L2CAP_SOURCE_CID_ALREADY_ALLOCATED:
257                 return L2CAP_SOURCE_CID_ALREADY_ALLOCATED_MSG;
258             case L2CAP_UNACCEPTABLE_PARAMETERS:
259                 return L2CAP_UNACCEPTABLE_PARAMETERS_MSG;
260             case L2CAP_INVALID_PARAMETERS:
261                 return L2CAP_INVALID_PARAMETERS_MSG;
262             case L2CAP_NO_RESOURCES:
263                 return L2CAP_NO_RESOURCES_MSG;
264             case L2CAP_NO_PSM_AVAILABLE:
265                 return L2CAP_NO_PSM_AVAILABLE_MSG;
266             case L2CAP_TIMEOUT:
267                 return L2CAP_TIMEOUT_MSG;
268             case L2CAP_UNKNOWN:
269                 return L2CAP_UNKNOWN_MSG;
270             case UNSPECIFIED:
271             default:
272                 return UNSPECIFIED_MSG;
273         }
274     }
275 }
276