10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.TelephonyManager; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.test.AndroidTestCase; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.test.suitebuilder.annotation.SmallTest; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.SmsMessage; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.HexDump; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class GsmSmsTest extends AndroidTestCase { 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testAddressing() throws Exception { 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E"; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+14155551212", sms.getServiceCenterAddress()); 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+16505551111", sms.getOriginatingAddress()); 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("Test", sms.getMessageBody()); 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07914151551512f2040B916105551511f100036060924180008A0DA" 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "8695DAC2E8FE9296A794E07"; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+14155551212", sms.getServiceCenterAddress()); 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+16505551111", sms.getOriginatingAddress()); 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("(Subject)Test", sms.getMessageBody()); 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testUdh() throws Exception { 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F" 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D" 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426" 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "66C414141414D7741414236514141414141008D908918802B3135313232393737" 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703" 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "A2F2F36"; 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsHeader header = sms.getUserDataHeader(); 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertNotNull(header); 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertNotNull(header.concatRef); 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.refNumber, 42); 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.msgCount, 2); 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.seqNumber, 1); 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.isEightBits, true); 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertNotNull(header.portAddrs); 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.portAddrs.destPort, 2948); 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.portAddrs.origPort, 9200); 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.portAddrs.areEightBits, false); 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07914140279510F6440A8111110301003BF56080207130238A3B0B05040B8423F" 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141" 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "42666C414141414D774141423651414141414100"; 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville header = sms.getUserDataHeader(); 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertNotNull(header); 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertNotNull(header.concatRef); 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.refNumber, 42); 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.msgCount, 2); 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.seqNumber, 2); 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.concatRef.isEightBits, true); 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertNotNull(header.portAddrs); 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.portAddrs.destPort, 2948); 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.portAddrs.origPort, 9200); 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(header.portAddrs.areEightBits, false); 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testUcs2() throws Exception { 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07912160130300F4040B914151245584F600087010807121352B1021220" 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "0A900AE00680065006C006C006F"; 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("\u2122\u00a9\u00aehello", sms.getMessageBody()); 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testMultipart() throws Exception { 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Multi-part text SMS with septet data. 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003" 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "00020162B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562"; 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(sms.getMessageBody(), 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "1111111111111111111111111111111111111111" 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "1111111111111111111111111111111111111111" 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "1111111111111111111111111111111111111111" 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "111111111111111111111111111111111"); 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07916163838408F6440B816105224431F700007060217185000A23050003" 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "00020262B1582C168BC96432994C2693C96432994C2693C96432990C"; 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("1111111222222222222222222222", sms.getMessageBody()); 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testCPHSVoiceMail() throws Exception { 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "set MWI flag" 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07912160130310F20404D0110041006060627171118A0120"; 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isReplace()); 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("_@", sms.getOriginatingAddress()); 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(" ", sms.getMessageBody()); 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMWISetMessage()); 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "clear mwi flag" 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07912160130310F20404D0100041006021924193352B0120"; 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMWIClearMessage()); 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "clear MWI flag" 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07912160130310F20404D0100041006060627161058A0120"; 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isReplace()); 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("\u0394@", sms.getOriginatingAddress()); 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(" ", sms.getMessageBody()); 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMWIClearMessage()); 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testCingularVoiceMail() throws Exception { 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "set MWI flag" 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07912180958750F84401800500C87020026195702B06040102000200"; 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMWISetMessage()); 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMwiDontStore()); 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "clear mwi flag" 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07912180958750F84401800500C07020027160112B06040102000000"; 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMWIClearMessage()); 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isMwiDontStore()); 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testEmailGateway() throws Exception { 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" + 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3"; 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+14155551212", sms.getServiceCenterAddress()); 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isEmail()); 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("foo@example.com", sms.getEmailFrom()); 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("foo@example.com", sms.getDisplayOriginatingAddress()); 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // As of https://android-git.corp.google.com/g/#change,9324 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // getPseudoSubject will always be empty, and any subject is not extracted. 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("", sms.getPseudoSubject()); 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("test subject /test body", sms.getDisplayMessageBody()); 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("test subject /test body", sms.getEmailBody()); 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // email gateway sms test, including gsm extended character set. 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" + 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629"; 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+14155551212", sms.getServiceCenterAddress()); 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertTrue(sms.isEmail()); 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("foo@example.com", sms.getDisplayOriginatingAddress()); 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("foo@example.com", sms.getEmailFrom()); 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("{ testBody[^~\\] }", sms.getDisplayMessageBody()); 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("{ testBody[^~\\] }", sms.getEmailBody()); 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testExtendedCharacterTable() throws Exception { 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String pdu = "07914151551512f2040B916105551511f100006080615131728A44D4F29C0E2" + 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "AE3E96537B94C068DD16179784C2FCB41F4B0985D06B958ADD00FB0E94536AF9749" + 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "74DA6D281BA00E95E26D509B946FC3DBF87A25D56A04"; 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+14155551212", sms.getServiceCenterAddress()); 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("+16505551111", sms.getOriginatingAddress()); 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#", 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms.getMessageBody()); 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // GSM 7 bit tables in String form, Escape (0x1B) replaced with '@' 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final String[] sBasicTables = { 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // GSM 7 bit default alphabet 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_" 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u00c6\u00e6\u00df\u00c9" 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6" 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0", 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Turkish locking shift table 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_" 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u015e\u015f\u00df\u00c9" 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6" 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0", 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // no locking shift table defined for Spanish 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "", 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Portuguese locking shift table 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_" 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|@\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba%&'()" 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc" 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0" 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville }; 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testFragmentText() throws Exception { 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville TelephonyManager.PHONE_TYPE_GSM); 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Valid 160 character 7-bit text. 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String text = "123456789012345678901234567890123456789012345678901234567890" + 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "1234567890123456789012345678901234567890123456789012345678901234567890" + 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "123456789012345678901234567890"; 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmAlphabet.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.msgCount); 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(160, ted.codeUnitCount); 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.codeUnitSize); 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageTable); 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageShiftTable); 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isGsmPhone) { 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, fragments.size()); 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Valid 161 character 7-bit text. 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville text = "123456789012345678901234567890123456789012345678901234567890" + 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "1234567890123456789012345678901234567890123456789012345678901234567890" + 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "1234567890123456789012345678901"; 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ted = SmsMessage.calculateLength(text, false); 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(2, ted.msgCount); 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(161, ted.codeUnitCount); 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.codeUnitSize); 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageTable); 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageShiftTable); 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isGsmPhone) { 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(2, fragments.size()); 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(text, fragments.get(0) + fragments.get(1)); 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(153, fragments.get(0).length()); 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(8, fragments.get(1).length()); 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testFragmentTurkishText() throws Exception { 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville TelephonyManager.PHONE_TYPE_GSM); 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables(); 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] turkishTable = { 1 }; 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmAlphabet.setEnabledSingleShiftTables(turkishTable); 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Valid 77 character text with Turkish characters. 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "ĞŞİğşıĞŞİğşıĞŞİğş"; 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmAlphabet.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.msgCount); 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(154, ted.codeUnitCount); 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.codeUnitSize); 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageTable); 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.languageShiftTable); 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isGsmPhone) { 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, fragments.size()); 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(text, fragments.get(0)); 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(77, fragments.get(0).length()); 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Valid 78 character text with Turkish characters. 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "ĞŞİğşıĞŞİğşıĞŞİğşı"; 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ted = SmsMessage.calculateLength(text, false); 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(2, ted.msgCount); 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(156, ted.codeUnitCount); 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.codeUnitSize); 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageTable); 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.languageShiftTable); 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isGsmPhone) { 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(2, fragments.size()); 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(text, fragments.get(0) + fragments.get(1)); 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(74, fragments.get(0).length()); 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(4, fragments.get(1).length()); 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Valid 160 character text with Turkish characters. 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" + 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı"; 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ted = SmsMessage.calculateLength(text, false); 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(3, ted.msgCount); 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(320, ted.codeUnitCount); 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.codeUnitSize); 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(0, ted.languageTable); 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(1, ted.languageShiftTable); 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isGsmPhone) { 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(3, fragments.size()); 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2)); 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(74, fragments.get(0).length()); 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(74, fragments.get(1).length()); 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(12, fragments.get(2).length()); 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmAlphabet.setEnabledSingleShiftTables(oldTables); 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testDecode() throws Exception { 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodeSingle(0); // default table 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodeSingle(1); // Turkish locking shift table 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodeSingle(3); // Portuguese locking shift table 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void decodeSingle(int language) throws Exception { 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] septets = new byte[(7 * 128 + 7) / 8]; 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitOffset = 0; 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < 128; i++) { 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int v; 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (i == 0x1b) { 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // extended escape char 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville v = 0; 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville v = i; 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int byteOffset = bitOffset / 8; 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int shift = bitOffset % 8; 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset] |= v << shift; 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (shift > 1) { 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset + 1] = (byte) (v >> (8 - shift)); 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitOffset += 7; 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, 128, 0, language, 0); 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, language, 0); 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(sBasicTables[language], decoded); 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // reEncoded has the count septets byte at the front 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(septets.length + 1, reEncoded.length); 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < septets.length; i++) { 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(septets[i], reEncoded[i + 1]); 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int GSM_ESCAPE_CHARACTER = 0x1b; 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final String[] sExtendedTables = { 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // GSM 7 bit default alphabet extension table 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "\f^{}\\[~]|\u20ac", 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Turkish single shift extension table 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "\f^{}\\[~]|\u011e\u0130\u015e\u00e7\u20ac\u011f\u0131\u015f", 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Spanish single shift extension table 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "\u00e7\f^{}\\[~]|\u00c1\u00cd\u00d3\u00da\u00e1\u20ac\u00ed\u00f3\u00fa", 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Portuguese single shift extension table 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "\u00ea\u00e7\f\u00d4\u00f4\u00c1\u00e1\u03a6\u0393^\u03a9\u03a0\u03a8\u03a3\u0398\u00ca" 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "{}\\[~]|\u00c0\u00cd\u00d3\u00da\u00c3\u00d5\u00c2\u20ac\u00ed\u00f3\u00fa\u00e3" 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "\u00f5\u00e2" 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville }; 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int[][] sExtendedTableIndexes = { 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x65}, 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x47, 0x49, 0x53, 0x63, 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0x65, 0x67, 0x69, 0x73}, 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville {0x09, 0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 0x4f, 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0x55, 0x61, 0x65, 0x69, 0x6f, 0x75}, 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville {0x05, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0x18, 0x19, 0x1f, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0x4f, 0x55, 0x5b, 0x5c, 0x61, 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x7c, 0x7f} 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville }; 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testDecodeExtended() throws Exception { 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int language = 0; language < 3; language++) { 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] tableIndex = sExtendedTableIndexes[language]; 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numSeptets = tableIndex.length * 2; // two septets per extended char 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] septets = new byte[(7 * numSeptets + 7) / 8]; 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitOffset = 0; 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int v : tableIndex) { 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // escape character 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int byteOffset = bitOffset / 8; 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int shift = bitOffset % 8; 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift; 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (shift > 1) { 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift)); 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitOffset += 7; 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // extended table index 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byteOffset = bitOffset / 8; 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville shift = bitOffset % 8; 4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset] |= v << shift; 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (shift > 1) { 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset + 1] = (byte) (v >> (8 - shift)); 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitOffset += 7; 4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0, language); 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, 0, language); 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(sExtendedTables[language], decoded); 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // reEncoded has the count septets byte at the front 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(septets.length + 1, reEncoded.length); 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < septets.length; i++) { 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(septets[i], reEncoded[i + 1]); 4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @SmallTest 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void testDecodeExtendedFallback() throws Exception { 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // verify that unmapped characters in extension table fall back to locking shift table 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int language = 0; language < 3; language++) { 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] tableIndex = sExtendedTableIndexes[language]; 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numChars = 128 - tableIndex.length; 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numSeptets = numChars * 2; // two septets per extended char 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] septets = new byte[(7 * numSeptets + 7) / 8]; 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tableOffset = 0; 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitOffset = 0; 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder defaultTable = new StringBuilder(128); 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder turkishTable = new StringBuilder(128); 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville StringBuilder portugueseTable = new StringBuilder(128); 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (char c = 0; c < 128; c++) { 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // skip characters that are present in the current extension table 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (tableOffset < tableIndex.length && tableIndex[tableOffset] == c) { 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tableOffset++; 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville continue; 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // escape character 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int byteOffset = bitOffset / 8; 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int shift = bitOffset % 8; 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift; 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (shift > 1) { 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift)); 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitOffset += 7; 5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // extended table index 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byteOffset = bitOffset / 8; 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville shift = bitOffset % 8; 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset] |= c << shift; 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (shift > 1) { 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville septets[byteOffset + 1] = (byte) (c >> (8 - shift)); 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitOffset += 7; 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (c == GsmAlphabet.GSM_EXTENDED_ESCAPE) { 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // double Escape maps to space character 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville defaultTable.append(' '); 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville turkishTable.append(' '); 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portugueseTable.append(' '); 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // other unmapped chars map to the default or locking shift table 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville defaultTable.append(sBasicTables[0].charAt(c)); 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville turkishTable.append(sBasicTables[1].charAt(c)); 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portugueseTable.append(sBasicTables[3].charAt(c)); 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0, language); 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(defaultTable.toString(), decoded); 5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 1, language); 5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(turkishTable.toString(), decoded); 5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 3, language); 5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assertEquals(portugueseTable.toString(), decoded); 5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 539