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