1 /*
2  * Copyright (C) 2021 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 "sim_utils.h"
17 
18 using namespace std;
19 
20 namespace OHOS {
21 namespace Telephony {
HexCharConvertToInt(char c)22 unsigned char SIMUtils::HexCharConvertToInt(char c)
23 {
24     if (c >= '0' && c <= '9') {
25         return (c - '0');
26     } else if (c >= 'A' && c <= 'F') {
27         return (c - 'A' + DECIMAL_MAX);
28     } else if (c >= 'a' && c <= 'f') {
29         return (c - 'a' + DECIMAL_MAX);
30     }
31     return 0;
32 }
33 
HexStringConvertToBytes(const std::string & s,int & byteslen)34 std::shared_ptr<unsigned char> SIMUtils::HexStringConvertToBytes(const std::string &s, int &byteslen)
35 {
36     if (s.empty()) {
37         return nullptr;
38     }
39     int id = 0;
40     int sz = static_cast<int>(s.length());
41     if (sz % HALF_LEN != 0) {
42         return nullptr;
43     }
44     int outlen = sz / HALF_LEN;
45     byteslen = outlen;
46     if (outlen == 0) {
47         return nullptr;
48     }
49     unsigned char *cache = (unsigned char *)calloc(outlen + 1, sizeof(unsigned char));
50     if (cache == nullptr) {
51         return nullptr;
52     }
53     (void)memset_s(cache, (outlen + 1) * sizeof(unsigned char), 0, (outlen + 1) * sizeof(unsigned char));
54     std::shared_ptr<unsigned char> ptr(cache, [](unsigned char *ptr) { free(ptr); });
55     unsigned char *ret = ptr.get();
56     for (int i = 0; i < sz; i += HALF_LEN) {
57         id = i / HALF_LEN;
58         ret[id] = (unsigned char)((HexCharConvertToInt(s.at(i)) << HALF_BYTE_LEN) | HexCharConvertToInt(s.at(i + 1)));
59     }
60     return ptr;
61 }
62 
BytesConvertToHexString(const unsigned char * bytes,int byteLen)63 std::string SIMUtils::BytesConvertToHexString(const unsigned char *bytes, int byteLen)
64 {
65     if (bytes == nullptr) {
66         return "";
67     }
68     std::string str = "";
69     for (int i = 0; i < byteLen; i++) {
70         int b = 0;
71         b = 0x0f & (bytes[i] >> HALF_BYTE_LEN);
72         str.push_back(HEX_CHARS[b]);
73         b = 0x0f & bytes[i];
74         str.push_back(HEX_CHARS[b]);
75     }
76     return str;
77 }
78 
ArrayCopy(const unsigned char * src,int srcPos,unsigned char * dest,int destPos,int length)79 void SIMUtils::ArrayCopy(const unsigned char *src, int srcPos, unsigned char *dest, int destPos, int length)
80 {
81     src += srcPos;
82     dest += destPos;
83     for (int i = 0; i < length; i++) {
84         dest[i] = src[i];
85     }
86 }
87 
IsShowableAscii(char c)88 bool SIMUtils::IsShowableAscii(char c)
89 {
90     char asciiFirst = 0x20;
91     char asciiLast = 0x7E;
92     return (asciiFirst <= c && c <= asciiLast) || c == '\r' || c == '\n';
93 }
94 
IsShowableAsciiOnly(const std::string & str)95 bool SIMUtils::IsShowableAsciiOnly(const std::string &str)
96 {
97     int len = static_cast<int>(str.length());
98     for (int i = 0; i < len; i++) {
99         if (!IsShowableAscii(str.at(i))) {
100             return false;
101         }
102     }
103     return true;
104 }
105 
CharsConvertToChar16(const unsigned char * charBytes,int charBytesLen,int & outChar16Len,bool bigEndian)106 std::shared_ptr<char16_t> SIMUtils::CharsConvertToChar16(
107     const unsigned char *charBytes, int charBytesLen, int &outChar16Len, bool bigEndian)
108 {
109     if (charBytes == nullptr || charBytesLen == 0) {
110         return nullptr;
111     }
112 
113     int id = 0;
114     if (charBytesLen % HALF_LEN != 0) {
115         return nullptr;
116     }
117 
118     int outLen = charBytesLen / HALF_LEN;
119     outChar16Len = outLen;
120     if (outChar16Len == 0) {
121         return nullptr;
122     }
123     char16_t *cache = (char16_t *)calloc(outLen + 1, sizeof(char16_t));
124     if (cache == nullptr) {
125         return nullptr;
126     }
127     (void)memset_s(cache, (outLen + 1) * sizeof(char16_t), 0, (outLen + 1) * sizeof(char16_t));
128     std::shared_ptr<char16_t> ptr(cache, [](char16_t *ptr) { free(ptr); });
129     char16_t *ret = ptr.get();
130     for (int i = 0; i < charBytesLen; i += HALF_LEN) {
131         id = i / HALF_LEN;
132         char16_t high = charBytes[i];
133         char16_t low = charBytes[i + 1];
134         if (bigEndian) {
135             ret[id] = (char16_t)((high << BYTE_LENGTH) | low);
136         } else {
137             ret[id] = (char16_t)((low << BYTE_LENGTH) | high);
138         }
139     }
140     return ptr;
141 }
142 
BcdPlmnConvertToString(const std::string & data,int offset)143 std::string SIMUtils::BcdPlmnConvertToString(const std::string &data, int offset)
144 {
145     std::string plmn = "";
146     if (static_cast<int>(data.size()) >= (offset + MCCMNC_LEN) && data.at(offset) != 'F') {
147         plmn.push_back(data[offset + BCD_PLMN_MCC1]);
148         plmn.push_back(data[offset + BCD_PLMN_MCC2]);
149         plmn.push_back(data[offset + BCD_PLMN_MCC3]);
150         plmn.push_back(data[offset + BCD_PLMN_MNC1]);
151         plmn.push_back(data[offset + BCD_PLMN_MNC2]);
152         if (data.at(offset + BCD_PLMN_MNC3) != 'F') {
153             plmn.push_back(data[offset + BCD_PLMN_MNC3]);
154         }
155     }
156     return plmn;
157 }
158 
Gsm7bitConvertToString(const unsigned char * bytes,int byteLen)159 std::string SIMUtils::Gsm7bitConvertToString(const unsigned char *bytes, int byteLen)
160 {
161     std::string str = "";
162     int i = 0;
163     int n = 0;
164     int pos = 0;
165     int left = 0;
166     uint8_t high = 0;
167     uint8_t low = 0;
168     left = BYTE_LENGTH;
169     n = (byteLen * BYTE_LENGTH) / CHAR_GSM_7BIT;
170     TELEPHONY_LOGI("Gsm7bitConvertToString byteLen:%{public}d", byteLen);
171     for (i = 0; i < n; i++) {
172         if (left == BYTE_LENGTH) {
173             str.push_back(bytes[pos] & (~(0xFF << (CHAR_GSM_7BIT))));
174             left -= CHAR_GSM_7BIT;
175         } else if (left == CHAR_GSM_7BIT) {
176             str.push_back((bytes[pos] & (0xFF << (BYTE_LENGTH - left))) >> (BYTE_LENGTH - left));
177             left = BYTE_LENGTH;
178             pos++;
179         } else {
180             low = (bytes[pos] & (unsigned char)(0xFF << (BYTE_LENGTH - left))) >> (BYTE_LENGTH - left);
181             high = (bytes[pos + 1] & (unsigned char)(~(0xFF << (CHAR_GSM_7BIT - left)))) << left;
182             str.push_back(high | low);
183             left = BYTE_LENGTH - (CHAR_GSM_7BIT - left);
184             pos++;
185         }
186     }
187     TELEPHONY_LOGI("Gsm7bitConvertToString str:%{public}s", str.c_str());
188     return str;
189 }
190 
DiallingNumberStringFieldConvertToString(std::shared_ptr<unsigned char> array,int offset,int length,int offPos)191 std::string SIMUtils::DiallingNumberStringFieldConvertToString(
192     std::shared_ptr<unsigned char> array, int offset, int length, int offPos)
193 {
194     if (offset >= length || offset < 0 || array == nullptr) {
195         return "";
196     }
197     unsigned char *data = array.get();
198     std::u16string hs = u"";
199     TELEPHONY_LOGI("DiallingNumberStringFieldToString: start 16be decode");
200     if (data[offset] == static_cast<unsigned char>(CHINESE_FLAG)) {
201         int ucslen = (length - 1) / HALF_LEN;
202         int outlen = 0;
203         std::shared_ptr<char16_t> cs = CharsConvertToChar16(data + 1, ucslen * HALF_LEN, outlen, true);
204         hs = std::u16string(cs.get(), 0, outlen);
205     }
206     if (length >= START_POS && data[offset] == static_cast<unsigned char>(UCS_FLAG)) {
207         hs = UcsConvertToString(data, length, offset);
208     }
209     if (length >= END_POS && data[offset] == static_cast<unsigned char>(UCS_WIDE_FLAG)) {
210         hs = UcsWideConvertToString(data, length, offset);
211     }
212     if (!hs.empty()) {
213         int ucslen = static_cast<int>(hs.length());
214         wchar_t c = L'\uFFFF';
215         while (ucslen > 0 && hs.at(ucslen - 1) == c) {
216             ucslen--;
217         }
218         std::u16string rtl = hs.substr(0, ucslen);
219         std::string uz = Str16ToStr8(hs);
220         std::string ns = Str16ToStr8(rtl);
221         return ns;
222     }
223     return Decode8BitConvertToString(data, length, offset);
224 }
225 
UcsConvertToString(unsigned char * data,int length,int offset)226 std::u16string SIMUtils::UcsConvertToString(unsigned char *data, int length, int offset)
227 {
228     if (data == nullptr || length <= offset + 1) {
229         return u"";
230     }
231     int len = data[offset + 1] & BYTE_VALUE;
232     if (len > length - START_POS) {
233         len = length - START_POS;
234     }
235     if (len <= 0) {
236         return u"";
237     }
238     unsigned char* dataUsc = new unsigned char[len * HALF_LEN]{ FF_DATA };
239     int index = 0;
240     int base = 0;
241     int dataOffset = UCS_OFFSET;
242     while (index < len * HALF_LEN && offset + dataOffset < length) {
243         if ((data[offset + dataOffset] & F0_DATA) > 0) {
244             base = (data[offset + UCS_BASE_POS] & BYTE_VALUE) << BYTE_LESS;
245         } else {
246             base = ZERO_DATA;
247         }
248         int dataDouble = base + (data[offset + dataOffset] & SEVENF_DATA);
249         dataUsc[index] = dataDouble / HEX_HUNDRE;
250         dataUsc[index + 1] = dataDouble % HEX_HUNDRE;
251         dataOffset++;
252         index = index + HALF_LEN;
253     }
254     int outlen = 0;
255     std::shared_ptr<char16_t> cs = CharsConvertToChar16(dataUsc, len * HALF_LEN, outlen, true);
256     delete[] dataUsc;
257     dataUsc = nullptr;
258     if (cs == nullptr) {
259         TELEPHONY_LOGE("cs is nullptr");
260         return u"";
261     }
262     return std::u16string(cs.get(), 0, outlen);
263 }
264 
UcsWideConvertToString(unsigned char * data,int length,int offset)265 std::u16string SIMUtils::UcsWideConvertToString(unsigned char *data, int length, int offset)
266 {
267     if (data == nullptr || length <= offset + 1) {
268         return u"";
269     }
270     int len = data[offset + 1] & BYTE_VALUE;
271     if (len > length - END_POS) {
272         len = length - END_POS;
273     }
274     if (len <= 0) {
275         return u"";
276     }
277     int base = (data[offset + UCS_BASE_POS] << BYTE_BIT) + data[offset + UCS_BASE_POS + 1];
278     unsigned char* dataUsc = new unsigned char[len * HALF_LEN]{ FF_DATA };
279     int dataOffset = UCS_WIDE_OFFSET;
280     int index = 0;
281     while (index < len * HALF_LEN && offset + dataOffset < length) {
282         if ((data[offset + dataOffset] & F0_DATA) > 0) {
283             int dataDouble = base + (data[offset + dataOffset] & SEVENF_DATA);
284             dataUsc[index] = dataDouble / HEX_HUNDRE;
285             dataUsc[index + 1] = dataDouble % HEX_HUNDRE;
286         } else {
287             dataUsc[index] = ZERO_DATA;
288             dataUsc[index + 1] = data[offset + dataOffset];
289         }
290         index = index + HALF_LEN;
291         dataOffset++;
292     }
293     int outlen = 0;
294     std::shared_ptr<char16_t> cs = CharsConvertToChar16(dataUsc, len * HALF_LEN, outlen, true);
295     delete[] dataUsc;
296     dataUsc = nullptr;
297     if (cs == nullptr) {
298         TELEPHONY_LOGE("cs is nullptr");
299         return u"";
300     }
301     return std::u16string(cs.get(), 0, outlen);
302 }
303 
Decode8BitConvertToString(unsigned char * data,int length,int offset)304 std::string SIMUtils::Decode8BitConvertToString(unsigned char *data, int length, int offset)
305 {
306     if (data == nullptr || length <= offset + 1 || offset < 0) {
307         return "";
308     }
309     int i = 0;
310     for (i = offset; i < length; i++) {
311         int c = data[i] & BYTE_VALUE;
312         if (c == BYTE_VALUE) {
313             break;
314         }
315     }
316     i -= offset;
317     std::string str(reinterpret_cast<char *>(data), offset, i);
318     return str;
319 }
320 
Trim(std::string & str)321 std::string SIMUtils::Trim(std::string &str)
322 {
323     string::size_type pos = str.find_last_not_of(' ');
324     if (pos != string::npos) {
325         str.erase(pos + POS_NOT_BLANK);
326         pos = str.find_first_not_of(' ');
327         if (pos != string::npos) {
328             str.erase(0, pos);
329         }
330     } else {
331         str.erase(str.begin(), str.end());
332     }
333     return str;
334 }
335 } // namespace Telephony
336 } // namespace OHOS
337