1 /*
2  * Copyright (C) 2013 Samsung System LSI
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 package com.android.bluetooth.map;
16 
17 import android.util.Log;
18 
19 import com.android.bluetooth.DeviceWorkArounds;
20 import com.android.bluetooth.map.BluetoothMapSmsPdu.SmsPdu;
21 import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
22 
23 import java.io.UnsupportedEncodingException;
24 import java.util.ArrayList;
25 
26 public class BluetoothMapbMessageSms extends BluetoothMapbMessage {
27 
28     private ArrayList<SmsPdu> mSmsBodyPdus = null;
29     private String mSmsBody = null;
30 
setSmsBodyPdus(ArrayList<SmsPdu> smsBodyPdus)31     public void setSmsBodyPdus(ArrayList<SmsPdu> smsBodyPdus) {
32         this.mSmsBodyPdus = smsBodyPdus;
33         this.mCharset = null;
34         if (smsBodyPdus.size() > 0) {
35             this.mEncoding = smsBodyPdus.get(0).getEncodingString();
36         }
37     }
38 
getSmsBody()39     public String getSmsBody() {
40         return mSmsBody;
41     }
42 
setSmsBody(String smsBody)43     public void setSmsBody(String smsBody) {
44         this.mSmsBody = smsBody;
45         this.mCharset = "UTF-8";
46         this.mEncoding = null;
47     }
48 
49     @Override
parseMsgPart(String msgPart)50     public void parseMsgPart(String msgPart) {
51         if (mAppParamCharset == BluetoothMapAppParams.CHARSET_NATIVE) {
52             Log.d(TAG, "Decoding \"" + msgPart + "\" as native PDU");
53             byte[] msgBytes = decodeBinary(msgPart);
54             if (msgBytes.length > 0
55                     && msgBytes[0] < msgBytes.length - 1
56                     && (msgBytes[msgBytes[0] + 1] & 0x03) != 0x01) {
57                 Log.d(TAG, "Only submit PDUs are supported");
58                 throw new IllegalArgumentException("Only submit PDUs are supported");
59             }
60 
61             mSmsBody +=
62                     BluetoothMapSmsPdu.decodePdu(
63                             msgBytes,
64                             mType == TYPE.SMS_CDMA
65                                     ? BluetoothMapSmsPdu.SMS_TYPE_CDMA
66                                     : BluetoothMapSmsPdu.SMS_TYPE_GSM);
67         } else {
68             mSmsBody += msgPart;
69         }
70     }
71 
72     @Override
parseMsgInit()73     public void parseMsgInit() {
74         mSmsBody = "";
75     }
76 
77     @Override
encode()78     public byte[] encode() throws UnsupportedEncodingException {
79         ArrayList<byte[]> bodyFragments = new ArrayList<byte[]>();
80 
81         /* Store the messages in an ArrayList to be able to handle the different message types in
82         a generic way.
83         * We use byte[] since we need to extract the length in bytes.
84         */
85         if (mSmsBody != null) {
86             String tmpBody =
87                     mSmsBody.replaceAll(
88                             "END:MSG",
89                             "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG
90             String remoteAddress = BluetoothMapService.getRemoteDevice().getAddress();
91             /* Fix IOT issue with PCM carkit where carkit is unable to parse
92             message if carriage return is present in it */
93             if (DeviceWorkArounds.addressStartsWith(remoteAddress, DeviceWorkArounds.PCM_CARKIT)) {
94                 tmpBody = tmpBody.replaceAll("\r", "");
95                 /* Fix Message Display issue with FORD SYNC carkit -
96                  * Remove line feed and include only carriage return */
97             } else if (DeviceWorkArounds.addressStartsWith(
98                     remoteAddress, DeviceWorkArounds.FORD_SYNC_CARKIT)) {
99                 tmpBody = tmpBody.replaceAll("\n", "");
100                 /* Fix IOT issue with SYNC carkit to remove trailing line feeds in the message body
101                  */
102             } else if (DeviceWorkArounds.addressStartsWith(
103                             remoteAddress, DeviceWorkArounds.SYNC_CARKIT)
104                     && tmpBody.length() > 0) {
105                 int trailingLF = 0;
106                 while ((tmpBody.charAt(tmpBody.length() - trailingLF - 1)) == '\n') trailingLF++;
107                 tmpBody = tmpBody.substring(0, (tmpBody.length() - trailingLF));
108             }
109             bodyFragments.add(tmpBody.getBytes("UTF-8"));
110         } else if (mSmsBodyPdus != null && mSmsBodyPdus.size() > 0) {
111             for (SmsPdu pdu : mSmsBodyPdus) {
112                 // This cannot(must not) contain END:MSG
113                 bodyFragments.add(
114                         encodeBinary(pdu.getData(), pdu.getScAddress()).getBytes("UTF-8"));
115             }
116         } else {
117             bodyFragments.add(new byte[0]); // An empty message - no text
118         }
119 
120         return encodeGeneric(bodyFragments);
121     }
122 }
123