Merge change 22886 into eclair

* changes:
  Move SMS pdu creation fully into the central Phone process.
This commit is contained in:
Android (Google) Code Review
2009-08-31 22:39:22 -07:00
11 changed files with 277 additions and 119 deletions

View File

@@ -81,9 +81,14 @@ public final class SmsManager {
throw new IllegalArgumentException("Invalid message body"); throw new IllegalArgumentException("Invalid message body");
} }
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu( try {
scAddress, destinationAddress, text, (deliveryIntent != null)); ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent); 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"); 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 { try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) { if (iccISms != null) {
iccISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF,
data, sentIntent, deliveryIntent);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it

View File

@@ -350,6 +350,25 @@ public class SmsMessage {
return calculateLength((CharSequence)messageBody, use7bitOnly); 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 * Get an SMS-SUBMIT PDU for a destination address and a message
* *

View File

@@ -67,24 +67,56 @@ interface ISms {
boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc); 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 * @param smsc the SMSC to send the message through, or NULL for the
* default SMSC * default SMSC
* @param pdu the raw PDU to send * @param data the body of the message to send
* @param sentIntent if not NULL this <code>Intent</code> is * @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is successfully sent, or failed. * broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success, * The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors: * or one of these errors:<br>
* <code>RESULT_ERROR_GENERIC_FAILURE</code> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
* <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_RADIO_OFF</code><br>
* <code>RESULT_ERROR_NULL_PDU</code>. * <code>RESULT_ERROR_NULL_PDU</code><br>
* @param deliveryIntent if not NULL this <code>Intent</code> is * 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 * broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu"). * raw pdu of the status report is in the extended data ("pdu").
*/ */
void sendRawPdu(in byte[] smsc, in byte[] pdu, in PendingIntent sentIntent, void sendData(in String destAddr, in String scAddr, in int destPort,
in PendingIntent deliveryIntent); 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. * Send a multi-part text based SMS.

View File

@@ -20,6 +20,8 @@ import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import com.android.internal.util.HexDump;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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 * @param destAddr the address to send the message to
* defatult SMSC * @param scAddr is the service center address or null to use
* @param pdu the raw PDU to send * the current default SMSC
* @param sentIntent if not NULL this <code>Intent</code> is * @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. * broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success, * The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors: * or one of these errors:<br>
* <code>RESULT_ERROR_GENERIC_FAILURE</code> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
* <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_RADIO_OFF</code><br>
* <code>RESULT_ERROR_NULL_PDU</code>. * <code>RESULT_ERROR_NULL_PDU</code><br>
* @param deliveryIntent if not NULL this <code>Intent</code> is * 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 * broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu"). * raw pdu of the status report is in the extended data ("pdu").
*/ */
public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, public void sendData(String destAddr, String scAddr, int destPort,
PendingIntent deliveryIntent) { byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
Context context = mPhone.getContext(); mPhone.getContext().enforceCallingPermission(
context.enforceCallingPermission(
"android.permission.SEND_SMS", "android.permission.SEND_SMS",
"Sending SMS message"); "Sending SMS message");
if (DBG) log("sendRawPdu: smsc=" + smsc + if (DBG) log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
" pdu="+ pdu + " sentIntent" + sentIntent + destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" +
" deliveryIntent" + deliveryIntent); sentIntent + " deliveryIntent=" + deliveryIntent);
mDispatcher.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, 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").
*/
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("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. * Send a multi-part text based SMS.
* *
* @param destinationAddress the address to send the message to * @param destAddr the address to send the message to
* @param scAddress is the service center address or null to use * @param scAddr is the service center address or null to use
* the current default SMSC * the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order, * @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message * comprise the original message
@@ -94,21 +137,22 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub {
* <code>RESULT_ERROR_GENERIC_FAILURE</code> * <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</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 * @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is * <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered * broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the * to the recipient. The raw pdu of the status report is in the
* extended data ("pdu"). * 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) { List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
Context context = mPhone.getContext(); mPhone.getContext().enforceCallingPermission(
context.enforceCallingPermission(
"android.permission.SEND_SMS", "android.permission.SEND_SMS",
"Sending SMS message"); "Sending SMS message");
if (DBG) log("sendMultipartText"); if (DBG) log("sendMultipartText");
mDispatcher.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts, mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
(ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents); (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
} }
@@ -163,4 +207,3 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub {
protected abstract void log(String msg); protected abstract void log(String msg);
} }

View File

@@ -50,16 +50,21 @@ public class IccSmsInterfaceManagerProxy extends ISms.Stub {
return mIccSmsInterfaceManager.getAllMessagesFromIccEf(); return mIccSmsInterfaceManager.getAllMessagesFromIccEf();
} }
public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, public void sendData(String destAddr, String scAddr, int destPort,
PendingIntent deliveryIntent) throws android.os.RemoteException { byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
mIccSmsInterfaceManager.sendRawPdu(smsc, pdu, sentIntent, mIccSmsInterfaceManager.sendData(destAddr, scAddr, destPort, data,
deliveryIntent); 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<String> parts, List<PendingIntent> sentIntents,
List<PendingIntent> deliveryIntents) throws android.os.RemoteException { List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
mIccSmsInterfaceManager.sendMultipartText(destinationAddress, scAddress, mIccSmsInterfaceManager.sendMultipartText(destAddr, scAddr,
parts, sentIntents, deliveryIntents); parts, sentIntents, deliveryIntents);
} }

View File

@@ -635,12 +635,66 @@ public abstract class SMSDispatcher extends Handler {
dispatch(intent, "android.permission.RECEIVE_SMS"); 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. * Send a multi-part text based SMS.
* *
* @param destinationAddress the address to send the message to * @param destAddr the address to send the message to
* @param scAddress is the service center address or null to use * @param scAddr is the service center address or null to use
* the current default SMSC * the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order, * @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message * 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 * to the recipient. The raw pdu of the status report is in the
* extended data ("pdu"). * 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<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents); ArrayList<PendingIntent> deliveryIntents);

