1 /* 2 * Copyright (C) 2022 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.telephony.ims.feature; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.util.SparseArray; 26 27 import com.android.internal.telephony.flags.Flags; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 32 /** 33 * Provides details on why transmitting IMS traffic failed. 34 * 35 * @hide 36 */ 37 @FlaggedApi(Flags.FLAG_SUPPORT_IMS_MMTEL_INTERFACE) 38 @SystemApi 39 public final class ConnectionFailureInfo implements Parcelable { 40 41 /** @hide */ 42 @Retention(RetentionPolicy.SOURCE) 43 @IntDef( 44 prefix = "REASON_", 45 value = { 46 REASON_NONE, 47 REASON_ACCESS_DENIED, 48 REASON_NAS_FAILURE, 49 REASON_RACH_FAILURE, 50 REASON_RLC_FAILURE, 51 REASON_RRC_REJECT, 52 REASON_RRC_TIMEOUT, 53 REASON_NO_SERVICE, 54 REASON_PDN_NOT_AVAILABLE, 55 REASON_RF_BUSY, 56 REASON_UNSPECIFIED 57 }) 58 public @interface FailureReason {} 59 60 /** Default value */ 61 public static final int REASON_NONE = 0; 62 /** Access class check failed */ 63 public static final int REASON_ACCESS_DENIED = 1; 64 /** 3GPP Non-access stratum failure */ 65 public static final int REASON_NAS_FAILURE = 2; 66 /** Random access failure */ 67 public static final int REASON_RACH_FAILURE = 3; 68 /** Radio link failure */ 69 public static final int REASON_RLC_FAILURE = 4; 70 /** Radio connection establishment rejected by network */ 71 public static final int REASON_RRC_REJECT = 5; 72 /** Radio connection establishment timed out */ 73 public static final int REASON_RRC_TIMEOUT = 6; 74 /** Device currently not in service */ 75 public static final int REASON_NO_SERVICE = 7; 76 /** The PDN is no longer active */ 77 public static final int REASON_PDN_NOT_AVAILABLE = 8; 78 /** Radio resource is busy with another subscription */ 79 public static final int REASON_RF_BUSY = 9; 80 /** Unspecified reason */ 81 public static final int REASON_UNSPECIFIED = 0xFFFF; 82 83 private static final SparseArray<String> sReasonMap; 84 static { 85 sReasonMap = new SparseArray<>(); sReasonMap.set(REASON_NONE, "NONE")86 sReasonMap.set(REASON_NONE, "NONE"); sReasonMap.set(REASON_ACCESS_DENIED, "ACCESS_DENIED")87 sReasonMap.set(REASON_ACCESS_DENIED, "ACCESS_DENIED"); sReasonMap.set(REASON_NAS_FAILURE, "NAS_FAILURE")88 sReasonMap.set(REASON_NAS_FAILURE, "NAS_FAILURE"); sReasonMap.set(REASON_RACH_FAILURE, "RACH_FAILURE")89 sReasonMap.set(REASON_RACH_FAILURE, "RACH_FAILURE"); sReasonMap.set(REASON_RLC_FAILURE, "RLC_FAILURE")90 sReasonMap.set(REASON_RLC_FAILURE, "RLC_FAILURE"); sReasonMap.set(REASON_RRC_REJECT, "RRC_REJECT")91 sReasonMap.set(REASON_RRC_REJECT, "RRC_REJECT"); sReasonMap.set(REASON_RRC_TIMEOUT, "RRC_TIMEOUT")92 sReasonMap.set(REASON_RRC_TIMEOUT, "RRC_TIMEOUT"); sReasonMap.set(REASON_NO_SERVICE, "NO_SERVICE")93 sReasonMap.set(REASON_NO_SERVICE, "NO_SERVICE"); sReasonMap.set(REASON_PDN_NOT_AVAILABLE, "PDN_NOT_AVAILABLE")94 sReasonMap.set(REASON_PDN_NOT_AVAILABLE, "PDN_NOT_AVAILABLE"); sReasonMap.set(REASON_RF_BUSY, "RF_BUSY")95 sReasonMap.set(REASON_RF_BUSY, "RF_BUSY"); sReasonMap.set(REASON_UNSPECIFIED, "UNSPECIFIED")96 sReasonMap.set(REASON_UNSPECIFIED, "UNSPECIFIED"); 97 } 98 99 /** The reason of failure */ 100 private final @FailureReason int mReason; 101 102 /** 103 * Failure cause code from network or modem specific to the failure 104 * 105 * Reference: 3GPP TS 24.401 Annex A (Cause values for EPS mobility management) 106 * Reference: 3GPP TS 24.501 Annex A (Cause values for 5GS mobility management) 107 */ 108 private final int mCauseCode; 109 110 /** Retry wait time provided by network in milliseconds */ 111 private final int mWaitTimeMillis; 112 ConnectionFailureInfo(Parcel in)113 private ConnectionFailureInfo(Parcel in) { 114 mReason = in.readInt(); 115 mCauseCode = in.readInt(); 116 mWaitTimeMillis = in.readInt(); 117 } 118 119 /** 120 * Constructor. 121 * 122 * @param reason The reason of failure. 123 * @param causeCode Failure cause code from network or modem specific to the failure. 124 * See 3GPP TS 24.401 Annex A (Cause values for EPS mobility management) and 125 * 3GPP TS 24.501 Annex A (Cause values for 5GS mobility management). 126 * @param waitTimeMillis Retry wait time provided by network in milliseconds. 127 * @hide 128 */ ConnectionFailureInfo(@ailureReason int reason, int causeCode, int waitTimeMillis)129 public ConnectionFailureInfo(@FailureReason int reason, int causeCode, int waitTimeMillis) { 130 mReason = reason; 131 mCauseCode = causeCode; 132 mWaitTimeMillis = waitTimeMillis; 133 } 134 135 /** 136 * @return the reason for the failure. 137 */ getReason()138 public @FailureReason int getReason() { 139 return mReason; 140 } 141 142 /** 143 * @return the cause code from the network or modem specific to the failure. 144 * See 3GPP TS 24.401 Annex A (Cause values for EPS mobility management) and 145 * 3GPP TS 24.501 Annex A (Cause values for 5GS mobility management). 146 */ getCauseCode()147 public int getCauseCode() { 148 return mCauseCode; 149 } 150 151 /** 152 * @return the retry wait time provided by the network in milliseconds. 153 */ getWaitTimeMillis()154 public int getWaitTimeMillis() { 155 return mWaitTimeMillis; 156 } 157 158 /** 159 * @return the string format of {@link ConnectionFailureInfo} 160 */ 161 @NonNull 162 @Override toString()163 public String toString() { 164 String reason = sReasonMap.get(mReason, "UNKNOWN"); 165 return "ConnectionFailureInfo :: {" + mReason + " : " + reason + ", " 166 + mCauseCode + ", " + mWaitTimeMillis + "}"; 167 } 168 169 @Override describeContents()170 public int describeContents() { 171 return 0; 172 } 173 174 @Override writeToParcel(@onNull Parcel out, int flags)175 public void writeToParcel(@NonNull Parcel out, int flags) { 176 out.writeInt(mReason); 177 out.writeInt(mCauseCode); 178 out.writeInt(mWaitTimeMillis); 179 } 180 181 public static final @NonNull Creator<ConnectionFailureInfo> CREATOR = 182 new Creator<ConnectionFailureInfo>() { 183 @Override 184 public ConnectionFailureInfo createFromParcel(Parcel in) { 185 return new ConnectionFailureInfo(in); 186 } 187 188 @Override 189 public ConnectionFailureInfo[] newArray(int size) { 190 return new ConnectionFailureInfo[size]; 191 } 192 }; 193 } 194