Merge "New system API to create SMS PDU and expose copyMessageToIcc()"
This commit is contained in:
@@ -9182,6 +9182,7 @@ package android.telephony {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class SmsManager {
|
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 @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int);
|
||||||
method public boolean disableCellBroadcastRange(int, int, int);
|
method public boolean disableCellBroadcastRange(int, int, int);
|
||||||
method public boolean enableCellBroadcastRange(int, int, int);
|
method public boolean enableCellBroadcastRange(int, int, int);
|
||||||
@@ -9193,6 +9194,7 @@ package android.telephony {
|
|||||||
|
|
||||||
public class SmsMessage {
|
public class SmsMessage {
|
||||||
method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean);
|
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);
|
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.
|
* ICC (Integrated Circuit Card) is the card of the device.
|
||||||
* For example, this can be the SIM or USIM for GSM.
|
* 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.
|
* operation is performed on the correct subscription.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param smsc the SMSC for this message, or NULL for the default SMSC
|
* @param smsc the SMSC for this messag or null for the default SMSC.
|
||||||
* @param pdu the raw PDU to store
|
* @param pdu the raw PDU to store.
|
||||||
* @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
|
* @param status message status. One of these status:
|
||||||
* STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
|
* <code>STATUS_ON_ICC_READ</code>
|
||||||
* @return true for success
|
* <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
|
* @throws IllegalArgumentException if pdu is null.
|
||||||
* {@hide}
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@SystemApi
|
||||||
public boolean copyMessageToIcc(byte[] smsc, byte[] pdu,int status) {
|
@RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
|
||||||
|
public boolean copyMessageToIcc(
|
||||||
|
@Nullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status) {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
|
|
||||||
if (null == pdu) {
|
if (pdu == null) {
|
||||||
throw new IllegalArgumentException("pdu is NULL");
|
throw new IllegalArgumentException("pdu is null");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ISms iSms = getISmsService();
|
ISms iSms = getISmsService();
|
||||||
@@ -2035,6 +2040,17 @@ public final class SmsManager {
|
|||||||
return ret;
|
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
|
// see SmsMessage.getStatusOnIcc
|
||||||
|
|
||||||
/** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
|
/** 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.
|
* 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.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* address, if applicable, and the encoded message.
|
* @param message string representation of the message payload.
|
||||||
* Returns null on encode error.
|
* @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,
|
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||||
String destinationAddress, String message, boolean statusReportRequested) {
|
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.
|
* 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 destinationAddress the address of the destination for the message.
|
||||||
* @param message String representation of the message payload.
|
* @param message string representation of the message payload.
|
||||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||||
* @param subId Subscription of the message
|
* @param subId subscription of the message.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||||
* address, if applicable, and the encoded message.
|
* encoded message. Returns null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
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.
|
* This method will not attempt to use any GSM national language 7 bit encodings.
|
||||||
*
|
*
|
||||||
* @param scAddress Service Centre address. null == use default
|
* @param scAddress Service Centre address. Null means use default.
|
||||||
* @param destinationAddress the address of the destination for the message
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* @param destinationPort the port to deliver the message to at the
|
* @param destinationPort the port to deliver the message to at the destination.
|
||||||
* destination
|
* @param data the data for the message.
|
||||||
* @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
|
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||||
* address, if applicable, and the encoded message.
|
* encoded message. 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, short destinationPort, byte[] data,
|
||||||
@@ -660,6 +660,55 @@ public class SmsMessage {
|
|||||||
return new SubmitPdu(spb);
|
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.
|
* Get an SMS-SUBMIT PDU's encoded message.
|
||||||
* This is used by Bluetooth MAP profile to handle long non UTF-8 SMS messages.
|
* 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
|
* Gets an SMS-SUBMIT PDU for a destination address and a message.
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
* @param scAddr Service Centre address. Null means use default.
|
* @param scAddr Service Centre address. No use for this message.
|
||||||
* @param destAddr Address of the recipient.
|
* @param destAddr the address of the destination for the message.
|
||||||
* @param message String representation of the message payload.
|
* @param message string representation of the message payload.
|
||||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||||
* @param smsHeader Array containing the data for the User Data Header, preceded
|
* @param smsHeader array containing the data for the User Data Header, preceded by the Element
|
||||||
* by the Element Identifiers.
|
* Identifiers.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||||
* address, if applicable, and the encoded message.
|
* null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@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 scAddr Service Centre address. No use for this message.
|
||||||
* @param destAddr Address of the recipient.
|
* @param destAddr the address of the destination for the message.
|
||||||
* @param message String representation of the message payload.
|
* @param message string representation of the message payload.
|
||||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||||
* @param smsHeader Array containing the data for the User Data Header, preceded
|
* @param smsHeader array containing the data for the User Data Header, preceded by the Element
|
||||||
* by the Element Identifiers.
|
* Identifiers.
|
||||||
* @param priority Priority level of the message
|
* @param priority priority level of the message.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||||
* address, if applicable, and the encoded message.
|
* null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@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 scAddr Service Centre address. No use for this message.
|
||||||
* @param destAddr the address of the destination for the message
|
* @param destAddr the address of the destination for the message.
|
||||||
* @param destPort the port to deliver the message to at the
|
* @param destPort the port to deliver the message to at the destination.
|
||||||
* destination
|
* @param data the data for the message.
|
||||||
* @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
|
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||||
* address, if applicable, and the encoded message.
|
* null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort,
|
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 destAddr the address of the destination for the message.
|
||||||
* @param userData the data for the message
|
* @param userData the data for the message.
|
||||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||||
* address, if applicable, and the encoded message.
|
* null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
|
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 destAddr the address of the destination for the message.
|
||||||
* @param userData the data for the message
|
* @param userData the data for the message.
|
||||||
* @param statusReportRequested Indicates whether a report is requested for this message.
|
* @param statusReportRequested indicates whether a report is requested for this message.
|
||||||
* @param priority Priority level of the message
|
* @param priority Priority level of the message.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
|
||||||
* address, if applicable, and the encoded message.
|
* null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
|
public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
|
||||||
@@ -1057,6 +1043,72 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
return null;
|
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.
|
* Creates byte array (pseudo pdu) from SMS object.
|
||||||
* Note: Do not call this method more than once per 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.BitwiseInputStream;
|
||||||
import com.android.internal.util.BitwiseOutputStream;
|
import com.android.internal.util.BitwiseOutputStream;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
@@ -284,6 +285,33 @@ public final class BearerData {
|
|||||||
return ts;
|
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() {
|
public long toMillis() {
|
||||||
LocalDateTime localDateTime =
|
LocalDateTime localDateTime =
|
||||||
LocalDateTime.of(year, month + 1, monthDay, hour, minute, second);
|
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.
|
* Create serialized representation for BearerData object.
|
||||||
* (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
|
* (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);
|
outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS);
|
||||||
encodeScpResults(bData, outStream);
|
encodeScpResults(bData, outStream);
|
||||||
}
|
}
|
||||||
|
if (bData.msgCenterTimeStamp != null) {
|
||||||
|
outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP);
|
||||||
|
encodeMsgCenterTimeStamp(bData, outStream);
|
||||||
|
}
|
||||||
return outStream.toByteArray();
|
return outStream.toByteArray();
|
||||||
} catch (BitwiseOutputStream.AccessException ex) {
|
} catch (BitwiseOutputStream.AccessException ex) {
|
||||||
Rlog.e(LOG_TAG, "BearerData encode failed: " + 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.ByteArrayOutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Short Message Service message.
|
* 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.
|
* @param scAddress Service Centre address. Null means use default.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* address, if applicable, and the encoded message.
|
* @param message string representation of the message payload.
|
||||||
* Returns null on encode error.
|
* @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
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
@@ -277,17 +283,19 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an SMS-SUBMIT PDU for a destination address and a message using the
|
* Gets an SMS-SUBMIT PDU for a destination address and a message using the specified encoding.
|
||||||
* specified encoding.
|
|
||||||
*
|
*
|
||||||
* @param scAddress Service Centre address. Null means use default.
|
* @param scAddress Service Centre address. Null means use default.
|
||||||
* @param encoding Encoding defined by constants in
|
* @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_*
|
* com.android.internal.telephony.SmsConstants.ENCODING_*
|
||||||
* @param languageTable
|
* @param languageTable
|
||||||
* @param languageShiftTable
|
* @param languageShiftTable
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||||
* address, if applicable, and the encoded message.
|
* encoded message. Returns null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
@@ -300,18 +308,20 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an SMS-SUBMIT PDU for a destination address and a message using the
|
* Gets an SMS-SUBMIT PDU for a destination address and a message using the specified encoding.
|
||||||
* specified encoding.
|
|
||||||
*
|
*
|
||||||
* @param scAddress Service Centre address. Null means use default.
|
* @param scAddress Service Centre address. Null means use default.
|
||||||
* @param encoding Encoding defined by constants in
|
* @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_*
|
* com.android.internal.telephony.SmsConstants.ENCODING_*
|
||||||
* @param languageTable
|
* @param languageTable
|
||||||
* @param languageShiftTable
|
* @param languageShiftTable
|
||||||
* @param validityPeriod Validity Period of the message in Minutes.
|
* @param validityPeriod Validity Period of the message in Minutes.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||||
* address, if applicable, and the encoded message.
|
* encoded message. Returns null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@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.
|
* @param scAddress Service Centre address. Null means use default.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* address, if applicable, and the encoded message.
|
* @param message string representation of the message payload.
|
||||||
* Returns null on encode error.
|
* @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
|
@UnsupportedAppUsage
|
||||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
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 scAddress Service Centre address. Null means use default.
|
||||||
* @param destinationAddress the address of the destination for the message
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* @param statusReportRequested staus report of the message Requested
|
* @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.
|
* @param validityPeriod Validity Period of the message in Minutes.
|
||||||
* @return a <code>SubmitPdu</code> containing the encoded SC
|
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||||
* address, if applicable, and the encoded message.
|
* encoded message. Returns null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
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 scAddress Service Centre address. Null means use default.
|
||||||
* @param destinationAddress the address of the destination for the message
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* @param destinationPort the port to deliver the message to at the
|
* @param destinationPort the port to deliver the message to at the destination.
|
||||||
* destination
|
* @param data the data for the message.
|
||||||
* @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
|
* @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
|
||||||
* address, if applicable, and the encoded message.
|
* encoded message. Returns null on encode error.
|
||||||
* Returns null on encode error.
|
|
||||||
*/
|
*/
|
||||||
public static SubmitPdu getSubmitPdu(String scAddress,
|
public static SubmitPdu getSubmitPdu(String scAddress,
|
||||||
String destinationAddress, int destinationPort, byte[] data,
|
String destinationAddress, int destinationPort, byte[] data,
|
||||||
@@ -551,8 +562,7 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
|
|
||||||
SubmitPdu ret = new SubmitPdu();
|
SubmitPdu ret = new SubmitPdu();
|
||||||
ByteArrayOutputStream bo = getSubmitPduHead(
|
ByteArrayOutputStream bo = getSubmitPduHead(
|
||||||
scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
|
scAddress, destinationAddress, (byte) 0x41, /* TP-MTI=SMS-SUBMIT, TP-UDHI=true */
|
||||||
// TP-UDHI = true
|
|
||||||
statusReportRequested, ret);
|
statusReportRequested, ret);
|
||||||
// Skip encoding pdu if error occurs when create pdu head and the error will be handled
|
// Skip encoding pdu if error occurs when create pdu head and the error will be handled
|
||||||
// properly later on encodedMessage sanity check.
|
// 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
|
* Creates the beginning of a SUBMIT PDU.
|
||||||
* 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
|
* 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>.
|
* <code>String</code>.
|
||||||
*
|
*
|
||||||
* @param scAddress Service Centre address. null == use default
|
* @param scAddress Service Centre address. Null means use default.
|
||||||
* @param destinationAddress the address of the destination for the message
|
* @param destinationAddress the address of the destination for the message.
|
||||||
* @param mtiByte
|
* @param mtiByte
|
||||||
* @param ret <code>SubmitPdu</code> containing the encoded SC
|
* @param statusReportRequested indicates whether a report is reuested for this message.
|
||||||
* address, if applicable, and the encoded message. Returns null on encode error.
|
* @param ret <code>SubmitPdu</code>.
|
||||||
|
* @return a byte array of the beginning of a SUBMIT PDU. Null for invalid destinationAddress.
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
private static ByteArrayOutputStream getSubmitPduHead(
|
private static ByteArrayOutputStream getSubmitPduHead(
|
||||||
@@ -636,6 +648,161 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
return bo;
|
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 {
|
private static class PduParser {
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
byte mPdu[];
|
byte mPdu[];
|
||||||
|
|||||||
Reference in New Issue
Block a user