Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0d4a350 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 133 into donut

* changes:
  Initial code for cdma sms encode and decode, in java, with simple tests.
parents f2aad4a4 83917db0
Loading
Loading
Loading
Loading
+116 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.util;

/**
 * An object that provides bitwise incremental read access to a byte array.
 *
 * This is useful, for example, when accessing a series of fields that
 * may not be aligned on byte boundaries.
 *
 * NOTE -- This class is not threadsafe.
 */
public class BitwiseInputStream {

    // The byte array being read from.
    private byte[] mBuf;

    // The current position offset, in bits, from the msb in byte 0.
    private int mPos;

    // The last valid bit offset.
    private int mEnd;

    /**
     * An exception to report access problems.
     */
    public static class AccessException extends Exception {
        public AccessException(String s) {
            super("BitwiseInputStream access failed: " + s);
        }
    }

    /**
     * Create object from byte array.
     *
     * @param buf a byte array containing data
     */
    public BitwiseInputStream(byte buf[]) {
        mBuf = buf;
        mEnd = buf.length * 8;
        mPos = 0;
    }

    /**
     * Return the number of bit still available for reading.
     */
    public int available() {
        return mEnd - mPos;
    }

    /**
     * Read some data and increment the current position.
     *
     * @param bits the amount of data to read (gte 0, lte 8)
     *
     * @return byte of read data (possibly partially filled, from lsb)
     */
    public byte read(int bits) throws AccessException {
        int index = mPos / 8;
        int offset = 16 - (mPos % 8) - bits;
        if ((bits < 0) || (bits > 8) || ((mPos + bits) > mEnd)) {
            throw new AccessException("illegal read " +
                "(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")");
        }
        int data = (mBuf[index] & 0xFF) << 8;
        if (offset < 8) data |= (mBuf[index + 1] & 0xFF);
        data >>>= offset;
        data &= (-1 >>> (32 - bits));
        mPos += bits;
        return (byte)data;
    }

    /**
     * Read data in bulk into a byte array and increment the current position.
     *
     * @param bits the amount of data to read
     *
     * @return newly allocated byte array of read data
     */
    public byte[] readByteArray(int bits) throws AccessException {
        int bytes = (bits / 8) + ((bits % 8) > 0 ? 1 : 0);
        byte[] arr = new byte[bytes];
        for (int i = 0; i < bytes; i++) {
            int increment = Math.min(8, bits - (i * 8));
            arr[i] = (byte)(read(increment) << (8 - increment));
        }
        return arr;
    }

    /**
     * Increment the current position and ignore contained data.
     *
     * @param bits the amount by which to increment the position
     */
    public void skip(int bits) throws AccessException {
        if ((mPos + bits) > mEnd) {
            throw new AccessException("illegal skip " +
                "(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")");
        }
        mPos += bits;
    }
}
+126 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+0 −14
Original line number Diff line number Diff line
@@ -20,20 +20,7 @@ import android.util.Log;
import com.android.internal.telephony.SmsHeader;
import java.util.Arrays;

import static android.telephony.SmsMessage.ENCODING_7BIT;
import static android.telephony.SmsMessage.ENCODING_16BIT;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
import static android.telephony.SmsMessage.MessageClass;
import static com.android.internal.telephony.SmsAddress.TON_ABBREVIATED;
import static com.android.internal.telephony.SmsAddress.TON_ALPHANUMERIC;
import static com.android.internal.telephony.SmsAddress.TON_INTERNATIONAL;
import static com.android.internal.telephony.SmsAddress.TON_NATIONAL;
import static com.android.internal.telephony.SmsAddress.TON_NETWORK;
import static com.android.internal.telephony.SmsAddress.TON_SUBSCRIBER;
import static com.android.internal.telephony.SmsAddress.TON_UNKNOWN;

