243 lines
8.1 KiB
Java
243 lines
8.1 KiB
Java
/*
|
|
* 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.internal.telephony;
|
|
|
|
import com.android.internal.util.HexDump;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* This class represents a SMS user data header.
|
|
*
|
|
*/
|
|
public class SmsHeader {
|
|
/** See TS 23.040 9.2.3.24 for description of this element ID. */
|
|
public static final int CONCATENATED_8_BIT_REFERENCE = 0x00;
|
|
/** See TS 23.040 9.2.3.24 for description of this element ID. */
|
|
public static final int SPECIAL_SMS_MESSAGE_INDICATION = 0x01;
|
|
/** See TS 23.040 9.2.3.24 for description of this element ID. */
|
|
public static final int APPLICATION_PORT_ADDRESSING_8_BIT = 0x04;
|
|
/** See TS 23.040 9.2.3.24 for description of this element ID. */
|
|
public static final int APPLICATION_PORT_ADDRESSING_16_BIT= 0x05;
|
|
/** See TS 23.040 9.2.3.24 for description of this element ID. */
|
|
public static final int CONCATENATED_16_BIT_REFERENCE = 0x08;
|
|
|
|
public static final int PORT_WAP_PUSH = 2948;
|
|
public static final int PORT_WAP_WSP = 9200;
|
|
|
|
private byte[] m_data;
|
|
private ArrayList<Element> m_elements = new ArrayList<Element>();
|
|
public int nbrOfHeaders;
|
|
|
|
/**
|
|
* Creates an SmsHeader object from raw user data header bytes.
|
|
*
|
|
* @param data is user data header bytes
|
|
* @return an SmsHeader object
|
|
*/
|
|
public static SmsHeader parse(byte[] data) {
|
|
SmsHeader header = new SmsHeader();
|
|
header.m_data = data;
|
|
|
|
int index = 0;
|
|
header.nbrOfHeaders = 0;
|
|
while (index < data.length) {
|
|
int id = data[index++] & 0xff;
|
|
int length = data[index++] & 0xff;
|
|
byte[] elementData = new byte[length];
|
|
System.arraycopy(data, index, elementData, 0, length);
|
|
header.add(new Element(id, elementData));
|
|
index += length;
|
|
header.nbrOfHeaders++;
|
|
}
|
|
|
|
return header;
|
|
}
|
|
|
|
public SmsHeader() { }
|
|
|
|
/**
|
|
* Returns the list of SmsHeader Elements that make up the header.
|
|
*
|
|
* @return the list of SmsHeader Elements.
|
|
*/
|
|
public ArrayList<Element> getElements() {
|
|
return m_elements;
|
|
}
|
|
|
|
/**
|
|
* Add an element to the SmsHeader.
|
|
*
|
|
* @param element to add.
|
|
*/
|
|
public void add(Element element) {
|
|
m_elements.add(element);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder builder = new StringBuilder();
|
|
|
|
builder.append("UDH LENGTH: " + m_data.length + " octets");
|
|
builder.append("UDH: ");
|
|
builder.append(HexDump.toHexString(m_data));
|
|
builder.append("\n");
|
|
|
|
for (Element e : getElements()) {
|
|
builder.append(" 0x" + HexDump.toHexString((byte)e.getID()) + " - ");
|
|
switch (e.getID()) {
|
|
case CONCATENATED_8_BIT_REFERENCE: {
|
|
builder.append("Concatenated Short Message 8bit ref\n");
|
|
byte[] data = e.getData();
|
|
builder.append(" " + data.length + " (0x");
|
|
builder.append(HexDump.toHexString((byte)data.length)
|
|
+ ") Bytes - Information Element\n");
|
|
builder.append(" " + data[0] + " : SM reference number\n");
|
|
builder.append(" " + data[1] + " : number of messages\n");
|
|
builder.append(" " + data[2] + " : this SM sequence number\n");
|
|
break;
|
|
}
|
|
|
|
case CONCATENATED_16_BIT_REFERENCE: {
|
|
builder.append("Concatenated Short Message 16bit ref\n");
|
|
byte[] data = e.getData();
|
|
builder.append(" " + data.length + " (0x");
|
|
builder.append(HexDump.toHexString((byte)data.length)
|
|
+ ") Bytes - Information Element\n");
|
|
builder.append(" " + (data[0] & 0xff) * 256 + (data[1] & 0xff)
|
|
+ " : SM reference number\n");
|
|
builder.append(" " + data[2] + " : number of messages\n");
|
|
builder.append(" " + data[3] + " : this SM sequence number\n");
|
|
break;
|
|
}
|
|
|
|
case APPLICATION_PORT_ADDRESSING_8_BIT:
|
|
{
|
|
builder.append("Application port addressing 8bit\n");
|
|
byte[] data = e.getData();
|
|
|
|
builder.append(" " + data.length + " (0x");
|
|
builder.append(HexDump.toHexString(
|
|
(byte)data.length) + ") Bytes - Information Element\n");
|
|
|
|
int source = (data[0] & 0xff);
|
|
builder.append(" " + source + " : DESTINATION port\n");
|
|
|
|
int dest = (data[1] & 0xff);
|
|
builder.append(" " + dest + " : SOURCE port\n");
|
|
break;
|
|
}
|
|
|
|
case APPLICATION_PORT_ADDRESSING_16_BIT: {
|
|
builder.append("Application port addressing 16bit\n");
|
|
byte[] data = e.getData();
|
|
|
|
builder.append(" " + data.length + " (0x");
|
|
builder.append(HexDump.toHexString((byte)data.length)
|
|
+ ") Bytes - Information Element\n");
|
|
|
|
int source = (data[0] & 0xff) << 8;
|
|
source |= (data[1] & 0xff);
|
|
builder.append(" " + source + " : DESTINATION port\n");
|
|
|
|
int dest = (data[2] & 0xff) << 8;
|
|
dest |= (data[3] & 0xff);
|
|
builder.append(" " + dest + " : SOURCE port\n");
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
builder.append("Unknown element\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return builder.toString();
|
|
}
|
|
|
|
private int calcSize() {
|
|
int size = 1; // +1 for the UDHL field
|
|
for (Element e : m_elements) {
|
|
size += e.getData().length;
|
|
size += 2; // 1 byte ID, 1 byte length
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Converts SmsHeader object to a byte array as specified in TS 23.040 9.2.3.24.
|
|
* @return Byte array representing the SmsHeader
|
|
*/
|
|
public byte[] toByteArray() {
|
|
if (m_elements.size() == 0) return null;
|
|
|
|
if (m_data == null) {
|
|
int size = calcSize();
|
|
int cur = 1;
|
|
m_data = new byte[size];
|
|
|
|
m_data[0] = (byte) (size-1); // UDHL does not include itself
|
|
|
|
for (Element e : m_elements) {
|
|
int length = e.getData().length;
|
|
m_data[cur++] = (byte) e.getID();
|
|
m_data[cur++] = (byte) length;
|
|
System.arraycopy(e.getData(), 0, m_data, cur, length);
|
|
cur += length;
|
|
}
|
|
}
|
|
|
|
return m_data;
|
|
}
|
|
|
|
/**
|
|
* A single Element in the SMS User Data Header.
|
|
*
|
|
* See TS 23.040 9.2.3.24.
|
|
*
|
|
*/
|
|
public static class Element {
|
|
private byte[] m_data;
|
|
private int m_id;
|
|
|
|
public Element(int id, byte[] data) {
|
|
m_id = id;
|
|
m_data = data;
|
|
}
|
|
|
|
/**
|
|
* Returns the Information Element Identifier for this element.
|
|
*
|
|
* @return the IE identifier.
|
|
*/
|
|
public int getID() {
|
|
return m_id;
|
|
}
|
|
|
|
/**
|
|
* Returns the data portion of this element.
|
|
*
|
|
* @return element data.
|
|
*/
|
|
public byte[] getData() {
|
|
return m_data;
|
|
}
|
|
}
|
|
}
|