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;
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) {
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");
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);
}
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);
}
/**
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: "
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) {