1f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold/*
2f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * Copyright (C) 2008 The Android Open Source Project
3f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold *
4f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * Licensed under the Apache License, Version 2.0 (the "License");
5f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * you may not use this file except in compliance with the License.
6f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * You may obtain a copy of the License at
7f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold *
8f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold *      http://www.apache.org/licenses/LICENSE-2.0
9f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold *
10f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * Unless required by applicable law or agreed to in writing, software
11f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * distributed under the License is distributed on an "AS IS" BASIS,
12f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * See the License for the specific language governing permissions and
14f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * limitations under the License.
15f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold */
16f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
17f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldpackage com.android.internal.telephony.cdma;
18f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
19f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.hardware.radio.V1_0.CdmaSmsMessage;
20f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.os.Parcel;
21f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.os.SystemProperties;
22f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.telephony.PhoneNumberUtils;
23f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.telephony.SmsCbLocation;
24f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.telephony.SmsCbMessage;
25f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.telephony.TelephonyManager;
26f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.telephony.cdma.CdmaSmsCbProgramData;
27f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.telephony.Rlog;
28f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.util.Log;
29f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.text.TextUtils;
30f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport android.content.res.Resources;
31f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
32f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
33f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.SmsConstants;
34f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.SmsHeader;
35f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.SmsMessageBase;
36f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.TelephonyProperties;
37f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.cdma.sms.BearerData;
38f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
39f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
40f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.cdma.sms.SmsEnvelope;
41f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.cdma.sms.UserData;
42f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.uicc.IccUtils;
43f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.util.BitwiseInputStream;
44f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.util.HexDump;
45f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport com.android.internal.telephony.Sms7BitEncodingTranslator;
46f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
47f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.io.BufferedOutputStream;
48f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.io.ByteArrayInputStream;
49f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.io.ByteArrayOutputStream;
50f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.io.DataInputStream;
51f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.io.DataOutputStream;
52f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.io.IOException;
53f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldimport java.util.ArrayList;
54f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
55f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold/**
56f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold * A Factory class to convert from RIL to Framework SMS
57f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold *
58f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold */
59f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Haroldpublic class SmsMessageConverter {
60f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    static final String LOG_TAG = "SmsMessageConverter";
61f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    static private final String LOGGABLE_TAG = "CDMA:SMS";
62f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    private static final boolean VDBG = false;
63f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
64f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    /**
65f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold     *  Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp.
66f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold     *  Note: Only primitive fields are set.
67f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold     */
68f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    public static SmsMessage newCdmaSmsMessageFromRil(
69f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            CdmaSmsMessage cdmaSmsMessage) {
70f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        // Note: Parcel.readByte actually reads one Int and masks to byte
71f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        SmsEnvelope env = new SmsEnvelope();
72f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        CdmaSmsAddress addr = new CdmaSmsAddress();
73f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
74f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        byte[] data;
75f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        byte count;
76f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        int countInt;
77f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        int addressDigitMode;
78f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
79f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        //currently not supported by the modem-lib: env.mMessageType
80f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        env.teleService = cdmaSmsMessage.teleserviceId;
81f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
82f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        if (cdmaSmsMessage.isServicePresent) {
83f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
84f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
85f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        else {
86f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
87f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold                // assume type ACK
88f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold                env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
89f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            } else {
90f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold                env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
91f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            }
92f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
93f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        env.serviceCategory = cdmaSmsMessage.serviceCategory;
94f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
95f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        // address
96f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addressDigitMode = cdmaSmsMessage.address.digitMode;
97f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addr.digitMode = (byte) (0xFF & addressDigitMode);
98f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addr.numberMode = (byte) (0xFF & cdmaSmsMessage.address.numberMode);
99f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addr.ton = cdmaSmsMessage.address.numberType;
100f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addr.numberPlan = (byte) (0xFF & cdmaSmsMessage.address.numberPlan);
101f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        count = (byte) cdmaSmsMessage.address.digits.size();
102f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addr.numberOfDigits = count;
103f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        data = new byte[count];
104f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        for (int index=0; index < count; index++) {
105f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            data[index] = cdmaSmsMessage.address.digits.get(index);
106f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
107f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            // convert the value if it is 4-bit DTMF to 8 bit
108f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
109f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold                data[index] = SmsMessage.convertDtmfToAscii(data[index]);
110f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            }
111f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
112f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
113f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        addr.origBytes = data;
114f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
115f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        subaddr.type = cdmaSmsMessage.subAddress.subaddressType;
116f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        subaddr.odd = (byte) (cdmaSmsMessage.subAddress.odd ? 1 : 0);
117f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        count = (byte) cdmaSmsMessage.subAddress.digits.size();
118f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
119f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        if (count < 0) {
120f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            count = 0;
121f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
122f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
123f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        // p_cur->sSubAddress.digits[digitCount] :
124f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
125f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        data = new byte[count];
126f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
127f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        for (int index = 0; index < count; ++index) {
128f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            data[index] = cdmaSmsMessage.subAddress.digits.get(index);
129f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
130f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
131f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        subaddr.origBytes = data;
132f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
133f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        /* currently not supported by the modem-lib:
134f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            env.bearerReply
135f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            env.replySeqNo
136f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            env.errorClass
137f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            env.causeCode
138f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        */
139f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
140f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        // bearer data
141f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        countInt = cdmaSmsMessage.bearerData.size();
142f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        if (countInt < 0) {
143f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            countInt = 0;
144f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
145f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
146f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        data = new byte[countInt];
147f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        for (int index=0; index < countInt; index++) {
148f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            data[index] = cdmaSmsMessage.bearerData.get(index);
149f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        }
150f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        // BD gets further decoded when accessed in SMSDispatcher
151f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        env.bearerData = data;
152f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
153f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        // link the the filled objects to the SMS
154f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        env.origAddress = addr;
155f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        env.origSubaddress = subaddr;
156f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
157f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        SmsMessage msg = new SmsMessage(addr, env);
158f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
159f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        return msg;
160f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    }
161f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold
162f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    public static android.telephony.SmsMessage newSmsMessageFromCdmaSmsMessage(
163f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold            CdmaSmsMessage msg) {
164f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold        return new android.telephony.SmsMessage((SmsMessageBase)newCdmaSmsMessageFromRil(msg));
165f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold    }
166f7dc5ac00bf6b0a82ba7ba5711d394191392eb15Nathan Harold}
167