1 /*
2 * Copyright (C) 2023 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 "gsm_user_data_encode.h"
17
18 #include "gsm_pdu_hex_value.h"
19 #include "gsm_sms_common_utils.h"
20 #include "securec.h"
21 #include "telephony_log_wrapper.h"
22
23 namespace OHOS {
24 namespace Telephony {
25 using namespace std;
26 static constexpr uint8_t NORMAL_BYTE_BITS = 8;
27 static constexpr uint8_t GSM_ENCODE_BITS = 7;
28 static constexpr uint8_t SLIDE_DATA_STEP = 2;
29 static constexpr uint8_t MAX_TPDU_LEN = 255;
30 static constexpr uint8_t HEX_07 = 0x07;
31 static constexpr uint8_t HEX_08 = 0x08;
32 const std::string CT_SMSC = "10659401";
33
GsmUserDataEncode(std::shared_ptr<GsmUserDataPdu> data)34 GsmUserDataEncode::GsmUserDataEncode(std::shared_ptr<GsmUserDataPdu> data)
35 {
36 userData_ = data;
37 }
38
~GsmUserDataEncode()39 GsmUserDataEncode::~GsmUserDataEncode() {}
40
EncodeGsmPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)41 bool GsmUserDataEncode::EncodeGsmPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
42 {
43 uint8_t fillBits = 0;
44 if (!EncodeGsmHeadPdu(buffer, userData, fillBits)) {
45 return false;
46 }
47 return EncodeGsmBodyPdu(buffer, userData, fillBits);
48 }
49
EncodeGsmHeadPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,uint8_t & fillBits)50 bool GsmUserDataEncode::EncodeGsmHeadPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, uint8_t &fillBits)
51 {
52 if (userData == nullptr || userData_ == nullptr) {
53 TELEPHONY_LOGE("nullptr error.");
54 return false;
55 }
56
57 uint16_t location = buffer.GetIndex();
58 if (userData->headerCnt > 0) {
59 buffer.MoveForward(SLIDE_DATA_STEP);
60 } else {
61 buffer.MoveForward(HEX_VALUE_01);
62 }
63 uint16_t udhl = buffer.GetIndex();
64 for (uint8_t i = 0; i < userData->headerCnt; i++) {
65 userData_->EncodeHeader(buffer, userData->header[i]);
66 }
67
68 if (buffer.GetIndex() > udhl) {
69 udhl = buffer.GetIndex() - udhl;
70 } else {
71 udhl = 0;
72 }
73 if (udhl > 0) {
74 fillBits = ((udhl + 1) * NORMAL_BYTE_BITS) % GSM_ENCODE_BITS; /* + UDHL */
75 }
76 if (fillBits > 0 && GSM_ENCODE_BITS > fillBits) {
77 fillBits = GSM_ENCODE_BITS - fillBits;
78 } else {
79 fillBits = 0;
80 }
81
82 /* Set UDL, UDHL */
83 if (udhl > 0) {
84 uint16_t value = ((udhl + 1) * HEX_08) + fillBits + (userData->length * HEX_07);
85 if (!buffer.InsertByte((value / HEX_07), location)) {
86 TELEPHONY_LOGE("write data error.");
87 return false;
88 }
89 if (!buffer.InsertByte(static_cast<uint8_t>(udhl), location + 1)) {
90 TELEPHONY_LOGE("write data error.");
91 return false;
92 }
93 } else {
94 if (!buffer.InsertByte(userData->length, location)) {
95 TELEPHONY_LOGE("write data error.");
96 return false;
97 }
98 }
99 return true;
100 }
101
EncodeGsmBodyPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,uint8_t fillBits)102 bool GsmUserDataEncode::EncodeGsmBodyPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, uint8_t fillBits)
103 {
104 if (userData == nullptr) {
105 TELEPHONY_LOGE("nullptr error.");
106 return false;
107 }
108
109 GsmSmsCommonUtils utils;
110 bool packResult =
111 utils.Pack7bitChar(buffer, reinterpret_cast<const uint8_t *>(userData->data), userData->length, fillBits);
112 return packResult;
113 }
114
Encode8bitPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,std::string & destAddr)115 bool GsmUserDataEncode::Encode8bitPdu(
116 SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, std::string &destAddr)
117 {
118 if (!Encode8bitHeadPdu(buffer, userData, destAddr)) {
119 return false;
120 }
121 return Encode8bitBodyPdu(buffer, userData);
122 }
123
Encode8bitHeadPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,std::string & destAddr)124 bool GsmUserDataEncode::Encode8bitHeadPdu(
125 SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, std::string &destAddr)
126 {
127 if (userData == nullptr || userData_ == nullptr) {
128 TELEPHONY_LOGE("nullptr error.");
129 return false;
130 }
131
132 uint16_t location = buffer.GetIndex();
133 if (userData->headerCnt > 0 && CT_SMSC.compare(destAddr) != 0) {
134 buffer.MoveForward(SLIDE_DATA_STEP);
135 } else {
136 buffer.MoveForward(HEX_VALUE_01);
137 }
138
139 /* Encode User Data Header */
140 uint16_t udhl = buffer.GetIndex();
141 for (uint8_t index = 0; index < userData->headerCnt && CT_SMSC.compare(destAddr) != 0; index++) {
142 userData_->EncodeHeader(buffer, userData->header[index]);
143 }
144 if (buffer.GetIndex() > udhl) {
145 udhl = buffer.GetIndex() - udhl;
146 } else {
147 udhl = 0;
148 }
149 /* Set UDL, UDHL */
150 if (udhl > 0) {
151 if (!buffer.InsertByte(static_cast<uint8_t>(udhl + 1 + userData->length), location)) {
152 TELEPHONY_LOGE("Encode8bitHeadPdu write data error.");
153 return false;
154 }
155 if (!buffer.InsertByte(static_cast<uint8_t>(udhl), location + 1)) {
156 TELEPHONY_LOGE("Encode8bitHeadPdu write data error.");
157 return false;
158 }
159 } else {
160 if (!buffer.InsertByte(userData->length, location)) {
161 TELEPHONY_LOGE("Encode8bitHeadPdu write data error.");
162 return false;
163 }
164 }
165 return true;
166 }
167
Encode8bitBodyPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)168 bool GsmUserDataEncode::Encode8bitBodyPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
169 {
170 if (userData == nullptr || buffer.data_ == nullptr) {
171 TELEPHONY_LOGE("nullptr error");
172 return false;
173 }
174
175 if (buffer.GetIndex() >= MAX_TPDU_LEN || userData->length + buffer.GetIndex() > MAX_TPDU_LEN) {
176 TELEPHONY_LOGE(" userData length error.");
177 return false;
178 }
179 if (buffer.GetIndex() >= buffer.GetSize() || userData->length + buffer.GetIndex() > buffer.GetSize()) {
180 TELEPHONY_LOGE("buffer error.");
181 return false;
182 }
183 uint16_t destLen = MAX_TPDU_LEN - buffer.GetIndex() - HEX_VALUE_01;
184 if (memcpy_s(buffer.data_.get() + buffer.GetIndex(), destLen, userData->data, userData->length) != EOK) {
185 TELEPHONY_LOGE("memcpy_s error");
186 return false;
187 }
188 buffer.MoveForward(userData->length);
189 return true;
190 }
191
EncodeUcs2Pdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)192 bool GsmUserDataEncode::EncodeUcs2Pdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
193 {
194 if (!EncodeUcs2HeadPdu(buffer, userData)) {
195 return false;
196 }
197 return EncodeUcs2BodyPdu(buffer, userData);
198 }
199
EncodeUcs2HeadPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)200 bool GsmUserDataEncode::EncodeUcs2HeadPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
201 {
202 if (userData == nullptr || userData_ == nullptr) {
203 TELEPHONY_LOGE("nullptr error");
204 return false;
205 }
206 uint16_t location = buffer.GetIndex();
207 if (userData->headerCnt == 0) {
208 buffer.MoveForward(1);
209 } else {
210 buffer.MoveForward(SLIDE_DATA_STEP);
211 }
212
213 /* Encode User Data Header */
214 uint16_t udhl = buffer.GetIndex();
215 for (uint8_t j = 0; j < userData->headerCnt; j++) {
216 userData_->EncodeHeader(buffer, userData->header[j]);
217 }
218 if (buffer.GetIndex() > udhl) {
219 udhl = buffer.GetIndex() - udhl;
220 } else {
221 udhl = 0;
222 }
223
224 /* Set UDL, UDHL */
225 if (udhl > 0) {
226 if (!buffer.InsertByte(static_cast<uint8_t>(udhl + 1 + userData->length), location)) {
227 TELEPHONY_LOGE("EncodeUcs2HeadPdu write data error.");
228 return false;
229 }
230 if (!buffer.InsertByte(static_cast<uint8_t>(udhl), location + 1)) {
231 TELEPHONY_LOGE("EncodeUcs2HeadPdu write data error.");
232 return false;
233 }
234 } else {
235 if (!buffer.InsertByte(userData->length, location)) {
236 TELEPHONY_LOGE("EncodeUcs2HeadPdu write data error.");
237 return false;
238 }
239 }
240 return true;
241 }
242
EncodeUcs2BodyPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)243 bool GsmUserDataEncode::EncodeUcs2BodyPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
244 {
245 if (userData == nullptr) {
246 TELEPHONY_LOGE("nullptr error");
247 return false;
248 }
249 if (userData->length + buffer.GetIndex() >= MAX_TPDU_LEN) {
250 TELEPHONY_LOGE("data length error");
251 return false;
252 }
253 if (buffer.data_ == nullptr || (buffer.GetIndex() + userData->length) > buffer.GetSize()) {
254 TELEPHONY_LOGE("buffer error.");
255 return false;
256 }
257 uint16_t destLen = MAX_TPDU_LEN - buffer.GetIndex() - HEX_VALUE_01;
258 if (memcpy_s(buffer.data_.get() + buffer.GetIndex(), destLen, userData->data, userData->length) != EOK) {
259 TELEPHONY_LOGE("memcpy_s error");
260 return false;
261 }
262 buffer.MoveForward(userData->length);
263 return true;
264 }
265 } // namespace Telephony
266 } // namespace OHOS