Loading telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +128 −1 Original line number Diff line number Diff line Loading @@ -919,6 +919,122 @@ public final class BearerData { } } /** * IS-91 Voice Mail message decoding * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) * (For character encodings, see TIA/EIA/IS-91, Annex B) * * Protocol Summary: The user data payload may contain 3-14 * characters. The first two characters are parsed as a number * and indicate the number of voicemails. The third character is * either a SPACE or '!' to indicate normal or urgent priority, * respectively. Any following characters are treated as normal * text user data payload. * * Note that the characters encoding is 6-bit packed. */ private static void decodeIs91VoicemailStatus(BearerData bData) throws BitwiseInputStream.AccessException, CodingException { BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); int dataLen = inStream.available() / 6; // 6-bit packed character encoding. int numFields = bData.userData.numFields; if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) { throw new CodingException("IS-91 voicemail status decoding failed"); } try { StringBuffer strbuf = new StringBuffer(dataLen); while (inStream.available() >= 6) { strbuf.append(UserData.IA5_MAP[inStream.read(6)]); } String data = strbuf.toString(); bData.numberOfMessages = Integer.parseInt(data.substring(0, 2)); char prioCode = data.charAt(2); if (prioCode == ' ') { bData.priority = PRIORITY_NORMAL; } else if (prioCode == '!') { bData.priority = PRIORITY_URGENT; } else { throw new CodingException("IS-91 voicemail status decoding failed: " + "illegal priority setting (" + prioCode + ")"); } bData.priorityIndicatorSet = true; bData.userData.payloadStr = data.substring(3, numFields - 3); } catch (java.lang.NumberFormatException ex) { throw new CodingException("IS-91 voicemail status decoding failed: " + ex); } catch (java.lang.IndexOutOfBoundsException ex) { throw new CodingException("IS-91 voicemail status decoding failed: " + ex); } } /** * IS-91 Short Message decoding * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) * (For character encodings, see TIA/EIA/IS-91, Annex B) * * Protocol Summary: The user data payload may contain 1-14 * characters, which are treated as normal text user data payload. * Note that the characters encoding is 6-bit packed. */ private static void decodeIs91ShortMessage(BearerData bData) throws BitwiseInputStream.AccessException, CodingException { BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); int dataLen = inStream.available() / 6; // 6-bit packed character encoding. int numFields = bData.userData.numFields; if ((dataLen > 14) || (dataLen < numFields)) { throw new CodingException("IS-91 voicemail status decoding failed"); } StringBuffer strbuf = new StringBuffer(dataLen); for (int i = 0; i < numFields; i++) { strbuf.append(UserData.IA5_MAP[inStream.read(6)]); } bData.userData.payloadStr = strbuf.toString(); } /** * IS-91 CLI message (callback number) decoding * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) * * Protocol Summary: The data payload may contain 1-32 digits, * encoded using standard 4-bit DTMF, which are treated as a * callback number. */ private static void decodeIs91Cli(BearerData bData) throws CodingException { BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); int dataLen = inStream.available() / 4; // 4-bit packed DTMF digit encoding. int numFields = bData.userData.numFields; if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) { throw new CodingException("IS-91 voicemail status decoding failed"); } CdmaSmsAddress addr = new CdmaSmsAddress(); addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF; addr.origBytes = bData.userData.payload; addr.numberOfDigits = (byte)numFields; decodeSmsAddress(addr); bData.callbackNumber = addr; } private static void decodeIs91(BearerData bData) throws BitwiseInputStream.AccessException, CodingException { switch (bData.userData.msgType) { case UserData.IS91_MSG_TYPE_VOICEMAIL_STATUS: decodeIs91VoicemailStatus(bData); break; case UserData.IS91_MSG_TYPE_CLI: decodeIs91Cli(bData); break; case UserData.IS91_MSG_TYPE_SHORT_MESSAGE_FULL: case UserData.IS91_MSG_TYPE_SHORT_MESSAGE: decodeIs91ShortMessage(bData); break; default: throw new CodingException("unsupported IS-91 message type (" + bData.userData.msgType + ")"); } } private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream) throws BitwiseInputStream.AccessException, CodingException { Loading Loading @@ -1219,8 +1335,19 @@ public final class BearerData { throw new CodingException("missing MESSAGE_IDENTIFIER subparam"); } if (bData.userData != null) { if (bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) { if ((foundSubparamMask ^ (1 << SUBPARAM_MESSAGE_IDENTIFIER) ^ (1 << SUBPARAM_USER_DATA)) != 0) { Log.e(LOG_TAG, "IS-91 must occur without extra subparams (" + foundSubparamMask + ")"); } decodeIs91(bData); } else { decodeUserDataPayload(bData.userData, bData.hasUserDataHeader); } } return bData; } catch (BitwiseInputStream.AccessException ex) { Log.e(LOG_TAG, "BearerData decode failed: " + ex); Loading telephony/java/com/android/internal/telephony/cdma/sms/UserData.java +14 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,15 @@ public class UserData { public static final int ENCODING_GSM_7BIT_ALPHABET = 0x09; public static final int ENCODING_GSM_DCS = 0x0A; /** * IS-91 message types. * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3) */ public static final int IS91_MSG_TYPE_VOICEMAIL_STATUS = 0x82; public static final int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83; public static final int IS91_MSG_TYPE_CLI = 0x84; public static final int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85; /** * IA5 data encoding character mappings. * (See CCITT Rec. T.50 Tables 1 and 3) Loading @@ -46,6 +55,11 @@ public class UserData { * Note this mapping is the the same as for printable ASCII * characters, with a 0x20 offset, meaning that the ASCII SPACE * character occurs with code 0x20. * * Note this mapping is also equivalent to that used by the IS-91 * protocol, except for the latter using only 6 bits, and hence * mapping only entries up to the '_' character. * */ public static final char[] IA5_MAP = { ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', Loading Loading @@ -96,7 +110,6 @@ public class UserData { public int msgEncoding; public boolean msgEncodingSet = false; // XXX needed when encoding is IS91 or DCS (not supported yet): public int msgType; /** Loading tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.test.suitebuilder.annotation.SmallTest; import java.util.Iterator; import java.lang.Integer; import android.util.Log; public class CdmaSmsTest extends AndroidTestCase { Loading Loading @@ -679,4 +681,15 @@ public class CdmaSmsTest extends AndroidTestCase { assertEquals(revBearerData.displayModeSet, true); assertEquals(revBearerData.displayMode, bearerData.displayMode); } @SmallTest public void testIs91() throws Exception { String pdu1 = "000320001001070c2039acc13880"; BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); assertEquals(bd1.callbackNumber.address, "3598271"); String pdu4 = "000320001001080c283c314724b34e"; BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); assertEquals(bd4.userData.payloadStr, "ABCDEFG"); } } Loading
telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +128 −1 Original line number Diff line number Diff line Loading @@ -919,6 +919,122 @@ public final class BearerData { } } /** * IS-91 Voice Mail message decoding * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) * (For character encodings, see TIA/EIA/IS-91, Annex B) * * Protocol Summary: The user data payload may contain 3-14 * characters. The first two characters are parsed as a number * and indicate the number of voicemails. The third character is * either a SPACE or '!' to indicate normal or urgent priority, * respectively. Any following characters are treated as normal * text user data payload. * * Note that the characters encoding is 6-bit packed. */ private static void decodeIs91VoicemailStatus(BearerData bData) throws BitwiseInputStream.AccessException, CodingException { BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); int dataLen = inStream.available() / 6; // 6-bit packed character encoding. int numFields = bData.userData.numFields; if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) { throw new CodingException("IS-91 voicemail status decoding failed"); } try { StringBuffer strbuf = new StringBuffer(dataLen); while (inStream.available() >= 6) { strbuf.append(UserData.IA5_MAP[inStream.read(6)]); } String data = strbuf.toString(); bData.numberOfMessages = Integer.parseInt(data.substring(0, 2)); char prioCode = data.charAt(2); if (prioCode == ' ') { bData.priority = PRIORITY_NORMAL; } else if (prioCode == '!') { bData.priority = PRIORITY_URGENT; } else { throw new CodingException("IS-91 voicemail status decoding failed: " + "illegal priority setting (" + prioCode + ")"); } bData.priorityIndicatorSet = true; bData.userData.payloadStr = data.substring(3, numFields - 3); } catch (java.lang.NumberFormatException ex) { throw new CodingException("IS-91 voicemail status decoding failed: " + ex); } catch (java.lang.IndexOutOfBoundsException ex) { throw new CodingException("IS-91 voicemail status decoding failed: " + ex); } } /** * IS-91 Short Message decoding * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) * (For character encodings, see TIA/EIA/IS-91, Annex B) * * Protocol Summary: The user data payload may contain 1-14 * characters, which are treated as normal text user data payload. * Note that the characters encoding is 6-bit packed. */ private static void decodeIs91ShortMessage(BearerData bData) throws BitwiseInputStream.AccessException, CodingException { BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); int dataLen = inStream.available() / 6; // 6-bit packed character encoding. int numFields = bData.userData.numFields; if ((dataLen > 14) || (dataLen < numFields)) { throw new CodingException("IS-91 voicemail status decoding failed"); } StringBuffer strbuf = new StringBuffer(dataLen); for (int i = 0; i < numFields; i++) { strbuf.append(UserData.IA5_MAP[inStream.read(6)]); } bData.userData.payloadStr = strbuf.toString(); } /** * IS-91 CLI message (callback number) decoding * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) * * Protocol Summary: The data payload may contain 1-32 digits, * encoded using standard 4-bit DTMF, which are treated as a * callback number. */ private static void decodeIs91Cli(BearerData bData) throws CodingException { BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); int dataLen = inStream.available() / 4; // 4-bit packed DTMF digit encoding. int numFields = bData.userData.numFields; if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) { throw new CodingException("IS-91 voicemail status decoding failed"); } CdmaSmsAddress addr = new CdmaSmsAddress(); addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF; addr.origBytes = bData.userData.payload; addr.numberOfDigits = (byte)numFields; decodeSmsAddress(addr); bData.callbackNumber = addr; } private static void decodeIs91(BearerData bData) throws BitwiseInputStream.AccessException, CodingException { switch (bData.userData.msgType) { case UserData.IS91_MSG_TYPE_VOICEMAIL_STATUS: decodeIs91VoicemailStatus(bData); break; case UserData.IS91_MSG_TYPE_CLI: decodeIs91Cli(bData); break; case UserData.IS91_MSG_TYPE_SHORT_MESSAGE_FULL: case UserData.IS91_MSG_TYPE_SHORT_MESSAGE: decodeIs91ShortMessage(bData); break; default: throw new CodingException("unsupported IS-91 message type (" + bData.userData.msgType + ")"); } } private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream) throws BitwiseInputStream.AccessException, CodingException { Loading Loading @@ -1219,8 +1335,19 @@ public final class BearerData { throw new CodingException("missing MESSAGE_IDENTIFIER subparam"); } if (bData.userData != null) { if (bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) { if ((foundSubparamMask ^ (1 << SUBPARAM_MESSAGE_IDENTIFIER) ^ (1 << SUBPARAM_USER_DATA)) != 0) { Log.e(LOG_TAG, "IS-91 must occur without extra subparams (" + foundSubparamMask + ")"); } decodeIs91(bData); } else { decodeUserDataPayload(bData.userData, bData.hasUserDataHeader); } } return bData; } catch (BitwiseInputStream.AccessException ex) { Log.e(LOG_TAG, "BearerData decode failed: " + ex); Loading
telephony/java/com/android/internal/telephony/cdma/sms/UserData.java +14 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,15 @@ public class UserData { public static final int ENCODING_GSM_7BIT_ALPHABET = 0x09; public static final int ENCODING_GSM_DCS = 0x0A; /** * IS-91 message types. * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3) */ public static final int IS91_MSG_TYPE_VOICEMAIL_STATUS = 0x82; public static final int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83; public static final int IS91_MSG_TYPE_CLI = 0x84; public static final int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85; /** * IA5 data encoding character mappings. * (See CCITT Rec. T.50 Tables 1 and 3) Loading @@ -46,6 +55,11 @@ public class UserData { * Note this mapping is the the same as for printable ASCII * characters, with a 0x20 offset, meaning that the ASCII SPACE * character occurs with code 0x20. * * Note this mapping is also equivalent to that used by the IS-91 * protocol, except for the latter using only 6 bits, and hence * mapping only entries up to the '_' character. * */ public static final char[] IA5_MAP = { ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', Loading Loading @@ -96,7 +110,6 @@ public class UserData { public int msgEncoding; public boolean msgEncodingSet = false; // XXX needed when encoding is IS91 or DCS (not supported yet): public int msgType; /** Loading
tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.test.suitebuilder.annotation.SmallTest; import java.util.Iterator; import java.lang.Integer; import android.util.Log; public class CdmaSmsTest extends AndroidTestCase { Loading Loading @@ -679,4 +681,15 @@ public class CdmaSmsTest extends AndroidTestCase { assertEquals(revBearerData.displayModeSet, true); assertEquals(revBearerData.displayMode, bearerData.displayMode); } @SmallTest public void testIs91() throws Exception { String pdu1 = "000320001001070c2039acc13880"; BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); assertEquals(bd1.callbackNumber.address, "3598271"); String pdu4 = "000320001001080c283c314724b34e"; BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); assertEquals(bd4.userData.payloadStr, "ABCDEFG"); } }