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.IkeIOException; 20 import android.net.ipsec.ike.exceptions.IkeInternalException; 21 import android.net.ipsec.ike.exceptions.IkeNetworkLostException; 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 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 public static final int SIM_NOT_READY_EXCEPTION = 6; 43 public static final int IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED = 7; 44 public static final int IKE_NETWORK_LOST_EXCEPTION = 8; 45 public static final int TUNNEL_NOT_FOUND = 9; 46 public static final int EPDG_ADDRESS_ONLY_IPV4_ALLOWED = 10; 47 public static final int EPDG_ADDRESS_ONLY_IPV6_ALLOWED = 11; 48 public static final int IKE_INIT_TIMEOUT = 12; 49 public static final int IKE_MOBILITY_TIMEOUT = 13; 50 public static final int IKE_DPD_TIMEOUT = 14; 51 52 @IntDef({ 53 NO_ERROR, 54 IKE_PROTOCOL_EXCEPTION, 55 IKE_INTERNAL_IO_EXCEPTION, 56 IKE_GENERIC_EXCEPTION, 57 EPDG_SELECTOR_SERVER_SELECTION_FAILED, 58 TUNNEL_TRANSFORM_FAILED, 59 SIM_NOT_READY_EXCEPTION, 60 IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED, 61 IKE_NETWORK_LOST_EXCEPTION, 62 TUNNEL_NOT_FOUND, 63 EPDG_ADDRESS_ONLY_IPV4_ALLOWED, 64 EPDG_ADDRESS_ONLY_IPV6_ALLOWED, 65 IKE_INIT_TIMEOUT, 66 IKE_MOBILITY_TIMEOUT, 67 IKE_DPD_TIMEOUT 68 }) 69 @interface IwlanErrorType {} 70 71 private static final Map<Integer, String> sErrorTypeStrings = 72 Map.ofEntries( 73 Map.entry(NO_ERROR, "IWLAN_NO_ERROR"), 74 Map.entry(IKE_PROTOCOL_EXCEPTION, "IWLAN_IKE_PROTOCOL_EXCEPTION"), 75 Map.entry(IKE_INTERNAL_IO_EXCEPTION, "IWLAN_IKE_INTERNAL_IO_EXCEPTION"), 76 Map.entry(IKE_GENERIC_EXCEPTION, "IWLAN_IKE_GENERIC_EXCEPTION"), 77 Map.entry( 78 EPDG_SELECTOR_SERVER_SELECTION_FAILED, 79 "IWLAN_EPDG_SELECTOR_SERVER_SELECTION_FAILED"), 80 Map.entry(TUNNEL_TRANSFORM_FAILED, "IWLAN_TUNNEL_TRANSFORM_FAILED"), 81 Map.entry(SIM_NOT_READY_EXCEPTION, "IWLAN_SIM_NOT_READY_EXCEPTION"), 82 Map.entry( 83 IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED, 84 "IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED"), 85 Map.entry(IKE_NETWORK_LOST_EXCEPTION, "IWLAN_IKE_NETWORK_LOST_EXCEPTION"), 86 Map.entry(TUNNEL_NOT_FOUND, "IWLAN_TUNNEL_NOT_FOUND"), 87 Map.entry(IKE_INIT_TIMEOUT, "IKE_INIT_TIMEOUT"), 88 Map.entry(IKE_MOBILITY_TIMEOUT, "IKE_MOBILITY_TIMEOUT"), 89 Map.entry(IKE_DPD_TIMEOUT, "IKE_DPD_TIMEOUT"), 90 Map.entry(EPDG_ADDRESS_ONLY_IPV4_ALLOWED, "EPDG_ADDRESS_ONLY_IPV4_ALLOWED"), 91 Map.entry(EPDG_ADDRESS_ONLY_IPV6_ALLOWED, "EPDG_ADDRESS_ONLY_IPV6_ALLOWED")); 92 private int mErrorType; 93 private Exception mException; 94 IwlanError(@wlanErrorType int err)95 public IwlanError(@IwlanErrorType int err) { 96 mErrorType = err; 97 } 98 IwlanError(@wlanErrorType int err, @NonNull Exception exception)99 public IwlanError(@IwlanErrorType int err, @NonNull Exception exception) { 100 mErrorType = err; 101 mException = exception; 102 } 103 104 /** 105 * Sets the IwlanError based on the Exception: 1. IkeException is base the class for all IKE 106 * exception ErrorType: IKE_GENERIC_EXCEPTION. 2. IkeProtocolException is for specific protocol 107 * errors (like IKE notify error codes) ErrorType: IKE_PROTOCOL_EXCEPTION 3. 108 * IkeInternalException is just a wrapper for various exceptions that IKE lib may encounter 109 * ErrorType: IKE_INTERNAL_IO_EXCEPTION if the Exception is instance of IOException ErrorType: 110 * IKE_GENERIC_EXCEPTION for all the other. 111 */ IwlanError(@onNull Exception exception)112 public IwlanError(@NonNull Exception exception) { 113 // resolve into specific types if possible 114 if (exception instanceof IkeProtocolException) { 115 IwlanErrorIkeProtocolException((IkeProtocolException) exception); 116 } else if (exception instanceof IkeIOException) { 117 IwlanErrorIkeIOException((IkeIOException) exception); 118 } else if (exception instanceof IkeInternalException) { 119 IwlanErrorIkeInternalException((IkeInternalException) exception); 120 } else if (exception instanceof IkeNetworkLostException) { 121 IwlanErrorIkeNetworkLostException((IkeNetworkLostException) exception); 122 } else { 123 mErrorType = IKE_GENERIC_EXCEPTION; 124 mException = exception; 125 } 126 } 127 IwlanErrorIkeProtocolException(@onNull IkeProtocolException exception)128 private void IwlanErrorIkeProtocolException(@NonNull IkeProtocolException exception) { 129 mErrorType = IKE_PROTOCOL_EXCEPTION; 130 mException = exception; 131 } 132 IwlanErrorIkeInternalException(@onNull IkeInternalException exception)133 private void IwlanErrorIkeInternalException(@NonNull IkeInternalException exception) { 134 if (exception.getCause() instanceof IOException) { 135 mErrorType = IKE_INTERNAL_IO_EXCEPTION; 136 } else { 137 mErrorType = IKE_GENERIC_EXCEPTION; 138 } 139 mException = exception; 140 } 141 IwlanErrorIkeIOException(@onNull IkeIOException exception)142 private void IwlanErrorIkeIOException(@NonNull IkeIOException exception) { 143 mErrorType = IKE_INTERNAL_IO_EXCEPTION; 144 mException = exception; 145 } 146 IwlanErrorIkeNetworkLostException(@onNull IkeNetworkLostException exception)147 private void IwlanErrorIkeNetworkLostException(@NonNull IkeNetworkLostException exception) { 148 mErrorType = IKE_NETWORK_LOST_EXCEPTION; 149 mException = exception; 150 } 151 getErrorType()152 public @IwlanErrorType int getErrorType() { 153 return mErrorType; 154 } 155 getException()156 public Exception getException() { 157 return mException; 158 } 159 getErrorTypeString(@wlanErrorType int error)160 private static @NonNull String getErrorTypeString(@IwlanErrorType int error) { 161 String s = sErrorTypeStrings.get(error); 162 return (s == null ? "IWLAN_UNKNOWN_ERROR_TYPE" : s); 163 } 164 165 @Override toString()166 public String toString() { 167 return ("TYPE: " + getErrorTypeString(mErrorType) + " " + errorDetailsString()); 168 } 169 errorDetailsString()170 private String errorDetailsString() { 171 StringBuilder sb = new StringBuilder(); 172 173 if (mException == null) { 174 return ""; 175 } 176 177 switch (mErrorType) { 178 case IKE_GENERIC_EXCEPTION: 179 sb.append("MSG: ").append(mException.getMessage()).append("\n CAUSE: "); 180 sb.append(mException.getCause()); 181 break; 182 case IKE_PROTOCOL_EXCEPTION: 183 sb.append("ERR: ") 184 .append(((IkeProtocolException) mException).getErrorType()) 185 .append("\nDATA:"); 186 for (byte b : ((IkeProtocolException) mException).getErrorData()) { 187 sb.append(String.format("%02x ", b)); 188 } 189 break; 190 case IKE_NETWORK_LOST_EXCEPTION: 191 sb.append("ERR: ") 192 .append(mException.getMessage()) 193 .append("\n CAUSE: ") 194 .append(mException.getCause()) 195 .append("\n NETWORK: ") 196 .append(((IkeNetworkLostException) mException).getNetwork()); 197 break; 198 default: 199 sb.append("-No Details-"); 200 } 201 return sb.toString(); 202 } 203 204 @Override equals(Object o)205 public boolean equals(Object o) { 206 if (!(o instanceof IwlanError error)) { 207 return false; 208 } 209 boolean ret = false; 210 if (mErrorType == error.getErrorType()) { 211 if (mException != null && error.getException() != null) { 212 ret = mException.getClass().equals(error.getException().getClass()); 213 if (ret && mException instanceof IkeProtocolException) { 214 ret = 215 (((IkeProtocolException) mException).getErrorType() 216 == ((IkeProtocolException) error.getException()) 217 .getErrorType()); 218 } 219 } else if (mException == null && error.getException() == null) { 220 ret = true; 221 } 222 } 223 return ret; 224 } 225 } 226