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