Initial code for cdma sms encode and decode, in java, with simple tests.

(direct cherry-pick of master 42/42/8)
diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java
new file mode 100644
index 0000000..5da3bc6
--- /dev/null
+++ b/core/java/com/android/internal/util/BitwiseInputStream.java
@@ -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;
+    }
+}
diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java
new file mode 100644
index 0000000..5941bf3
--- /dev/null
+++ b/core/java/com/android/internal/util/BitwiseOutputStream.java
@@ -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;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 7c32451..1aad38d 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -20,20 +20,7 @@
 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 @@
     }
 
 }
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index e4b474a..2f26bdc 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -27,7 +27,6 @@
 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_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 @@
 
         // 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 @@
             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 @@
                 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 @@
 
         // 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 @@
      * 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 @@
             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 @@
         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 @@
         // ** 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());
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index fec9529..8e67387 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -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 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 @@
      * (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 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;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
index 1643cab..440debb 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
@@ -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 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();
+    }
+
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java
deleted file mode 100644
index 6ba7463..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java
+++ /dev/null
@@ -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");
-        }
-    }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
index e761469..bd6fbb4 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
@@ -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 @@
     /**
      * 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();
+    }
 
 }
diff --git a/telephony/jni/cdmasms/Android.mk b/telephony/jni/cdmasms/Android.mk
deleted file mode 100644
index b0c96b4..0000000
--- a/telephony/jni/cdmasms/Android.mk
+++ /dev/null
@@ -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)
diff --git a/telephony/jni/cdmasms/cdma_sms_jni.cpp b/telephony/jni/cdmasms/cdma_sms_jni.cpp
deleted file mode 100644
index 2a8e825..0000000
--- a/telephony/jni/cdmasms/cdma_sms_jni.cpp
+++ /dev/null
@@ -1,1300 +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.
- */
-
-/**
- * @file cdma_sms_jni.cpp
- *
- * This file implement the Java Native Interface
- * for encoding and decoding of SMS
- */
-
-
-#include <nativehelper/jni.h>
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <cdma_sms_jni.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif //__cplusplus
-
-#include <reference-cdma-sms.h>
-
-#ifdef __cplusplus
-}
-#endif //__cplusplus
-
-#undef LOG_TAG
-#define LOG_TAG "CDMA"
-#include <utils/Log.h>
-
-static RIL_CDMA_SMS_ClientBd *clientBdData = NULL;
-
-
-static jint getObjectIntField(JNIEnv * env, jobject obj, const char *name, jint * value)
-{
-    jclass clazz;
-    jfieldID field;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("getObjectIntField():");
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "I");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    *value = env->GetIntField(obj, field);
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("  %s = %d\n", name, *value);
-#endif
-
-    return JNI_SUCCESS;
-}
-
-static jint setObjectIntField(JNIEnv * env, jobject obj, const char *name, jint value)
-{
-    jclass clazz;
-    jfieldID field;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("setObjectIntField(): %s = %d\n", name, value);
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "I");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    env->SetIntField(obj, field, value);
-
-    return JNI_SUCCESS;
-}
-
-static jint getObjectByteField(JNIEnv * env, jobject obj, const char *name, jbyte * value)
-{
-    jclass clazz;
-    jfieldID field;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("getObjectByteField():");
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "B");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    *value = env->GetByteField(obj, field);
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("  %s = %02x\n", name, *value);
-#endif
-
-    return JNI_SUCCESS;
-}
-
-static jint setObjectByteField(JNIEnv * env, jobject obj, const char *name, jbyte value)
-{
-    jclass clazz;
-    jfieldID field;
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("setObjectByteField(): %s = 0x%02x\n", name, value);
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "B");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    env->SetByteField(obj, field, value);
-
-    return JNI_SUCCESS;
-}
-
-static jint getObjectBooleanField(JNIEnv * env, jobject obj, const char *name, jboolean * value)
-{
-    jclass clazz;
-    jfieldID field;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("getObjectBooleanField():");
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "Z");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    *value = env->GetBooleanField(obj, field);
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("  %s = %d\n", name, *value);
-#endif
-
-    return JNI_SUCCESS;
-}
-
-static jint setObjectBooleanField(JNIEnv * env, jobject obj, const char *name, jboolean value)
-{
-    jclass clazz;
-    jfieldID field;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("setObjectBooleanField(): %s = %d\n", name, value);
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "Z");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    env->SetBooleanField(obj, field, value);
-
-    return JNI_SUCCESS;
-}
-
-static jint getObjectByteArrayField(JNIEnv * env, jobject obj, const char *name, jbyte* arrData, int* length)
-{
-    jclass clazz;
-    jfieldID field;
-    jbyte * data_buf;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("getObjectByteArrayField(): %s\n", name);
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "[B");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    jbyteArray buffer = (jbyteArray)(env->GetObjectField(obj, field));
-    if (buffer != NULL) {
-        int len = env->GetArrayLength(buffer);
-        data_buf = env->GetByteArrayElements(buffer, NULL);
-        for (int i=0; i<len; i++) {
-            *arrData++ = data_buf[i];
-#ifdef DBG_LOG_LEVEL_B
-            LOGD("  [%d] = 0x%02x\n", i, data_buf[i]);
-#endif
-        }
-        *length = len;
-    } else {
-        jniThrowException(env, "java/lang/NullPointerException", NULL);
-        return JNI_FAILURE;
-    }
-
-    return JNI_SUCCESS;
-}
-
-static jint setObjectByteArrayField(JNIEnv * env, jobject obj, const char *name, jbyte* arrData, int length)
-{
-    jclass clazz;
-    jfieldID field;
-    jbyte* byte_buf;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("setObjectByteArrayField(): %s\n", name);
-#endif
-
-    clazz = env->GetObjectClass(obj);
-    if (NULL == clazz) {
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return JNI_FAILURE;
-    }
-
-    field = env->GetFieldID(clazz, name, "[B");
-    env->DeleteLocalRef(clazz);
-
-    if (NULL == field) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", name);
-        return JNI_FAILURE;
-    }
-
-    jbyteArray buffer = (jbyteArray)(env->GetObjectField(obj, field));
-    if (buffer == NULL) {
-#ifdef DBG_LOG_LEVEL_B
-        LOGD("setObjectByteArrayField(): %s = null\n", name);
-#endif
-        buffer = env->NewByteArray(length);
-        env->SetObjectField(obj, field, buffer);
-    }
-
-    if (buffer != NULL) {
-#ifdef DBG_LOG_LEVEL_B
-        for (int i=0; i<length; i++) {
-            LOGD("  [%d] = 0x%02x\n", i, arrData[i]);
-        }
-#endif
-        env->SetByteArrayRegion(buffer, 0, length, arrData);
-    } else {
-        jniThrowException(env, "java/lang/NullPointerException", NULL);
-        return JNI_FAILURE;
-    }
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD
-  (JNIEnv * env, jobject obj)
-{
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsConstructClientBD()...\n");
-#endif
-
-    clientBdData = (RIL_CDMA_SMS_ClientBd *)malloc(sizeof(RIL_CDMA_SMS_ClientBd));
-    if (NULL == clientBdData) {
-        jniThrowException(env, "java/lang/OutOfMemoryError", "clientBdData memory allocation failed");
-        return JNI_FAILURE;
-    }
-    memset(clientBdData, 0, sizeof(RIL_CDMA_SMS_ClientBd));
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD
-  (JNIEnv * env, jobject obj)
-{
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsDestructClientBD()...\n");
-#endif
-
-    if (clientBdData == NULL) {
-        jniThrowException(env, "java/lang/NullPointerException", "clientBdData is null");
-        return JNI_FAILURE;
-    }
-    free(clientBdData);
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives
-  (JNIEnv * env, jobject obj, jobject bearerData)
-{
-    jbyteArray mc_time = NULL;
-    jbyte mctime_buffer[6];
-    int length;
-    jint intData;
-    jbyte byteData;
-    jboolean booleanData;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsSetBearerDataPrimitives()...\n");
-#endif
-
-    // mask
-    if (getObjectIntField(env, bearerData, "mask", &intData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->mask = intData;
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->mask = 0x%x\n", clientBdData->mask);
-#endif
-
-    // message_id.type
-    if (getObjectByteField(env, bearerData, "messageType", &byteData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->message_id.type = (RIL_CDMA_SMS_BdMessageType)(byteData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->message_id.type = 0x%02x\n", clientBdData->message_id.type);
-#endif
-
-    // message_id.id_number
-    if ((clientBdData->mask & WMS_MASK_BD_MSG_ID) == WMS_MASK_BD_MSG_ID) {
-        if (getObjectIntField(env, bearerData, "messageID", &intData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->message_id.id_number = (RIL_CDMA_SMS_MessageNumber)(intData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->message_id.id_number = %d\n", clientBdData->message_id.id_number);
-#endif
-    }
-
-    // message_id.udh_present
-    if (getObjectBooleanField(env, bearerData, "hasUserDataHeader", &booleanData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->message_id.udh_present = (unsigned char)(booleanData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->message_id.udh_present = %d\n", clientBdData->message_id.udh_present);
-#endif
-
-    // user_response
-    // TODO
-
-    // mc_time
-    if ((clientBdData->mask & WMS_MASK_BD_MC_TIME) == WMS_MASK_BD_MC_TIME) {
-        if (getObjectByteArrayField(env, bearerData, "timeStamp", mctime_buffer, &length) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        if (mctime_buffer != NULL) {
-            clientBdData->mc_time.year     = mctime_buffer[0];
-            clientBdData->mc_time.month    = mctime_buffer[1];
-            clientBdData->mc_time.day      = mctime_buffer[2];
-            clientBdData->mc_time.hour     = mctime_buffer[3];
-            clientBdData->mc_time.minute   = mctime_buffer[4];
-            clientBdData->mc_time.second   = mctime_buffer[5];
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->mc_time.year   = %d\n", clientBdData->mc_time.year);
-            LOGD("clientBdData->mc_time.month  = %d\n", clientBdData->mc_time.month);
-            LOGD("clientBdData->mc_time.day    = %d\n", clientBdData->mc_time.day);
-            LOGD("clientBdData->mc_time.hour   = %d\n", clientBdData->mc_time.hour);
-            LOGD("clientBdData->mc_time.minute = %d\n", clientBdData->mc_time.minute);
-            LOGD("clientBdData->mc_time.second = %d\n", clientBdData->mc_time.second);
-#endif
-        }
-    }
-
-    // clientBdData->mc_time.timezone
-    // TODO
-
-    // validity_absolute;
-    // TODO
-
-    // validity_relative;
-    // TODO
-
-    // deferred_absolute
-    // TODO
-
-    // deferred_relative;
-    // TODO
-
-    // priority
-    // TODO
-
-    // privacy
-    // TODO
-
-    if ((clientBdData->mask & WMS_MASK_BD_REPLY_OPTION) == WMS_MASK_BD_REPLY_OPTION) {
-        // reply_option.user_ack_requested
-        if (getObjectBooleanField(env, bearerData, "userAckReq", &booleanData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->reply_option.user_ack_requested = (unsigned char)(booleanData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->reply_option.user_ack_requested = %d\n", clientBdData->reply_option.user_ack_requested);
-#endif
-        // reply_option.user_ack_requested
-        if (getObjectBooleanField(env, bearerData, "deliveryAckReq", &booleanData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->reply_option.delivery_ack_requested = (unsigned char)(booleanData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->reply_option.delivery_ack_requested = %d\n", clientBdData->reply_option.delivery_ack_requested);
-#endif
-        // reply_option.user_ack_requested
-        if (getObjectBooleanField(env, bearerData, "readAckReq", &booleanData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->reply_option.read_ack_requested = (unsigned char)(booleanData);
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->reply_option.read_ack_requested = %d\n", clientBdData->reply_option.read_ack_requested);
-#endif
-    }
-
-    // num_messages
-    if ((clientBdData->mask & WMS_MASK_BD_NUM_OF_MSGS) == WMS_MASK_BD_NUM_OF_MSGS) {
-        if (getObjectIntField(env, bearerData, "numberOfMessages", &intData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->num_messages = (unsigned char)(intData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->num_messages = %d\n", clientBdData->num_messages);
-#endif
-    }
-
-    // alert_mode
-    // TODO
-
-    // language
-    // TODO
-
-    // display_mode
-    if ((clientBdData->mask & WMS_MASK_BD_DISPLAY_MODE) == WMS_MASK_BD_DISPLAY_MODE) {
-        if (getObjectByteField(env, bearerData, "displayMode", &byteData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->display_mode = (RIL_CDMA_SMS_DisplayMode)(byteData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->display_mode = 0x%02x\n", clientBdData->display_mode);
-#endif
-    }
-
-    // delivery_status
-    if ((clientBdData->mask & WMS_MASK_BD_DELIVERY_STATUS) == WMS_MASK_BD_DELIVERY_STATUS) {
-        // delivery_status.error_class
-        if (getObjectIntField(env, bearerData, "errorClass", &intData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->delivery_status.error_class = (RIL_CDMA_SMS_ErrorClass)(intData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->delivery_status.error_class = %d\n", clientBdData->delivery_status.error_class);
-#endif
-        // delivery_status.status
-        if (getObjectIntField(env, bearerData, "messageStatus", &intData) != JNI_SUCCESS)
-            return JNI_FAILURE;
-        clientBdData->delivery_status.status = (RIL_CDMA_SMS_DeliveryStatusE)(intData);
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->delivery_status.status = %d\n", clientBdData->delivery_status.status);
-#endif
-    }
-
-    // deposit_index
-    // TODO
-
-    // ip_address
-    // TODO
-
-    // rsn_no_notify
-    // TODO
-
-    // other
-    // TODO
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives
-  (JNIEnv * env, jobject obj, jobject bearerData)
-{
-    jclass BearerDataClass;
-    jfieldID field;
-    jbyte mctime_buffer[6];
-    jbyteArray addr_array;
-    int length;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsGetBearerDataPrimitives()...\n");
-#endif
-
-    // mask
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->mask = 0x%x\n", clientBdData->mask);
-#endif
-    if (setObjectIntField(env, bearerData, "mask", clientBdData->mask) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // message_id.type
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->message_id.type = 0x%02x\n", clientBdData->message_id.type);
-#endif
-    if (setObjectByteField(env, bearerData, "messageType", (jbyte)clientBdData->message_id.type) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // message_id.id_number
-    if ((clientBdData->mask & WMS_MASK_BD_MSG_ID) == WMS_MASK_BD_MSG_ID) {
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->message_id.id_number = %d\n", clientBdData->message_id.id_number);
-#endif
-        if (setObjectIntField(env, bearerData, "messageID", clientBdData->message_id.id_number) != JNI_SUCCESS)
-            return JNI_FAILURE;
-    }
-
-    // message_id.udh_present
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->message_id.udh_present = %d\n", clientBdData->message_id.udh_present);
-#endif
-    if (setObjectBooleanField(env, bearerData, "hasUserDataHeader", (jboolean)clientBdData->message_id.udh_present) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // user_response
-    // TODO
-
-    // mc_time
-    if ((clientBdData->mask & WMS_MASK_BD_MC_TIME) == WMS_MASK_BD_MC_TIME) {
-        jclass clazz= env->GetObjectClass(bearerData);
-        if (NULL == clazz)
-            return JNI_FAILURE;
-        jfieldID field = env->GetFieldID(clazz, "timeStamp", "[B");
-        env->DeleteLocalRef(clazz);
-
-        addr_array = env->NewByteArray((jsize)6);
-        env->SetObjectField(bearerData, field, addr_array);
-
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->mc_time.year   = %d\n", clientBdData->mc_time.year);
-        LOGD("clientBdData->mc_time.month  = %d\n", clientBdData->mc_time.month);
-        LOGD("clientBdData->mc_time.day    = %d\n", clientBdData->mc_time.day);
-        LOGD("clientBdData->mc_time.hour   = %d\n", clientBdData->mc_time.hour);
-        LOGD("clientBdData->mc_time.minute = %d\n", clientBdData->mc_time.minute);
-        LOGD("clientBdData->mc_time.second = %d\n", clientBdData->mc_time.second);
-#endif
-        mctime_buffer[0] = clientBdData->mc_time.year;
-        mctime_buffer[1] = clientBdData->mc_time.month;
-        mctime_buffer[2] = clientBdData->mc_time.day;
-        mctime_buffer[3] = clientBdData->mc_time.hour;
-        mctime_buffer[4] = clientBdData->mc_time.minute;
-        mctime_buffer[5] = clientBdData->mc_time.second;
-        length = sizeof(mctime_buffer) / sizeof(jbyte);
-        if (setObjectByteArrayField(env, bearerData, "timeStamp", mctime_buffer, length) != JNI_SUCCESS)
-            return JNI_FAILURE;
-    }
-
-    // clientBdData->mc_time.timezone
-    // TODO
-
-    // validity_absolute;
-    // TODO
-
-    // validity_relative;
-    // TODO
-
-    // deferred_absolute
-    // TODO
-
-    // deferred_relative;
-    // TODO
-
-    // priority
-    // TODO
-
-    // privacy
-    // TODO
-
-    if ((clientBdData->mask & WMS_MASK_BD_REPLY_OPTION) == WMS_MASK_BD_REPLY_OPTION) {
-        // reply_option.user_ack_requested
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->reply_option.user_ack_requested = %d\n", clientBdData->reply_option.user_ack_requested);
-#endif
-        if (setObjectBooleanField(env, bearerData, "userAckReq", (jboolean)clientBdData->reply_option.user_ack_requested) != JNI_SUCCESS)
-            return JNI_FAILURE;
-
-        // reply_option.user_ack_requested
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->reply_option.delivery_ack_requested = %d\n", clientBdData->reply_option.delivery_ack_requested);
-#endif
-        if (setObjectBooleanField(env, bearerData, "deliveryAckReq", (jboolean)clientBdData->reply_option.delivery_ack_requested) != JNI_SUCCESS)
-            return JNI_FAILURE;
-
-        // reply_option.user_ack_requested
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->reply_option.read_ack_requested = %d\n", clientBdData->reply_option.read_ack_requested);
-#endif
-        if (setObjectBooleanField(env, bearerData, "readAckReq", (jboolean)clientBdData->reply_option.read_ack_requested) != JNI_SUCCESS)
-            return JNI_FAILURE;
-    }
-
-    // num_messages
-    if ((clientBdData->mask & WMS_MASK_BD_NUM_OF_MSGS) == WMS_MASK_BD_NUM_OF_MSGS) {
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->num_messages = %d\n", clientBdData->num_messages);
-#endif
-        if (setObjectIntField(env, bearerData, "numberOfMessages", (int)clientBdData->num_messages) != JNI_SUCCESS)
-            return JNI_FAILURE;
-    }
-
-    // alert_mode
-    // TODO
-
-    // language
-    // TODO
-
-    // display_mode
-    if ((clientBdData->mask & WMS_MASK_BD_DISPLAY_MODE) == WMS_MASK_BD_DISPLAY_MODE) {
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->display_mode = 0x%02x\n", clientBdData->display_mode);
-#endif
-        if (setObjectByteField(env, bearerData, "displayMode", (jbyte)clientBdData->display_mode) != JNI_SUCCESS)
-            return JNI_FAILURE;
-    }
-
-    // delivery_status
-    if ((clientBdData->mask & WMS_MASK_BD_DELIVERY_STATUS) == WMS_MASK_BD_DELIVERY_STATUS) {
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->delivery_status.error_class = %d\n", clientBdData->delivery_status.error_class);
-#endif
-        // delivery_status.error_class
-        if (setObjectIntField(env, bearerData, "errorClass", (int)clientBdData->delivery_status.error_class) != JNI_SUCCESS)
-            return JNI_FAILURE;
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->delivery_status.status = %d\n", clientBdData->delivery_status.status);
-#endif
-        // delivery_status.status
-        if (setObjectIntField(env, bearerData, "messageStatus", (int)clientBdData->delivery_status.status) != JNI_SUCCESS)
-            return JNI_FAILURE;
-    }
-
-    // deposit_index
-    // TODO
-
-    // ip_address
-    // TODO
-
-    // rsn_no_notify
-    // TODO
-
-    // other
-    // TODO
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData
-  (JNIEnv * env, jobject obj, jobject userData)
-{
-    jclass UserDataClass;
-    jfieldID field;
-    jbyteArray arrData = NULL;
-    jbyte data_buf[RIL_CDMA_SMS_USER_DATA_MAX];
-    int length;
-    jint intData;
-    jbyte byteData;
-    jboolean booleanData;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsSetUserData()...\n");
-#endif
-
-    // set num_headers to 0 here, increment later
-    clientBdData->user_data.num_headers = 0;
-
-    // user_data.encoding
-    if (getObjectIntField(env, userData, "userDataEncoding", &intData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->user_data.encoding = (RIL_CDMA_SMS_UserDataEncoding)(intData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.encoding = %d\n", clientBdData->user_data.encoding);
-#endif
-
-    // is91ep_type
-    // TODO
-
-    // user_data.padding_bits
-    if (getObjectIntField(env, userData, "paddingBits", &intData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->user_data.padding_bits = (unsigned char)(intData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.padding_bits = %d\n", clientBdData->user_data.padding_bits);
-#endif
-
-    // user_data.data
-    if (getObjectByteArrayField(env, userData, "userData", data_buf, &length) != JNI_SUCCESS )
-        return JNI_FAILURE;
-    for (int i = 0; i < length; i++) {
-        clientBdData->user_data.data[i] = data_buf[i];
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->user_data.data[%d] = 0x%02x\n", i, clientBdData->user_data.data[i]);
-#endif
-    }
-
-    // user_data.data_len
-    // TODO
-
-    // number_of_digits
-    clientBdData->user_data.number_of_digits = (unsigned char)(length);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.number_of_digits = %d\n", clientBdData->user_data.number_of_digits);
-#endif
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData
-  (JNIEnv * env, jobject obj, jobject userData)
-{
-    jclass UserDataClass;
-    jfieldID field;
-    jbyte *data_buf;
-    int length;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsGetUserData()...\n");
-#endif
-
-    // user_data.num_headers
-//    if (setObjectIntField(env, userData, "mNumberOfHeaders", (int)clientBdData->user_data.num_headers) != JNI_SUCCESS)
-//        return JNI_FAILURE;
-
-    // user_data.encoding
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.encoding = %d\n", clientBdData->user_data.encoding);
-#endif
-    if (setObjectIntField(env, userData, "userDataEncoding", clientBdData->user_data.encoding) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // is91ep_type
-    // TODO
-
-    // user_data.data_len
-//    if (setObjectIntField(env, userData, "mDataLength", (int)clientBdData->user_data.data_len) != JNI_SUCCESS)
-//        return JNI_FAILURE;
-
-    // user_data.padding_bits
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.padding_bits = %d\n", clientBdData->user_data.padding_bits);
-#endif
-    if (setObjectIntField(env, userData, "paddingBits", (int)clientBdData->user_data.padding_bits) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // user_data.data
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.data_len = %d\n", clientBdData->user_data.data_len);
-#endif
-    length = clientBdData->user_data.data_len;
-#ifdef DBG_LOG_LEVEL_A
-    for (int i = 0; i < length; i++) {
-        LOGD("clientBdData->user_data.data[%d] = 0x%02x\n", i, clientBdData->user_data.data[i]);
-    }
-#endif
-    data_buf = (jbyte*)clientBdData->user_data.data;
-    if (setObjectByteArrayField(env, userData, "userData", data_buf, length) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // number_of_digits
-    // TODO
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader
-  (JNIEnv * env, jobject obj, jint ID, jbyteArray data, jint length, jint index)
-{
-    jbyte data_buf[length];
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsSetUserDataHeader()...\n");
-#endif
-
-    env->GetByteArrayRegion(data, 0, length, data_buf);
-
-    // user_data.headers[index].header_id
-    clientBdData->user_data.headers[index].header_id = (RIL_CDMA_SMS_UdhId)(ID);
-
-    // user_data.headers[index].u
-    // TODO: add support for all udh id's
-    switch(clientBdData->user_data.headers[index].header_id)
-    {
-        case RIL_CDMA_SMS_UDH_CONCAT_8:
-            clientBdData->user_data.headers[index].u.concat_8.msg_ref  = data_buf[0];
-            clientBdData->user_data.headers[index].u.concat_8.total_sm = data_buf[1];
-            clientBdData->user_data.headers[index].u.concat_8.seq_num  = data_buf[2];
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->user_data.headers[%d].u.concat_8.msg_ref  = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.msg_ref);
-            LOGD("clientBdData->user_data.headers[%d].u.concat_8.total_sm = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.total_sm);
-            LOGD("clientBdData->user_data.headers[%d].u.concat_8.seq_num  = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.seq_num);
-#endif
-        break;
-        case RIL_CDMA_SMS_UDH_SPECIAL_SM:
-            clientBdData->user_data.headers[index].u.special_sm.msg_waiting      = (RIL_CDMA_SMS_GWMsgWaiting)(
-                                                                                   (data_buf[0] << 23) | (data_buf[1] << 15) |
-                                                                                   (data_buf[2] << 7)  |  data_buf[3]);
-            clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind = (RIL_CDMA_SMS_GWMsgWaitingKind)(
-                                                                                   (data_buf[4] << 23) | (data_buf[5] << 15) |
-                                                                                   (data_buf[6] << 7)  |  data_buf[7]);
-            clientBdData->user_data.headers[index].u.special_sm.message_count    =  data_buf[8];
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting      = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting);
-            LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting_kind = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind);
-            LOGD("clientBdData->user_data.headers[%d].u.special_sm.message_count    = 0x%02x\n", index, clientBdData->user_data.headers[index].u.special_sm.message_count);
-#endif
-        break;
-        case RIL_CDMA_SMS_UDH_PORT_8:
-            clientBdData->user_data.headers[index].u.wap_8.dest_port = data_buf[0];
-            clientBdData->user_data.headers[index].u.wap_8.orig_port = data_buf[1];
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->user_data.headers[%d].u.wap_8.dest_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.dest_port);
-            LOGD("clientBdData->user_data.headers[%d].u.wap_8.orig_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.orig_port);
-#endif
-        break;
-        case RIL_CDMA_SMS_UDH_PORT_16:
-            clientBdData->user_data.headers[index].u.wap_16.dest_port = (data_buf[0] << 7) | data_buf[1]; // unsigned short
-            clientBdData->user_data.headers[index].u.wap_16.orig_port = (data_buf[2] << 7) | data_buf[3]; // unsigned short
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->user_data.headers[%d].u.wap_16.dest_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.dest_port);
-            LOGD("clientBdData->user_data.headers[%d].u.wap_16.orig_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.orig_port);
-#endif
-        break;
-        case RIL_CDMA_SMS_UDH_CONCAT_16:
-            clientBdData->user_data.headers[index].u.concat_16.msg_ref  = (data_buf[0] << 7) | data_buf[1]; // unsigned short
-            clientBdData->user_data.headers[index].u.concat_16.total_sm =  data_buf[2];
-            clientBdData->user_data.headers[index].u.concat_16.seq_num  =  data_buf[3];
-#ifdef DBG_LOG_LEVEL_A
-            LOGD("clientBdData->user_data.headers[%d].u.concat_16.msg_ref  = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.msg_ref);
-            LOGD("clientBdData->user_data.headers[%d].u.concat_16.total_sm = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.total_sm);
-            LOGD("clientBdData->user_data.headers[%d].u.concat_16.seq_num  = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.seq_num);
-#endif
-        break;
-        default:
-        break;
-    }
-
-    // increment num_of_headers
-    clientBdData->user_data.num_headers++;
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jbyteArray JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader
-  (JNIEnv * env, jobject obj)
-{
-    jbyteArray arrData = NULL;
-    jbyte data_buf[sizeof(clientBdData->user_data.headers)];
-    int length = 0;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsGetUserDataHeader()...\n");
-#endif
-
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->user_data.num_headers = %d, size = %d\n", clientBdData->user_data.num_headers, sizeof(clientBdData->user_data.headers));
-#endif
-
-    for (int index = 0; index < clientBdData->user_data.num_headers; index++) {
-        // user_data.headers[index].header_id
-        data_buf[length++] = (jbyte)clientBdData->user_data.headers[index].header_id;
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->user_data.headers[%d].header_id = %d", index, clientBdData->user_data.headers[index].header_id);
-#endif
-
-        // user_data.headers[index].u
-        // TODO: add support for all udh id's
-        switch(clientBdData->user_data.headers[index].header_id)
-        {
-            case RIL_CDMA_SMS_UDH_CONCAT_8:
-#ifdef DBG_LOG_LEVEL_A
-                LOGD("clientBdData->user_data.headers[%d].u.concat_8.msg_ref  = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.msg_ref);
-                LOGD("clientBdData->user_data.headers[%d].u.concat_8.total_sm = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.total_sm);
-                LOGD("clientBdData->user_data.headers[%d].u.concat_8.seq_num  = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.seq_num);
-#endif
-                data_buf[length++] = 3;
-                data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.msg_ref;
-                data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.total_sm;
-                data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.seq_num;
-            break;
-            case RIL_CDMA_SMS_UDH_SPECIAL_SM:
-#ifdef DBG_LOG_LEVEL_A
-                LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting      = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting);
-                LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting_kind = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind);
-                LOGD("clientBdData->user_data.headers[%d].u.special_sm.message_count    = 0x%02x\n", index, clientBdData->user_data.headers[index].u.special_sm.message_count);
-#endif
-                data_buf[length++] = 9;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0xFF000000) >> 23; // int
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x00FF0000) >> 15;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x0000FF00) >> 7;
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x000000FF;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0xFF000000) >> 23; // int
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x00FF0000) >> 15;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x0000FF00) >> 7;
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x000000FF;
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.special_sm.message_count;
-            break;
-            case RIL_CDMA_SMS_UDH_PORT_8:
-#ifdef DBG_LOG_LEVEL_A
-                LOGD("clientBdData->user_data.headers[%d].u.wap_8.dest_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.dest_port);
-                LOGD("clientBdData->user_data.headers[%d].u.wap_8.orig_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.orig_port);
-#endif
-                data_buf[length++] = 2;
-                data_buf[length++] = clientBdData->user_data.headers[index].u.wap_8.dest_port;
-                data_buf[length++] = clientBdData->user_data.headers[index].u.wap_8.orig_port;
-            break;
-            case RIL_CDMA_SMS_UDH_PORT_16:
-#ifdef DBG_LOG_LEVEL_A
-                LOGD("clientBdData->user_data.headers[%d].u.wap_16.dest_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.dest_port);
-                LOGD("clientBdData->user_data.headers[%d].u.wap_16.orig_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.orig_port);
-#endif
-                data_buf[length++] = 4;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.wap_16.dest_port & 0xFF00) >> 7; // unsigned short
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.wap_16.dest_port & 0x00FF;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.wap_16.orig_port & 0xFF00) >> 7; // unsigned short
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.wap_16.orig_port & 0x00FF;
-            break;
-            case RIL_CDMA_SMS_UDH_CONCAT_16:
-#ifdef DBG_LOG_LEVEL_A
-                LOGD("clientBdData->user_data.headers[%d].u.concat_16.msg_ref  = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.msg_ref);
-                LOGD("clientBdData->user_data.headers[%d].u.concat_16.total_sm = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.total_sm);
-                LOGD("clientBdData->user_data.headers[%d].u.concat_16.seq_num  = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.seq_num);
-#endif
-                data_buf[length++] = 4;
-                data_buf[length++] = (clientBdData->user_data.headers[index].u.concat_16.msg_ref & 0xFF00) >> 7; // unsigned short
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.concat_16.msg_ref & 0x00FF;
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.concat_16.total_sm;
-                data_buf[length++] =  clientBdData->user_data.headers[index].u.concat_16.seq_num;
-            break;
-            default:
-            break;
-        }
-    }
-
-    if (length != 0) {
-        arrData = env->NewByteArray((jsize)length);
-        env->SetByteArrayRegion(arrData, 0, length, data_buf);
-    }
-
-    return arrData;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress
-  (JNIEnv * env, jobject obj, jobject smsAddress)
-{
-    jclass SmsAddressClass;
-    jfieldID field;
-    jbyteArray arrData = NULL;
-    jbyte byte_buf[RIL_CDMA_SMS_ADDRESS_MAX];
-    int length;
-    jint intData;
-    jbyte byteData;
-    jboolean booleanData;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsSetSmsAddress()...\n");
-#endif
-
-    // callback.digit_mode
-    if (getObjectByteField(env, smsAddress, "digitMode", &byteData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->callback.digit_mode = (RIL_CDMA_SMS_DigitMode)(byteData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.digit_mode = 0x%02x\n", clientBdData->callback.digit_mode);
-#endif
-
-    // callback.number_mode
-    if (getObjectByteField(env, smsAddress, "numberMode", &byteData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->callback.number_mode = (RIL_CDMA_SMS_NumberMode)(byteData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_mode = 0x%02x\n", clientBdData->callback.number_mode);
-#endif
-
-    // callback.number_type
-    if (getObjectIntField(env, smsAddress, "ton", &intData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->callback.number_type = (RIL_CDMA_SMS_NumberType)(intData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_type = %d\n", clientBdData->callback.number_type);
-#endif
-
-    // callback.number_plan
-    if (getObjectByteField(env, smsAddress, "numberPlan", &byteData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->callback.number_plan = (RIL_CDMA_SMS_NumberPlan)(byteData);
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_plan = 0x%02x\n", clientBdData->callback.number_plan);
-#endif
-
-    // callback.number_of_digits
-    if (getObjectByteField(env, smsAddress, "numberOfDigits", &byteData) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    clientBdData->callback.number_of_digits = byteData;
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_of_digits = %d\n",clientBdData->callback.number_of_digits);
-#endif
-
-    // callback.digits
-    if (getObjectByteArrayField(env, smsAddress, "origBytes", byte_buf, &length) != JNI_SUCCESS)
-        return JNI_FAILURE;
-    for (int i = 0; i < clientBdData->callback.number_of_digits; i++) {
-        clientBdData->callback.digits[i] = byte_buf[i];
-#ifdef DBG_LOG_LEVEL_A
-        LOGD("clientBdData->callback.digits[%d] = 0x%02x\n", i, clientBdData->callback.digits[i]);
-#endif
-    }
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress
-  (JNIEnv * env, jobject obj, jobject smsAddress)
-{
-    jclass SmsAddressClass;
-    jfieldID field;
-    jbyteArray arrData = NULL;
-    jbyte *byte_buf;
-    int length;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsGetSmsAddress()...\n");
-#endif
-
-    // callback.digit_mode
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.digit_mode = 0x%02x\n", clientBdData->callback.digit_mode);
-#endif
-    if (setObjectByteField(env, smsAddress, "digitMode", (jbyte)clientBdData->callback.digit_mode) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // callback.number_mode
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_mode = 0x%02x\n", clientBdData->callback.number_mode);
-#endif
-    if (setObjectByteField(env, smsAddress, "numberMode", (jbyte)clientBdData->callback.number_mode) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // callback.number_type
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_type = %d\n", clientBdData->callback.number_type);
-#endif
-    if (setObjectIntField(env, smsAddress, "ton", (jint)clientBdData->callback.number_type) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // callback.number_plan
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_plan = 0x%02x\n", clientBdData->callback.number_plan);
-#endif
-    if (setObjectByteField(env, smsAddress, "numberPlan", (jbyte)clientBdData->callback.number_plan) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // callback.number_of_digits
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("clientBdData->callback.number_of_digits = %d\n", clientBdData->callback.number_of_digits);
-#endif
-    if (setObjectByteField(env, smsAddress, "numberOfDigits", (jbyte)clientBdData->callback.number_of_digits) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    // callback.digits
-    byte_buf = (jbyte*)clientBdData->callback.digits;
-    length = clientBdData->callback.number_of_digits;
-#ifdef DBG_LOG_LEVEL_A
-    for (int i = 0; i < length; i++) {
-        LOGD("clientBdData->callback.digits[%d] = 0x%02x\n", i, clientBdData->callback.digits[i]);
-    }
-#endif
-
-    if (setObjectByteArrayField(env, smsAddress, "origBytes", byte_buf, length) != JNI_SUCCESS)
-        return JNI_FAILURE;
-
-    return JNI_SUCCESS;
-}
-
-
-/* native interface */
-JNIEXPORT jbyteArray JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms
-  (JNIEnv * env, jobject obj)
-{
-    RIL_CDMA_Encoded_SMS *encoded_sms = (RIL_CDMA_Encoded_SMS *)malloc(sizeof(RIL_CDMA_Encoded_SMS));
-    jbyte* data_buf;
-    jint result = JNI_SUCCESS;
-    jbyteArray encodedSMS;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsEncodeSms(): entry\n");
-#endif
-
-    if (NULL == encoded_sms) {
-        jniThrowException(env, "java/lang/NullPointerException", "encoded_sms is null");
-        return NULL;
-    }
-    memset(encoded_sms, 0, sizeof(RIL_CDMA_Encoded_SMS));
-
-    // call CDMA SMS encode function
-    if(wmsts_ril_cdma_encode_sms(clientBdData, encoded_sms) != RIL_E_SUCCESS) {
-        jniThrowException(env, "java/lang/Exception", "CDMA SMS Encoding failed");
-        return NULL;
-    }
-
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("  EncodeSMS: length = %i\n", encoded_sms->length);
-#endif
-    encodedSMS = env->NewByteArray((jsize)encoded_sms->length);
-    env->SetByteArrayRegion(encodedSMS, 0, encoded_sms->length, (jbyte*)encoded_sms->data);
-    free(encoded_sms);
-
-    return encodedSMS;
-}
-
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms
-  (JNIEnv * env, jobject obj, jbyteArray encodedSMS)
-{
-    RIL_CDMA_Encoded_SMS *encoded_sms = (RIL_CDMA_Encoded_SMS *)malloc(sizeof(RIL_CDMA_Encoded_SMS));
-    jbyte* data_buf;
-    jint result = JNI_SUCCESS;
-    jsize length;
-
-#ifdef DBG_LOG_LEVEL_B
-    LOGD("nativeCdmaSmsDecodeSms(): entry\n");
-#endif
-
-    if (NULL == encoded_sms) {
-        jniThrowException(env, "java/lang/NullPointerException", "encoded_sms is null");
-        return JNI_FAILURE;
-    }
-    memset(encoded_sms, 0, sizeof(RIL_CDMA_Encoded_SMS));
-
-    length = env->GetArrayLength(encodedSMS);
-    if (length < 0 || length > 255) {
-        jniThrowException(env, "java/lang/ArrayIndexOutOfBounds", "wrong encoded SMS data length");
-        return JNI_FAILURE;
-    }
-    encoded_sms->length = length;
-#ifdef DBG_LOG_LEVEL_A
-    LOGD("  DecodeSMS: arrayLength = %d\n", encoded_sms->length);
-#endif
-    data_buf = env->GetByteArrayElements(encodedSMS, NULL);
-    encoded_sms->data = (unsigned char*)data_buf;
-    env->ReleaseByteArrayElements(encodedSMS, data_buf, 0);
-
-    // call CDMA SMS decode function
-    if(wmsts_ril_cdma_decode_sms(encoded_sms, clientBdData) != RIL_E_SUCCESS) {
-        jniThrowException(env, "java/lang/Exception", "CDMA SMS Decoding failed");
-        result = JNI_FAILURE;
-    }
-
-    free(encoded_sms);
-
-    return result;
-}
-
-
-// ---------------------------------------------------------------------------
-
-static const char *classPathName = "com/android/internal/telephony/cdma/sms/SmsDataCoding";
-
-static JNINativeMethod methods[] = {
-    /* name, signature, funcPtr */
-    {"nativeCdmaSmsConstructClientBD", "()I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD },
-    {"nativeCdmaSmsDestructClientBD", "()I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD },
-    {"nativeCdmaSmsSetBearerDataPrimitives", "(Lcom/android/internal/telephony/cdma/sms/BearerData;)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives },
-    {"nativeCdmaSmsGetBearerDataPrimitives", "(Lcom/android/internal/telephony/cdma/sms/BearerData;)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives },
-    {"nativeCdmaSmsSetUserData", "(Lcom/android/internal/telephony/cdma/sms/UserData;)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData },
-    {"nativeCdmaSmsGetUserData", "(Lcom/android/internal/telephony/cdma/sms/UserData;)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData },
-    {"nativeCdmaSmsSetUserDataHeader", "(I[BII)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader },
-    {"nativeCdmaSmsGetUserDataHeader", "()[B",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader },
-    {"nativeCdmaSmsSetSmsAddress", "(Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress },
-    {"nativeCdmaSmsGetSmsAddress", "(Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress },
-    {"nativeCdmaSmsEncodeSms", "()[B",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms },
-    {"nativeCdmaSmsDecodeSms", "([B)I",
-      (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms },
-};
-
-int register_android_cdma_sms_methods(JNIEnv *_env)
-{
-    return android::AndroidRuntime::registerNativeMethods(
-            _env, classPathName, methods, NELEM(methods));
-}
-
-// ---------------------------------------------------------------------------
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        LOGE("ERROR: GetEnv failed\n");
-        goto bail;
-    }
-    assert(env != NULL);
-
-    if (register_android_cdma_sms_methods(env) < 0) {
-        LOGE("ERROR: CDMA SMS native registration failed\n");
-        goto bail;
-    }
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
diff --git a/telephony/jni/cdmasms/cdma_sms_jni.h b/telephony/jni/cdmasms/cdma_sms_jni.h
deleted file mode 100644
index 253c006..0000000
--- a/telephony/jni/cdmasms/cdma_sms_jni.h
+++ /dev/null
@@ -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
diff --git a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
new file mode 100644
index 0000000..2c9075c
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
@@ -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));
+    }
+}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
new file mode 100644
index 0000000..723512c
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -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);
+
+}