diff options
11 files changed, 276 insertions, 118 deletions
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 14b1563..80de074 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -81,9 +81,14 @@ public final class SmsManager { throw new IllegalArgumentException("Invalid message body"); } - SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu( - scAddress, destinationAddress, text, (deliveryIntent != null)); - sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent); + try { + ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); + if (iccISms != null) { + iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); + } + } catch (RemoteException ex) { + // ignore it + } } /** @@ -202,43 +207,11 @@ public final class SmsManager { throw new IllegalArgumentException("Invalid message data"); } - SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu( - scAddress, destinationAddress, - destinationPort, data, (deliveryIntent != null)); - sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent); - } - - /** - * Send a raw SMS PDU. - * A PDU is a protocol data unit. It contains the message and the - * associated meta information. - * - * @param smsc the SMSC to send the message through, or NULL for the - * default SMSC - * @param pdu the raw PDU to send - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) { try { ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); if (iccISms != null) { - iccISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); + iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF, + data, sentIntent, deliveryIntent); } } catch (RemoteException ex) { // ignore it diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index 056eee2..7a10512 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -350,6 +350,25 @@ public class SmsMessage { return calculateLength((CharSequence)messageBody, use7bitOnly); } + /* + * TODO(cleanup): It looks like there is now no useful reason why + * apps should generate pdus themselves using these routines, + * instead of handing the raw data to SMSDispatcher (and thereby + * have the phone process do the encoding). Moreover, CDMA now + * has shared state (in the form of the msgId system property) + * which can only be modified by the phone process, and hence + * makes the output of these routines incorrect. Since they now + * serve no purpose, they should probably just return null + * directly, and be deprecated. Going further in that direction, + * the above parsers of serialized pdu data should probably also + * be gotten rid of, hiding all but the necessarily visible + * structured data from client apps. A possible concern with + * doing this is that apps may be using these routines to generate + * pdus that are then sent elsewhere, some network server, for + * example, and that always returning null would thereby break + * otherwise useful apps. + */ + /** * Get an SMS-SUBMIT PDU for a destination address and a message * diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index 257f1e6..65bad96 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -67,24 +67,56 @@ interface ISms { boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc); /** - * Send a SMS + * Send a data SMS. * * @param smsc the SMSC to send the message through, or NULL for the * default SMSC - * @param pdu the raw PDU to send - * @param sentIntent if not NULL this <code>Intent</code> is - * broadcast when the message is successfully sent, or failed. + * @param data the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntent if not NULL this <code>Intent</code> is + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applicaitons, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is delivered to the recipient. The * raw pdu of the status report is in the extended data ("pdu"). */ - void sendRawPdu(in byte[] smsc, in byte[] pdu, in PendingIntent sentIntent, - in PendingIntent deliveryIntent); + void sendData(in String destAddr, in String scAddr, in int destPort, + in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent); + + /** + * Send an SMS. + * + * @param smsc the SMSC to send the message through, or NULL for the + * default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + */ + void sendText(in String destAddr, in String scAddr, in String text, + in PendingIntent sentIntent, in PendingIntent deliveryIntent); /** * Send a multi-part text based SMS. diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java index 620f2de..2cb0041 100644 --- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java @@ -20,6 +20,8 @@ import android.app.PendingIntent; import android.content.Context; import android.util.Log; +import com.android.internal.util.HexDump; + import java.util.ArrayList; import java.util.List; @@ -49,40 +51,81 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { } /** - * Send a Raw PDU SMS + * Send a data based SMS to a specific application port. * - * @param smsc the SMSC to send the message through, or NULL for the - * defatult SMSC - * @param pdu the raw PDU to send - * @param sentIntent if not NULL this <code>Intent</code> is + * @param destAddr the address to send the message to + * @param scAddr is the service center address or null to use + * the current default SMSC + * @param destPort the port to deliver the message to + * @param data the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is sucessfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntent if not NULL this <code>Intent</code> is + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applicaitons, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is delivered to the recipient. The * raw pdu of the status report is in the extended data ("pdu"). */ - public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - Context context = mPhone.getContext(); + public void sendData(String destAddr, String scAddr, int destPort, + byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { + mPhone.getContext().enforceCallingPermission( + "android.permission.SEND_SMS", + "Sending SMS message"); + if (DBG) log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + + destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" + + sentIntent + " deliveryIntent=" + deliveryIntent); + mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); + } - context.enforceCallingPermission( + /** + * Send a text based SMS. + * + * @param destAddr the address to send the message to + * @param scAddr is the service center address or null to use + * the current default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + */ + public void sendText(String destAddr, String scAddr, + String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { + mPhone.getContext().enforceCallingPermission( "android.permission.SEND_SMS", "Sending SMS message"); - if (DBG) log("sendRawPdu: smsc=" + smsc + - " pdu="+ pdu + " sentIntent" + sentIntent + - " deliveryIntent" + deliveryIntent); - mDispatcher.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); + if (DBG) log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr + + " text='"+ text + "' sentIntent=" + + sentIntent + " deliveryIntent=" + deliveryIntent); + mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); } /** * Send a multi-part text based SMS. * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use + * @param destAddr the address to send the message to + * @param scAddr is the service center address or null to use * the current default SMSC * @param parts an <code>ArrayList</code> of strings that, in order, * comprise the original message @@ -94,21 +137,22 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * <code>RESULT_ERROR_GENERIC_FAILURE</code> * <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_NULL_PDU</code>. + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applicaitons, + * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntents if not null, an <code>ArrayList</code> of * <code>PendingIntent</code>s (one for each message part) that is * broadcast when the corresponding message part has been delivered * to the recipient. The raw pdu of the status report is in the * extended data ("pdu"). */ - public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts, + public void sendMultipartText(String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { - Context context = mPhone.getContext(); - - context.enforceCallingPermission( + mPhone.getContext().enforceCallingPermission( "android.permission.SEND_SMS", "Sending SMS message"); if (DBG) log("sendMultipartText"); - mDispatcher.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts, + mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts, (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents); } @@ -163,4 +207,3 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { protected abstract void log(String msg); } - diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java index a51d074..1910a9c 100644 --- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java +++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java @@ -50,16 +50,21 @@ public class IccSmsInterfaceManagerProxy extends ISms.Stub { return mIccSmsInterfaceManager.getAllMessagesFromIccEf(); } - public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) throws android.os.RemoteException { - mIccSmsInterfaceManager.sendRawPdu(smsc, pdu, sentIntent, - deliveryIntent); + public void sendData(String destAddr, String scAddr, int destPort, + byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { + mIccSmsInterfaceManager.sendData(destAddr, scAddr, destPort, data, + sentIntent, deliveryIntent); } - public void sendMultipartText(String destinationAddress, String scAddress, + public void sendText(String destAddr, String scAddr, + String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { + mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); + } + + public void sendMultipartText(String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) throws android.os.RemoteException { - mIccSmsInterfaceManager.sendMultipartText(destinationAddress, scAddress, + mIccSmsInterfaceManager.sendMultipartText(destAddr, scAddr, parts, sentIntents, deliveryIntents); } diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index bbfc6c9..7efaa2e 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -635,12 +635,66 @@ public abstract class SMSDispatcher extends Handler { dispatch(intent, "android.permission.RECEIVE_SMS"); } + /** + * Send a data based SMS to a specific application port. + * + * @param destAddr the address to send the message to + * @param scAddr is the service center address or null to use + * the current default SMSC + * @param destPort the port to deliver the message to + * @param data the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applicaitons, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + */ + protected abstract void sendData(String destAddr, String scAddr, int destPort, + byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent); + + /** + * Send a text based SMS. + * + * @param destAddr the address to send the message to + * @param scAddr is the service center address or null to use + * the current default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + */ + protected abstract void sendText(String destAddr, String scAddr, + String text, PendingIntent sentIntent, PendingIntent deliveryIntent); /** * Send a multi-part text based SMS. * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use + * @param destAddr the address to send the message to + * @param scAddr is the service center address or null to use * the current default SMSC * @param parts an <code>ArrayList</code> of strings that, in order, * comprise the original message @@ -661,7 +715,7 @@ public abstract class SMSDispatcher extends Handler { * to the recipient. The raw pdu of the status report is in the * extended data ("pdu"). */ - protected abstract void sendMultipartText(String destinationAddress, String scAddress, + protected abstract void sendMultipartText(String destAddr, String scAddr, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents); diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index de5bbc1..55ba149 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -130,4 +130,10 @@ public interface TelephonyProperties * The number of milli-seconds between CALL_RING notifications. */ static final String PROPERTY_CALL_RING_DELAY = "ro.telephony.call_ring.delay"; + + /** + * Track CDMA SMS message id numbers to ensure they increment + * monotonically, regardless of reboots. + */ + static final String PROPERTY_CDMA_MSG_ID = "persist.radio.cdma.msgid"; } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index 88cccd3..ca15a03 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -286,6 +286,22 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } /** {@inheritDoc} */ + protected void sendData(String destAddr, String scAddr, int destPort, + byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { + SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( + scAddr, destAddr, destPort, data, (deliveryIntent != null)); + sendSubmitPdu(pdu, sentIntent, deliveryIntent); + } + + /** {@inheritDoc} */ + protected void sendText(String destAddr, String scAddr, String text, + PendingIntent sentIntent, PendingIntent deliveryIntent) { + SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( + scAddr, destAddr, text, (deliveryIntent != null), null); + sendSubmitPdu(pdu, sentIntent, deliveryIntent); + } + + /** {@inheritDoc} */ protected void sendMultipartText(String destAddr, String scAddr, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { @@ -329,16 +345,9 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } } - protected void sendSubmitPdu(SmsMessage.SubmitPdu submitPdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - sendRawPdu(submitPdu.encodedScAddress, submitPdu.encodedMessage, - sentIntent, deliveryIntent); - } - - protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - String inEcm = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE); - if (Boolean.parseBoolean(inEcm)) { + protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu, + PendingIntent sentIntent, PendingIntent deliveryIntent) { + if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) { if (sentIntent != null) { try { sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); @@ -349,8 +358,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } return; } - - super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); + sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); } /** {@inheritDoc} */ diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 1597427..2c20784 100755 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -17,6 +17,7 @@ package com.android.internal.telephony.cdma; import android.os.Parcel; +import android.os.SystemProperties; import android.text.format.Time; import android.util.Config; import android.util.Log; @@ -25,6 +26,7 @@ import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.IccUtils; import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; +import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.cdma.sms.BearerData; import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; import com.android.internal.telephony.cdma.sms.SmsEnvelope; @@ -38,7 +40,6 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.util.Random; /** * TODO(cleanup): these constants are disturbing... are they not just @@ -78,14 +79,6 @@ public class SmsMessage extends SmsMessageBase { */ private int status; - /** The next message ID for the BearerData. Shall be a random value on first use. - * (See C.S0015-B, v2.0, 4.3.1.5) - */ - private static int nextMessageId = 0; - - /** Specifies if this is the first SMS message submit */ - private static boolean firstSMS = true; - /** Specifies if a return of an acknowledgment is requested for send SMS */ private static final int RETURN_NO_ACK = 0; private static final int RETURN_ACK = 1; @@ -331,7 +324,7 @@ public class SmsMessage extends SmsMessageBase { * address, if applicable, and the encoded message. * Returns null on encode error. */ - public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, short destPort, + public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort, byte[] data, boolean statusReportRequested) { /** @@ -605,18 +598,28 @@ public class SmsMessage extends SmsMessageBase { } /** - * Set the nextMessageId to a random value between 0 and 65536 - * See C.S0015-B, v2.0, 4.3.1.5 + * Calculate the next message id, starting at 0 and iteratively + * incrementing within the range 0..65535 remembering the state + * via a persistent system property. (See C.S0015-B, v2.0, + * 4.3.1.5) */ - private static void setNextMessageId() { - // Message ID, modulo 65536 - if(firstSMS) { - Random generator = new Random(); - nextMessageId = generator.nextInt(65536); - firstSMS = false; - } else { - nextMessageId = ++nextMessageId & 0xFFFF; + private synchronized static int getNextMessageId() { + // The only (meaningful) way this code can be called is via + // binder-call into the Phone process. All other calls will + // assumedly not be as with UID radio, and hence will be + // unable to modify the system property. Synchronization has + // thus been added to this function conservatively -- if it + // can be conclusively reasoned to be unnecessary, it should + // be removed. + int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 0); + String nextMsgId = Integer.toString((msgId + 1) & 0xFFFF); + SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId); + if (DBG_SMS) { + Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId); + Log.d(LOG_TAG, "readback gets " + + SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID)); } + return msgId; } /** @@ -642,8 +645,7 @@ public class SmsMessage extends SmsMessageBase { BearerData bearerData = new BearerData(); bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; - if (userData != null) setNextMessageId(); - bearerData.messageId = nextMessageId; + bearerData.messageId = getNextMessageId(); bearerData.deliveryAckReq = statusReportRequested; bearerData.userAckReq = false; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index 2770ddc..b412fec 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -137,6 +137,22 @@ final class GsmSMSDispatcher extends SMSDispatcher { } /** {@inheritDoc} */ + protected void sendData(String destAddr, String scAddr, int destPort, + byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { + SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( + scAddr, destAddr, destPort, data, (deliveryIntent != null)); + sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); + } + + /** {@inheritDoc} */ + protected void sendText(String destAddr, String scAddr, String text, + PendingIntent sentIntent, PendingIntent deliveryIntent) { + SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( + scAddr, destAddr, text, (deliveryIntent != null)); + sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); + } + + /** {@inheritDoc} */ protected void sendMultipartText(String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 93721ff..569cf25 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -337,7 +337,7 @@ public class SmsMessage extends SmsMessageBase{ * Returns null on encode error. */ public static SubmitPdu getSubmitPdu(String scAddress, - String destinationAddress, short destinationPort, byte[] data, + String destinationAddress, int destinationPort, byte[] data, boolean statusReportRequested) { SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); |