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 "core_manager_inner.h"
19 #include "radio_event.h"
20 #include "telephony_log_wrapper.h"
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 "default.h"
28 #include "disconnecting.h"
29 #include "inactive.h"
30
31 namespace OHOS {
32 using namespace NetManagerStandard;
33 namespace Telephony {
IsInactiveState() const34 bool CellularDataStateMachine::IsInactiveState() const
35 {
36 return currentState_ == inActiveState_;
37 }
38
SetCapability(uint64_t capability)39 void CellularDataStateMachine::SetCapability(uint64_t capability)
40 {
41 capability_ = capability;
42 }
43
GetCapability() const44 uint64_t CellularDataStateMachine::GetCapability() const
45 {
46 return capability_;
47 }
48
GetCid() const49 int32_t CellularDataStateMachine::GetCid() const
50 {
51 return cid_;
52 }
53
SetCid(const int32_t cid)54 void CellularDataStateMachine::SetCid(const int32_t cid)
55 {
56 cid_ = cid;
57 }
58
GetSlotId() const59 int32_t CellularDataStateMachine::GetSlotId() const
60 {
61 if (cdConnectionManager_ == nullptr) {
62 TELEPHONY_LOGE("cdConnectionManager_ is null");
63 return DEFAULT_SIM_SLOT_ID;
64 }
65 return cdConnectionManager_->GetSlotId();
66 }
67
GetApnItem() const68 sptr<ApnItem> CellularDataStateMachine::GetApnItem() const
69 {
70 return apnItem_;
71 }
72
DoConnect(const DataConnectionParams & connectionParams)73 void CellularDataStateMachine::DoConnect(const DataConnectionParams &connectionParams)
74 {
75 if (connectionParams.GetApnHolder() == nullptr) {
76 TELEPHONY_LOGE("apnHolder is null");
77 return;
78 }
79 apnId_ = ApnManager::FindApnIdByApnName(connectionParams.GetApnHolder()->GetApnType());
80 sptr<ApnItem> apn = connectionParams.GetApnHolder()->GetCurrentApn();
81 apnItem_ = apn;
82 if (apnItem_ == nullptr) {
83 TELEPHONY_LOGE("apnItem is null");
84 return;
85 }
86 const int32_t slotId = GetSlotId();
87 int32_t radioTech = static_cast<int32_t>(RadioTech::RADIO_TECHNOLOGY_INVALID);
88 CoreManagerInner::GetInstance().GetPsRadioTech(slotId, radioTech);
89 ActivateDataParam activeDataParam;
90 activeDataParam.param = connectId_;
91 activeDataParam.radioTechnology = radioTech;
92 activeDataParam.allowRoaming = connectionParams.GetRoamingState();
93 activeDataParam.isRoaming = connectionParams.GetUserDataRoaming();
94 activeDataParam.dataProfile.profileId = apn->attr_.profileId_;
95 activeDataParam.dataProfile.apn = apn->attr_.apn_;
96 activeDataParam.dataProfile.protocol = apn->attr_.protocol_;
97 activeDataParam.dataProfile.verType = apn->attr_.authType_;
98 activeDataParam.dataProfile.userName = apn->attr_.user_;
99 activeDataParam.dataProfile.password = apn->attr_.password_;
100 activeDataParam.dataProfile.roamingProtocol = apn->attr_.roamingProtocol_;
101 TELEPHONY_LOGI("Slot%{public}d: Activate PDP context (%{public}d, %{public}s, %{public}s, %{public}s)", slotId,
102 apn->attr_.profileId_, apn->attr_.apn_, apn->attr_.protocol_, apn->attr_.types_);
103 int32_t result = CoreManagerInner::GetInstance().ActivatePdpContext(slotId, RadioEvent::RADIO_RIL_SETUP_DATA_CALL,
104 activeDataParam, stateMachineEventHandler_);
105 if (result != TELEPHONY_ERR_SUCCESS) {
106 TELEPHONY_LOGE("Slot%{public}d: Activate PDP context failed", slotId);
107 CellularDataHiSysEvent::WriteDataActivateFaultEvent(
108 slotId, SWITCH_ON, CellularDataErrorCode::DATA_ERROR_PDP_ACTIVATE_FAIL, "Activate PDP context failed");
109 }
110 if (stateMachineEventHandler_ == nullptr) {
111 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
112 return;
113 }
114 stateMachineEventHandler_->SendEvent(
115 CellularDataEventCode::MSG_CONNECT_TIMEOUT_CHECK, connectId_, CONNECTION_DISCONNECTION_TIMEOUT);
116 }
117
FreeConnection(const DataDisconnectParams & params)118 void CellularDataStateMachine::FreeConnection(const DataDisconnectParams ¶ms)
119 {
120 const int32_t slotId = GetSlotId();
121 int32_t apnId = ApnManager::FindApnIdByApnName(params.GetApnType());
122 TELEPHONY_LOGI("Slot%{public}d: Deactivate PDP context cid:%{public}d type:%{public}s id:%{public}d",
123 slotId, cid_, params.GetApnType().c_str(), apnId);
124 DeactivateDataParam deactivateDataParam;
125 deactivateDataParam.param = connectId_;
126 deactivateDataParam.cid = cid_;
127 deactivateDataParam.reason = static_cast<int32_t>(params.GetReason());
128 int32_t result = CoreManagerInner::GetInstance().DeactivatePdpContext(slotId,
129 RadioEvent::RADIO_RIL_DEACTIVATE_DATA_CALL, deactivateDataParam, stateMachineEventHandler_);
130 if (result != TELEPHONY_ERR_SUCCESS) {
131 TELEPHONY_LOGE("Slot%{public}d: Deactivate PDP context failed", slotId);
132 CellularDataHiSysEvent::WriteDataActivateFaultEvent(
133 slotId, SWITCH_OFF, CellularDataErrorCode::DATA_ERROR_PDP_DEACTIVATE_FAIL, "Deactivate PDP context failed");
134 }
135 if (stateMachineEventHandler_ == nullptr) {
136 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr");
137 return;
138 }
139 stateMachineEventHandler_->SendEvent(
140 CellularDataEventCode::MSG_DISCONNECT_TIMEOUT_CHECK, connectId_, CONNECTION_DISCONNECTION_TIMEOUT);
141 }
142
operator ==(const CellularDataStateMachine & stateMachine) const143 bool CellularDataStateMachine::operator==(const CellularDataStateMachine &stateMachine) const
144 {
145 return this->GetCid() == stateMachine.GetCid();
146 }
147
Init()148 void CellularDataStateMachine::Init()
149 {
150 activeState_ = std::make_unique<Active>(
151 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Active").release();
152 inActiveState_ = std::make_unique<Inactive>(
153 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Inactive").release();
154 activatingState_ = std::make_unique<Activating>(
155 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Activating").release();
156 disconnectingState_ = std::make_unique<Disconnecting>(
157 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Disconnecting").release();
158 defaultState_ = std::make_unique<Default>(
159 std::weak_ptr<CellularDataStateMachine>(shared_from_this()), "Default").release();
160 netSupplierInfo_ = std::make_unique<NetSupplierInfo>().release();
161 netLinkInfo_ = std::make_unique<NetLinkInfo>().release();
162 if (activeState_ == nullptr || inActiveState_ == nullptr || activatingState_ == nullptr ||
163 disconnectingState_ == nullptr || defaultState_ == nullptr || netSupplierInfo_ == nullptr ||
164 netLinkInfo_ == nullptr) {
165 TELEPHONY_LOGE("memory allocation failed");
166 return;
167 }
168 activeState_->SetParentState(defaultState_);
169 inActiveState_->SetParentState(defaultState_);
170 activatingState_->SetParentState(defaultState_);
171 disconnectingState_->SetParentState(defaultState_);
172 StateMachine::SetOriginalState(inActiveState_);
173 StateMachine::Start();
174 }
175
SetCurrentState(const sptr<State> && state)176 void CellularDataStateMachine::SetCurrentState(const sptr<State> &&state)
177 {
178 currentState_ = std::move(state);
179 }
180
GetCurrentState() const181 sptr<State> CellularDataStateMachine::GetCurrentState() const
182 {
183 return currentState_;
184 }
185
UpdateNetworkInfo(const SetupDataCallResultInfo & dataCallInfo)186 void CellularDataStateMachine::UpdateNetworkInfo(const SetupDataCallResultInfo &dataCallInfo)
187 {
188 std::lock_guard<std::mutex> guard(mtx_);
189 int32_t slotId = GetSlotId();
190 TELEPHONY_LOGD("Slot%{private}d: dataCall, capability:%{private}" PRIu64", state:%{private}d, addr:%{private}s, "
191 "dns: %{private}s, gw: %{private}s", slotId, capability_, dataCallInfo.reason,
192 dataCallInfo.address.c_str(), dataCallInfo.dns.c_str(), dataCallInfo.gateway.c_str());
193 std::vector<AddressInfo> ipInfoArray = CellularDataUtils::ParseIpAddr(dataCallInfo.address);
194 std::vector<AddressInfo> dnsInfoArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.dns);
195 std::vector<AddressInfo> dnsSecArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.dnsSec);
196 dnsInfoArray.insert(dnsInfoArray.end(), dnsSecArray.begin(), dnsSecArray.end());
197 std::vector<AddressInfo> routeInfoArray = CellularDataUtils::ParseNormalIpAddr(dataCallInfo.gateway);
198 if (ipInfoArray.empty() || dnsInfoArray.empty() || routeInfoArray.empty()) {
199 TELEPHONY_LOGE("Verifying network Information(ipInfoArray or dnsInfoArray or routeInfoArray empty)");
200 }
201 if (netLinkInfo_ == nullptr || netSupplierInfo_ == nullptr) {
202 TELEPHONY_LOGE("Slot%{public}d: start update net info,but netLinkInfo or netSupplierInfo is null!", slotId);
203 return;
204 }
205 bool roamingState = false;
206 if (CoreManagerInner::GetInstance().GetPsRoamingState(slotId) > 0) {
207 roamingState = true;
208 }
209 netLinkInfo_->ifaceName_ = dataCallInfo.netPortName;
210 netLinkInfo_->mtu_ = (dataCallInfo.maxTransferUnit == 0) ? DEFAULT_MTU : dataCallInfo.maxTransferUnit;
211 netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
212 ResolveIp(ipInfoArray);
213 ResolveDns(dnsInfoArray);
214 ResolveRoute(routeInfoArray, dataCallInfo.netPortName);
215 netSupplierInfo_->isAvailable_ = (dataCallInfo.active > 0);
216 netSupplierInfo_->isRoaming_ = roamingState;
217 netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
218 netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
219 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
220 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
221 netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
222 if (netSupplierInfo_->isAvailable_) {
223 netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
224 }
225 }
226
UpdateNetworkInfo()227 void CellularDataStateMachine::UpdateNetworkInfo()
228 {
229 int32_t slotId = GetSlotId();
230 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
231 netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
232 netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
233 netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
234 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
235 netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
236 if (netSupplierInfo_->isAvailable_) {
237 netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
238 }
239 }
240
ResolveIp(std::vector<AddressInfo> & ipInfoArray)241 void CellularDataStateMachine::ResolveIp(std::vector<AddressInfo> &ipInfoArray)
242 {
243 TELEPHONY_LOGD("Resolve Ip ifaceName_: %{private}s, domain_: %{private}s, mtu_: %{private}d, isAvailable_:"
244 " %{private}d, isRoaming_:%{private}d", netLinkInfo_->ifaceName_.c_str(),
245 netLinkInfo_->domain_.c_str(), netLinkInfo_->mtu_,
246 netSupplierInfo_->isAvailable_, netSupplierInfo_->isRoaming_);
247 netLinkInfo_->netAddrList_.clear();
248 for (AddressInfo ipInfo : ipInfoArray) {
249 INetAddr netAddr;
250 netAddr.address_ = ipInfo.ip;
251 netAddr.family_ = ipInfo.type;
252 netAddr.type_ = ipInfo.type;
253 netAddr.hostName_ = DEFAULT_HOSTNAME;
254 netAddr.netMask_ = ipInfo.netMask.length() > 0 ? ipInfo.netMask : DEFAULT_MASK;
255 netAddr.prefixlen_ = ipInfo.prefixLen;
256 netLinkInfo_->netAddrList_.push_back(netAddr);
257 }
258 }
259
ResolveDns(std::vector<AddressInfo> & dnsInfoArray)260 void CellularDataStateMachine::ResolveDns(std::vector<AddressInfo> &dnsInfoArray)
261 {
262 netLinkInfo_->dnsList_.clear();
263 for (AddressInfo dnsInfo : dnsInfoArray) {
264 INetAddr dnsAddr;
265 dnsAddr.address_ = dnsInfo.ip;
266 dnsAddr.family_ = dnsInfo.type;
267 dnsAddr.type_ = dnsInfo.type;
268 dnsAddr.hostName_ = DEFAULT_HOSTNAME;
269 dnsAddr.netMask_ = dnsInfo.netMask;
270 dnsAddr.prefixlen_ = dnsInfo.prefixLen;
271 netLinkInfo_->dnsList_.push_back(dnsAddr);
272 }
273 }
274
ResolveRoute(std::vector<AddressInfo> & routeInfoArray,const std::string & name)275 void CellularDataStateMachine::ResolveRoute(std::vector<AddressInfo> &routeInfoArray, const std::string &name)
276 {
277 netLinkInfo_->routeList_.clear();
278 for (AddressInfo routeInfo : routeInfoArray) {
279 NetManagerStandard::Route route;
280 route.iface_ = name;
281 route.gateway_.address_ = routeInfo.ip;
282 route.gateway_.family_ = routeInfo.type;
283 route.gateway_.type_ = routeInfo.type;
284 route.gateway_.hostName_ = DEFAULT_HOSTNAME;
285 route.gateway_.netMask_ = DEFAULT_MASK;
286 route.gateway_.prefixlen_ = routeInfo.prefixLen;
287 route.destination_.address_ = "0.0.0.0";
288 route.destination_.family_ = routeInfo.type;
289 route.destination_.type_ = routeInfo.type;
290 route.destination_.hostName_ = DEFAULT_HOSTNAME;
291 route.destination_.netMask_ = DEFAULT_MASK;
292 route.destination_.prefixlen_ = 0;
293 netLinkInfo_->routeList_.push_back(route);
294 }
295 }
296
SetConnectionBandwidth(const uint32_t upBandwidth,const uint32_t downBandwidth)297 void CellularDataStateMachine::SetConnectionBandwidth(const uint32_t upBandwidth, const uint32_t downBandwidth)
298 {
299 upBandwidth_ = upBandwidth;
300 downBandwidth_ = downBandwidth;
301 }
302
SetConnectionTcpBuffer(const std::string & tcpBuffer)303 void CellularDataStateMachine::SetConnectionTcpBuffer(const std::string &tcpBuffer)
304 {
305 tcpBuffer_ = tcpBuffer;
306 }
307 } // namespace Telephony
308 } // namespace OHOS
309