From 9d34319f1ce5be4124a0b6293162587f4573496f Mon Sep 17 00:00:00 2001 From: Christian Gustafsson Date: Tue, 15 Sep 2009 19:09:13 -0500 Subject: [PATCH] CDMA Check for network duplicate sms In some cases a sms acknowledgement might be lost. The network will then resend the same sms. These duplicate sms should be acknowledged but not shown to the user. C.S0015-B 4.3.1.6 Unique Message Identification. The fields used to identify a message are: * Message Identifier, * Originating Address, * Originating Subaddress, and * Message Center Time Stamp. Since some of the fields are optional, the Teleservice Layer shall use as many of the fields as are present in the SMS message to determine message uniqueness. Mobile stations should discard repeated messages. 1. Add a fingerprint function to SmsMessage.java. This returns a byte array to be used as a unique identifier. Parts that make up the identifier are the originating address, teleservice id and the bearerdata. Using all of the bearerdata saves parsing time. There are no random bits allowed in the standard. This makes binary comparison possible. Using all of the bearerdata accounts for the message id, smsc timestamp and "... shall use as many of the fields as are present in the SMS message". 2. Have CdmaSMSDispatcher.dispatchMessage() pull a fingerprint and check if it matches the last acknowledged fingerprint. When it matches return and signal that message was handled. 3. Have CdmaSMSDispatcher.acknowledgeLastIncomingSms() take the last dispatched fingerprint move it to the last acknowledged fingerprint. Only do this if processing of the sms was successful. Change-Id: If79f8fe40896cd290940b7ccd5a17531ab937b60 --- .../telephony/cdma/CdmaSMSDispatcher.java | 20 +++++++++++++++++-- .../internal/telephony/cdma/SmsMessage.java | 15 ++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index 386dc3d468994..730dc49a4f029 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -48,6 +48,7 @@ import com.android.internal.util.HexDump; import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.lang.Boolean; @@ -57,6 +58,9 @@ final class CdmaSMSDispatcher extends SMSDispatcher { private CDMAPhone mCdmaPhone; + private byte[] mLastDispatchedSmsFingerprint; + private byte[] mLastAcknowledgedSmsFingerprint; + CdmaSMSDispatcher(CDMAPhone phone) { super(phone); mCdmaPhone = phone; @@ -104,8 +108,14 @@ final class CdmaSMSDispatcher extends SMSDispatcher { return Intents.RESULT_SMS_GENERIC_ERROR; } - // Decode BD stream and set sms variables. + // See if we have a network duplicate SMS. SmsMessage sms = (SmsMessage) smsb; + mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); + if (mLastAcknowledgedSmsFingerprint != null && + Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { + return Intents.RESULT_SMS_HANDLED; + } + // Decode BD stream and set sms variables. sms.parseSms(); int teleService = sms.getTeleService(); boolean handled = false; @@ -433,7 +443,13 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } if (mCm != null) { - mCm.acknowledgeLastIncomingCdmaSms(success, resultToCause(result), response); + int causeCode = resultToCause(result); + mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response); + + if (causeCode == 0) { + mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; + } + mLastDispatchedSmsFingerprint = null; } } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 266d1270cfd86..3e491d1442dcf 100755 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -794,5 +794,20 @@ public class SmsMessage extends SmsMessageBase { return mBearerData.numberOfMessages; } + /** + * Returns a byte array that can be use to uniquely identify a received SMS message. + * C.S0015-B 4.3.1.6 Unique Message Identification. + * + * @return byte array uniquely identifying the message. + * @hide + */ + /* package */ byte[] getIncomingSmsFingerprint() { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + output.write(mEnvelope.teleService); + output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length); + output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length); + + return output.toByteArray(); + } }