Merge change 1522 into donut
* changes: support more minor cdms sms bearer data subparameters
This commit is contained in:
@@ -356,39 +356,6 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
|
return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class PduParser {
|
|
||||||
|
|
||||||
PduParser() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses an SC timestamp and returns a currentTimeMillis()-style
|
|
||||||
* timestamp
|
|
||||||
*/
|
|
||||||
static long getSCTimestampMillis(byte[] timestamp) {
|
|
||||||
// TP-Service-Centre-Time-Stamp
|
|
||||||
int year = IccUtils.beBcdByteToInt(timestamp[0]);
|
|
||||||
int month = IccUtils.beBcdByteToInt(timestamp[1]);
|
|
||||||
int day = IccUtils.beBcdByteToInt(timestamp[2]);
|
|
||||||
int hour = IccUtils.beBcdByteToInt(timestamp[3]);
|
|
||||||
int minute = IccUtils.beBcdByteToInt(timestamp[4]);
|
|
||||||
int second = IccUtils.beBcdByteToInt(timestamp[5]);
|
|
||||||
|
|
||||||
Time time = new Time(Time.TIMEZONE_UTC);
|
|
||||||
|
|
||||||
// C.S0015-B v2.0, 4.5.4: range is 1996-2095
|
|
||||||
time.year = year >= 96 ? year + 1900 : year + 2000;
|
|
||||||
time.month = month - 1;
|
|
||||||
time.monthDay = day;
|
|
||||||
time.hour = hour;
|
|
||||||
time.minute = minute;
|
|
||||||
time.second = second;
|
|
||||||
|
|
||||||
return time.toMillis(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: This function is a GSM specific functionality which is not supported in CDMA mode.
|
* Note: This function is a GSM specific functionality which is not supported in CDMA mode.
|
||||||
*/
|
*/
|
||||||
@@ -557,8 +524,8 @@ public class SmsMessage extends SmsMessageBase {
|
|||||||
+ originatingAddress.address);
|
+ originatingAddress.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mBearerData.timeStamp != null) {
|
if (mBearerData.msgCenterTimeStamp != null) {
|
||||||
scTimeMillis = PduParser.getSCTimestampMillis(mBearerData.timeStamp);
|
scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
|
if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import android.util.Log;
|
|||||||
|
|
||||||
import android.telephony.SmsMessage;
|
import android.telephony.SmsMessage;
|
||||||
|
|
||||||
|
import android.text.format.Time;
|
||||||
|
|
||||||
|
import com.android.internal.telephony.IccUtils;
|
||||||
import com.android.internal.telephony.GsmAlphabet;
|
import com.android.internal.telephony.GsmAlphabet;
|
||||||
import com.android.internal.telephony.SmsHeader;
|
import com.android.internal.telephony.SmsHeader;
|
||||||
import com.android.internal.telephony.cdma.sms.UserData;
|
import com.android.internal.telephony.cdma.sms.UserData;
|
||||||
@@ -38,15 +41,16 @@ public final class BearerData{
|
|||||||
/**
|
/**
|
||||||
* Bearer Data Subparameter Indentifiers
|
* Bearer Data Subparameter Indentifiers
|
||||||
* (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
|
* (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
|
||||||
|
* NOTE: Commented subparameter types are not implemented.
|
||||||
*/
|
*/
|
||||||
private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00;
|
private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00;
|
||||||
private final static byte SUBPARAM_USER_DATA = 0x01;
|
private final static byte SUBPARAM_USER_DATA = 0x01;
|
||||||
private final static byte SUBPARAM_USER_REPONSE_CODE = 0x02;
|
private final static byte SUBPARAM_USER_REPONSE_CODE = 0x02;
|
||||||
private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03;
|
private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03;
|
||||||
//private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
|
private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
|
||||||
//private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
|
private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
|
||||||
//private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06;
|
private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06;
|
||||||
//private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07;
|
private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07;
|
||||||
private final static byte SUBPARAM_PRIORITY_INDICATOR = 0x08;
|
private final static byte SUBPARAM_PRIORITY_INDICATOR = 0x08;
|
||||||
private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09;
|
private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09;
|
||||||
private final static byte SUBPARAM_REPLY_OPTION = 0x0A;
|
private final static byte SUBPARAM_REPLY_OPTION = 0x0A;
|
||||||
@@ -56,7 +60,7 @@ public final class BearerData{
|
|||||||
private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E;
|
private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E;
|
||||||
private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F;
|
private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F;
|
||||||
//private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10;
|
//private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10;
|
||||||
//private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11;
|
private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11;
|
||||||
//private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12;
|
//private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12;
|
||||||
//private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13;
|
//private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13;
|
||||||
private final static byte SUBPARAM_MESSAGE_STATUS = 0x14;
|
private final static byte SUBPARAM_MESSAGE_STATUS = 0x14;
|
||||||
@@ -205,23 +209,94 @@ public final class BearerData{
|
|||||||
*/
|
*/
|
||||||
public UserData userData;
|
public UserData userData;
|
||||||
|
|
||||||
//public UserResponseCode userResponseCode;
|
/**
|
||||||
|
* The User Response Code subparameter is used in the SMS User
|
||||||
|
* Acknowledgment Message to respond to previously received short
|
||||||
|
* messages. This message center-specific element carries the
|
||||||
|
* identifier of a predefined response. (See 3GPP2 C.S.0015-B, v2,
|
||||||
|
* 4.5.3)
|
||||||
|
*/
|
||||||
|
public boolean userResponseCodeSet = false;
|
||||||
|
public int userResponseCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
|
* 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
|
||||||
* year, month, day, hours, minutes, seconds;
|
|
||||||
*/
|
*/
|
||||||
public byte[] timeStamp;
|
public static class TimeStamp extends Time {
|
||||||
|
|
||||||
//public SmsTime validityPeriodAbsolute;
|
public TimeStamp() {
|
||||||
//public SmsRelTime validityPeriodRelative;
|
super(Time.TIMEZONE_UTC);
|
||||||
//public SmsTime deferredDeliveryTimeAbsolute;
|
}
|
||||||
//public SmsRelTime deferredDeliveryTimeRelative;
|
|
||||||
|
public static TimeStamp fromByteArray(byte[] data) {
|
||||||
|
TimeStamp ts = new TimeStamp();
|
||||||
|
// C.S0015-B v2.0, 4.5.4: range is 1996-2095
|
||||||
|
int year = IccUtils.beBcdByteToInt(data[0]);
|
||||||
|
if (year > 99 || year < 0) return null;
|
||||||
|
ts.year = year >= 96 ? year + 1900 : year + 2000;
|
||||||
|
int month = IccUtils.beBcdByteToInt(data[1]);
|
||||||
|
if (month < 1 || month > 12) return null;
|
||||||
|
ts.month = month - 1;
|
||||||
|
int day = IccUtils.beBcdByteToInt(data[2]);
|
||||||
|
if (day < 1 || day > 31) return null;
|
||||||
|
ts.monthDay = day;
|
||||||
|
int hour = IccUtils.beBcdByteToInt(data[3]);
|
||||||
|
if (hour < 0 || hour > 23) return null;
|
||||||
|
ts.hour = hour;
|
||||||
|
int minute = IccUtils.beBcdByteToInt(data[4]);
|
||||||
|
if (minute < 0 || minute > 59) return null;
|
||||||
|
ts.minute = minute;
|
||||||
|
int second = IccUtils.beBcdByteToInt(data[5]);
|
||||||
|
if (second < 0 || second > 59) return null;
|
||||||
|
ts.second = second;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("TimeStamp ");
|
||||||
|
builder.append("{ year=" + year);
|
||||||
|
builder.append(", month=" + month);
|
||||||
|
builder.append(", day=" + monthDay);
|
||||||
|
builder.append(", hour=" + hour);
|
||||||
|
builder.append(", minute=" + minute);
|
||||||
|
builder.append(", second=" + second);
|
||||||
|
builder.append(" }");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeStamp msgCenterTimeStamp;
|
||||||
|
public TimeStamp validityPeriodAbsolute;
|
||||||
|
public TimeStamp deferredDeliveryTimeAbsolute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reply Option
|
* Relative time is specified as one byte, the value of which
|
||||||
* 1-bit values which indicate whether SMS acknowledgment is requested or not.
|
* falls into a series of ranges, as specified below. The idea is
|
||||||
* (See 3GPP2 C.S0015-B, v2, 4.5.11)
|
* that shorter time intervals allow greater precision -- the
|
||||||
|
* value means minutes from zero until the MINS_LIMIT (inclusive),
|
||||||
|
* upon which it means hours until the HOURS_LIMIT, and so
|
||||||
|
* forth. (See 3GPP2 C.S0015-B, v2, 4.5.6-1)
|
||||||
|
*/
|
||||||
|
public static final int RELATIVE_TIME_MINS_LIMIT = 143;
|
||||||
|
public static final int RELATIVE_TIME_HOURS_LIMIT = 167;
|
||||||
|
public static final int RELATIVE_TIME_DAYS_LIMIT = 196;
|
||||||
|
public static final int RELATIVE_TIME_WEEKS_LIMIT = 244;
|
||||||
|
public static final int RELATIVE_TIME_INDEFINITE = 245;
|
||||||
|
public static final int RELATIVE_TIME_NOW = 246;
|
||||||
|
public static final int RELATIVE_TIME_MOBILE_INACTIVE = 247;
|
||||||
|
public static final int RELATIVE_TIME_RESERVED = 248;
|
||||||
|
|
||||||
|
public boolean validityPeriodRelativeSet;
|
||||||
|
public int validityPeriodRelative;
|
||||||
|
public boolean deferredDeliveryTimeRelativeSet;
|
||||||
|
public int deferredDeliveryTimeRelative;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Reply Option subparameter contains 1-bit values which
|
||||||
|
* indicate whether SMS acknowledgment is requested or not. (See
|
||||||
|
* 3GPP2 C.S0015-B, v2, 4.5.11)
|
||||||
*/
|
*/
|
||||||
public boolean userAckReq;
|
public boolean userAckReq;
|
||||||
public boolean deliveryAckReq;
|
public boolean deliveryAckReq;
|
||||||
@@ -229,13 +304,27 @@ public final class BearerData{
|
|||||||
public boolean reportReq;
|
public boolean reportReq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of Messages element (8-bit value) is a decimal number in the 0 to 99 range
|
* The Number of Messages subparameter (8-bit value) is a decimal
|
||||||
* representing the number of messages stored at the Voice Mail System. This element is
|
* number in the 0 to 99 range representing the number of messages
|
||||||
* used by the Voice Mail Notification service.
|
* stored at the Voice Mail System. This element is used by the
|
||||||
* (See 3GPP2 C.S0015-B, v2, 4.5.12)
|
* Voice Mail Notification service. (See 3GPP2 C.S0015-B, v2,
|
||||||
|
* 4.5.12)
|
||||||
*/
|
*/
|
||||||
public int numberOfMessages;
|
public int numberOfMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Message Deposit Index subparameter is assigned by the
|
||||||
|
* message center as a unique index to the contents of the User
|
||||||
|
* Data subparameter in each message sent to a particular mobile
|
||||||
|
* station. The mobile station, when replying to a previously
|
||||||
|
* received short message which included a Message Deposit Index
|
||||||
|
* subparameter, may include the Message Deposit Index of the
|
||||||
|
* received message to indicate to the message center that the
|
||||||
|
* original contents of the message are to be included in the
|
||||||
|
* reply. (See 3GPP2 C.S0015-B, v2, 4.5.18)
|
||||||
|
*/
|
||||||
|
public int depositIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 4-bit or 8-bit value that indicates the number to be dialed in reply to a
|
* 4-bit or 8-bit value that indicates the number to be dialed in reply to a
|
||||||
* received SMS message.
|
* received SMS message.
|
||||||
@@ -262,14 +351,23 @@ public final class BearerData{
|
|||||||
builder.append(", language=" + (languageIndicatorSet ? language : "unset"));
|
builder.append(", language=" + (languageIndicatorSet ? language : "unset"));
|
||||||
builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset"));
|
builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset"));
|
||||||
builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset"));
|
builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset"));
|
||||||
builder.append(", timeStamp=" +
|
builder.append(", msgCenterTimeStamp=" +
|
||||||
((timeStamp != null) ? HexDump.toHexString(timeStamp) : "unset"));
|
((msgCenterTimeStamp != null) ? msgCenterTimeStamp : "unset"));
|
||||||
|
builder.append(", validityPeriodAbsolute=" +
|
||||||
|
((validityPeriodAbsolute != null) ? validityPeriodAbsolute : "unset"));
|
||||||
|
builder.append(", validityPeriodRelative=" +
|
||||||
|
((validityPeriodRelativeSet) ? validityPeriodRelative : "unset"));
|
||||||
|
builder.append(", deferredDeliveryTimeAbsolute=" +
|
||||||
|
((deferredDeliveryTimeAbsolute != null) ? deferredDeliveryTimeAbsolute : "unset"));
|
||||||
|
builder.append(", deferredDeliveryTimeRelative=" +
|
||||||
|
((deferredDeliveryTimeRelativeSet) ? deferredDeliveryTimeRelative : "unset"));
|
||||||
builder.append(", userAckReq=" + userAckReq);
|
builder.append(", userAckReq=" + userAckReq);
|
||||||
builder.append(", deliveryAckReq=" + deliveryAckReq);
|
builder.append(", deliveryAckReq=" + deliveryAckReq);
|
||||||
builder.append(", readAckReq=" + readAckReq);
|
builder.append(", readAckReq=" + readAckReq);
|
||||||
builder.append(", reportReq=" + reportReq);
|
builder.append(", reportReq=" + reportReq);
|
||||||
builder.append(", numberOfMessages=" + numberOfMessages);
|
builder.append(", numberOfMessages=" + numberOfMessages);
|
||||||
builder.append(", callbackNumber=" + callbackNumber);
|
builder.append(", callbackNumber=" + callbackNumber);
|
||||||
|
builder.append(", depositIndex=" + depositIndex);
|
||||||
builder.append(", hasUserDataHeader=" + hasUserDataHeader);
|
builder.append(", hasUserDataHeader=" + hasUserDataHeader);
|
||||||
builder.append(", userData=" + userData);
|
builder.append(", userData=" + userData);
|
||||||
builder.append(" }");
|
builder.append(" }");
|
||||||
@@ -518,11 +616,11 @@ public final class BearerData{
|
|||||||
outStream.write(8, bData.numberOfMessages);
|
outStream.write(8, bData.numberOfMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void encodeMsgCenterTimeStamp(BearerData bData, BitwiseOutputStream outStream)
|
private static void encodeValidityPeriodRel(BearerData bData, BitwiseOutputStream outStream)
|
||||||
throws BitwiseOutputStream.AccessException
|
throws BitwiseOutputStream.AccessException
|
||||||
{
|
{
|
||||||
outStream.write(8, 6);
|
outStream.write(8, 1);
|
||||||
outStream.writeByteArray(6 * 8, bData.timeStamp);
|
outStream.write(8, bData.validityPeriodRelative);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void encodePrivacyIndicator(BearerData bData, BitwiseOutputStream outStream)
|
private static void encodePrivacyIndicator(BearerData bData, BitwiseOutputStream outStream)
|
||||||
@@ -595,9 +693,9 @@ public final class BearerData{
|
|||||||
outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES);
|
outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES);
|
||||||
encodeMsgCount(bData, outStream);
|
encodeMsgCount(bData, outStream);
|
||||||
}
|
}
|
||||||
if (bData.timeStamp != null) {
|
if (bData.validityPeriodRelativeSet) {
|
||||||
outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP);
|
outStream.write(8, SUBPARAM_VALIDITY_PERIOD_RELATIVE);
|
||||||
encodeMsgCenterTimeStamp(bData, outStream);
|
encodeValidityPeriodRel(bData, outStream);
|
||||||
}
|
}
|
||||||
if (bData.privacyIndicatorSet) {
|
if (bData.privacyIndicatorSet) {
|
||||||
outStream.write(8, SUBPARAM_PRIVACY_INDICATOR);
|
outStream.write(8, SUBPARAM_PRIVACY_INDICATOR);
|
||||||
@@ -791,6 +889,15 @@ public final class BearerData{
|
|||||||
bData.numberOfMessages = inStream.read(8);
|
bData.numberOfMessages = inStream.read(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void decodeDepositIndex(BearerData bData, BitwiseInputStream inStream)
|
||||||
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
|
{
|
||||||
|
if (inStream.read(8) != 2) {
|
||||||
|
throw new CodingException("MESSAGE_DEPOSIT_INDEX subparam size incorrect");
|
||||||
|
}
|
||||||
|
bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8);
|
||||||
|
}
|
||||||
|
|
||||||
private static String decodeDtmfSmsAddress(byte[] rawData, int numFields)
|
private static String decodeDtmfSmsAddress(byte[] rawData, int numFields)
|
||||||
throws CodingException
|
throws CodingException
|
||||||
{
|
{
|
||||||
@@ -863,14 +970,51 @@ public final class BearerData{
|
|||||||
bData.messageStatusSet = true;
|
bData.messageStatusSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void decodeMsgCenterTimeStamp(BearerData bData,
|
private static void decodeMsgCenterTimeStamp(BearerData bData, BitwiseInputStream inStream)
|
||||||
BitwiseInputStream inStream)
|
|
||||||
throws BitwiseInputStream.AccessException, CodingException
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
{
|
{
|
||||||
if (inStream.read(8) != 6) {
|
if (inStream.read(8) != 6) {
|
||||||
throw new CodingException("MESSAGE_CENTER_TIME_STAMP subparam size incorrect");
|
throw new CodingException("MESSAGE_CENTER_TIME_STAMP subparam size incorrect");
|
||||||
}
|
}
|
||||||
bData.timeStamp = inStream.readByteArray(6 * 8);
|
bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void decodeValidityAbs(BearerData bData, BitwiseInputStream inStream)
|
||||||
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
|
{
|
||||||
|
if (inStream.read(8) != 6) {
|
||||||
|
throw new CodingException("VALIDITY_PERIOD_ABSOLUTE subparam size incorrect");
|
||||||
|
}
|
||||||
|
bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void decodeDeferredDeliveryAbs(BearerData bData, BitwiseInputStream inStream)
|
||||||
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
|
{
|
||||||
|
if (inStream.read(8) != 6) {
|
||||||
|
throw new CodingException("DEFERRED_DELIVERY_TIME_ABSOLUTE subparam size incorrect");
|
||||||
|
}
|
||||||
|
bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void decodeValidityRel(BearerData bData, BitwiseInputStream inStream)
|
||||||
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
|
{
|
||||||
|
if (inStream.read(8) != 1) {
|
||||||
|
throw new CodingException("VALIDITY_PERIOD_RELATIVE subparam size incorrect");
|
||||||
|
}
|
||||||
|
bData.deferredDeliveryTimeRelative = inStream.read(8);
|
||||||
|
bData.deferredDeliveryTimeRelativeSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void decodeDeferredDeliveryRel(BearerData bData, BitwiseInputStream inStream)
|
||||||
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
|
{
|
||||||
|
if (inStream.read(8) != 1) {
|
||||||
|
throw new CodingException("DEFERRED_DELIVERY_TIME_RELATIVE subparam size incorrect");
|
||||||
|
}
|
||||||
|
bData.validityPeriodRelative = inStream.read(8);
|
||||||
|
bData.validityPeriodRelativeSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void decodePrivacyIndicator(BearerData bData, BitwiseInputStream inStream)
|
private static void decodePrivacyIndicator(BearerData bData, BitwiseInputStream inStream)
|
||||||
@@ -927,6 +1071,16 @@ public final class BearerData{
|
|||||||
bData.alertIndicatorSet = true;
|
bData.alertIndicatorSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void decodeUserResponseCode(BearerData bData, BitwiseInputStream inStream)
|
||||||
|
throws BitwiseInputStream.AccessException, CodingException
|
||||||
|
{
|
||||||
|
if (inStream.read(8) != 1) {
|
||||||
|
throw new CodingException("USER_REPONSE_CODE subparam size incorrect");
|
||||||
|
}
|
||||||
|
bData.userResponseCode = inStream.read(8);
|
||||||
|
bData.userResponseCodeSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create BearerData object from serialized representation.
|
* Create BearerData object from serialized representation.
|
||||||
* (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)
|
||||||
@@ -955,6 +1109,9 @@ public final class BearerData{
|
|||||||
case SUBPARAM_USER_DATA:
|
case SUBPARAM_USER_DATA:
|
||||||
decodeUserData(bData, inStream);
|
decodeUserData(bData, inStream);
|
||||||
break;
|
break;
|
||||||
|
case SUBPARAM_USER_REPONSE_CODE:
|
||||||
|
decodeUserResponseCode(bData, inStream);
|
||||||
|
break;
|
||||||
case SUBPARAM_REPLY_OPTION:
|
case SUBPARAM_REPLY_OPTION:
|
||||||
decodeReplyOption(bData, inStream);
|
decodeReplyOption(bData, inStream);
|
||||||
break;
|
break;
|
||||||
@@ -970,6 +1127,18 @@ public final class BearerData{
|
|||||||
case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
|
case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
|
||||||
decodeMsgCenterTimeStamp(bData, inStream);
|
decodeMsgCenterTimeStamp(bData, inStream);
|
||||||
break;
|
break;
|
||||||
|
case SUBPARAM_VALIDITY_PERIOD_ABSOLUTE:
|
||||||
|
decodeValidityAbs(bData, inStream);
|
||||||
|
break;
|
||||||
|
case SUBPARAM_VALIDITY_PERIOD_RELATIVE:
|
||||||
|
decodeValidityRel(bData, inStream);
|
||||||
|
break;
|
||||||
|
case SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE:
|
||||||
|
decodeDeferredDeliveryAbs(bData, inStream);
|
||||||
|
break;
|
||||||
|
case SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE:
|
||||||
|
decodeDeferredDeliveryRel(bData, inStream);
|
||||||
|
break;
|
||||||
case SUBPARAM_PRIVACY_INDICATOR:
|
case SUBPARAM_PRIVACY_INDICATOR:
|
||||||
decodePrivacyIndicator(bData, inStream);
|
decodePrivacyIndicator(bData, inStream);
|
||||||
break;
|
break;
|
||||||
@@ -985,6 +1154,9 @@ public final class BearerData{
|
|||||||
case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY:
|
case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY:
|
||||||
decodeMsgDeliveryAlert(bData, inStream);
|
decodeMsgDeliveryAlert(bData, inStream);
|
||||||
break;
|
break;
|
||||||
|
case SUBPARAM_MESSAGE_DEPOSIT_INDEX:
|
||||||
|
decodeDepositIndex(bData, inStream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new CodingException("unsupported bearer data subparameter ("
|
throw new CodingException("unsupported bearer data subparameter ("
|
||||||
+ subparamId + ")");
|
+ subparamId + ")");
|
||||||
|
|||||||
@@ -20,23 +20,31 @@ import com.android.internal.telephony.SmsAddress;
|
|||||||
import com.android.internal.util.HexDump;
|
import com.android.internal.util.HexDump;
|
||||||
|
|
||||||
public class CdmaSmsAddress extends SmsAddress {
|
public class CdmaSmsAddress extends SmsAddress {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* digit mode indicators
|
* Digit Mode Indicator is a 1-bit value that indicates whether
|
||||||
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
* the address digits are 4-bit DTMF codes or 8-bit codes. (See
|
||||||
|
* 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
||||||
*/
|
*/
|
||||||
static public final int DIGIT_MODE_4BIT_DTMF = 0x00;
|
static public final int DIGIT_MODE_4BIT_DTMF = 0x00;
|
||||||
static public final int DIGIT_MODE_8BIT_CHAR = 0x01;
|
static public final int DIGIT_MODE_8BIT_CHAR = 0x01;
|
||||||
|
|
||||||
|
public byte digitMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* number mode indicators
|
* Number Mode Indicator is 1-bit value that indicates whether the
|
||||||
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
* address type is a data network address or not. (See 3GPP2
|
||||||
|
* C.S0015-B, v2, 3.4.3.3)
|
||||||
*/
|
*/
|
||||||
static public final int NUMBER_MODE_NOT_DATA_NETWORK = 0x00;
|
static public final int NUMBER_MODE_NOT_DATA_NETWORK = 0x00;
|
||||||
static public final int NUMBER_MODE_DATA_NETWORK = 0x01;
|
static public final int NUMBER_MODE_DATA_NETWORK = 0x01;
|
||||||
|
|
||||||
|
public byte numberMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* number types for data networks
|
* Number Types for data networks.
|
||||||
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
||||||
|
* NOTE: value is stored in the parent class ton field.
|
||||||
*/
|
*/
|
||||||
static public final int TON_UNKNOWN = 0x00;
|
static public final int TON_UNKNOWN = 0x00;
|
||||||
static public final int TON_INTERNATIONAL_OR_IP = 0x01;
|
static public final int TON_INTERNATIONAL_OR_IP = 0x01;
|
||||||
@@ -48,65 +56,51 @@ public class CdmaSmsAddress extends SmsAddress {
|
|||||||
static public final int TON_RESERVED = 0x07;
|
static public final int TON_RESERVED = 0x07;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* maximum lengths for fields as defined in ril_cdma_sms.h
|
* Maximum lengths for fields as defined in ril_cdma_sms.h.
|
||||||
*/
|
*/
|
||||||
static public final int SMS_ADDRESS_MAX = 36;
|
static public final int SMS_ADDRESS_MAX = 36;
|
||||||
static public final int SMS_SUBADDRESS_MAX = 36;
|
static public final int SMS_SUBADDRESS_MAX = 36;
|
||||||
|
|
||||||
/**
|
|
||||||
* Supported numbering plan identification
|
|
||||||
* (See C.S005-D, v1.0, table 2.7.1.3.2.4-3)
|
|
||||||
*/
|
|
||||||
static public final int NUMBERING_PLAN_UNKNOWN = 0x0;
|
|
||||||
static public final int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1;
|
|
||||||
//static protected final int NUMBERING_PLAN_DATA = 0x3;
|
|
||||||
//static protected final int NUMBERING_PLAN_TELEX = 0x4;
|
|
||||||
//static protected final int NUMBERING_PLAN_PRIVATE = 0x9;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1-bit value that indicates whether the address digits are 4-bit DTMF codes
|
|
||||||
* or 8-bit codes.
|
|
||||||
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
|
||||||
*/
|
|
||||||
public byte digitMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1-bit value that indicates whether the address type is a data network address or not.
|
|
||||||
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
|
||||||
*/
|
|
||||||
public byte numberMode;
|
|
||||||
|
|
||||||
// use parent class member ton instead public byte numberType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 0 or 4-bit value that indicates which numbering plan identification is set.
|
|
||||||
* (See 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
|
|
||||||
*/
|
|
||||||
public byte numberPlan;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This field shall be set to the number of address digits
|
* This field shall be set to the number of address digits
|
||||||
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
* (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
|
||||||
*/
|
*/
|
||||||
public byte numberOfDigits;
|
public byte numberOfDigits;
|
||||||
|
|
||||||
// use parent class member orig_bytes instead of public byte[] digits;
|
/**
|
||||||
|
* Numbering Plan identification is a 0 or 4-bit value that
|
||||||
|
* indicates which numbering plan identification is set. (See
|
||||||
|
* 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
|
||||||
|
*/
|
||||||
|
static public final int NUMBERING_PLAN_UNKNOWN = 0x0;
|
||||||
|
static public final int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1;
|
||||||
|
//static protected final int NUMBERING_PLAN_DATA = 0x3;
|
||||||
|
//static protected final int NUMBERING_PLAN_TELEX = 0x4;
|
||||||
|
//static protected final int NUMBERING_PLAN_PRIVATE = 0x9;
|
||||||
|
|
||||||
|
public byte numberPlan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE: the parsed string address and the raw byte array values
|
||||||
|
* are stored in the parent class address and origBytes fields,
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public CdmaSmsAddress(){
|
public CdmaSmsAddress(){
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("CdmaSmsAddress:\n");
|
builder.append("CdmaSmsAddress ");
|
||||||
builder.append(" digitMode: " + digitMode + "\n");
|
builder.append("{ digitMode=" + digitMode);
|
||||||
builder.append(" numberMode: " + numberMode + "\n");
|
builder.append(", numberMode=" + numberMode);
|
||||||
builder.append(" numberPlan: " + numberPlan + "\n");
|
builder.append(", numberPlan=" + numberPlan);
|
||||||
builder.append(" numberOfDigits: " + numberOfDigits + "\n");
|
builder.append(", numberOfDigits=" + numberOfDigits);
|
||||||
builder.append(" ton: " + ton + "\n");
|
builder.append(", ton=" + ton);
|
||||||
builder.append(" address: " + address + "\n");
|
builder.append(", address=" + address);
|
||||||
builder.append(" origBytes: " + HexDump.toHexString(origBytes) + "\n");
|
builder.append(", origBytes=" + HexDump.toHexString(origBytes));
|
||||||
|
builder.append(" }");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import java.util.Iterator;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class CdmaSmsTest extends AndroidTestCase {
|
public class CdmaSmsTest extends AndroidTestCase {
|
||||||
private final static String LOG_TAG = "Cdma_Sms_Test";
|
private final static String LOG_TAG = "CDMA";
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testUserData7bitGsm() throws Exception {
|
public void testUserData7bitGsm() throws Exception {
|
||||||
@@ -135,6 +135,100 @@ public class CdmaSmsTest extends AndroidTestCase {
|
|||||||
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
|
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
public void testMonolithicOne() throws Exception {
|
||||||
|
String pdu = "0003200010010410168d2002010503060812011101590501c706069706180000000701c108" +
|
||||||
|
"01c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566";
|
||||||
|
BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
|
||||||
|
assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT);
|
||||||
|
assertEquals(bearerData.messageId, 1);
|
||||||
|
assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY);
|
||||||
|
assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL);
|
||||||
|
assertEquals(bearerData.userAckReq, true);
|
||||||
|
assertEquals(bearerData.readAckReq, true);
|
||||||
|
assertEquals(bearerData.deliveryAckReq, true);
|
||||||
|
assertEquals(bearerData.reportReq, false);
|
||||||
|
assertEquals(bearerData.numberOfMessages, 3);
|
||||||
|
assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO);
|
||||||
|
assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW);
|
||||||
|
assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
|
||||||
|
assertEquals(bearerData.callbackNumber.numberMode,
|
||||||
|
CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
|
||||||
|
assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN);
|
||||||
|
assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN);
|
||||||
|
assertEquals(bearerData.callbackNumber.numberOfDigits, 7);
|
||||||
|
assertEquals(bearerData.callbackNumber.address, "3598271");
|
||||||
|
assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER);
|
||||||
|
assertEquals(bearerData.depositIndex, 1382);
|
||||||
|
assertEquals(bearerData.userResponseCode, 5);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.year, 2008);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.month, 11);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.hour, 11);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.second, 59);
|
||||||
|
assertEquals(bearerData.validityPeriodAbsolute, null);
|
||||||
|
assertEquals(bearerData.validityPeriodRelative, -63);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeRelative, -57);
|
||||||
|
assertEquals(bearerData.hasUserDataHeader, false);
|
||||||
|
assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
|
||||||
|
assertEquals(bearerData.userData.numFields, 2);
|
||||||
|
assertEquals(bearerData.userData.payloadStr, "hi");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
public void testMonolithicTwo() throws Exception {
|
||||||
|
String pdu = "0003200010010410168d200201050306081201110159050192060697061800000007013d0" +
|
||||||
|
"801c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566";
|
||||||
|
BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
|
||||||
|
assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT);
|
||||||
|
assertEquals(bearerData.messageId, 1);
|
||||||
|
assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY);
|
||||||
|
assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL);
|
||||||
|
assertEquals(bearerData.userAckReq, true);
|
||||||
|
assertEquals(bearerData.readAckReq, true);
|
||||||
|
assertEquals(bearerData.deliveryAckReq, true);
|
||||||
|
assertEquals(bearerData.reportReq, false);
|
||||||
|
assertEquals(bearerData.numberOfMessages, 3);
|
||||||
|
assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO);
|
||||||
|
assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW);
|
||||||
|
assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
|
||||||
|
assertEquals(bearerData.callbackNumber.numberMode,
|
||||||
|
CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
|
||||||
|
assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN);
|
||||||
|
assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN);
|
||||||
|
assertEquals(bearerData.callbackNumber.numberOfDigits, 7);
|
||||||
|
assertEquals(bearerData.callbackNumber.address, "3598271");
|
||||||
|
assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER);
|
||||||
|
assertEquals(bearerData.depositIndex, 1382);
|
||||||
|
assertEquals(bearerData.userResponseCode, 5);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.year, 2008);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.month, 11);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.hour, 11);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
|
||||||
|
assertEquals(bearerData.msgCenterTimeStamp.second, 59);
|
||||||
|
assertEquals(bearerData.validityPeriodAbsolute, null);
|
||||||
|
assertEquals(bearerData.validityPeriodRelative, 61);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
|
||||||
|
assertEquals(bearerData.deferredDeliveryTimeRelative, -110);
|
||||||
|
assertEquals(bearerData.hasUserDataHeader, false);
|
||||||
|
assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
|
||||||
|
assertEquals(bearerData.userData.numFields, 2);
|
||||||
|
assertEquals(bearerData.userData.payloadStr, "hi");
|
||||||
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testUserDataHeaderConcatRefFeedback() throws Exception {
|
public void testUserDataHeaderConcatRefFeedback() throws Exception {
|
||||||
BearerData bearerData = new BearerData();
|
BearerData bearerData = new BearerData();
|
||||||
@@ -409,22 +503,6 @@ public class CdmaSmsTest extends AndroidTestCase {
|
|||||||
assertEquals(addr.address, revAddr.address);
|
assertEquals(addr.address, revAddr.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
|
||||||
public void testMsgCenterTimeStampFeedback() throws Exception {
|
|
||||||
BearerData bearerData = new BearerData();
|
|
||||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
|
||||||
bearerData.messageId = 0;
|
|
||||||
bearerData.hasUserDataHeader = false;
|
|
||||||
UserData userData = new UserData();
|
|
||||||
userData.payloadStr = "test message center timestamp";
|
|
||||||
bearerData.userData = userData;
|
|
||||||
bearerData.timeStamp = HexDump.hexStringToByteArray("112233445566");
|
|
||||||
byte []encodedSms = BearerData.encode(bearerData);
|
|
||||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
|
||||||
assertEquals(HexDump.toHexString(bearerData.timeStamp),
|
|
||||||
HexDump.toHexString(revBearerData.timeStamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testPrivacyIndicator() throws Exception {
|
public void testPrivacyIndicator() throws Exception {
|
||||||
String pdu1 = "0003104090010c485f4194dfea34becf61b840090140";
|
String pdu1 = "0003104090010c485f4194dfea34becf61b840090140";
|
||||||
|
|||||||
Reference in New Issue
Block a user