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 ConvertTo 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 = 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, sizeof(unsigned char));
50 if (cache == nullptr) {
51 return nullptr;
52 }
53 std::shared_ptr<unsigned char> ptr(cache, [](unsigned char *ptr) { free(ptr); });
54 unsigned char *ret = ptr.get();
55 for (int i = 0; i < sz; i += HALF_LEN) {
56 id = i / HALF_LEN;
57 ret[id] =
58 (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 int asciiFirst = 0x20;
91 int 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 = 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, sizeof(char16_t));
124 if (cache == nullptr) {
125 return nullptr;
126 }
127 std::shared_ptr<char16_t> ptr(cache, [](char16_t *ptr) { free(ptr); });
128 char16_t *ret = ptr.get();
129 for (int i = 0; i < charBytesLen; i += HALF_LEN) {
130 id = i / HALF_LEN;
131 char16_t high = charBytes[i];
132 char16_t low = charBytes[i + 1];
133 if (bigEndian) {
134 ret[id] = (char16_t)((high << BYTE_LENGTH) | low);
135 } else {
136 ret[id] = (char16_t)((low << BYTE_LENGTH) | high);
137 }
138 }
139 return ptr;
140 }
141
BcdPlmnConvertToString(const std::string & data,int offset)142 std::string SIMUtils::BcdPlmnConvertToString(const std::string &data, int offset)
143 {
144 (void)data;
145 (void)offset;
146 return "";
147 }
148
DiallingNumberStringFieldConvertToString(std::shared_ptr<unsigned char> array,int offset,int length,int offPos)149 std::string SIMUtils::DiallingNumberStringFieldConvertToString(
150 std::shared_ptr<unsigned char> array, int offset, int length, int offPos)
151 {
152 if (length <= 0 || array == nullptr) {
153 return "";
154 }
155 unsigned char *data = array.get();
156
157 if (data[offset] == (unsigned char)CHINESE_FLAG) {
158 TELEPHONY_LOGI("DiallingNumberStringFieldToString: start 16be decode");
159 int ucslen = (length - 1) / HALF_LEN;
160 int outlen = 0;
161 std::shared_ptr<char16_t> cs = CharsConvertToChar16(data + 1, ucslen * HALF_LEN, outlen, true);
162 std::string ns = "";
163 std::u16string hs(cs.get(), 0, outlen);
164 std::u16string rtl = u"";
165 if (!hs.empty()) {
166 ucslen = hs.length();
167 wchar_t c = L'\uFFFF';
168 while (ucslen > 0 && hs.at(ucslen - 1) == c) {
169 ucslen--;
170 }
171 rtl = hs.substr(0, ucslen);
172 std::string uz = Str16ToStr8(hs);
173 ns = Str16ToStr8(rtl);
174 TELEPHONY_LOGI("16be result %{public}s, %{public}s", uz.c_str(), ns.c_str());
175 return ns;
176 }
177 } else {
178 int i = 0;
179 for (i = offset; i < offset + length; i++) {
180 int c = data[i] & BYTE_VALUE;
181 if (c == BYTE_VALUE) {
182 break;
183 }
184 }
185 i -= offset;
186 std::string str((char *)data, offset, i);
187 TELEPHONY_LOGI("8bit decode result");
188 if (!str.empty()) {
189 return str;
190 }
191 }
192 return UcsCodeConvertToString(array, offset, length, offPos);
193 }
194
UcsCodeConvertToString(std::shared_ptr<unsigned char> array,int offset,int length,int offPos)195 std::string SIMUtils::UcsCodeConvertToString(
196 std::shared_ptr<unsigned char> array, int offset, int length, int offPos)
197 {
198 bool isucs2 = false;
199 char base = '\0';
200 int len = 0;
201 unsigned char *data = array.get();
202 if (length >= START_POS && data[offset] == (unsigned char)UCS_FLAG) {
203 len = data[offset + 1] & BYTE_VALUE;
204 if (len > length - START_POS) {
205 len = length - START_POS;
206 }
207 base = (char)((data[offset + HALF_LEN] & BYTE_VALUE) << BYTE_LESS);
208 offset += START_POS;
209 isucs2 = true;
210 } else if (length >= END_POS && data[offset] == (unsigned char)UCS_WIDE_FLAG) {
211 len = data[offset + 1] & BYTE_VALUE;
212 if (len > length - END_POS)
213 len = length - END_POS;
214
215 base =
216 (char)(((data[offset + HALF_LEN] & BYTE_VALUE) << BYTE_BIT) | (data[offset + START_POS] & BYTE_VALUE));
217 offset += END_POS;
218 isucs2 = true;
219 }
220
221 if (isucs2) {
222 std::string retuc = "";
223 while (len > 0) {
224 if (data[offset] < 0) {
225 retuc.push_back((char)(base + (data[offset] & 0x7F)));
226 offset++;
227 len--;
228 }
229 int count = 0;
230 int id = offset + count;
231 while ((count < len) && (data[id] >= 0)) {
232 count++;
233 id = offset + count;
234 }
235 TELEPHONY_LOGI("start 8bit decode");
236 offset += count;
237 len -= count;
238 }
239 TELEPHONY_LOGI("isucs2 decode result %{public}s", retuc.c_str());
240 return retuc;
241 }
242
243 std::string defaultCharset = "";
244 TELEPHONY_LOGI("UcsCodeConvertToString finished");
245 return defaultCharset;
246 }
247
Trim(std::string & str)248 std::string SIMUtils::Trim(std::string& str)
249 {
250 string::size_type pos = str.find_last_not_of(' ');
251 if (pos != string::npos) {
252 str.erase(pos + POS_NOT_BLANK);
253 pos = str.find_first_not_of(' ');
254 if (pos != string::npos) {
255 str.erase(0, pos);
256 }
257 } else {
258 str.erase(str.begin(), str.end());
259 }
260 return str;
261 }
262 } // namespace Telephony
263 } // namespace OHOS