Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d304ae58 authored by Tammo Spalink's avatar Tammo Spalink
Browse files

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
parent f84a2182
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -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);
        }
+22 −21
Original line number Diff line number Diff line
@@ -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,12 +557,27 @@ 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)) {
        // 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) {
            if (Config.LOGV) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'");