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 "cellular_data_utils.h"
17
18 #include "telephony_common_utils.h"
19 #include "telephony_log_wrapper.h"
20
21 namespace OHOS {
22 namespace Telephony {
23 using namespace NetManagerStandard;
ParseIpAddr(const std::string & address)24 std::vector<AddressInfo> CellularDataUtils::ParseIpAddr(const std::string &address)
25 {
26 std::vector<AddressInfo> ipInfoArray;
27 std::vector<std::string> ipArray = Split(address, " ");
28 for (std::string &ipItem: ipArray) {
29 AddressInfo ipInfo;
30 std::string flag = (ipItem.find('.') == std::string::npos) ? ":" : ".";
31 std::vector<std::string> ipData = Split(ipItem, "/");
32 if (ipData.size() == 0) {
33 TELEPHONY_LOGE("ParseIpAddr ipData is empty");
34 continue;
35 }
36 ipInfo.ip = ipData[0];
37 if (flag == ".") {
38 std::vector<std::string> ipSubData = Split(ipInfo.ip, flag);
39 ipInfo.type = (ipSubData.size() > MIN_IPV4_ITEM) ? INetAddr::IpType::IPV6 : INetAddr::IpType::IPV4;
40 ipInfo.prefixLen = (ipSubData.size() > MIN_IPV4_ITEM) ? IPV6_BIT : IPV4_BIT;
41 } else {
42 ipInfo.type = INetAddr::IpType::IPV6;
43 ipInfo.prefixLen = IPV6_BIT;
44 }
45 if ((ipData.size() >= VALID_IP_SIZE) && IsValidDecValue(ipData[1].c_str())) {
46 ipInfo.prefixLen = std::stoi(ipData[1].c_str());
47 }
48 ipInfoArray.push_back(ipInfo);
49 }
50 return ipInfoArray;
51 }
52
ParseDotIpData(const std::string & address,AddressInfo & ipInfo)53 bool CellularDataUtils::ParseDotIpData(const std::string &address, AddressInfo &ipInfo)
54 {
55 bool bOnlyAddress = false;
56 int prefixLen = 0;
57 // a1.a2.a3.a4.m1.m2.m3.m4
58 // a1.a2.a3.a4.a5.a6.a7.a8.a9.a10.a11.a12.a13.a14.a15.a16.m1.m2.m3.m4.m5.m6.m7.m8.m9.m10.m11.m12.m13.m14.m15.m16
59 std::vector<std::string> ipSubData = Split(ipInfo.ip, ".");
60 if (ipSubData.size() > MIN_IPV6_ITEM) {
61 ipInfo.type = INetAddr::IpType::IPV6;
62 ipInfo.ip = ipSubData[0];
63 for (int32_t i = 1; i < MIN_IPV6_ITEM; ++i) {
64 ipInfo.ip += "." + ipSubData[i];
65 }
66 ipInfo.netMask = ipSubData[MIN_IPV6_ITEM];
67 for (size_t j = MIN_IPV6_ITEM; j < ipSubData.size(); ++j) {
68 ipInfo.netMask += "." + ipSubData[j];
69 }
70 prefixLen = GetPrefixLen(ipSubData, MIN_IPV6_ITEM);
71 } else if (ipSubData.size() > MAX_IPV4_ITEM) {
72 ipInfo.type = INetAddr::IpType::IPV6;
73 bOnlyAddress = true;
74 } else if (ipSubData.size() > MIN_IPV4_ITEM) {
75 ipInfo.type = INetAddr::IpType::IPV4;
76 ipInfo.ip = ipSubData[0];
77 for (int32_t i = 1; i < MIN_IPV4_ITEM; ++i) {
78 ipInfo.ip += "." + ipSubData[i];
79 }
80 ipInfo.netMask = ipSubData[MIN_IPV4_ITEM];
81 for (size_t j = MIN_IPV4_ITEM; j < ipSubData.size(); ++j) {
82 ipInfo.netMask += "." + ipSubData[j];
83 }
84 prefixLen = GetPrefixLen(ipSubData, MIN_IPV4_ITEM);
85 } else {
86 ipInfo.type = INetAddr::IpType::IPV4;
87 bOnlyAddress = true;
88 }
89 ipInfo.prefixLen = prefixLen;
90 return bOnlyAddress;
91 }
92
ParseNormalIpAddr(const std::string & address)93 std::vector<AddressInfo> CellularDataUtils::ParseNormalIpAddr(const std::string &address)
94 {
95 std::vector<AddressInfo> ipInfoArray;
96 std::vector<std::string> ipArray = Split(address, " ");
97 for (size_t i = 0; i < ipArray.size(); ++i) {
98 AddressInfo ipInfo;
99 if (ipArray[i].find(':') == std::string::npos) {
100 ipInfo.prefixLen = IPV4_BIT;
101 ipInfo.type = INetAddr::IpType::IPV4;
102 } else {
103 ipInfo.prefixLen = IPV6_BIT;
104 ipInfo.type = INetAddr::IpType::IPV6;
105 }
106 ipInfo.ip = ipArray[i];
107 ipInfoArray.push_back(ipInfo);
108 }
109 return ipInfoArray;
110 }
111
ParseRoute(const std::string & address)112 std::vector<RouteInfo> CellularDataUtils::ParseRoute(const std::string &address)
113 {
114 std::vector<RouteInfo> routeInfoArray;
115 std::vector<std::string> routeArray = Split(address, " ");
116 for (size_t i = 0; i < routeArray.size(); ++i) {
117 RouteInfo route;
118 if (routeArray[i].find(':') == std::string::npos) {
119 route.type = INetAddr::IpType::IPV4;
120 route.destination = ROUTED_IPV4;
121 } else {
122 route.type = INetAddr::IpType::IPV6;
123 route.destination = ROUTED_IPV6;
124 }
125 route.ip = routeArray[i];
126 routeInfoArray.push_back(route);
127 }
128 return routeInfoArray;
129 }
130
Split(const std::string & input,const std::string & flag)131 std::vector<std::string> CellularDataUtils::Split(const std::string &input, const std::string &flag)
132 {
133 std::vector<std::string> vec;
134 if (input.empty()) {
135 TELEPHONY_LOGE("input is null");
136 return vec;
137 }
138 std::string::size_type start = 0;
139 std::string::size_type pos = 0;
140 while ((pos = input.find(flag, start)) != std::string::npos) {
141 vec.push_back(input.substr(start, pos - start));
142 start = pos + flag.size();
143 }
144 if (start != input.size()) {
145 vec.push_back(input.substr(start, input.size() - start));
146 }
147 return vec;
148 }
149
IsDigit(const std::string & data)150 bool CellularDataUtils::IsDigit(const std::string &data)
151 {
152 if (data.empty()) {
153 TELEPHONY_LOGE("data is null");
154 return false;
155 }
156 for (size_t i = 0; i < data.size(); ++i) {
157 if (data[0] == '-') {
158 continue;
159 }
160 if (!isdigit(data[i])) {
161 TELEPHONY_LOGE("data %{public}s is not digit!", data.c_str());
162 return false;
163 }
164 }
165 return true;
166 }
167
GetPrefixLen(const std::string & netmask,const std::string & flag)168 int32_t CellularDataUtils::GetPrefixLen(const std::string &netmask, const std::string& flag)
169 {
170 std::vector<std::string> mask = Split(netmask, flag);
171 return GetPrefixLen(mask, 0);
172 }
173
GetPrefixLen(const std::vector<std::string> & netmask,const size_t start)174 int32_t CellularDataUtils::GetPrefixLen(const std::vector<std::string> &netmask, const size_t start)
175 {
176 int32_t prefixLen = 0;
177 for (size_t i = start; i < netmask.size(); ++i) {
178 if (!IsValidDecValue(netmask[i].c_str())) {
179 break;
180 }
181 int32_t maskValue = (std::stoi(netmask[i].c_str()) & 0x00FF);
182 if (maskValue == 0) {
183 break;
184 }
185 while ((maskValue & 0x80) != 0) {
186 prefixLen++;
187 maskValue = (maskValue << 1);
188 }
189 if ((prefixLen % MASK_BYTE_BIT) != 0) {
190 break;
191 }
192 }
193 return prefixLen;
194 }
195
GetDefaultMobileMtuConfig()196 int CellularDataUtils::GetDefaultMobileMtuConfig()
197 {
198 char mobile_mtu[MIN_BUFFER_SIZE] = {0};
199 GetParameter(CONFIG_MOBILE_MTU, DEFAULT_MOBILE_MTU, mobile_mtu, MIN_BUFFER_SIZE);
200 return std::atoi(mobile_mtu);
201 }
202
GetDefaultPreferApnConfig()203 bool CellularDataUtils::GetDefaultPreferApnConfig()
204 {
205 char preferApn[MIN_BUFFER_SIZE] = {0};
206 GetParameter(CONFIG_PREFERAPN, DEFAULT_PREFER_APN, preferApn, MIN_BUFFER_SIZE);
207 return std::atoi(preferApn);
208 }
209
GetDefaultMultipleConnectionsConfig()210 bool CellularDataUtils::GetDefaultMultipleConnectionsConfig()
211 {
212 char connections[MIN_BUFFER_SIZE] = {0};
213 GetParameter(CONFIG_MULTIPLE_CONNECTIONS, DEFAULT_MULTIPLE_CONNECTIONS, connections, MIN_BUFFER_SIZE);
214 return std::atoi(connections) > 0 ? true : false;
215 }
216
ConvertRadioTechToRadioName(const int32_t radioTech)217 std::string CellularDataUtils::ConvertRadioTechToRadioName(const int32_t radioTech)
218 {
219 std::string radioName = "unknown";
220 switch (radioTech) {
221 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_UNKNOWN):
222 radioName = "unknown";
223 break;
224 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_GSM):
225 radioName = "EDGE";
226 break;
227 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_1XRTT):
228 radioName = "1xRTT";
229 break;
230 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_WCDMA):
231 radioName = "UMTS";
232 break;
233 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_HSPA):
234 radioName = "HSPA";
235 break;
236 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_HSPAP):
237 radioName = "HSPAP";
238 break;
239 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_TD_SCDMA):
240 radioName = "TD-SCDMA";
241 break;
242 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_EVDO):
243 radioName = "EVDO";
244 break;
245 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_EHRPD):
246 radioName = "eHRPD";
247 break;
248 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_LTE):
249 radioName = "LTE";
250 break;
251 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_LTE_CA):
252 radioName = "LTE_CA";
253 break;
254 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_IWLAN):
255 radioName = "IWAN";
256 break;
257 case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_NR):
258 radioName = "NR";
259 break;
260 default:
261 break;
262 }
263 return radioName;
264 }
265 } // namespace Telephony
266 } // namespace OHOS