• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sms_common_utils.h"
17 
18 #include <ctime>
19 #include "securec.h"
20 #include "telephony_log_wrapper.h"
21 
22 namespace OHOS {
23 namespace Telephony {
24 static constexpr uint8_t SMS_ENCODE_GSM_BIT = 7;
25 static constexpr uint8_t MAX_GSM_7BIT_DATA_LEN = 160;
26 static constexpr uint8_t SMS_BYTE_BIT = 8;
27 static constexpr uint16_t SEC_PER_HOUR = 3600;
28 static constexpr uint8_t BASE_GSM_YEAR = 100;
29 static constexpr uint8_t MAX_ABS_TIME_LEN = 32;
30 static constexpr uint8_t HEX_NUM_A = 0x0A;
31 static constexpr uint8_t HEX_NUM_B = 0x0B;
32 static constexpr uint8_t HEX_NUM_C = 0x0C;
33 
Pack7bitChar(const uint8_t * userData,uint16_t dataLen,uint8_t fillBits,uint8_t * packData,uint16_t packLen)34 uint16_t SmsCommonUtils::Pack7bitChar(
35     const uint8_t *userData, uint16_t dataLen, uint8_t fillBits, uint8_t *packData, uint16_t packLen)
36 {
37     uint16_t dstIdx = 0;
38     if (userData == nullptr || packData == nullptr || dataLen > MAX_GSM_7BIT_DATA_LEN) {
39         TELEPHONY_LOGE("userData error.");
40         return dstIdx;
41     }
42 
43     auto shift = fillBits;
44     if (shift > 0) {
45         dstIdx = 1;
46     }
47     uint16_t srcIdx = 0;
48     while (srcIdx < dataLen && dstIdx < packLen) {
49         if (shift == 0) {
50             packData[dstIdx] = userData[srcIdx];
51             shift = SMS_ENCODE_GSM_BIT;
52             srcIdx++;
53             dstIdx++;
54             if (srcIdx >= dataLen) {
55                 break;
56             }
57         }
58         if (shift > 1) {
59             packData[dstIdx - 1] |= userData[srcIdx] << shift;
60             packData[dstIdx] = userData[srcIdx] >> (SMS_BYTE_BIT - shift);
61             srcIdx++;
62             dstIdx++;
63             shift--;
64         } else if (shift == 1) {
65             packData[dstIdx - 1] |= userData[srcIdx] << shift;
66             shift--;
67             srcIdx++;
68         }
69     }
70     return dstIdx;
71 }
72 
Unpack7bitChar(const uint8_t * tpdu,uint16_t dataLen,uint8_t fillBits,uint8_t * unpackData,uint16_t unpackDataLen)73 uint16_t SmsCommonUtils::Unpack7bitChar(
74     const uint8_t *tpdu, uint16_t dataLen, uint8_t fillBits, uint8_t *unpackData, uint16_t unpackDataLen)
75 {
76     uint16_t srcIdx = 0;
77     uint16_t dstIdx = 0;
78     auto shift = fillBits;
79     if (unpackData == nullptr || tpdu == nullptr || dataLen == 0 || unpackDataLen == 0 || dataLen > unpackDataLen) {
80         TELEPHONY_LOGE("userData error.");
81         return dstIdx;
82     }
83     if (shift > 0) {
84         srcIdx = 1;
85     }
86     for (; srcIdx < dataLen && dstIdx < unpackDataLen; dstIdx++) {
87         if (shift == 0) {
88             unpackData[dstIdx] = tpdu[srcIdx] & 0x7F;
89             shift = SMS_ENCODE_GSM_BIT;
90             srcIdx++;
91             dstIdx++;
92             if (dstIdx >= dataLen) {
93                 break;
94             }
95         }
96         if (shift > 0 && srcIdx < dataLen && dstIdx < unpackDataLen) {
97             unpackData[dstIdx] = ((unsigned int)tpdu[srcIdx - 1] >> shift) + (tpdu[srcIdx] << (SMS_BYTE_BIT - shift));
98             unpackData[dstIdx] &= 0x7F;
99             shift--;
100             if (shift > 0) {
101                 srcIdx++;
102             }
103         }
104     }
105     return dstIdx;
106 }
107 
DigitToDtmfChar(const uint8_t c)108 uint8_t SmsCommonUtils::DigitToDtmfChar(const uint8_t c)
109 {
110     if (c == '0') {
111         return HEX_NUM_A;
112     } else if (c == '*') {
113         return HEX_NUM_B;
114     } else if (c == '#') {
115         return HEX_NUM_C;
116     } else {
117         return (c - '0');
118     }
119 }
120 
DtmfCharToDigit(const uint8_t c)121 uint8_t SmsCommonUtils::DtmfCharToDigit(const uint8_t c)
122 {
123     switch (c) {
124         case HEX_NUM_B:
125             return '*';
126         case HEX_NUM_C:
127             return '#';
128         case HEX_NUM_A:
129             return '0';
130         default:
131             return (c + '0');
132     }
133 }
134 
ConvertTime(const struct SmsTimeAbs & timeAbs)135 int64_t SmsCommonUtils::ConvertTime(const struct SmsTimeAbs &timeAbs)
136 {
137     time_t rawtime;
138     struct tm tmObj;
139     if (memset_s(&tmObj, sizeof(struct tm), 0x00, sizeof(tm)) != EOK) {
140         return time(nullptr);
141     }
142     tmObj.tm_year = (timeAbs.year + BASE_GSM_YEAR);
143     tmObj.tm_mon = (timeAbs.month - 0x01);
144     tmObj.tm_mday = timeAbs.day;
145     tmObj.tm_hour = timeAbs.hour;
146     tmObj.tm_min = timeAbs.minute;
147     tmObj.tm_sec = timeAbs.second;
148     tmObj.tm_isdst = 0;
149     rawtime = mktime(&tmObj);
150     GetDisplayTime(rawtime);
151     rawtime -= (timeAbs.timeZone * (SEC_PER_HOUR / 0x04));
152     GetDisplayTime(rawtime);
153     /* timezone value is tiemzone + daylight. So should not add daylight */
154     rawtime -= timezone;
155     GetDisplayTime(rawtime);
156     return rawtime;
157 }
158 
GetDisplayTime(const time_t & rawtime)159 void SmsCommonUtils::GetDisplayTime(const time_t &rawtime)
160 {
161     struct tm tmObj;
162     char displayTime[MAX_ABS_TIME_LEN];
163     if (memset_s(&tmObj, sizeof(struct tm), 0x00, sizeof(tm)) != EOK) {
164         TELEPHONY_LOGE("GetDisplayTime memset fail.");
165         return;
166     }
167 
168     if (memset_s(displayTime, sizeof(displayTime), 0x00, sizeof(displayTime)) != EOK) {
169         TELEPHONY_LOGE("GetDisplayTime memset fail.");
170         return;
171     }
172 
173     localtime_r(&rawtime, &tmObj);
174     if (strftime(displayTime, MAX_ABS_TIME_LEN, "%Y-%02m-%02d %T %z", &tmObj) <= 0) {
175         TELEPHONY_LOGE("strftime error.");
176         return;
177     }
178     TELEPHONY_LOGI("displayTime [%{public}s]", displayTime);
179 }
180 } // namespace Telephony
181 } // namespace OHOS
182