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 
17 package com.android.internal.telephony.uicc;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 
21 import com.android.internal.telephony.util.TelephonyUtils;
22 
23 /**
24  * {@hide}
25  */
26 public class
27 IccIoResult {
28 
29     private static final String UNKNOWN_ERROR = "unknown";
30 
getErrorString()31     private String getErrorString() {
32         // Errors from 3gpp 11.11 9.4.1
33         // Additional Errors from ETSI 102.221
34         //
35         // All error codes below are copied directly from their respective specification
36         // without modification except in cases where necessary string formatting has been omitted.
37         switch(sw1) {
38             case 0x61: return sw2 + " more response bytes available";
39             case 0x62:
40                 switch(sw2) {
41                     case 0x00: return "no information given,"
42                             + " state of non volatile memory unchanged";
43                     case 0x81: return "part of returned data may be corrupted";
44                     case 0x82: return "end of file/record reached before reading Le bytes";
45                     case 0x83: return "selected file invalidated";
46                     case 0x84: return "selected file in termination state";
47                     case 0xF1: return "more data available";
48                     case 0xF2: return "more data available and proactive command pending";
49                     case 0xF3: return "response data available";
50                 }
51                 break;
52             case 0x63:
53                 if (sw2 >> 4 == 0x0C) {
54                     int retries = sw2 & 0x0F;
55                     return "command successful but after using an internal update retry routine "
56                             + retries + " times,"
57                             + " or verification failed, " + retries + " retries remaining";
58                 }
59                 switch(sw2) {
60                     case 0xF1: return "more data expected";
61                     case 0xF2: return "more data expected and proactive command pending";
62                 }
63                 break;
64             case 0x64:
65                 switch(sw2) {
66                     case 0x00: return "no information given,"
67                                + " state of non-volatile memory unchanged";
68                 }
69                 break;
70             case 0x65:
71                 switch(sw2) {
72                     case 0x00: return "no information given, state of non-volatile memory changed";
73                     case 0x81: return "memory problem";
74                 }
75                 break;
76             case 0x67:
77                 switch(sw2) {
78                     case 0x00: return "incorrect parameter P3";
79                     default: return "the interpretation of this status word is command dependent";
80                 }
81                 // break;
82             case 0x68:
83                 switch(sw2) {
84                     case 0x00: return "no information given";
85                     case 0x81: return "logical channel not supported";
86                     case 0x82: return "secure messaging not supported";
87                 }
88                 break;
89             case 0x69:
90                 switch(sw2) {
91                     case 0x00: return "no information given";
92                     case 0x81: return "command incompatible with file structure";
93                     case 0x82: return "security status not satisfied";
94                     case 0x83: return "authentication/PIN method blocked";
95                     case 0x84: return "referenced data invalidated";
96                     case 0x85: return "conditions of use not satisfied";
97                     case 0x86: return "command not allowed (no EF selected)";
98                     case 0x89: return "command not allowed - secure channel -"
99                             + " security not satisfied";
100                 }
101                 break;
102             case 0x6A:
103                 switch(sw2) {
104                     case 0x80: return "incorrect parameters in the data field";
105                     case 0x81: return "function not supported";
106                     case 0x82: return "file not found";
107                     case 0x83: return "record not found";
108                     case 0x84: return "not enough memory space";
109                     case 0x86: return "incorrect parameters P1 to P2";
110                     case 0x87: return "lc inconsistent with P1 to P2";
111                     case 0x88: return "referenced data not found";
112                 }
113                 break;
114             case 0x6B: return "incorrect parameter P1 or P2";
115             case 0x6C: return "wrong length, retry with " + sw2;
116             case 0x6D: return "unknown instruction code given in the command";
117             case 0x6E: return "wrong instruction class given in the command";
118             case 0x6F:
119                 switch(sw2) {
120                     case 0x00: return "technical problem with no diagnostic given";
121                     default: return "the interpretation of this status word is command dependent";
122                 }
123                 // break;
124             case 0x90: return null; // success
125             case 0x91: return null; // success
126             //Status Code 0x92 has contradictory meanings from 11.11 and 102.221 10.2.1.1
127             case 0x92:
128                 if (sw2 >> 4 == 0) {
129                     return "command successful but after using an internal update retry routine";
130                 }
131                 switch(sw2) {
132                     case 0x40: return "memory problem";
133                 }
134                 break;
135             case 0x93:
136                 switch(sw2) {
137                     case 0x00: return "SIM Application Toolkit is busy. Command cannot be executed"
138                             + " at present, further normal commands are allowed";
139                 }
140                 break;
141             case 0x94:
142                 switch(sw2) {
143                     case 0x00: return "no EF selected";
144                     case 0x02: return "out f range (invalid address)";
145                     case 0x04: return "file ID not found/pattern not found";
146                     case 0x08: return "file is inconsistent with the command";
147                 }
148                 break;
149             case 0x98:
150                 switch(sw2) {
151                     case 0x02: return "no CHV initialized";
152                     case 0x04: return "access condition not fulfilled/"
153                             + "unsuccessful CHV verification, at least one attempt left/"
154                             + "unsuccessful UNBLOCK CHV verification, at least one attempt left/"
155                             + "authentication failed";
156                     case 0x08: return "in contradiction with CHV status";
157                     case 0x10: return "in contradiction with invalidation status";
158                     case 0x40: return "unsuccessful CHV verification, no attempt left/"
159                             + "unsuccessful UNBLOCK CHV verification, no attempt left/"
160                             + "CHV blocked/"
161                             + "UNBLOCK CHV blocked";
162                     case 0x50: return "increase cannot be performed, Max value reached";
163                     // The definition for these status codes can be found in TS 31.102 7.3.1
164                     case 0x62: return "authentication error, application specific";
165                     case 0x64: return "authentication error, security context not supported";
166                     case 0x65: return "key freshness failure";
167                     case 0x66: return "authentication error, no memory space available";
168                     case 0x67: return "authentication error, no memory space available in EF_MUK";
169                 }
170                 break;
171             case 0x9E: return null; // success
172             case 0x9F: return null; // success
173         }
174         return UNKNOWN_ERROR;
175     }
176 
177 
178     @UnsupportedAppUsage
179     public int sw1;
180     @UnsupportedAppUsage
181     public int sw2;
182 
183     @UnsupportedAppUsage
184     public byte[] payload;
185 
186     @UnsupportedAppUsage
IccIoResult(int sw1, int sw2, byte[] payload)187     public IccIoResult(int sw1, int sw2, byte[] payload) {
188         this.sw1 = sw1;
189         this.sw2 = sw2;
190         this.payload = payload;
191     }
192 
193     @UnsupportedAppUsage
IccIoResult(int sw1, int sw2, String hexString)194     public IccIoResult(int sw1, int sw2, String hexString) {
195         this(sw1, sw2, IccUtils.hexStringToBytes(hexString));
196     }
197 
198     @Override
toString()199     public String toString() {
200         return "IccIoResult sw1:0x"
201                 + Integer.toHexString(sw1)
202                 + " sw2:0x"
203                 + Integer.toHexString(sw2)
204                 + " Payload: "
205                 + (TelephonyUtils.IS_DEBUGGABLE ? IccUtils.bytesToHexString(payload) : "*******")
206                 + ((!success()) ? " Error: " + getErrorString() : "");
207     }
208 
209     /**
210      * true if this operation was successful
211      * See GSM 11.11 Section 9.4
212      * (the fun stuff is absent in 51.011)
213      */
214     @UnsupportedAppUsage
success()215     public boolean success() {
216         return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f;
217     }
218 
219     /**
220      * Returns exception on error or null if success
221      */
getException()222     public IccException getException() {
223         if (success()) return null;
224 
225         switch (sw1) {
226             case 0x94:
227                 if (sw2 == 0x08) {
228                     return new IccFileTypeMismatch();
229                 } else {
230                     return new IccFileNotFound();
231                 }
232             default:
233                 return new IccException("sw1:" + sw1 + " sw2:" + sw2);
234         }
235     }
236 }
237