1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "gsm_sms_udata_codec.h"
18
19 #include "securec.h"
20 #include "sms_common_utils.h"
21 #include "telephony_log_wrapper.h"
22
23 namespace OHOS {
24 namespace Telephony {
25 using namespace std;
26 static constexpr uint8_t MAX_GSM_7BIT_DATA_LEN = 160;
27 static constexpr uint8_t MAX_UCS2_DATA_LEN = 140;
28 static constexpr uint8_t MAX_TPDU_DATA_LEN = 255;
29 static constexpr uint8_t BYTE_BIT = 8;
30 static constexpr uint8_t ENCODE_BYTE_BIT = 7;
31 static constexpr uint8_t HEX_BYTE_STEP = 2;
32
33 template<typename T>
UniquePtrDeleterOneDimension(T ** (& ptr))34 inline void UniquePtrDeleterOneDimension(T **(&ptr))
35 {
36 if (ptr && *ptr) {
37 delete[] *ptr;
38 *ptr = nullptr;
39 }
40 }
41
EncodeUserData(const struct SmsUserData * (& pUserData),SmsCodingScheme CodingScheme,char * (& pEncodeData))42 int GsmSmsUDataCodec::EncodeUserData(
43 const struct SmsUserData *(&pUserData), SmsCodingScheme CodingScheme, char *(&pEncodeData))
44 {
45 int encodeSize = 0;
46 switch (CodingScheme) {
47 case SMS_CODING_7BIT:
48 encodeSize = EncodeGSMData(pUserData, pEncodeData);
49 break;
50 case SMS_CODING_8BIT:
51 encodeSize = Encode8bitData(pUserData, pEncodeData);
52 break;
53 case SMS_CODING_UCS2:
54 encodeSize = EncodeUCS2Data(pUserData, pEncodeData);
55 break;
56 default:
57 break;
58 }
59 return encodeSize;
60 }
61
DecodeUserData(const unsigned char * pTpdu,const int tpduLen,bool bHeaderInd,SmsCodingScheme CodingScheme,struct SmsUserData * pUserData)62 int GsmSmsUDataCodec::DecodeUserData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd,
63 SmsCodingScheme CodingScheme, struct SmsUserData *pUserData)
64 {
65 int decodeSize = 0;
66 if (pTpdu == nullptr) {
67 TELEPHONY_LOGE("pTpdu is nullptr.");
68 return decodeSize;
69 }
70 if (memset_s(pUserData, sizeof(struct SmsUserData), 0x00, sizeof(struct SmsUserData)) != EOK) {
71 TELEPHONY_LOGE("memset_s error.");
72 return decodeSize;
73 }
74 switch (CodingScheme) {
75 case SMS_CODING_7BIT:
76 decodeSize = DecodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, nullptr);
77 break;
78 case SMS_CODING_8BIT:
79 decodeSize = Decode8bitData(pTpdu, bHeaderInd, pUserData, nullptr);
80 break;
81 case SMS_CODING_UCS2:
82 decodeSize = DecodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, nullptr);
83 break;
84 default:
85 break;
86 }
87
88 return decodeSize;
89 }
90
DecodeUserData(const unsigned char * pTpdu,const int tpduLen,bool bHeaderInd,SmsCodingScheme CodingScheme,struct SmsUserData * pUserData,struct SmsTpud * pTPUD)91 int GsmSmsUDataCodec::DecodeUserData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd,
92 SmsCodingScheme CodingScheme, struct SmsUserData *pUserData, struct SmsTpud *pTPUD)
93 {
94 int decodeSize = 0;
95 if (pTpdu == nullptr) {
96 TELEPHONY_LOGE("pTpdu is nullptr.");
97 return decodeSize;
98 }
99 if (memset_s(pUserData, sizeof(struct SmsUserData), 0x00, sizeof(struct SmsUserData)) != EOK) {
100 TELEPHONY_LOGE("memset_s error.");
101 return decodeSize;
102 }
103 switch (CodingScheme) {
104 case SMS_CODING_7BIT:
105 decodeSize = DecodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
106 break;
107 case SMS_CODING_8BIT:
108 decodeSize = Decode8bitData(pTpdu, bHeaderInd, pUserData, pTPUD);
109 break;
110 case SMS_CODING_UCS2:
111 decodeSize = DecodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
112 break;
113 case SMS_CODING_EUCKR:
114 decodeSize = DecodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
115 break;
116 default:
117 break;
118 }
119 return decodeSize;
120 }
121
EncodeGSMData(const struct SmsUserData * pUserData,char * pEncodeData)122 int GsmSmsUDataCodec::EncodeGSMData(const struct SmsUserData *pUserData, char *pEncodeData)
123 {
124 int offset = 0;
125 int fillBits = 0;
126 int packSize = 0;
127 int encodeLen = 0;
128 unsigned char udhl = 0x00;
129
130 if (pUserData->headerCnt > 0) {
131 offset = HEX_BYTE_STEP;
132 } else {
133 offset = 0x01;
134 }
135 TELEPHONY_LOGI("pUserData->headerCnt [%{public}d]", pUserData->headerCnt);
136 for (int i = 0; i < pUserData->headerCnt; i++) {
137 int headerLen = EncodeHeader(pUserData->header[i], &(pEncodeData[offset]));
138 TELEPHONY_LOGI("headerLen [%{public}d]", headerLen);
139 udhl += (char)headerLen;
140 offset += headerLen;
141 }
142 TELEPHONY_LOGI("udhl [%{public}u]", udhl);
143 if (udhl > 0) {
144 fillBits = ((udhl + 1) * BYTE_BIT) % ENCODE_BYTE_BIT; /* + UDHL */
145 }
146 if (fillBits > 0) {
147 fillBits = ENCODE_BYTE_BIT - fillBits;
148 }
149 TELEPHONY_LOGI("fillBits [%{public}d] dataLen [%{public}d]", fillBits, pUserData->length);
150 /* Set UDL, UDHL */
151 if (udhl > 0) {
152 pEncodeData[0] = (unsigned char)(((((int)udhl + 1) * 0x08) + fillBits + (pUserData->length * 0x07)) / 0x07);
153 pEncodeData[1] = udhl;
154 } else {
155 pEncodeData[0] = (char)pUserData->length;
156 }
157
158 packSize = SmsCommonUtils::Pack7bitChar(reinterpret_cast<const unsigned char *>(pUserData->data), pUserData->length,
159 fillBits, reinterpret_cast<unsigned char *>(&pEncodeData[offset]));
160 encodeLen = offset + packSize;
161 TELEPHONY_LOGI("packSize [%{public}d] encodeLen [%{public}d]", packSize, encodeLen);
162 return encodeLen;
163 }
164
Encode8bitData(const struct SmsUserData * pUserData,char * pEncodeData)165 int GsmSmsUDataCodec::Encode8bitData(const struct SmsUserData *pUserData, char *pEncodeData)
166 {
167 int offset = 0;
168 int fillBits = 0;
169 int encodeLen = 0;
170 unsigned char udhl = 0x00;
171
172 if (pUserData->headerCnt > 0) {
173 offset = 0x02;
174 } else {
175 offset = 0x01;
176 }
177 /* Encode User Data Header */
178 for (int i = 0; i < pUserData->headerCnt; i++) {
179 int headerLen = EncodeHeader(pUserData->header[i], &(pEncodeData[offset]));
180 udhl += (char)headerLen;
181 offset += headerLen;
182 }
183 TELEPHONY_LOGI("fillBits [%{public}d]", fillBits);
184 TELEPHONY_LOGI("dataLen [%{public}d]", pUserData->length);
185 /* Set UDL, UDHL */
186 if (udhl > 0) {
187 pEncodeData[0] = (unsigned char)(((int)udhl + 1) + fillBits + pUserData->length);
188 pEncodeData[1] = udhl;
189 } else {
190 pEncodeData[0] = (char)pUserData->length;
191 }
192 if (pUserData->length > static_cast<int>(MAX_TPDU_DATA_LEN - offset)) {
193 TELEPHONY_LOGE("Encode8bitData data length invalid tempLen.");
194 return encodeLen;
195 }
196 if (memcpy_s(&(pEncodeData[offset]), MAX_TPDU_DATA_LEN - offset, pUserData->data, pUserData->length) != EOK) {
197 TELEPHONY_LOGE("Encode8bitData memcpy_s error");
198 return encodeLen;
199 }
200 encodeLen = offset + pUserData->length;
201 return encodeLen;
202 }
203
EncodeUCS2Data(const struct SmsUserData * pUserData,char * pEncodeData)204 int GsmSmsUDataCodec::EncodeUCS2Data(const struct SmsUserData *pUserData, char *pEncodeData)
205 {
206 int offset = HEX_BYTE_STEP;
207 int fillBits = 0;
208 int encodeLen = 0;
209 unsigned char udhl = 0x00;
210
211 if (pUserData->headerCnt <= 0) {
212 offset = 1;
213 }
214 /* Encode User Data Header */
215 for (int i = 0; i < pUserData->headerCnt; i++) {
216 int headerLen = EncodeHeader(pUserData->header[i], &(pEncodeData[offset]));
217 udhl += (char)headerLen;
218 offset += headerLen;
219 }
220 TELEPHONY_LOGI("fillBits [%{public}d] dataLen [%{public}d]", fillBits, pUserData->length);
221 /* Set UDL, UDHL */
222 if (udhl > 0) {
223 pEncodeData[0] = (unsigned char)(((int)udhl + 1) + fillBits + pUserData->length);
224 pEncodeData[1] = udhl;
225 } else {
226 pEncodeData[0] = (char)pUserData->length;
227 }
228 if (pUserData->length > static_cast<int>(MAX_TPDU_DATA_LEN - offset)) {
229 TELEPHONY_LOGE("EncodeUCS2Data data length invalid");
230 return encodeLen;
231 }
232 if (memcpy_s(&(pEncodeData[offset]), MAX_TPDU_DATA_LEN - offset, pUserData->data, pUserData->length) != EOK) {
233 TELEPHONY_LOGE("EncodeUCS2Data memcpy_s error");
234 return encodeLen;
235 }
236 encodeLen = offset + pUserData->length;
237 return encodeLen;
238 }
239
DecodeGSMData(const unsigned char * pTpdu,const int tpduLen,bool bHeaderInd,struct SmsUserData * pUserData,struct SmsTpud * pTPUD)240 int GsmSmsUDataCodec::DecodeGSMData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd,
241 struct SmsUserData *pUserData, struct SmsTpud *pTPUD)
242 {
243 int offset = 0;
244 int udl = 0;
245 int udhl = 0;
246 int fillBits = 0;
247 int octetUdl = 0;
248 /* UDL */
249 udl = pTpdu[offset++];
250 octetUdl = (udl * ENCODE_BYTE_BIT) / BYTE_BIT;
251 TELEPHONY_LOGI("udl= %{public}d, tpdulen= %{public}d, octetUdl= %{public}d, bHeaderInd= %{public}d", udl,
252 tpduLen, octetUdl, bHeaderInd);
253 if (udl > MAX_GSM_7BIT_DATA_LEN || octetUdl > tpduLen) {
254 pUserData->length = 0;
255 pUserData->headerCnt = 0;
256 return 0;
257 }
258 /* Setting for Wap Push */
259 if (pTPUD != nullptr) {
260 pTPUD->udl = udl;
261 if (static_cast<unsigned long>(udl) > sizeof(pTPUD->ud)) {
262 TELEPHONY_LOGE("DecodeGSMData data length invalid");
263 return 0;
264 }
265 if (memcpy_s(pTPUD->ud, sizeof(pTPUD->ud), &(pTpdu[offset]), udl) != EOK) {
266 TELEPHONY_LOGE("DecodeGSMData memcpy_s error");
267 return 0;
268 }
269 pTPUD->ud[udl] = '\0';
270 }
271 /* Decode User Data Header */
272 if (bHeaderInd == true) {
273 /* UDHL */
274 udhl = pTpdu[offset++];
275 TELEPHONY_LOGI("udhl = %{public}d", udhl);
276 pUserData->headerCnt = 0;
277 for (int i = 0; offset < udhl && i < MAX_UD_HEADER_NUM; i++) {
278 int headerLen = DecodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
279 if (headerLen <= 0) {
280 TELEPHONY_LOGE("Error to Header. headerLen [%{public}d]", headerLen);
281 ResetUserData(*pUserData);
282 return 0;
283 }
284 offset += headerLen;
285 if (offset > (udhl + HEX_BYTE_STEP)) {
286 TELEPHONY_LOGE("Error to Header. offset [%{public}d] > (udhl [%{public}d] + 2)", offset, udhl);
287 ResetUserData(*pUserData);
288 return 0;
289 }
290 pUserData->headerCnt++;
291 }
292 } else {
293 pUserData->headerCnt = 0;
294 }
295
296 TELEPHONY_LOGI("headerCnt = %{public}d", pUserData->headerCnt);
297 if (udhl > 0) {
298 fillBits = ((udl * ENCODE_BYTE_BIT) - ((udhl + 1) * BYTE_BIT)) % ENCODE_BYTE_BIT;
299 udl = ((udl * ENCODE_BYTE_BIT) - ((udhl + 1) * BYTE_BIT)) / ENCODE_BYTE_BIT;
300 }
301 TELEPHONY_LOGI("fillBits = %{public}d udhl = %{public}d udl = %{public}d offset = %{public}d", fillBits, udhl,
302 udl, offset);
303 pUserData->length = SmsCommonUtils::Unpack7bitChar(
304 &(pTpdu[offset]), udl, fillBits, reinterpret_cast<unsigned char *>(pUserData->data), MAX_USER_DATA_LEN + 1);
305 return pUserData->length;
306 }
307
ResetUserData(struct SmsUserData & userData)308 void GsmSmsUDataCodec::ResetUserData(struct SmsUserData &userData)
309 {
310 userData.length = 0;
311 if (memset_s(userData.data, sizeof(userData.data), 0x00, sizeof(userData.data)) != EOK) {
312 TELEPHONY_LOGE("ResetUserData memset_s error!");
313 return;
314 }
315 TELEPHONY_LOGI("ResetUserData memset_s ok!");
316 }
317
GetHeaderCnt(const unsigned char * pTpdu,struct SmsUserData * pUserData,int & offset,int & udhl,int i)318 bool GsmSmsUDataCodec::GetHeaderCnt(
319 const unsigned char *pTpdu, struct SmsUserData *pUserData, int &offset, int &udhl, int i)
320 {
321 int headerLen = DecodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
322 if (headerLen <= 0) {
323 pUserData->length = 0;
324 if (memset_s(pUserData->data, sizeof(pUserData->data), 0x00, sizeof(pUserData->data)) != EOK) {
325 TELEPHONY_LOGE("memset_s fail.");
326 }
327 return false;
328 }
329 offset += headerLen;
330 if (offset > (udhl + HEX_BYTE_STEP)) {
331 pUserData->length = 0;
332 if (memset_s(pUserData->data, sizeof(pUserData->data), 0x00, sizeof(pUserData->data)) != EOK) {
333 TELEPHONY_LOGE("memset_s fail.");
334 }
335 return false;
336 }
337 pUserData->headerCnt++;
338 return true;
339 }
340
Decode8bitData(const unsigned char * pTpdu,bool bHeaderInd,struct SmsUserData * pUserData,struct SmsTpud * pTPUD)341 int GsmSmsUDataCodec::Decode8bitData(
342 const unsigned char *pTpdu, bool bHeaderInd, struct SmsUserData *pUserData, struct SmsTpud *pTPUD)
343 {
344 int offset = 0;
345 int udl = 0;
346 int udhl = 0;
347 /* UDL */
348 udl = pTpdu[offset++];
349 if (udl > MAX_UCS2_DATA_LEN) {
350 pUserData->length = 0;
351 return 0;
352 }
353 /* Setting for Wap Push */
354 if (pTPUD != nullptr) {
355 pTPUD->udl = udl;
356 if (static_cast<unsigned long>(udl) > sizeof(pTPUD->ud)) {
357 TELEPHONY_LOGE("Decode8bitData data length invalid");
358 return 0;
359 }
360 if (memcpy_s(pTPUD->ud, sizeof(pTPUD->ud), &(pTpdu[offset]), udl) != EOK) {
361 TELEPHONY_LOGE("memcpy_s error.");
362 return 0;
363 }
364 pTPUD->ud[udl] = '\0';
365 }
366 TELEPHONY_LOGI("udl = %{public}d bHeaderInd = %{public}d", udl, bHeaderInd);
367 /* Decode User Data Header */
368 if (bHeaderInd == true) {
369 /* UDHL */
370 udhl = pTpdu[offset++];
371 TELEPHONY_LOGI("udhl = %{public}d", udhl);
372 pUserData->headerCnt = 0;
373 for (int i = 0; offset < udhl && i < MAX_UD_HEADER_NUM; i++) {
374 if (!GetHeaderCnt(pTpdu, pUserData, offset, udhl, i)) {
375 return 0;
376 }
377 }
378 } else {
379 pUserData->headerCnt = 0;
380 }
381 if (udhl > 0) {
382 pUserData->length = (udl) - (udhl + 1);
383 } else {
384 pUserData->length = udl;
385 }
386 TELEPHONY_LOGI("pUserData->length= %{public}d offset= %{public}d", pUserData->length, offset);
387 if (static_cast<unsigned long>(udl) > sizeof(pTPUD->ud)) {
388 TELEPHONY_LOGE("Decode8bitData data length invalid");
389 return 0;
390 }
391 if (memcpy_s(pUserData->data, sizeof(pUserData->data), &(pTpdu[offset]), pUserData->length) != EOK) {
392 return 0;
393 }
394 return pUserData->length;
395 }
396
DecodeUCS2Data(const unsigned char * pTpdu,const int tpduLen,bool bHeaderInd,struct SmsUserData * pUserData,struct SmsTpud * pTPUD)397 int GsmSmsUDataCodec::DecodeUCS2Data(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd,
398 struct SmsUserData *pUserData, struct SmsTpud *pTPUD)
399 {
400 int offset = 0;
401 int udl = 0;
402 int udhl = 0;
403 /* UDL */
404 udl = pTpdu[offset++];
405 if (udl > MAX_UCS2_DATA_LEN || udl > tpduLen) {
406 pUserData->length = 0;
407 pUserData->headerCnt = 0;
408 return 0;
409 }
410 /* Setting for Wap Push */
411 if (pTPUD != nullptr) {
412 pTPUD->udl = udl;
413 if (memcpy_s(pTPUD->ud, sizeof(pTPUD->ud), &(pTpdu[offset]), udl) != EOK) {
414 TELEPHONY_LOGE("memcpy_s error.");
415 return 0;
416 }
417 pTPUD->ud[udl] = '\0';
418 }
419 /* Decode User Data Header */
420 if (bHeaderInd == true) {
421 /* UDHL */
422 udhl = pTpdu[offset++];
423 pUserData->headerCnt = 0;
424 for (int i = 0; offset < udhl && i < MAX_UD_HEADER_NUM; i++) {
425 int headerLen = DecodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
426 if (headerLen <= 0) {
427 ResetUserData(*pUserData);
428 return 0;
429 }
430 offset += headerLen;
431 if (offset > (udhl + HEX_BYTE_STEP)) {
432 ResetUserData(*pUserData);
433 return 0;
434 }
435 pUserData->headerCnt++;
436 }
437 } else {
438 pUserData->headerCnt = 0;
439 }
440
441 if (udhl > 0) {
442 pUserData->length = (udl) - (udhl + 1);
443 } else {
444 pUserData->length = udl;
445 }
446 TELEPHONY_LOGI("pUserData->length= %{public}d", pUserData->length);
447 if (memcpy_s(pUserData->data, sizeof(pUserData->data), &(pTpdu[offset]), pUserData->length) != EOK) {
448 TELEPHONY_LOGE("memcpy_s error.");
449 return 0;
450 }
451 pUserData->data[pUserData->length] = 0;
452 return pUserData->length;
453 }
454
EncodeHeader(const struct SmsUDH header,char * pHeader)455 int GsmSmsUDataCodec::EncodeHeader(const struct SmsUDH header, char *pHeader)
456 {
457 int index = 0;
458 int addrLen = 0;
459 char *encodedAddr = nullptr;
460 unique_ptr<char *, void (*)(char **(&))> addressBuf(&encodedAddr, UniquePtrDeleterOneDimension);
461 switch (header.udhType) {
462 case SMS_UDH_CONCAT_8BIT:
463 case SMS_UDH_CONCAT_16BIT:
464 index += EncodeHeaderConcat(header, pHeader);
465 break;
466 case SMS_UDH_APP_PORT_8BIT:
467 /* IEI */
468 pHeader[index++] = SMS_UDH_APP_PORT_8BIT;
469 /* IEDL */
470 pHeader[index++] = 0x02;
471 /* Dest Port */
472 pHeader[index++] = header.udh.appPort8bit.destPort;
473 /* Origin Port */
474 pHeader[index++] = header.udh.appPort8bit.originPort;
475 break;
476 case SMS_UDH_APP_PORT_16BIT:
477 /* IEI */
478 pHeader[index++] = SMS_UDH_APP_PORT_16BIT;
479 /* IEDL */
480 pHeader[index++] = 0x04;
481 /* Dest Port */
482 pHeader[index++] = (char)(header.udh.appPort16bit.destPort >> BYTE_BIT);
483 pHeader[index++] = header.udh.appPort16bit.destPort & 0x00FF;
484 /* Origin Port */
485 pHeader[index++] = (char)(header.udh.appPort16bit.originPort >> BYTE_BIT);
486 pHeader[index++] = header.udh.appPort16bit.originPort & 0x00FF;
487 break;
488 case SMS_UDH_ALTERNATE_REPLY_ADDRESS:
489 /* IEI */
490 pHeader[index++] = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
491 addrLen = GsmSmsParamCodec::EncodeAddress(&(header.udh.alternateAddress), &encodedAddr);
492 /* IEDL */
493 pHeader[index++] = (char)addrLen;
494 /* Alternate Reply Address */
495 if (memcpy_s(&pHeader[index], addrLen, encodedAddr, addrLen) != EOK) {
496 TELEPHONY_LOGE("EncodeHeader memcpy_s error");
497 return index;
498 }
499 index += addrLen;
500 break;
501 case SMS_UDH_SINGLE_SHIFT:
502 /* IEI */
503 pHeader[index++] = SMS_UDH_SINGLE_SHIFT;
504 /* IEDL */
505 pHeader[index++] = 0x01;
506 /* National Language Identifier */
507 pHeader[index++] = header.udh.singleShift.langId;
508 break;
509 case SMS_UDH_LOCKING_SHIFT:
510 /* IEI */
511 pHeader[index++] = SMS_UDH_LOCKING_SHIFT;
512 /* IEDL */
513 pHeader[index++] = 0x01;
514 /* National Language Identifier */
515 pHeader[index++] = header.udh.lockingShift.langId;
516 break;
517 case SMS_UDH_NONE:
518 default:
519 break;
520 }
521 return index;
522 }
523
EncodeHeaderConcat(const struct SmsUDH header,char * pHeader)524 int GsmSmsUDataCodec::EncodeHeaderConcat(const struct SmsUDH header, char *pHeader)
525 {
526 int index = 0;
527 switch (header.udhType) {
528 case SMS_UDH_CONCAT_8BIT:
529 /* IEI */
530 pHeader[index++] = SMS_UDH_CONCAT_8BIT;
531 /* IEDL */
532 pHeader[index++] = 0x03;
533 /* Reference Number */
534 pHeader[index++] = header.udh.concat8bit.msgRef;
535 /* Number of Segments */
536 pHeader[index++] = header.udh.concat8bit.totalSeg;
537 /* Sequence Number */
538 pHeader[index++] = header.udh.concat8bit.seqNum;
539 break;
540 case SMS_UDH_CONCAT_16BIT:
541 /* IEI */
542 pHeader[index++] = SMS_UDH_CONCAT_16BIT;
543 /* IEDL */
544 pHeader[index++] = 0x04;
545 /* Reference Number */
546 pHeader[index++] = (char)(header.udh.concat16bit.msgRef >> BYTE_BIT);
547 pHeader[index++] = header.udh.concat16bit.msgRef & 0x00FF;
548 /* Number of Segments */
549 pHeader[index++] = header.udh.concat16bit.totalSeg;
550 /* Sequence Number */
551 pHeader[index++] = header.udh.concat16bit.seqNum;
552 break;
553 case SMS_UDH_NONE:
554 default:
555 break;
556 }
557 return index;
558 }
559
DecodeHeader(const unsigned char * pTpdu,struct SmsUDH * pHeader)560 int GsmSmsUDataCodec::DecodeHeader(const unsigned char *pTpdu, struct SmsUDH *pHeader)
561 {
562 int offset = 0;
563 unsigned char IEDL = 0;
564 pHeader->udhType = pTpdu[offset++];
565 switch (pHeader->udhType) {
566 case SMS_UDH_CONCAT_8BIT: {
567 IEDL = pTpdu[offset++];
568 if (IEDL == 0) {
569 return 0;
570 }
571 pHeader->udh.concat8bit.msgRef = pTpdu[offset++];
572 pHeader->udh.concat8bit.totalSeg = pTpdu[offset++];
573 pHeader->udh.concat8bit.seqNum = pTpdu[offset++];
574 DebugDecodeHeader(pHeader);
575 break;
576 }
577 case SMS_UDH_CONCAT_16BIT: {
578 IEDL = pTpdu[offset++];
579 if (IEDL == 0) {
580 return 0;
581 }
582 pHeader->udh.concat16bit.msgRef = pTpdu[offset++];
583 pHeader->udh.concat16bit.msgRef =
584 (unsigned short)((pHeader->udh.concat16bit.msgRef << BYTE_BIT) | pTpdu[offset++]);
585 pHeader->udh.concat16bit.totalSeg = pTpdu[offset++];
586 pHeader->udh.concat16bit.seqNum = pTpdu[offset++];
587 DebugDecodeHeader(pHeader);
588 break;
589 }
590 case SMS_UDH_APP_PORT_8BIT: {
591 IEDL = pTpdu[offset++];
592 if (IEDL == 0) {
593 return 0;
594 }
595 pHeader->udh.appPort8bit.destPort = pTpdu[offset++];
596 pHeader->udh.appPort8bit.originPort = pTpdu[offset++];
597 DebugDecodeHeader(pHeader);
598 break;
599 }
600 case SMS_UDH_APP_PORT_16BIT: {
601 IEDL = pTpdu[offset++];
602 if (IEDL == 0) {
603 return 0;
604 }
605 pHeader->udh.appPort16bit.destPort = pTpdu[offset++];
606 pHeader->udh.appPort16bit.destPort =
607 (unsigned short)((pHeader->udh.appPort16bit.destPort << BYTE_BIT) | pTpdu[offset++]);
608 pHeader->udh.appPort16bit.originPort = pTpdu[offset++];
609 pHeader->udh.appPort16bit.originPort =
610 (unsigned short)((pHeader->udh.appPort16bit.originPort << BYTE_BIT) | pTpdu[offset++]);
611 DebugDecodeHeader(pHeader);
612 break;
613 }
614 case SMS_UDH_SPECIAL_SMS: {
615 IEDL = pTpdu[offset++];
616 if (IEDL != 0x02) {
617 return 0;
618 }
619 TELEPHONY_LOGI("Decoding special sms udh.");
620 pHeader->udh.specialInd.bStore = (bool)(pTpdu[offset] & 0x80);
621 pHeader->udh.specialInd.msgInd = (unsigned short)(pTpdu[offset++] & 0x7F);
622 pHeader->udh.specialInd.waitMsgNum = (unsigned short)pTpdu[offset];
623 break;
624 }
625 case SMS_UDH_ALTERNATE_REPLY_ADDRESS: {
626 IEDL = pTpdu[offset++];
627 if (IEDL == 0) {
628 return 0;
629 }
630 offset += GsmSmsParamCodec::DecodeAddress(&pTpdu[offset], &(pHeader->udh.alternateAddress));
631 TELEPHONY_LOGI("alternate reply address [%{private}s]", pHeader->udh.alternateAddress.address);
632 break;
633 }
634 case SMS_UDH_SINGLE_SHIFT: {
635 IEDL = pTpdu[offset++];
636 if (IEDL == 0) {
637 return 0;
638 }
639 pHeader->udh.singleShift.langId = pTpdu[offset++];
640 TELEPHONY_LOGI("singleShift.langId [%{public}02x]", pHeader->udh.singleShift.langId);
641 break;
642 }
643 case SMS_UDH_LOCKING_SHIFT: {
644 IEDL = pTpdu[offset++];
645 if (IEDL == 0) {
646 return 0;
647 }
648 pHeader->udh.lockingShift.langId = pTpdu[offset++];
649 TELEPHONY_LOGI("lockingShift.langId [%{public}02x]", pHeader->udh.lockingShift.langId);
650 break;
651 }
652 default: {
653 TELEPHONY_LOGI("Not Supported Header Type [%{public}02x]", pHeader->udhType);
654 IEDL = pTpdu[offset++];
655 TELEPHONY_LOGI("IEDL [%{public}u]", IEDL);
656 return (offset + (int)IEDL);
657 }
658 }
659 return offset;
660 }
661
DebugDecodeHeader(const struct SmsUDH * pHeader)662 void GsmSmsUDataCodec::DebugDecodeHeader(const struct SmsUDH *pHeader)
663 {
664 if (pHeader == nullptr) {
665 TELEPHONY_LOGE("DebugDecodeHeader pHeader nullptr");
666 return;
667 }
668 switch (pHeader->udhType) {
669 case SMS_UDH_CONCAT_8BIT: {
670 TELEPHONY_LOGI("concat8bit.seqNum [%{public}02x]", pHeader->udh.concat8bit.seqNum);
671 break;
672 }
673 case SMS_UDH_CONCAT_16BIT: {
674 TELEPHONY_LOGI("concat16bit.seqNum [%{public}02x]", pHeader->udh.concat16bit.seqNum);
675 break;
676 }
677 case SMS_UDH_APP_PORT_8BIT: {
678 TELEPHONY_LOGI("appPort8bit.destPort [%{private}02x]", pHeader->udh.appPort8bit.destPort);
679 TELEPHONY_LOGI("appPort8bit.originPort [%{private}02x]", pHeader->udh.appPort8bit.originPort);
680 break;
681 }
682 case SMS_UDH_APP_PORT_16BIT: {
683 TELEPHONY_LOGI("appPort16bit.destPort [%{private}04x]", pHeader->udh.appPort16bit.destPort);
684 TELEPHONY_LOGI("appPort16bit.originPort [%{private}04x]", pHeader->udh.appPort16bit.originPort);
685 break;
686 }
687 case SMS_UDH_SPECIAL_SMS: {
688 TELEPHONY_LOGI("Decoding special sms udh.");
689 break;
690 }
691 case SMS_UDH_ALTERNATE_REPLY_ADDRESS:
692 break;
693 case SMS_UDH_SINGLE_SHIFT: {
694 TELEPHONY_LOGI("singleShift.langId [%{public}02x]", pHeader->udh.singleShift.langId);
695 break;
696 }
697 case SMS_UDH_LOCKING_SHIFT: {
698 TELEPHONY_LOGI("lockingShift.langId [%{public}02x]", pHeader->udh.lockingShift.langId);
699 break;
700 }
701 default:
702 break;
703 }
704 }
705 } // namespace Telephony
706 } // namespace OHOS