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 package com.google.android.iwlan; 18 19 import android.net.ipsec.ike.exceptions.IkeException; 20 import android.net.ipsec.ike.exceptions.IkeIOException; 21 import android.net.ipsec.ike.exceptions.IkeInternalException; 22 import android.net.ipsec.ike.exceptions.IkeProtocolException; 23 import android.support.annotation.IntDef; 24 import android.support.annotation.NonNull; 25 26 import java.io.IOException; 27 import java.util.Map; 28 import java.util.concurrent.ConcurrentHashMap; 29 30 public class IwlanError { 31 32 // error types 33 public static final int NO_ERROR = 0; 34 35 // IKE lib related 36 public static final int IKE_PROTOCOL_EXCEPTION = 1; 37 public static final int IKE_INTERNAL_IO_EXCEPTION = 2; 38 public static final int IKE_GENERIC_EXCEPTION = 3; // catch all 39 40 // Known internal types 41 public static final int EPDG_SELECTOR_SERVER_SELECTION_FAILED = 4; 42 public static final int TUNNEL_TRANSFORM_FAILED = 5; 43 public static final int SIM_NOT_READY_EXCEPTION = 6; 44 public static final int NETWORK_FAILURE = 7; 45 46 // Catch all exception 47 public static final int UNKNOWN_EXCEPTION = 8; // catch all 48 49 @IntDef({ 50 NO_ERROR, 51 IKE_PROTOCOL_EXCEPTION, 52 IKE_INTERNAL_IO_EXCEPTION, 53 IKE_GENERIC_EXCEPTION, 54 EPDG_SELECTOR_SERVER_SELECTION_FAILED, 55 TUNNEL_TRANSFORM_FAILED, 56 SIM_NOT_READY_EXCEPTION, 57 NETWORK_FAILURE, 58 UNKNOWN_EXCEPTION 59 }) 60 @interface IwlanErrorType {}; 61 62 private static final Map<Integer, String> sErrorTypeStrings = 63 new ConcurrentHashMap<>() { 64 { 65 put(NO_ERROR, "IWLAN_NO_ERROR"); 66 put(IKE_PROTOCOL_EXCEPTION, "IWLAN_IKE_PROTOCOL_EXCEPTION"); 67 put(IKE_INTERNAL_IO_EXCEPTION, "IWLAN_IKE_INTERNAL_IO_EXCEPTION"); 68 put(IKE_GENERIC_EXCEPTION, "IWLAN_IKE_GENERIC_EXCEPTION"); 69 put( 70 EPDG_SELECTOR_SERVER_SELECTION_FAILED, 71 "IWLAN_EPDG_SELECTOR_SERVER_SELECTION_FAILED"); 72 put(TUNNEL_TRANSFORM_FAILED, "IWLAN_TUNNEL_TRANSFORM_FAILED"); 73 put(SIM_NOT_READY_EXCEPTION, "IWLAN_SIM_NOT_READY_EXCEPTION"); 74 put(NETWORK_FAILURE, "IWLAN_NETWORK_FAILURE"); 75 put(UNKNOWN_EXCEPTION, "IWLAN_UNKNOWN_EXCEPTION"); 76 } 77 }; 78 79 private int mErrorType; 80 private Exception mException; 81 IwlanError(@wlanErrorType int err)82 public IwlanError(@IwlanErrorType int err) { 83 mErrorType = err; 84 } 85 86 /** 87 * Sets the IwlanError based on the Exception: 1. IkeException is base the class for all IKE 88 * exception ErrorType: IKE_GENERIC_EXCEPTION. 2. IkeProtocolException is for specific protocol 89 * errors (like IKE notify error codes) ErrorType: IKE_PROTOCOL_EXCEPTION 3. 90 * IkeInternalException is just a wrapper for various exeptions that IKE lib may encounter 91 * ErrorType: IKE_INTERNAL_IO_EXCEPTION if the Exception is instance of IOException ErrorType: 92 * IKE_GENERIC_EXCEPTION for all the other. 93 */ IwlanError(@onNull Exception exception)94 public IwlanError(@NonNull Exception exception) { 95 // resolve into specific types if possible 96 if (exception instanceof IkeProtocolException) { 97 IwlanErrorIkeProtocolException((IkeProtocolException) exception); 98 } else if (exception instanceof IkeIOException) { 99 IwlanErrorIkeIOException((IkeIOException) exception); 100 } else if (exception instanceof IkeInternalException) { 101 IwlanErrorIkeInternalException((IkeInternalException) exception); 102 } else if (exception instanceof IkeException) { 103 mErrorType = IKE_GENERIC_EXCEPTION; 104 mException = exception; 105 } else { 106 mErrorType = UNKNOWN_EXCEPTION; 107 mException = exception; 108 } 109 } 110 IwlanErrorIkeProtocolException(@onNull IkeProtocolException exception)111 private void IwlanErrorIkeProtocolException(@NonNull IkeProtocolException exception) { 112 mErrorType = IKE_PROTOCOL_EXCEPTION; 113 mException = exception; 114 } 115 IwlanErrorIkeInternalException(@onNull IkeInternalException exception)116 private void IwlanErrorIkeInternalException(@NonNull IkeInternalException exception) { 117 if (exception.getCause() instanceof IOException) { 118 mErrorType = IKE_INTERNAL_IO_EXCEPTION; 119 } else { 120 mErrorType = IKE_GENERIC_EXCEPTION; 121 } 122 mException = exception; 123 } 124 IwlanErrorIkeIOException(@onNull IkeIOException exception)125 private void IwlanErrorIkeIOException(@NonNull IkeIOException exception) { 126 mErrorType = IKE_INTERNAL_IO_EXCEPTION; 127 mException = exception; 128 } 129 getErrorType()130 public @IwlanErrorType int getErrorType() { 131 return mErrorType; 132 } 133 getException()134 public Exception getException() { 135 return mException; 136 } 137 getErrorTypeString(@wlanErrorType int error)138 private static @NonNull String getErrorTypeString(@IwlanErrorType int error) { 139 String s = sErrorTypeStrings.get(error); 140 return (s == null ? "IWLAN_UNKNOWN_ERROR_TYPE" : s); 141 } 142 143 @Override toString()144 public String toString() { 145 return ("TYPE: " + getErrorTypeString(mErrorType) + " " + errorDetailsString()); 146 } 147 errorDetailsString()148 private String errorDetailsString() { 149 StringBuilder sb = new StringBuilder(); 150 151 if (mException == null) { 152 return ""; 153 } 154 155 switch (mErrorType) { 156 case IKE_GENERIC_EXCEPTION: 157 sb.append("MSG: " + mException.getMessage() + "\n CAUSE: "); 158 sb.append(mException.getCause()); 159 break; 160 case UNKNOWN_EXCEPTION: 161 sb.append(mException.toString()); 162 break; 163 case IKE_PROTOCOL_EXCEPTION: 164 sb.append("ERR: " + ((IkeProtocolException) mException).getErrorType() + "\nDATA:"); 165 for (byte b : ((IkeProtocolException) mException).getErrorData()) { 166 sb.append(String.format("%02x ", b)); 167 } 168 break; 169 default: 170 sb.append("-No Details-"); 171 } 172 return sb.toString(); 173 } 174 175 /** 176 * Returns the error of the String. String that matches the name of the Error 177 * 178 * @param errorType string form of errorType 179 * @return IwlanErrorType 180 */ getErrorType(String errorType)181 public static int getErrorType(String errorType) { 182 int ret = IwlanError.UNKNOWN_EXCEPTION; 183 184 // TODO: Add representation for Global error 185 switch (errorType) { 186 case "IKE_PROTOCOL_EXCEPTION": 187 ret = IwlanError.IKE_PROTOCOL_EXCEPTION; 188 break; 189 case "IKE_INTERNAL_IO_EXCEPTION": 190 ret = IwlanError.IKE_INTERNAL_IO_EXCEPTION; 191 break; 192 case "IKE_GENERIC_EXCEPTION": 193 ret = IwlanError.IKE_GENERIC_EXCEPTION; 194 break; 195 case "EPDG_SELECTOR_SERVER_SELECTION_FAILED": 196 ret = IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED; 197 break; 198 case "TUNNEL_TRANSFORM_FAILED": 199 ret = IwlanError.TUNNEL_TRANSFORM_FAILED; 200 break; 201 case "SIM_NOT_READY_EXCEPTION": 202 ret = IwlanError.SIM_NOT_READY_EXCEPTION; 203 break; 204 case "NETWORK_FAILURE": 205 ret = IwlanError.NETWORK_FAILURE; 206 break; 207 } 208 return ret; 209 } 210 211 @Override equals(Object o)212 public boolean equals(Object o) { 213 if (!(o instanceof IwlanError)) { 214 return false; 215 } 216 IwlanError error = (IwlanError) o; 217 boolean ret = false; 218 if (mErrorType == error.getErrorType()) { 219 if (mException != null && error.getException() != null) { 220 ret = mException.getClass().equals(error.getException().getClass()); 221 if (ret && mException instanceof IkeProtocolException) { 222 ret = 223 (((IkeProtocolException) mException).getErrorType() 224 == ((IkeProtocolException) error.getException()) 225 .getErrorType()); 226 } 227 } else if (mException == null && error.getException() == null) { 228 ret = true; 229 } 230 } 231 return ret; 232 } 233 } 234 ; 235