• 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 #include "mms_body.h"
16 
17 #include "mms_decode_buffer.h"
18 #include "telephony_log_wrapper.h"
19 
20 namespace OHOS {
21 namespace Telephony {
22 using namespace std;
MmsBody()23 MmsBody::MmsBody() : bodyEntrys_(0) {}
24 
DumpMmsBody()25 void MmsBody::DumpMmsBody()
26 {
27     for (auto bodyPart : mmsBodyParts_) {
28         bodyPart.DumpMmsBodyPart();
29     }
30 }
31 
32 /**
33  * @brief DecodeMultipart
34  * wap-230-wsp-20010705-a.pdf   section:8.5 Multipart Data
35  * The application/vnd.wap.multipart content type consists of a header followed by 0 or more entries.
36  * @param decodeBuffer
37  * @return true
38  * @return false
39  */
DecodeMultipart(MmsDecodeBuffer & decodeBuffer)40 bool MmsBody::DecodeMultipart(MmsDecodeBuffer &decodeBuffer)
41 {
42     uint32_t nEntries = 0;
43     uint32_t length = 0;
44     if (!decodeBuffer.DecodeUintvar(nEntries, length)) {
45         TELEPHONY_LOGE("Body decode multipart uintvar fail.");
46         return false;
47     }
48     bodyEntrys_ = nEntries;
49     TELEPHONY_LOGE("attachment number: %{public}u", nEntries);
50     while (nEntries) {
51         MmsBodyPart bodyPart;
52         if (!bodyPart.DecodePart(decodeBuffer, nEntries)) {
53             TELEPHONY_LOGE("Body decode multipart DecodePart fail.");
54             return false;
55         }
56         mmsBodyParts_.push_back(bodyPart);
57         nEntries--;
58     }
59     return true;
60 }
61 
DecodeMmsBody(MmsDecodeBuffer & decodeBuffer,MmsHeader & header)62 bool MmsBody::DecodeMmsBody(MmsDecodeBuffer &decodeBuffer, MmsHeader &header)
63 {
64     unsigned char msgType = 0;
65     if (!header.GetOctetValue(MMS_MESSAGE_TYPE, msgType)) {
66         TELEPHONY_LOGE("Body decode GetOctetValue fail.");
67         return false;
68     }
69 
70     if (msgType != MMS_MSGTYPE_SEND_REQ && msgType != MMS_MSGTYPE_RETRIEVE_CONF) {
71         // no body
72         TELEPHONY_LOGI("this mms message type no body");
73         return true;
74     }
75     std::string contentType = "";
76     header.GetHeaderContentType().GetContentType(contentType);
77     switch (static_cast<ContentTypes>(MmsContentType::GetContentTypeFromString(contentType))) {
78         case ContentTypes::APPLICATION_VND_WAP_MULTIPART_MIXED:
79         case ContentTypes::APPLICATION_VND_WAP_MULTIPART_RELATED:
80         case ContentTypes::APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
81         case ContentTypes::MULTIPART_MIXED:
82         case ContentTypes::MULTIPART_ALTERNATIVE:
83         case ContentTypes::APPLICATION_VND_OMA_DRM_MESSAGE:
84         case ContentTypes::APPLICATION_VND_OMA_DRM_CONTENT:
85             return DecodeMultipart(decodeBuffer);
86         default:
87             break;
88     }
89     return true;
90 }
91 
EncodeMmsBody(MmsEncodeBuffer & encodeBuffer)92 bool MmsBody::EncodeMmsBody(MmsEncodeBuffer &encodeBuffer)
93 {
94     uint32_t partsNum = GetBodyPartCount();
95     if (!encodeBuffer.EncodeUintvar(partsNum)) {
96         TELEPHONY_LOGE("Body encode uintvar fail.");
97         return false;
98     }
99     for (uint32_t i = 0; i < partsNum; i++) {
100         if (!mmsBodyParts_.at(i).EncodeMmsBodyPart(encodeBuffer)) {
101             TELEPHONY_LOGE("Body encode EncodeMmsBodyPart fail.");
102             return false;
103         }
104     }
105     return true;
106 }
107 
108 /**
109  * @brief EncodeMmsHeaderContentType
110  * wap-230-wsp-20010705-a   section:8.4.2.24 Content type field section:8.4.2.1 Basic rules
111  * Content-type-value = Constrained-media | Content-general-form
112  * Constrained-media = Constrained-encoding
113  * Constrained-encoding = Extension-Media | Short-integer
114  * Extension-media = *TEXT End-of-string
115  * Content-general-form = Value-length Media-type
116  * Media-type = (Well-known-media | Extension-Media) *(Parameter)
117  * Well-known-media = Integer-value
118  * Parameter = Typed-parameter | Untyped-parameter
119  * @param mmsHeader
120  * @param encodeBuffer
121  * @return true
122  * @return false
123  */
EncodeMmsHeaderContentType(MmsHeader & mmsHeader,MmsEncodeBuffer & encodeBuffer)124 bool MmsBody::EncodeMmsHeaderContentType(MmsHeader &mmsHeader, MmsEncodeBuffer &encodeBuffer)
125 {
126     if (!encodeBuffer.WriteByte((int8_t)(MMS_CONTENT_TYPE))) {
127         TELEPHONY_LOGE("Body encode WriteByte fail.");
128         return false;
129     }
130     std::string strContentType = "";
131     mmsHeader.GetHeaderContentType().GetContentType(strContentType);
132     if (!strContentType.length()) {
133         TELEPHONY_LOGE("Body encode ContentType length is zero.");
134         return false;
135     }
136     if (!mmsHeader.IsHaveBody() || GetBodyPartCount() == 0) {
137         if (!encodeBuffer.EncodeText(strContentType)) {
138             TELEPHONY_LOGE("Body encode ContentType EncodeText fail.");
139             return false;
140         }
141         return true;
142     }
143 
144     MmsEncodeBuffer tmpEncodeBuffer;
145     if (!tmpEncodeBuffer.EncodeText(strContentType)) {
146         TELEPHONY_LOGE("Body encode ContentType EncodeText fail.");
147         return false;
148     }
149     // parameter
150     mmsHeader.GetHeaderContentType().EncodeTextField(tmpEncodeBuffer);
151     mmsHeader.GetHeaderContentType().EncodeTypeField(tmpEncodeBuffer);
152     mmsHeader.GetHeaderContentType().EncodeCharsetField(tmpEncodeBuffer);
153 
154     if (!encodeBuffer.EncodeValueLength(tmpEncodeBuffer.GetCurPosition())) {
155         TELEPHONY_LOGE("Body encode ContentType EncodeValueLength fail.");
156         return false;
157     }
158     if (!encodeBuffer.WriteBuffer(tmpEncodeBuffer)) {
159         TELEPHONY_LOGE("Body encode ContentType WriteBuffer fail.");
160         return false;
161     }
162     return true;
163 }
164 
GetBodyPartCount()165 uint32_t MmsBody::GetBodyPartCount()
166 {
167     return mmsBodyParts_.size();
168 }
169 
IsContentLocationPartExist(std::string contentLocation)170 bool MmsBody::IsContentLocationPartExist(std::string contentLocation)
171 {
172     for (auto item : mmsBodyParts_) {
173         std::string strlocation = "";
174         item.GetPartHeader().GetContentLocation(strlocation);
175         if (contentLocation == strlocation) {
176             return true;
177         }
178     }
179     return false;
180 }
181 
IsContentIdPartExist(std::string contentId)182 bool MmsBody::IsContentIdPartExist(std::string contentId)
183 {
184     for (auto item : mmsBodyParts_) {
185         std::string strId = "";
186         item.GetPartHeader().GetContentId(strId);
187         if (contentId == strId) {
188             return true;
189         }
190     }
191     return false;
192 }
193 
IsBodyPartExist(MmsBodyPart & bodyPart)194 bool MmsBody::IsBodyPartExist(MmsBodyPart &bodyPart)
195 {
196     std::string contentId;
197     bodyPart.GetContentId(contentId);
198     if (IsContentIdPartExist(contentId)) {
199         return true;
200     }
201 
202     std::string contentLocation;
203     bodyPart.GetContentLocation(contentLocation);
204     if (IsContentLocationPartExist(contentLocation)) {
205         return true;
206     }
207     return false;
208 }
209 
GetMmsBodyPart(std::vector<MmsBodyPart> & parts)210 void MmsBody::GetMmsBodyPart(std::vector<MmsBodyPart> &parts)
211 {
212     parts.clear();
213     parts.assign(mmsBodyParts_.begin(), mmsBodyParts_.end());
214 }
215 
AddMmsBodyPart(MmsBodyPart & bodyPart)216 bool MmsBody::AddMmsBodyPart(MmsBodyPart &bodyPart)
217 {
218     if (bodyPart.IsSmilFile() && bHaveSmilPart_) {
219         TELEPHONY_LOGE("Not allowed to add more than two SmilPart File error.");
220         return false;
221     }
222 
223     if (bodyPart.IsSmilFile()) {
224         mmsBodyParts_.insert(mmsBodyParts_.begin(), bodyPart);
225         bHaveSmilPart_ = true;
226     } else {
227         mmsBodyParts_.push_back(bodyPart);
228     }
229     return true;
230 }
231 } // namespace Telephony
232 } // namespace OHOS
233