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;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user