• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.List;
26 
27 public class BluetoothMapbMessageSms extends BluetoothMapbMessage {
28 
29     private List<SmsPdu> mSmsBodyPdus = null;
30     private String mSmsBody = null;
31 
setSmsBodyPdus(List<SmsPdu> smsBodyPdus)32     public void setSmsBodyPdus(List<SmsPdu> smsBodyPdus) {
33         this.mSmsBodyPdus = smsBodyPdus;
34         this.mCharset = null;
35         if (smsBodyPdus.size() > 0) {
36             this.mEncoding = smsBodyPdus.get(0).getEncodingString();
37         }
38     }
39 
getSmsBody()40     public String getSmsBody() {
41         return mSmsBody;
42     }
43 
setSmsBody(String smsBody)44     public void setSmsBody(String smsBody) {
45         this.mSmsBody = smsBody;
46         this.mCharset = "UTF-8";
47         this.mEncoding = null;
48     }
49 
50     @Override
parseMsgPart(String msgPart)51     public void parseMsgPart(String msgPart) {
52         if (mAppParamCharset == BluetoothMapAppParams.CHARSET_NATIVE) {
53             Log.d(TAG, "Decoding \"" + msgPart + "\" as native PDU");
54             byte[] msgBytes = decodeBinary(msgPart);
55             if (msgBytes.length > 0
56                     && msgBytes[0] < msgBytes.length - 1
57                     && (msgBytes[msgBytes[0] + 1] & 0x03) != 0x01) {
58                 Log.d(TAG, "Only submit PDUs are supported");
59                 throw new IllegalArgumentException("Only submit PDUs are supported");
60             }
61 
62             mSmsBody =
63                     mSmsBody
64                             + BluetoothMapSmsPdu.decodePdu(
65                                     msgBytes,
66                                     mType == TYPE.SMS_CDMA
67                                             ? BluetoothMapSmsPdu.SMS_TYPE_CDMA
68                                             : BluetoothMapSmsPdu.SMS_TYPE_GSM);
69         } else {
70             mSmsBody = mSmsBody + msgPart;
71         }
72     }
73 
74     @Override
parseMsgInit()75     public void parseMsgInit() {
76         mSmsBody = "";
77     }
78 
79     @Override
encode()80     public byte[] encode() {
81         List<byte[]> bodyFragments = new ArrayList<>();
82 
83         /* Store the messages in an ArrayList to be able to handle the different message types in
84         a generic way.
85         * We use byte[] since we need to extract the length in bytes.
86         */
87         if (mSmsBody != null) {
88             String tmpBody =
89                     mSmsBody.replaceAll(
90                             "END:MSG",
91                             "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG
92             String remoteAddress =
93                     BluetoothMapService.getBluetoothMapService().getRemoteDevice().getAddress();
94             /* Fix IOT issue with PCM carkit where carkit is unable to parse
95             message if carriage return is present in it */
96             if (DeviceWorkArounds.addressStartsWith(remoteAddress, DeviceWorkArounds.PCM_CARKIT)) {
97                 tmpBody = tmpBody.replaceAll("\r", "");
98                 /* Fix Message Display issue with FORD SYNC carkit -
99                  * Remove line feed and include only carriage return */
100             } else if (DeviceWorkArounds.addressStartsWith(
101                     remoteAddress, DeviceWorkArounds.FORD_SYNC_CARKIT)) {
102                 tmpBody = tmpBody.replaceAll("\n", "");
103                 /* Fix IOT issue with SYNC carkit to remove trailing line feeds in the message body
104                  */
105             } else if (DeviceWorkArounds.addressStartsWith(
106                             remoteAddress, DeviceWorkArounds.SYNC_CARKIT)
107                     && tmpBody.length() > 0) {
108                 int trailingLF = 0;
109                 while ((tmpBody.charAt(tmpBody.length() - trailingLF - 1)) == '\n') trailingLF++;
110                 tmpBody = tmpBody.substring(0, (tmpBody.length() - trailingLF));
111             }
112             bodyFragments.add(tmpBody.getBytes(StandardCharsets.UTF_8));
113         } else if (mSmsBodyPdus != null && mSmsBodyPdus.size() > 0) {
114             for (SmsPdu pdu : mSmsBodyPdus) {
115                 // This cannot(must not) contain END:MSG
116                 bodyFragments.add(
117                         encodeBinary(pdu.getData(), pdu.getScAddress())
118                                 .getBytes(StandardCharsets.UTF_8));
119             }
120         } else {
121             bodyFragments.add(new byte[0]); // An empty message - no text
122         }
123 
124         return encodeGeneric(bodyFragments);
125     }
126 }
127