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 (length <= offset || 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 TELEPHONY_LOGD("16be result %{public}s, %{public}s", uz.c_str(), ns.c_str());
222 return ns;
223 }
224 return Decode8BitConvertToString(data, length, offset);
225 }
226
UcsConvertToString(unsigned char * data,int length,int offset)227 std::u16string SIMUtils::UcsConvertToString(unsigned char *data, int length, int offset)
228 {
229 if (length <= offset + 1) {
230 return u"";
231 }
232 int len = data[offset + 1] & BYTE_VALUE;
233 if (len > length - START_POS) {
234 len = length - START_POS;
235 }
236 unsigned char dataUsc[MAX_ENGLISH_NAME * HALF_LEN] = { FF_DATA };
237 int index = 0;
238 int base = 0;
239 int dataOffset = UCS_OFFSET;
240 while (index < len * HALF_LEN && offset + dataOffset < length) {
241 if ((data[offset + dataOffset] & F0_DATA) > 0) {
242 base = (data[offset + UCS_BASE_POS] & BYTE_VALUE) << BYTE_LESS;
243 } else {
244 base = ZERO_DATA;
245 }
246 int dataDouble = base + (data[offset + dataOffset] & SEVENF_DATA);
247 dataUsc[index] = dataDouble / HEX_HUNDRE;
248 dataUsc[index + 1] = dataDouble % HEX_HUNDRE;
249 dataOffset++;
250 index = index + HALF_LEN;
251 }
252 int outlen = 0;
253 std::shared_ptr<char16_t> cs = CharsConvertToChar16(dataUsc, MAX_ENGLISH_NAME * HALF_LEN, outlen, true);
254 return std::u16string(cs.get(), 0, outlen);
255 }
256
UcsWideConvertToString(unsigned char * data,int length,int offset)257 std::u16string SIMUtils::UcsWideConvertToString(unsigned char *data, int length, int offset)
258 {
259 if (length <= offset + 1) {
260 return u"";
261 }
262 int len = data[offset + 1] & BYTE_VALUE;
263 if (len > length - END_POS) {
264 len = length - END_POS;
265 }
266 int base = (data[offset + UCS_BASE_POS] << BYTE_BIT) + data[offset + UCS_BASE_POS + 1];
267 unsigned char dataUsc[MAX_ENGLISH_NAME * HALF_LEN] = { FF_DATA };
268 int dataOffset = UCS_WIDE_OFFSET;
269 int index = 0;
270 while (index < len * HALF_LEN && offset + dataOffset < length) {
271 if ((data[offset + dataOffset] & F0_DATA) > 0) {
272 int dataDouble = base + (data[offset + dataOffset] & SEVENF_DATA);
273 dataUsc[index] = dataDouble / HEX_HUNDRE;
274 dataUsc[index + 1] = dataDouble % HEX_HUNDRE;
275 } else {
276 dataUsc[index] = ZERO_DATA;
277 dataUsc[index + 1] = data[offset + dataOffset];
278 }
279 index = index + HALF_LEN;
280 dataOffset++;
281 }
282 int outlen = 0;
283 std::shared_ptr<char16_t> cs = CharsConvertToChar16(dataUsc, MAX_ENGLISH_NAME * HALF_LEN, outlen, true);
284 return std::u16string(cs.get(), 0, outlen);
285 }
286
Decode8BitConvertToString(unsigned char * data,int length,int offset)287 std::string SIMUtils::Decode8BitConvertToString(unsigned char *data, int length, int offset)
288 {
289 int i = 0;
290 for (i = offset; i < offset + length; i++) {
291 int c = data[i] & BYTE_VALUE;
292 if (c == BYTE_VALUE) {
293 break;
294 }
295 }
296 i -= offset;
297 std::string str(reinterpret_cast<char *>(data), offset, i);
298 TELEPHONY_LOGI("8bit decode result");
299 return str;
300 }
301
Trim(std::string & str)302 std::string SIMUtils::Trim(std::string &str)
303 {
304 string::size_type pos = str.find_last_not_of(' ');
305 if (pos != string::npos) {
306 str.erase(pos + POS_NOT_BLANK);
307 pos = str.find_first_not_of(' ');
308 if (pos != string::npos) {
309 str.erase(0, pos);
310 }
311 } else {
312 str.erase(str.begin(), str.end());
313 }
314 return str;
315 }
316 } // namespace Telephony
317 } // namespace OHOS
318