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:
@@ -21,6 +21,7 @@ import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.PendingIntent.CanceledException;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
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!");
|
||||
}
|
||||
|
||||
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} */
|
||||
protected int dispatchMessage(SmsMessageBase smsb) {
|
||||
|
||||
@@ -105,6 +123,11 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
|
||||
editor.commit();
|
||||
((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
|
||||
handled = true;
|
||||
} else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
|
||||
(SmsEnvelope.TELESERVICE_WEMT == teleService)) &&
|
||||
sms.isStatusReportMessage()) {
|
||||
handleCdmaStatusReport(sms);
|
||||
handled = true;
|
||||
} else if ((sms.getUserData() == null)) {
|
||||
if (Config.LOGD) {
|
||||
Log.d(TAG, "Received SMS without user data");
|
||||
@@ -354,8 +377,12 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
|
||||
uData.payloadStr = parts.get(i);
|
||||
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,
|
||||
uData, deliveryIntent != null);
|
||||
uData, (deliveryIntent != null) && (i == (msgCount - 1)));
|
||||
|
||||
sendSubmitPdu(submitPdu, sentIntent, deliveryIntent);
|
||||
}
|
||||
|
||||
@@ -424,12 +424,9 @@ public class SmsMessage extends SmsMessageBase {
|
||||
return (status << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This function is a GSM specific functionality which is not supported in CDMA mode.
|
||||
*/
|
||||
/** Return true iff the bearer data message type is DELIVERY_ACK. */
|
||||
public boolean isStatusReportMessage() {
|
||||
Log.w(LOG_TAG, "isStatusReportMessage: is not supported in CDMA mode.");
|
||||
return false;
|
||||
return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -548,17 +545,6 @@ public class SmsMessage extends SmsMessageBase {
|
||||
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) {
|
||||
originatingAddress.address = new String(originatingAddress.origBytes);
|
||||
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);
|
||||
|
||||
// TODO(Teleca): do we really want this test to occur only for DELIVERY_ACKs?
|
||||
if ((mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) &&
|
||||
(mBearerData.errorClass != BearerData.ERROR_UNDEFINED)) {
|
||||
status = mBearerData.errorClass << 8;
|
||||
status |= mBearerData.messageStatus;
|
||||
// Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
|
||||
if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) {
|
||||
// The BearerData MsgStatus subparameter should only be
|
||||
// included for DELIVERY_ACK messages. If it occurred for
|
||||
// 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) {
|
||||
|
||||
Reference in New Issue
Block a user