/**
 * Base class declaring the specific methods and members for SmsMessage.
@@ -385,4 +372,3 @@ public abstract class SmsMessageBase {
    }

}
+22 −40
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.cdma.sms.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
import com.android.internal.telephony.cdma.sms.SmsDataCoding;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.telephony.cdma.sms.UserData;

@@ -50,23 +49,6 @@ import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
import static android.telephony.SmsMessage.MessageClass;
import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_NONE;
import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_TEMPORARY;
import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_PERMANENT;
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVER;
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_SUBMIT;
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_CANCELLATION;
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVERY_ACK;
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_USER_ACK;
import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_READ_ACK;
import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_ADDRESS_MAX;
import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_SUBADDRESS_MAX;
import static com.android.internal.telephony.cdma.sms.SmsEnvelope.SMS_BEARER_DATA_MAX;
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_7BIT_ASCII;
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_GSM_7BIT_ALPHABET;
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_IA5;
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_OCTET;
import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_UNICODE_16;

/**
 * A Short Message Service message.
@@ -186,7 +168,7 @@ public class SmsMessage extends SmsMessageBase {

        // ignore subaddress
        p.readInt(); //p_cur->sSubAddress.subaddressType
        p.readByte(); //p_cur->sSubAddress.odd
        p.readInt(); //p_cur->sSubAddress.odd
        count = p.readByte(); //p_cur->sSubAddress.number_of_digits
        //p_cur->sSubAddress.digits[digitCount] :
        for (int index=0; index < count; index++) {
@@ -309,15 +291,15 @@ public class SmsMessage extends SmsMessageBase {
            int septetCount = GsmAlphabet.countGsmSeptets(message, true);
            // User Data (and length)

            uData.userData = message.getBytes();
            uData.payload = message.getBytes();

            if (uData.userData.length > MAX_USER_DATA_SEPTETS) {
            if (uData.payload.length > MAX_USER_DATA_SEPTETS) {
                // Message too long
                return null;
            }

            // desired TP-Data-Coding-Scheme
            uData.userDataEncoding = UserData.UD_ENCODING_GSM_7BIT_ALPHABET;
            uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;

            // paddingBits not needed for UD_ENCODING_GSM_7BIT_ALPHABET

@@ -341,15 +323,15 @@ public class SmsMessage extends SmsMessageBase {
                return null;
            }

            uData.userData = textPart;
            uData.payload = textPart;

            if (uData.userData.length > MAX_USER_DATA_BYTES) {
            if (uData.payload.length > MAX_USER_DATA_BYTES) {
                // Message too long
                return null;
            }

            // TP-Data-Coding-Scheme
            uData.userDataEncoding = UserData.UD_ENCODING_UNICODE_16;
            uData.msgEncoding = UserData.ENCODING_UNICODE_16;

            // sms header
            if(headerData != null) {
@@ -425,8 +407,8 @@ public class SmsMessage extends SmsMessageBase {

        // TP-Data-Coding-Scheme
        // No class, 8 bit data
        uData.userDataEncoding = UserData.UD_ENCODING_OCTET;
        uData.userData = data;
        uData.msgEncoding = UserData.ENCODING_OCTET;
        uData.payload = data;

        byte[] msgData = sms.getEnvelope(destinationAddress, statusReportRequested, uData,
                true, true);
@@ -619,21 +601,21 @@ public class SmsMessage extends SmsMessageBase {
     * Parses a SMS message from its BearerData stream. (mobile-terminated only)
     */
    protected void parseSms() {
        mBearerData = SmsDataCoding.decodeCdmaSms(mEnvelope.bearerData);
        messageRef = mBearerData.messageID;
        mBearerData = BearerData.decode(mEnvelope.bearerData);
        messageRef = mBearerData.messageId;

        // TP-Message-Type-Indicator
        // (See 3GPP2 C.S0015-B, v2, 4.5.1)
        int messageType = mBearerData.messageType;

        switch (messageType) {
        case MESSAGE_TYPE_USER_ACK:
        case MESSAGE_TYPE_READ_ACK:
        case MESSAGE_TYPE_DELIVER:
        case BearerData.MESSAGE_TYPE_USER_ACK:
        case BearerData.MESSAGE_TYPE_READ_ACK:
        case BearerData.MESSAGE_TYPE_DELIVER:
            // Deliver (mobile-terminated only)
            parseSmsDeliver();
            break;
        case MESSAGE_TYPE_DELIVERY_ACK:
        case BearerData.MESSAGE_TYPE_DELIVERY_ACK:
            parseSmsDeliveryAck();
            break;

@@ -699,22 +681,22 @@ public class SmsMessage extends SmsMessageBase {
            return;
        }

        encodingType = uData.userDataEncoding;
        encodingType = uData.msgEncoding;

        // insert DCS-decoding here when type is supported by ril-library

        userData = uData.userData;
        userData = uData.payload;
        userDataHeader = uData.userDataHeader;

        switch (encodingType) {
        case UD_ENCODING_GSM_7BIT_ALPHABET:
        case UD_ENCODING_UNICODE_16:
        case UserData.ENCODING_GSM_7BIT_ALPHABET:
        case UserData.ENCODING_UNICODE_16:
            // user data was already decoded by wmsts-library
            messageBody = new String(userData);
            break;

        // data and unsupported encodings:
        case UD_ENCODING_OCTET:
        case UserData.ENCODING_OCTET:
        default:
            messageBody = null;
            break;
@@ -771,7 +753,7 @@ public class SmsMessage extends SmsMessageBase {
        if (useNewId) {
            setNextMessageId();
        }
        mBearerData.messageID = nextMessageId;
        mBearerData.messageId = nextMessageId;

        // Set the reply options (See C.S0015-B, v2.0, 4.5.11)
        if(statusReportRequested) {
@@ -795,7 +777,7 @@ public class SmsMessage extends SmsMessageBase {
        // ** encode BearerData **
        byte[] encodedBearerData = null;
        try {
            encodedBearerData = SmsDataCoding.encodeCdmaSms(mBearerData);
            encodedBearerData = BearerData.encode(mBearerData);
        } catch (Exception e) {
            Log.e(LOG_TAG, "doGetSubmitPdu: EncodeCdmaSMS function in JNI interface failed: "
                    + e.getMessage());
+482 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading