GsmSMSDispatcher.java revision 0d4bcdf379842af4b6304809156971e926f374f0
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project 3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License. 6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at 7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * http://www.apache.org/licenses/LICENSE-2.0 9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software 11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and 14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License. 15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.gsm; 18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.Activity; 20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent; 21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent.CanceledException; 22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent; 23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult; 24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message; 25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Telephony.Sms; 26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Telephony.Sms.Intents; 27ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.GsmAlphabet; 30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.PhoneBase; 31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SMSDispatcher; 320d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.SmsConstants; 33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsHeader; 34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsUsageMonitor; 35d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils; 36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap; 38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class GsmSMSDispatcher extends SMSDispatcher { 40cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final String TAG = "GsmSMSDispatcher"; 41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Status report received */ 43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_NEW_SMS_STATUS_REPORT = 100; 44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public GsmSMSDispatcher(PhoneBase phone, SmsUsageMonitor usageMonitor) { 460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby super(phone, usageMonitor); 4722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null); 48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void dispose() { 520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby super.dispose(); 5322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.unSetOnSmsStatus(this); 54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected String getFormat() { 58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return SmsConstants.FORMAT_3GPP; 59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Handles 3GPP format-specific events coming from the phone stack. 63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Other events are handled by {@link SMSDispatcher#handleMessage}. 64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param msg the message to handle 66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void handleMessage(Message msg) { 69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (msg.what) { 70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_NEW_SMS_STATUS_REPORT: 71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handleStatusReport((AsyncResult) msg.obj); 72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville super.handleMessage(msg); 76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Called when a status report is received. This should correspond to 81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * a previously successful SEND. 82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param ar AsyncResult passed into the message handler. ar.result should 84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * be a String representing the status report PDU, as ASCII hex. 85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void handleStatusReport(AsyncResult ar) { 87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String pduString = (String) ar.result; 88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage sms = SmsMessage.newFromCDS(pduString); 89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sms != null) { 91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int tpStatus = sms.getStatus(); 9222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int messageRef = sms.mMessageRef; 93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { 94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsTracker tracker = deliveryPendingList.get(i); 95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (tracker.mMessageRef == messageRef) { 96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Found it. Remove from list and broadcast. 97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) { 98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville deliveryPendingList.remove(i); 99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville PendingIntent intent = tracker.mDeliveryIntent; 101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville Intent fillIn = new Intent(); 102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString)); 103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fillIn.putExtra("format", SmsConstants.FORMAT_3GPP); 104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville try { 105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville intent.send(mContext, Activity.RESULT_OK, fillIn); 106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } catch (CanceledException ex) {} 107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Only expect to see one tracker matching this messageref 109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mCi.acknowledgeLastIncomingGsmSms(true, Intents.RESULT_SMS_HANDLED, null); 114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendData(String destAddr, String scAddr, int destPort, 119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville scAddr, destAddr, destPort, data, (deliveryIntent != null)); 122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (pdu != null) { 123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, 124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville destAddr); 125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 126ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null"); 127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendText(String destAddr, String scAddr, String text, 133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville PendingIntent sentIntent, PendingIntent deliveryIntent) { 134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville scAddr, destAddr, text, (deliveryIntent != null)); 136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (pdu != null) { 137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, 138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville destAddr); 139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 140ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null"); 141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected GsmAlphabet.TextEncodingDetails calculateLength(CharSequence messageBody, 147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean use7bitOnly) { 148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return SmsMessage.calculateLength(messageBody, use7bitOnly); 149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendNewSubmitPdu(String destinationAddress, String scAddress, 154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String message, SmsHeader smsHeader, int encoding, 155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) { 156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, 157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader), 158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville encoding, smsHeader.languageTable, smsHeader.languageShiftTable); 159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (pdu != null) { 160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, 161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville destinationAddress); 162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 163ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null"); 164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendSms(SmsTracker tracker) { 170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville HashMap<String, Object> map = tracker.mData; 171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte smsc[] = (byte[]) map.get("smsc"); 173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte pdu[] = (byte[]) map.get("pdu"); 174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 176454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks 177454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks if (tracker.mRetryCount > 0) { 178454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks Rlog.d(TAG, "sendSms: " 179454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks + " mRetryCount=" + tracker.mRetryCount 180454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks + " mMessageRef=" + tracker.mMessageRef 181454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks + " SS=" + mPhone.getServiceState().getState()); 182454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks 183454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks // per TS 23.040 Section 9.2.3.6: If TP-MTI SMS-SUBMIT (0x01) type 184454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks // TP-RD (bit 2) is 1 for retry 185454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks // and TP-MR is set to previously failed sms TP-MR 186454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks if (((0x01 & pdu[0]) == 0x01)) { 187454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks pdu[0] |= 0x04; // TP-RD 188454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks pdu[1] = (byte) tracker.mMessageRef; // TP-MR 189454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks } 190454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks } 19122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply); 192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville} 194