• 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 #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 &params)
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