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 "hril_data_parcel.h"
21 #include "inactive.h"
22 #include "radio_event.h"
23 #include "telephony_log_wrapper.h"
24
25 namespace OHOS {
26 namespace Telephony {
StateBegin()27 void Activating::StateBegin()
28 {
29 TELEPHONY_LOGI("Enter activating state");
30 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
31 if (stateMachine == nullptr) {
32 TELEPHONY_LOGE("stateMachine is null");
33 return;
34 }
35 isActive_ = true;
36 stateMachine->SetCurrentState(sptr<State>(this));
37 }
38
StateEnd()39 void Activating::StateEnd()
40 {
41 TELEPHONY_LOGI("Exit activating state");
42 isActive_ = false;
43 }
44
RilActivatePdpContextDone(const AppExecFwk::InnerEvent::Pointer & event)45 bool Activating::RilActivatePdpContextDone(const AppExecFwk::InnerEvent::Pointer &event)
46 {
47 if (event == nullptr) {
48 TELEPHONY_LOGE("event is null");
49 return false;
50 }
51 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
52 if (stateMachine == nullptr) {
53 TELEPHONY_LOGE("stateMachine is null");
54 return false;
55 }
56 std::shared_ptr<SetupDataCallResultInfo> resultInfo = event->GetSharedObject<SetupDataCallResultInfo>();
57 if (resultInfo == nullptr) {
58 TELEPHONY_LOGE("result info is null");
59 return RilErrorResponse(event);
60 }
61 TELEPHONY_LOGI("callDone active: %{public}d flag: %{public}d, cid: %{public}d, reason: %{public}d",
62 resultInfo->active, resultInfo->flag, resultInfo->cid, resultInfo->reason);
63 if (stateMachine->connectId_ != resultInfo->flag) {
64 TELEPHONY_LOGE("connectId is %{public}d, flag is %{public}d", stateMachine->connectId_, resultInfo->flag);
65 return false;
66 }
67 if (resultInfo->reason != 0) {
68 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
69 DisConnectionReason disReason = DataCallPdpError(resultInfo->reason);
70 inActive->SetReason(disReason);
71 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
72 stateMachine->TransitionTo(stateMachine->inActiveState_);
73 return true;
74 }
75 if (resultInfo->active == 0) {
76 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
77 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
78 inActive->SetReason(DisConnectionReason::REASON_RETRY_CONNECTION);
79 stateMachine->TransitionTo(stateMachine->inActiveState_);
80 return true;
81 }
82 stateMachine->SetCid(resultInfo->cid);
83 if (stateMachine->cdConnectionManager_ != nullptr) {
84 stateMachine->cdConnectionManager_->AddActiveConnectionByCid(stateMachine_.lock());
85 } else {
86 TELEPHONY_LOGE("cdConnectionManager is null");
87 }
88 stateMachine->DeferEvent(std::move(event));
89 stateMachine->TransitionTo(stateMachine->activeState_);
90 return true;
91 }
92
DataCallPdpError(int32_t reason)93 DisConnectionReason Activating::DataCallPdpError(int32_t reason)
94 {
95 switch (reason) {
96 case HRilPdpErrorReason::HRIL_PDP_ERR_RETRY:
97 case HRilPdpErrorReason::HRIL_PDP_ERR_UNKNOWN:
98 case HRilPdpErrorReason::HRIL_PDP_ERR_SHORTAGE_RESOURCES:
99 case HRilPdpErrorReason::HRIL_PDP_ERR_ACTIVATION_REJECTED_UNSPECIFIED:
100 case HRilPdpErrorReason::HRIL_PDP_ERR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER:
101 case HRilPdpErrorReason::HRIL_PDP_ERR_APN_NOT_SUPPORTED_IN_CURRENT_RAT_PLMN:
102 case HRilPdpErrorReason::HRIL_PDP_ERR_APN_RESTRICTION_VALUE_INCOMPATIBLE: {
103 TELEPHONY_LOGE("DataCall: The connection failed, try again");
104 return DisConnectionReason::REASON_RETRY_CONNECTION;
105 }
106 case HRilPdpErrorReason::HRIL_PDP_ERR_MULT_ACCESSES_PDN_NOT_ALLOWED:
107 case HRilPdpErrorReason::HRIL_PDP_ERR_OPERATOR_DETERMINED_BARRING:
108 case HRilPdpErrorReason::HRIL_PDP_ERR_MISSING_OR_UNKNOWN_APN:
109 case HRilPdpErrorReason::HRIL_PDP_ERR_UNKNOWN_PDP_ADDR_OR_TYPE:
110 case HRilPdpErrorReason::HRIL_PDP_ERR_USER_VERIFICATION:
111 case HRilPdpErrorReason::HRIL_PDP_ERR_ACTIVATION_REJECTED_GGSN:
112 case HRilPdpErrorReason::HRIL_PDP_ERR_SERVICE_OPTION_NOT_SUPPORTED:
113 case HRilPdpErrorReason::HRIL_PDP_ERR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED:
114 case HRilPdpErrorReason::HRIL_PDP_ERR_NSAPI_ALREADY_USED:
115 case HRilPdpErrorReason::HRIL_PDP_ERR_IPV4_ONLY_ALLOWED:
116 case HRilPdpErrorReason::HRIL_PDP_ERR_IPV6_ONLY_ALLOWED:
117 case HRilPdpErrorReason::HRIL_PDP_ERR_IPV4V6_ONLY_ALLOWED:
118 case HRilPdpErrorReason::HRIL_PDP_ERR_NON_IP_ONLY_ALLOWED:
119 case HRilPdpErrorReason::HRIL_PDP_ERR_MAX_NUM_OF_PDP_CONTEXTS:
120 case HRilPdpErrorReason::HRIL_PDP_ERR_PROTOCOL_ERRORS: {
121 TELEPHONY_LOGE("DataCall: The connection failed, not try again");
122 return DisConnectionReason::REASON_CLEAR_CONNECTION;
123 }
124 default: {
125 if (reason > HRIL_PDP_ERR_PROTOCOL_ERRORS && reason < HRIL_PDP_ERR_APN_RESTRICTION_VALUE_INCOMPATIBLE) {
126 TELEPHONY_LOGE("DataCall: The protocol error, not try again");
127 return DisConnectionReason::REASON_CLEAR_CONNECTION;
128 }
129 break;
130 }
131 }
132 TELEPHONY_LOGE("DataCall: Connection failed for an unsupported reason, not try again");
133 return DisConnectionReason::REASON_CLEAR_CONNECTION;
134 }
135
RilErrorResponse(const AppExecFwk::InnerEvent::Pointer & event)136 bool Activating::RilErrorResponse(const AppExecFwk::InnerEvent::Pointer &event)
137 {
138 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
139 if (stateMachine == nullptr) {
140 TELEPHONY_LOGE("stateMachine is null");
141 return false;
142 }
143 std::shared_ptr<HRilRadioResponseInfo> rilInfo = event->GetSharedObject<HRilRadioResponseInfo>();
144 if (rilInfo == nullptr) {
145 TELEPHONY_LOGE("SetupDataCallResultInfo and HRilRadioResponseInfo is null");
146 return false;
147 }
148 if (stateMachine->connectId_ != rilInfo->flag) {
149 TELEPHONY_LOGE("connectId is %{public}d, flag is %{public}d", stateMachine->connectId_, rilInfo->flag);
150 return false;
151 }
152 TELEPHONY_LOGI("HRilRadioResponseInfo flag:%{public}d error:%{public}d", rilInfo->flag, rilInfo->error);
153 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
154 switch (rilInfo->error) {
155 case HRilErrType::HRIL_ERR_GENERIC_FAILURE:
156 case HRilErrType::HRIL_ERR_CMD_SEND_FAILURE:
157 case HRilErrType::HRIL_ERR_NULL_POINT: {
158 inActive->SetReason(DisConnectionReason::REASON_RETRY_CONNECTION);
159 CellularDataHiSysEvent::WriteDataActivateFaultEvent(INVALID_PARAMETER, SWITCH_ON,
160 CellularDataErrorCode::DATA_ERROR_RADIO_RESPONSEINFO_ERROR,
161 "HRilErrType " + std::to_string(static_cast<int32_t>(rilInfo->error)));
162 TELEPHONY_LOGI("Handle supported error responses and retry the connection.");
163 break;
164 }
165 case HRilErrType::HRIL_ERR_INVALID_RESPONSE:
166 case HRilErrType::HRIL_ERR_CMD_NO_CARRIER:
167 case HRilErrType::HRIL_ERR_HDF_IPC_FAILURE:
168 inActive->SetReason(DisConnectionReason::REASON_CLEAR_CONNECTION);
169 TELEPHONY_LOGI("Handle the supported error response and clear the connection.");
170 break;
171 default: {
172 inActive->SetReason(DisConnectionReason::REASON_CLEAR_CONNECTION);
173 TELEPHONY_LOGE("Handle the unsupported error response");
174 break;
175 }
176 }
177 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
178 stateMachine->TransitionTo(stateMachine->inActiveState_);
179 return true;
180 }
181
ProcessConnectTimeout(const AppExecFwk::InnerEvent::Pointer & event)182 void Activating::ProcessConnectTimeout(const AppExecFwk::InnerEvent::Pointer &event)
183 {
184 if (event == nullptr) {
185 TELEPHONY_LOGE("event is null");
186 return;
187 }
188 int32_t connectId = event->GetParam();
189 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
190 if (stateMachine == nullptr) {
191 TELEPHONY_LOGE("stateMachine is null");
192 return;
193 }
194 if (connectId != stateMachine->connectId_) {
195 return;
196 }
197 Inactive *inActive = static_cast<Inactive *>(stateMachine->inActiveState_.GetRefPtr());
198 inActive->SetDeActiveApnTypeId(stateMachine->apnId_);
199 inActive->SetReason(DisConnectionReason::REASON_RETRY_CONNECTION);
200 stateMachine->TransitionTo(stateMachine->inActiveState_);
201 TELEPHONY_LOGI("ProcessConnectTimeout");
202 }
203
StateProcess(const AppExecFwk::InnerEvent::Pointer & event)204 bool Activating::StateProcess(const AppExecFwk::InnerEvent::Pointer &event)
205 {
206 if (event == nullptr) {
207 TELEPHONY_LOGE("event is null");
208 return false;
209 }
210 std::shared_ptr<CellularDataStateMachine> stateMachine = stateMachine_.lock();
211 if (stateMachine == nullptr) {
212 TELEPHONY_LOGE("stateMachine is null");
213 return false;
214 }
215 bool retVal = false;
216 uint32_t eventCode = event->GetInnerEventId();
217 switch (eventCode) {
218 case CellularDataEventCode::MSG_SM_DRS_OR_RAT_CHANGED:
219 [[fallthrough]];
220 case CellularDataEventCode::MSG_SM_CONNECT:
221 TELEPHONY_LOGI("Activating::MSG_SM_CONNECT");
222 stateMachine->DeferEvent(std::move(event));
223 retVal = PROCESSED;
224 break;
225 case RadioEvent::RADIO_RIL_SETUP_DATA_CALL: {
226 retVal = RilActivatePdpContextDone(event);
227 break;
228 }
229 case CellularDataEventCode::MSG_SM_GET_LAST_FAIL_DONE:
230 stateMachine->TransitionTo(stateMachine->inActiveState_);
231 retVal = PROCESSED;
232 break;
233 case CellularDataEventCode::MSG_GET_RIL_BANDWIDTH:
234 stateMachine->DeferEvent(std::move(event));
235 break;
236 case CellularDataEventCode::MSG_CONNECT_TIMEOUT_CHECK:
237 ProcessConnectTimeout(event);
238 retVal = PROCESSED;
239 break;
240 default:
241 TELEPHONY_LOGE("eventCode:%{public}d goto default", eventCode);
242 break;
243 }
244 return retVal;
245 }
246 } // namespace Telephony
247 } // namespace OHOS