Fix CDMA SMS delivery status reporting.

CDMA SMS status reports are messages with bearer data message type
DELIVERY_ACK.  Identify these messages after parsing during demux,
update the deliveryPendingList and generate a RESULT_OK intent in the
same manner as GSM.

Addresses issue:
http://buganizer/issue?id=2047571

Change-Id: Ia38718b0bb169a0f3398f50c27a95e8bce7e4c99
This commit is contained in:
Tammo Spalink
2009-09-03 19:05:53 +08:00
parent f84a21820b
commit d304ae583d
2 changed files with 50 additions and 22 deletions

View File

@@ -21,6 +21,7 @@ import android.app.Activity;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException; import android.app.PendingIntent.CanceledException;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.database.SQLException; import android.database.SQLException;
@@ -73,6 +74,23 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!"); Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!");
} }
private void handleCdmaStatusReport(SmsMessage sms) {
for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
SmsTracker tracker = deliveryPendingList.get(i);
if (tracker.mMessageRef == sms.messageRef) {
// Found it. Remove from list and broadcast.
deliveryPendingList.remove(i);
PendingIntent intent = tracker.mDeliveryIntent;
Intent fillIn = new Intent();
fillIn.putExtra("pdu", sms.getPdu());
try {
intent.send(mContext, Activity.RESULT_OK, fillIn);
} catch (CanceledException ex) {}
break; // Only expect to see one tracker matching this message.
}
}
}
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int dispatchMessage(SmsMessageBase smsb) { protected int dispatchMessage(SmsMessageBase smsb) {
@@ -105,6 +123,11 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
editor.commit(); editor.commit();
((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount); ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
handled = true; handled = true;
} else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
(SmsEnvelope.TELESERVICE_WEMT == teleService)) &&
sms.isStatusReportMessage()) {
handleCdmaStatusReport(sms);
handled = true;
} else if ((sms.getUserData() == null)) { } else if ((sms.getUserData() == null)) {
if (Config.LOGD) { if (Config.LOGD) {
Log.d(TAG, "Received SMS without user data"); Log.d(TAG, "Received SMS without user data");
@@ -354,8 +377,12 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
uData.payloadStr = parts.get(i); uData.payloadStr = parts.get(i);
uData.userDataHeader = smsHeader; uData.userDataHeader = smsHeader;
/* By setting the statusReportRequested bit only for the
* last message fragment, this will result in only one
* callback to the sender when that last fragment delivery
* has been acknowledged. */
SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destAddr, SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destAddr,
uData, deliveryIntent != null); uData, (deliveryIntent != null) && (i == (msgCount - 1)));
sendSubmitPdu(submitPdu, sentIntent, deliveryIntent); sendSubmitPdu(submitPdu, sentIntent, deliveryIntent);
} }

View File

@@ -424,12 +424,9 @@ public class SmsMessage extends SmsMessageBase {
return (status << 16); return (status << 16);
} }
/** /** Return true iff the bearer data message type is DELIVERY_ACK. */
* Note: This function is a GSM specific functionality which is not supported in CDMA mode.
*/
public boolean isStatusReportMessage() { public boolean isStatusReportMessage() {
Log.w(LOG_TAG, "isStatusReportMessage: is not supported in CDMA mode."); return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK);
return false;
} }
/** /**
@@ -548,17 +545,6 @@ public class SmsMessage extends SmsMessageBase {
messageBody = mBearerData.userData.payloadStr; messageBody = mBearerData.userData.payloadStr;
} }
// TP-Message-Type-Indicator (See 3GPP2 C.S0015-B, v2, 4.5.1)
switch (mBearerData.messageType) {
case BearerData.MESSAGE_TYPE_USER_ACK:
case BearerData.MESSAGE_TYPE_READ_ACK:
case BearerData.MESSAGE_TYPE_DELIVER:
case BearerData.MESSAGE_TYPE_DELIVERY_ACK:
break;
default:
throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
}
if (originatingAddress != null) { if (originatingAddress != null) {
originatingAddress.address = new String(originatingAddress.origBytes); originatingAddress.address = new String(originatingAddress.origBytes);
if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: " if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
@@ -571,11 +557,26 @@ public class SmsMessage extends SmsMessageBase {
if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis); if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
// TODO(Teleca): do we really want this test to occur only for DELIVERY_ACKs? // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
if ((mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) && if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) {
(mBearerData.errorClass != BearerData.ERROR_UNDEFINED)) { // The BearerData MsgStatus subparameter should only be
status = mBearerData.errorClass << 8; // included for DELIVERY_ACK messages. If it occurred for
status |= mBearerData.messageStatus; // other messages, it would be unclear what the status
// being reported refers to. The MsgStatus subparameter
// is primarily useful to indicate error conditions -- a
// message without this subparameter is assumed to
// indicate successful delivery (status == 0).
if (! mBearerData.messageStatusSet) {
Log.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
(userData == null ? "also missing" : "does have") +
" userData).");
status = 0;
} else {
status = mBearerData.errorClass << 8;
status |= mBearerData.messageStatus;
}
} else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) {
throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
} }
if (messageBody != null) { if (messageBody != null) {