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