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 
ParseNormalIpAddr(const std::string & address)53 std::vector<AddressInfo> CellularDataUtils::ParseNormalIpAddr(const std::string &address)
54 {
55     std::vector<AddressInfo> ipInfoArray;
56     std::vector<std::string> ipArray = Split(address, " ");
57     for (size_t i = 0; i < ipArray.size(); ++i) {
58         AddressInfo ipInfo;
59         if (ipArray[i].find(':') == std::string::npos) {
60             ipInfo.prefixLen = IPV4_BIT;
61             ipInfo.type = INetAddr::IpType::IPV4;
62         } else {
63             ipInfo.prefixLen = IPV6_BIT;
64             ipInfo.type = INetAddr::IpType::IPV6;
65         }
66         ipInfo.ip = ipArray[i];
67         ipInfoArray.push_back(ipInfo);
68     }
69     return ipInfoArray;
70 }
71 
ParseRoute(const std::string & address)72 std::vector<RouteInfo> CellularDataUtils::ParseRoute(const std::string &address)
73 {
74     std::vector<RouteInfo> routeInfoArray;
75     std::vector<std::string> routeArray = Split(address, " ");
76     for (size_t i = 0; i < routeArray.size(); ++i) {
77         RouteInfo route;
78         if (routeArray[i].find(':') == std::string::npos) {
79             route.type = INetAddr::IpType::IPV4;
80             route.destination = ROUTED_IPV4;
81         } else {
82             route.type = INetAddr::IpType::IPV6;
83             route.destination = ROUTED_IPV6;
84         }
85         route.ip = routeArray[i];
86         routeInfoArray.push_back(route);
87     }
88     return routeInfoArray;
89 }
90 
Split(const std::string & input,const std::string & flag)91 std::vector<std::string> CellularDataUtils::Split(const std::string &input, const std::string &flag)
92 {
93     std::vector<std::string> vec;
94     if (input.empty()) {
95         TELEPHONY_LOGE("input is null");
96         return vec;
97     }
98     std::string::size_type start = 0;
99     std::string::size_type pos = 0;
100     while ((pos = input.find(flag, start)) != std::string::npos) {
101         vec.push_back(input.substr(start, pos - start));
102         start = pos + flag.size();
103     }
104     if (start != input.size()) {
105         vec.push_back(input.substr(start, input.size() - start));
106     }
107     return vec;
108 }
109 
GetPrefixLen(const std::string & netmask,const std::string & flag)110 int32_t CellularDataUtils::GetPrefixLen(const std::string &netmask, const std::string& flag)
111 {
112     std::vector<std::string> mask = Split(netmask, flag);
113     return GetPrefixLen(mask, 0);
114 }
115 
GetPrefixLen(const std::vector<std::string> & netmask,const size_t start)116 int32_t CellularDataUtils::GetPrefixLen(const std::vector<std::string> &netmask, const size_t start)
117 {
118     int32_t prefixLen = 0;
119     for (size_t i = start; i < netmask.size(); ++i) {
120         if (!IsValidDecValue(netmask[i].c_str())) {
121             break;
122         }
123         int32_t maskValue = (std::stoi(netmask[i].c_str()) & 0x00FF);
124         if (maskValue == 0) {
125             break;
126         }
127         while ((maskValue & 0x80) != 0) {
128             prefixLen++;
129             maskValue = (maskValue << 1);
130         }
131         if ((prefixLen % MASK_BYTE_BIT) != 0) {
132             break;
133         }
134     }
135     return prefixLen;
136 }
137 
GetDefaultMobileMtuConfig()138 int CellularDataUtils::GetDefaultMobileMtuConfig()
139 {
140     char mobile_mtu[MIN_BUFFER_SIZE] = {0};
141     GetParameter(CONFIG_MOBILE_MTU, DEFAULT_MOBILE_MTU, mobile_mtu, MIN_BUFFER_SIZE);
142     return std::atoi(mobile_mtu);
143 }
144 
GetDefaultPreferApnConfig()145 bool CellularDataUtils::GetDefaultPreferApnConfig()
146 {
147     char preferApn[MIN_BUFFER_SIZE] = {0};
148     GetParameter(CONFIG_PREFERAPN, DEFAULT_PREFER_APN, preferApn, MIN_BUFFER_SIZE);
149     return std::atoi(preferApn);
150 }
151 
GetDefaultMultipleConnectionsConfig()152 bool CellularDataUtils::GetDefaultMultipleConnectionsConfig()
153 {
154     char connections[MIN_BUFFER_SIZE] = {0};
155     GetParameter(CONFIG_MULTIPLE_CONNECTIONS, DEFAULT_MULTIPLE_CONNECTIONS, connections, MIN_BUFFER_SIZE);
156     return std::atoi(connections) > 0 ? true : false;
157 }
158 
ConvertRadioTechToRadioName(const int32_t radioTech)159 std::string CellularDataUtils::ConvertRadioTechToRadioName(const int32_t radioTech)
160 {
161     std::string radioName = "unknown";
162     switch (radioTech) {
163         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_UNKNOWN):
164             radioName = "unknown";
165             break;
166         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_GSM):
167             radioName = "EDGE";
168             break;
169         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_1XRTT):
170             radioName = "1xRTT";
171             break;
172         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_WCDMA):
173             radioName = "UMTS";
174             break;
175         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_HSPA):
176             radioName = "HSPA";
177             break;
178         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_HSPAP):
179             radioName = "HSPAP";
180             break;
181         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_TD_SCDMA):
182             radioName = "TD-SCDMA";
183             break;
184         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_EVDO):
185             radioName = "EVDO";
186             break;
187         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_EHRPD):
188             radioName = "eHRPD";
189             break;
190         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_LTE):
191             radioName = "LTE";
192             break;
193         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_LTE_CA):
194             radioName = "LTE_CA";
195             break;
196         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_IWLAN):
197             radioName = "IWAN";
198             break;
199         case static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_NR):
200             radioName = "NR";
201             break;
202         default:
203             break;
204     }
205     return radioName;
206 }
207 } // namespace Telephony
208 } // namespace OHOS