• 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 "gsm_sms_common_utils.h"
17 
18 #include <ctime>
19 
20 #include "gsm_pdu_hex_value.h"
21 #include "securec.h"
22 #include "telephony_log_wrapper.h"
23 
24 namespace OHOS {
25 namespace Telephony {
26 static constexpr uint8_t DIGITAL_STEP = 2;
27 static constexpr uint8_t SMS_ENCODE_GSM_BIT = 7;
28 static constexpr uint8_t MAX_GSM_7BIT_DATA_LEN = 160;
29 static constexpr uint8_t SMS_BYTE_BIT = 8;
30 static constexpr uint8_t MIN_REMAIN_LEN = 2;
31 
Pack7bitChar(SmsWriteBuffer & buffer,const uint8_t * userData,uint8_t dataLen,uint8_t fillBits)32 bool GsmSmsCommonUtils::Pack7bitChar(SmsWriteBuffer &buffer, const uint8_t *userData, uint8_t dataLen, uint8_t fillBits)
33 {
34     if (userData == nullptr || dataLen > MAX_GSM_7BIT_DATA_LEN) {
35         TELEPHONY_LOGE("userData error.");
36         return false;
37     }
38     auto shift = fillBits;
39     if (shift > 0) {
40         buffer.MoveForward(1);
41     }
42     uint8_t srcIdx = 0;
43     while (srcIdx < dataLen) {
44         if (shift == 0) {
45             if (!buffer.WriteByte(userData[srcIdx])) {
46                 TELEPHONY_LOGE("write data error.");
47                 return false;
48             }
49             shift = SMS_ENCODE_GSM_BIT;
50             srcIdx++;
51             if (srcIdx >= dataLen) {
52                 break;
53             }
54         }
55         if (shift > 1) {
56             if (!Pack7bitCharPartData(buffer, userData, srcIdx, shift)) {
57                 TELEPHONY_LOGE("packet fail.");
58                 return false;
59             }
60             shift--;
61             srcIdx++;
62         } else if (shift == 1) {
63             uint8_t oneByte = 0;
64             if (!buffer.GetValueFromIndex(buffer.GetIndex() - 1, oneByte)) {
65                 TELEPHONY_LOGE("get data error.");
66                 return false;
67             }
68             oneByte |= (userData[srcIdx] << shift);
69             if (!buffer.InsertByte(oneByte, (buffer.GetIndex() - 1))) {
70                 TELEPHONY_LOGE("write data error.");
71                 return false;
72             }
73             srcIdx++;
74             shift--;
75         }
76     }
77     return true;
78 }
79 
Pack7bitCharPartData(SmsWriteBuffer & buffer,const uint8_t * userData,uint8_t & srcIdx,uint8_t & shift)80 bool GsmSmsCommonUtils::Pack7bitCharPartData(
81     SmsWriteBuffer &buffer, const uint8_t *userData, uint8_t &srcIdx, uint8_t &shift)
82 {
83     uint8_t oneByte = 0;
84     if (!buffer.GetValueFromIndex(buffer.GetIndex() - 1, oneByte)) {
85         TELEPHONY_LOGE("get data error.");
86         return false;
87     }
88     oneByte |= (userData[srcIdx] << shift);
89     if (!buffer.InsertByte(oneByte, (buffer.GetIndex() - 1))) {
90         TELEPHONY_LOGE("write data error.");
91         return false;
92     }
93     if (!buffer.GetTopValue(oneByte)) {
94         TELEPHONY_LOGE("get data error.");
95         return false;
96     }
97     uint8_t nextByte = userData[srcIdx] >> (SMS_BYTE_BIT - shift);
98     if (!buffer.WriteByte(oneByte | nextByte)) {
99         TELEPHONY_LOGE("write data error.");
100         return false;
101     }
102     return true;
103 }
104 
Unpack7bitChar(SmsReadBuffer & buffer,uint8_t dataLen,uint8_t fillBits,uint8_t * unpackData,uint8_t unpackDataLen,uint8_t & dstIdx)105 bool GsmSmsCommonUtils::Unpack7bitChar(SmsReadBuffer &buffer, uint8_t dataLen, uint8_t fillBits, uint8_t *unpackData,
106     uint8_t unpackDataLen, uint8_t &dstIdx)
107 {
108     auto shift = fillBits;
109     if (unpackData == nullptr || dataLen >= unpackDataLen || fillBits > SMS_BYTE_BIT - 1) {
110         TELEPHONY_LOGE("data error.");
111         return false;
112     }
113     if (shift > 0) {
114         buffer.MoveForward(1);
115     }
116     for (; dstIdx < unpackDataLen; dstIdx++) {
117         if (shift == 0) {
118             uint8_t oneByte = 0;
119             if (!buffer.ReadByte(oneByte)) {
120                 TELEPHONY_LOGI("data unpack finish.");
121                 return true;
122             }
123             unpackData[dstIdx] = oneByte & HEX_VALUE_7F;
124             shift = SMS_ENCODE_GSM_BIT;
125             dstIdx++;
126             if (dstIdx >= unpackDataLen) {
127                 break;
128             }
129         }
130 
131         uint8_t oneByte = 0;
132         if (!buffer.PickOneByteFromIndex(buffer.GetIndex() - 1, oneByte)) {
133             TELEPHONY_LOGI("data unpack finish.");
134             return true;
135         }
136         uint8_t nextByte = 0;
137         if (!buffer.PickOneByte(nextByte)) {
138             TELEPHONY_LOGI("data unpack finish.");
139             unpackData[dstIdx] = (oneByte >> shift);
140             if (unpackData[dstIdx] != 0) {
141                 dstIdx++;
142             }
143             return true;
144         }
145         unpackData[dstIdx] = (oneByte >> shift) + (nextByte << (SMS_BYTE_BIT - shift));
146         unpackData[dstIdx] &= HEX_VALUE_7F;
147         shift--;
148         if (shift > 0) {
149             buffer.MoveForward(1);
150         }
151     }
152     return true;
153 }
154 
DigitToBcd(const char * digit,uint8_t digitLen,uint8_t * bcd,uint8_t bcdLen,uint8_t & len)155 bool GsmSmsCommonUtils::DigitToBcd(const char *digit, uint8_t digitLen, uint8_t *bcd, uint8_t bcdLen, uint8_t &len)
156 {
157     if (digit == nullptr || bcd == nullptr || len >= bcdLen) {
158         TELEPHONY_LOGE("data error.");
159         return false;
160     }
161 
162     len = 0;
163     for (uint8_t i = 0; i < digitLen; i++) {
164         uint8_t temp = static_cast<uint8_t>(digit[i] - '0');
165         if (len >= bcdLen) {
166             TELEPHONY_LOGE("len invalid.");
167             return false;
168         }
169         if ((i % DIGITAL_STEP) == 0) {
170             bcd[len] = temp & HEX_VALUE_0F;
171         } else {
172             bcd[len++] |= ((temp & HEX_VALUE_0F) << HEX_VALUE_04);
173         }
174     }
175 
176     if (len + 1 >= bcdLen) {
177         TELEPHONY_LOGE("len invalid.");
178         return false;
179     }
180     if ((digitLen % DIGITAL_STEP) == 1) {
181         bcd[len++] |= HEX_VALUE_F0;
182     }
183     return true;
184 }
185 
BcdToDigit(const uint8_t * bcd,uint8_t bcdLen,std::string & digit,uint8_t maxDigitLen)186 bool GsmSmsCommonUtils::BcdToDigit(const uint8_t *bcd, uint8_t bcdLen, std::string &digit, uint8_t maxDigitLen)
187 {
188     if (bcd == nullptr || bcdLen == 0 || maxDigitLen == 0) {
189         TELEPHONY_LOGE("data error.");
190         return false;
191     }
192     for (uint8_t i = 0; i < bcdLen; i++) {
193         uint8_t temp = bcd[i] & HEX_VALUE_0F;
194         if (digit.size() + MIN_REMAIN_LEN >= maxDigitLen) {
195             TELEPHONY_LOGE("digit size over max");
196             return false;
197         }
198         digit.push_back(BcdToChar(temp));
199         temp = (bcd[i] & HEX_VALUE_F0) >> HEX_VALUE_04;
200         if (temp == HEX_VALUE_0F) {
201             return true;
202         }
203         digit.push_back(BcdToChar(temp));
204     }
205     return true;
206 }
207 
BcdToChar(const uint8_t c)208 char GsmSmsCommonUtils::BcdToChar(const uint8_t c)
209 {
210     char temp = static_cast<char>(c + '0');
211     return temp;
212 }
213 } // namespace Telephony
214 } // namespace OHOS