View File

@@ -130,4 +130,10 @@ public interface TelephonyProperties
* The number of milli-seconds between CALL_RING notifications. * The number of milli-seconds between CALL_RING notifications.
*/ */
static final String PROPERTY_CALL_RING_DELAY = "ro.telephony.call_ring.delay"; 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";
} }

View File

@@ -285,6 +285,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} */ /** {@inheritDoc} */
protected void sendMultipartText(String destAddr, String scAddr, protected void sendMultipartText(String destAddr, String scAddr,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
@@ -329,16 +345,9 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
} }
} }
protected void sendSubmitPdu(SmsMessage.SubmitPdu submitPdu, PendingIntent sentIntent, protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu,
PendingIntent deliveryIntent) { PendingIntent sentIntent, PendingIntent deliveryIntent) {
sendRawPdu(submitPdu.encodedScAddress, submitPdu.encodedMessage, if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) {
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)) {
if (sentIntent != null) { if (sentIntent != null) {
try { try {
sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
@@ -349,8 +358,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
} }
return; return;
} }
sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@@ -17,6 +17,7 @@
package com.android.internal.telephony.cdma; package com.android.internal.telephony.cdma;
import android.os.Parcel; import android.os.Parcel;
import android.os.SystemProperties;
import android.text.format.Time; import android.text.format.Time;
import android.util.Config; import android.util.Config;
import android.util.Log; 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.IccUtils;
import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase; 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.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
import com.android.internal.telephony.cdma.sms.SmsEnvelope; import com.android.internal.telephony.cdma.sms.SmsEnvelope;
@@ -38,7 +40,6 @@ import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Random;
/** /**
* TODO(cleanup): these constants are disturbing... are they not just * TODO(cleanup): these constants are disturbing... are they not just
@@ -78,14 +79,6 @@ public class SmsMessage extends SmsMessageBase {
*/ */
private int status; 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 */ /** 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_NO_ACK = 0;
private static final int RETURN_ACK = 1; private static final int RETURN_ACK = 1;
@@ -331,7 +324,7 @@ public class SmsMessage extends SmsMessageBase {
* address, if applicable, and the encoded message. * address, if applicable, and the encoded message.
* Returns null on encode error. * 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) { byte[] data, boolean statusReportRequested) {
/** /**
@@ -605,18 +598,28 @@ public class SmsMessage extends SmsMessageBase {
} }
/** /**
* Set the nextMessageId to a random value between 0 and 65536 * Calculate the next message id, starting at 0 and iteratively
* See C.S0015-B, v2.0, 4.3.1.5 * 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() { private synchronized static int getNextMessageId() {
// Message ID, modulo 65536 // The only (meaningful) way this code can be called is via
if(firstSMS) { // binder-call into the Phone process. All other calls will
Random generator = new Random(); // assumedly not be as with UID radio, and hence will be
nextMessageId = generator.nextInt(65536); // unable to modify the system property. Synchronization has
firstSMS = false; // thus been added to this function conservatively -- if it
} else { // can be conclusively reasoned to be unnecessary, it should
nextMessageId = ++nextMessageId & 0xFFFF; // 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 bearerData = new BearerData();
bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
if (userData != null) setNextMessageId(); bearerData.messageId = getNextMessageId();
bearerData.messageId = nextMessageId;
bearerData.deliveryAckReq = statusReportRequested; bearerData.deliveryAckReq = statusReportRequested;
bearerData.userAckReq = false; bearerData.userAckReq = false;

View File

@@ -136,6 +136,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} */ /** {@inheritDoc} */
protected void sendMultipartText(String destinationAddress, String scAddress, protected void sendMultipartText(String destinationAddress, String scAddress,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,

View File

@@ -337,7 +337,7 @@ public class SmsMessage extends SmsMessageBase{
* Returns null on encode error. * Returns null on encode error.
*/ */
public static SubmitPdu getSubmitPdu(String scAddress, public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, short destinationPort, byte[] data, String destinationAddress, int destinationPort, byte[] data,
boolean statusReportRequested) { boolean statusReportRequested) {
SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();