• 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                 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