summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
authorTammo Spalink <tammo@google.com>2009-08-25 15:51:32 +0800
committerTammo Spalink <tammo@google.com>2009-09-01 13:37:03 +0800
commit1f952a178db86559ff4bab79c4a9b5fae18096bf (patch)
treea266554459aba5412e3f176790f541b6a9d61bed /telephony
parentce54003aa8961764763c4045991b730974fa9083 (diff)
downloadframeworks_base-1f952a178db86559ff4bab79c4a9b5fae18096bf.zip
frameworks_base-1f952a178db86559ff4bab79c4a9b5fae18096bf.tar.gz
frameworks_base-1f952a178db86559ff4bab79c4a9b5fae18096bf.tar.bz2
Move SMS pdu creation fully into the central Phone process.
Previously pdu creation was haphazardly done sometimes by the app and sometimes centrally by the phone process -- specifically the phone process did creation for multipart texts. This change gets rid of the previous IPC interface for sending raw pdus to SMSDispatch in the phone process, and instead makes everything work like multipart messages worked before, namely the structured data is passed and pdu encoding done centrally. The motivation for this was the need to ensure that CDMA message id numbers were strictly monotonic, including across reboots, which necessitated central state in the form of a system property, which could in turn only be modified by the phone process. Hence, this (in part) addresses issue: http://buganizer/issue?id=2075760 Change-Id: I94ca207b6e657c465e8472534704db8646ee277c
Diffstat (limited to 'telephony')
-rw-r--r--telephony/java/android/telephony/SmsManager.java47
-rw-r--r--telephony/java/android/telephony/SmsMessage.java19
-rw-r--r--telephony/java/com/android/internal/telephony/ISms.aidl54
-rw-r--r--telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java95
-rw-r--r--telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java17
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java60
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java6
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java32
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/SmsMessage.java46
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java16
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java2
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();