• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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