• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "mms_body_part_header.h"
17 
18 #include "telephony_log_wrapper.h"
19 
20 namespace OHOS {
21 namespace Telephony {
operator =(const MmsBodyPartHeader & srcHeader)22 MmsBodyPartHeader &MmsBodyPartHeader::operator=(const MmsBodyPartHeader &srcHeader)
23 {
24     if (this != &srcHeader) {
25         strContentTransferEncoding_ = srcHeader.strContentTransferEncoding_;
26         strFileName_ = srcHeader.strFileName_;
27         strContentLocation_ = srcHeader.strContentLocation_;
28         strContentID_ = srcHeader.strContentID_;
29         strDisposition_ = srcHeader.strDisposition_;
30         textMap_ = srcHeader.textMap_;
31     }
32     return *this;
33 }
34 
MmsBodyPartHeader(const MmsBodyPartHeader & obj)35 MmsBodyPartHeader::MmsBodyPartHeader(const MmsBodyPartHeader &obj)
36 {
37     *this = obj;
38 }
39 
DumpBodyPartHeader()40 void MmsBodyPartHeader::DumpBodyPartHeader() {}
41 
42 /**
43  * @brief DecodeContentLocation
44  * OMA-TS-MMS_ENC-V1_3-20110913-A   section:7.3.10 X-Mms-Content-Location Field
45  * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
46  * Content-location-value = Uri-value
47  * When used in the M-Mbox-Delete.conf and M-Delete.conf PDU:
48  * Content-location-Del-value = Value-length Status-count-value Content-location-value
49  * Status-count-value = Integer-value
50  * Uri-value = Text-string
51  * @param decodeBuffer
52  * @param Len
53  * @return true
54  * @return false
55  */
DecodeContentLocation(MmsDecodeBuffer & decodeBuffer,uint32_t & Len)56 bool MmsBodyPartHeader::DecodeContentLocation(MmsDecodeBuffer &decodeBuffer, uint32_t &Len)
57 {
58     std::string sTmp = "";
59     Len = 0;
60     if (!decodeBuffer.DecodeText(sTmp, Len)) {
61         TELEPHONY_LOGE("Body part header decode text fail.");
62         return false;
63     }
64     strContentLocation_ = sTmp;
65     return true;
66 }
67 
68 /**
69  * @brief DecodeContentId
70  * wap-230-wsp-20010705-a   section:8.4.2.67 Content-ID field
71  * Content-ID-value = Quoted-string
72  * @param decodeBuffer
73  * @param Len
74  * @return true
75  * @return false
76  */
DecodeContentId(MmsDecodeBuffer & decodeBuffer,uint32_t & Len)77 bool MmsBodyPartHeader::DecodeContentId(MmsDecodeBuffer &decodeBuffer, uint32_t &Len)
78 {
79     std::string sTmp = "";
80     Len = 0;
81     if (!decodeBuffer.DecodeQuotedText(sTmp, Len)) {
82         TELEPHONY_LOGE("Body part header decode quoted text fail.");
83         return false;
84     }
85     strContentID_ = sTmp;
86     return true;
87 }
88 
89 /**
90  * @brief DecodeContentDisposition
91  * wap-230-wsp-20010705-a   section:8.4.2.53 Content-disposition field
92  * Content-disposition-value = Value-length Disposition *(Parameter)
93  * Disposition = Form-data | Attachment | Inline | Token-text
94  * Form-data = <Octet 128>
95  * Attachment = <Octet 129>
96  * Inline = <Octet 130>
97  * @param decodeBuffer
98  * @param Len
99  * @return true
100  * @return false
101  */
DecodeContentDisposition(MmsDecodeBuffer & decodeBuffer,uint32_t & Len)102 bool MmsBodyPartHeader::DecodeContentDisposition(MmsDecodeBuffer &decodeBuffer, uint32_t &Len)
103 {
104     uint32_t dispositionLength = 0;
105     uint32_t count = 0;
106     if (!decodeBuffer.DecodeUintvar(dispositionLength, count)) {
107         TELEPHONY_LOGE("Body part header decode uintvar fail.");
108         return false;
109     }
110 
111     uint32_t beginPostion = decodeBuffer.GetCurPosition();
112     uint8_t oneByte = 0;
113     if (!decodeBuffer.GetOneByte(oneByte)) {
114         TELEPHONY_LOGE("Body part header decode get one byte fail.");
115         return false;
116     }
117 
118     switch (static_cast<MmsDispositonParam>(oneByte)) {
119         case MmsDispositonParam::P_DISPOSITION_FROM_DATA: {
120             strDisposition_ = DISPOSITION_FROM_DATA;
121             break;
122         }
123         case MmsDispositonParam::P_DISPOSITION_ATTACHMENT: {
124             strDisposition_ = DISPOSITION_ATTACHMENT;
125             break;
126         }
127         case MmsDispositonParam::P_DISPOSITION_INLINE: {
128             strDisposition_ = DISPOSITION_INLINE;
129             break;
130         }
131         default: {
132             if (!decodeBuffer.DecreasePointer(1)) {
133                 TELEPHONY_LOGE("Body part header move pointer fail.");
134                 return false;
135             }
136             std::string strTmp = "";
137             uint32_t tmpLen = 0;
138             if (!decodeBuffer.DecodeText(strTmp, tmpLen)) {
139                 TELEPHONY_LOGE("Body part header decode text fail.");
140                 return false;
141             }
142             strDisposition_ = strTmp;
143             break;
144         }
145     }
146     TELEPHONY_LOGI("strDisposition_ == %{public}s", strDisposition_.c_str());
147     if (!DecodeDispositionParameter(decodeBuffer, dispositionLength, beginPostion)) {
148         TELEPHONY_LOGE("Decode Disposition Parameter error.");
149         return false;
150     }
151     Len = dispositionLength + count + 1;
152     return true;
153 }
154 
155 /**
156  * @brief DecodeContentDispositionParameter
157  * wap-230-wsp-20010705-a   section:8.4.2.53 Content-disposition field
158  * Content-disposition-value = Value-length Disposition *(Parameter)
159  * Disposition = Form-data | Attachment | Inline | Token-text
160  * Form-data = <Octet 128>
161  * Attachment = <Octet 129>
162  * Inline = <Octet 130>
163  * @param decodeBuffer
164  * @param dispLen
165  * @param beginPos
166  * @return true
167  * @return false
168  */
DecodeDispositionParameter(MmsDecodeBuffer & decodeBuffer,uint32_t & dispLen,uint32_t beginPos)169 bool MmsBodyPartHeader::DecodeDispositionParameter(
170     MmsDecodeBuffer &decodeBuffer, uint32_t &dispLen, uint32_t beginPos)
171 {
172     const uint8_t pFileNameValue = 0x98;
173     uint32_t endPostion = decodeBuffer.GetCurPosition();
174     uint8_t oneByte = 0;
175     if (endPostion < beginPos) {
176         TELEPHONY_LOGI("Body part header data case 1.");
177         return true;
178     } else if ((dispLen <= (endPostion - beginPos)) && dispLen >= 1) {
179         dispLen = endPostion - beginPos - 1;
180         TELEPHONY_LOGI("Body part header data case 2.");
181         return true;
182     }
183 
184     if (!decodeBuffer.GetOneByte(oneByte)) {
185         TELEPHONY_LOGE("Body part header decode get one byte fail.");
186         return false;
187     }
188     if (oneByte == pFileNameValue) {
189         std::string strTmp = "";
190         uint32_t tmpLen = 0;
191         if (!decodeBuffer.DecodeText(strTmp, tmpLen)) {
192             TELEPHONY_LOGE("Body part header decode text fail.");
193             return false;
194         }
195         strFileName_ = strTmp;
196     }
197     endPostion = decodeBuffer.GetCurPosition();
198     if ((endPostion < beginPos) || dispLen < (endPostion - beginPos)) {
199         TELEPHONY_LOGE("Body part header data error.");
200         return false;
201     }
202     if (!decodeBuffer.IncreasePointer(dispLen - (endPostion - beginPos))) {
203         TELEPHONY_LOGE("Body part header decode content disposition move pointer err.");
204         return false;
205     }
206     return true;
207 }
208 
209 /**
210  * @brief DecodeWellKnownHeader
211  * wap-230-wsp-20010705-a   section:8.4.2.6 Header
212  * Well-known-header = Well-known-field-name Wap-value
213  * Well-known-field-name = Short-integer
214  * Wap-value = Accept-value | Accept-charset-value |...
215  * @param decodeBuffer
216  * @param headerLen
217  * @return true
218  * @return false
219  */
DecodeWellKnownHeader(MmsDecodeBuffer & decodeBuffer,uint32_t & headerLen)220 bool MmsBodyPartHeader::DecodeWellKnownHeader(MmsDecodeBuffer &decodeBuffer, uint32_t &headerLen)
221 {
222     const uint8_t endStringZeroLen = 1;
223     uint8_t fieldCode = 0xff;
224     uint8_t oneByte = 0;
225     if (!decodeBuffer.GetOneByte(oneByte)) {
226         TELEPHONY_LOGE("Body part header decode get one byte fail.");
227         return false;
228     }
229     headerLen--;
230     uint32_t len = 0;
231     fieldCode = oneByte & 0x7f;
232     switch (static_cast<MmsHeaderParam>(fieldCode)) {
233         case MmsHeaderParam::P_CONTENT_LOCATION_V1: /* Content-Location */
234         case MmsHeaderParam::P_CONTENT_LOCATION_V2: { /* Content-Location */
235             if (!DecodeContentLocation(decodeBuffer, len)) {
236                 TELEPHONY_LOGE("Body part header decode content location fail.");
237                 return false;
238             }
239             break;
240         }
241         case MmsHeaderParam::P_CONTENT_ID: { /* Content-ID */
242             if (!DecodeContentId(decodeBuffer, len)) {
243                 TELEPHONY_LOGE("Body part header decode contentId fail.");
244                 return false;
245             }
246             break;
247         }
248         case MmsHeaderParam::P_CONTENT_DISPOSITION_V1: /* Content-Disposition */
249         case MmsHeaderParam::P_CONTENT_DISPOSITION_V2: {
250             if (!DecodeContentDisposition(decodeBuffer, len)) {
251                 TELEPHONY_LOGE("Body part header decode content disposition fail.");
252                 return false;
253             }
254             break;
255         }
256         default: {
257             std::string sTmp = "";
258             decodeBuffer.DecodeQuotedText(sTmp, len);
259             break;
260         }
261     }
262     if (headerLen > len + endStringZeroLen) {
263         headerLen -= len + endStringZeroLen;
264     } else {
265         headerLen = 0;
266     }
267     return true;
268 }
269 
270 /**
271  * @brief DecodeApplicationHeader
272  * wap-230-wsp-20010705-a   section:8.4.2.6 Header
273  * Application-header		  = Token-text Application-specific-value
274  * Application-specific-value = Text-string
275  * @param decodeBuffer
276  * @param headerLen
277  * @return true
278  * @return false
279  */
DecodeApplicationHeader(MmsDecodeBuffer & decodeBuffer,uint32_t & headerLen)280 bool MmsBodyPartHeader::DecodeApplicationHeader(MmsDecodeBuffer &decodeBuffer, uint32_t &headerLen)
281 {
282     const uint32_t endStringZeroLen = 2;
283     headerLen = 0;
284     std::string sField = "";
285     uint32_t fieldLen = 0;
286     if (!decodeBuffer.DecodeTokenText(sField, fieldLen)) {
287         TELEPHONY_LOGE("Body part header decode token text fail.");
288         return false;
289     }
290 
291     std::string sValue = "";
292     uint32_t valueLen = 0;
293     if (!decodeBuffer.DecodeText(sValue, valueLen)) {
294         TELEPHONY_LOGE("Body part header decode text fail.");
295         return false;
296     }
297     if (sField == "Content-Transfer-Encoding") {
298         strContentTransferEncoding_ = sValue;
299     }
300     if (headerLen > fieldLen + valueLen + endStringZeroLen) {
301         headerLen -= fieldLen + valueLen + endStringZeroLen;
302     } else {
303         headerLen = 0;
304     }
305     return true;
306 }
307 
GetContentId(std::string & contentId)308 bool MmsBodyPartHeader::GetContentId(std::string &contentId)
309 {
310     contentId.clear();
311     contentId = strContentID_;
312     return true;
313 }
314 
SetContentId(std::string contentId)315 bool MmsBodyPartHeader::SetContentId(std::string contentId)
316 {
317     strContentID_ = contentId;
318     return true;
319 }
320 
GetContentTransferEncoding(std::string & contentTransferEncoding)321 bool MmsBodyPartHeader::GetContentTransferEncoding(std::string &contentTransferEncoding)
322 {
323     contentTransferEncoding.clear();
324     contentTransferEncoding = strContentTransferEncoding_;
325     return true;
326 }
327 
SetContentTransferEncoding(std::string contentTransferEncoding)328 bool MmsBodyPartHeader::SetContentTransferEncoding(std::string contentTransferEncoding)
329 {
330     strContentTransferEncoding_ = contentTransferEncoding;
331     return true;
332 }
333 
GetContentLocation(std::string & contentLocation)334 bool MmsBodyPartHeader::GetContentLocation(std::string &contentLocation)
335 {
336     contentLocation.clear();
337     contentLocation.assign(strContentLocation_);
338     return true;
339 }
340 
SetContentLocation(std::string contentLocation)341 bool MmsBodyPartHeader::SetContentLocation(std::string contentLocation)
342 {
343     strContentLocation_ = contentLocation;
344     return true;
345 }
346 
GetContentDisposition(std::string & contentDisposition)347 bool MmsBodyPartHeader::GetContentDisposition(std::string &contentDisposition)
348 {
349     contentDisposition.clear();
350     contentDisposition.assign(strDisposition_);
351     return true;
352 }
353 
SetContentDisposition(std::string contentDisposition)354 bool MmsBodyPartHeader::SetContentDisposition(std::string contentDisposition)
355 {
356     strDisposition_ = contentDisposition;
357     return true;
358 }
359 
360 /**
361  * @brief EncodeContentLocation
362  * OMA-TS-MMS_ENC-V1_3-20110913-A   section:7.3.10 X-Mms-Content-Location Field
363  * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
364  * Content-location-value = Uri-value
365  * When used in the M-Mbox-Delete.conf and M-Delete.conf PDU:
366  * Content-location-Del-value = Value-length Status-count-value Content-location-value
367  * Status-count-value = Integer-value
368  * Uri-value = Text-string
369  * @param encodeBuffer
370  * @return true
371  * @return false
372  */
EncodeContentLocation(MmsEncodeBuffer & encodeBuffer)373 bool MmsBodyPartHeader::EncodeContentLocation(MmsEncodeBuffer &encodeBuffer)
374 {
375     const uint8_t setHighestBitOne = 0x80;
376     if (strContentLocation_.empty()) {
377         TELEPHONY_LOGI("Body part header encode content location is empty.");
378         return true;
379     }
380 
381     if (!encodeBuffer.WriteByte(static_cast<uint8_t>(MmsHeaderParam::P_CONTENT_LOCATION_V2) | setHighestBitOne)) {
382         TELEPHONY_LOGE("Body part header encode content location write byte fail.");
383         return false;
384     }
385     if (!encodeBuffer.EncodeText(strContentLocation_)) {
386         TELEPHONY_LOGE("Body part header encode content location fail.");
387         return false;
388     }
389     return true;
390 }
391 
392 /**
393  * @brief EncodeContentId
394  * wap-230-wsp-20010705-a   section:8.4.2.67 Content-ID field
395  * Content-ID-value = Quoted-string
396  * @param encodeBuffer
397  * @return true
398  * @return false
399  */
EncodeContentId(MmsEncodeBuffer & encodeBuffer)400 bool MmsBodyPartHeader::EncodeContentId(MmsEncodeBuffer &encodeBuffer)
401 {
402     const uint8_t setHighestBitOne = 0x80;
403     if (strContentID_.empty()) {
404         TELEPHONY_LOGI("Body part header encode content ID is empty.");
405         return true;
406     }
407 
408     if (!encodeBuffer.WriteByte(static_cast<uint8_t>(MmsHeaderParam::P_CONTENT_ID) | setHighestBitOne)) {
409         TELEPHONY_LOGE("Body part header encode content ID write byte fail.");
410         return false;
411     }
412     if (!encodeBuffer.EncodeQuotedText(strContentID_)) {
413         TELEPHONY_LOGE("Body part header encode content ID fail.");
414         return false;
415     }
416     return true;
417 }
418 
419 /**
420  * @brief EncodeContentDisposition
421  * wap-230-wsp-20010705-a   section:8.4.2.53 Content-disposition field
422  * Content-disposition-value = Value-length Disposition *(Parameter)
423  * Disposition = Form-data | Attachment | Inline | Token-text
424  * Form-data = <Octet 128>
425  * Attachment = <Octet 129>
426  * Inline = <Octet 130>
427  * @param encodeBuffer
428  * @return true
429  * @return false
430  */
EncodeContentDisposition(MmsEncodeBuffer & encodeBuffer)431 bool MmsBodyPartHeader::EncodeContentDisposition(MmsEncodeBuffer &encodeBuffer)
432 {
433     const uint8_t setHighestBitOne = 0x80;
434     std::vector<std::string> dispVec {DISPOSITION_FROM_DATA, DISPOSITION_ATTACHMENT, DISPOSITION_INLINE};
435     auto it = std::find(dispVec.begin(), dispVec.end(), strDisposition_);
436     if (it == dispVec.end()) {
437         return true;
438     }
439 
440     TELEPHONY_LOGI("strDisposition = %{public}s", strDisposition_.c_str());
441     if (!encodeBuffer.WriteByte(static_cast<uint8_t>(MmsHeaderParam::P_CONTENT_DISPOSITION_V1) | setHighestBitOne)) {
442         TELEPHONY_LOGE("Body part header encode content disposition write byte fail.");
443         return false;
444     }
445     if (!encodeBuffer.EncodeUintvar(0x01)) {
446         TELEPHONY_LOGE("EncodeContentDisposition EncodeUintvar Error.");
447         return false;
448     }
449     if (strDisposition_ == DISPOSITION_FROM_DATA) {
450         if (!encodeBuffer.WriteByte(static_cast<uint8_t>(MmsDispositonParam::P_DISPOSITION_FROM_DATA))) {
451             TELEPHONY_LOGE("Body part header encode content disposition write byte fail.");
452             return false;
453         }
454         return true;
455     }
456     if (strDisposition_ == DISPOSITION_ATTACHMENT) {
457         if (!encodeBuffer.WriteByte(static_cast<uint8_t>(MmsDispositonParam::P_DISPOSITION_ATTACHMENT))) {
458             TELEPHONY_LOGE("Body part header encode content disposition write byte fail.");
459             return false;
460         }
461         return true;
462     }
463     if (strDisposition_ == DISPOSITION_INLINE) {
464         if (!encodeBuffer.WriteByte(static_cast<uint8_t>(MmsDispositonParam::P_DISPOSITION_INLINE))) {
465             TELEPHONY_LOGE("Body part header encode content disposition write byte fail.");
466             return false;
467         }
468         return true;
469     }
470     return true;
471 }
472 
473 /**
474  * @brief EncodeContentDisposition
475  * wap-230-wsp-20010705-a   section:8.4.2.46 Transfer encoding field
476  * Transfer-encoding-values = Chunked | Token-text
477  * Chunked = <Octet 128>
478  * @param encodeBuffer
479  * @return true
480  * @return false
481  */
EncodeContentTransferEncoding(MmsEncodeBuffer & encodeBuffer)482 bool MmsBodyPartHeader::EncodeContentTransferEncoding(MmsEncodeBuffer &encodeBuffer)
483 {
484     if (strContentTransferEncoding_.empty()) {
485         TELEPHONY_LOGI("Body part header encode content transfer encoding is empty.");
486         return true;
487     }
488 
489     if (!encodeBuffer.EncodeText("Content-Transfer-Encoding")) {
490         TELEPHONY_LOGE("Body part header encode content transfer encoding encode text fail.");
491         return false;
492     }
493     if (!encodeBuffer.EncodeText(strContentTransferEncoding_)) {
494         TELEPHONY_LOGE("Body part header encode content transfer encoding encode text fail.");
495         return false;
496     }
497     return true;
498 }
499 
500 /**
501  * @brief EncodeMmsBodyPartHeader
502  * wap-230-wsp-20010705-a   section:8.4.2.6 Header
503  * Well-known-header = Well-known-field-name Wap-value
504  * Well-known-field-name = Short-integer
505  * Wap-value = Accept-value | Accept-charset-value |...
506  * @param encodeBuffer
507  * @return true
508  * @return false
509  */
EncodeMmsBodyPartHeader(MmsEncodeBuffer & encodeBuffer)510 bool MmsBodyPartHeader::EncodeMmsBodyPartHeader(MmsEncodeBuffer &encodeBuffer)
511 {
512     if (!EncodeContentId(encodeBuffer)) {
513         TELEPHONY_LOGE("Body part header encode ContentId fail.");
514         return false;
515     }
516     if (!EncodeContentLocation(encodeBuffer)) {
517         TELEPHONY_LOGE("Body part header encode ContentLocation fail.");
518         return false;
519     }
520     if (!EncodeContentDisposition(encodeBuffer)) {
521         TELEPHONY_LOGE("Body part header encode ContentDisposition fail.");
522         return false;
523     }
524     if (!EncodeContentTransferEncoding(encodeBuffer)) {
525         TELEPHONY_LOGE("Body part header encode ContentTransferEncoding fail.");
526         return false;
527     }
528     return true;
529 }
530 } // namespace Telephony
531 } // namespace OHOS
532