• 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_state_machine.h"
17 
18 #include <cinttypes>
19 #include <string_ex.h>
20 
21 #include "activating.h"
22 #include "active.h"
23 #include "apn_manager.h"
24 #include "cellular_data_hisysevent.h"
25 #include "cellular_data_utils.h"
26 #include "core_manager_inner.h"
27 #include "default.h"
28 #include "disconnecting.h"
29 #include "inactive.h"
30 #include "radio_event.h"
31 #include "telephony_log_wrapper.h"
32 
33 namespace OHOS {
34 using namespace NetManagerStandard;
35 namespace Telephony {
36 static const int32_t INVALID_MTU_VALUE = -1;
IsInactiveState() const37 bool CellularDataStateMachine::IsInactiveState() const
38 {
39     return currentState_ == inActiveState_;
40 }
41 
SetCapability(uint64_t capability)42 void CellularDataStateMachine::SetCapability(uint64_t capability)
43 {
44     capability_ = capability;
45 }
46 
GetCapability() const47 uint64_t CellularDataStateMachine::GetCapability() const
48 {
49     return capability_;
50 }
51 
GetCid() const52 int32_t CellularDataStateMachine::GetCid() const
53 {
54     return cid_;
55 }
56 
SetCid(const int32_t cid)57 void CellularDataStateMachine::SetCid(const int32_t cid)
58 {
59     cid_ = cid;
60 }
61 
GetSlotId() const62 int32_t CellularDataStateMachine::GetSlotId() const
63 {
64     if (cdConnectionManager_ == nullptr) {
65         TELEPHONY_LOGE("cdConnectionManager_ is null");
66         return DEFAULT_SIM_SLOT_ID;
67     }
68     return cdConnectionManager_->GetSlotId();
69 }
70 
GetApnItem() const71 sptr<ApnItem> CellularDataStateMachine::GetApnItem() const
72 {
73     return apnItem_;
74 }
75 
DoConnect(const DataConnectionParams & connectionParams)76 void CellularDataStateMachine::DoConnect(const DataConnectionParams &connectionParams)
77 {
78     if (connectionParams.GetApnHolder() == nullptr) {
79         TELEPHONY_LOGE("apnHolder is null");
80         return;
81     }
82     apnId_ = ApnManager::FindApnIdByApnName(connectionParams.GetApnHolder()->GetApnType());
83     sptr<ApnItem> apn = connectionParams.GetApnHolder()->GetCurrentApn();
84     apnItem_ = apn;
85     if (apnItem_ == nullptr) {
86         TELEPHONY_LOGE("apnItem is null");
87         return;
88     }
89     const int32_t slotId = GetSlotId();
90     int32_t radioTech = static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_INVALID);
91     CoreManagerInner::GetInstance().GetPsRadioTech(slotId, radioTech);
92     ActivateDataParam activeDataParam;
93     activeDataParam.param = connectId_;
94     activeDataParam.radioTechnology = radioTech;
95     activeDataParam.allowRoaming = connectionParams.GetRoamingState();
96     activeDataParam.isRoaming = connectionParams.GetUserDataRoaming();
97     activeDataParam.dataProfile.profileId = apn->attr_.profileId_;
98     activeDataParam.dataProfile.apn = apn->attr_.apn_;
99     activeDataParam.dataProfile.protocol = apn->attr_.protocol_;
100     activeDataParam.dataProfile.verType = apn->attr_.authType_;
101     activeDataParam.dataProfile.userName = apn->attr_.user_;
102     activeDataParam.dataProfile.password = apn->attr_.password_;
103     activeDataParam.dataProfile.roamingProtocol = apn->attr_.roamingProtocol_;
104     TELEPHONY_LOGI("Slot%{public}d: Activate PDP context (%{public}d, %{public}s, %{public}s, %{public}s)", slotId,
105         apn->attr_.profileId_, apn->attr_.apn_, apn->attr_.protocol_, apn->attr_.types_);
106     int32_t result = CoreManagerInner::GetInstance().ActivatePdpContext(slotId, RadioEvent::RADIO_RIL_SETUP_DATA_CALL,
107         activeDataParam, stateMachineEventHandler_);
108     if (result != TELEPHONY_ERR_SUCCESS) {
109         TELEPHONY_LOGE("Slot%{public}d: Activate PDP context failed", slotId);
110         CellularDataHiSysEvent::WriteDataActivateFaultEvent(
111             slotId, SWITCH_ON, CellularDataErrorCode::DATA_ERROR_PDP_ACTIVATE_FAIL, "Activate PDP context failed");
112     }
113     if (stateMachineEventHandler_ == nullptr) {
114         TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
115         return;
116     }
117     stateMachineEventHandler_->SendEvent(
118         CellularDataEventCode::MSG_CONNECT_TIMEOUT_CHECK, connectId_, CONNECTION_DISCONNECTION_TIMEOUT);
119 }
120 
FreeConnection(const DataDisconnectParams & params)121 void CellularDataStateMachine::FreeConnection(const DataDisconnectParams &params)
122 {
123     const int32_t slotId = GetSlotId();
124     int32_t apnId = ApnManager::FindApnIdByApnName(params.GetApnType());
125     TELEPHONY_LOGI("Slot%{public}d: Deactivate PDP context cid:%{public}d type:%{public}s id:%{public}d",
126         slotId, cid_, params.GetApnType().c_str(), apnId);
127     DeactivateDataParam deactivateDataParam;
128     deactivateDataParam.param = connectId_;
129     deactivateDataParam.cid = cid_;
130     deactivateDataParam.reason = static_cast<int32_t>(params.GetReason());
131     int32_t result = CoreManagerInner::GetInstance().DeactivatePdpContext(slotId,
132         RadioEvent::RADIO_RIL_DEACTIVATE_DATA_CALL, deactivateDataParam, stateMachineEventHandler_);
133     if (result != TELEPHONY_ERR_SUCCESS) {
134         TELEPHONY_LOGE("Slot%{public}d: Deactivate PDP context failed", slotId);
135         CellularDataHiSysEvent::WriteDataActivateFaultEvent(
136             slotId, SWITCH_OFF, CellularDataErrorCode::DATA_ERROR_PDP_DEACTIVATE_FAIL, "Deactivate PDP context failed");
137     }
138     if (stateMachineEventHandler_ == nullptr) {
139         TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
140         return;
141     }
142     stateMachineEventHandler_->SendEvent(
143         CellularDataEventCode::MSG_DISCONNECT_TIMEOUT_CHECK, connectId_, CONNECTION_DISCONNECTION_TIMEOUT);
144 }
145 
operator ==(const CellularDataStateMachine & stateMachine) const146 bool CellularDataStateMachine::operator==(const CellularDataStateMachine &stateMachine) const
147 {
148     return this->GetCid() == stateMachine.GetCid();
149 }
150 
Init()151 void CellularDataStateMachine::Init()
152 {
153     activeState_ = std::make_unique<Active>(
154         std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Active").release();
155     inActiveState_ = std::make_unique<Inactive>(
156         std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Inactive").release();
157     activatingState_ = std::make_unique<Activating>(
158         std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Activating").release();
159     disconnectingState_ = std::make_unique<Disconnecting>(
160         std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Disconnecting").release();
161     defaultState_ = std::make_unique<Default>(
162         std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Default").release();
163     netSupplierInfo_ = std::make_unique<NetSupplierInfo>().release();
164     netLinkInfo_ = std::make_unique<NetLinkInfo>().release();
165     if (activeState_ == nullptr || inActiveState_ == nullptr || activatingState_ == nullptr ||
166         disconnectingState_ == nullptr || defaultState_ == nullptr || netSupplierInfo_ == nullptr ||
167         netLinkInfo_ == nullptr) {
168         TELEPHONY_LOGE("memory allocation failed");
169         return;
170     }
171     activeState_->SetParentState(defaultState_);
172     inActiveState_->SetParentState(defaultState_);
173     activatingState_->SetParentState(defaultState_);
174     disconnectingState_->SetParentState(defaultState_);
175     StateMachine::SetOriginalState(inActiveState_);
176     StateMachine::Start();
177 }
178 
SetCurrentState(const sptr<State> && state)179 void CellularDataStateMachine::SetCurrentState(const sptr<State> &&state)
180 {
181     currentState_ = std::move(state);
182 }
183 
GetCurrentState() const184 sptr<State> CellularDataStateMachine::GetCurrentState() const
185 {
186     return currentState_;
187 }
188 
HasMatchedIpTypeAddrs(uint8_t ipType,uint8_t ipInfoArraySize,std::vector<AddressInfo> ipInfoArray)189 bool CellularDataStateMachine::HasMatchedIpTypeAddrs(uint8_t ipType, uint8_t ipInfoArraySize,
190     std::vector<AddressInfo> ipInfoArray)
191 {
192     for (int i = 0; i < ipInfoArraySize; i++) {
193         if (ipInfoArray[i].type == ipType) {
194             return true;
195         }
196     }
197     return false;
198 }
199 
GetIpType(std::vector<AddressInfo> ipInfoArray)200 std::string CellularDataStateMachine::GetIpType(std::vector<AddressInfo> ipInfoArray)
201 {
202     uint8_t ipInfoArraySize = ipInfoArray.size();
203     uint8_t ipv4Type = INetAddr::IpType::IPV4;
204     uint8_t ipv6Type = INetAddr::IpType::IPV6;
205     std::string result;
206     if (HasMatchedIpTypeAddrs(ipv4Type, ipInfoArraySize, ipInfoArray) &&
207         HasMatchedIpTypeAddrs(ipv6Type, ipInfoArraySize, ipInfoArray)) {
208         result = "IPV4V6";
209     } else if (HasMatchedIpTypeAddrs(ipv4Type, ipInfoArraySize, ipInfoArray)) {
210         result = "IPV4";
211     } else if (HasMatchedIpTypeAddrs(ipv6Type, ipInfoArraySize, ipInfoArray)) {
212         result = "IPV6";
213     } else {
214         TELEPHONY_LOGE("Ip type not match");
215     }
216     return result;
217 }
218 
GetIpType()219 std::string CellularDataStateMachine::GetIpType()
220 {
221     return ipType_;
222 }
223 
GetMtuSizeFromOpCfg(int32_t & mtuSize,int32_t slotId)224 void CellularDataStateMachine::GetMtuSizeFromOpCfg(int32_t &mtuSize, int32_t slotId)
225 {
226     std::string mtuString = "";
227     int32_t mtuValue = INVALID_MTU_VALUE;
228     OperatorConfig configsForMtuSize;
229     CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, configsForMtuSize);
230     if (configsForMtuSize.stringValue.find(KEY_MTU_SIZE_STRING) != configsForMtuSize.stringValue.end()) {
231         mtuString = configsForMtuSize.stringValue[KEY_MTU_SIZE_STRING];
232     }
233     std::vector<std::string> mtuArray = CellularDataUtils::Split(mtuString, ";");
234     for (std::string &ipTypeArray : mtuArray) {
235         std::vector<std::string> mtuIpTypeArray = CellularDataUtils::Split(ipTypeArray, ":");
236         if (mtuIpTypeArray.size() != VALID_VECTOR_SIZE || mtuIpTypeArray[0].empty() || mtuIpTypeArray[1].empty()) {
237             TELEPHONY_LOGE("mtu size string is invalid");
238             break;
239         }
240         std::string ipTypeString = mtuIpTypeArray[0];
241         StrToInt(mtuIpTypeArray[1], mtuValue);
242         if (mtuValue == INVALID_MTU_VALUE) {
243             TELEPHONY_LOGE("mtu values is invalid");
244             break;
245         }
246         if (!ipTypeString.empty() && ipTypeString == ipType_) {
247             mtuSize = mtuValue;
248         }
249     }
250     return;
251 }
252 
SplitProxyIpAddress(const std::string & proxyIpAddress,std::string & host,uint16_t & port)253 void CellularDataStateMachine::SplitProxyIpAddress(const std::string &proxyIpAddress, std::string &host, uint16_t &port)
254 {
255     std::vector<std::string> address;
256     size_t pos = 0;
257     size_t found = 0;
258     while ((found = proxyIpAddress.find(':', pos)) != std::string::npos) {
259         address.push_back(proxyIpAddress.substr(pos, found - pos));
260         pos = found + 1;
261     }
262     address.push_back(proxyIpAddress.substr(pos));
263     if (address.size() == HOST_SIZE) {
264         host = address[0];
265     }
266     if (address.size() == HOST_PORT_SIZE) {
267         host = address[0];
268         port = static_cast<uint16_t>(std::stoi(address[1]));
269     }
270 }
271 
UpdateHttpProxy(const std::string & proxyIpAddress)272 void CellularDataStateMachine::UpdateHttpProxy(const std::string &proxyIpAddress)
273 {
274     std::string host = "";
275     uint16_t port = DEFAULT_PORT;
276     SplitProxyIpAddress(proxyIpAddress, host, port);
277     HttpProxy httpProxy = { host, port, {} };
278     netLinkInfo_->httpProxy_ = httpProxy;
279 }
280 
UpdateNetworkInfo(const SetupDataCallResultInfo & dataCallInfo)281 void CellularDataStateMachine::UpdateNetworkInfo(const SetupDataCallResultInfo &dataCallInfo)
282 {
283     std::lock_guard<std::mutex> guard(mtx_);
284     int32_t slotId = GetSlotId();
285     TELEPHONY_LOGD("Slot%{private}d: dataCall, capability:%{private}" PRIu64", state:%{private}d, addr:%{private}s, "
286         "dns: %{private}s, gw: %{private}s", slotId, capability_, dataCallInfo.reason,
287         dataCallInfo.address.c_str(), dataCallInfo.dns.c_str(), dataCallInfo.gateway.c_str());
288     std::vector<AddressInfo> ipInfoArray = CellularDataUtils::ParseIpAddr(dataCallInfo.address);
289     std::vector<AddressInfo> dnsInfoArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.dns);
290     std::vector<AddressInfo> dnsSecArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.dnsSec);
291     dnsInfoArray.insert(dnsInfoArray.end(), dnsSecArray.begin(), dnsSecArray.end());
292     std::vector<AddressInfo> routeInfoArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.gateway);
293     if (ipInfoArray.empty() || dnsInfoArray.empty() || routeInfoArray.empty()) {
294         TELEPHONY_LOGE("Verifying network Information(ipInfoArray or dnsInfoArray or routeInfoArray empty)");
295     }
296     if (netLinkInfo_ == nullptr || netSupplierInfo_ == nullptr) {
297         TELEPHONY_LOGE("Slot%{public}d: start update net info,but netLinkInfo or netSupplierInfo is null!", slotId);
298         return;
299     }
300     bool roamingState = false;
301     if (CoreManagerInner::GetInstance().GetPsRoamingState(slotId) > 0) {
302         roamingState = true;
303     }
304     int32_t mtuSize = (dataCallInfo.maxTransferUnit == 0) ? DEFAULT_MTU : dataCallInfo.maxTransferUnit;
305     ipType_ = GetIpType(ipInfoArray);
306     GetMtuSizeFromOpCfg(mtuSize, slotId);
307     netLinkInfo_->ifaceName_ = dataCallInfo.netPortName;
308     netLinkInfo_->mtu_ = mtuSize;
309     netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
310     ResolveIp(ipInfoArray);
311     ResolveDns(dnsInfoArray);
312     ResolveRoute(routeInfoArray, dataCallInfo.netPortName);
313     netSupplierInfo_->isAvailable_ = (dataCallInfo.active > 0);
314     netSupplierInfo_->isRoaming_ = roamingState;
315     netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
316     netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
317     cause_ = dataCallInfo.reason;
318     CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
319     int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
320     netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
321     if (netSupplierInfo_->isAvailable_) {
322         netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
323     }
324 }
325 
UpdateNetworkInfo()326 void CellularDataStateMachine::UpdateNetworkInfo()
327 {
328     int32_t slotId = GetSlotId();
329     CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
330     netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
331     netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
332     netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
333     int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
334     netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
335     if (netSupplierInfo_->isAvailable_) {
336         netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
337     }
338 }
339 
ResolveIp(std::vector<AddressInfo> & ipInfoArray)340 void CellularDataStateMachine::ResolveIp(std::vector<AddressInfo> &ipInfoArray)
341 {
342     TELEPHONY_LOGD("Resolve Ip ifaceName_: %{private}s, domain_: %{private}s, mtu_: %{private}d, isAvailable_:"
343         " %{private}d, isRoaming_:%{private}d", netLinkInfo_->ifaceName_.c_str(),
344         netLinkInfo_->domain_.c_str(), netLinkInfo_->mtu_,
345         netSupplierInfo_->isAvailable_, netSupplierInfo_->isRoaming_);
346     netLinkInfo_->netAddrList_.clear();
347     for (AddressInfo ipInfo : ipInfoArray) {
348         INetAddr netAddr;
349         netAddr.address_ = ipInfo.ip;
350         netAddr.family_ = ipInfo.type;
351         netAddr.type_ = ipInfo.type;
352         netAddr.hostName_ = DEFAULT_HOSTNAME;
353         netAddr.netMask_ = ipInfo.netMask.length() > 0 ? ipInfo.netMask : DEFAULT_MASK;
354         netAddr.prefixlen_ = ipInfo.prefixLen;
355         netLinkInfo_->netAddrList_.push_back(netAddr);
356     }
357 }
358 
ResolveDns(std::vector<AddressInfo> & dnsInfoArray)359 void CellularDataStateMachine::ResolveDns(std::vector<AddressInfo> &dnsInfoArray)
360 {
361     netLinkInfo_->dnsList_.clear();
362     for (AddressInfo dnsInfo : dnsInfoArray) {
363         INetAddr dnsAddr;
364         dnsAddr.address_ = dnsInfo.ip;
365         dnsAddr.family_ = dnsInfo.type;
366         dnsAddr.type_ = dnsInfo.type;
367         dnsAddr.hostName_ = DEFAULT_HOSTNAME;
368         dnsAddr.netMask_ = dnsInfo.netMask;
369         dnsAddr.prefixlen_ = dnsInfo.prefixLen;
370         netLinkInfo_->dnsList_.push_back(dnsAddr);
371     }
372 }
373 
ResolveRoute(std::vector<AddressInfo> & routeInfoArray,const std::string & name)374 void CellularDataStateMachine::ResolveRoute(std::vector<AddressInfo> &routeInfoArray, const std::string &name)
375 {
376     netLinkInfo_->routeList_.clear();
377     for (AddressInfo routeInfo : routeInfoArray) {
378         NetManagerStandard::Route route;
379         route.iface_ = name;
380         route.gateway_.address_ = routeInfo.ip;
381         route.gateway_.family_ = routeInfo.type;
382         route.gateway_.type_ = routeInfo.type;
383         route.gateway_.hostName_ = DEFAULT_HOSTNAME;
384         route.gateway_.netMask_ = DEFAULT_MASK;
385         route.gateway_.prefixlen_ = routeInfo.prefixLen;
386         if (routeInfo.type == INetAddr::IpType::IPV4) {
387             route.destination_.address_ = ROUTED_IPV4;
388         } else {
389             route.destination_.address_ = ROUTED_IPV6;
390         }
391         route.destination_.family_ = routeInfo.type;
392         route.destination_.type_ = routeInfo.type;
393         route.destination_.hostName_ = DEFAULT_HOSTNAME;
394         route.destination_.netMask_ = DEFAULT_MASK;
395         route.destination_.prefixlen_ = 0;
396         netLinkInfo_->routeList_.push_back(route);
397     }
398 }
399 
SetConnectionBandwidth(const uint32_t upBandwidth,const uint32_t downBandwidth)400 void CellularDataStateMachine::SetConnectionBandwidth(const uint32_t upBandwidth, const uint32_t downBandwidth)
401 {
402     upBandwidth_ = upBandwidth;
403     downBandwidth_ = downBandwidth;
404 }
405 
SetConnectionTcpBuffer(const std::string & tcpBuffer)406 void CellularDataStateMachine::SetConnectionTcpBuffer(const std::string &tcpBuffer)
407 {
408     tcpBuffer_ = tcpBuffer;
409 }
410 } // namespace Telephony
411 } // namespace OHOS
412