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 return;
201 }
202 if (netLinkInfo_ == nullptr || netSupplierInfo_ == nullptr) {
203 TELEPHONY_LOGE("Slot%{public}d: start update net info,but netLinkInfo or netSupplierInfo is null!", slotId);
204 return;
205 }
206 bool roamingState = false;
207 if (CoreManagerInner::GetInstance().GetPsRoamingState(slotId) > 0) {
208 roamingState = true;
209 }
210 netLinkInfo_->ifaceName_ = dataCallInfo.netPortName;
211 netLinkInfo_->mtu_ = (dataCallInfo.maxTransferUnit == 0) ? DEFAULT_MTU : dataCallInfo.maxTransferUnit;
212 netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
213 ResolveIp(ipInfoArray);
214 ResolveDns(dnsInfoArray);
215 ResolveRoute(routeInfoArray, dataCallInfo.netPortName);
216 netSupplierInfo_->isAvailable_ = (dataCallInfo.active > 0);
217 netSupplierInfo_->isRoaming_ = roamingState;
218 netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
219 netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
220 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
221 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
222 netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
223 netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
224 }
225
UpdateNetworkInfo()226 void CellularDataStateMachine::UpdateNetworkInfo()
227 {
228 int32_t slotId = GetSlotId();
229 CellularDataNetAgent &netAgent = CellularDataNetAgent::GetInstance();
230 netLinkInfo_->tcpBufferSizes_ = tcpBuffer_;
231 netSupplierInfo_->linkUpBandwidthKbps_ = upBandwidth_;
232 netSupplierInfo_->linkDownBandwidthKbps_ = downBandwidth_;
233 int32_t supplierId = netAgent.GetSupplierId(slotId, capability_);
234 netAgent.UpdateNetSupplierInfo(supplierId, netSupplierInfo_);
235 netAgent.UpdateNetLinkInfo(supplierId, netLinkInfo_);
236 }
237
ResolveIp(std::vector<AddressInfo> & ipInfoArray)238 void CellularDataStateMachine::ResolveIp(std::vector<AddressInfo> &ipInfoArray)
239 {
240 TELEPHONY_LOGD("Resolve Ip ifaceName_: %{private}s, domain_: %{private}s, mtu_: %{private}d, isAvailable_:"
241 " %{private}d, isRoaming_:%{private}d", netLinkInfo_->ifaceName_.c_str(),
242 netLinkInfo_->domain_.c_str(), netLinkInfo_->mtu_,
243 netSupplierInfo_->isAvailable_, netSupplierInfo_->isRoaming_);
244 netLinkInfo_->netAddrList_.clear();
245 for (AddressInfo ipInfo : ipInfoArray) {
246 INetAddr netAddr;
247 netAddr.address_ = ipInfo.ip;
248 netAddr.family_ = ipInfo.type;
249 netAddr.type_ = ipInfo.type;
250 netAddr.hostName_ = DEFAULT_HOSTNAME;
251 netAddr.netMask_ = ipInfo.netMask.length() > 0 ? ipInfo.netMask : DEFAULT_MASK;
252 netAddr.prefixlen_ = ipInfo.prefixLen;
253 netLinkInfo_->netAddrList_.push_back(netAddr);
254 }
255 }
256
ResolveDns(std::vector<AddressInfo> & dnsInfoArray)257 void CellularDataStateMachine::ResolveDns(std::vector<AddressInfo> &dnsInfoArray)
258 {
259 netLinkInfo_->dnsList_.clear();
260 for (AddressInfo dnsInfo : dnsInfoArray) {
261 INetAddr dnsAddr;
262 dnsAddr.address_ = dnsInfo.ip;
263 dnsAddr.family_ = dnsInfo.type;
264 dnsAddr.type_ = dnsInfo.type;
265 dnsAddr.hostName_ = DEFAULT_HOSTNAME;
266 dnsAddr.netMask_ = dnsInfo.netMask;
267 dnsAddr.prefixlen_ = dnsInfo.prefixLen;
268 netLinkInfo_->dnsList_.push_back(dnsAddr);
269 }
270 }
271
ResolveRoute(std::vector<AddressInfo> & routeInfoArray,const std::string & name)272 void CellularDataStateMachine::ResolveRoute(std::vector<AddressInfo> &routeInfoArray, const std::string &name)
273 {
274 netLinkInfo_->routeList_.clear();
275 for (AddressInfo routeInfo : routeInfoArray) {
276 NetManagerStandard::Route route;
277 route.iface_ = name;
278 route.gateway_.address_ = routeInfo.ip;
279 route.gateway_.family_ = routeInfo.type;
280 route.gateway_.type_ = routeInfo.type;
281 route.gateway_.hostName_ = DEFAULT_HOSTNAME;
282 route.gateway_.netMask_ = DEFAULT_MASK;
283 route.gateway_.prefixlen_ = routeInfo.prefixLen;
284 route.destination_.address_ = "0.0.0.0";
285 route.destination_.family_ = routeInfo.type;
286 route.destination_.type_ = routeInfo.type;
287 route.destination_.hostName_ = DEFAULT_HOSTNAME;
288 route.destination_.netMask_ = DEFAULT_MASK;
289 route.destination_.prefixlen_ = 0;
290 netLinkInfo_->routeList_.push_back(route);
291 }
292 }
293
SetConnectionBandwidth(const uint32_t upBandwidth,const uint32_t downBandwidth)294 void CellularDataStateMachine::SetConnectionBandwidth(const uint32_t upBandwidth, const uint32_t downBandwidth)
295 {
296 upBandwidth_ = upBandwidth;
297 downBandwidth_ = downBandwidth;
298 }
299
SetConnectionTcpBuffer(const std::string & tcpBuffer)300 void CellularDataStateMachine::SetConnectionTcpBuffer(const std::string &tcpBuffer)
301 {
302 tcpBuffer_ = tcpBuffer;
303 }
304 } // namespace Telephony
305 } // namespace OHOS
306