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 "activating.h"
17
18 #include "cellular_data_event_code.h"
19 #include "cellular_data_hisysevent.h"
20 #include "tel_ril_data_parcel.h"
21 #include "inactive.h"
22 #include "radio_event.h"
23 #include "telephony_log_wrapper.h"
24 #include "apn_manager.h"
25
26 namespace OHOS {
27 namespace Telephony {
28 static const int32_t MAX_RIL_ERR_RETRY_COUNT = 3;
29
StateBegin()30 void Activating::StateBegin()
31 {
32 TELEPHONY_LOGI("Enter activating state");
33 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
34 if (stateMachine == nullptr) {
35 TELEPHONY_LOGE("stateMachine is null");
36 return;
37 }
38 isActive_ = true;
39 stateMachine->SetCurrentState(sptr<State>(this));
40 }
41
StateEnd()42 void Activating::StateEnd()
43 {
44 TELEPHONY_LOGI("Exit activating state");
45 isActive_ = false;
46 }
47
RilActivatePdpContextDone(const AppExecFwk::InnerEvent::Pointer & event)48 bool Activating::RilActivatePdpContextDone(const AppExecFwk::InnerEvent::Pointer &event)
49 {
50 if (event == nullptr) {
51 TELEPHONY_LOGE("event is null");
52 return false;
53 }
54 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
55 if (stateMachine == nullptr) {
56 TELEPHONY_LOGE("stateMachine is null");
57 return false;
58 }
59 std::shared_ptr<SetupDataCallResultInfo> resultInfo = event->GetSharedObject<SetupDataCallResultInfo>();
60 if (resultInfo == nullptr) {
61 TELEPHONY_LOGI("resultInfo null, goto RilErrorResponse");
62 return RilErrorResponse(event);
63 }
64 rilErrTryCount_ = 0;
65 TELEPHONY_LOGI("callDone active: %{public}d flag: %{public}d, cid: %{public}d, reason: %{public}d",
66 resultInfo->active, resultInfo->flag, resultInfo->cid, resultInfo->reason);
67 if (stateMachine->connectId_ != resultInfo->flag) {
68 TELEPHONY_LOGE("connectId is %{public}d, flag is %{public}d", stateMachine->connectId_, resultInfo->flag);
69 return false;
70 }
71 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
72 if (inActive == nullptr) {
73 TELEPHONY_LOGE("Inactive is null");
74 return false;
75 }
76 stateMachine->SetCid(resultInfo->cid);
77 if (resultInfo->reason != 0 || resultInfo->active == 0) {
78 resultInfo->retryScene = static_cast<int32_t>(RetryScene::RETRY_SCENE_SETUP_DATA);
79 inActive->SetDataCallResultInfo(resultInfo);
80 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
81 stateMachine->TransitionTo(stateMachine->inActiveState_);
82 return true;
83 }
84 if (stateMachine->cdConnectionManager_ != nullptr) {
85 stateMachine->cdConnectionManager_->AddActiveConnectionByCid(stateMachine_.lock());
86 } else {
87 TELEPHONY_LOGE("cdConnectionManager is null");
88 }
89 stateMachine->DeferEvent(std::move(event));
90 stateMachine->TransitionTo(stateMachine->activeState_);
91 return true;
92 }
93
RilErrorResponse(const AppExecFwk::InnerEvent::Pointer & event)94 bool Activating::RilErrorResponse(const AppExecFwk::InnerEvent::Pointer &event)
95 {
96 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
97 if (stateMachine == nullptr) {
98 TELEPHONY_LOGE("stateMachine is null");
99 return false;
100 }
101 std::shared_ptr<RadioResponseInfo> rilInfo = event->GetSharedObject<RadioResponseInfo>();
102 if (rilInfo == nullptr) {
103 TELEPHONY_LOGE("SetupDataCallResultInfo and RadioResponseInfo is null");
104 return false;
105 }
106 if (stateMachine->connectId_ != rilInfo->flag) {
107 TELEPHONY_LOGE("connectId is %{public}d, flag is %{public}d", stateMachine->connectId_, rilInfo->flag);
108 return false;
109 }
110 TELEPHONY_LOGI("RadioResponseInfo flag:%{public}d error:%{public}d", rilInfo->flag, rilInfo->error);
111 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
112 if (inActive == nullptr) {
113 TELEPHONY_LOGE("Inactive is null");
114 return false;
115 }
116 ++rilErrTryCount_;
117 if (rilErrTryCount_ > MAX_RIL_ERR_RETRY_COUNT) {
118 rilErrTryCount_ = 0;
119 inActive->SetPdpErrorReason(PdpErrorReason::PDP_ERR_TO_CLEAR_CONNECTION);
120 } else {
121 inActive->SetPdpErrorReason(PdpErrorReason::PDP_ERR_RETRY);
122 }
123 CellularDataHiSysEvent::WriteDataActivateFaultEvent(INVALID_PARAMETER, SWITCH_ON,
124 CellularDataErrorCode::DATA_ERROR_RADIO_RESPONSEINFO_ERROR,
125 "ErrType " + std::to_string(static_cast<int32_t>(rilInfo->error)));
126 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
127 stateMachine->TransitionTo(stateMachine->inActiveState_);
128 return true;
129 }
130
ProcessConnectTimeout(const AppExecFwk::InnerEvent::Pointer & event)131 void Activating::ProcessConnectTimeout(const AppExecFwk::InnerEvent::Pointer &event)
132 {
133 if (event == nullptr) {
134 TELEPHONY_LOGE("event is null");
135 return;
136 }
137 int32_t connectId = event->GetParam();
138 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
139 if (stateMachine == nullptr) {
140 TELEPHONY_LOGE("stateMachine is null");
141 return;
142 }
143 if (connectId != stateMachine->connectId_) {
144 return;
145 }
146 int64_t currentTime =
147 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
148 .count();
149 if ((currentTime - stateMachine->startTimeConnectTimeoutTask_) < CONNECTION_TASK_TIME) {
150 TELEPHONY_LOGE("ProcessConnectTimeout error, delay: %{public}lld",
151 static_cast<long long>(currentTime - stateMachine->startTimeConnectTimeoutTask_));
152 return;
153 }
154 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
155 if (inActive == nullptr) {
156 TELEPHONY_LOGE("Inactive is null");
157 return;
158 }
159 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
160 inActive->SetPdpErrorReason(PdpErrorReason::PDP_ERR_RETRY);
161 stateMachine->TransitionTo(stateMachine->inActiveState_);
162 std::string apnType = ApnManager::FindApnNameByApnId(stateMachine->apnId_);
163 CellularDataHiSysEvent::WriteDataActivateFaultEvent(stateMachine->GetSlotId(), SWITCH_ON,
164 CellularDataErrorCode::DATA_ERROR_DATA_ACTIVATE_TIME_OUT, apnType + " activate time out.");
165 TELEPHONY_LOGI("ProcessConnectTimeout");
166 }
167
StateProcess(const AppExecFwk::InnerEvent::Pointer & event)168 bool Activating::StateProcess(const AppExecFwk::InnerEvent::Pointer &event)
169 {
170 if (event == nullptr) {
171 TELEPHONY_LOGE("event is null");
172 return false;
173 }
174 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
175 if (stateMachine == nullptr) {
176 TELEPHONY_LOGE("stateMachine is null");
177 return false;
178 }
179 bool retVal = false;
180 uint32_t eventCode = event->GetInnerEventId();
181 switch (eventCode) {
182 case CellularDataEventCode::MSG_SM_DRS_OR_RAT_CHANGED:
183 [[fallthrough]];
184 case CellularDataEventCode::MSG_SM_CONNECT:
185 TELEPHONY_LOGI("Activating::MSG_SM_CONNECT");
186 stateMachine->DeferEvent(std::move(event));
187 retVal = PROCESSED;
188 break;
189 case RadioEvent::RADIO_RIL_SETUP_DATA_CALL: {
190 retVal = RilActivatePdpContextDone(event);
191 break;
192 }
193 case CellularDataEventCode::MSG_SM_GET_LAST_FAIL_DONE:
194 stateMachine->TransitionTo(stateMachine->inActiveState_);
195 retVal = PROCESSED;
196 break;
197 case CellularDataEventCode::MSG_GET_RIL_BANDWIDTH:
198 stateMachine->DeferEvent(std::move(event));
199 break;
200 case CellularDataEventCode::MSG_CONNECT_TIMEOUT_CHECK:
201 ProcessConnectTimeout(event);
202 retVal = PROCESSED;
203 break;
204 default:
205 TELEPHONY_LOGE("eventCode:%{public}d goto default", eventCode);
206 break;
207 }
208 return retVal;
209 }
210 } // namespace Telephony
211 } // namespace OHOS