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