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