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