• 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 "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