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