Merge change 133 into donut
* changes: Initial code for cdma sms encode and decode, in java, with simple tests.
This commit is contained in:
116
core/java/com/android/internal/util/BitwiseInputStream.java
Normal file
116
core/java/com/android/internal/util/BitwiseInputStream.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.util;
|
||||
|
||||
/**
|
||||
* An object that provides bitwise incremental read access to a byte array.
|
||||
*
|
||||
* This is useful, for example, when accessing a series of fields that
|
||||
* may not be aligned on byte boundaries.
|
||||
*
|
||||
* NOTE -- This class is not threadsafe.
|
||||
*/
|
||||
public class BitwiseInputStream {
|
||||
|
||||
// The byte array being read from.
|
||||
private byte[] mBuf;
|
||||
|
||||
// The current position offset, in bits, from the msb in byte 0.
|
||||
private int mPos;
|
||||
|
||||
// The last valid bit offset.
|
||||
private int mEnd;
|
||||
|
||||
/**
|
||||
* An exception to report access problems.
|
||||
*/
|
||||
public static class AccessException extends Exception {
|
||||
public AccessException(String s) {
|
||||
super("BitwiseInputStream access failed: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create object from byte array.
|
||||
*
|
||||
* @param buf a byte array containing data
|
||||
*/
|
||||
public BitwiseInputStream(byte buf[]) {
|
||||
mBuf = buf;
|
||||
mEnd = buf.length * 8;
|
||||
mPos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of bit still available for reading.
|
||||
*/
|
||||
public int available() {
|
||||
return mEnd - mPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read some data and increment the current position.
|
||||
*
|
||||
* @param bits the amount of data to read (gte 0, lte 8)
|
||||
*
|
||||
* @return byte of read data (possibly partially filled, from lsb)
|
||||
*/
|
||||
public byte read(int bits) throws AccessException {
|
||||
int index = mPos / 8;
|
||||
int offset = 16 - (mPos % 8) - bits;
|
||||
if ((bits < 0) || (bits > 8) || ((mPos + bits) > mEnd)) {
|
||||
throw new AccessException("illegal read " +
|
||||
"(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")");
|
||||
}
|
||||
int data = (mBuf[index] & 0xFF) << 8;
|
||||
if (offset < 8) data |= (mBuf[index + 1] & 0xFF);
|
||||
data >>>= offset;
|
||||
data &= (-1 >>> (32 - bits));
|
||||
mPos += bits;
|
||||
return (byte)data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data in bulk into a byte array and increment the current position.
|
||||
*
|
||||
* @param bits the amount of data to read
|
||||
*
|
||||
* @return newly allocated byte array of read data
|
||||
*/
|
||||
public byte[] readByteArray(int bits) throws AccessException {
|
||||
int bytes = (bits / 8) + ((bits % 8) > 0 ? 1 : 0);
|
||||
byte[] arr = new byte[bytes];
|
||||
for (int i = 0; i < bytes; i++) {
|
||||
int increment = Math.min(8, bits - (i * 8));
|
||||
arr[i] = (byte)(read(increment) << (8 - increment));
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the current position and ignore contained data.
|
||||
*
|
||||
* @param bits the amount by which to increment the position
|
||||
*/
|
||||
public void skip(int bits) throws AccessException {
|
||||
if ((mPos + bits) > mEnd) {
|
||||
throw new AccessException("illegal skip " +
|
||||
"(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")");
|
||||
}
|
||||
mPos += bits;
|
||||
}
|
||||
}
|
||||
126
core/java/com/android/internal/util/BitwiseOutputStream.java
Normal file
126
core/java/com/android/internal/util/BitwiseOutputStream.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.util;
|
||||
|
||||
/**
|
||||
* An object that rovides bitwise incremental write access to a byte array.
|
||||
*
|
||||
* This is useful, for example, when writing a series of fields that
|
||||
* may not be aligned on byte boundaries.
|
||||
*
|
||||
* NOTE -- This class is not threadsafe.
|
||||
*/
|
||||
public class BitwiseOutputStream {
|
||||
|
||||
// The byte array being written to, which will be grown as needed.
|
||||
private byte[] mBuf;
|
||||
|
||||
// The current position offset, in bits, from the msb in byte 0.
|
||||
private int mPos;
|
||||
|
||||
// The last bit offset, given the current buf length.
|
||||
private int mEnd;
|
||||
|
||||
/**
|
||||
* An exception to report access problems.
|
||||
*/
|
||||
public static class AccessException extends Exception {
|
||||
public AccessException(String s) {
|
||||
super("BitwiseOutputStream access failed: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create object from hint at desired size.
|
||||
*
|
||||
* @param startingLength initial internal byte array length in bytes
|
||||
*/
|
||||
public BitwiseOutputStream(int startingLength) {
|
||||
mBuf = new byte[startingLength];
|
||||
mEnd = startingLength * 8;
|
||||
mPos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return byte array containing accumulated data, sized to just fit.
|
||||
*
|
||||
* @return newly allocated byte array
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
int len = (mPos / 8) + ((mPos % 8) > 0 ? 1 : 0);
|
||||
byte[] newBuf = new byte[len];
|
||||
System.arraycopy(mBuf, 0, newBuf, 0, len);
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new internal buffer, if needed.
|
||||
*
|
||||
* @param bits additional bits to be accommodated
|
||||
*/
|
||||
private void possExpand(int bits) {
|
||||
if ((mPos + bits) < mEnd) return;
|
||||
byte[] newBuf = new byte[((mPos + bits) * 2) / 8];
|
||||
System.arraycopy(mBuf, 0, newBuf, 0, mEnd / 8);
|
||||
mBuf = newBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some data and increment the current position.
|
||||
*
|
||||
* @param bits the amount of data to write (gte 0, lte 8)
|
||||
* @param data to write, will be masked to expose only bits param from lsb
|
||||
*/
|
||||
public void write(int bits, int data) throws AccessException {
|
||||
if ((bits < 0) || (bits > 8)) {
|
||||
throw new AccessException("illegal write (" + bits + " bits)");
|
||||
}
|
||||
possExpand(bits);
|
||||
data &= (-1 >>> (32 - bits));
|
||||
int index = mPos / 8;
|
||||
int offset = 16 - (mPos % 8) - bits;
|
||||
data <<= offset;
|
||||
mPos += bits;
|
||||
mBuf[index] |= (data >>> 8);
|
||||
if (offset < 8) mBuf[index + 1] |= (data & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data in bulk from a byte array and increment the current position.
|
||||
*
|
||||
* @param bits the amount of data to write
|
||||
* @param arr the byte array containing data to be written
|
||||
*/
|
||||
public void writeByteArray(int bits, byte[] arr) throws AccessException {
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
int increment = Math.min(8, bits - (i * 8));
|
||||
if (increment > 0) {
|
||||
write(increment, (byte)(arr[i] >>> (8 - increment)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the current position, implicitly writing zeros.
|
||||
*
|
||||
* @param bits the amount by which to increment the position
|
||||
*/
|
||||
public void skip(int bits) {
|
||||
possExpand(bits);
|
||||
mPos += bits;
|
||||
}
|
||||
}
|
||||
@@ -20,20 +20,7 @@ import android.util.Log;
|
||||
import com.android.internal.telephony.SmsHeader;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static android.telephony.SmsMessage.ENCODING_7BIT;
|
||||
import static android.telephony.SmsMessage.ENCODING_16BIT;
|
||||
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
|
||||
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
|
||||
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
|
||||
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
|
||||
import static android.telephony.SmsMessage.MessageClass;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_ABBREVIATED;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_ALPHANUMERIC;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_INTERNATIONAL;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_NATIONAL;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_NETWORK;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_SUBSCRIBER;
|
||||
import static com.android.internal.telephony.SmsAddress.TON_UNKNOWN;
|
||||
|
||||
/**
|
||||
* Base class declaring the specific methods and members for SmsMessage.
|
||||
@@ -385,4 +372,3 @@ public abstract class SmsMessageBase {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.android.internal.telephony.SmsHeader;
|
||||
import com.android.internal.telephony.SmsMessageBase;
|
||||
import com.android.internal.telephony.cdma.sms.BearerData;
|
||||
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
|
||||
import com.android.internal.telephony.cdma.sms.SmsDataCoding;
|
||||
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
|
||||
import com.android.internal.telephony.cdma.sms.UserData;
|
||||
|
||||
@@ -50,23 +49,6 @@ import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
|
||||
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
|
||||
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
|
||||
import static android.telephony.SmsMessage.MessageClass;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_NONE;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_TEMPORARY;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_PERMANENT;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVER;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_SUBMIT;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_CANCELLATION;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVERY_ACK;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_USER_ACK;
|
||||
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_READ_ACK;
|
||||
import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_ADDRESS_MAX;
|
||||
import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_SUBADDRESS_MAX;
|
||||
import static com.android.internal.telephony.cdma.sms.SmsEnvelope.SMS_BEARER_DATA_MAX;
|
||||
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_7BIT_ASCII;
|
||||
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_GSM_7BIT_ALPHABET;
|
||||
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_IA5;
|
||||
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_OCTET;
|
||||
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_UNICODE_16;
|
||||
|
||||
/**
|
||||
* A Short Message Service message.
|
||||
@@ -186,7 +168,7 @@ public class SmsMessage extends SmsMessageBase {
|
||||
|
||||
// ignore subaddress
|
||||
p.readInt(); //p_cur->sSubAddress.subaddressType
|
||||
p.readByte(); //p_cur->sSubAddress.odd
|
||||
p.readInt(); //p_cur->sSubAddress.odd
|
||||
count = p.readByte(); //p_cur->sSubAddress.number_of_digits
|
||||
//p_cur->sSubAddress.digits[digitCount] :
|
||||
for (int index=0; index < count; index++) {
|
||||
@@ -309,15 +291,15 @@ public class SmsMessage extends SmsMessageBase {
|
||||
int septetCount = GsmAlphabet.countGsmSeptets(message, true);
|
||||
// User Data (and length)
|
||||
|
||||
uData.userData = message.getBytes();
|
||||
uData.payload = message.getBytes();
|
||||
|
||||
if (uData.userData.length > MAX_USER_DATA_SEPTETS) {
|
||||
if (uData.payload.length > MAX_USER_DATA_SEPTETS) {
|
||||
// Message too long
|
||||
return null;
|
||||
}
|
||||
|
||||
// desired TP-Data-Coding-Scheme
|
||||
uData.userDataEncoding = UserData.UD_ENCODING_GSM_7BIT_ALPHABET;
|
||||
uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
|
||||
|
||||
// paddingBits not needed for UD_ENCODING_GSM_7BIT_ALPHABET
|
||||
|
||||
@@ -341,15 +323,15 @@ public class SmsMessage extends SmsMessageBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
uData.userData = textPart;
|
||||
uData.payload = textPart;
|
||||
|
||||
if (uData.userData.length > MAX_USER_DATA_BYTES) {
|
||||
if (uData.payload.length > MAX_USER_DATA_BYTES) {
|
||||
// Message too long
|
||||
return null;
|
||||
}
|
||||
|
||||
// TP-Data-Coding-Scheme
|
||||
uData.userDataEncoding = UserData.UD_ENCODING_UNICODE_16;
|
||||
uData.msgEncoding = UserData.ENCODING_UNICODE_16;
|
||||
|
||||
// sms header
|
||||
if(headerData != null) {
|
||||
@@ -425,8 +407,8 @@ public class SmsMessage extends SmsMessageBase {
|
||||
|
||||
// TP-Data-Coding-Scheme
|
||||
// No class, 8 bit data
|
||||
uData.userDataEncoding = UserData.UD_ENCODING_OCTET;
|
||||
uData.userData = data;
|
||||
uData.msgEncoding = UserData.ENCODING_OCTET;
|
||||
uData.payload = data;
|
||||
|
||||
byte[] msgData = sms.getEnvelope(destinationAddress, statusReportRequested, uData,
|
||||
true, true);
|
||||
@@ -619,21 +601,21 @@ public class SmsMessage extends SmsMessageBase {
|
||||
* Parses a SMS message from its BearerData stream. (mobile-terminated only)
|
||||
*/
|
||||
protected void parseSms() {
|
||||
mBearerData = SmsDataCoding.decodeCdmaSms(mEnvelope.bearerData);
|
||||
messageRef = mBearerData.messageID;
|
||||
mBearerData = BearerData.decode(mEnvelope.bearerData);
|
||||
messageRef = mBearerData.messageId;
|
||||
|
||||
// TP-Message-Type-Indicator
|
||||
// (See 3GPP2 C.S0015-B, v2, 4.5.1)
|
||||
int messageType = mBearerData.messageType;
|
||||
|
||||
switch (messageType) {
|
||||
case MESSAGE_TYPE_USER_ACK:
|
||||
case MESSAGE_TYPE_READ_ACK:
|
||||
case MESSAGE_TYPE_DELIVER:
|
||||
case BearerData.MESSAGE_TYPE_USER_ACK:
|
||||
case BearerData.MESSAGE_TYPE_READ_ACK:
|
||||
case BearerData.MESSAGE_TYPE_DELIVER:
|
||||
// Deliver (mobile-terminated only)
|
||||
parseSmsDeliver();
|
||||
break;
|
||||
case MESSAGE_TYPE_DELIVERY_ACK:
|
||||
case BearerData.MESSAGE_TYPE_DELIVERY_ACK:
|
||||
parseSmsDeliveryAck();
|
||||
break;
|
||||
|
||||
@@ -699,22 +681,22 @@ public class SmsMessage extends SmsMessageBase {
|
||||
return;
|
||||
}
|
||||
|
||||
encodingType = uData.userDataEncoding;
|
||||
encodingType = uData.msgEncoding;
|
||||
|
||||
// insert DCS-decoding here when type is supported by ril-library
|
||||
|
||||
userData = uData.userData;
|
||||
userData = uData.payload;
|
||||
userDataHeader = uData.userDataHeader;
|
||||
|
||||
switch (encodingType) {
|
||||
case UD_ENCODING_GSM_7BIT_ALPHABET:
|
||||
case UD_ENCODING_UNICODE_16:
|
||||
case UserData.ENCODING_GSM_7BIT_ALPHABET:
|
||||
case UserData.ENCODING_UNICODE_16:
|
||||
// user data was already decoded by wmsts-library
|
||||
messageBody = new String(userData);
|
||||
break;
|
||||
|
||||
// data and unsupported encodings:
|
||||
case UD_ENCODING_OCTET:
|
||||
case UserData.ENCODING_OCTET:
|
||||
default:
|
||||
messageBody = null;
|
||||
break;
|
||||
@@ -771,7 +753,7 @@ public class SmsMessage extends SmsMessageBase {
|
||||
if (useNewId) {
|
||||
setNextMessageId();
|
||||
}
|
||||
mBearerData.messageID = nextMessageId;
|
||||
mBearerData.messageId = nextMessageId;
|
||||
|
||||
// Set the reply options (See C.S0015-B, v2.0, 4.5.11)
|
||||
if(statusReportRequested) {
|
||||
@@ -795,7 +777,7 @@ public class SmsMessage extends SmsMessageBase {
|
||||
// ** encode BearerData **
|
||||
byte[] encodedBearerData = null;
|
||||
try {
|
||||
encodedBearerData = SmsDataCoding.encodeCdmaSms(mBearerData);
|
||||
encodedBearerData = BearerData.encode(mBearerData);
|
||||
} catch (Exception e) {
|
||||
Log.e(LOG_TAG, "doGetSubmitPdu: EncodeCdmaSMS function in JNI interface failed: "
|
||||
+ e.getMessage());
|
||||
|
||||
@@ -16,7 +16,52 @@
|
||||
|
||||
package com.android.internal.telephony.cdma.sms;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.telephony.GsmAlphabet;
|
||||
import com.android.internal.telephony.SmsHeader;
|
||||
import com.android.internal.telephony.cdma.sms.UserData;
|
||||
|
||||
import com.android.internal.util.HexDump;
|
||||
import com.android.internal.util.BitwiseInputStream;
|
||||
import com.android.internal.util.BitwiseOutputStream;
|
||||
|
||||
/**
|
||||
* XXX
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final class BearerData{
|
||||
private final static String LOG_TAG = "SMS";
|
||||
|
||||
/**
|
||||
* Bearer Data Subparameter Indentifiers
|
||||
* (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
|
||||
*/
|
||||
private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00;
|
||||
private final static byte SUBPARAM_USER_DATA = 0x01;
|
||||
private final static byte SUBPARAM_USER_REPONSE_CODE = 0x02;
|
||||
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_RELATIVE = 0x05;
|
||||
//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_PRIORITY_INDICATOR = 0x08;
|
||||
//private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09;
|
||||
private final static byte SUBPARAM_REPLY_OPTION = 0x0A;
|
||||
private final static byte SUBPARAM_NUMBER_OF_MESSAGES = 0x0B;
|
||||
//private final static byte SUBPARAM_ALERT_ON_MESSAGE_DELIVERY = 0x0C;
|
||||
//private final static byte SUBPARAM_LANGUAGE_INDICATOR = 0x0D;
|
||||
private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E;
|
||||
//private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F;
|
||||
//private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10;
|
||||
//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_RESULTS = 0x13;
|
||||
private final static byte SUBPARAM_MESSAGE_STATUS = 0x14;
|
||||
//private final static byte SUBPARAM_TP_FAILURE_CAUSE = 0x15;
|
||||
//private final static byte SUBPARAM_ENHANCED_VMN = 0x16;
|
||||
//private final static byte SUBPARAM_ENHANCED_VMN_ACK = 0x17;
|
||||
|
||||
// For completeness the following fields are listed, though not used yet.
|
||||
/**
|
||||
@@ -94,9 +139,6 @@ public final class BearerData{
|
||||
public static final int ERROR_UNDEFINED = 0xFF;
|
||||
public static final int STATUS_UNDEFINED = 0xFF;
|
||||
|
||||
/** Bit-mask indicating used fields for SmsDataCoding */
|
||||
public int mask;
|
||||
|
||||
/**
|
||||
* 4-bit value indicating the message type in accordance to
|
||||
* table 4.5.1-1
|
||||
@@ -109,7 +151,7 @@ public final class BearerData{
|
||||
* (Special rules apply for WAP-messages.)
|
||||
* (See 3GPP2 C.S0015-B, v2, 4.5.1)
|
||||
*/
|
||||
public int messageID;
|
||||
public int messageId;
|
||||
|
||||
/**
|
||||
* 1-bit value that indicates whether a User Data Header is present.
|
||||
@@ -188,5 +230,440 @@ public final class BearerData{
|
||||
*/
|
||||
public int messageStatus = STATUS_UNDEFINED;
|
||||
|
||||
}
|
||||
private static class CodingException extends Exception {
|
||||
public CodingException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("BearerData:\n");
|
||||
builder.append(" messageType: " + messageType + "\n");
|
||||
builder.append(" messageId: " + (int)messageId + "\n");
|
||||
builder.append(" hasUserDataHeader: " + hasUserDataHeader + "\n");
|
||||
builder.append(" timeStamp: " + timeStamp + "\n");
|
||||
builder.append(" userAckReq: " + userAckReq + "\n");
|
||||
builder.append(" deliveryAckReq: " + deliveryAckReq + "\n");
|
||||
builder.append(" readAckReq: " + readAckReq + "\n");
|
||||
builder.append(" reportReq: " + reportReq + "\n");
|
||||
builder.append(" numberOfMessages: " + numberOfMessages + "\n");
|
||||
builder.append(" callbackNumber: " + callbackNumber + "\n");
|
||||
builder.append(" displayMode: " + displayMode + "\n");
|
||||
builder.append(" errorClass: " + errorClass + "\n");
|
||||
builder.append(" messageStatus: " + messageStatus + "\n");
|
||||
builder.append(" userData: " + userData + "\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static void encodeMessageId(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException
|
||||
{
|
||||
outStream.write(8, 3);
|
||||
outStream.write(4, bData.messageType);
|
||||
outStream.write(8, bData.messageId >> 8);
|
||||
outStream.write(8, bData.messageId);
|
||||
outStream.write(1, bData.hasUserDataHeader ? 1 : 0);
|
||||
outStream.skip(3);
|
||||
}
|
||||
|
||||
private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException
|
||||
{
|
||||
int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits;
|
||||
byte[] headerData = null;
|
||||
if (bData.hasUserDataHeader) {
|
||||
headerData = bData.userData.userDataHeader.toByteArray();
|
||||
dataBits += headerData.length * 8;
|
||||
}
|
||||
int paramBits = dataBits + 13;
|
||||
if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
|
||||
(bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
|
||||
paramBits += 8;
|
||||
}
|
||||
int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
|
||||
int paddingBits = (paramBytes * 8) - paramBits;
|
||||
outStream.write(8, paramBytes);
|
||||
outStream.write(5, bData.userData.msgEncoding);
|
||||
if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
|
||||
(bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
|
||||
outStream.write(8, bData.userData.msgType);
|
||||
}
|
||||
outStream.write(8, bData.userData.numFields);
|
||||
if (headerData != null) outStream.writeByteArray(headerData.length * 8, headerData);
|
||||
outStream.writeByteArray(dataBits, bData.userData.payload);
|
||||
if (paddingBits > 0) outStream.write(paddingBits, 0);
|
||||
}
|
||||
|
||||
private static void encodeReplyOption(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException
|
||||
{
|
||||
outStream.write(8, 1);
|
||||
outStream.write(1, bData.userAckReq ? 1 : 0);
|
||||
outStream.write(1, bData.deliveryAckReq ? 1 : 0);
|
||||
outStream.write(1, bData.readAckReq ? 1 : 0);
|
||||
outStream.write(1, bData.reportReq ? 1 : 0);
|
||||
outStream.write(4, 0);
|
||||
}
|
||||
|
||||
private static byte[] encodeDtmfSmsAddress(String address) {
|
||||
int digits = address.length();
|
||||
int dataBits = digits * 4;
|
||||
int dataBytes = (dataBits / 8);
|
||||
dataBytes += (dataBits % 8) > 0 ? 1 : 0;
|
||||
byte[] rawData = new byte[dataBytes];
|
||||
for (int i = 0; i < digits; i++) {
|
||||
char c = address.charAt(i);
|
||||
int val = 0;
|
||||
if ((c >= '1') && (c <= '9')) val = c - '0';
|
||||
else if (c == '0') val = 10;
|
||||
else if (c == '*') val = 11;
|
||||
else if (c == '#') val = 12;
|
||||
else return null;
|
||||
rawData[i / 2] |= val << (4 - ((i % 2) * 4));
|
||||
}
|
||||
return rawData;
|
||||
}
|
||||
|
||||
private static void encodeCdmaSmsAddress(CdmaSmsAddress addr) throws CodingException {
|
||||
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
|
||||
try {
|
||||
addr.origBytes = addr.address.getBytes("US-ASCII");
|
||||
} catch (java.io.UnsupportedEncodingException ex) {
|
||||
throw new CodingException("invalid SMS address, cannot convert to ASCII");
|
||||
}
|
||||
} else {
|
||||
addr.origBytes = encodeDtmfSmsAddress(addr.address);
|
||||
}
|
||||
}
|
||||
|
||||
private static void encodeCallbackNumber(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException, CodingException
|
||||
{
|
||||
CdmaSmsAddress addr = bData.callbackNumber;
|
||||
encodeCdmaSmsAddress(addr);
|
||||
int paramBits = 9;
|
||||
int dataBits = 0;
|
||||
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
|
||||
paramBits += 7;
|
||||
dataBits = addr.numberOfDigits * 8;
|
||||
} else {
|
||||
dataBits = addr.numberOfDigits * 4;
|
||||
}
|
||||
paramBits += dataBits;
|
||||
int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
|
||||
int paddingBits = (paramBytes * 8) - paramBits;
|
||||
outStream.write(8, paramBytes);
|
||||
outStream.write(1, addr.digitMode);
|
||||
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
|
||||
outStream.write(3, addr.ton);
|
||||
outStream.write(4, addr.numberPlan);
|
||||
}
|
||||
outStream.write(8, addr.numberOfDigits);
|
||||
outStream.writeByteArray(dataBits, addr.origBytes);
|
||||
if (paddingBits > 0) outStream.write(paddingBits, 0);
|
||||
}
|
||||
|
||||
private static void encodeMsgStatus(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException
|
||||
{
|
||||
outStream.write(8, 1);
|
||||
outStream.write(2, bData.errorClass);
|
||||
outStream.write(6, bData.messageStatus);
|
||||
}
|
||||
|
||||
private static void encodeMsgCount(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException
|
||||
{
|
||||
outStream.write(8, 1);
|
||||
outStream.write(8, bData.numberOfMessages);
|
||||
}
|
||||
|
||||
private static void encodeMsgCenterTimeStamp(BearerData bData, BitwiseOutputStream outStream)
|
||||
throws BitwiseOutputStream.AccessException
|
||||
{
|
||||
outStream.write(8, 6);
|
||||
outStream.writeByteArray(6 * 8, bData.timeStamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create serialized representation for BearerData object.
|
||||
* (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
|
||||
*
|
||||
* @param bearerData an instance of BearerData.
|
||||
*
|
||||
* @return data byta array of raw encoded SMS bearer data.
|
||||
*/
|
||||
public static byte[] encode(BearerData bData) {
|
||||
try {
|
||||
BitwiseOutputStream outStream = new BitwiseOutputStream(200);
|
||||
outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
|
||||
encodeMessageId(bData, outStream);
|
||||
if (bData.userData != null) {
|
||||
outStream.write(8, SUBPARAM_USER_DATA);
|
||||
encodeUserData(bData, outStream);
|
||||
}
|
||||
if (bData.callbackNumber != null) {
|
||||
outStream.write(8, SUBPARAM_CALLBACK_NUMBER);
|
||||
encodeCallbackNumber(bData, outStream);
|
||||
}
|
||||
if (bData.userAckReq || bData.deliveryAckReq || bData.readAckReq || bData.reportReq) {
|
||||
outStream.write(8, SUBPARAM_REPLY_OPTION);
|
||||
encodeReplyOption(bData, outStream);
|
||||
}
|
||||
if (bData.numberOfMessages != 0) {
|
||||
outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES);
|
||||
encodeMsgCount(bData, outStream);
|
||||
}
|
||||
if (bData.timeStamp != null) {
|
||||
outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP);
|
||||
encodeMsgCenterTimeStamp(bData, outStream);
|
||||
}
|
||||
return outStream.toByteArray();
|
||||
} catch (BitwiseOutputStream.AccessException ex) {
|
||||
Log.e(LOG_TAG, "BearerData encode failed: " + ex);
|
||||
} catch (CodingException ex) {
|
||||
Log.e(LOG_TAG, "BearerData encode failed: " + ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void decodeMessageId(BearerData bData, BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException, CodingException
|
||||
{
|
||||
if (inStream.read(8) != 3) {
|
||||
throw new CodingException("MESSAGE_IDENTIFIER subparam size incorrect");
|
||||
}
|
||||
bData.messageType = inStream.read(4);
|
||||
bData.messageId = inStream.read(8) << 8;
|
||||
bData.messageId |= inStream.read(8);
|
||||
bData.hasUserDataHeader = (inStream.read(1) == 1);
|
||||
inStream.skip(3);
|
||||
}
|
||||
|
||||
private static void decodeUserData(BearerData bData, BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException
|
||||
{
|
||||
byte paramBytes = inStream.read(8);
|
||||
bData.userData = new UserData();
|
||||
bData.userData.msgEncoding = inStream.read(5);
|
||||
bData.userData.msgType = 0;
|
||||
int consumedBits = 5;
|
||||
if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
|
||||
(bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
|
||||
bData.userData.msgType = inStream.read(8);
|
||||
consumedBits += 8;
|
||||
}
|
||||
bData.userData.numFields = inStream.read(8);
|
||||
consumedBits += 8;
|
||||
int dataBits = (paramBytes * 8) - consumedBits;
|
||||
bData.userData.payload = inStream.readByteArray(dataBits);
|
||||
}
|
||||
|
||||
private static String decodePayloadStr(byte[] data, int offset, int numFields, String format)
|
||||
throws CodingException
|
||||
{
|
||||
try {
|
||||
return new String(data, offset, numFields, format);
|
||||
} catch (java.io.UnsupportedEncodingException ex) {
|
||||
throw new CodingException("invalid ASCII user data code");
|
||||
}
|
||||
}
|
||||
|
||||
private static void decodeUserDataPayload(UserData userData, boolean hasUserDataHeader)
|
||||
throws CodingException
|
||||
{
|
||||
int offset = 0;
|
||||
if (hasUserDataHeader) {
|
||||
int UdhLen = userData.payload[0];
|
||||
byte[] headerData = new byte[UdhLen];
|
||||
System.arraycopy(userData.payload, 1, headerData, 0, UdhLen);
|
||||
userData.userDataHeader = SmsHeader.parse(headerData);
|
||||
}
|
||||
switch (userData.msgEncoding) {
|
||||
case UserData.ENCODING_GSM_7BIT_ALPHABET:
|
||||
userData.payloadStr = GsmAlphabet.gsm7BitPackedToString(userData.payload,
|
||||
offset, userData.numFields);
|
||||
break;
|
||||
case UserData.ENCODING_7BIT_ASCII:
|
||||
userData.payloadStr = decodePayloadStr(userData.payload, offset,
|
||||
userData.numFields, "US-ASCII");
|
||||
break;
|
||||
case UserData.ENCODING_UNICODE_16:
|
||||
userData.payloadStr = decodePayloadStr(userData.payload, offset,
|
||||
userData.numFields * 2, "UTF-16");
|
||||
break;
|
||||
default:
|
||||
throw new CodingException("unsupported user data encoding ("
|
||||
+ userData.msgEncoding + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException, CodingException
|
||||
{
|
||||
byte paramBytes = inStream.read(8);
|
||||
if (paramBytes != 1) {
|
||||
throw new CodingException("REPLY_OPTION subparam size incorrect");
|
||||
}
|
||||
bData.userAckReq = (inStream.read(1) == 1);
|
||||
bData.deliveryAckReq = (inStream.read(1) == 1);
|
||||
bData.readAckReq = (inStream.read(1) == 1);
|
||||
bData.reportReq = (inStream.read(1) == 1);
|
||||
inStream.skip(4);
|
||||
}
|
||||
|
||||
private static void decodeMsgCount(BearerData bData, BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException, CodingException
|
||||
{
|
||||
if (inStream.read(8) != 1) {
|
||||
throw new CodingException("NUMBER_OF_MESSAGES subparam size incorrect");
|
||||
}
|
||||
bData.numberOfMessages = inStream.read(8);
|
||||
}
|
||||
|
||||
private static String decodeDtmfSmsAddress(byte[] rawData, int numFields)
|
||||
throws CodingException
|
||||
{
|
||||
/* DTMF 4-bit digit encoding, defined in at
|
||||
* 3GPP2 C.S005-D, v2.0, table 2.7.1.3.2.4-4 */
|
||||
StringBuffer strBuf = new StringBuffer(numFields);
|
||||
for (int i = 0; i < numFields; i++) {
|
||||
int val = 0x0F & (rawData[i / 2] >>> (4 - ((i % 2) * 4)));
|
||||
if ((val >= 1) && (val <= 9)) strBuf.append(Integer.toString(val, 10));
|
||||
else if (val == 10) strBuf.append('0');
|
||||
else if (val == 11) strBuf.append('*');
|
||||
else if (val == 12) strBuf.append('#');
|
||||
else throw new CodingException("invalid SMS address DTMF code (" + val + ")");
|
||||
}
|
||||
return strBuf.toString();
|
||||
}
|
||||
|
||||
private static void decodeSmsAddress(CdmaSmsAddress addr) throws CodingException {
|
||||
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
|
||||
try {
|
||||
/* As specified in 3GPP2 C.S0015-B, v2, 4.5.15 -- actually
|
||||
* just 7-bit ASCII encoding, with the MSB being zero. */
|
||||
addr.address = new String(addr.origBytes, 0, addr.origBytes.length, "US-ASCII");
|
||||
} catch (java.io.UnsupportedEncodingException ex) {
|
||||
throw new CodingException("invalid SMS address ASCII code");
|
||||
}
|
||||
} else {
|
||||
addr.address = decodeDtmfSmsAddress(addr.origBytes, addr.numberOfDigits);
|
||||
}
|
||||
}
|
||||
|
||||
private static void decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException, CodingException
|
||||
{
|
||||
byte paramBytes = inStream.read(8);
|
||||
CdmaSmsAddress addr = new CdmaSmsAddress();
|
||||
addr.digitMode = inStream.read(1);
|
||||
byte fieldBits = 4;
|
||||
byte consumedBits = 1;
|
||||
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
|
||||
addr.ton = inStream.read(3);
|
||||
addr.numberPlan = inStream.read(4);
|
||||
fieldBits = 8;
|
||||
consumedBits += 7;
|
||||
}
|
||||
addr.numberOfDigits = inStream.read(8);
|
||||
consumedBits += 8;
|
||||
int remainingBits = (paramBytes * 8) - consumedBits;
|
||||
int dataBits = addr.numberOfDigits * fieldBits;
|
||||
int paddingBits = remainingBits - dataBits;
|
||||
if (remainingBits < dataBits) {
|
||||
throw new CodingException("CALLBACK_NUMBER subparam encoding size error (" +
|
||||
"remainingBits " + remainingBits + ", dataBits " +
|
||||
dataBits + ", paddingBits " + paddingBits + ")");
|
||||
}
|
||||
addr.origBytes = inStream.readByteArray(dataBits);
|
||||
inStream.skip(paddingBits);
|
||||
decodeSmsAddress(addr);
|
||||
bData.callbackNumber = addr;
|
||||
}
|
||||
|
||||
private static void decodeMsgStatus(BearerData bData, BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException, CodingException
|
||||
{
|
||||
if (inStream.read(8) != 1) {
|
||||
throw new CodingException("MESSAGE_STATUS subparam size incorrect");
|
||||
}
|
||||
bData.errorClass = inStream.read(2);
|
||||
bData.messageStatus = inStream.read(6);
|
||||
}
|
||||
|
||||
private static void decodeMsgCenterTimeStamp(BearerData bData,
|
||||
BitwiseInputStream inStream)
|
||||
throws BitwiseInputStream.AccessException, CodingException
|
||||
{
|
||||
if (inStream.read(8) != 6) {
|
||||
throw new CodingException("MESSAGE_CENTER_TIME_STAMP subparam size incorrect");
|
||||
}
|
||||
bData.timeStamp = inStream.readByteArray(6 * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create BearerData object from serialized representation.
|
||||
* (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
|
||||
*
|
||||
* @param smsData byte array of raw encoded SMS bearer data.
|
||||
*
|
||||
* @return an instance of BearerData.
|
||||
*/
|
||||
public static BearerData decode(byte[] smsData) {
|
||||
try {
|
||||
BitwiseInputStream inStream = new BitwiseInputStream(smsData);
|
||||
BearerData bData = new BearerData();
|
||||
int foundSubparamMask = 0;
|
||||
while (inStream.available() > 0) {
|
||||
int subparamId = inStream.read(8);
|
||||
int subparamIdBit = 1 << subparamId;
|
||||
if ((foundSubparamMask & subparamIdBit) != 0) {
|
||||
throw new CodingException("illegal duplicate subparameter (" +
|
||||
subparamId + ")");
|
||||
}
|
||||
foundSubparamMask |= subparamIdBit;
|
||||
switch (subparamId) {
|
||||
case SUBPARAM_MESSAGE_IDENTIFIER:
|
||||
decodeMessageId(bData, inStream);
|
||||
break;
|
||||
case SUBPARAM_USER_DATA:
|
||||
decodeUserData(bData, inStream);
|
||||
break;
|
||||
case SUBPARAM_REPLY_OPTION:
|
||||
decodeReplyOption(bData, inStream);
|
||||
break;
|
||||
case SUBPARAM_NUMBER_OF_MESSAGES:
|
||||
decodeMsgCount(bData, inStream);
|
||||
break;
|
||||
case SUBPARAM_CALLBACK_NUMBER:
|
||||
decodeCallbackNumber(bData, inStream);
|
||||
break;
|
||||
case SUBPARAM_MESSAGE_STATUS:
|
||||
decodeMsgStatus(bData, inStream);
|
||||
break;
|
||||
case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
|
||||
decodeMsgCenterTimeStamp(bData, inStream);
|
||||
break;
|
||||
default:
|
||||
throw new CodingException("unsupported bearer data subparameter ("
|
||||
+ subparamId + ")");
|
||||
}
|
||||
}
|
||||
if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) {
|
||||
throw new CodingException("missing MESSAGE_IDENTIFIER subparam");
|
||||
}
|
||||
if (bData.userData != null) {
|
||||
decodeUserDataPayload(bData.userData, bData.hasUserDataHeader);
|
||||
}
|
||||
return bData;
|
||||
} catch (BitwiseInputStream.AccessException ex) {
|
||||
Log.e(LOG_TAG, "BearerData decode failed: " + ex);
|
||||
} catch (CodingException ex) {
|
||||
Log.e(LOG_TAG, "BearerData decode failed: " + ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.internal.telephony.cdma.sms;
|
||||
|
||||
import com.android.internal.telephony.SmsAddress;
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
public class CdmaSmsAddress extends SmsAddress {
|
||||
/**
|
||||
@@ -95,4 +96,18 @@ public class CdmaSmsAddress extends SmsAddress {
|
||||
public CdmaSmsAddress(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CdmaSmsAddress:\n");
|
||||
builder.append(" digitMode: " + digitMode + "\n");
|
||||
builder.append(" numberMode: " + numberMode + "\n");
|
||||
builder.append(" numberPlan: " + numberPlan + "\n");
|
||||
builder.append(" numberOfDigits: " + numberOfDigits + "\n");
|
||||
builder.append(" ton: " + ton + "\n");
|
||||
builder.append(" address: " + address + "\n");
|
||||
builder.append(" origBytes: " + HexDump.toHexString(origBytes) + "\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony.cdma.sms;
|
||||
|
||||
import com.android.internal.telephony.SmsHeader;
|
||||
|
||||
/*
|
||||
* The SMSDataCoding class encodes and decodes CDMA SMS messages.
|
||||
*/
|
||||
public class SmsDataCoding {
|
||||
private final static String TAG = "CDMA_SMS_JNI";
|
||||
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_NULL = 0x00000000;
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_MSG_ID = 0x00000001;
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_USER_DATA = 0x00000002;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_USER_RESP = 0x00000004;
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_MC_TIME = 0x00000008;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_VALID_ABS = 0x00000010;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_VALID_REL = 0x00000020;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_DEFER_ABS = 0x00000040;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_DEFER_REL = 0x00000080;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_PRIORITY = 0x00000100;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_PRIVACY = 0x00000200;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_REPLY_OPTION = 0x00000400;
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS = 0x00000800;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_ALERT = 0x00001000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_LANGUAGE = 0x00002000;
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_CALLBACK = 0x00004000;
|
||||
private final static int CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE = 0x00008000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_SCPT_DATA = 0x00010000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_SCPT_RESULT = 0x00020000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_DEPOSIT_INDEX = 0x00040000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_DELIVERY_STATUS = 0x00080000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_IP_ADDRESS = 0x10000000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_RSN_NO_NOTIFY = 0x20000000;
|
||||
// private final static int CDMA_SMS_WMS_MASK_BD_OTHER = 0x40000000;
|
||||
|
||||
/**
|
||||
* Successful operation.
|
||||
*/
|
||||
private static final int JNI_CDMA_SMS_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* General failure.
|
||||
*/
|
||||
private static final int JNI_CDMA_SMS_FAILURE = 1;
|
||||
|
||||
/**
|
||||
* Data length is out of length.
|
||||
*/
|
||||
private static final int JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE = 2;
|
||||
|
||||
/**
|
||||
* Class name unknown.
|
||||
*/
|
||||
private static final int JNI_CDMA_SMS_CLASS_UNKNOWN = 3;
|
||||
|
||||
/**
|
||||
* Field ID unknown.
|
||||
*/
|
||||
private static final int JNI_CDMA_SMS_FIELD_ID_UNKNOWN = 4;
|
||||
|
||||
/**
|
||||
* Memory allocation failed.
|
||||
*/
|
||||
private static final int JNI_CDMA_SMS_OUT_OF_MEMORY = 5;
|
||||
|
||||
/**
|
||||
* Encode SMS.
|
||||
*
|
||||
* @param bearerData an instance of BearerData.
|
||||
*
|
||||
* @return the encoded SMS as byte[].
|
||||
*/
|
||||
public static byte[] encodeCdmaSms(BearerData bearerData) {
|
||||
byte[] encodedSms;
|
||||
|
||||
if( nativeCdmaSmsConstructClientBD() == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
// check bearer data and generate bit mask
|
||||
generateBearerDataBitMask(bearerData);
|
||||
encodedSms = startEncoding(bearerData);
|
||||
|
||||
if( nativeCdmaSmsDestructClientBD() == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
return encodedSms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode SMS.
|
||||
*
|
||||
* @param SmsData the encoded SMS.
|
||||
*
|
||||
* @return an instance of BearerData.
|
||||
*/
|
||||
public static BearerData decodeCdmaSms(byte[] SmsData) {
|
||||
BearerData bearerData;
|
||||
|
||||
if( nativeCdmaSmsConstructClientBD() == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
bearerData = startDecoding(SmsData);
|
||||
|
||||
if( nativeCdmaSmsDestructClientBD() == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
return bearerData;
|
||||
}
|
||||
|
||||
private static void generateBearerDataBitMask(BearerData bearerData) {
|
||||
// initial
|
||||
bearerData.mask = CDMA_SMS_WMS_MASK_BD_NULL;
|
||||
|
||||
// check message type
|
||||
if (bearerData.messageType != 0){
|
||||
bearerData.mask |= CDMA_SMS_WMS_MASK_BD_MSG_ID;
|
||||
}
|
||||
|
||||
// check mUserData
|
||||
if (bearerData.userData != null){
|
||||
bearerData.mask |= CDMA_SMS_WMS_MASK_BD_USER_DATA;
|
||||
}
|
||||
|
||||
// check mTimeStamp
|
||||
if (bearerData.timeStamp != null){
|
||||
bearerData.mask |= CDMA_SMS_WMS_MASK_BD_MC_TIME;
|
||||
}
|
||||
|
||||
// check mNumberOfMessages
|
||||
if (bearerData.numberOfMessages > 0){
|
||||
bearerData.mask |= CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS;
|
||||
}
|
||||
|
||||
// check mCallbackNumber
|
||||
if(bearerData.callbackNumber != null){
|
||||
bearerData.mask |= CDMA_SMS_WMS_MASK_BD_CALLBACK;
|
||||
}
|
||||
|
||||
// check DisplayMode
|
||||
if(bearerData.displayMode == BearerData.DISPLAY_DEFAULT ||
|
||||
bearerData.displayMode == BearerData.DISPLAY_IMMEDIATE ||
|
||||
bearerData.displayMode == BearerData.DISPLAY_USER){
|
||||
bearerData.mask |= CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] startEncoding(BearerData bearerData) {
|
||||
int m_id;
|
||||
byte[] m_data;
|
||||
int dataLength;
|
||||
byte[] encodedSms;
|
||||
int nbrOfHeaders = 0;
|
||||
|
||||
if( nativeCdmaSmsSetBearerDataPrimitives(bearerData) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((bearerData.mask & CDMA_SMS_WMS_MASK_BD_USER_DATA) == CDMA_SMS_WMS_MASK_BD_USER_DATA){
|
||||
if( nativeCdmaSmsSetUserData(bearerData.userData) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
if (bearerData.userData.userDataHeader != null){
|
||||
nbrOfHeaders = bearerData.userData.userDataHeader.nbrOfHeaders;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nbrOfHeaders; i++) {
|
||||
m_id = bearerData.userData.userDataHeader.getElements().get(i).getID();
|
||||
m_data = bearerData.userData.userDataHeader.getElements().get(i).getData();
|
||||
dataLength = m_data.length;
|
||||
if( nativeCdmaSmsSetUserDataHeader(m_id, m_data, dataLength, i)
|
||||
== JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((bearerData.mask & CDMA_SMS_WMS_MASK_BD_CALLBACK) == CDMA_SMS_WMS_MASK_BD_CALLBACK) {
|
||||
if( nativeCdmaSmsSetSmsAddress(bearerData.callbackNumber) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* call native method to encode SMS */
|
||||
encodedSms = nativeCdmaSmsEncodeSms();
|
||||
|
||||
return encodedSms;
|
||||
}
|
||||
|
||||
private static BearerData startDecoding(byte[] SmsData) {
|
||||
BearerData bData = new BearerData();
|
||||
byte[] udhData;
|
||||
|
||||
/* call native method to decode SMS */
|
||||
if( nativeCdmaSmsDecodeSms(SmsData) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
if( nativeCdmaSmsGetBearerDataPrimitives(bData) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((bData.mask & CDMA_SMS_WMS_MASK_BD_USER_DATA) == CDMA_SMS_WMS_MASK_BD_USER_DATA) {
|
||||
bData.userData = new UserData();
|
||||
if( nativeCdmaSmsGetUserData(bData.userData) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
|
||||
udhData = nativeCdmaSmsGetUserDataHeader();
|
||||
if (udhData != null) {
|
||||
bData.userData.userDataHeader = SmsHeader.parse(udhData);
|
||||
}
|
||||
}
|
||||
|
||||
if ((bData.mask & CDMA_SMS_WMS_MASK_BD_CALLBACK) == CDMA_SMS_WMS_MASK_BD_CALLBACK) {
|
||||
bData.callbackNumber = new CdmaSmsAddress();
|
||||
if( nativeCdmaSmsGetSmsAddress(bData.callbackNumber) == JNI_CDMA_SMS_FAILURE){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
// native methods
|
||||
|
||||
/**
|
||||
* native method: Allocate memory for clientBD structure
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsConstructClientBD();
|
||||
|
||||
/**
|
||||
* native method: Free memory used for clientBD structure
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsDestructClientBD();
|
||||
|
||||
/**
|
||||
* native method: fill clientBD structure with bearerData primitives
|
||||
*
|
||||
* @param bearerData an instance of BearerData.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsSetBearerDataPrimitives(BearerData bearerData);
|
||||
|
||||
/**
|
||||
* native method: fill bearerData primitives with clientBD variables
|
||||
*
|
||||
* @param bearerData an instance of BearerData.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsGetBearerDataPrimitives(BearerData bearerData);
|
||||
|
||||
/**
|
||||
* native method: fill clientBD.user_data with UserData primitives
|
||||
*
|
||||
* @param userData an instance of UserData.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsSetUserData(UserData userData);
|
||||
|
||||
/**
|
||||
* native method: fill UserData primitives with clientBD.user_data
|
||||
*
|
||||
* @param userData an instance of UserData.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsGetUserData(UserData userData);
|
||||
|
||||
/**
|
||||
* native method: fill clientBD.user_data.headers with UserDataHeader primitives
|
||||
*
|
||||
* @param ID ID of element.
|
||||
* @param data element data.
|
||||
* @param dataLength data length
|
||||
* @param index index of element
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsSetUserDataHeader(
|
||||
int ID, byte[] data, int dataLength, int index);
|
||||
|
||||
/**
|
||||
* native method: fill UserDataHeader primitives with clientBD.user_data.headers
|
||||
*
|
||||
* @return user data headers
|
||||
*/
|
||||
private static native byte[] nativeCdmaSmsGetUserDataHeader();
|
||||
|
||||
/**
|
||||
* native method: fill clientBD.callback with SmsAddress primitives
|
||||
*
|
||||
* @param smsAddr an instance of SmsAddress.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsSetSmsAddress(CdmaSmsAddress smsAddr);
|
||||
|
||||
/**
|
||||
* native method: fill SmsAddress primitives with clientBD.callback
|
||||
*
|
||||
* @param smsAddr an instance of SmsAddress.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsGetSmsAddress(CdmaSmsAddress smsAddr);
|
||||
|
||||
/**
|
||||
* native method: call encoding functions and get encoded SMS
|
||||
*
|
||||
* @return the encoded SMS
|
||||
*/
|
||||
private static native byte[] nativeCdmaSmsEncodeSms();
|
||||
|
||||
/**
|
||||
* native method: call decode functions
|
||||
*
|
||||
* @param encodedSMS encoded SMS.
|
||||
*
|
||||
* @return #JNI_CDMA_SMS_SUCCESS if succeed.
|
||||
* #JNI_CDMA_SMS_FAILURE if fail.
|
||||
*/
|
||||
private static native int nativeCdmaSmsDecodeSms(byte[] encodedSMS);
|
||||
|
||||
/**
|
||||
* Load the shared library to link the native methods.
|
||||
*/
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cdma_sms_jni");
|
||||
}
|
||||
catch (UnsatisfiedLinkError ule) {
|
||||
System.err.println("WARNING: Could not load cdma_sms_jni.so");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,24 +17,25 @@
|
||||
package com.android.internal.telephony.cdma.sms;
|
||||
|
||||
import com.android.internal.telephony.SmsHeader;
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
public class UserData{
|
||||
|
||||
/**
|
||||
* Supported user data encoding types
|
||||
* User data encoding types
|
||||
* (See 3GPP2 C.R1001-F, v1.0, table 9.1-1)
|
||||
*/
|
||||
public static final int UD_ENCODING_OCTET = 0x00;
|
||||
//public static final int UD_ENCODING_EXTENDED_PROTOCOL = 0x01;
|
||||
public static final int UD_ENCODING_7BIT_ASCII = 0x02;
|
||||
public static final int UD_ENCODING_IA5 = 0x03;
|
||||
public static final int UD_ENCODING_UNICODE_16 = 0x04;
|
||||
//public static final int UD_ENCODING_SHIFT_JIS = 0x05;
|
||||
//public static final int UD_ENCODING_KOREAN = 0x06;
|
||||
//public static final int UD_ENCODING_LATIN_HEBREW = 0x07;
|
||||
//public static final int UD_ENCODING_LATIN = 0x08;
|
||||
public static final int UD_ENCODING_GSM_7BIT_ALPHABET = 0x09;
|
||||
//public static final int UD_ENCODING_GSM_DCS = 0x0A;
|
||||
public static final int ENCODING_OCTET = 0x00;
|
||||
public static final int ENCODING_IS91_EXTENDED_PROTOCOL = 0x01;
|
||||
public static final int ENCODING_7BIT_ASCII = 0x02;
|
||||
//public static final int ENCODING_IA5 = 0x03;
|
||||
public static final int ENCODING_UNICODE_16 = 0x04;
|
||||
//public static final int ENCODING_SHIFT_JIS = 0x05;
|
||||
//public static final int ENCODING_KOREAN = 0x06;
|
||||
//public static final int ENCODING_LATIN_HEBREW = 0x07;
|
||||
//public static final int ENCODING_LATIN = 0x08;
|
||||
public static final int ENCODING_GSM_7BIT_ALPHABET = 0x09;
|
||||
public static final int ENCODING_GSM_DCS = 0x0A;
|
||||
|
||||
/**
|
||||
* Contains the data header of the user data
|
||||
@@ -44,20 +45,37 @@ public class UserData{
|
||||
/**
|
||||
* Contains the data encoding type for the SMS message
|
||||
*/
|
||||
public int userDataEncoding;
|
||||
public int msgEncoding;
|
||||
|
||||
// needed when encoding is IS91 or DCS (not supported yet):
|
||||
//public int messageType;
|
||||
// XXX needed when encoding is IS91 or DCS (not supported yet):
|
||||
public int msgType;
|
||||
|
||||
/**
|
||||
* Number of invalid bits in the last byte of data.
|
||||
*/
|
||||
public int paddingBits;
|
||||
|
||||
public int numFields;
|
||||
|
||||
/**
|
||||
* Contains the user data of a SMS message
|
||||
* (See 3GPP2 C.S0015-B, v2, 4.5.2)
|
||||
*/
|
||||
public byte[] userData;
|
||||
public byte[] payload;
|
||||
public String payloadStr;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("UserData:\n");
|
||||
builder.append(" msgEncoding: " + msgEncoding + "\n");
|
||||
builder.append(" msgType: " + msgType + "\n");
|
||||
builder.append(" paddingBits: " + paddingBits + "\n");
|
||||
builder.append(" numFields: " + (int)numFields + "\n");
|
||||
builder.append(" userDataHeader: " + userDataHeader + "\n");
|
||||
builder.append(" payload: " + HexDump.toHexString(payload));
|
||||
builder.append(" payloadStr: " + payloadStr);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
cdma_sms_jni.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
libutils \
|
||||
libandroid_runtime \
|
||||
libnativehelper
|
||||
|
||||
LOCAL_MODULE:= libcdma_sms_jni
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(JNI_H_INCLUDE) \
|
||||
hardware/ril/include/telephony
|
||||
|
||||
LOCAL_C_INCLUDES += hardware/ril/reference-cdma-sms
|
||||
LOCAL_SHARED_LIBRARIES += libreference-cdma-sms
|
||||
LOCAL_CFLAGS += -DREFERENCE_CDMA_SMS
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_android_internal_telephony_cdma_sms_SmsDataCoding */
|
||||
|
||||
#ifndef _Included_com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
#define _Included_com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NULL
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NULL 0L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MSG_ID
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MSG_ID 1L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_USER_DATA
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_USER_DATA 2L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MC_TIME
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MC_TIME 8L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS 2048L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_CALLBACK
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_CALLBACK 16384L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE 32768L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS 0L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE 1L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE 2L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_CLASS_UNKNOWN
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_CLASS_UNKNOWN 3L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FIELD_ID_UNKNOWN
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FIELD_ID_UNKNOWN 4L
|
||||
#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_OUT_OF_MEMORY
|
||||
#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_OUT_OF_MEMORY 5L
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsConstructClientBD
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsDestructClientBD
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsSetBearerDataPrimitives
|
||||
* Signature: (Lcom/android/internal/telephony/cdma/sms/BearerData;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsGetBearerDataPrimitives
|
||||
* Signature: (Lcom/android/internal/telephony/cdma/sms/BearerData;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsSetUserData
|
||||
* Signature: (Lcom/android/internal/telephony/cdma/sms/UserData;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsGetUserData
|
||||
* Signature: (Lcom/android/internal/telephony/cdma/sms/UserData;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsSetUserDataHeader
|
||||
* Signature: (I[BII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader
|
||||
(JNIEnv *, jobject, jint, jbyteArray, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsGetUserDataHeader
|
||||
* Signature: ()[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsSetSmsAddress
|
||||
* Signature: (Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsGetSmsAddress
|
||||
* Signature: (Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsEncodeSms
|
||||
* Signature: ()[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
|
||||
* Method: nativeCdmaSmsDecodeSms
|
||||
* Signature: ([B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms
|
||||
(JNIEnv *, jobject, jbyteArray);
|
||||
|
||||
/**
|
||||
* CDMA SMS return value defines
|
||||
*/
|
||||
#define JNI_SUCCESS \
|
||||
com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS /**< Successful operation */
|
||||
#define JNI_FAILURE \
|
||||
com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE /**< General failure */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.unit_tests;
|
||||
|
||||
import com.android.internal.util.BitwiseInputStream;
|
||||
import com.android.internal.util.BitwiseOutputStream;
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
public class BitwiseStreamsTest extends AndroidTestCase {
|
||||
private final static String LOG_TAG = "BitwiseStreamsTest";
|
||||
|
||||
@SmallTest
|
||||
public void testOne() throws Exception {
|
||||
int offset = 3;
|
||||
byte[] inBuf = HexDump.hexStringToByteArray("FFDD");
|
||||
BitwiseOutputStream outStream = new BitwiseOutputStream(30);
|
||||
outStream.skip(offset);
|
||||
for (int i = 0; i < inBuf.length; i++) outStream.write(8, inBuf[i]);
|
||||
byte[] outBuf = outStream.toByteArray();
|
||||
BitwiseInputStream inStream = new BitwiseInputStream(outBuf);
|
||||
byte[] inBufDup = new byte[inBuf.length];
|
||||
inStream.skip(offset);
|
||||
for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
|
||||
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testTwo() throws Exception {
|
||||
int offset = 3;
|
||||
byte[] inBuf = HexDump.hexStringToByteArray("11d4f29c0e9ad3c36e72584e064d9b53");
|
||||
BitwiseOutputStream outStream = new BitwiseOutputStream(30);
|
||||
outStream.skip(offset);
|
||||
for (int i = 0; i < inBuf.length; i++) outStream.write(8, inBuf[i]);
|
||||
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
|
||||
inStream.skip(offset);
|
||||
byte[] inBufDup = new byte[inBuf.length];
|
||||
for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
|
||||
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testThree() throws Exception {
|
||||
int offset = 4;
|
||||
byte[] inBuf = HexDump.hexStringToByteArray("00031040900112488ea794e0");
|
||||
BitwiseOutputStream outStream = new BitwiseOutputStream(30);
|
||||
outStream.skip(offset);
|
||||
for (int i = 0; i < inBuf.length; i++) outStream.write(8, inBuf[i]);
|
||||
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
|
||||
inStream.skip(offset);
|
||||
byte[] inBufDup = new byte[inBuf.length];
|
||||
for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
|
||||
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testFour() throws Exception {
|
||||
int offset = 7;
|
||||
byte[] inBuf = HexDump.hexStringToByteArray("00031040900112488ea794e0");
|
||||
BitwiseOutputStream outStream = new BitwiseOutputStream(30);
|
||||
outStream.skip(offset);
|
||||
for (int i = 0; i < inBuf.length; i++) {
|
||||
outStream.write(5, inBuf[i] >>> 3);
|
||||
outStream.write(3, inBuf[i] & 0x07);
|
||||
}
|
||||
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
|
||||
inStream.skip(offset);
|
||||
byte[] inBufDup = new byte[inBuf.length];
|
||||
for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
|
||||
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
|
||||
}
|
||||
}
|
||||
273
tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
Normal file
273
tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.unit_tests;
|
||||
|
||||
import com.android.internal.telephony.GsmAlphabet;
|
||||
import com.android.internal.telephony.SmsHeader;
|
||||
import com.android.internal.telephony.cdma.sms.BearerData;
|
||||
import com.android.internal.telephony.cdma.sms.UserData;
|
||||
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
|
||||
import com.android.internal.util.BitwiseInputStream;
|
||||
import com.android.internal.util.BitwiseOutputStream;
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class CdmaSmsTest extends AndroidTestCase {
|
||||
private final static String LOG_TAG = "Cdma_Sms_Test";
|
||||
|
||||
private static UserData makeUserData(String msg) {
|
||||
UserData userData = new UserData();
|
||||
byte[] payload;
|
||||
try {
|
||||
payload = GsmAlphabet.stringToGsm7BitPacked(msg);
|
||||
userData.payload = new byte[payload.length - 1];
|
||||
for (int i = 0; i < userData.payload.length; i++) userData.payload[i] = payload[i + 1];
|
||||
userData.numFields = payload[0];
|
||||
userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7);
|
||||
userData.paddingBits = 0; // XXX this is better, wtf?
|
||||
userData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
|
||||
} catch (com.android.internal.telephony.EncodeException ex) {
|
||||
assertEquals(1, 0);
|
||||
}
|
||||
return userData;
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testStandardSms() throws Exception {
|
||||
String pdu = "00031040900112488ea794e074d69e1b7392c270326cde9e98";
|
||||
BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
|
||||
assertEquals("Test standard SMS", bearerData.userData.payloadStr);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testStandardSmsFeedback() throws Exception {
|
||||
BearerData bearerData = new BearerData();
|
||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
||||
bearerData.messageId = 0;
|
||||
bearerData.hasUserDataHeader = false;
|
||||
String payloadStr = "Test standard SMS";
|
||||
bearerData.userData = makeUserData(payloadStr);
|
||||
byte []encodedSms = BearerData.encode(bearerData);
|
||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
|
||||
assertEquals(0, revBearerData.messageId);
|
||||
assertEquals(false, revBearerData.hasUserDataHeader);
|
||||
assertEquals(UserData.ENCODING_GSM_7BIT_ALPHABET, revBearerData.userData.msgEncoding);
|
||||
assertEquals(payloadStr.length(), revBearerData.userData.numFields);
|
||||
assertEquals(payloadStr, revBearerData.userData.payloadStr);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testAltUserDataFeedback() throws Exception {
|
||||
try {
|
||||
BearerData bearerData = new BearerData();
|
||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
||||
bearerData.messageId = 0;
|
||||
bearerData.hasUserDataHeader = false;
|
||||
UserData userData = new UserData();
|
||||
String str1 = "test ascii user data encoding";
|
||||
userData.payload = str1.getBytes("US-ASCII");
|
||||
userData.numFields = str1.length();
|
||||
userData.paddingBits = 0;
|
||||
userData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
|
||||
bearerData.userData = userData;
|
||||
byte []encodedSms = BearerData.encode(bearerData);
|
||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(str1, revBearerData.userData.payloadStr);
|
||||
String str2 = "\u0160u\u1E5B\u0301r\u1ECFg\uD835\uDC1At\u00E9\u4E002\u3042";
|
||||
userData.payload = str2.getBytes("UTF-16");
|
||||
userData.numFields = str2.length() + 1;
|
||||
userData.msgEncoding = UserData.ENCODING_UNICODE_16;
|
||||
encodedSms = BearerData.encode(bearerData);
|
||||
revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(str2, revBearerData.userData.payloadStr);
|
||||
} catch (java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException("user data encoding error");
|
||||
}
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testReplyOption() throws Exception {
|
||||
String pdu1 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87450080a0180";
|
||||
BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
|
||||
assertEquals("Test Acknowledgement 1", bd1.userData.payloadStr);
|
||||
assertEquals(true, bd1.userAckReq);
|
||||
assertEquals(false, bd1.deliveryAckReq);
|
||||
assertEquals(false, bd1.readAckReq);
|
||||
assertEquals(false, bd1.reportReq);
|
||||
String pdu2 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87490080a0140";
|
||||
BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
|
||||
assertEquals("Test Acknowledgement 2", bd2.userData.payloadStr);
|
||||
assertEquals(false, bd2.userAckReq);
|
||||
assertEquals(true, bd2.deliveryAckReq);
|
||||
assertEquals(false, bd2.readAckReq);
|
||||
assertEquals(false, bd2.reportReq);
|
||||
String pdu3 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d874d0080a0120";
|
||||
BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
|
||||
assertEquals("Test Acknowledgement 3", bd3.userData.payloadStr);
|
||||
assertEquals(false, bd3.userAckReq);
|
||||
assertEquals(false, bd3.deliveryAckReq);
|
||||
assertEquals(true, bd3.readAckReq);
|
||||
assertEquals(false, bd3.reportReq);
|
||||
String pdu4 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87510080a0110";
|
||||
BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
|
||||
assertEquals("Test Acknowledgement 4", bd4.userData.payloadStr);
|
||||
assertEquals(false, bd4.userAckReq);
|
||||
assertEquals(false, bd4.deliveryAckReq);
|
||||
assertEquals(false, bd4.readAckReq);
|
||||
assertEquals(true, bd4.reportReq);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testReplyOptionFeedback() throws Exception {
|
||||
BearerData bearerData = new BearerData();
|
||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
||||
bearerData.messageId = 0;
|
||||
bearerData.hasUserDataHeader = false;
|
||||
bearerData.userData = makeUserData("test reply option");
|
||||
bearerData.userAckReq = true;
|
||||
byte []encodedSms = BearerData.encode(bearerData);
|
||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(true, revBearerData.userAckReq);
|
||||
assertEquals(false, revBearerData.deliveryAckReq);
|
||||
assertEquals(false, revBearerData.readAckReq);
|
||||
assertEquals(false, revBearerData.reportReq);
|
||||
bearerData.userAckReq = false;
|
||||
bearerData.deliveryAckReq = true;
|
||||
encodedSms = BearerData.encode(bearerData);
|
||||
revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(false, revBearerData.userAckReq);
|
||||
assertEquals(true, revBearerData.deliveryAckReq);
|
||||
assertEquals(false, revBearerData.readAckReq);
|
||||
assertEquals(false, revBearerData.reportReq);
|
||||
bearerData.deliveryAckReq = false;
|
||||
bearerData.readAckReq = true;
|
||||
encodedSms = BearerData.encode(bearerData);
|
||||
revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(false, revBearerData.userAckReq);
|
||||
assertEquals(false, revBearerData.deliveryAckReq);
|
||||
assertEquals(true, revBearerData.readAckReq);
|
||||
assertEquals(false, revBearerData.reportReq);
|
||||
bearerData.readAckReq = false;
|
||||
bearerData.reportReq = true;
|
||||
encodedSms = BearerData.encode(bearerData);
|
||||
revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(false, revBearerData.userAckReq);
|
||||
assertEquals(false, revBearerData.deliveryAckReq);
|
||||
assertEquals(false, revBearerData.readAckReq);
|
||||
assertEquals(true, revBearerData.reportReq);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNumberOfMessages() throws Exception {
|
||||
String pdu1 = "000310409001124896a794e07595f69f199540ea759a0dc8e00b0163";
|
||||
BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
|
||||
assertEquals("Test Voice mail 99", bd1.userData.payloadStr);
|
||||
assertEquals(99, bd1.numberOfMessages);
|
||||
String pdu2 = "00031040900113489ea794e07595f69f199540ea759a0988c0600b0164";
|
||||
BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
|
||||
assertEquals("Test Voice mail 100", bd2.userData.payloadStr);
|
||||
assertEquals(100, bd2.numberOfMessages);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNumberOfMessagesFeedback() throws Exception {
|
||||
BearerData bearerData = new BearerData();
|
||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
||||
bearerData.messageId = 0;
|
||||
bearerData.hasUserDataHeader = false;
|
||||
bearerData.userData = makeUserData("test message count");
|
||||
bearerData.numberOfMessages = 27;
|
||||
byte []encodedSms = BearerData.encode(bearerData);
|
||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(bearerData.numberOfMessages, revBearerData.numberOfMessages);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCallbackNum() throws Exception {
|
||||
String pdu1 = "00031040900112488ea794e070d436cb638bc5e035ce2f97900e06910431323334";
|
||||
BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
|
||||
assertEquals("Test Callback nbr", bd1.userData.payloadStr);
|
||||
assertEquals(CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR, bd1.callbackNumber.digitMode);
|
||||
assertEquals(CdmaSmsAddress.TON_INTERNATIONAL_OR_IP, bd1.callbackNumber.ton);
|
||||
assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode);
|
||||
assertEquals(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY, bd1.callbackNumber.numberPlan);
|
||||
assertEquals("1234", bd1.callbackNumber.address);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCallbackNumFeedback() throws Exception {
|
||||
BearerData bearerData = new BearerData();
|
||||
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
|
||||
bearerData.messageId = 0;
|
||||
bearerData.hasUserDataHeader = false;
|
||||
bearerData.userData = makeUserData("test callback number");
|
||||
CdmaSmsAddress addr = new CdmaSmsAddress();
|
||||
addr.digitMode = CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR;
|
||||
addr.ton = CdmaSmsAddress.TON_NATIONAL_OR_EMAIL;
|
||||
addr.numberMode = CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK;
|
||||
addr.numberPlan = CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN;
|
||||
addr.address = "8005551212";
|
||||
addr.numberOfDigits = (byte)addr.address.length();
|
||||
bearerData.callbackNumber = addr;
|
||||
byte []encodedSms = BearerData.encode(bearerData);
|
||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
||||
CdmaSmsAddress revAddr = revBearerData.callbackNumber;
|
||||
assertEquals(addr.digitMode, revAddr.digitMode);
|
||||
assertEquals(addr.ton, revAddr.ton);
|
||||
assertEquals(addr.numberMode, revAddr.numberMode);
|
||||
assertEquals(addr.numberPlan, revAddr.numberPlan);
|
||||
assertEquals(addr.numberOfDigits, revAddr.numberOfDigits);
|
||||
assertEquals(addr.address, revAddr.address);
|
||||
addr.address = "8*55#1012";
|
||||
addr.numberOfDigits = (byte)addr.address.length();
|
||||
addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF;
|
||||
encodedSms = BearerData.encode(bearerData);
|
||||
revBearerData = BearerData.decode(encodedSms);
|
||||
revAddr = revBearerData.callbackNumber;
|
||||
assertEquals(addr.digitMode, revAddr.digitMode);
|
||||
assertEquals(addr.numberOfDigits, revAddr.numberOfDigits);
|
||||
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;
|
||||
bearerData.userData = makeUserData("test message center timestamp");
|
||||
bearerData.timeStamp = HexDump.hexStringToByteArray("112233445566");
|
||||
byte []encodedSms = BearerData.encode(bearerData);
|
||||
BearerData revBearerData = BearerData.decode(encodedSms);
|
||||
assertEquals(HexDump.toHexString(bearerData.timeStamp),
|
||||
HexDump.toHexString(revBearerData.timeStamp));
|
||||
}
|
||||
|
||||
// XXX test messageId
|
||||
|
||||
// String pdu1 = "0003104090010d4866a794e07055965b91d040300c0100"; sid 12
|
||||
// String pdu1 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0101"; sid 13
|
||||
// Log.d(LOG_TAG, "revBearerData -- " + revBearerData);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user