10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 17d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkapackage com.android.internal.telephony.uicc; 18d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide} 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class 240825495a331bb44df395a0cdb79fab85e68db5d5Wink SavilleIccIoResult { 25633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold 26633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold private static final String UNKNOWN_ERROR = "unknown"; 27633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold 28633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold private String getErrorString() { 29633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // Errors from 3gpp 11.11 9.4.1 30633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // Additional Errors from ETSI 102.221 31633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // 32633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // All error codes below are copied directly from their respective specification 33633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // without modification except in cases where necessary string formatting has been omitted. 34633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw1) { 35633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x62: 36633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 37633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "No information given," 38633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + " state of non volatile memory unchanged"; 39633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x81: return "Part of returned data may be corrupted"; 40633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x82: return "End of file/record reached before reading Le bytes"; 41633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x83: return "Selected file invalidated"; 42633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x84: return "Selected file in termination state"; 43633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0xF1: return "More data available"; 44633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0xF2: return "More data available and proactive command pending"; 45633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0xF3: return "Response data available"; 46633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 47633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 48633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x63: 49633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold if (sw2 >> 4 == 0x0C) { 50633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold return "Command successful but after using an internal" 51633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "update retry routine but Verification failed"; 52633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 53633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 54633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0xF1: return "More data expected"; 55633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0xF2: return "More data expected and proactive command pending"; 56633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 57633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 58633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x64: 59633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 60633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "No information given," 61633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + " state of non-volatile memory unchanged"; 62633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 63633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 64633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x65: 65633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 66633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "No information given, state of non-volatile memory changed"; 67633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x81: return "Memory problem"; 68633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 69633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 70633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x67: 71633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 72633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "incorrect parameter P3"; 73633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold default: return "The interpretation of this status word is command dependent"; 74633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 75633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // break; 76633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x6B: return "incorrect parameter P1 or P2"; 77633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x6D: return "unknown instruction code given in the command"; 78633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x6E: return "wrong instruction class given in the command"; 79633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x6F: 80633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 81633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "technical problem with no diagnostic given"; 82633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold default: return "The interpretation of this status word is command dependent"; 83633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 84633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold // break; 85633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x68: 86633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 87633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "No information given"; 88633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x81: return "Logical channel not supported"; 89633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x82: return "Secure messaging not supported"; 90633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 91633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 92633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x69: 93633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 94633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "No information given"; 95633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x81: return "Command incompatible with file structure"; 96633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x82: return "Security status not satisfied"; 97633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x83: return "Authentication/PIN method blocked"; 98633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x84: return "Referenced data invalidated"; 99633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x85: return "Conditions of use not satisfied"; 100633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x86: return "Command not allowed (no EF selected)"; 101633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x89: return "Command not allowed - secure channel -" 102633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + " security not satisfied"; 103633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 104633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 105633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x6A: 106633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 107633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x80: return "Incorrect parameters in the data field"; 108633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x81: return "Function not supported"; 109633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x82: return "File not found"; 110633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x83: return "Record not found"; 111633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x84: return "Not enough memory space"; 112633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x86: return "Incorrect parameters P1 to P2"; 113633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x87: return "Lc inconsistent with P1 to P2"; 114633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x88: return "Referenced data not found"; 115633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 116633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 117633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x90: return null; // success 118633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x91: return null; // success 119633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold //Status Code 0x92 has contradictory meanings from 11.11 and 102.221 10.2.1.1 120633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x92: 121633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold if (sw2 >> 4 == 0) { 122633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold return "command successful but after using an internal update retry routine"; 123633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 124633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 125633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x40: return "memory problem"; 126633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 127633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 128633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x93: 129633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 130633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: 131633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold return "SIM Application Toolkit is busy. Command cannot be executed" 132633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + " at present, further normal commands are allowed."; 133633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 134633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 135633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x94: 136633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 137633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x00: return "no EF selected"; 138633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x02: return "out f range (invalid address)"; 139633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x04: return "file ID not found/pattern not found"; 140633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x08: return "file is inconsistent with the command"; 141633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 142633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 143633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x98: 144633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold switch(sw2) { 145633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x02: return "no CHV initialized"; 146633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x04: return "access condition not fulfilled/" 147633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "unsuccessful CHV verification, at least one attempt left/" 148633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "unsuccessful UNBLOCK CHV verification, at least one attempt left/" 149633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "authentication failed"; 150633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x08: return "in contradiction with CHV status"; 151633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x10: return "in contradiction with invalidation status"; 152633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x40: return "unsuccessful CHV verification, no attempt left/" 153633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "unsuccessful UNBLOCK CHV verification, no attempt left/" 154633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "CHV blocked" 155633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + "UNBLOCK CHV blocked"; 156633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x50: return "increase cannot be performed, Max value reached"; 157633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 158633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold break; 159633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x9E: return null; // success 160633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold case 0x9F: return null; // success 161633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 162633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold return UNKNOWN_ERROR; 163633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold } 164633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold 165633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int sw1; 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int sw2; 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public byte[] payload; 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public IccIoResult(int sw1, int sw2, byte[] payload) { 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.sw1 = sw1; 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.sw2 = sw2; 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.payload = payload; 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public IccIoResult(int sw1, int sw2, String hexString) { 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this(sw1, sw2, IccUtils.hexStringToBytes(hexString)); 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 181cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String toString() { 183633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold return "IccIoResult sw1:0x" + Integer.toHexString(sw1) + " sw2:0x" 184633765fea496acd1c3891b1020f622b0dcf29439Nathan Harold + Integer.toHexString(sw2) + ((!success()) ? " Error: " + getErrorString() : ""); 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * true if this operation was successful 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See GSM 11.11 Section 9.4 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * (the fun stuff is absent in 51.011) 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean success() { 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f; 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns exception on error or null if success 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public IccException getException() { 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (success()) return null; 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (sw1) { 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 0x94: 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (sw2 == 0x08) { 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new IccFileTypeMismatch(); 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new IccFileNotFound(); 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new IccException("sw1:" + sw1 + " sw2:" + sw2); 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 214