• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <sstream>
17 #include "sim_utils.h"
18 
19 #include "str_convert.h"
20 
21 using namespace std;
22 
23 namespace OHOS {
24 namespace Telephony {
25 
26 static const uint8_t WORD_LEN = 2;
27 
HexCharConvertToInt(char c)28 unsigned char SIMUtils::HexCharConvertToInt(char c)
29 {
30     if (c >= '0' && c <= '9') {
31         return (c - '0');
32     } else if (c >= 'A' && c <= 'F') {
33         return (c - 'A' + DECIMAL_MAX);
34     } else if (c >= 'a' && c <= 'f') {
35         return (c - 'a' + DECIMAL_MAX);
36     }
37     return 0;
38 }
39 
HexStringConvertToBytes(const std::string & s,int & byteslen)40 std::shared_ptr<unsigned char> SIMUtils::HexStringConvertToBytes(const std::string &s, int &byteslen)
41 {
42     if (s.empty()) {
43         return nullptr;
44     }
45     int id = 0;
46     int sz = static_cast<int>(s.length());
47     if (sz % HALF_LEN != 0) {
48         return nullptr;
49     }
50     int outlen = sz / HALF_LEN;
51     byteslen = outlen;
52     if (outlen == 0) {
53         return nullptr;
54     }
55     unsigned char *cache = (unsigned char *)calloc(outlen + 1, sizeof(unsigned char));
56     if (cache == nullptr) {
57         return nullptr;
58     }
59     (void)memset_s(cache, (outlen + 1) * sizeof(unsigned char), 0, (outlen + 1) * sizeof(unsigned char));
60     std::shared_ptr<unsigned char> ptr(cache, [](unsigned char *ptr) { free(ptr); });
61     unsigned char *ret = ptr.get();
62     for (int i = 0; i < sz; i += HALF_LEN) {
63         id = i / HALF_LEN;
64         ret[id] = (unsigned char)((HexCharConvertToInt(s.at(i)) << HALF_BYTE_LEN) | HexCharConvertToInt(s.at(i + 1)));
65     }
66     return ptr;
67 }
68 
BytesConvertToHexString(const unsigned char * bytes,int byteLen)69 std::string SIMUtils::BytesConvertToHexString(const unsigned char *bytes, int byteLen)
70 {
71     if (bytes == nullptr) {
72         return "";
73     }
74     std::string str = "";
75     for (int i = 0; i < byteLen; i++) {
76         int b = 0;
77         b = 0x0f & (bytes[i] >> HALF_BYTE_LEN);
78         str.push_back(HEX_CHARS[b]);
79         b = 0x0f & bytes[i];
80         str.push_back(HEX_CHARS[b]);
81     }
82     return str;
83 }
84 
ArrayCopy(const unsigned char * src,int srcPos,unsigned char * dest,int destPos,int length)85 void SIMUtils::ArrayCopy(const unsigned char *src, int srcPos, unsigned char *dest, int destPos, int length)
86 {
87     src += srcPos;
88     dest += destPos;
89     for (int i = 0; i < length; i++) {
90         dest[i] = src[i];
91     }
92 }
93 
IsShowableAscii(char c)94 bool SIMUtils::IsShowableAscii(char c)
95 {
96     char asciiFirst = 0x20;
97     char asciiLast = 0x7E;
98     return (asciiFirst <= c && c <= asciiLast) || c == '\r' || c == '\n';
99 }
100 
IsShowableAsciiOnly(const std::string & str)101 bool SIMUtils::IsShowableAsciiOnly(const std::string &str)
102 {
103     int len = static_cast<int>(str.length());
104     for (int i = 0; i < len; i++) {
105         if (!IsShowableAscii(str.at(i))) {
106             return false;
107         }
108     }
109     return true;
110 }
111 
CharsConvertToChar16(const unsigned char * charBytes,int charBytesLen,int & outChar16Len,bool bigEndian)112 std::shared_ptr<char16_t> SIMUtils::CharsConvertToChar16(
113     const unsigned char *charBytes, int charBytesLen, int &outChar16Len, bool bigEndian)
114 {
115     if (charBytes == nullptr || charBytesLen == 0) {
116         return nullptr;
117     }
118 
119     int id = 0;
120     if (charBytesLen % HALF_LEN != 0) {
121         return nullptr;
122     }
123 
124     int outLen = charBytesLen / HALF_LEN;
125     outChar16Len = outLen;
126     if (outChar16Len == 0) {
127         return nullptr;
128     }
129     char16_t *cache = (char16_t *)calloc(outLen + 1, sizeof(char16_t));
130     if (cache == nullptr) {
131         return nullptr;
132     }
133     (void)memset_s(cache, (outLen + 1) * sizeof(char16_t), 0, (outLen + 1) * sizeof(char16_t));
134     std::shared_ptr<char16_t> ptr(cache, [](char16_t *ptr) { free(ptr); });
135     char16_t *ret = ptr.get();
136     for (int i = 0; i < charBytesLen; i += HALF_LEN) {
137         id = i / HALF_LEN;
138         char16_t high = charBytes[i];
139         char16_t low = charBytes[i + 1];
140         if (bigEndian) {
141             ret[id] = (char16_t)((high << BYTE_LENGTH) | low);
142         } else {
143             ret[id] = (char16_t)((low << BYTE_LENGTH) | high);
144         }
145     }
146     return ptr;
147 }
148 
BcdPlmnConvertToString(const std::string & data,int offset)149 std::string SIMUtils::BcdPlmnConvertToString(const std::string &data, int offset)
150 {
151     std::string plmn = "";
152     if (static_cast<int>(data.size()) >= (offset + MCCMNC_LEN) && data.at(offset) != 'F') {
153         plmn.push_back(data[offset + BCD_PLMN_MCC1]);
154         plmn.push_back(data[offset + BCD_PLMN_MCC2]);
155         plmn.push_back(data[offset + BCD_PLMN_MCC3]);
156         plmn.push_back(data[offset + BCD_PLMN_MNC1]);
157         plmn.push_back(data[offset + BCD_PLMN_MNC2]);
158         if (data.at(offset + BCD_PLMN_MNC3) != 'F') {
159             plmn.push_back(data[offset + BCD_PLMN_MNC3]);
160         }
161     }
162     return plmn;
163 }
164 
Gsm7bitConvertToString(const unsigned char * bytes,int byteLen)165 std::string SIMUtils::Gsm7bitConvertToString(const unsigned char *bytes, int byteLen)
166 {
167     std::wstring wide_str = L"";
168     int i = 0;
169     int n = 0;
170     int pos = 0;
171     int left = 0;
172     uint8_t high = 0;
173     uint8_t low = 0;
174     uint8_t gsmVal = 0;
175     left = BYTE_LENGTH;
176     n = (byteLen * BYTE_LENGTH) / CHAR_GSM_7BIT;
177     TELEPHONY_LOGI("Gsm7bitConvertToString byteLen:%{public}d", byteLen);
178     for (i = 0; i < n; i++) {
179         if (left == BYTE_LENGTH) {
180             gsmVal = bytes[pos] & (~(0xFF << (CHAR_GSM_7BIT)));
181             left -= CHAR_GSM_7BIT;
182         } else if (left == CHAR_GSM_7BIT) {
183             gsmVal = (bytes[pos] & (0xFF << (BYTE_LENGTH - left))) >> (BYTE_LENGTH - left);
184             left = BYTE_LENGTH;
185             pos++;
186         } else {
187             low = (bytes[pos] & (unsigned char)(0xFF << (BYTE_LENGTH - left))) >> (BYTE_LENGTH - left);
188             high = (bytes[pos + 1] & (unsigned char)(~(0xFF << (CHAR_GSM_7BIT - left)))) << left;
189             gsmVal = low | high;
190             left = BYTE_LENGTH - (CHAR_GSM_7BIT - left);
191             pos++;
192         }
193         int gsmValIndex = static_cast<int>(gsmVal);
194         if (gsmValIndex < 0 || gsmValIndex >= 129) { // 129 is gsm val index max
195             continue;
196         }
197         wchar_t c = LANGUAGE_TABLE[gsmValIndex];
198         wide_str += c;
199     }
200     if (byteLen > 0 && byteLen % CHAR_GSM_7BIT == 0) {
201         wide_str = static_cast<int>(bytes[byteLen - 1]) > 1 ? wide_str : wide_str.substr(0, n);
202     } else {
203         wide_str = wide_str.substr(0, n);
204     }
205     TELEPHONY_LOGI("Gsm7bitConvertToString str:%{public}s", ToUtf8(wide_str).c_str());
206     return ToUtf8(wide_str);
207 }
208 
Cphs7bitConvertToString(const std::string & rawData)209 std::string SIMUtils::Cphs7bitConvertToString(const std::string &rawData)
210 {
211     if (rawData.empty()) {
212         return "";
213     }
214     const char *bytes = rawData.c_str();
215     std::wstring wide_str = L"";
216     int high = 0;
217     int low = 0;
218     int gsmVal = 0;
219     int byteLen = strlen(bytes);
220     bool escTag = false;
221     wchar_t c;
222     for (int i = 0; i < byteLen; i++) {
223         low = (int)HexCharConvertToInt(bytes[i]);
224         if (i + 1 < byteLen) {
225             high = (int)HexCharConvertToInt(bytes[i + 1]);
226         } else {
227             break;
228         }
229         gsmVal = low * 16 + high; // 16 is the hex val max
230         i++;
231         if (gsmVal < 0 || gsmVal >= static_cast<int>(sizeof(LANGUAGE_TABLE) / sizeof(LANGUAGE_TABLE[0]))) {
232             continue;
233         }
234         if (!escTag && gsmVal == 0x1B) { // 1B is the ESC tag refer to GSM 03.38;
235             escTag = true;
236             continue;
237         } else if (escTag && gsmVal == 0x1B) { // Two escape chars in a row We treat this as a space
238                                                // See Note 1 in table 6.2.1 of TS 23.038 v7.00
239             escTag = false;
240             c = ' ';
241             wide_str += c;
242             continue;
243         }
244         if (escTag == true) {
245             if (LANGUAGE_EXT_TABLE_MAP.find(gsmVal) != LANGUAGE_EXT_TABLE_MAP.end()) {
246                 c = LANGUAGE_EXT_TABLE_MAP.at(gsmVal);
247                 wide_str += c;
248             } else {
249                 c = LANGUAGE_TABLE[gsmVal];
250                 wide_str += c;
251             }
252             escTag = false;
253         } else {
254             c = LANGUAGE_TABLE[gsmVal];
255             wide_str += c;
256         }
257     }
258     TELEPHONY_LOGI("Cphs7bitConvertToString str:%{public}s", ToUtf8(wide_str).c_str());
259     return ToUtf8(wide_str);
260 }
261 
HexVecToHexStr(const std::vector<uint8_t> & arr)262 std::string SIMUtils::HexVecToHexStr(const std::vector<uint8_t> &arr)
263 {
264     std::stringstream ss;
265     for (auto it = arr.begin(); it != arr.end(); it++) {
266         ss << std::setiosflags(std::ios::uppercase) << std::hex << std::setw(WORD_LEN) << std::setfill('0') << int(*it);
267     }
268     return ss.str();
269 }
270 
DiallingNumberStringFieldConvertToString(std::shared_ptr<unsigned char> array,int offset,int length,int offPos)271 std::string SIMUtils::DiallingNumberStringFieldConvertToString(
272     std::shared_ptr<unsigned char> array, int offset, int length, int offPos)
273 {
274     if (offset >= length || offset < 0 || array == nullptr) {
275         return "";
276     }
277     unsigned char *data = array.get();
278     std::u16string hs = u"";
279     if (data[offset] == static_cast<unsigned char>(CHINESE_FLAG)) {
280         int ucslen = (length - 1) / HALF_LEN;
281         int outlen = 0;
282         std::shared_ptr<char16_t> cs = CharsConvertToChar16(data + 1, ucslen * HALF_LEN, outlen, true);
283         hs = std::u16string(cs.get(), 0, outlen);
284     }
285     if (length >= START_POS && data[offset] == static_cast<unsigned char>(UCS_FLAG)) {
286         hs = UcsConvertToString(data, length, offset);
287     }
288     if (length >= END_POS && data[offset] == static_cast<unsigned char>(UCS_WIDE_FLAG)) {
289         hs = UcsWideConvertToString(data, length, offset);
290     }
291     if (!hs.empty()) {
292         int ucslen = static_cast<int>(hs.length());
293         wchar_t c = L'\uFFFF';
294         while (ucslen > 0 && hs.at(ucslen - 1) == c) {
295             ucslen--;
296         }
297         std::u16string rtl = hs.substr(0, ucslen);
298         std::string uz = Str16ToStr8(hs);
299         std::string ns = Str16ToStr8(rtl);
300         return ns;
301     }
302     std::string tempData = SIMUtils::BytesConvertToHexString(data, length);
303     return Cphs7bitConvertToString(tempData);
304 }
305 
UcsConvertToString(unsigned char * data,int length,int offset)306 std::u16string SIMUtils::UcsConvertToString(unsigned char *data, int length, int offset)
307 {
308     if (data == nullptr || length <= offset + 1) {
309         return u"";
310     }
311     int len = data[offset + 1] & BYTE_VALUE;
312     if (len > length - START_POS) {
313         len = length - START_POS;
314     }
315     if (len <= 0) {
316         return u"";
317     }
318     unsigned char* dataUsc = new unsigned char[len * HALF_LEN]{ FF_DATA };
319     int index = 0;
320     int base = 0;
321     int dataOffset = UCS_OFFSET;
322     while (index < len * HALF_LEN && offset + dataOffset < length) {
323         if ((data[offset + dataOffset] & F0_DATA) > 0) {
324             base = (data[offset + UCS_BASE_POS] & BYTE_VALUE) << BYTE_LESS;
325         } else {
326             base = ZERO_DATA;
327         }
328         int dataDouble = base + (data[offset + dataOffset] & SEVENF_DATA);
329         dataUsc[index] = dataDouble / HEX_HUNDRE;
330         dataUsc[index + 1] = dataDouble % HEX_HUNDRE;
331         dataOffset++;
332         index = index + HALF_LEN;
333     }
334     int outlen = 0;
335     std::shared_ptr<char16_t> cs = CharsConvertToChar16(dataUsc, len * HALF_LEN, outlen, true);
336     delete[] dataUsc;
337     dataUsc = nullptr;
338     if (cs == nullptr) {
339         TELEPHONY_LOGE("cs is nullptr");
340         return u"";
341     }
342     return std::u16string(cs.get(), 0, outlen);
343 }
344 
UcsWideConvertToString(unsigned char * data,int length,int offset)345 std::u16string SIMUtils::UcsWideConvertToString(unsigned char *data, int length, int offset)
346 {
347     if (data == nullptr || length <= offset + 1) {
348         return u"";
349     }
350     int len = data[offset + 1] & BYTE_VALUE;
351     if (len > length - END_POS) {
352         len = length - END_POS;
353     }
354     if (len <= 0) {
355         return u"";
356     }
357     int base = (data[offset + UCS_BASE_POS] << BYTE_BIT) + data[offset + UCS_BASE_POS + 1];
358     unsigned char* dataUsc = new unsigned char[len * HALF_LEN]{ FF_DATA };
359     int dataOffset = UCS_WIDE_OFFSET;
360     int index = 0;
361     while (index < len * HALF_LEN && offset + dataOffset < length) {
362         if ((data[offset + dataOffset] & F0_DATA) > 0) {
363             int dataDouble = base + (data[offset + dataOffset] & SEVENF_DATA);
364             dataUsc[index] = dataDouble / HEX_HUNDRE;
365             dataUsc[index + 1] = dataDouble % HEX_HUNDRE;
366         } else {
367             dataUsc[index] = ZERO_DATA;
368             dataUsc[index + 1] = data[offset + dataOffset];
369         }
370         index = index + HALF_LEN;
371         dataOffset++;
372     }
373     int outlen = 0;
374     std::shared_ptr<char16_t> cs = CharsConvertToChar16(dataUsc, len * HALF_LEN, outlen, true);
375     delete[] dataUsc;
376     dataUsc = nullptr;
377     if (cs == nullptr) {
378         TELEPHONY_LOGE("cs is nullptr");
379         return u"";
380     }
381     return std::u16string(cs.get(), 0, outlen);
382 }
383 
Decode8BitConvertToString(unsigned char * data,int length,int offset)384 std::string SIMUtils::Decode8BitConvertToString(unsigned char *data, int length, int offset)
385 {
386     if (data == nullptr || length <= offset + 1 || offset < 0) {
387         return "";
388     }
389     int i = 0;
390     for (i = offset; i < length; i++) {
391         int c = data[i] & BYTE_VALUE;
392         if (c == BYTE_VALUE) {
393             break;
394         }
395     }
396     i -= offset;
397     std::string str(reinterpret_cast<char *>(data), offset, i);
398     TELEPHONY_LOGI("Decode8BitConvertToString str:%{public}s", str.c_str());
399     return str;
400 }
401 
Trim(std::string & str)402 std::string SIMUtils::Trim(std::string &str)
403 {
404     string::size_type pos = str.find_last_not_of(' ');
405     if (pos != string::npos) {
406         str.erase(pos + POS_NOT_BLANK);
407         pos = str.find_first_not_of(' ');
408         if (pos != string::npos) {
409             str.erase(0, pos);
410         }
411     } else {
412         str.erase(str.begin(), str.end());
413     }
414     return str;
415 }
416 } // namespace Telephony
417 } // namespace OHOS
418