14980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen/* 24980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * Copyright (C) 2006 The Android Open Source Project 34980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * 44980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * Licensed under the Apache License, Version 2.0 (the "License"); 54980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * you may not use this file except in compliance with the License. 64980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * You may obtain a copy of the License at 74980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * 84980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * http://www.apache.org/licenses/LICENSE-2.0 94980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * 104980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * Unless required by applicable law or agreed to in writing, software 114980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * distributed under the License is distributed on an "AS IS" BASIS, 124980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * See the License for the specific language governing permissions and 144980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * limitations under the License. 154980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 164980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 174980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenpackage com.android.internal.telephony; 184980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 194980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenimport com.android.internal.telephony.SmsConstants; 204980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenimport com.android.internal.util.HexDump; 214980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 224980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenimport java.io.ByteArrayInputStream; 234980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenimport java.io.ByteArrayOutputStream; 244980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 254980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenimport java.util.ArrayList; 264980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 274980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen/** 284980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * SMS user data header, as specified in TS 23.040 9.2.3.24. 294980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 304980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsenpublic class SmsHeader { 314980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 324980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen // TODO(cleanup): this data structure is generally referred to as 334980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen // the 'user data header' or UDH, and so the class name should 344980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen // change to reflect this... 354980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 364980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** SMS user data header information element identifiers. 374980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * (see TS 23.040 9.2.3.24) 384980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 394980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_CONCATENATED_8_BIT_REFERENCE = 0x00; 404980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION = 0x01; 414980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT = 0x04; 424980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05; 434980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_SMSC_CONTROL_PARAMS = 0x06; 444980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_UDH_SOURCE_INDICATION = 0x07; 454980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_CONCATENATED_16_BIT_REFERENCE = 0x08; 464980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL = 0x09; 474980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_TEXT_FORMATTING = 0x0A; 484980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_PREDEFINED_SOUND = 0x0B; 494980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_USER_DEFINED_SOUND = 0x0C; 504980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_PREDEFINED_ANIMATION = 0x0D; 514980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_LARGE_ANIMATION = 0x0E; 524980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_SMALL_ANIMATION = 0x0F; 534980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_LARGE_PICTURE = 0x10; 544980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_SMALL_PICTURE = 0x11; 554980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_VARIABLE_PICTURE = 0x12; 564980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_USER_PROMPT_INDICATOR = 0x13; 574980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_EXTENDED_OBJECT = 0x14; 584980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_REUSED_EXTENDED_OBJECT = 0x15; 594980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_COMPRESSION_CONTROL = 0x16; 604980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_OBJECT_DISTR_INDICATOR = 0x17; 614980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_STANDARD_WVG_OBJECT = 0x18; 624980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_CHARACTER_SIZE_WVG_OBJECT = 0x19; 634980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD = 0x1A; 644980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_RFC_822_EMAIL_HEADER = 0x20; 654980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_HYPERLINK_FORMAT_ELEMENT = 0x21; 664980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_REPLY_ADDRESS_ELEMENT = 0x22; 674980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION = 0x23; 684980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24; 694980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25; 704980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 714980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int PORT_WAP_PUSH = 2948; 724980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static final int PORT_WAP_WSP = 9200; 734980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 744980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static class PortAddrs { 754980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int destPort; 764980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int origPort; 774980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public boolean areEightBits; 784980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 794980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 804980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static class ConcatRef { 814980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int refNumber; 824980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int seqNumber; 834980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int msgCount; 844980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public boolean isEightBits; 854980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 864980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 874980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static class SpecialSmsMsg { 884980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int msgIndType; 894980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int msgCount; 904980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 914980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 924980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** 934980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * A header element that is not explicitly parsed, meaning not 944980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * PortAddrs or ConcatRef or SpecialSmsMsg. 954980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 964980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static class MiscElt { 974980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int id; 984980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public byte[] data; 994980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 1004980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 1014980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public PortAddrs portAddrs; 1024980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public ConcatRef concatRef; 1034980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public ArrayList<SpecialSmsMsg> specialSmsMsgList = new ArrayList<SpecialSmsMsg>(); 1044980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public ArrayList<MiscElt> miscEltList = new ArrayList<MiscElt>(); 1054980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 1064980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** 7 bit national language locking shift table, or 0 for GSM default 7 bit alphabet. */ 1074980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int languageTable; 1084980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 1094980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** 7 bit national language single shift table, or 0 for GSM default 7 bit extension table. */ 1104980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public int languageShiftTable; 1114980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 1124980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public SmsHeader() {} 1134980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 1144980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** 1154980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * Create structured SmsHeader object from serialized byte array representation. 1164980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * (see TS 23.040 9.2.3.24) 1174980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * @param data is user data header bytes 1184980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * @return SmsHeader object 1194980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 1204980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static SmsHeader fromByteArray(byte[] data) { 1214980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen ByteArrayInputStream inStream = new ByteArrayInputStream(data); 1224980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen SmsHeader smsHeader = new SmsHeader(); 1234980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen while (inStream.available() > 0) { 1244980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** 1254980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * NOTE: as defined in the spec, ConcatRef and PortAddr 1264980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * fields should not reoccur, but if they do the last 1274980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * occurrence is to be used. Also, for ConcatRef 1284980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * elements, if the count is zero, sequence is zero, or 1294980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * sequence is larger than count, the entire element is to 1304980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * be ignored. 1314980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 1324980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen int id = inStream.read(); 1334980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen int length = inStream.read(); 1344980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen ConcatRef concatRef; 1354980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen PortAddrs portAddrs; 1364980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen switch (id) { 1374980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_CONCATENATED_8_BIT_REFERENCE: 1384980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef = new ConcatRef(); 1394980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.refNumber = inStream.read(); 1404980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.msgCount = inStream.read(); 1414980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.seqNumber = inStream.read(); 1424980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.isEightBits = true; 1434980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 && 1444980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.seqNumber <= concatRef.msgCount) { 1454980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.concatRef = concatRef; 1464980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 1474980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1484980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_CONCATENATED_16_BIT_REFERENCE: 1494980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef = new ConcatRef(); 1504980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.refNumber = (inStream.read() << 8) | inStream.read(); 1514980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.msgCount = inStream.read(); 1524980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.seqNumber = inStream.read(); 1534980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.isEightBits = false; 1544980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 && 1554980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen concatRef.seqNumber <= concatRef.msgCount) { 1564980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.concatRef = concatRef; 1574980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 1584980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1594980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT: 1604980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs = new PortAddrs(); 1614980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs.destPort = inStream.read(); 1624980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs.origPort = inStream.read(); 1634980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs.areEightBits = true; 1644980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.portAddrs = portAddrs; 1654980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1664980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT: 1674980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs = new PortAddrs(); 1684980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs.destPort = (inStream.read() << 8) | inStream.read(); 1694980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs.origPort = (inStream.read() << 8) | inStream.read(); 1704980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen portAddrs.areEightBits = false; 1714980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.portAddrs = portAddrs; 1724980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1734980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT: 1744980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.languageShiftTable = inStream.read(); 1754980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1764980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT: 1774980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.languageTable = inStream.read(); 1784980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1794980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen case ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION: 1804980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen SpecialSmsMsg specialSmsMsg = new SpecialSmsMsg(); 1814980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen specialSmsMsg.msgIndType = inStream.read(); 1824980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen specialSmsMsg.msgCount = inStream.read(); 1834980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.specialSmsMsgList.add(specialSmsMsg); 1844980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen break; 1854980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen default: 1864980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen MiscElt miscElt = new MiscElt(); 1874980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen miscElt.id = id; 1884980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen miscElt.data = new byte[length]; 1894980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen inStream.read(miscElt.data, 0, length); 1904980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen smsHeader.miscEltList.add(miscElt); 1914980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 1924980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 1934980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen return smsHeader; 1944980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 1954980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 1964980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen /** 1974980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * Create serialized byte array representation from structured SmsHeader object. 1984980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * (see TS 23.040 9.2.3.24) 1994980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen * @return Byte array representing the SmsHeader 2004980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen */ 2014980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public static byte[] toByteArray(SmsHeader smsHeader) { 2024980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if ((smsHeader.portAddrs == null) && 2034980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen (smsHeader.concatRef == null) && 2044980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen (smsHeader.specialSmsMsgList.isEmpty()) && 2054980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen (smsHeader.miscEltList.isEmpty()) && 2064980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen (smsHeader.languageShiftTable == 0) && 2074980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen (smsHeader.languageTable == 0)) { 2084980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen return null; 2094980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2104980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 2114980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen ByteArrayOutputStream outStream = 2124980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen new ByteArrayOutputStream(SmsConstants.MAX_USER_DATA_BYTES); 2134980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen ConcatRef concatRef = smsHeader.concatRef; 2144980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (concatRef != null) { 2154980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (concatRef.isEightBits) { 2164980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_CONCATENATED_8_BIT_REFERENCE); 2174980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(3); 2184980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(concatRef.refNumber); 2194980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } else { 2204980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_CONCATENATED_16_BIT_REFERENCE); 2214980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(4); 2224980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(concatRef.refNumber >>> 8); 2234980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(concatRef.refNumber & 0x00FF); 2244980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2254980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(concatRef.msgCount); 2264980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(concatRef.seqNumber); 2274980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2284980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen PortAddrs portAddrs = smsHeader.portAddrs; 2294980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (portAddrs != null) { 2304980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (portAddrs.areEightBits) { 2314980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT); 2324980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(2); 2334980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(portAddrs.destPort); 2344980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(portAddrs.origPort); 2354980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } else { 2364980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT); 2374980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(4); 2384980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(portAddrs.destPort >>> 8); 2394980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(portAddrs.destPort & 0x00FF); 2404980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(portAddrs.origPort >>> 8); 2414980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(portAddrs.origPort & 0x00FF); 2424980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2434980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2444980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (smsHeader.languageShiftTable != 0) { 2454980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT); 2464980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(1); 2474980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(smsHeader.languageShiftTable); 2484980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2494980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (smsHeader.languageTable != 0) { 2504980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT); 2514980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(1); 2524980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(smsHeader.languageTable); 2534980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2544980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen for (SpecialSmsMsg specialSmsMsg : smsHeader.specialSmsMsgList) { 2554980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION); 2564980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(2); 2574980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(specialSmsMsg.msgIndType & 0xFF); 2584980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(specialSmsMsg.msgCount & 0xFF); 2594980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2604980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen for (MiscElt miscElt : smsHeader.miscEltList) { 2614980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(miscElt.id); 2624980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(miscElt.data.length); 2634980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen outStream.write(miscElt.data, 0, miscElt.data.length); 2644980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2654980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen return outStream.toByteArray(); 2664980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2674980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 2684980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen @Override 2694980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen public String toString() { 2704980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen StringBuilder builder = new StringBuilder(); 2714980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("UserDataHeader "); 2724980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("{ ConcatRef "); 2734980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (concatRef == null) { 2744980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("unset"); 2754980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } else { 2764980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("{ refNumber=" + concatRef.refNumber); 2774980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", msgCount=" + concatRef.msgCount); 2784980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", seqNumber=" + concatRef.seqNumber); 2794980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", isEightBits=" + concatRef.isEightBits); 2804980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(" }"); 2814980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2824980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", PortAddrs "); 2834980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (portAddrs == null) { 2844980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("unset"); 2854980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } else { 2864980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("{ destPort=" + portAddrs.destPort); 2874980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", origPort=" + portAddrs.origPort); 2884980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", areEightBits=" + portAddrs.areEightBits); 2894980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(" }"); 2904980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2914980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (languageShiftTable != 0) { 2924980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", languageShiftTable=" + languageShiftTable); 2934980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2944980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen if (languageTable != 0) { 2954980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", languageTable=" + languageTable); 2964980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 2974980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen for (SpecialSmsMsg specialSmsMsg : specialSmsMsgList) { 2984980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", SpecialSmsMsg "); 2994980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("{ msgIndType=" + specialSmsMsg.msgIndType); 3004980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", msgCount=" + specialSmsMsg.msgCount); 3014980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(" }"); 3024980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 3034980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen for (MiscElt miscElt : miscEltList) { 3044980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", MiscElt "); 3054980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append("{ id=" + miscElt.id); 3064980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", length=" + miscElt.data.length); 3074980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(", data=" + HexDump.toHexString(miscElt.data)); 3084980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(" }"); 3094980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 3104980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen builder.append(" }"); 3114980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen return builder.toString(); 3124980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen } 3134980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen 3144980bf4aff8d49ac4e05444a6ef40ea1536f1afbDan Willemsen} 315