blob: 2984fa8a576cd6ab1d7c62d027a476a52f6585cc [file] [log] [blame]
/*
* 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.telephony;
/**
* Implement the WSP data type decoder.
*
* @hide
*/
public class WspTypeDecoder {
private static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
private static final int WAP_PDU_LENGTH_QUOTE = 31;
public static final int PDU_TYPE_PUSH = 0x06;
public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a;
public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b;
public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e;
public static final int CONTENT_TYPE_B_PUSH_SL = 0x30;
public static final int CONTENT_TYPE_B_PUSH_CO = 0x32;
public static final int CONTENT_TYPE_B_MMS = 0x3e;
public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML =
"application/vnd.oma.drm.rights+xml";
public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML =
"application/vnd.oma.drm.rights+wbxml";
public static final String CONTENT_MIME_TYPE_B_PUSH_SI = "application/vnd.wap.sic";
public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc";
public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message";
public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
byte[] wspData;
int dataLength;
long unsigned32bit;
String stringValue;
public WspTypeDecoder(byte[] pdu) {
wspData = pdu;
}
/**
* Decode the "Text-string" type for WSP pdu
*
* @param startIndex The starting position of the "Text-string" in this pdu
*
* @return false when error(not a Text-string) occur
* return value can be retrieved by getValueString() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeTextString(int startIndex) {
int index = startIndex;
while (wspData[index] != 0) {
index++;
}
dataLength = index - startIndex + 1;
if (wspData[startIndex] == 127) {
stringValue = new String(wspData, startIndex+1, dataLength - 2);
} else {
stringValue = new String(wspData, startIndex, dataLength - 1);
}
return true;
}
/**
* Decode the "Short-integer" type for WSP pdu
*
* @param startIndex The starting position of the "Short-integer" in this pdu
*
* @return false when error(not a Short-integer) occur
* return value can be retrieved by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeShortInteger(int startIndex) {
if ((wspData[startIndex] & 0x80) == 0) {
return false;
}
unsigned32bit = wspData[startIndex] & 0x7f;
dataLength = 1;
return true;
}
/**
* Decode the "Long-integer" type for WSP pdu
*
* @param startIndex The starting position of the "Long-integer" in this pdu
*
* @return false when error(not a Long-integer) occur
* return value can be retrieved by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeLongInteger(int startIndex) {
int lengthMultiOctet = wspData[startIndex] & 0xff;
if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) {
return false;
}
unsigned32bit = 0;
for (int i=1; i<=lengthMultiOctet; i++) {
unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff);
}
dataLength = 1+lengthMultiOctet;
return true;
}
/**
* Decode the "Integer-Value" type for WSP pdu
*
* @param startIndex The starting position of the "Integer-Value" in this pdu
*
* @return false when error(not a Integer-Value) occur
* return value can be retrieved by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeIntegerValue(int startIndex) {
if (decodeShortInteger(startIndex) == true) {
return true;
}
return decodeLongInteger(startIndex);
}
/**
* Decode the "Uintvar-integer" type for WSP pdu
*
* @param startIndex The starting position of the "Uintvar-integer" in this pdu
*
* @return false when error(not a Uintvar-integer) occur
* return value can be retrieved by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeUintvarInteger(int startIndex) {
int index = startIndex;
unsigned32bit = 0;
while ((wspData[index] & 0x80) != 0) {
if ((index - startIndex) >= 4) {
return false;
}
unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
index++;
}
unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
dataLength = index - startIndex + 1;
return true;
}
/**
* Decode the "Value-length" type for WSP pdu
*
* @param startIndex The starting position of the "Value-length" in this pdu
*
* @return false when error(not a Value-length) occur
* return value can be retrieved by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeValueLength(int startIndex) {
if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
return false;
}
if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) {
unsigned32bit = wspData[startIndex];
dataLength = 1;
} else {
decodeUintvarInteger(startIndex+1);
dataLength ++;
}
return true;
}
/**
* Decode the "Extension-media" type for WSP pdu
*
* @param startIndex The starting position of the "Extension-media" in this pdu
*
* @return false when error(not a Extension-media) occur
* return value can be retrieved by getValueString() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeExtensionMedia(int startIndex) {
int index = startIndex;
while (wspData[index] != 0) {
index++;
}
dataLength = index - startIndex + 1;
stringValue = new String(wspData, startIndex, dataLength - 1);
return true;
}
/**
* Decode the "Constrained-encoding" type for WSP pdu
*
* @param startIndex The starting position of the "Constrained-encoding" in this pdu
*
* @return false when error(not a Constrained-encoding) occur
* return value can be retrieved first by getValueString() and second by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeConstrainedEncoding(int startIndex) {
if (decodeShortInteger(startIndex) == true) {
stringValue = null;
return true;
}
return decodeExtensionMedia(startIndex);
}
/**
* Decode the "Content-type" type for WSP pdu
*
* @param startIndex The starting position of the "Content-type" in this pdu
*
* @return false when error(not a Content-type) occur
* return value can be retrieved first by getValueString() and second by getValue32()
* method length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeContentType(int startIndex) {
int mediaPrefixLength;
long mediaFieldLength;
if (decodeValueLength(startIndex) == false) {
return decodeConstrainedEncoding(startIndex);
}
mediaPrefixLength = getDecodedDataLength();
mediaFieldLength = getValue32();
if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
dataLength += mediaPrefixLength;
stringValue = null;
return true;
}
if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
dataLength += mediaPrefixLength;
return true;
}
return false;
}
/**
* Decode the "Content length" type for WSP pdu
*
* @param startIndex The starting position of the "Content length" in this pdu
*
* @return false when error(not a Content length) occur
* return value can be retrieved by getValue32() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeContentLength(int startIndex) {
return decodeIntegerValue(startIndex);
}
/**
* Decode the "Content location" type for WSP pdu
*
* @param startIndex The starting position of the "Content location" in this pdu
*
* @return false when error(not a Content location) occur
* return value can be retrieved by getValueString() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeContentLocation(int startIndex) {
return decodeTextString(startIndex);
}
/**
* Decode the "X-Wap-Application-Id" type for WSP pdu
*
* @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu
*
* @return false when error(not a X-Wap-Application-Id) occur
* return value can be retrieved first by getValueString() and second by getValue32()
* method length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeXWapApplicationId(int startIndex) {
if (decodeIntegerValue(startIndex) == true) {
stringValue = null;
return true;
}
return decodeTextString(startIndex);
}
/**
* Decode the "X-Wap-Content-URI" type for WSP pdu
*
* @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu
*
* @return false when error(not a X-Wap-Content-URI) occur
* return value can be retrieved by getValueString() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeXWapContentURI(int startIndex) {
return decodeTextString(startIndex);
}
/**
* Decode the "X-Wap-Initiator-URI" type for WSP pdu
*
* @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu
*
* @return false when error(not a X-Wap-Initiator-URI) occur
* return value can be retrieved by getValueString() method
* length of data in pdu can be retrieved by getValue32() method
*/
public boolean decodeXWapInitiatorURI(int startIndex) {
return decodeTextString(startIndex);
}
/**
* The data length of latest operation.
*/
public int getDecodedDataLength() {
return dataLength;
}
/**
* The 32-bits result of latest operation.
*/
public long getValue32() {
return unsigned32bit;
}
/**
* The String result of latest operation.
*/
public String getValueString() {
return stringValue;
}
}