10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2011 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 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.gsm; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.Activity; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Telephony.Sms.Intents; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccIoResult; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccUtils; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cat.ComprehensionTlvTag; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Handler for SMS-PP data download messages. 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See 3GPP TS 31.111 section 7.1.1 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class UsimDataDownloadHandler extends Handler { 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final String TAG = "UsimDataDownloadHandler"; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** BER-TLV tag for SMS-PP download. TS 31.111 section 9.1. */ 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int BER_SMS_PP_DOWNLOAD_TAG = 0xd1; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Device identity value for UICC (destination). */ 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_UICC = 0x81; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Device identity value for network (source). */ 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_NETWORK = 0x83; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Message containing new SMS-PP message to process. */ 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_START_DATA_DOWNLOAD = 1; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Response to SMS-PP download envelope command. */ 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_SEND_ENVELOPE_RESPONSE = 2; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final CommandsInterface mCI; 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public UsimDataDownloadHandler(CommandsInterface commandsInterface) { 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCI = commandsInterface; 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Start an SMS-PP data download for the specified message. Can be called from a different 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * thread than this Handler is running on. 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param smsMessage the message to process 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return Activity.RESULT_OK on success; Intents.RESULT_SMS_GENERIC_ERROR on failure 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int startDataDownload(SmsMessage smsMessage) { 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (sendMessage(obtainMessage(EVENT_START_DATA_DOWNLOAD, smsMessage))) { 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Activity.RESULT_OK; // we will send SMS ACK/ERROR based on UICC response 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "startDataDownload failed to send message to start data download."); 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_GENERIC_ERROR; 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleDataDownload(SmsMessage smsMessage) { 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int dcs = smsMessage.getDataCodingScheme(); 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int pid = smsMessage.getProtocolIdentifier(); 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] pdu = smsMessage.getPdu(); // includes SC address 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int scAddressLength = pdu[0] & 0xff; 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tpduIndex = scAddressLength + 1; // start of TPDU 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tpduLength = pdu.length - tpduIndex; 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bodyLength = getEnvelopeBodyLength(scAddressLength, tpduLength); 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Add 1 byte for SMS-PP download tag and 1-2 bytes for BER-TLV length. 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See ETSI TS 102 223 Annex C for encoding of length and tags. 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int totalLength = bodyLength + 1 + (bodyLength > 127 ? 2 : 1); 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] envelope = new byte[totalLength]; 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int index = 0; 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // SMS-PP download tag and length (assumed to be < 256 bytes). 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) BER_SMS_PP_DOWNLOAD_TAG; 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (bodyLength > 127) { 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) 0x81; // length 128-255 encoded as 0x81 + length 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) bodyLength; 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Device identities TLV 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value()); 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) 2; 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) DEV_ID_NETWORK; 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) DEV_ID_UICC; 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Address TLV (if present). Encoded length is assumed to be < 127 bytes. 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (scAddressLength != 0) { 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) ComprehensionTlvTag.ADDRESS.value(); 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) scAddressLength; 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(pdu, 1, envelope, index, scAddressLength); 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index += scAddressLength; 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // SMS TPDU TLV. Length is assumed to be < 256 bytes. 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.SMS_TPDU.value()); 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (tpduLength > 127) { 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) 0x81; // length 128-255 encoded as 0x81 + length 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope[index++] = (byte) tpduLength; 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(pdu, tpduIndex, envelope, index, tpduLength); 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index += tpduLength; 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Verify that we calculated the payload size correctly. 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (index != envelope.length) { 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "startDataDownload() calculated incorrect envelope length, aborting."); 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR); 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String encodedEnvelope = IccUtils.bytesToHexString(envelope); 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCI.sendEnvelopeWithStatus(encodedEnvelope, obtainMessage( 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville EVENT_SEND_ENVELOPE_RESPONSE, new int[]{ dcs, pid })); 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return the size in bytes of the envelope to send to the UICC, excluding the 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * SMS-PP download tag byte and length byte(s). If the size returned is <= 127, 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the BER-TLV length will be encoded in 1 byte, otherwise 2 bytes are required. 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddressLength the length of the SMSC address, or zero if not present 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param tpduLength the length of the TPDU from the SMS-PP message 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the number of bytes to allocate for the envelope command 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int getEnvelopeBodyLength(int scAddressLength, int tpduLength) { 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Add 4 bytes for device identities TLV + 1 byte for SMS TPDU tag byte 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int length = tpduLength + 5; 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Add 1 byte for TPDU length, or 2 bytes if length > 127 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville length += (tpduLength > 127 ? 2 : 1); 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Add length of address tag, if present (+ 2 bytes for tag and length) 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (scAddressLength != 0) { 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville length = length + 2 + scAddressLength; 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return length; 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Handle the response to the ENVELOPE command. 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param response UICC response encoded as hexadecimal digits. First two bytes are the 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * UICC SW1 and SW2 status bytes. 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void sendSmsAckForEnvelopeResponse(IccIoResult response, int dcs, int pid) { 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int sw1 = response.sw1; 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int sw2 = response.sw2; 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean success; 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(TAG, "USIM data download succeeded: " + response.toString()); 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville success = true; 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (sw1 == 0x93 && sw2 == 0x00) { 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "USIM data download failed: Toolkit busy"); 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY); 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (sw1 == 0x62 || sw1 == 0x63) { 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "USIM data download failed: " + response.toString()); 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville success = false; 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "Unexpected SW1/SW2 response from UICC: " + response.toString()); 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville success = false; 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] responseBytes = response.payload; 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (responseBytes == null || responseBytes.length == 0) { 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (success) { 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCI.acknowledgeLastIncomingGsmSms(true, 0, null); 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville acknowledgeSmsWithError( 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR); 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] smsAckPdu; 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int index = 0; 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (success) { 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu = new byte[responseBytes.length + 5]; 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = 0x00; // TP-MTI, TP-UDHI 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = 0x07; // TP-PI: TP-PID, TP-DCS, TP-UDL present 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu = new byte[responseBytes.length + 6]; 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = 0x00; // TP-MTI, TP-UDHI 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = (byte) 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR; // TP-FCS 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = 0x07; // TP-PI: TP-PID, TP-DCS, TP-UDL present 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = (byte) pid; 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = (byte) dcs; 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (is7bitDcs(dcs)) { 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int septetCount = responseBytes.length * 8 / 7; 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = (byte) septetCount; 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsAckPdu[index++] = (byte) responseBytes.length; 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(responseBytes, 0, smsAckPdu, index, responseBytes.length); 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCI.acknowledgeIncomingGsmSmsWithPdu(success, 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IccUtils.bytesToHexString(smsAckPdu), null); 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void acknowledgeSmsWithError(int cause) { 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCI.acknowledgeLastIncomingGsmSms(false, cause, null); 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns whether the DCS is 7 bit. If so, set TP-UDL to the septet count of TP-UD; 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * otherwise, set TP-UDL to the octet count of TP-UD. 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param dcs the TP-Data-Coding-Scheme field from the original download SMS 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if the DCS specifies 7 bit encoding; false otherwise 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static boolean is7bitDcs(int dcs) { 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See 3GPP TS 23.038 section 4 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((dcs & 0x8C) == 0x00) || ((dcs & 0xF4) == 0xF0); 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Handle UICC envelope response and send SMS acknowledgement. 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param msg the message to handle 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void handleMessage(Message msg) { 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (msg.what) { 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_START_DATA_DOWNLOAD: 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleDataDownload((SmsMessage) msg.obj); 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SEND_ENVELOPE_RESPONSE: 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncResult ar = (AsyncResult) msg.obj; 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar.exception != null) { 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "UICC Send Envelope failure, exception: " + ar.exception); 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville acknowledgeSmsWithError( 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR); 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] dcsPid = (int[]) ar.userObj; 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendSmsAckForEnvelopeResponse((IccIoResult) ar.result, dcsPid[0], dcsPid[1]); 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(TAG, "Ignoring unexpected message, what=" + msg.what); 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 268