1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
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
16 #include "map_mse_bmsg.h"
17 using std::string;
18 using std::vector;
19
20 namespace OHOS {
21 namespace bluetooth {
22 const std::string MapMseBmsg::MAP_MSE_BMESSAGE_VERSION = "VERSION:";
23
MapMseBmsg()24 MapMseBmsg::MapMseBmsg()
25 {}
26
~MapMseBmsg()27 MapMseBmsg::~MapMseBmsg()
28 {}
29
GetVersion(void) const30 std::string MapMseBmsg::GetVersion(void) const
31 {
32 return version_;
33 }
34
GetStatus(void) const35 std::string MapMseBmsg::GetStatus(void) const
36 {
37 return status_;
38 }
39
GetExtendedData(void) const40 std::string MapMseBmsg::GetExtendedData(void) const
41 {
42 return extendedData_;
43 }
44
SetExtendedData(const std::string & exdData)45 void MapMseBmsg::SetExtendedData(const std::string &exdData)
46 {
47 extendedData_ = exdData;
48 }
49
GetMsgBody(void) const50 std::string MapMseBmsg::GetMsgBody(void) const
51 {
52 return msgData_;
53 }
54
SetMsgBody(const std::string & body)55 void MapMseBmsg::SetMsgBody(const std::string &body)
56 {
57 msgData_ = body;
58 }
59
GetEncoding(void) const60 std::string MapMseBmsg::GetEncoding(void) const
61 {
62 return encoding_;
63 }
64
SetEncoding(const std::string & encoding)65 void MapMseBmsg::SetEncoding(const std::string &encoding)
66 {
67 encoding_ = encoding;
68 }
69
GetCharset(void) const70 std::string MapMseBmsg::GetCharset(void) const
71 {
72 return charset_;
73 }
74
SetCharset(const std::string & charset)75 void MapMseBmsg::SetCharset(const std::string &charset)
76 {
77 charset_ = charset;
78 }
79
GetLanguage(void) const80 std::string MapMseBmsg::GetLanguage(void) const
81 {
82 return language_;
83 }
84
SetLanguage(const std::string & language)85 void MapMseBmsg::SetLanguage(const std::string &language)
86 {
87 language_ = language;
88 }
89
GetBmsgLength(void) const90 std::string MapMseBmsg::GetBmsgLength(void) const
91 {
92 return std::to_string(bmsgLength_);
93 }
94
SetBmsgLength(const int length)95 void MapMseBmsg::SetBmsgLength(const int length)
96 {
97 bmsgLength_ = length;
98 }
99
SetVersion(const std::string & version)100 void MapMseBmsg::SetVersion(const std::string &version)
101 {
102 version_ = version;
103 }
104
SetMessageType(const std::string & typeName)105 void MapMseBmsg::SetMessageType(const std::string &typeName)
106 {
107 if (MAP_MSE_TYPE_EMAIL == typeName) {
108 msgType_ = MessageType::EMAIL;
109 } else if (MAP_MSE_TYPE_IM == typeName) {
110 msgType_ = MessageType::IM;
111 } else if (MAP_MSE_TYPE_MMS == typeName) {
112 msgType_ = MessageType::MMS;
113 } else if (MAP_MSE_TYPE_SMS_CDMA == typeName) {
114 msgType_ = MessageType::SMS_CDMA;
115 } else if (MAP_MSE_TYPE_SMS_GSM == typeName) {
116 msgType_ = MessageType::SMS_GSM;
117 }
118 }
119
Init(std::string body,const uint8_t charset)120 int MapMseBmsg::Init(std::string body, const uint8_t charset)
121 {
122 MSE_LOG_INFO("%{public}s Enter", __PRETTY_FUNCTION__);
123
124 vector<string> bodyList;
125 if (body.find("\r\n") != string::npos) {
126 Split(body, "\r\n", bodyList);
127 } else {
128 Split(body, "\n", bodyList);
129 }
130 size_t pos = 0;
131 if (ParseCheck(bodyList, pos, charset) != RET_NO_ERROR) {
132 return RET_BAD_STATUS;
133 }
134 ParseOrgEnve(bodyList, pos);
135 ParseBody(bodyList, pos);
136 return RET_NO_ERROR;
137 }
138
ParseCheck(const std::vector<std::string> & src,size_t & pos,const uint8_t charset)139 int MapMseBmsg::ParseCheck(const std::vector<std::string> &src, size_t &pos, const uint8_t charset)
140 {
141 if (src.size() == pos) {
142 return RET_BAD_STATUS;
143 }
144 for (; pos < src.size(); pos++) {
145 if (src[pos].find("BEGIN:BMSG") != string::npos || src[pos].find("VERSION:") != string::npos)
146 continue;
147 if (src[pos].find("BEGIN:VCARD") != string::npos || src[pos].find("BEGIN:BENV") != string::npos) {
148 break;
149 }
150 if (ParseProperty(src, pos)) {
151 continue;
152 }
153 }
154 if (static_cast<uint8_t>(Charset::NATIVE) == charset && MessageType::SMS_CDMA != msgType_ &&
155 MessageType::SMS_GSM != msgType_) {
156 MSE_LOG_ERROR("Native appParamsCharset only supported for SMS.");
157 return RET_BAD_STATUS;
158 }
159 if (status_.size() == 0) {
160 MSE_LOG_ERROR("Missing value for 'STATUS'.");
161 return RET_BAD_STATUS;
162 }
163 return RET_NO_ERROR;
164 }
165
ParseProperty(const std::vector<std::string> & src,size_t & pos)166 bool MapMseBmsg::ParseProperty(const std::vector<std::string> &src, size_t &pos)
167 {
168 bool hath = false;
169 if (auto temp = GetNodeValue(src[pos], "STATUS:"); temp.size() > 0) {
170 status_ = temp;
171 hath = true;
172 }
173 if (auto temp = GetNodeValue(src[pos], "TYPE:"); temp.size() > 0) {
174 SetMessageType(temp);
175 hath = true;
176 }
177 if (auto temp = GetNodeValue(src[pos], "FOLDER:"); temp.size() > 0) {
178 folder_ = temp;
179 hath = true;
180 }
181 if (auto temp = GetNodeValue(src[pos], "EXTENDEDDATA:"); temp.size() > 0) {
182 extendedData_ = temp;
183 hath = true;
184 }
185 return hath;
186 }
187
ParseOrgEnve(const std::vector<std::string> & src,size_t & pos)188 void MapMseBmsg::ParseOrgEnve(const std::vector<std::string> &src, size_t &pos)
189 {
190 for (; pos < src.size(); pos++) {
191 if (src[pos].find("BEGIN:VCARD") != string::npos) {
192 ++pos;
193 originator_.push_back(ParseVCard(src, pos, 0));
194 if (src[pos].find("END:VCARD") != string::npos)
195 continue;
196 }
197 if (src[pos].find("BEGIN:BENV") != string::npos)
198 break;
199 }
200 for (; pos < src.size(); pos++) {
201 if (src[pos].find("BEGIN:BENV") != string::npos) {
202 ++pos;
203 ParseEnvelope(src, pos, 0);
204 }
205 if (src[pos].find("BEGIN:BBODY") != string::npos)
206 break;
207 }
208 }
209
ParseBody(const std::vector<std::string> & src,size_t & pos)210 void MapMseBmsg::ParseBody(const std::vector<std::string> &src, size_t &pos)
211 {
212 MSE_LOG_INFO("%{public}s Enter", __PRETTY_FUNCTION__);
213 while (src[pos].find("END:") == string::npos) {
214 if (auto temp = GetNodeValue(src[pos], "PARTID:"); temp.size() > 0) {
215 partId_ = std::stoi(temp);
216 pos++;
217 continue;
218 }
219 if (auto temp = GetNodeValue(src[pos], "ENCODING:"); temp.size() > 0) {
220 encoding_ = temp;
221 pos++;
222 continue;
223 }
224 if (auto temp = GetNodeValue(src[pos], "CHARSET:"); temp.size() > 0) {
225 charset_ = temp;
226 pos++;
227 continue;
228 }
229 if (auto temp = GetNodeValue(src[pos], "LANGUAGE:"); temp.size() > 0) {
230 language_ = temp;
231 pos++;
232 continue;
233 }
234 if (auto temp = GetNodeValue(src[pos], "LENGTH:"); temp.size() > 0) {
235 bmsgLength_ = std::stoi(temp);
236 pos++;
237 continue;
238 }
239 if (src[pos].find("BEGIN:MSG") != string::npos) {
240 msgData_.append(src[pos]);
241 msgData_.append("\n");
242 pos++;
243 while (src[pos].find("END:MSG") == string::npos) {
244 msgData_.append(src[pos]);
245 msgData_.append("\n");
246 pos++;
247 }
248 msgData_.append("/");
249 msgData_.append(src[pos]);
250 }
251 pos++;
252 }
253 MSE_LOG_INFO("Msg Data: %{public}s ", msgData_.c_str());
254 }
255
ParseEnvelope(const std::vector<std::string> & src,size_t & pos,int level)256 void MapMseBmsg::ParseEnvelope(const std::vector<std::string> &src, size_t &pos, int level)
257 {
258 MSE_LOG_INFO("%{public}s Enter", __PRETTY_FUNCTION__);
259
260 for (; pos < src.size(); pos++) {
261 if (src[pos].find("BEGIN:VCARD") != string::npos) {
262 ++pos;
263 recipient_.push_back(ParseVCard(src, pos, level));
264 if (src[pos].find("END:VCARD") != string::npos) {
265 continue;
266 }
267 }
268 if (src[pos].find("BEGIN:BENV") != string::npos) {
269 ++pos;
270 ParseEnvelope(src, pos, ++level);
271 }
272 if (src[pos].find("BEGIN:BBODY") != string::npos) {
273 break;
274 }
275 }
276 }
277
ParseVCard(const std::vector<std::string> & src,size_t & pos,int level) const278 MapMseVcard MapMseBmsg::ParseVCard(const std::vector<std::string> &src, size_t &pos, int level) const
279 {
280 string vcardVersion, name, formattedName;
281 vector<string> phoneNumbers, emailAddresses, btUids, btUcis;
282 for (; pos < src.size(); pos++) {
283 if (src[pos].find("END:VCARD") == string::npos) {
284 if (src[pos].find("BEGIN:BENV") != string::npos || src[pos].find("EGIN:VCARD") != string::npos) {
285 continue;
286 }
287 if (string tempStr = GetNodeValue(src[pos], "VERSION:"); tempStr.size() > 0) {
288 vcardVersion = tempStr == "3.0" ? "3.0" : "2.1";
289 continue;
290 }
291 if (string tempStr = GetNodeValue(src[pos], "FN:"); tempStr.size() > 0) {
292 formattedName = tempStr;
293 continue;
294 }
295 if (string tempStr = GetNodeValue(src[pos], "N:"); tempStr.size() > 0) {
296 name = tempStr;
297 continue;
298 }
299 if (string tempStr = GetNodeValue(src[pos], "TEL:"); tempStr.size() > 0) {
300 Split(tempStr, ";", phoneNumbers);
301 continue;
302 }
303 if (string tempStr = GetNodeValue(src[pos], "EMAIL:"); tempStr.size() > 0) {
304 Split(tempStr, ";", emailAddresses);
305 continue;
306 }
307 if (string tempStr = GetNodeValue(src[pos], "X-BT-UID:"); tempStr.size() > 0) {
308 Split(tempStr, ";", btUids);
309 continue;
310 }
311 if (string tempStr = GetNodeValue(src[pos], "X-BT-UCI:"); tempStr.size() > 0) {
312 Split(tempStr, ";", btUcis);
313 continue;
314 }
315 } else {
316 break;
317 }
318 }
319 if (version_ == MAP_V11) {
320 MseVcard3 vcard3 {
321 name, vcardVersion, formattedName, phoneNumbers, emailAddresses, btUids, btUcis, level
322 };
323 return MapMseVcard(vcard3);
324 }
325 MseVcard2 vcard2 {name, vcardVersion, formattedName, phoneNumbers, emailAddresses, level};
326 return MapMseVcard(vcard2);
327 }
328
GetNodeValue(const std::string & src,std::string name)329 std::string MapMseBmsg::GetNodeValue(const std::string &src, std::string name)
330 {
331 MSE_LOG_INFO("%{public}s Enter", __PRETTY_FUNCTION__);
332
333 string str = src;
334 std::string ret;
335 if (str.find(name) != string::npos) {
336 string::size_type start = str.find_first_of(':', 0);
337 if (start != string::npos) {
338 ret = str.substr(start + 1);
339 }
340 }
341 MSE_LOG_INFO("Node value: %{public}s ", ret.c_str());
342 return ret;
343 }
344
Split(const std::string & src,const std::string & separator,std::vector<std::string> & dest)345 void MapMseBmsg::Split(const std::string &src, const std::string &separator, std::vector<std::string> &dest)
346 {
347 string str = src;
348 string substring;
349 string::size_type start = 0;
350 dest.clear();
351 string::size_type index = str.find_first_of(separator, start);
352 do {
353 if (index != string::npos) {
354 substring = str.substr(start, index - start);
355 dest.push_back(substring);
356 start = index + separator.size();
357 index = str.find(separator, start);
358 if (start == string::npos) {
359 break;
360 }
361 }
362 } while (index != string::npos);
363
364 substring = str.substr(start);
365 dest.push_back(substring);
366 }
367
AddBbody(std::string & bmessage)368 void MapMseBmsg::AddBbody(std::string &bmessage)
369 {
370 bmessage.append("BEGIN:BBODY");
371 bmessage.append("\n");
372 if (partId_ != -1) {
373 bmessage.append("PARTID:" + std::to_string(partId_));
374 bmessage.append("\n");
375 }
376 if (encoding_ != "") {
377 bmessage.append("ENCODING:" + encoding_);
378 bmessage.append("\n");
379 }
380 if (charset_ != "") {
381 bmessage.append("CHARSET:" + charset_);
382 bmessage.append("\n");
383 }
384 if (language_ != "") {
385 bmessage.append("LANGUAGE:" + language_);
386 bmessage.append("\n");
387 }
388 if (bmsgLength_ == -1) {
389 bmsgLength_ = msgData_.size();
390 }
391 bmessage.append("LENGTH:" + std::to_string(bmsgLength_));
392 bmessage.append("\n");
393 bmessage.append(msgData_);
394 bmessage.append("\n");
395 bmessage.append("END:BBODY");
396 bmessage.append("\n");
397 }
398
AddRecipient(std::string & bmessage)399 void MapMseBmsg::AddRecipient(std::string &bmessage)
400 {
401 for (auto &iter : recipient_) {
402 if (iter.GetEnvLevel() == 0) {
403 bmessage.append(iter.ToVcardString(version_));
404 bmessage.append("\n");
405 }
406 }
407 std::string benv1 = "";
408 for (auto &iter : recipient_) {
409 if (iter.GetEnvLevel() == 1) {
410 benv1.append(iter.ToVcardString(version_));
411 benv1.append("\n");
412 }
413 }
414 if (benv1 != "") {
415 bmessage.append("BEGIN:BENV");
416 bmessage.append("\n");
417 bmessage.append(benv1);
418 }
419 std::string benv2 = "";
420 for (auto &iter : recipient_) {
421 if (iter.GetEnvLevel() == 0x2) {
422 benv2.append(iter.ToVcardString(version_));
423 benv2.append("\n");
424 }
425 }
426 if (benv2 != "") {
427 bmessage.append("BEGIN:BENV");
428 bmessage.append("\n");
429 bmessage.append(benv2);
430 }
431 AddBbody(bmessage);
432 if (benv2 != "") {
433 bmessage.append("END:BENV");
434 bmessage.append("\n");
435 }
436 if (benv1 != "") {
437 bmessage.append("END:BENV");
438 bmessage.append("\n");
439 }
440 }
441
ToBmessageString(void)442 std::string MapMseBmsg::ToBmessageString(void)
443 {
444 std::string bmessage;
445 bmessage.append("BEGIN:BMSG");
446 bmessage.append("\n");
447 bmessage.append("VERSION:" + version_);
448 bmessage.append("\n");
449 bmessage.append("STATUS:" + status_);
450 bmessage.append("\n");
451 bmessage.append("TYPE:" + msgTypeName_);
452 bmessage.append("\n");
453 bmessage.append("FOLDER:" + folder_);
454 bmessage.append("\n");
455 if (version_ == "1.1") {
456 bmessage.append("EXTENDEDDATA:" + extendedData_);
457 bmessage.append("\n");
458 }
459 for (auto &iter : originator_) {
460 bmessage.append(iter.ToVcardString(version_));
461 bmessage.append("\n");
462 }
463 bmessage.append("BEGIN:BENV");
464 bmessage.append("\n");
465 AddRecipient(bmessage);
466 bmessage.append("END:BENV");
467 bmessage.append("\n");
468 bmessage.append("END:BMSG");
469 bmessage.append("\n");
470 return bmessage;
471 }
472
SetStatus(const std::string & status)473 void MapMseBmsg::SetStatus(const std::string &status)
474 {
475 status_ = status;
476 }
477
SetType(const MessageType & type)478 void MapMseBmsg::SetType(const MessageType &type)
479 {
480 msgType_ = type;
481 }
482
GetType(void) const483 MessageType MapMseBmsg::GetType(void) const
484 {
485 return msgType_;
486 }
487
SetMsgTypeName(const std::string & name)488 void MapMseBmsg::SetMsgTypeName(const std::string &name)
489 {
490 msgTypeName_ = name;
491 }
492
SetPartId(const int id)493 void MapMseBmsg::SetPartId(const int id)
494 {
495 partId_ = id;
496 }
497
GetPartId(void) const498 std::string MapMseBmsg::GetPartId(void) const
499 {
500 return std::to_string(partId_);
501 }
502
GetFolder(void) const503 std::string MapMseBmsg::GetFolder(void) const
504 {
505 return folder_;
506 }
507
SetFolder(const std::string & folder)508 void MapMseBmsg::SetFolder(const std::string &folder)
509 {
510 folder_ = folder;
511 }
512
GetOriginators(void) const513 std::vector<MapMseVcard> MapMseBmsg::GetOriginators(void) const
514 {
515 return originator_;
516 }
517
SetOriginators(const std::vector<MapMseVcard> & originator)518 void MapMseBmsg::SetOriginators(const std::vector<MapMseVcard> &originator)
519 {
520 originator_ = originator;
521 }
522
GetRecipients(void) const523 std::vector<MapMseVcard> MapMseBmsg::GetRecipients(void) const
524 {
525 return recipient_;
526 }
527
SetRecipients(const std::vector<MapMseVcard> & recipient)528 void MapMseBmsg::SetRecipients(const std::vector<MapMseVcard> &recipient)
529 {
530 recipient_ = recipient;
531 }
532 } // namespace bluetooth
533 } // namespace OHOS
534