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