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