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             if (D) {
53                 Log.d(TAG, "Decoding \"" + msgPart + "\" as native PDU");
54             }
55             byte[] msgBytes = decodeBinary(msgPart);
56             if (msgBytes.length > 0 && msgBytes[0] < msgBytes.length - 1
57                     && (msgBytes[msgBytes[0] + 1] & 0x03) != 0x01) {
58                 if (D) {
59                     Log.d(TAG, "Only submit PDUs are supported");
60                 }
61                 throw new IllegalArgumentException("Only submit PDUs are supported");
62             }
63 
64             mSmsBody += BluetoothMapSmsPdu.decodePdu(msgBytes,
65                     mType == TYPE.SMS_CDMA ? 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 = mSmsBody.replaceAll("END:MSG",
87                     "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG
88             String remoteAddress = BluetoothMapService.getRemoteDevice().getAddress();
89             /* Fix IOT issue with PCM carkit where carkit is unable to parse
90                message if carriage return is present in it */
91             if (DeviceWorkArounds.addressStartsWith(remoteAddress, DeviceWorkArounds.PCM_CARKIT)) {
92                 tmpBody = tmpBody.replaceAll("\r", "");
93                 /* Fix Message Display issue with FORD SYNC carkit -
94                  * Remove line feed and include only carriage return */
95             } else if (DeviceWorkArounds.addressStartsWith(
96                                remoteAddress, DeviceWorkArounds.FORD_SYNC_CARKIT)) {
97                 tmpBody = tmpBody.replaceAll("\n", "");
98                 /* Fix IOT issue with SYNC carkit to remove trailing line feeds in the message body
99                  */
100             } else if (DeviceWorkArounds.addressStartsWith(
101                                remoteAddress, DeviceWorkArounds.SYNC_CARKIT)
102                     && tmpBody.length() > 0) {
103                 int trailingLF = 0;
104                 while ((tmpBody.charAt(tmpBody.length() - trailingLF - 1)) == '\n') trailingLF++;
105                 tmpBody = tmpBody.substring(0, (tmpBody.length() - trailingLF));
106             }
107             bodyFragments.add(tmpBody.getBytes("UTF-8"));
108         } else if (mSmsBodyPdus != null && mSmsBodyPdus.size() > 0) {
109             for (SmsPdu pdu : mSmsBodyPdus) {
110                 // This cannot(must not) contain END:MSG
111                 bodyFragments.add(
112                         encodeBinary(pdu.getData(), pdu.getScAddress()).getBytes("UTF-8"));
113             }
114         } else {
115             bodyFragments.add(new byte[0]); // An empty message - no text
116         }
117 
118         return encodeGeneric(bodyFragments);
119     }
120 
121 }
122