CdmaSMSDispatcher.java revision 867641ece36e2fd17faaea79cf19506ab17177c6
1767a662ecde33c3979bf02b793d392aca0403162Wink Saville/* 2767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Copyright (C) 2008 The Android Open Source Project 3767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 4767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5767a662ecde33c3979bf02b793d392aca0403162Wink Saville * you may not use this file except in compliance with the License. 6767a662ecde33c3979bf02b793d392aca0403162Wink Saville * You may obtain a copy of the License at 7767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 8767a662ecde33c3979bf02b793d392aca0403162Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 9767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 10767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Unless required by applicable law or agreed to in writing, software 11767a662ecde33c3979bf02b793d392aca0403162Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13767a662ecde33c3979bf02b793d392aca0403162Wink Saville * See the License for the specific language governing permissions and 14767a662ecde33c3979bf02b793d392aca0403162Wink Saville * limitations under the License. 15767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 16767a662ecde33c3979bf02b793d392aca0403162Wink Saville 17767a662ecde33c3979bf02b793d392aca0403162Wink Savillepackage com.android.internal.telephony.cdma; 18767a662ecde33c3979bf02b793d392aca0403162Wink Saville 19767a662ecde33c3979bf02b793d392aca0403162Wink Saville 20867641ece36e2fd17faaea79cf19506ab17177c6jshimport android.app.Activity; 21767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.app.PendingIntent; 22767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.content.ContentValues; 23767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.database.Cursor; 24767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.database.SQLException; 25767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.AsyncResult; 26767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Message; 27867641ece36e2fd17faaea79cf19506ab17177c6jshimport android.provider.Telephony.Sms.Intents; 28767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.Config; 29767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.Log; 30767a662ecde33c3979bf02b793d392aca0403162Wink Saville 31867641ece36e2fd17faaea79cf19506ab17177c6jshimport com.android.internal.telephony.CommandsInterface; 32767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsHeader; 33767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 34767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SMSDispatcher; 35767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.SmsMessage; 36767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 37767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.util.HexDump; 38767a662ecde33c3979bf02b793d392aca0403162Wink Saville 39767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.ByteArrayOutputStream; 40767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.ArrayList; 41767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.HashMap; 42767a662ecde33c3979bf02b793d392aca0403162Wink Saville 43767a662ecde33c3979bf02b793d392aca0403162Wink Saville 44767a662ecde33c3979bf02b793d392aca0403162Wink Savillefinal class CdmaSMSDispatcher extends SMSDispatcher { 45767a662ecde33c3979bf02b793d392aca0403162Wink Saville private static final String TAG = "CDMA"; 46767a662ecde33c3979bf02b793d392aca0403162Wink Saville 4764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink private CDMAPhone mCdmaPhone; 4864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 49767a662ecde33c3979bf02b793d392aca0403162Wink Saville CdmaSMSDispatcher(CDMAPhone phone) { 50767a662ecde33c3979bf02b793d392aca0403162Wink Saville super(phone); 5164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink mCdmaPhone = phone; 52767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 53767a662ecde33c3979bf02b793d392aca0403162Wink Saville 54767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 55767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Called when a status report is received. This should correspond to 56767a662ecde33c3979bf02b793d392aca0403162Wink Saville * a previously successful SEND. 57767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Is a special GSM function, should never be called in CDMA!! 58767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 59767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param ar AsyncResult passed into the message handler. ar.result should 60767a662ecde33c3979bf02b793d392aca0403162Wink Saville * be a String representing the status report PDU, as ASCII hex. 61767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 62767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void handleStatusReport(AsyncResult ar) { 63767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!"); 64767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 65767a662ecde33c3979bf02b793d392aca0403162Wink Saville 66767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 67767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Dispatches an incoming SMS messages. 68767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 69767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param smsb the incoming message from the phone 70767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 71767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void dispatchMessage(SmsMessageBase smsb) { 72767a662ecde33c3979bf02b793d392aca0403162Wink Saville 73767a662ecde33c3979bf02b793d392aca0403162Wink Saville // If sms is null, means there was a parsing error. 74767a662ecde33c3979bf02b793d392aca0403162Wink Saville // TODO: Should NAK this. 75767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (smsb == null) { 76767a662ecde33c3979bf02b793d392aca0403162Wink Saville return; 77767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 78767a662ecde33c3979bf02b793d392aca0403162Wink Saville 79767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Decode BD stream and set sms variables. 8064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsMessage sms = (SmsMessage) smsb; 81767a662ecde33c3979bf02b793d392aca0403162Wink Saville sms.parseSms(); 8264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink int teleService = sms.getTeleService(); 8364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink boolean handled = false; 84767a662ecde33c3979bf02b793d392aca0403162Wink Saville 85767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Teleservices W(E)MT and VMN are handled together: 8664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if ((teleService == SmsEnvelope.TELESERVICE_WMT) 8764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink || (teleService == SmsEnvelope.TELESERVICE_WEMT) 8864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink || (teleService == SmsEnvelope.TELESERVICE_VMN)) { 89767a662ecde33c3979bf02b793d392aca0403162Wink Saville // From here on we need decoded BD. 90767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Special case the message waiting indicator messages 91767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (sms.isMWISetMessage()) { 9264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink mCdmaPhone.updateMessageWaitingIndicator(true); 9364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink handled |= sms.isMwiDontStore(); 94767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (Config.LOGD) { 9564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled); 96767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 97767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else if (sms.isMWIClearMessage()) { 9864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink mCdmaPhone.updateMessageWaitingIndicator(false); 9964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink handled |= sms.isMwiDontStore(); 100767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (Config.LOGD) { 10164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled); 102767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 103767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 104767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 105767a662ecde33c3979bf02b793d392aca0403162Wink Saville 10664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if (sms.getUserData() == null) { 107767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (Config.LOGD) { 108767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "Received SMS without user data"); 109767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 11064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink handled = true; 111767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 112767a662ecde33c3979bf02b793d392aca0403162Wink Saville 113767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (handled) return; 114767a662ecde33c3979bf02b793d392aca0403162Wink Saville 115767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (SmsEnvelope.TELESERVICE_WAP == teleService){ 116767a662ecde33c3979bf02b793d392aca0403162Wink Saville processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress()); 117767a662ecde33c3979bf02b793d392aca0403162Wink Saville return; 118767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 119767a662ecde33c3979bf02b793d392aca0403162Wink Saville 12064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink /** 12164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): Why are we using a getter method for this 12264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * (and for so many other sms fields)? Trivial getters and 12364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * setters like this are direct violations of the style guide. 12464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * If the purpose is to protect agaist writes (by not 12564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * providing a setter) then any protection is illusory (and 12664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * hence bad) for cases where the values are not primitives, 12764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * such as this call for the header. Since this is an issue 12864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * with the public API it cannot be changed easily, but maybe 12964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * something can be done eventually. 13064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 13164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader smsHeader = sms.getUserDataHeader(); 13264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 13364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink /** 13464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): Since both CDMA and GSM use the same header 13564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * format, this dispatch processing is naturally identical, 13664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * and code should probably not be replicated explicitly. 13764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 13864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // See if message is partial or port addressed. 13964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if ((smsHeader == null) || (smsHeader.concatRef == null)) { 14064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // Message is not partial (not part of concatenated sequence). 141767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[][] pdus = new byte[1][]; 142767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus[0] = sms.getPdu(); 143767a662ecde33c3979bf02b793d392aca0403162Wink Saville 14431fd22923aaefc85652a5b5939c6d4aa6fa289e2jsh if (smsHeader != null && smsHeader.portAddrs != null) { 14564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { 14664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // GSM-style WAP indication 147767a662ecde33c3979bf02b793d392aca0403162Wink Saville mWapPush.dispatchWapPdu(sms.getUserData()); 148767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 14964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // The message was sent to a port, so concoct a URI for it. 15064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); 151767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 15264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // Normal short and non-port-addressed message, dispatch it. 153767a662ecde33c3979bf02b793d392aca0403162Wink Saville dispatchPdus(pdus); 154767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 155767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 15664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // Process the message part. 15764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs); 158767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 159767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 160767a662ecde33c3979bf02b793d392aca0403162Wink Saville 161767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 162767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Processes inbound messages that are in the WAP-WDP PDU format. See 163767a662ecde33c3979bf02b793d392aca0403162Wink Saville * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format. 164767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WDP segments are gathered until a datagram completes and gets dispatched. 165767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 166767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param pdu The WAP-WDP PDU segment 167767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 168767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) { 169767a662ecde33c3979bf02b793d392aca0403162Wink Saville int segment; 170767a662ecde33c3979bf02b793d392aca0403162Wink Saville int totalSegments; 171767a662ecde33c3979bf02b793d392aca0403162Wink Saville int index = 0; 172767a662ecde33c3979bf02b793d392aca0403162Wink Saville int msgType; 173767a662ecde33c3979bf02b793d392aca0403162Wink Saville 174767a662ecde33c3979bf02b793d392aca0403162Wink Saville int sourcePort; 175767a662ecde33c3979bf02b793d392aca0403162Wink Saville int destinationPort; 176767a662ecde33c3979bf02b793d392aca0403162Wink Saville 177767a662ecde33c3979bf02b793d392aca0403162Wink Saville msgType = pdu[index++]; 178767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (msgType != 0){ 179767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(TAG, "Received a WAP SMS which is not WDP. Discard."); 180767a662ecde33c3979bf02b793d392aca0403162Wink Saville return; 181767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 182767a662ecde33c3979bf02b793d392aca0403162Wink Saville totalSegments = pdu[index++]; // >=1 183767a662ecde33c3979bf02b793d392aca0403162Wink Saville segment = pdu[index++]; // >=0 184767a662ecde33c3979bf02b793d392aca0403162Wink Saville 185767a662ecde33c3979bf02b793d392aca0403162Wink Saville //process WDP segment 186767a662ecde33c3979bf02b793d392aca0403162Wink Saville sourcePort = (0xFF & pdu[index++]) << 8; 187767a662ecde33c3979bf02b793d392aca0403162Wink Saville sourcePort |= 0xFF & pdu[index++]; 188767a662ecde33c3979bf02b793d392aca0403162Wink Saville destinationPort = (0xFF & pdu[index++]) << 8; 189767a662ecde33c3979bf02b793d392aca0403162Wink Saville destinationPort |= 0xFF & pdu[index++]; 190767a662ecde33c3979bf02b793d392aca0403162Wink Saville 191767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Lookup all other related parts 192767a662ecde33c3979bf02b793d392aca0403162Wink Saville StringBuilder where = new StringBuilder("reference_number ="); 193767a662ecde33c3979bf02b793d392aca0403162Wink Saville where.append(referenceNumber); 194767a662ecde33c3979bf02b793d392aca0403162Wink Saville where.append(" AND address = ?"); 195767a662ecde33c3979bf02b793d392aca0403162Wink Saville String[] whereArgs = new String[] {address}; 196767a662ecde33c3979bf02b793d392aca0403162Wink Saville 197767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address 198767a662ecde33c3979bf02b793d392aca0403162Wink Saville + ", src-port = " + sourcePort + ", dst-port = " + destinationPort 199767a662ecde33c3979bf02b793d392aca0403162Wink Saville + ", ID = " + referenceNumber + ", segment# = " + segment + "/" + totalSegments); 200767a662ecde33c3979bf02b793d392aca0403162Wink Saville 201767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[][] pdus = null; 202767a662ecde33c3979bf02b793d392aca0403162Wink Saville Cursor cursor = null; 203767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 204767a662ecde33c3979bf02b793d392aca0403162Wink Saville cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null); 205767a662ecde33c3979bf02b793d392aca0403162Wink Saville int cursorCount = cursor.getCount(); 206767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (cursorCount != totalSegments - 1) { 207767a662ecde33c3979bf02b793d392aca0403162Wink Saville // We don't have all the parts yet, store this one away 208767a662ecde33c3979bf02b793d392aca0403162Wink Saville ContentValues values = new ContentValues(); 209767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("date", new Long(0)); 210767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("pdu", HexDump.toHexString(pdu, index, pdu.length - index)); 211767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("address", address); 212767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("reference_number", referenceNumber); 213767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("count", totalSegments); 214767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("sequence", segment); 215767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("destination_port", destinationPort); 216767a662ecde33c3979bf02b793d392aca0403162Wink Saville 217767a662ecde33c3979bf02b793d392aca0403162Wink Saville mResolver.insert(mRawUri, values); 218767a662ecde33c3979bf02b793d392aca0403162Wink Saville 219767a662ecde33c3979bf02b793d392aca0403162Wink Saville return; 220767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 221767a662ecde33c3979bf02b793d392aca0403162Wink Saville 222767a662ecde33c3979bf02b793d392aca0403162Wink Saville // All the parts are in place, deal with them 223767a662ecde33c3979bf02b793d392aca0403162Wink Saville int pduColumn = cursor.getColumnIndex("pdu"); 224767a662ecde33c3979bf02b793d392aca0403162Wink Saville int sequenceColumn = cursor.getColumnIndex("sequence"); 225767a662ecde33c3979bf02b793d392aca0403162Wink Saville 226767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus = new byte[totalSegments][]; 227767a662ecde33c3979bf02b793d392aca0403162Wink Saville for (int i = 0; i < cursorCount; i++) { 228767a662ecde33c3979bf02b793d392aca0403162Wink Saville cursor.moveToNext(); 229767a662ecde33c3979bf02b793d392aca0403162Wink Saville int cursorSequence = (int)cursor.getLong(sequenceColumn); 230767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus[cursorSequence] = HexDump.hexStringToByteArray( 231767a662ecde33c3979bf02b793d392aca0403162Wink Saville cursor.getString(pduColumn)); 232767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 233767a662ecde33c3979bf02b793d392aca0403162Wink Saville // The last part will be added later 234767a662ecde33c3979bf02b793d392aca0403162Wink Saville 235767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Remove the parts from the database 236767a662ecde33c3979bf02b793d392aca0403162Wink Saville mResolver.delete(mRawUri, where.toString(), whereArgs); 237767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch (SQLException e) { 238767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.e(TAG, "Can't access multipart SMS database", e); 239767a662ecde33c3979bf02b793d392aca0403162Wink Saville return; // TODO: NACK the message or something, don't just discard. 240767a662ecde33c3979bf02b793d392aca0403162Wink Saville } finally { 241767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (cursor != null) cursor.close(); 242767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 243767a662ecde33c3979bf02b793d392aca0403162Wink Saville 244767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Build up the data stream 245767a662ecde33c3979bf02b793d392aca0403162Wink Saville ByteArrayOutputStream output = new ByteArrayOutputStream(); 246767a662ecde33c3979bf02b793d392aca0403162Wink Saville for (int i = 0; i < totalSegments-1; i++) { 247767a662ecde33c3979bf02b793d392aca0403162Wink Saville // reassemble the (WSP-)pdu 248767a662ecde33c3979bf02b793d392aca0403162Wink Saville output.write(pdus[i], 0, pdus[i].length); 249767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 250767a662ecde33c3979bf02b793d392aca0403162Wink Saville 251767a662ecde33c3979bf02b793d392aca0403162Wink Saville // This one isn't in the DB, so add it 252767a662ecde33c3979bf02b793d392aca0403162Wink Saville output.write(pdu, index, pdu.length - index); 253767a662ecde33c3979bf02b793d392aca0403162Wink Saville 254767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[] datagram = output.toByteArray(); 255767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Dispatch the PDU to applications 256767a662ecde33c3979bf02b793d392aca0403162Wink Saville switch (destinationPort) { 257767a662ecde33c3979bf02b793d392aca0403162Wink Saville case SmsHeader.PORT_WAP_PUSH: 258767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Handle the PUSH 259767a662ecde33c3979bf02b793d392aca0403162Wink Saville mWapPush.dispatchWapPdu(datagram); 260767a662ecde33c3979bf02b793d392aca0403162Wink Saville break; 261767a662ecde33c3979bf02b793d392aca0403162Wink Saville 262767a662ecde33c3979bf02b793d392aca0403162Wink Saville default:{ 263767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus = new byte[1][]; 264767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus[0] = datagram; 265767a662ecde33c3979bf02b793d392aca0403162Wink Saville // The messages were sent to any other WAP port 266767a662ecde33c3979bf02b793d392aca0403162Wink Saville dispatchPortAddressedPdus(pdus, destinationPort); 267767a662ecde33c3979bf02b793d392aca0403162Wink Saville break; 268767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 269767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 270767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 271767a662ecde33c3979bf02b793d392aca0403162Wink Saville 272767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 27364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink protected void sendMultipartText(String destAddr, String scAddr, 274767a662ecde33c3979bf02b793d392aca0403162Wink Saville ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, 275767a662ecde33c3979bf02b793d392aca0403162Wink Saville ArrayList<PendingIntent> deliveryIntents) { 276767a662ecde33c3979bf02b793d392aca0403162Wink Saville 27764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink /** 27864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): There is no real code difference between 27964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * this and the GSM version, and hence it should be moved to 28064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * the base class or consolidated somehow, provided calling 28164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * the proper submitpdu stuff can be arranged. 28264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 283767a662ecde33c3979bf02b793d392aca0403162Wink Saville 28464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink int refNumber = getNextConcatenatedRef() & 0x00FF; 285767a662ecde33c3979bf02b793d392aca0403162Wink Saville 28664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink for (int i = 0, msgCount = parts.size(); i < msgCount; i++) { 28764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); 28864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.refNumber = refNumber; 28964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.seqNumber = i + 1; // 1-based sequence 29064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.msgCount = msgCount; 29164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.isEightBits = true; 29264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader smsHeader = new SmsHeader(); 29364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink smsHeader.concatRef = concatRef; 294767a662ecde33c3979bf02b793d392aca0403162Wink Saville 29564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink PendingIntent sentIntent = null; 296767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (sentIntents != null && sentIntents.size() > i) { 297767a662ecde33c3979bf02b793d392aca0403162Wink Saville sentIntent = sentIntents.get(i); 298767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 29964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 30064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink PendingIntent deliveryIntent = null; 301767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (deliveryIntents != null && deliveryIntents.size() > i) { 302767a662ecde33c3979bf02b793d392aca0403162Wink Saville deliveryIntent = deliveryIntents.get(i); 303767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 304767a662ecde33c3979bf02b793d392aca0403162Wink Saville 30564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(scAddr, destAddr, 30664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink parts.get(i), deliveryIntent != null, smsHeader); 307767a662ecde33c3979bf02b793d392aca0403162Wink Saville 30864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink sendSubmitPdu(submitPdu, sentIntent, deliveryIntent); 309767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 310767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 311767a662ecde33c3979bf02b793d392aca0403162Wink Saville 31264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink protected void sendSubmitPdu(SmsMessage.SubmitPdu submitPdu, PendingIntent sentIntent, 313767a662ecde33c3979bf02b793d392aca0403162Wink Saville PendingIntent deliveryIntent) { 31464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink sendRawPdu(submitPdu.encodedScAddress, submitPdu.encodedMessage, 31564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink sentIntent, deliveryIntent); 316767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 317767a662ecde33c3979bf02b793d392aca0403162Wink Saville 318767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 319767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void sendSms(SmsTracker tracker) { 320767a662ecde33c3979bf02b793d392aca0403162Wink Saville HashMap map = tracker.mData; 321767a662ecde33c3979bf02b793d392aca0403162Wink Saville 322767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte smsc[] = (byte[]) map.get("smsc"); 323767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte pdu[] = (byte[]) map.get("pdu"); 324767a662ecde33c3979bf02b793d392aca0403162Wink Saville 325767a662ecde33c3979bf02b793d392aca0403162Wink Saville Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 326767a662ecde33c3979bf02b793d392aca0403162Wink Saville 327767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.sendCdmaSms(pdu, reply); 328767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 329767a662ecde33c3979bf02b793d392aca0403162Wink Saville 330767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 331767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void sendMultipartSms (SmsTracker tracker) { 332767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "TODO: CdmaSMSDispatcher.sendMultipartSms not implemented"); 333767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 334767a662ecde33c3979bf02b793d392aca0403162Wink Saville 335767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 336867641ece36e2fd17faaea79cf19506ab17177c6jsh protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){ 337767a662ecde33c3979bf02b793d392aca0403162Wink Saville // FIXME unit test leaves cm == null. this should change 338767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (mCm != null) { 339867641ece36e2fd17faaea79cf19506ab17177c6jsh mCm.acknowledgeLastIncomingCdmaSms(success, resultToCause(result), response); 340767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 341767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 342767a662ecde33c3979bf02b793d392aca0403162Wink Saville 343767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 344767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void activateCellBroadcastSms(int activate, Message response) { 345767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.activateCdmaBroadcastSms(activate, response); 346767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 347767a662ecde33c3979bf02b793d392aca0403162Wink Saville 348767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 349767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void getCellBroadcastSmsConfig(Message response) { 350767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.getCdmaBroadcastConfig(response); 351767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 352767a662ecde33c3979bf02b793d392aca0403162Wink Saville 353767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 354767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void setCellBroadcastConfig(int[] configValuesArray, Message response) { 355767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.setCdmaBroadcastConfig(configValuesArray, response); 356767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 357767a662ecde33c3979bf02b793d392aca0403162Wink Saville 358867641ece36e2fd17faaea79cf19506ab17177c6jsh private int resultToCause(int rc) { 359867641ece36e2fd17faaea79cf19506ab17177c6jsh switch (rc) { 360867641ece36e2fd17faaea79cf19506ab17177c6jsh case Activity.RESULT_OK: 361867641ece36e2fd17faaea79cf19506ab17177c6jsh case Intents.RESULT_SMS_HANDLED: 362867641ece36e2fd17faaea79cf19506ab17177c6jsh // Cause code is ignored on success. 363867641ece36e2fd17faaea79cf19506ab17177c6jsh return 0; 364867641ece36e2fd17faaea79cf19506ab17177c6jsh case Intents.RESULT_SMS_OUT_OF_MEMORY: 365867641ece36e2fd17faaea79cf19506ab17177c6jsh return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; 366867641ece36e2fd17faaea79cf19506ab17177c6jsh case Intents.RESULT_SMS_GENERIC_ERROR: 367867641ece36e2fd17faaea79cf19506ab17177c6jsh default: 368867641ece36e2fd17faaea79cf19506ab17177c6jsh return CommandsInterface.CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM; 369867641ece36e2fd17faaea79cf19506ab17177c6jsh } 370867641ece36e2fd17faaea79cf19506ab17177c6jsh } 371767a662ecde33c3979bf02b793d392aca0403162Wink Saville} 372