• 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 "sms_common_utils.h"
18 
19 #include <ctime>
20 #include "securec.h"
21 #include "telephony_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace Telephony {
Pack7bitChar(const unsigned char * userData,int dataLen,int fillBits,unsigned char * packData)25 int SmsCommonUtils::Pack7bitChar(const unsigned char *userData, int dataLen, int fillBits, unsigned char *packData)
26 {
27     int srcIdx = 0;
28     int dstIdx = 0;
29     auto shift = static_cast<unsigned int>(fillBits);
30 
31     if (userData == nullptr || packData == nullptr) {
32         return dstIdx;
33     }
34 
35     if (shift > 0) {
36         dstIdx = 1;
37     }
38     while (srcIdx < dataLen) {
39         if (shift == 0) {
40             packData[dstIdx] = userData[srcIdx];
41             shift = SmsCommonUtils::SMS_ENCODE_GSM_BIT;
42             srcIdx++;
43             dstIdx++;
44             if (srcIdx >= dataLen) {
45                 break;
46             }
47         }
48         if (shift > 1) {
49             packData[dstIdx - 1] |= userData[srcIdx] << shift;
50             packData[dstIdx] = userData[srcIdx] >> (SmsCommonUtils::SMS_BYTE_BIT - shift);
51             shift--;
52             srcIdx++;
53             dstIdx++;
54         } else if (shift == 1) {
55             packData[dstIdx - 1] |= static_cast<unsigned int>(userData[srcIdx]) << shift;
56             srcIdx++;
57             shift--;
58         }
59     }
60     return dstIdx;
61 }
62 
Unpack7bitChar(const unsigned char * tpdu,unsigned char dataLen,int fillBits,unsigned char * unpackData,unsigned int unpackDataLen)63 int SmsCommonUtils::Unpack7bitChar(const unsigned char *tpdu, unsigned char dataLen, int fillBits,
64     unsigned char *unpackData, unsigned int unpackDataLen)
65 {
66     int srcIdx = 0;
67     int dstIdx = 0;
68     auto shift = static_cast<unsigned int>(fillBits);
69     if (unpackData == nullptr || tpdu == nullptr || dataLen > unpackDataLen) {
70         return dstIdx;
71     }
72     if (shift > 0) {
73         srcIdx = 1;
74     }
75     for (; dstIdx < dataLen; dstIdx++) {
76         if (shift == 0) {
77             unpackData[dstIdx] = tpdu[srcIdx] & 0x7F;
78             shift = SmsCommonUtils::SMS_ENCODE_GSM_BIT;
79             srcIdx++;
80             dstIdx++;
81             if (dstIdx >= dataLen) {
82                 break;
83             }
84         }
85         if (shift > 0) {
86             unpackData[dstIdx] =
87                 ((unsigned int)tpdu[srcIdx - 1] >> shift) + (tpdu[srcIdx] << (SmsCommonUtils::SMS_BYTE_BIT - shift));
88             unpackData[dstIdx] &= 0x7F;
89             shift--;
90             if (shift > 0) {
91                 srcIdx++;
92             }
93         }
94     }
95     return dstIdx;
96 }
97 
DigitToBcd(const char * digit,int digitLen,unsigned char * bcd)98 int SmsCommonUtils::DigitToBcd(const char *digit, int digitLen, unsigned char *bcd)
99 {
100     int offset = 0;
101     unsigned char temp;
102     if (digit == nullptr || bcd == nullptr) {
103         return offset;
104     }
105     for (int i = 0; i < digitLen; i++) {
106         switch (digit[i]) {
107             case '*':
108                 temp = 0x0A;
109                 break;
110             case '#':
111                 temp = 0x0B;
112                 break;
113             case 'P':
114             case 'p':
115                 temp = 0x0C;
116                 break;
117             default:
118                 temp = digit[i] - '0';
119                 break;
120         }
121         if ((i % SmsCommonUtils::SMS_HEX_BYTE_STEP) == 0) {
122             bcd[offset] = temp & 0x0F;
123         } else {
124             bcd[offset++] |= ((temp & 0x0F) << 0x04);
125         }
126     }
127 
128     if ((digitLen % SmsCommonUtils::SMS_HEX_BYTE_STEP) == 1) {
129         bcd[offset++] |= 0xF0;
130     }
131     return offset;
132 }
133 
BcdToDigit(const unsigned char * bcd,int bcdLen,char * digit)134 int SmsCommonUtils::BcdToDigit(const unsigned char *bcd, int bcdLen, char *digit)
135 {
136     int offset = 0;
137     unsigned char temp;
138     if (bcd == nullptr || digit == nullptr) {
139         return offset;
140     }
141     for (int i = 0; i < bcdLen; i++) {
142         temp = bcd[i] & 0x0F;
143         digit[offset++] = BcdToChar(temp);
144         temp = (bcd[i] & 0xF0) >> 0x04;
145         if (temp == 0x0F) {
146             digit[offset] = '\0';
147             return offset;
148         }
149         digit[offset++] = BcdToChar(temp);
150     }
151     digit[offset] = '\0';
152     return offset;
153 }
154 
BcdToDigitCdma(const unsigned char * bcd,int bcdLen,char * digit)155 int SmsCommonUtils::BcdToDigitCdma(const unsigned char *bcd, int bcdLen, char *digit)
156 {
157     int offset = 0;
158     unsigned char temp;
159     if (bcd == nullptr || digit == nullptr) {
160         return offset;
161     }
162 
163     for (int i = 0; i < bcdLen; i++) {
164         temp = (bcd[i] & 0xF0) >> 0x04;
165         digit[offset++] = BcdToChar(temp);
166         temp = bcd[i] & 0x0F;
167         if (temp == 0x0F) {
168             digit[offset] = '\0';
169             return offset;
170         }
171         digit[offset++] = BcdToChar(temp);
172     }
173     digit[offset] = '\0';
174     return offset;
175 }
176 
BcdToChar(const unsigned char c)177 char SmsCommonUtils::BcdToChar(const unsigned char c)
178 {
179     char temp = 0;
180     switch (c) {
181         case 0x0A:
182             temp = '*';
183             break;
184         case 0x0B:
185             temp = '#';
186             break;
187         case 0x0C:
188             temp = 'P';
189             break;
190         default:
191             temp = c + '0';
192             break;
193     }
194     return temp;
195 }
196 
ConvertDigitToDTMF(const char * digit,int digitLen,int startBit,unsigned char * dtmf)197 int SmsCommonUtils::ConvertDigitToDTMF(const char *digit, int digitLen, int startBit, unsigned char *dtmf)
198 {
199     int shift = startBit;
200     int offset = 0;
201     int srcIdx = 0;
202     uint8_t smsMaxShift = 4;
203     unsigned char temp;
204     if (digit == nullptr || dtmf == nullptr) {
205         TELEPHONY_LOGE("digit or dtmf is nullptr.");
206         return offset;
207     }
208     /* shift 1 and shift 2 are supported in this spec. */
209     if (shift >= smsMaxShift) {
210         TELEPHONY_LOGE("Invalid Param value shift : %{public}d", shift);
211         return offset;
212     }
213 
214     for (int i = 0; i < digitLen; i++) {
215         temp = DigitToDtmfChar(digit[srcIdx]);
216         temp &= 0x0F;
217         if (shift == 0) {
218             if (i % SmsCommonUtils::SMS_HEX_BYTE_STEP == 0x01) {
219                 dtmf[offset] |= temp;
220                 offset++;
221             } else {
222                 dtmf[offset] |= temp << 0x04;
223             }
224         } else if (shift >= 0x01 && shift < smsMaxShift) {
225             if (i % SmsCommonUtils::SMS_HEX_BYTE_STEP == 0x01) {
226                 dtmf[offset] |= (temp >> shift);
227                 dtmf[offset + 0x01] = temp << (SmsCommonUtils::SMS_BYTE_BIT - shift);
228                 offset++;
229             } else {
230                 dtmf[offset] |= (char)(temp << (SmsCommonUtils::SMS_BYTE_BIT - shift - smsMaxShift));
231             }
232         }
233         srcIdx++;
234     }
235     return offset;
236 }
237 
DigitToDtmfChar(const unsigned char c)238 unsigned char SmsCommonUtils::DigitToDtmfChar(const unsigned char c)
239 {
240     switch (c) {
241         case '*':
242             return 0x0B;
243         case '#':
244             return 0x0C;
245         case '0':
246             return 0x0A;
247         default:
248             return (c - '0');
249     }
250 }
251 
ConvertTime(const struct SmsTimeAbs & timeAbs)252 long SmsCommonUtils::ConvertTime(const struct SmsTimeAbs &timeAbs)
253 {
254     time_t rawtime;
255     struct tm tmInfo;
256     if (memset_s(&tmInfo, sizeof(struct tm), 0x00, sizeof(tm)) != EOK) {
257         return time(nullptr);
258     }
259     tmInfo.tm_year = (timeAbs.year + BASE_GSM_YEAR);
260     tmInfo.tm_mon = (timeAbs.month - 0x01);
261     tmInfo.tm_mday = timeAbs.day;
262     tmInfo.tm_hour = timeAbs.hour;
263     tmInfo.tm_min = timeAbs.minute;
264     tmInfo.tm_sec = timeAbs.second;
265     tmInfo.tm_isdst = 0;
266     rawtime = mktime(&tmInfo);
267     DisplayTime(rawtime);
268     rawtime -= (timeAbs.timeZone * (SEC_PER_HOUR / 0x04));
269     DisplayTime(rawtime);
270 /* timezone value is tiemzone + daylight. So should not add daylight */
271 #ifdef __MSG_DAYLIGHT_APPLIED__
272     rawtime -= (timezone - daylight * SEC_PER_HOUR);
273 #else
274     rawtime -= timezone;
275 #endif
276     DisplayTime(rawtime);
277     return rawtime;
278 }
279 
DisplayTime(const time_t & rawtime)280 void SmsCommonUtils::DisplayTime(const time_t &rawtime)
281 {
282     struct tm tmInfo;
283     const uint8_t maxAbsTimeLen = 32;
284     char displayTime[maxAbsTimeLen];
285     if (memset_s(&tmInfo, sizeof(struct tm), 0x00, sizeof(tm)) != EOK) {
286         TELEPHONY_LOGE("DisplayTime memset fail.");
287         return;
288     }
289 
290     if (memset_s(displayTime, sizeof(displayTime), 0x00, sizeof(displayTime)) != EOK) {
291         TELEPHONY_LOGE("DisplayTime memset fail.");
292         return;
293     }
294 
295     localtime_r(&rawtime, &tmInfo);
296     if (strftime(displayTime, maxAbsTimeLen, "%Y-%02m-%02d %T %z", &tmInfo) <= 0) {
297         TELEPHONY_LOGE("strftime error.");
298         return;
299     }
300     TELEPHONY_LOGI("displayTime [%{public}s]", displayTime);
301 }
302 } // namespace Telephony
303 } // namespace OHOS