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