1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 import android.telephony.TelephonyManager; 20 import android.test.AndroidTestCase; 21 import android.test.suitebuilder.annotation.SmallTest; 22 23 import com.android.internal.telephony.gsm.SmsMessage; 24 import com.android.internal.util.HexDump; 25 26 import java.util.ArrayList; 27 28 public class GsmSmsTest extends AndroidTestCase { 29 30 @SmallTest 31 public void testAddressing() throws Exception { 32 String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E"; 33 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 34 assertEquals("+14155551212", sms.getServiceCenterAddress()); 35 assertEquals("+16505551111", sms.getOriginatingAddress()); 36 assertEquals("Test", sms.getMessageBody()); 37 38 pdu = "07914151551512f2040B916105551511f100036060924180008A0DA" 39 + "8695DAC2E8FE9296A794E07"; 40 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 41 assertEquals("+14155551212", sms.getServiceCenterAddress()); 42 assertEquals("+16505551111", sms.getOriginatingAddress()); 43 assertEquals("(Subject)Test", sms.getMessageBody()); 44 45 pdu = "07914151551512F20409E1BADCBE5AF100006060605130308A04D4F29C0E"; 46 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 47 assertEquals("*#abc#*51", sms.getOriginatingAddress()); 48 } 49 50 @SmallTest 51 public void testUdh() throws Exception { 52 String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F" 53 + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D" 54 + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426" 55 + "66C414141414D7741414236514141414141008D908918802B3135313232393737" 56 + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703" 57 + "A2F2F36"; 58 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 59 SmsHeader header = sms.getUserDataHeader(); 60 assertNotNull(header); 61 assertNotNull(header.concatRef); 62 assertEquals(header.concatRef.refNumber, 42); 63 assertEquals(header.concatRef.msgCount, 2); 64 assertEquals(header.concatRef.seqNumber, 1); 65 assertEquals(header.concatRef.isEightBits, true); 66 assertNotNull(header.portAddrs); 67 assertEquals(header.portAddrs.destPort, 2948); 68 assertEquals(header.portAddrs.origPort, 9200); 69 assertEquals(header.portAddrs.areEightBits, false); 70 71 pdu = "07914140279510F6440A8111110301003BF56080207130238A3B0B05040B8423F" 72 + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141" 73 + "42666C414141414D774141423651414141414100"; 74 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 75 header = sms.getUserDataHeader(); 76 assertNotNull(header); 77 assertNotNull(header.concatRef); 78 assertEquals(header.concatRef.refNumber, 42); 79 assertEquals(header.concatRef.msgCount, 2); 80 assertEquals(header.concatRef.seqNumber, 2); 81 assertEquals(header.concatRef.isEightBits, true); 82 assertNotNull(header.portAddrs); 83 assertEquals(header.portAddrs.destPort, 2948); 84 assertEquals(header.portAddrs.origPort, 9200); 85 assertEquals(header.portAddrs.areEightBits, false); 86 } 87 88 @SmallTest 89 public void testUcs2() throws Exception { 90 String pdu = "07912160130300F4040B914151245584F600087010807121352B1021220" 91 + "0A900AE00680065006C006C006F"; 92 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 93 assertEquals("\u2122\u00a9\u00aehello", sms.getMessageBody()); 94 } 95 96 @SmallTest 97 public void testMultipart() throws Exception { 98 /* 99 * Multi-part text SMS with septet data. 100 */ 101 String pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003" 102 + "00020162B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 103 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 104 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 105 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" 106 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562"; 107 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 108 assertEquals(sms.getMessageBody(), 109 "1111111111111111111111111111111111111111" 110 + "1111111111111111111111111111111111111111" 111 + "1111111111111111111111111111111111111111" 112 + "111111111111111111111111111111111"); 113 114 pdu = "07916163838408F6440B816105224431F700007060217185000A23050003" 115 + "00020262B1582C168BC96432994C2693C96432994C2693C96432990C"; 116 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 117 assertEquals("1111111222222222222222222222", sms.getMessageBody()); 118 } 119 120 @SmallTest 121 public void testCPHSVoiceMail() throws Exception { 122 // "set MWI flag" 123 124 String pdu = "07912160130310F20404D0110041006060627171118A0120"; 125 126 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 127 128 assertTrue(sms.isReplace()); 129 assertEquals("_@", sms.getOriginatingAddress()); 130 assertEquals(" ", sms.getMessageBody()); 131 assertTrue(sms.isMWISetMessage()); 132 133 // "clear mwi flag" 134 135 pdu = "07912160130310F20404D0100041006021924193352B0120"; 136 137 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 138 139 assertTrue(sms.isMWIClearMessage()); 140 141 // "clear MWI flag" 142 143 pdu = "07912160130310F20404D0100041006060627161058A0120"; 144 145 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 146 147 assertTrue(sms.isReplace()); 148 assertEquals("\u0394@", sms.getOriginatingAddress()); 149 assertEquals(" ", sms.getMessageBody()); 150 assertTrue(sms.isMWIClearMessage()); 151 } 152 153 @SmallTest 154 public void testCingularVoiceMail() throws Exception { 155 // "set MWI flag" 156 157 String pdu = "07912180958750F84401800500C87020026195702B06040102000200"; 158 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 159 160 assertTrue(sms.isMWISetMessage()); 161 assertTrue(sms.isMwiDontStore()); 162 163 // "clear mwi flag" 164 165 pdu = "07912180958750F84401800500C07020027160112B06040102000000"; 166 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 167 168 assertTrue(sms.isMWIClearMessage()); 169 assertTrue(sms.isMwiDontStore()); 170 } 171 172 @SmallTest 173 public void testEmailGateway() throws Exception { 174 String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" + 175 "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3"; 176 177 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 178 179 assertEquals("+14155551212", sms.getServiceCenterAddress()); 180 assertTrue(sms.isEmail()); 181 assertEquals("foo (at) example.com", sms.getEmailFrom()); 182 assertEquals("foo (at) example.com", sms.getDisplayOriginatingAddress()); 183 // As of https://android-git.corp.google.com/g/#change,9324 184 // getPseudoSubject will always be empty, and any subject is not extracted. 185 assertEquals("", sms.getPseudoSubject()); 186 assertEquals("test subject /test body", sms.getDisplayMessageBody()); 187 assertEquals("test subject /test body", sms.getEmailBody()); 188 189 // email gateway sms test, including gsm extended character set. 190 pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" + 191 "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629"; 192 193 sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 194 195 assertEquals("+14155551212", sms.getServiceCenterAddress()); 196 assertTrue(sms.isEmail()); 197 assertEquals("foo (at) example.com", sms.getDisplayOriginatingAddress()); 198 assertEquals("foo (at) example.com", sms.getEmailFrom()); 199 assertEquals("{ testBody[^~\\] }", sms.getDisplayMessageBody()); 200 assertEquals("{ testBody[^~\\] }", sms.getEmailBody()); 201 } 202 203 @SmallTest 204 public void testExtendedCharacterTable() throws Exception { 205 String pdu = "07914151551512f2040B916105551511f100006080615131728A44D4F29C0E2" + 206 "AE3E96537B94C068DD16179784C2FCB41F4B0985D06B958ADD00FB0E94536AF9749" + 207 "74DA6D281BA00E95E26D509B946FC3DBF87A25D56A04"; 208 209 SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); 210 211 assertEquals("+14155551212", sms.getServiceCenterAddress()); 212 assertEquals("+16505551111", sms.getOriginatingAddress()); 213 assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#", 214 sms.getMessageBody()); 215 } 216 217 // GSM 7 bit tables in String form, Escape (0x1B) replaced with '@' 218 private static final String[] sBasicTables = { 219 // GSM 7 bit default alphabet 220 "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_" 221 + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u00c6\u00e6\u00df\u00c9" 222 + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6" 223 + "\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0", 224 225 // Turkish locking shift table 226 "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_" 227 + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u015e\u015f\u00df\u00c9" 228 + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6" 229 + "\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0", 230 231 // no locking shift table defined for Spanish 232 "", 233 234 // Portuguese locking shift table 235 "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_" 236 + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|@\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba%&'()" 237 + "*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc" 238 + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0" 239 }; 240 241 @SmallTest 242 public void testFragmentText() throws Exception { 243 boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == 244 TelephonyManager.PHONE_TYPE_GSM); 245 246 // Valid 160 character 7-bit text. 247 String text = "123456789012345678901234567890123456789012345678901234567890" + 248 "1234567890123456789012345678901234567890123456789012345678901234567890" + 249 "123456789012345678901234567890"; 250 GsmAlphabet.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); 251 assertEquals(1, ted.msgCount); 252 assertEquals(160, ted.codeUnitCount); 253 assertEquals(1, ted.codeUnitSize); 254 assertEquals(0, ted.languageTable); 255 assertEquals(0, ted.languageShiftTable); 256 if (isGsmPhone) { 257 ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 258 assertEquals(1, fragments.size()); 259 } 260 261 // Valid 161 character 7-bit text. 262 text = "123456789012345678901234567890123456789012345678901234567890" + 263 "1234567890123456789012345678901234567890123456789012345678901234567890" + 264 "1234567890123456789012345678901"; 265 ted = SmsMessage.calculateLength(text, false); 266 assertEquals(2, ted.msgCount); 267 assertEquals(161, ted.codeUnitCount); 268 assertEquals(1, ted.codeUnitSize); 269 assertEquals(0, ted.languageTable); 270 assertEquals(0, ted.languageShiftTable); 271 if (isGsmPhone) { 272 ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 273 assertEquals(2, fragments.size()); 274 assertEquals(text, fragments.get(0) + fragments.get(1)); 275 assertEquals(153, fragments.get(0).length()); 276 assertEquals(8, fragments.get(1).length()); 277 } 278 } 279 280 @SmallTest 281 public void testFragmentTurkishText() throws Exception { 282 boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == 283 TelephonyManager.PHONE_TYPE_GSM); 284 285 int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables(); 286 int[] turkishTable = { 1 }; 287 GsmAlphabet.setEnabledSingleShiftTables(turkishTable); 288 289 // Valid 77 character text with Turkish characters. 290 String text = "" + 291 ""; 292 GsmAlphabet.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); 293 assertEquals(1, ted.msgCount); 294 assertEquals(154, ted.codeUnitCount); 295 assertEquals(1, ted.codeUnitSize); 296 assertEquals(0, ted.languageTable); 297 assertEquals(1, ted.languageShiftTable); 298 if (isGsmPhone) { 299 ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 300 assertEquals(1, fragments.size()); 301 assertEquals(text, fragments.get(0)); 302 assertEquals(77, fragments.get(0).length()); 303 } 304 305 // Valid 78 character text with Turkish characters. 306 text = "" + 307 ""; 308 ted = SmsMessage.calculateLength(text, false); 309 assertEquals(2, ted.msgCount); 310 assertEquals(156, ted.codeUnitCount); 311 assertEquals(1, ted.codeUnitSize); 312 assertEquals(0, ted.languageTable); 313 assertEquals(1, ted.languageShiftTable); 314 if (isGsmPhone) { 315 ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 316 assertEquals(2, fragments.size()); 317 assertEquals(text, fragments.get(0) + fragments.get(1)); 318 assertEquals(74, fragments.get(0).length()); 319 assertEquals(4, fragments.get(1).length()); 320 } 321 322 // Valid 160 character text with Turkish characters. 323 text = "" + 324 "" + 325 ""; 326 ted = SmsMessage.calculateLength(text, false); 327 assertEquals(3, ted.msgCount); 328 assertEquals(320, ted.codeUnitCount); 329 assertEquals(1, ted.codeUnitSize); 330 assertEquals(0, ted.languageTable); 331 assertEquals(1, ted.languageShiftTable); 332 if (isGsmPhone) { 333 ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); 334 assertEquals(3, fragments.size()); 335 assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2)); 336 assertEquals(74, fragments.get(0).length()); 337 assertEquals(74, fragments.get(1).length()); 338 assertEquals(12, fragments.get(2).length()); 339 } 340 341 GsmAlphabet.setEnabledSingleShiftTables(oldTables); 342 } 343 344 345 @SmallTest 346 public void testDecode() throws Exception { 347 decodeSingle(0); // default table 348 decodeSingle(1); // Turkish locking shift table 349 decodeSingle(3); // Portuguese locking shift table 350 } 351 352 private void decodeSingle(int language) throws Exception { 353 byte[] septets = new byte[(7 * 128 + 7) / 8]; 354 355 int bitOffset = 0; 356 357 for (int i = 0; i < 128; i++) { 358 int v; 359 if (i == 0x1b) { 360 // extended escape char 361 v = 0; 362 } else { 363 v = i; 364 } 365 366 int byteOffset = bitOffset / 8; 367 int shift = bitOffset % 8; 368 369 septets[byteOffset] |= v << shift; 370 371 if (shift > 1) { 372 septets[byteOffset + 1] = (byte) (v >> (8 - shift)); 373 } 374 375 bitOffset += 7; 376 } 377 378 String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, 128, 0, language, 0); 379 byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, language, 0); 380 381 assertEquals(sBasicTables[language], decoded); 382 383 // reEncoded has the count septets byte at the front 384 assertEquals(septets.length + 1, reEncoded.length); 385 386 for (int i = 0; i < septets.length; i++) { 387 assertEquals(septets[i], reEncoded[i + 1]); 388 } 389 } 390 391 private static final int GSM_ESCAPE_CHARACTER = 0x1b; 392 393 private static final String[] sExtendedTables = { 394 // GSM 7 bit default alphabet extension table 395 "\f^{}\\[~]|\u20ac", 396 397 // Turkish single shift extension table 398 "\f^{}\\[~]|\u011e\u0130\u015e\u00e7\u20ac\u011f\u0131\u015f", 399 400 // Spanish single shift extension table 401 "\u00e7\f^{}\\[~]|\u00c1\u00cd\u00d3\u00da\u00e1\u20ac\u00ed\u00f3\u00fa", 402 403 // Portuguese single shift extension table 404 "\u00ea\u00e7\f\u00d4\u00f4\u00c1\u00e1\u03a6\u0393^\u03a9\u03a0\u03a8\u03a3\u0398\u00ca" 405 + "{}\\[~]|\u00c0\u00cd\u00d3\u00da\u00c3\u00d5\u00c2\u20ac\u00ed\u00f3\u00fa\u00e3" 406 + "\u00f5\u00e2" 407 }; 408 409 private static final int[][] sExtendedTableIndexes = { 410 {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x65}, 411 {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x47, 0x49, 0x53, 0x63, 412 0x65, 0x67, 0x69, 0x73}, 413 {0x09, 0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 0x4f, 414 0x55, 0x61, 0x65, 0x69, 0x6f, 0x75}, 415 {0x05, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 416 0x18, 0x19, 0x1f, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 417 0x4f, 0x55, 0x5b, 0x5c, 0x61, 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x7c, 0x7f} 418 }; 419 420 @SmallTest 421 public void testDecodeExtended() throws Exception { 422 for (int language = 0; language < 3; language++) { 423 int[] tableIndex = sExtendedTableIndexes[language]; 424 int numSeptets = tableIndex.length * 2; // two septets per extended char 425 byte[] septets = new byte[(7 * numSeptets + 7) / 8]; 426 427 int bitOffset = 0; 428 429 for (int v : tableIndex) { 430 // escape character 431 int byteOffset = bitOffset / 8; 432 int shift = bitOffset % 8; 433 434 septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift; 435 436 if (shift > 1) { 437 septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift)); 438 } 439 440 bitOffset += 7; 441 442 // extended table index 443 byteOffset = bitOffset / 8; 444 shift = bitOffset % 8; 445 446 septets[byteOffset] |= v << shift; 447 448 if (shift > 1) { 449 septets[byteOffset + 1] = (byte) (v >> (8 - shift)); 450 } 451 452 bitOffset += 7; 453 } 454 455 String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 456 0, language); 457 byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, 0, language); 458 459 assertEquals(sExtendedTables[language], decoded); 460 461 // reEncoded has the count septets byte at the front 462 assertEquals(septets.length + 1, reEncoded.length); 463 464 for (int i = 0; i < septets.length; i++) { 465 assertEquals(septets[i], reEncoded[i + 1]); 466 } 467 } 468 } 469 470 @SmallTest 471 public void testDecodeExtendedFallback() throws Exception { 472 // verify that unmapped characters in extension table fall back to locking shift table 473 for (int language = 0; language < 3; language++) { 474 int[] tableIndex = sExtendedTableIndexes[language]; 475 int numChars = 128 - tableIndex.length; 476 int numSeptets = numChars * 2; // two septets per extended char 477 byte[] septets = new byte[(7 * numSeptets + 7) / 8]; 478 479 int tableOffset = 0; 480 int bitOffset = 0; 481 482 StringBuilder defaultTable = new StringBuilder(128); 483 StringBuilder turkishTable = new StringBuilder(128); 484 StringBuilder portugueseTable = new StringBuilder(128); 485 486 for (char c = 0; c < 128; c++) { 487 // skip characters that are present in the current extension table 488 if (tableOffset < tableIndex.length && tableIndex[tableOffset] == c) { 489 tableOffset++; 490 continue; 491 } 492 493 // escape character 494 int byteOffset = bitOffset / 8; 495 int shift = bitOffset % 8; 496 497 septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift; 498 499 if (shift > 1) { 500 septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift)); 501 } 502 503 bitOffset += 7; 504 505 // extended table index 506 byteOffset = bitOffset / 8; 507 shift = bitOffset % 8; 508 509 septets[byteOffset] |= c << shift; 510 511 if (shift > 1) { 512 septets[byteOffset + 1] = (byte) (c >> (8 - shift)); 513 } 514 515 bitOffset += 7; 516 517 if (c == GsmAlphabet.GSM_EXTENDED_ESCAPE) { 518 // double Escape maps to space character 519 defaultTable.append(' '); 520 turkishTable.append(' '); 521 portugueseTable.append(' '); 522 } else { 523 // other unmapped chars map to the default or locking shift table 524 defaultTable.append(sBasicTables[0].charAt(c)); 525 turkishTable.append(sBasicTables[1].charAt(c)); 526 portugueseTable.append(sBasicTables[3].charAt(c)); 527 } 528 } 529 530 String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 531 0, language); 532 533 assertEquals(defaultTable.toString(), decoded); 534 535 decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 1, language); 536 assertEquals(turkishTable.toString(), decoded); 537 538 decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 3, language); 539 assertEquals(portugueseTable.toString(), decoded); 540 } 541 } 542 } 543