1 /* 2 * Copyright (C) 2006 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 package com.android.internal.telephony.dataconnection; 17 18 import android.content.Context; 19 import android.content.res.Resources; 20 import android.os.PersistableBundle; 21 import android.telephony.CarrierConfigManager; 22 23 import java.util.HashMap; 24 import java.util.HashSet; 25 26 /** 27 * Returned as the reason for a connection failure as defined 28 * by RIL_DataCallFailCause in ril.h and some local errors. 29 */ 30 public enum DcFailCause { 31 NONE(0), 32 33 // This series of errors as specified by the standards 34 // specified in ril.h 35 OPERATOR_BARRED(0x08), /* no retry */ 36 NAS_SIGNALLING(0x0E), 37 LLC_SNDCP(0x19), 38 INSUFFICIENT_RESOURCES(0x1A), 39 MISSING_UNKNOWN_APN(0x1B), /* no retry */ 40 UNKNOWN_PDP_ADDRESS_TYPE(0x1C), /* no retry */ 41 USER_AUTHENTICATION(0x1D), /* no retry */ 42 ACTIVATION_REJECT_GGSN(0x1E), /* no retry */ 43 ACTIVATION_REJECT_UNSPECIFIED(0x1F), 44 SERVICE_OPTION_NOT_SUPPORTED(0x20), /* no retry */ 45 SERVICE_OPTION_NOT_SUBSCRIBED(0x21), /* no retry */ 46 SERVICE_OPTION_OUT_OF_ORDER(0x22), 47 NSAPI_IN_USE(0x23), /* no retry */ 48 REGULAR_DEACTIVATION(0x24), /* possibly restart radio, based on config */ 49 QOS_NOT_ACCEPTED(0x25), 50 NETWORK_FAILURE(0x26), 51 UMTS_REACTIVATION_REQ(0x27), 52 FEATURE_NOT_SUPP(0x28), 53 TFT_SEMANTIC_ERROR(0x29), 54 TFT_SYTAX_ERROR(0x2A), 55 UNKNOWN_PDP_CONTEXT(0x2B), 56 FILTER_SEMANTIC_ERROR(0x2C), 57 FILTER_SYTAX_ERROR(0x2D), 58 PDP_WITHOUT_ACTIVE_TFT(0x2E), 59 ONLY_IPV4_ALLOWED(0x32), /* no retry */ 60 ONLY_IPV6_ALLOWED(0x33), /* no retry */ 61 ONLY_SINGLE_BEARER_ALLOWED(0x34), 62 ESM_INFO_NOT_RECEIVED(0x35), 63 PDN_CONN_DOES_NOT_EXIST(0x36), 64 MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED(0x37), 65 MAX_ACTIVE_PDP_CONTEXT_REACHED(0x41), 66 UNSUPPORTED_APN_IN_CURRENT_PLMN(0x42), 67 INVALID_TRANSACTION_ID(0x51), 68 MESSAGE_INCORRECT_SEMANTIC(0x5F), 69 INVALID_MANDATORY_INFO(0x60), 70 MESSAGE_TYPE_UNSUPPORTED(0x61), 71 MSG_TYPE_NONCOMPATIBLE_STATE(0x62), 72 UNKNOWN_INFO_ELEMENT(0x63), 73 CONDITIONAL_IE_ERROR(0x64), 74 MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE(0x65), 75 PROTOCOL_ERRORS(0x6F), /* no retry */ 76 APN_TYPE_CONFLICT(0x70), 77 INVALID_PCSCF_ADDR(0x71), 78 INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN(0x72), 79 EMM_ACCESS_BARRED(0x73), 80 EMERGENCY_IFACE_ONLY(0x74), 81 IFACE_MISMATCH(0x75), 82 COMPANION_IFACE_IN_USE(0x76), 83 IP_ADDRESS_MISMATCH(0x77), 84 IFACE_AND_POL_FAMILY_MISMATCH(0x78), 85 EMM_ACCESS_BARRED_INFINITE_RETRY(0x79), 86 AUTH_FAILURE_ON_EMERGENCY_CALL(0x7A), 87 88 // OEM sepecific error codes. To be used by OEMs when they don't 89 // want to reveal error code which would be replaced by ERROR_UNSPECIFIED 90 OEM_DCFAILCAUSE_1(0x1001), 91 OEM_DCFAILCAUSE_2(0x1002), 92 OEM_DCFAILCAUSE_3(0x1003), 93 OEM_DCFAILCAUSE_4(0x1004), 94 OEM_DCFAILCAUSE_5(0x1005), 95 OEM_DCFAILCAUSE_6(0x1006), 96 OEM_DCFAILCAUSE_7(0x1007), 97 OEM_DCFAILCAUSE_8(0x1008), 98 OEM_DCFAILCAUSE_9(0x1009), 99 OEM_DCFAILCAUSE_10(0x100A), 100 OEM_DCFAILCAUSE_11(0x100B), 101 OEM_DCFAILCAUSE_12(0x100C), 102 OEM_DCFAILCAUSE_13(0x100D), 103 OEM_DCFAILCAUSE_14(0x100E), 104 OEM_DCFAILCAUSE_15(0x100F), 105 106 // Local errors generated by Vendor RIL 107 // specified in ril.h 108 REGISTRATION_FAIL(-1), 109 GPRS_REGISTRATION_FAIL(-2), 110 SIGNAL_LOST(-3), /* no retry */ 111 PREF_RADIO_TECH_CHANGED(-4), 112 RADIO_POWER_OFF(-5), /* no retry */ 113 TETHERED_CALL_ACTIVE(-6), /* no retry */ 114 ERROR_UNSPECIFIED(0xFFFF), 115 116 // Errors generated by the Framework 117 // specified here 118 UNKNOWN(0x10000), 119 RADIO_NOT_AVAILABLE(0x10001), /* no retry */ 120 UNACCEPTABLE_NETWORK_PARAMETER(0x10002), /* no retry */ 121 CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003), 122 LOST_CONNECTION(0x10004), 123 RESET_BY_FRAMEWORK(0x10005); 124 125 private final int mErrorCode; 126 private static final HashMap<Integer, DcFailCause> sErrorCodeToFailCauseMap; 127 static { 128 sErrorCodeToFailCauseMap = new HashMap<Integer, DcFailCause>(); 129 for (DcFailCause fc : values()) { fc.getErrorCode()130 sErrorCodeToFailCauseMap.put(fc.getErrorCode(), fc); 131 } 132 } 133 134 /** 135 * Map of subId -> set of data call setup permanent failure for the carrier. 136 */ 137 private static final HashMap<Integer, HashSet<DcFailCause>> sPermanentFailureCache = 138 new HashMap<>(); 139 DcFailCause(int errorCode)140 DcFailCause(int errorCode) { 141 mErrorCode = errorCode; 142 } 143 getErrorCode()144 public int getErrorCode() { 145 return mErrorCode; 146 } 147 148 /** 149 * Returns whether or not the radio has failed and also needs to be restarted. 150 * By default, we do not restart radio on REGULAR_DEACTIVATION. 151 * 152 * @param context device context 153 * @param subId subscription id 154 * @return true if the radio has failed and the carrier requres restart, otherwise false 155 */ isRestartRadioFail(Context context, int subId)156 public boolean isRestartRadioFail(Context context, int subId) { 157 if (this == REGULAR_DEACTIVATION) { 158 CarrierConfigManager configManager = (CarrierConfigManager) 159 context.getSystemService(Context.CARRIER_CONFIG_SERVICE); 160 if (configManager != null) { 161 PersistableBundle b = configManager.getConfigForSubId(subId); 162 if (b != null) { 163 return b.getBoolean(CarrierConfigManager. 164 KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL); 165 } 166 } 167 } 168 return false; 169 } 170 isPermanentFailure(Context context, int subId)171 public boolean isPermanentFailure(Context context, int subId) { 172 173 synchronized (sPermanentFailureCache) { 174 175 HashSet<DcFailCause> permanentFailureSet = sPermanentFailureCache.get(subId); 176 177 // In case of cache miss, we need to look up the settings from carrier config. 178 if (permanentFailureSet == null) { 179 // Retrieve the permanent failure from carrier config 180 CarrierConfigManager configManager = (CarrierConfigManager) 181 context.getSystemService(Context.CARRIER_CONFIG_SERVICE); 182 if (configManager != null) { 183 PersistableBundle b = configManager.getConfigForSubId(subId); 184 if (b != null) { 185 String[] permanentFailureStrings = b.getStringArray(CarrierConfigManager. 186 KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS); 187 188 if (permanentFailureStrings != null) { 189 permanentFailureSet = new HashSet<>(); 190 for (String failure : permanentFailureStrings) { 191 permanentFailureSet.add(DcFailCause.valueOf(failure)); 192 } 193 } 194 } 195 } 196 197 // If we are not able to find the configuration from carrier config, use the default 198 // ones. 199 if (permanentFailureSet == null) { 200 permanentFailureSet = new HashSet<DcFailCause>() { 201 { 202 add(OPERATOR_BARRED); 203 add(MISSING_UNKNOWN_APN); 204 add(UNKNOWN_PDP_ADDRESS_TYPE); 205 add(USER_AUTHENTICATION); 206 add(ACTIVATION_REJECT_GGSN); 207 add(SERVICE_OPTION_NOT_SUPPORTED); 208 add(SERVICE_OPTION_NOT_SUBSCRIBED); 209 add(NSAPI_IN_USE); 210 add(ONLY_IPV4_ALLOWED); 211 add(ONLY_IPV6_ALLOWED); 212 add(PROTOCOL_ERRORS); 213 add(RADIO_POWER_OFF); 214 add(TETHERED_CALL_ACTIVE); 215 add(RADIO_NOT_AVAILABLE); 216 add(UNACCEPTABLE_NETWORK_PARAMETER); 217 add(SIGNAL_LOST); 218 } 219 }; 220 } 221 222 sPermanentFailureCache.put(subId, permanentFailureSet); 223 } 224 225 return permanentFailureSet.contains(this); 226 } 227 } 228 isEventLoggable()229 public boolean isEventLoggable() { 230 return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) || 231 (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) || 232 (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) || 233 (this == SERVICE_OPTION_NOT_SUBSCRIBED) || 234 (this == SERVICE_OPTION_NOT_SUPPORTED) || 235 (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) || 236 (this == ONLY_IPV4_ALLOWED) || (this == ONLY_IPV6_ALLOWED) || 237 (this == PROTOCOL_ERRORS) || (this == SIGNAL_LOST) || 238 (this == RADIO_POWER_OFF) || (this == TETHERED_CALL_ACTIVE) || 239 (this == UNACCEPTABLE_NETWORK_PARAMETER); 240 } 241 fromInt(int errorCode)242 public static DcFailCause fromInt(int errorCode) { 243 DcFailCause fc = sErrorCodeToFailCauseMap.get(errorCode); 244 if (fc == null) { 245 fc = UNKNOWN; 246 } 247 return fc; 248 } 249 } 250