Skip to content

Commit ee7d197

Browse files
author
Rekha Kumar
committed
Telephony: Add support to read 3GPP2 sms from CSIM/RUIM
Add parser to parse 3GPP2 format sms stored in CSIM/RUIM card Change-Id: I4720ba7602fcc1b078de0d5fea34247541242c1c
1 parent c1c45a4 commit ee7d197

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

telephony/java/com/android/internal/telephony/cdma/SmsMessage.java

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
3333
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
3434
import com.android.internal.telephony.cdma.sms.UserData;
35+
import com.android.internal.util.BitwiseInputStream;
3536
import com.android.internal.util.HexDump;
3637

3738
import java.io.BufferedInputStream;
@@ -72,6 +73,16 @@ public class SmsMessage extends SmsMessageBase {
7273
static final String LOG_TAG = "CDMA";
7374
static private final String LOGGABLE_TAG = "CDMA:SMS";
7475

76+
private final static byte TELESERVICE_IDENTIFIER = 0x00;
77+
private final static byte SERVICE_CATEGORY = 0x01;
78+
private final static byte ORIGINATING_ADDRESS = 0x02;
79+
private final static byte ORIGINATING_SUB_ADDRESS = 0x03;
80+
private final static byte DESTINATION_ADDRESS = 0x04;
81+
private final static byte DESTINATION_SUB_ADDRESS = 0x05;
82+
private final static byte BEARER_REPLY_OPTION = 0x06;
83+
private final static byte CAUSE_CODES = 0x07;
84+
private final static byte BEARER_DATA = 0x08;
85+
7586
/**
7687
* Status of a previously submitted SMS.
7788
* This field applies to SMS Delivery Acknowledge messages. 0 indicates success;
@@ -267,6 +278,7 @@ public static SmsMessage createFromEfRecord(int index, byte[] data) {
267278
System.arraycopy(data, 2, pdu, 0, size);
268279
// the message has to be parsed before it can be displayed
269280
// see gsm.SmsMessage
281+
msg.parsePduFromEfRecord(pdu);
270282
return msg;
271283
} catch (RuntimeException ex) {
272284
Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
@@ -538,6 +550,143 @@ private void parsePdu(byte[] pdu) {
538550
parseSms();
539551
}
540552

553+
/**
554+
* Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0
555+
*/
556+
private void parsePduFromEfRecord(byte[] pdu) {
557+
ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
558+
DataInputStream dis = new DataInputStream(bais);
559+
SmsEnvelope env = new SmsEnvelope();
560+
CdmaSmsAddress addr = new CdmaSmsAddress();
561+
CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress();
562+
563+
try {
564+
env.messageType = dis.readByte();
565+
566+
while (dis.available() > 0) {
567+
int parameterId = dis.readByte();
568+
int parameterLen = dis.readByte();
569+
byte[] parameterData = new byte[parameterLen];
570+
571+
switch (parameterId) {
572+
case TELESERVICE_IDENTIFIER:
573+
/*
574+
* 16 bit parameter that identifies which upper layer
575+
* service access point is sending or should receive
576+
* this message
577+
*/
578+
env.teleService = dis.readUnsignedShort();
579+
Log.i(LOG_TAG, "teleservice = " + env.teleService);
580+
break;
581+
case SERVICE_CATEGORY:
582+
/*
583+
* 16 bit parameter that identifies type of service as
584+
* in 3GPP2 C.S0015-0 Table 3.4.3.2-1
585+
*/
586+
env.serviceCategory = dis.readUnsignedShort();
587+
break;
588+
case ORIGINATING_ADDRESS:
589+
case DESTINATION_ADDRESS:
590+
dis.read(parameterData, 0, parameterLen);
591+
BitwiseInputStream addrBis = new BitwiseInputStream(parameterData);
592+
addr.digitMode = addrBis.read(1);
593+
addr.numberMode = addrBis.read(1);
594+
int numberType = 0;
595+
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
596+
numberType = addrBis.read(3);
597+
addr.ton = numberType;
598+
599+
if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK)
600+
addr.numberPlan = addrBis.read(4);
601+
}
602+
603+
addr.numberOfDigits = addrBis.read(8);
604+
605+
byte[] data = new byte[addr.numberOfDigits];
606+
byte b = 0x00;
607+
608+
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
609+
/* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */
610+
for (int index = 0; index < addr.numberOfDigits; index++) {
611+
b = (byte) (0xF & addrBis.read(4));
612+
// convert the value if it is 4-bit DTMF to 8
613+
// bit
614+
data[index] = convertDtmfToAscii(b);
615+
}
616+
} else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
617+
if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) {
618+
for (int index = 0; index < addr.numberOfDigits; index++) {
619+
b = (byte) (0xFF & addrBis.read(8));
620+
data[index] = b;
621+
}
622+
623+
} else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) {
624+
if (numberType == 2)
625+
Log.e(LOG_TAG, "TODO: Originating Addr is email id");
626+
else
627+
Log.e(LOG_TAG,
628+
"TODO: Originating Addr is data network address");
629+
} else {
630+
Log.e(LOG_TAG, "Originating Addr is of incorrect type");
631+
}
632+
} else {
633+
Log.e(LOG_TAG, "Incorrect Digit mode");
634+
}
635+
addr.origBytes = data;
636+
Log.i(LOG_TAG, "Originating Addr=" + addr.toString());
637+
break;
638+
case ORIGINATING_SUB_ADDRESS:
639+
case DESTINATION_SUB_ADDRESS:
640+
dis.read(parameterData, 0, parameterLen);
641+
BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData);
642+
subAddr.type = subAddrBis.read(3);
643+
subAddr.odd = subAddrBis.readByteArray(1)[0];
644+
int subAddrLen = subAddrBis.read(8);
645+
byte[] subdata = new byte[subAddrLen];
646+
for (int index = 0; index < subAddrLen; index++) {
647+
b = (byte) (0xFF & subAddrBis.read(4));
648+
// convert the value if it is 4-bit DTMF to 8 bit
649+
subdata[index] = convertDtmfToAscii(b);
650+
}
651+
subAddr.origBytes = subdata;
652+
break;
653+
case BEARER_REPLY_OPTION:
654+
dis.read(parameterData, 0, parameterLen);
655+
BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData);
656+
env.bearerReply = replyOptBis.read(6);
657+
break;
658+
case CAUSE_CODES:
659+
dis.read(parameterData, 0, parameterLen);
660+
BitwiseInputStream ccBis = new BitwiseInputStream(parameterData);
661+
env.replySeqNo = ccBis.readByteArray(6)[0];
662+
env.errorClass = ccBis.readByteArray(2)[0];
663+
if (env.errorClass != 0x00)
664+
env.causeCode = ccBis.readByteArray(8)[0];
665+
break;
666+
case BEARER_DATA:
667+
dis.read(parameterData, 0, parameterLen);
668+
env.bearerData = parameterData;
669+
break;
670+
default:
671+
throw new Exception("unsupported parameterId (" + parameterId + ")");
672+
}
673+
}
674+
bais.close();
675+
dis.close();
676+
} catch (Exception ex) {
677+
Log.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex);
678+
}
679+
680+
// link the filled objects to this SMS
681+
originatingAddress = addr;
682+
env.origAddress = addr;
683+
env.origSubaddress = subAddr;
684+
mEnvelope = env;
685+
mPdu = pdu;
686+
687+
parseSms();
688+
}
689+
541690
/**
542691
* Parses a SMS message from its BearerData stream. (mobile-terminated only)
543692
*/

0 commit comments

Comments
 (0)