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 #include <charconv>
21
22 #include "activating.h"
23 #include "active.h"
24 #include "apn_manager.h"
25 #include "cellular_data_hisysevent.h"
26 #include "cellular_data_utils.h"
27 #include "core_manager_inner.h"
28 #include "default.h"
29 #include "disconnecting.h"
30 #include "inactive.h"
31 #include "radio_event.h"
32 #include "telephony_common_utils.h"
33 #include "telephony_log_wrapper.h"
34 #include "networkslice_client.h"
35
36 namespace OHOS {
37 using namespace NetManagerStandard;
38 namespace Telephony {
39 static const int32_t INVALID_MTU_VALUE = -1;
40 static const bool IS_SUPPORT_NR_SLICE = system::GetBoolParameter("persist.netmgr_ext.networkslice", false);
41 constexpr int INTERFACE_DOWN_TIMEOUT = 2 * 1000; // 2000ms
42
~CellularDataStateMachine()43 CellularDataStateMachine::~CellularDataStateMachine()
44 {
45 UnregisterNetInterfaceCallback();
46 }
47
UnregisterNetInterfaceCallback()48 void CellularDataStateMachine::UnregisterNetInterfaceCallback()
49 {
50 if (netInterfaceCallback_ != nullptr) {
51 OHOS::NetManagerStandard::NetConnClient::GetInstance().UnregisterNetInterfaceCallback(
52 netInterfaceCallback_);
53 }
54 }
55
IsInactiveState() const56 bool CellularDataStateMachine::IsInactiveState() const
57 {
58 return currentState_ == inActiveState_;
59 }
60
IsActivatingState() const61 bool CellularDataStateMachine::IsActivatingState() const
62 {
63 return currentState_ == activatingState_;
64 }
65
IsDisconnectingState() const66 bool CellularDataStateMachine::IsDisconnectingState() const
67 {
68 return currentState_ == disconnectingState_;
69 }
70
IsActiveState() const71 bool CellularDataStateMachine::IsActiveState() const
72 {
73 return currentState_ == activeState_;
74 }
75
IsDefaultState() const76 bool CellularDataStateMachine::IsDefaultState() const
77 {
78 return currentState_ == defaultState_;
79 }
80
SetCapability(uint64_t capability)81 void CellularDataStateMachine::SetCapability(uint64_t capability)
82 {
83 capability_ = capability;
84 }
85
GetCapability() const86 uint64_t CellularDataStateMachine::GetCapability() const
87 {
88 return capability_;
89 }
90
GetCid() const91 int32_t CellularDataStateMachine::GetCid() const
92 {
93 return cid_;
94 }
95
SetCid(const int32_t cid)96 void CellularDataStateMachine::SetCid(const int32_t cid)
97 {
98 cid_ = cid;
99 }
100
GetSlotId() const101 int32_t CellularDataStateMachine::GetSlotId() const
102 {
103 if (cdConnectionManager_ == nullptr) {
104 TELEPHONY_LOGE("cdConnectionManager_ is null");
105 return DEFAULT_SIM_SLOT_ID;
106 }
107 return cdConnectionManager_->GetSlotId();
108 }
109
GetApnItem() const110 sptr<ApnItem> CellularDataStateMachine::GetApnItem() const
111 {
112 return apnItem_;
113 }
114
FillActivateDataParam(ActivateDataParam & activeDataParam,sptr<ApnItem> apn)115 static void FillActivateDataParam(ActivateDataParam& activeDataParam, sptr<ApnItem> apn)
116 {
117 activeDataParam.dataProfile.profileId = apn->attr_.profileId_;
118 activeDataParam.dataProfile.apn = apn->attr_.apn_;
119 activeDataParam.dataProfile.protocol = apn->attr_.protocol_;
120 activeDataParam.dataProfile.verType = apn->attr_.authType_;
121 activeDataParam.dataProfile.userName = apn->attr_.user_;
122 activeDataParam.dataProfile.password = apn->attr_.password_;
123 activeDataParam.dataProfile.roamingProtocol = apn->attr_.roamingProtocol_;
124 }
125
DoConnect(const DataConnectionParams & connectionParams)126 void CellularDataStateMachine::DoConnect(const DataConnectionParams &connectionParams)
127 {
128 if (connectionParams.GetApnHolder() == nullptr) {
129 TELEPHONY_LOGE("apnHolder is null");
130 return;
131 }
132 apnId_ = ApnManager::FindApnIdByApnName(connectionParams.GetApnHolder()->GetApnType());
133 sptr<ApnItem> apn = connectionParams.GetApnHolder()->GetCurrentApn();
134 apnItem_ = apn;
135 if (apnItem_ == nullptr) {
136 TELEPHONY_LOGE("apnItem is null");
137 return;
138 }
139 const int32_t slotId = GetSlotId();
140 int32_t radioTech = static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_INVALID);
141 CoreManagerInner::GetInstance().GetPsRadioTech(slotId, radioTech);
142 ActivateDataParam activeDataParam;
143 activeDataParam.param = connectId_;
144 activeDataParam.radioTechnology = radioTech;
145 activeDataParam.allowRoaming = connectionParams.GetRoamingState();
146 activeDataParam.isRoaming = connectionParams.GetUserDataRoaming();
147 FillActivateDataParam(activeDataParam, apn);
148 if (IS_SUPPORT_NR_SLICE) {
149 GetNetworkSlicePara(connectionParams, apn);
150 activeDataParam.dataProfile.snssai = apn->attr_.snssai_;
151 activeDataParam.dataProfile.sscMode = apn->attr_.sscMode_;
152 activeDataParam.dataProfile.apn = apn->attr_.apn_;
153 activeDataParam.dataProfile.protocol = apn->attr_.protocol_;
154 }
155 int32_t bitMap = ApnManager::FindApnTypeByApnName(connectionParams.GetApnHolder()->GetApnType());
156 activeDataParam.dataProfile.supportedApnTypesBitmap = bitMap;
157 TELEPHONY_LOGI("Slot%{public}d: Activate PDP context (%{public}d, %{public}s, %{public}s, %{public}s, %{public}d)",
158 slotId, apn->attr_.profileId_, apn->attr_.apn_, apn->attr_.protocol_, apn->attr_.types_, bitMap);
159 int32_t result = CoreManagerInner::GetInstance().ActivatePdpContext(slotId, RadioEvent::RADIO_RIL_SETUP_DATA_CALL,
160 activeDataParam, stateMachineEventHandler_);
161 if (result != TELEPHONY_ERR_SUCCESS) {
162 TELEPHONY_LOGE("Slot%{public}d: Activate PDP context failed", slotId);
163 CellularDataHiSysEvent::WriteDataActivateFaultEvent(
164 slotId, SWITCH_ON, CellularDataErrorCode::DATA_ERROR_PDP_ACTIVATE_FAIL, "Activate PDP context failed");
165 }
166 if (stateMachineEventHandler_ == nullptr) {
167 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
168 return;
169 }
170 startTimeConnectTimeoutTask_ =
171 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
172 .count();
173 stateMachineEventHandler_->SendEvent(
174 CellularDataEventCode::MSG_CONNECT_TIMEOUT_CHECK, connectId_, CONNECTION_TIMEOUT);
175 }
176
FreeConnection(const DataDisconnectParams & params)177 void CellularDataStateMachine::FreeConnection(const DataDisconnectParams ¶ms)
178 {
179 const int32_t slotId = GetSlotId();
180 int32_t apnId = ApnManager::FindApnIdByApnName(params.GetApnType());
181 TELEPHONY_LOGI("Slot%{public}d: Deactivate PDP context cid:%{public}d type:%{public}s id:%{public}d",
182 slotId, cid_, params.GetApnType().c_str(), apnId);
183 DeactivateDataParam deactivateDataParam;
184 deactivateDataParam.param = connectId_;
185 deactivateDataParam.cid = cid_;
186 deactivateDataParam.reason = static_cast<int32_t>(params.GetReason());
187 int32_t result = CoreManagerInner::GetInstance().DeactivatePdpContext(slotId,
188 RadioEvent::RADIO_RIL_DEACTIVATE_DATA_CALL, deactivateDataParam, stateMachineEventHandler_);
189 if (result != TELEPHONY_ERR_SUCCESS) {
190 TELEPHONY_LOGE("Slot%{public}d: Deactivate PDP context failed", slotId);
191 CellularDataHiSysEvent::WriteDataActivateFaultEvent(
192 slotId, SWITCH_OFF, CellularDataErrorCode::DATA_ERROR_PDP_DEACTIVATE_FAIL, "Deactivate PDP context failed");
193 }
194 if (stateMachineEventHandler_ == nullptr) {
195 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
196 return;
197 }
198 stateMachineEventHandler_->SendEvent(
199 CellularDataEventCode::MSG_DISCONNECT_TIMEOUT_CHECK, connectId_, DISCONNECTION_TIMEOUT);
200 }
201
OnInterfaceLinkStateChanged(const std::string & ifName,bool up)202 int32_t CellularDataStateMachine::NetInterfaceCallback::OnInterfaceLinkStateChanged(const std::string &ifName, bool up)
203 {
204 auto cellularDataStateMachine = cellularDataStateMachine_.lock();
205 if (cellularDataStateMachine == nullptr) {
206 TELEPHONY_LOGE("cellularDataStateMachine is nullptr");
207 return 0;
208 }
209 cellularDataStateMachine->OnInterfaceLinkStateChanged(ifName, up);
210 return 0;
211 }
212
OnInterfaceLinkStateChanged(const std::string & ifName,bool up)213 int32_t CellularDataStateMachine::OnInterfaceLinkStateChanged(const std::string &ifName, bool up)
214 {
215 if (ifName != ifName_) {
216 return 0;
217 }
218 if (!up) {
219 if (stateMachineEventHandler_ == nullptr) {
220 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
221 return 0;
222 }
223 if (stateMachineEventHandler_->HasInnerEvent(CellularDataEventCode::MSG_DISCONNECT_TIMEOUT_CHECK)) {
224 TELEPHONY_LOGI("connectId_:%{public}d", connectId_);
225 stateMachineEventHandler_->RemoveEvent(CellularDataEventCode::MSG_DISCONNECT_TIMEOUT_CHECK);
226 stateMachineEventHandler_->SendEvent(
227 CellularDataEventCode::MSG_DISCONNECT_TIMEOUT_CHECK, connectId_, INTERFACE_DOWN_TIMEOUT);
228 }
229 }
230 return 0;
231 }
232
operator ==(const CellularDataStateMachine & stateMachine) const233 bool CellularDataStateMachine::operator==(const CellularDataStateMachine &stateMachine) const
234 {
235 return this->GetCid() == stateMachine.GetCid();
236 }
237
Init()238 void CellularDataStateMachine::Init()
239 {
240 activeState_ = std::make_unique<Active>(
241 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Active").release();
242 inActiveState_ = std::make_unique<Inactive>(
243 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Inactive").release();
244 activatingState_ = std::make_unique<Activating>(
245 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Activating").release();
246 disconnectingState_ = std::make_unique<Disconnecting>(
247 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Disconnecting").release();
248 defaultState_ = std::make_unique<Default>(
249 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Default").release();
250 netSupplierInfo_ = std::make_unique<NetSupplierInfo>().release();
251 netLinkInfo_ = std::make_unique<NetLinkInfo>().release();
252 if (activeState_ == nullptr || inActiveState_ == nullptr || activatingState_ == nullptr ||
253 disconnectingState_ == nullptr || defaultState_ == nullptr || netSupplierInfo_ == nullptr ||
254 netLinkInfo_ == nullptr) {
255 TELEPHONY_LOGE("memory allocation failed");
256 return;
257 }
258 activeState_->SetParentState(defaultState_);
259 inActiveState_->SetParentState(defaultState_);
260 activatingState_->SetParentState(defaultState_);
261 disconnectingState_->SetParentState(defaultState_);
262 netInterfaceCallback_ =
263 sptr<NetInterfaceCallback>::MakeSptr(std::weak_ptr<CellularDataStateMachine>(shared_from_this()));
264 if (netInterfaceCallback_ != nullptr) {
265 OHOS::NetManagerStandard::NetConnClient::GetInstance().RegisterNetInterfaceCallback(netInterfaceCallback_);
266 }
267 StateMachine::SetOriginalState(inActiveState_);
268 StateMachine::Start();
269 }
270
SetCurrentState(const sptr<State> && state)271 void CellularDataStateMachine::SetCurrentState(const sptr<State> &&state)
272 {
273 currentState_ = std::move(state);
274 }
275
GetCurrentState() const276 sptr<State> CellularDataStateMachine::GetCurrentState() const
277 {
278 return currentState_;
279 }
280
HasMatchedIpTypeAddrs(uint8_t ipType,uint8_t ipInfoArraySize,std::vector<AddressInfo> ipInfoArray)281 bool CellularDataStateMachine::HasMatchedIpTypeAddrs(uint8_t ipType, uint8_t ipInfoArraySize,
282 std::vector<AddressInfo> ipInfoArray)
283 {
284 for (int i = 0; i < ipInfoArraySize; i++) {
285 if (ipInfoArray[i].type == ipType) {
286 return true;
287 }
288 }
289 return false;
290 }
291
GetIpType(std::vector<AddressInfo> ipInfoArray)292 std::string CellularDataStateMachine::GetIpType(std::vector<AddressInfo> ipInfoArray)
293 {
294 uint8_t ipInfoArraySize = ipInfoArray.size();
295 uint8_t ipv4Type = INetAddr::IpType::IPV4;
296 uint8_t ipv6Type = INetAddr::IpType::IPV6;
297 std::string result;
298 if (HasMatchedIpTypeAddrs(ipv4Type, ipInfoArraySize, ipInfoArray) &&
299 HasMatchedIpTypeAddrs(ipv6Type, ipInfoArraySize, ipInfoArray)) {
300 result = "IPV4V6";
301 } else if (HasMatchedIpTypeAddrs(ipv4Type, ipInfoArraySize, ipInfoArray)) {
302 result = "IPV4";
303 } else if (HasMatchedIpTypeAddrs(ipv6Type, ipInfoArraySize, ipInfoArray)) {
304 result = "IPV6";
305 } else {
306 TELEPHONY_LOGE("Ip type not match");
307 }
308 return result;
309 }
310
GetIpType()311 std::string CellularDataStateMachine::GetIpType()
312 {
313 std::lock_guard<std::mutex> guard(mtx_);
314 return ipType_;
315 }
316
GetMtuSizeFromOpCfg(int32_t & mtuSize,int32_t slotId)317 void CellularDataStateMachine::GetMtuSizeFromOpCfg(int32_t &mtuSize, int32_t slotId)
318 {
319 std::string mtuString = "";
320 int32_t mtuValue = INVALID_MTU_VALUE;
321 OperatorConfig configsForMtuSize;
322 CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, configsForMtuSize);
323 if (configsForMtuSize.stringValue.find(KEY_MTU_SIZE_STRING) != configsForMtuSize.stringValue.end()) {
324 mtuString = configsForMtuSize.stringValue[KEY_MTU_SIZE_STRING];
325 }
326 std::vector<std::string> mtuArray = CellularDataUtils::Split(mtuString, ";");
327 for (std::string &ipTypeArray : mtuArray) {
328 std::vector<std::string> mtuIpTypeArray = CellularDataUtils::Split(ipTypeArray, ":");
329 if (mtuIpTypeArray.size() != VALID_VECTOR_SIZE || mtuIpTypeArray[0].empty() || mtuIpTypeArray[1].empty()) {
330 TELEPHONY_LOGE("mtu size string is invalid");
331 break;
332 }
333 std::string ipTypeString = mtuIpTypeArray[0];
334 StrToInt(mtuIpTypeArray[1], mtuValue);
335 if (mtuValue == INVALID_MTU_VALUE) {
336 TELEPHONY_LOGE("mtu values is invalid");
337 break;
338 }
339 if (!ipTypeString.empty() && ipTypeString == ipType_) {
340 mtuSize = mtuValue;
341 }
342 }
343 return;
344 }
345
SplitProxyIpAddress(const std::string & proxyIpAddress,std::string & host,uint16_t & port)346 void CellularDataStateMachine::SplitProxyIpAddress(const std::string &proxyIpAddress, std::string &host, uint16_t &port)
347 {
348 std::vector<std::string> address;
349 size_t pos = 0;
350 size_t found = 0;
351 while ((found = proxyIpAddress.find(':', pos)) != std::string::npos) {
352 address.push_back(proxyIpAddress.substr(pos, found - pos));
353 pos = found + 1;
354 }
355 address.push_back(proxyIpAddress.substr(pos));
356 if (address.size() == HOST_SIZE) {
357 host = address[0];
358 }
359 if (address.size() == HOST_PORT_SIZE) {
360 host = address[0];
361 if (!address[1].empty() && IsValidDecValue(address[1])) {
362 port = static_cast<uint16_t>(std::stoi(address[1]));
363 }
364 }
365 }
366
UpdateHttpProxy(const std::string & proxyIpAddress)367 void CellularDataStateMachine::UpdateHttpProxy(const std::string &proxyIpAddress)
368 {
369 std::string host = "";
370 uint16_t port = DEFAULT_PORT;
371 SplitProxyIpAddress(proxyIpAddress, host, port);
372 HttpProxy httpProxy = { host, port, {} };
373 netLinkInfo_->httpProxy_ = httpProxy;
374 }
375
GetNetScoreBySlotId(int32_t slotId)376 int32_t CellularDataStateMachine::GetNetScoreBySlotId(int32_t slotId)
377 {
378 int32_t score = DEFAULT_INTERNET_CONNECTION_SCORE;
379 int32_t defaultSlotId = CoreManagerInner::GetInstance().GetDefaultCellularDataSlotId();
380 if (slotId != defaultSlotId) {
381 score = OTHER_CONNECTION_SCORE;
382 }
383 return score;
384 }
385
UpdateNetworkInfo(const SetupDataCallResultInfo & dataCallInfo)386 void CellularDataStateMachine::UpdateNetworkInfo(const SetupDataCallResultInfo &dataCallInfo)
387 {
388 std::lock_guard<std::mutex> guard(mtx_);
389 int32_t slotId = GetSlotId();
390 TELEPHONY_LOGD("Slot%{private}d: dataCall, capability:%{private}" PRIu64", state:%{private}d, addr:%{private}s, "
391 "dns: %{private}s, gw: %{private}s", slotId, capability_, dataCallInfo.reason,
392 dataCallInfo.address.c_str(), dataCallInfo.dns.c_str(), dataCallInfo.gateway.c_str());
393 std::vector<AddressInfo> ipInfoArray = CellularDataUtils::ParseIpAddr(dataCallInfo.address);
394 std::vector<AddressInfo> dnsInfoArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.dns);
395 std::vector<AddressInfo> dnsSecArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.dnsSec);
396 dnsInfoArray.insert(dnsInfoArray.end(), dnsSecArray.begin(), dnsSecArray.end());
397 std::vector<AddressInfo> routeInfoArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.gateway);
398 if (ipInfoArray.empty() || dnsInfoArray.empty() || routeInfoArray.empty()) {
399 TELEPHONY_LOGE("Verifying network Information(ipInfoArray or dnsInfoArray or routeInfoArray empty)");
400 }
401 if (netLinkInfo_ == nullptr || netSupplierInfo_ == nullptr) {
402 TELEPHONY_LOGE("Slot%{public}d: start update net info,but netLinkInfo or netSupplierInfo is null!", slotId);
403 return;
404 }
405 bool roamingState = false;
406 if (CoreManagerInner::GetInstance().GetPsRoamingState(slotId) > 0) {
407 roamingState = true;
408 }
409 int32_t mtuSize = (dataCallInfo.maxTransferUnit == 0) ? DEFAULT_MTU : dataCallInfo.maxTransferUnit;
410 ipType_ = GetIpType(ipInfoArray);
411 GetMtuSizeFromOpCfg(mtuSize, slotId);
412 netLinkInfo_->ifaceName_ = dataCallInfo.netPortName;
413 ifName_ = dataCallInfo.netPortName;
414 netLinkInfo_->mtu_ = mtuSize;
415 netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
416 ResolveIp(ipInfoArray);
417 ResolveDns(dnsInfoArray);
418 ResolveRoute(routeInfoArray, dataCallInfo.netPortName);
419 netSupplierInfo_->isAvailable_ = (dataCallInfo.active > 0);
420 netSupplierInfo_->isRoaming_ = roamingState;
421 netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
422 netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
423 netSupplierInfo_->score_ = GetNetScoreBySlotId(slotId);
424 cause_ = dataCallInfo.reason;
425 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
426 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
427 netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
428 if (netSupplierInfo_->isAvailable_) {
429 netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
430 }
431 }
432
UpdateNetworkInfo()433 void CellularDataStateMachine::UpdateNetworkInfo()
434 {
435 std::lock_guard<std::mutex> guard(mtx_);
436 int32_t slotId = GetSlotId();
437 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
438 netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
439 netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
440 netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
441 netSupplierInfo_->score_ = GetNetScoreBySlotId(slotId);
442 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
443 netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
444 if (netSupplierInfo_->isAvailable_) {
445 netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
446 }
447 }
448
SetIfReuseSupplierId(bool isReused)449 void CellularDataStateMachine::SetIfReuseSupplierId(bool isReused)
450 {
451 if (reuseApnCap_ == NetManagerStandard::NetCap::NET_CAPABILITY_END) {
452 return;
453 }
454 int32_t slotId = GetSlotId();
455 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
456 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
457 int32_t reuseSupplierId = netAgent.GetSupplierId(slotId, reuseApnCap_);
458 TELEPHONY_LOGI("SetIfReuseSupplierId: cap[%{public}d], reuseCap[%{public}d], reuse[%{public}d]",
459 static_cast<int32_t>(capability_), static_cast<int32_t>(reuseApnCap_), isReused);
460 netAgent.SetReuseSupplierId(supplierId, reuseSupplierId, isReused);
461 }
462
ResolveIp(std::vector<AddressInfo> & ipInfoArray)463 void CellularDataStateMachine::ResolveIp(std::vector<AddressInfo> &ipInfoArray)
464 {
465 TELEPHONY_LOGD("Resolve Ip ifaceName_: %{private}s, domain_: %{private}s, mtu_: %{private}d, isAvailable_:"
466 " %{private}d, isRoaming_:%{private}d", netLinkInfo_->ifaceName_.c_str(),
467 netLinkInfo_->domain_.c_str(), netLinkInfo_->mtu_,
468 netSupplierInfo_->isAvailable_, netSupplierInfo_->isRoaming_);
469 netLinkInfo_->netAddrList_.clear();
470 for (AddressInfo ipInfo : ipInfoArray) {
471 INetAddr netAddr;
472 netAddr.address_ = ipInfo.ip;
473 netAddr.family_ = ipInfo.type;
474 netAddr.type_ = ipInfo.type;
475 netAddr.hostName_ = DEFAULT_HOSTNAME;
476 netAddr.netMask_ = ipInfo.netMask.length() > 0 ? ipInfo.netMask : DEFAULT_MASK;
477 netAddr.prefixlen_ = ipInfo.prefixLen;
478 netLinkInfo_->netAddrList_.push_back(netAddr);
479 }
480 }
481
ResolveDns(std::vector<AddressInfo> & dnsInfoArray)482 void CellularDataStateMachine::ResolveDns(std::vector<AddressInfo> &dnsInfoArray)
483 {
484 netLinkInfo_->dnsList_.clear();
485 for (AddressInfo dnsInfo : dnsInfoArray) {
486 INetAddr dnsAddr;
487 dnsAddr.address_ = dnsInfo.ip;
488 dnsAddr.family_ = dnsInfo.type;
489 dnsAddr.type_ = dnsInfo.type;
490 dnsAddr.hostName_ = DEFAULT_HOSTNAME;
491 dnsAddr.netMask_ = dnsInfo.netMask;
492 dnsAddr.prefixlen_ = dnsInfo.prefixLen;
493 netLinkInfo_->dnsList_.push_back(dnsAddr);
494 }
495 }
496
ResolveRoute(std::vector<AddressInfo> & routeInfoArray,const std::string & name)497 void CellularDataStateMachine::ResolveRoute(std::vector<AddressInfo> &routeInfoArray, const std::string &name)
498 {
499 netLinkInfo_->routeList_.clear();
500 for (AddressInfo routeInfo : routeInfoArray) {
501 NetManagerStandard::Route route;
502 route.iface_ = name;
503 route.gateway_.address_ = routeInfo.ip;
504 route.gateway_.family_ = routeInfo.type;
505 route.gateway_.type_ = routeInfo.type;
506 route.gateway_.hostName_ = DEFAULT_HOSTNAME;
507 route.gateway_.netMask_ = DEFAULT_MASK;
508 route.gateway_.prefixlen_ = routeInfo.prefixLen;
509 if (routeInfo.type == INetAddr::IpType::IPV4) {
510 route.destination_.address_ = ROUTED_IPV4;
511 } else {
512 route.destination_.address_ = ROUTED_IPV6;
513 }
514 route.destination_.family_ = routeInfo.type;
515 route.destination_.type_ = routeInfo.type;
516 route.destination_.hostName_ = DEFAULT_HOSTNAME;
517 route.destination_.netMask_ = DEFAULT_MASK;
518 route.destination_.prefixlen_ = 0;
519 netLinkInfo_->routeList_.push_back(route);
520 }
521 }
522
SetConnectionBandwidth(const uint32_t upBandwidth,const uint32_t downBandwidth)523 void CellularDataStateMachine::SetConnectionBandwidth(const uint32_t upBandwidth, const uint32_t downBandwidth)
524 {
525 upBandwidth_ = upBandwidth;
526 downBandwidth_ = downBandwidth;
527 }
528
SetConnectionTcpBuffer(const std::string & tcpBuffer)529 void CellularDataStateMachine::SetConnectionTcpBuffer(const std::string &tcpBuffer)
530 {
531 std::lock_guard<std::mutex> guard(mtx_);
532 tcpBuffer_ = tcpBuffer;
533 }
534
UpdateNetworkInfoIfInActive(SetupDataCallResultInfo & info)535 void CellularDataStateMachine::UpdateNetworkInfoIfInActive(SetupDataCallResultInfo &info)
536 {
537 if (cellularDataHandler_ == nullptr) {
538 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
539 return;
540 }
541 auto netInfo = std::make_shared<SetupDataCallResultInfo>(info);
542 netInfo->flag = apnId_;
543 cellularDataHandler_->SendEvent(CellularDataEventCode::MSG_DATA_CALL_LIST_CHANGED, netInfo);
544 }
545
SetReuseApnCap(uint64_t cap)546 void CellularDataStateMachine::SetReuseApnCap(uint64_t cap)
547 {
548 reuseApnCap_ = cap;
549 }
550
GetReuseApnCap() const551 uint64_t CellularDataStateMachine::GetReuseApnCap() const
552 {
553 return reuseApnCap_;
554 }
555
GetNetworkSlicePara(const DataConnectionParams & connectionParams,sptr<ApnItem> apn)556 void CellularDataStateMachine::GetNetworkSlicePara(const DataConnectionParams& connectionParams, sptr<ApnItem> apn)
557 {
558 std::string apnType = connectionParams.GetApnHolder()->GetApnType();
559 bool isNrSa = false;
560 int slotId = 0;
561 sptr<NetworkState> networkState(new NetworkState());
562 CoreManagerInner::GetInstance().GetNetworkStatus(slotId, networkState);
563 if (networkState->GetPsRadioTech() == RadioTech::RADIO_TECHNOLOGY_NR &&
564 networkState->GetNrState() == NrState::NR_NSA_STATE_SA_ATTACHED) {
565 isNrSa = true;
566 }
567 if (!isNrSa) {
568 return;
569 }
570 std::string dnn = apn->attr_.apn_;
571 TELEPHONY_LOGI("GetNetworkSlicePara apnType = %{public}s, dnn = %{public}s",
572 apnType.c_str(), dnn.c_str());
573 if (apnType.find("snssai") != std::string::npos) {
574 int32_t apnId = ApnManager::FindApnIdByApnName(apnType);
575 int32_t netcap = static_cast<int32_t>(ApnManager::FindCapabilityByApnId(apnId));
576 std::map<std::string, std::string> networkSliceParas;
577 DelayedSingleton<NetManagerStandard::NetworkSliceClient>::GetInstance()->GetRSDByNetCap(
578 netcap, networkSliceParas);
579 FillRSDFromNetCap(networkSliceParas, apn);
580 } else if (!dnn.empty()) {
581 std::string snssai;
582 uint8_t sscMode = 0;
583 DelayedSingleton<NetManagerStandard::NetworkSliceClient>::GetInstance()->GetRouteSelectionDescriptorByDNN(
584 dnn, snssai, sscMode);
585 apn->attr_.sscMode_ = sscMode;
586 if (!snssai.empty()) {
587 std::fill(apn->attr_.snssai_, apn->attr_.snssai_ + ApnItem::ALL_APN_ITEM_CHAR_LENGTH, '\0');
588 std::copy(snssai.begin(), snssai.end(), apn->attr_.snssai_);
589 apn->attr_.snssai_[std::min((int)snssai.size(), ApnItem::ALL_APN_ITEM_CHAR_LENGTH - 1)] = '\0';
590 }
591 TELEPHONY_LOGI("GetRouteSelectionDescriptorByDNN snssai = %{public}s, sscmode = %{public}d",
592 snssai.c_str(), sscMode);
593 }
594 }
595
FillRSDFromNetCap(std::map<std::string,std::string> networkSliceParas,sptr<ApnItem> apn)596 void CellularDataStateMachine::FillRSDFromNetCap(
597 std::map<std::string, std::string> networkSliceParas, sptr<ApnItem> apn)
598 {
599 if (networkSliceParas["sscmode"] != "0") {
600 int sscMode = 0;
601 std::from_chars(networkSliceParas["sscmode"].data(), networkSliceParas["sscmode"].data() +
602 networkSliceParas["sscmode"].size(), sscMode);
603 apn->attr_.sscMode_ = sscMode;
604 }
605 if (networkSliceParas["snssai"] != "") {
606 std::string snssai = networkSliceParas["snssai"];
607 std::fill(apn->attr_.snssai_, apn->attr_.snssai_ + ApnItem::ALL_APN_ITEM_CHAR_LENGTH, '\0');
608 std::copy(snssai.begin(), snssai.end(), apn->attr_.snssai_);
609 apn->attr_.snssai_[std::min((int)snssai.size(), ApnItem::ALL_APN_ITEM_CHAR_LENGTH - 1)] = '\0';
610 }
611 if (networkSliceParas["dnn"] != "") {
612 std::string dnn = networkSliceParas["dnn"];
613 std::fill(apn->attr_.apn_, apn->attr_.apn_ + ApnItem::ALL_APN_ITEM_CHAR_LENGTH, '\0');
614 std::copy(dnn.begin(), dnn.end(), apn->attr_.apn_);
615 apn->attr_.apn_[std::min((int)dnn.size(), ApnItem::ALL_APN_ITEM_CHAR_LENGTH - 1)] = '\0';
616 }
617 if (networkSliceParas["pdusessiontype"] != "0") {
618 std::string pdusessiontype = networkSliceParas["pdusessiontype"];
619 std::fill(apn->attr_.protocol_, apn->attr_.protocol_ + ApnItem::ALL_APN_ITEM_CHAR_LENGTH, '\0');
620 std::copy(pdusessiontype.begin(), pdusessiontype.end(), apn->attr_.protocol_);
621 apn->attr_.apn_[std::min((int)pdusessiontype.size(), ApnItem::ALL_APN_ITEM_CHAR_LENGTH - 1)] = '\0';
622 }
623 TELEPHONY_LOGI("FillRSD: snssai = %{public}s, sscmode = %{public}s, dnn = %{public}s, pdusession = %{public}s",
624 networkSliceParas["snssai"].c_str(), networkSliceParas["sscmode"].c_str(), networkSliceParas["dnn"].c_str(),
625 networkSliceParas["pdusessiontype"].c_str());
626 }
627 } // namespace Telephony
628 } // namespace OHOS
629