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 dstIdx--;
94 break;
95 }
96 }
97 if (shift > 0 && srcIdx < dataLen && dstIdx < unpackDataLen) {
98 unpackData[dstIdx] = ((unsigned int)tpdu[srcIdx - 1] >> shift) + (tpdu[srcIdx] << (SMS_BYTE_BIT - shift));
99 unpackData[dstIdx] &= 0x7F;
100 shift--;
101 if (shift > 0) {
102 srcIdx++;
103 }
104 }
105 }
106 return dstIdx;
107 }
108
DigitToDtmfChar(const uint8_t c)109 uint8_t SmsCommonUtils::DigitToDtmfChar(const uint8_t c)
110 {
111 if (c == '0') {
112 return HEX_NUM_A;
113 } else if (c == '*') {
114 return HEX_NUM_B;
115 } else if (c == '#') {
116 return HEX_NUM_C;
117 } else {
118 return (c - '0');
119 }
120 }
121
DtmfCharToDigit(const uint8_t c)122 uint8_t SmsCommonUtils::DtmfCharToDigit(const uint8_t c)
123 {
124 switch (c) {
125 case HEX_NUM_B:
126 return '*';
127 case HEX_NUM_C:
128 return '#';
129 case HEX_NUM_A:
130 return '0';
131 default:
132 return (c + '0');
133 }
134 }
135
ConvertTime(const struct SmsTimeAbs & timeAbs)136 int64_t SmsCommonUtils::ConvertTime(const struct SmsTimeAbs &timeAbs)
137 {
138 time_t rawtime;
139 struct tm tmObj;
140 if (memset_s(&tmObj, sizeof(struct tm), 0x00, sizeof(tm)) != EOK) {
141 return time(nullptr);
142 }
143 tmObj.tm_year = (timeAbs.year + BASE_GSM_YEAR);
144 tmObj.tm_mon = (timeAbs.month - 0x01);
145 tmObj.tm_mday = timeAbs.day;
146 tmObj.tm_hour = timeAbs.hour;
147 tmObj.tm_min = timeAbs.minute;
148 tmObj.tm_sec = timeAbs.second;
149 tmObj.tm_isdst = 0;
150 rawtime = mktime(&tmObj);
151 GetDisplayTime(rawtime);
152 rawtime -= (timeAbs.timeZone * (SEC_PER_HOUR / 0x04));
153 GetDisplayTime(rawtime);
154 /* timezone value is tiemzone + daylight. So should not add daylight */
155 rawtime -= timezone;
156 GetDisplayTime(rawtime);
157 return rawtime;
158 }
159
GetDisplayTime(const time_t & rawtime)160 void SmsCommonUtils::GetDisplayTime(const time_t &rawtime)
161 {
162 struct tm tmObj;
163 char displayTime[MAX_ABS_TIME_LEN];
164 if (memset_s(&tmObj, sizeof(struct tm), 0x00, sizeof(tm)) != EOK) {
165 TELEPHONY_LOGE("GetDisplayTime memset fail.");
166 return;
167 }
168
169 if (memset_s(displayTime, sizeof(displayTime), 0x00, sizeof(displayTime)) != EOK) {
170 TELEPHONY_LOGE("GetDisplayTime memset fail.");
171 return;
172 }
173
174 localtime_r(&rawtime, &tmObj);
175 if (strftime(displayTime, MAX_ABS_TIME_LEN, "%Y-%02m-%02d %T %z", &tmObj) <= 0) {
176 TELEPHONY_LOGE("strftime error.");
177 return;
178 }
179 TELEPHONY_LOGI("displayTime [%{public}s]", displayTime);
180 }
181 } // namespace Telephony
182 } // namespace OHOS
183