Merge "New system API to create SMS PDU and expose copyMessageToIcc()"
am: ca45896352
Change-Id: I0a71827058f5ef75e164135516c6228649cfe072
This commit is contained in:
@@ -9182,6 +9182,7 @@ package android.telephony {
|
||||
}
|
||||
|
||||
public final class SmsManager {
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean copyMessageToIcc(@Nullable byte[], @NonNull byte[], int);
|
||||
method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int);
|
||||
method public boolean disableCellBroadcastRange(int, int, int);
|
||||
method public boolean enableCellBroadcastRange(int, int, int);
|
||||
@@ -9193,6 +9194,7 @@ package android.telephony {
|
||||
|
||||
public class SmsMessage {
|
||||
method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean);
|
||||
method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, int, int, int, int, int);
|
||||
}
|
||||
|
||||
|
||||
@@ -1577,7 +1577,7 @@ public final class SmsManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a raw SMS PDU to the ICC.
|
||||
* Copies a raw SMS PDU to the ICC.
|
||||
* ICC (Integrated Circuit Card) is the card of the device.
|
||||
* For example, this can be the SIM or USIM for GSM.
|
||||
*
|
||||
@@ -1591,21 +1591,26 @@ public final class SmsManager {
|
||||
* operation is performed on the correct subscription.
|
||||
* </p>
|
||||
*
|
||||
* @param smsc the SMSC for this message, or NULL for the default SMSC
|
||||
* @param pdu the raw PDU to store
|
||||
* @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
|
||||
* STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
|
||||
* @return true for success
|
||||
* @param smsc the SMSC for this messag or null for the default SMSC.
|
||||
* @param pdu the raw PDU to store.
|
||||
* @param status message status. One of these status:
|
||||
* <code>STATUS_ON_ICC_READ</code>
|
||||
* <code>STATUS_ON_ICC_UNREAD</code>
|
||||
* <code>STATUS_ON_ICC_SENT</code>
|
||||
* <code>STATUS_ON_ICC_UNSENT</code>
|
||||
* @return true for success. Otherwise false.
|
||||
*
|
||||
* @throws IllegalArgumentException if pdu is NULL
|
||||
* {@hide}
|
||||
* @throws IllegalArgumentException if pdu is null.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public boolean copyMessageToIcc(byte[] smsc, byte[] pdu,int status) {
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
|
||||
public boolean copyMessageToIcc(
|
||||
@Nullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status) {
|
||||
boolean success = false;
|
||||
|
||||
if (null == pdu) {
|
||||
throw new IllegalArgumentException("pdu is NULL");
|
||||
if (pdu == null) {
|
||||
throw new IllegalArgumentException("pdu is null");
|
||||
}
|
||||
try {
|
||||
ISms iSms = getISmsService();
|
||||
@@ -2035,6 +2040,17 @@ public final class SmsManager {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "STATUS_ON_ICC_" }, value = {
|
||||
STATUS_ON_ICC_FREE,
|
||||
STATUS_ON_ICC_READ,
|
||||
STATUS_ON_ICC_UNREAD,
|
||||
STATUS_ON_ICC_SENT,
|
||||
STATUS_ON_ICC_UNSENT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StatusOnIcc {}
|
||||
|
||||
// see SmsMessage.getStatusOnIcc
|
||||
|
||||
/** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
|
||||
|
||||
@@ -585,13 +585,15 @@ public class SmsMessage {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message.
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
* This method will not attempt to use any GSM national language 7 bit encodings.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
*/
|
||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||
String destinationAddress, String message, boolean statusReportRequested) {
|
||||
@@ -604,17 +606,16 @@ public class SmsMessage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message.
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
* This method will not attempt to use any GSM national language 7 bit encodings.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message String representation of the message payload.
|
||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
||||
* @param subId Subscription of the message
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @param subId subscription of the message.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||
@@ -632,17 +633,16 @@ public class SmsMessage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a data message to a destination address & port.
|
||||
* Gets an SMS-SUBMIT PDU for a data message to a destination address & port.
|
||||
* This method will not attempt to use any GSM national language 7 bit encodings.
|
||||
*
|
||||
* @param scAddress Service Centre address. null == use default
|
||||
* @param destinationAddress the address of the destination for the message
|
||||
* @param destinationPort the port to deliver the message to at the
|
||||
* destination
|
||||
* @param data the data for the message
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param destinationPort the port to deliver the message to at the destination.
|
||||
* @param data the data for the message.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
*/
|
||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||
String destinationAddress, short destinationPort, byte[] data,
|
||||
@@ -660,6 +660,55 @@ public class SmsMessage {
|
||||
return new SubmitPdu(spb);
|
||||
}
|
||||
|
||||
// TODO: SubmitPdu class is used for SMS-DELIVER also now. Refactor for SubmitPdu and new
|
||||
// DeliverPdu accordingly.
|
||||
|
||||
/**
|
||||
* Gets an SMS PDU to store in the ICC.
|
||||
*
|
||||
* @param subId subscription of the message.
|
||||
* @param status message status. One of these status:
|
||||
* <code>SmsManager.STATUS_ON_ICC_READ</code>
|
||||
* <code>SmsManager.STATUS_ON_ICC_UNREAD</code>
|
||||
* <code>SmsManager.STATUS_ON_ICC_SENT</code>
|
||||
* <code>SmsManager.STATUS_ON_ICC_UNSENT</code>
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param address destination or originating address.
|
||||
* @param message string representation of the message payload.
|
||||
* @param date the time stamp the message was received.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@Nullable
|
||||
public static SubmitPdu getSmsPdu(int subId, @SmsManager.StatusOnIcc int status,
|
||||
@Nullable String scAddress, @NonNull String address, @NonNull String message,
|
||||
long date) {
|
||||
SubmitPduBase spb;
|
||||
if (isCdmaVoice(subId)) { // 3GPP2 format
|
||||
if (status == SmsManager.STATUS_ON_ICC_READ
|
||||
|| status == SmsManager.STATUS_ON_ICC_UNREAD) { // Deliver PDU
|
||||
spb = com.android.internal.telephony.cdma.SmsMessage.getDeliverPdu(address,
|
||||
message, date);
|
||||
} else { // Submit PDU
|
||||
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
|
||||
address, message, false /* statusReportRequested */, null /* smsHeader */);
|
||||
}
|
||||
} else { // 3GPP format
|
||||
if (status == SmsManager.STATUS_ON_ICC_READ
|
||||
|| status == SmsManager.STATUS_ON_ICC_UNREAD) { // Deliver PDU
|
||||
spb = com.android.internal.telephony.gsm.SmsMessage.getDeliverPdu(scAddress,
|
||||
address, message, date);
|
||||
} else { // Submit PDU
|
||||
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
|
||||
address, message, false /* statusReportRequested */, null /* header */);
|
||||
}
|
||||
}
|
||||
|
||||
return spb != null ? new SubmitPdu(spb) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU's encoded message.
|
||||
* This is used by Bluetooth MAP profile to handle long non UTF-8 SMS messages.
|
||||
|
||||
@@ -201,26 +201,16 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO(cleanup): why do getSubmitPdu methods take an scAddr input
|
||||
* and do nothing with it? GSM allows us to specify a SC (eg,
|
||||
* when responding to an SMS that explicitly requests the response
|
||||
* is sent to a specific SC), or pass null to use the default
|
||||
* value. Is there no similar notion in CDMA? Or do we just not
|
||||
* have it hooked up?
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
*
|
||||
* @param scAddr Service Centre address. Null means use default.
|
||||
* @param destAddr Address of the recipient.
|
||||
* @param message String representation of the message payload.
|
||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
||||
* @param smsHeader Array containing the data for the User Data Header, preceded
|
||||
* by the Element Identifiers.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddr Service Centre address. No use for this message.
|
||||
* @param destAddr the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @param smsHeader array containing the data for the User Data Header, preceded by the Element
|
||||
* Identifiers.
|
||||
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||
* null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@@ -230,18 +220,17 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
*
|
||||
* @param scAddr Service Centre address. Null means use default.
|
||||
* @param destAddr Address of the recipient.
|
||||
* @param message String representation of the message payload.
|
||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
||||
* @param smsHeader Array containing the data for the User Data Header, preceded
|
||||
* by the Element Identifiers.
|
||||
* @param priority Priority level of the message
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddr Service Centre address. No use for this message.
|
||||
* @param destAddr the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @param smsHeader array containing the data for the User Data Header, preceded by the Element
|
||||
* Identifiers.
|
||||
* @param priority priority level of the message.
|
||||
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||
* null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@@ -264,16 +253,15 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a data message to a destination address and port.
|
||||
* Gets an SMS-SUBMIT PDU for a data message to a destination address & port.
|
||||
*
|
||||
* @param scAddr Service Centre address. null == use default
|
||||
* @param destAddr the address of the destination for the message
|
||||
* @param destPort the port to deliver the message to at the
|
||||
* destination
|
||||
* @param data the data for the message
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddr Service Centre address. No use for this message.
|
||||
* @param destAddr the address of the destination for the message.
|
||||
* @param destPort the port to deliver the message to at the destination.
|
||||
* @param data the data for the message.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||
* null on encode error.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort,
|
||||
@@ -304,14 +292,13 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a data message to a destination address & port
|
||||
* Gets an SMS-SUBMIT PDU for a data message to a destination address & port.
|
||||
*
|
||||
* @param destAddr the address of the destination for the message
|
||||
* @param userData the data for the message
|
||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param destAddr the address of the destination for the message.
|
||||
* @param userData the data for the message.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||
* null on encode error.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
|
||||
@@ -320,15 +307,14 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a data message to a destination address & port
|
||||
* Gets an SMS-SUBMIT PDU for a data message to a destination address & port.
|
||||
*
|
||||
* @param destAddr the address of the destination for the message
|
||||
* @param userData the data for the message
|
||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
||||
* @param priority Priority level of the message
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param destAddr the address of the destination for the message.
|
||||
* @param userData the data for the message.
|
||||
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||
* @param priority Priority level of the message.
|
||||
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||
* null on encode error.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
|
||||
@@ -1057,6 +1043,72 @@ public class SmsMessage extends SmsMessageBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an SMS-DELIVER PDU for a originating address and a message.
|
||||
*
|
||||
* @param origAddr the address of the originating for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param date the time stamp the message was received.
|
||||
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||
* null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
public static SubmitPdu getDeliverPdu(String origAddr, String message, long date) {
|
||||
if (origAddr == null || message == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CdmaSmsAddress addr = CdmaSmsAddress.parse(origAddr);
|
||||
if (addr == null) return null;
|
||||
|
||||
BearerData bearerData = new BearerData();
|
||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
||||
|
||||
bearerData.messageId = 0;
|
||||
|
||||
bearerData.deliveryAckReq = false;
|
||||
bearerData.userAckReq = false;
|
||||
bearerData.readAckReq = false;
|
||||
bearerData.reportReq = false;
|
||||
|
||||
bearerData.userData = new UserData();
|
||||
bearerData.userData.payloadStr = message;
|
||||
|
||||
bearerData.msgCenterTimeStamp = BearerData.TimeStamp.fromMillis(date);
|
||||
|
||||
byte[] encodedBearerData = BearerData.encode(bearerData);
|
||||
if (encodedBearerData == null) return null;
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
|
||||
DataOutputStream dos = new DataOutputStream(baos);
|
||||
dos.writeInt(SmsEnvelope.TELESERVICE_WMT);
|
||||
dos.writeInt(0); // servicePresent
|
||||
dos.writeInt(0); // serviceCategory
|
||||
dos.write(addr.digitMode);
|
||||
dos.write(addr.numberMode);
|
||||
dos.write(addr.ton); // number_type
|
||||
dos.write(addr.numberPlan);
|
||||
dos.write(addr.numberOfDigits);
|
||||
dos.write(addr.origBytes, 0, addr.origBytes.length); // digits
|
||||
// Subaddress is not supported.
|
||||
dos.write(0); // subaddressType
|
||||
dos.write(0); // subaddr_odd
|
||||
dos.write(0); // subaddr_nbr_of_digits
|
||||
dos.write(encodedBearerData.length);
|
||||
dos.write(encodedBearerData, 0, encodedBearerData.length);
|
||||
dos.close();
|
||||
|
||||
SubmitPdu pdu = new SubmitPdu();
|
||||
pdu.encodedMessage = baos.toByteArray();
|
||||
pdu.encodedScAddress = null;
|
||||
return pdu;
|
||||
} catch (IOException ex) {
|
||||
Rlog.e(LOG_TAG, "creating Deliver PDU failed: " + ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates byte array (pseudo pdu) from SMS object.
|
||||
* Note: Do not call this method more than once per object!
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.android.internal.telephony.uicc.IccUtils;
|
||||
import com.android.internal.util.BitwiseInputStream;
|
||||
import com.android.internal.util.BitwiseOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
@@ -284,6 +285,33 @@ public final class BearerData {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public static TimeStamp fromMillis(long timeInMillis) {
|
||||
TimeStamp ts = new TimeStamp();
|
||||
LocalDateTime localDateTime =
|
||||
Instant.ofEpochMilli(timeInMillis).atZone(ts.mZoneId).toLocalDateTime();
|
||||
int year = localDateTime.getYear();
|
||||
if (year < 1996 || year > 2095) return null;
|
||||
ts.year = year;
|
||||
ts.month = localDateTime.getMonthValue();
|
||||
ts.monthDay = localDateTime.getDayOfMonth();
|
||||
ts.hour = localDateTime.getHour();
|
||||
ts.minute = localDateTime.getMinute();
|
||||
ts.second = localDateTime.getSecond();
|
||||
return ts;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
int year = this.year % 100; // 00 - 99
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream(6);
|
||||
outStream.write((((year / 10) & 0x0F) << 4) | ((year % 10) & 0x0F));
|
||||
outStream.write((((month / 10) << 4) & 0xF0) | ((month % 10) & 0x0F));
|
||||
outStream.write((((monthDay / 10) << 4) & 0xF0) | ((monthDay % 10) & 0x0F));
|
||||
outStream.write((((hour / 10) << 4) & 0xF0) | ((hour % 10) & 0x0F));
|
||||
outStream.write((((minute / 10) << 4) & 0xF0) | ((minute % 10) & 0x0F));
|
||||
outStream.write((((second / 10) << 4) & 0xF0) | ((second % 10) & 0x0F));
|
||||
return outStream.toByteArray();
|
||||
}
|
||||
|
||||
public long toMillis() {
|
||||
LocalDateTime localDateTime =
|
||||
LocalDateTime.of(year, month + 1, monthDay, hour, minute, second);
|
||||
@@ -957,6 +985,12 @@ public final class BearerData {
|
||||
}
|
||||
}
|
||||
|
||||
private static void encodeMsgCenterTimeStamp(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException {
|
||||
outStream.write(8, 6);
|
||||
outStream.writeByteArray(8 * 6, bData.msgCenterTimeStamp.toByteArray());
|
||||
};
|
||||
|
||||
/**
|
||||
* Create serialized representation for BearerData object.
|
||||
* (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
|
||||
@@ -1021,6 +1055,10 @@ public final class BearerData {
|
||||
outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS);
|
||||
encodeScpResults(bData, outStream);
|
||||
}
|
||||
if (bData.msgCenterTimeStamp != null) {
|
||||
outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP);
|
||||
encodeMsgCenterTimeStamp(bData, outStream);
|
||||
}
|
||||
return outStream.toByteArray();
|
||||
} catch (BitwiseOutputStream.AccessException ex) {
|
||||
Rlog.e(LOG_TAG, "BearerData encode failed: " + ex);
|
||||
|
||||
@@ -42,8 +42,11 @@ import com.android.internal.telephony.uicc.IccUtils;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* A Short Message Service message.
|
||||
@@ -259,12 +262,15 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @param header a byte array containing the data for the User Data Header.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@@ -277,17 +283,19 @@ public class SmsMessage extends SmsMessageBase {
|
||||
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message using the
|
||||
* specified encoding.
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message using the specified encoding.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param encoding Encoding defined by constants in
|
||||
* com.android.internal.telephony.SmsConstants.ENCODING_*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @param header a byte array containing the data for the User Data Header.
|
||||
* @param encoding encoding defined by constants in
|
||||
* com.android.internal.telephony.SmsConstants.ENCODING_*
|
||||
* @param languageTable
|
||||
* @param languageShiftTable
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@@ -300,18 +308,20 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message using the
|
||||
* specified encoding.
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message using the specified encoding.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param encoding Encoding defined by constants in
|
||||
* com.android.internal.telephony.SmsConstants.ENCODING_*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @param header a byte array containing the data for the User Data Header.
|
||||
* @param encoding encoding defined by constants in
|
||||
* com.android.internal.telephony.SmsConstants.ENCODING_*
|
||||
* @param languageTable
|
||||
* @param languageShiftTable
|
||||
* @param validityPeriod Validity Period of the message in Minutes.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@@ -483,12 +493,14 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||
@@ -499,15 +511,15 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a destination address and a message
|
||||
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message
|
||||
* @param statusReportRequested staus report of the message Requested
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @param validityPeriod Validity Period of the message in Minutes.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||
@@ -518,16 +530,15 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an SMS-SUBMIT PDU for a data message to a destination address & port
|
||||
* Gets an SMS-SUBMIT PDU for a data message to a destination address & port.
|
||||
*
|
||||
* @param scAddress Service Centre address. null == use default
|
||||
* @param destinationAddress the address of the destination for the message
|
||||
* @param destinationPort the port to deliver the message to at the
|
||||
* destination
|
||||
* @param data the data for the message
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message.
|
||||
* Returns null on encode error.
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param destinationPort the port to deliver the message to at the destination.
|
||||
* @param data the data for the message.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
*/
|
||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||
String destinationAddress, int destinationPort, byte[] data,
|
||||
@@ -551,8 +562,7 @@ public class SmsMessage extends SmsMessageBase {
|
||||
|
||||
SubmitPdu ret = new SubmitPdu();
|
||||
ByteArrayOutputStream bo = getSubmitPduHead(
|
||||
scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
|
||||
// TP-UDHI = true
|
||||
scAddress, destinationAddress, (byte) 0x41, /* TP-MTI=SMS-SUBMIT, TP-UDHI=true */
|
||||
statusReportRequested, ret);
|
||||
// Skip encoding pdu if error occurs when create pdu head and the error will be handled
|
||||
// properly later on encodedMessage sanity check.
|
||||
@@ -579,16 +589,18 @@ public class SmsMessage extends SmsMessageBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the beginning of a SUBMIT PDU. This is the part of the
|
||||
* SUBMIT PDU that is common to the two versions of {@link #getSubmitPdu},
|
||||
* one of which takes a byte array and the other of which takes a
|
||||
* Creates the beginning of a SUBMIT PDU.
|
||||
*
|
||||
* This is the part of the SUBMIT PDU that is common to the two versions of
|
||||
* {@link #getSubmitPdu}, one of which takes a byte array and the other of which takes a
|
||||
* <code>String</code>.
|
||||
*
|
||||
* @param scAddress Service Centre address. null == use default
|
||||
* @param destinationAddress the address of the destination for the message
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param destinationAddress the address of the destination for the message.
|
||||
* @param mtiByte
|
||||
* @param ret <code>SubmitPdu</code> containing the encoded SC
|
||||
* address, if applicable, and the encoded message. Returns null on encode error.
|
||||
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||
* @param ret <code>SubmitPdu</code>.
|
||||
* @return a byte array of the beginning of a SUBMIT PDU. Null for invalid destinationAddress.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
private static ByteArrayOutputStream getSubmitPduHead(
|
||||
@@ -636,6 +648,161 @@ public class SmsMessage extends SmsMessageBase {
|
||||
return bo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an SMS-DELIVER PDU for an originating address and a message.
|
||||
*
|
||||
* @param scAddress Service Centre address. Null means use default.
|
||||
* @param originatingAddress the address of the originating for the message.
|
||||
* @param message string representation of the message payload.
|
||||
* @param date the time stamp the message was received.
|
||||
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||
* encoded message. Returns null on encode error.
|
||||
* @hide
|
||||
*/
|
||||
public static SubmitPdu getDeliverPdu(
|
||||
String scAddress, String originatingAddress, String message, long date) {
|
||||
if (originatingAddress == null || message == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find the best encoding to use
|
||||
TextEncodingDetails ted = calculateLength(message, false);
|
||||
int encoding = ted.codeUnitSize;
|
||||
int languageTable = ted.languageTable;
|
||||
int languageShiftTable = ted.languageShiftTable;
|
||||
byte[] header = null;
|
||||
|
||||
if (encoding == ENCODING_7BIT && (languageTable != 0 || languageShiftTable != 0)) {
|
||||
SmsHeader smsHeader = new SmsHeader();
|
||||
smsHeader.languageTable = languageTable;
|
||||
smsHeader.languageShiftTable = languageShiftTable;
|
||||
header = SmsHeader.toByteArray(smsHeader);
|
||||
}
|
||||
|
||||
SubmitPdu ret = new SubmitPdu();
|
||||
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream(MAX_USER_DATA_BYTES + 40);
|
||||
|
||||
// SMSC address with length octet, or 0
|
||||
if (scAddress == null) {
|
||||
ret.encodedScAddress = null;
|
||||
} else {
|
||||
ret.encodedScAddress =
|
||||
PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(scAddress);
|
||||
}
|
||||
|
||||
// TP-Message-Type-Indicator
|
||||
bo.write(0); // SMS-DELIVER
|
||||
|
||||
byte[] oaBytes;
|
||||
|
||||
oaBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(originatingAddress);
|
||||
|
||||
// Return null for invalid originating address
|
||||
if (oaBytes == null) return null;
|
||||
|
||||
// Originating address length in BCD digits, ignoring TON byte and pad
|
||||
// TODO Should be better.
|
||||
bo.write((oaBytes.length - 1) * 2 - ((oaBytes[oaBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));
|
||||
|
||||
// Originating Address
|
||||
bo.write(oaBytes, 0, oaBytes.length);
|
||||
|
||||
// TP-Protocol-Identifier
|
||||
bo.write(0);
|
||||
|
||||
// User Data (and length)
|
||||
byte[] userData;
|
||||
try {
|
||||
if (encoding == ENCODING_7BIT) {
|
||||
userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,
|
||||
languageTable, languageShiftTable);
|
||||
} else { // Assume UCS-2
|
||||
try {
|
||||
userData = encodeUCS2(message, header);
|
||||
} catch (UnsupportedEncodingException uex) {
|
||||
Rlog.e(LOG_TAG, "Implausible UnsupportedEncodingException ", uex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch (EncodeException ex) {
|
||||
if (ex.getError() == EncodeException.ERROR_EXCEED_SIZE) {
|
||||
Rlog.e(LOG_TAG, "Exceed size limitation EncodeException", ex);
|
||||
return null;
|
||||
} else {
|
||||
// Encoding to the 7-bit alphabet failed. Let's see if we can send it as a UCS-2
|
||||
// encoded message
|
||||
try {
|
||||
userData = encodeUCS2(message, header);
|
||||
encoding = ENCODING_16BIT;
|
||||
} catch (EncodeException ex1) {
|
||||
Rlog.e(LOG_TAG, "Exceed size limitation EncodeException", ex1);
|
||||
return null;
|
||||
} catch (UnsupportedEncodingException uex) {
|
||||
Rlog.e(LOG_TAG, "Implausible UnsupportedEncodingException ", uex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (encoding == ENCODING_7BIT) {
|
||||
if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
|
||||
// Message too long
|
||||
Rlog.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " septets)");
|
||||
return null;
|
||||
}
|
||||
// TP-Data-Coding-Scheme
|
||||
// Default encoding, uncompressed
|
||||
bo.write(0x00);
|
||||
} else { // Assume UCS-2
|
||||
if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) {
|
||||
// Message too long
|
||||
Rlog.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " bytes)");
|
||||
return null;
|
||||
}
|
||||
// TP-Data-Coding-Scheme
|
||||
// UCS-2 encoding, uncompressed
|
||||
bo.write(0x08);
|
||||
}
|
||||
|
||||
// TP-Service-Centre-Time-Stamp
|
||||
byte[] scts = new byte[7];
|
||||
|
||||
ZonedDateTime zoneDateTime = Instant.ofEpochMilli(date).atZone(ZoneId.systemDefault());
|
||||
LocalDateTime localDateTime = zoneDateTime.toLocalDateTime();
|
||||
|
||||
// It indicates the difference, expressed in quarters of an hour, between the local time and
|
||||
// GMT.
|
||||
int timezoneOffset = zoneDateTime.getOffset().getTotalSeconds() / 60 / 15;
|
||||
boolean negativeOffset = timezoneOffset < 0;
|
||||
if (negativeOffset) {
|
||||
timezoneOffset = -timezoneOffset;
|
||||
}
|
||||
int year = localDateTime.getYear();
|
||||
int month = localDateTime.getMonthValue();
|
||||
int day = localDateTime.getDayOfMonth();
|
||||
int hour = localDateTime.getHour();
|
||||
int minute = localDateTime.getMinute();
|
||||
int second = localDateTime.getSecond();
|
||||
|
||||
year = year > 2000 ? year - 2000 : year - 1900;
|
||||
scts[0] = (byte) ((((year % 10) & 0x0F) << 4) | ((year / 10) & 0x0F));
|
||||
scts[1] = (byte) ((((month % 10) & 0x0F) << 4) | ((month / 10) & 0x0F));
|
||||
scts[2] = (byte) ((((day % 10) & 0x0F) << 4) | ((day / 10) & 0x0F));
|
||||
scts[3] = (byte) ((((hour % 10) & 0x0F) << 4) | ((hour / 10) & 0x0F));
|
||||
scts[4] = (byte) ((((minute % 10) & 0x0F) << 4) | ((minute / 10) & 0x0F));
|
||||
scts[5] = (byte) ((((second % 10) & 0x0F) << 4) | ((second / 10) & 0x0F));
|
||||
scts[6] = (byte) ((((timezoneOffset % 10) & 0x0F) << 4) | ((timezoneOffset / 10) & 0x0F));
|
||||
if (negativeOffset) {
|
||||
scts[0] |= 0x08; // Negative offset
|
||||
}
|
||||
bo.write(scts, 0, scts.length);
|
||||
|
||||
bo.write(userData, 0, userData.length);
|
||||
ret.encodedMessage = bo.toByteArray();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static class PduParser {
|
||||
@UnsupportedAppUsage
|
||||
byte mPdu[];
|
||||
|
||||
Reference in New Issue
Block a user