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 "stk_controller.h"
17
18 #include "common_event_data.h"
19 #include "common_event_manager.h"
20 #include "common_event_publish_info.h"
21 #include "common_event_support.h"
22 #include "hril_types.h"
23 #include "radio_event.h"
24 #include "telephony_errors.h"
25 #include "telephony_log_wrapper.h"
26
27 namespace OHOS {
28 namespace Telephony {
29 namespace {
30 const int32_t ICC_CARD_STATE_ABSENT = 0;
31 const int32_t ICC_CARD_STATE_PRESENT = 1;
32 const int32_t WAIT_TIME_SECOND = 2; // Set the timeout for sending the stk command
33 const std::string PARAM_SLOTID = "slotId";
34 const std::string PARAM_MSG_CMD = "msgCmd";
35 const std::string PARAM_CARD_STATUS = "cardStatus";
36 const std::string PARAM_ALPHA_STRING = "alphaString";
37 const std::string PARAM_REFRESH_RESULT = "refreshResult";
38 } // namespace
39
StkController(const std::shared_ptr<AppExecFwk::EventRunner> & runner,const std::weak_ptr<Telephony::ITelRilManager> & telRilManager,const std::weak_ptr<Telephony::SimStateManager> & simStateManager,int32_t slotId)40 StkController::StkController(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
41 const std::weak_ptr<Telephony::ITelRilManager> &telRilManager,
42 const std::weak_ptr<Telephony::SimStateManager> &simStateManager, int32_t slotId)
43 : AppExecFwk::EventHandler(runner), telRilManager_(telRilManager),
44 simStateManager_(simStateManager), slotId_(slotId)
45 {}
46
Init()47 void StkController::Init()
48 {
49 RegisterEvents();
50 }
51
RegisterEvents()52 void StkController::RegisterEvents()
53 {
54 std::shared_ptr<ITelRilManager> telRilManager = telRilManager_.lock();
55 if (telRilManager == nullptr) {
56 TELEPHONY_LOGE("StkController[%{public}d]::RegisterEvents() telRilManager is nullptr", slotId_);
57 return;
58 }
59 std::shared_ptr<SimStateManager> simStateManager = simStateManager_.lock();
60 if (simStateManager == nullptr) {
61 TELEPHONY_LOGE("StkController[%{public}d]::RegisterEvents() simStateManager is nullptr", slotId_);
62 return;
63 }
64 simStateManager->RegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
65 telRilManager->RegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_SESSION_END, nullptr);
66 telRilManager->RegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_PROACTIVE_COMMAND, nullptr);
67 telRilManager->RegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_ALPHA_NOTIFY, nullptr);
68 telRilManager->RegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_EVENT_NOTIFY, nullptr);
69 telRilManager->RegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_CALL_SETUP, nullptr);
70 telRilManager->RegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_ICC_REFRESH, nullptr);
71 }
72
UnRegisterEvents()73 void StkController::UnRegisterEvents()
74 {
75 std::shared_ptr<ITelRilManager> telRilManager = telRilManager_.lock();
76 if (telRilManager == nullptr) {
77 TELEPHONY_LOGE("StkController[%{public}d]::UnRegisterEvents() telRilManager is nullptr", slotId_);
78 return;
79 }
80 std::shared_ptr<SimStateManager> simStateManager = simStateManager_.lock();
81 if (simStateManager == nullptr) {
82 TELEPHONY_LOGE("StkController[%{public}d]::UnRegisterEvents() simStateManager is nullptr", slotId_);
83 return;
84 }
85 simStateManager->UnRegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_STATE_CHANGE);
86 telRilManager->UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_SESSION_END);
87 telRilManager->UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_PROACTIVE_COMMAND);
88 telRilManager->UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_ALPHA_NOTIFY);
89 telRilManager->UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_EVENT_NOTIFY);
90 telRilManager->UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_STK_CALL_SETUP);
91 telRilManager->UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_ICC_REFRESH);
92 }
93
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)94 void StkController::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
95 {
96 if (event == nullptr) {
97 TELEPHONY_LOGE("StkController[%{public}d]::ProcessEvent() event is nullptr", slotId_);
98 return;
99 }
100 uint32_t id = event->GetInnerEventId();
101 switch (id) {
102 case RadioEvent::RADIO_SIM_STATE_CHANGE:
103 OnIccStateChanged(event);
104 break;
105 case RadioEvent::RADIO_STK_SESSION_END:
106 OnSendRilSessionEnd(event);
107 break;
108 case RadioEvent::RADIO_STK_PROACTIVE_COMMAND:
109 OnSendRilProactiveCommand(event);
110 break;
111 case RadioEvent::RADIO_STK_ALPHA_NOTIFY:
112 OnSendRilAlphaNotify(event);
113 break;
114 case RadioEvent::RADIO_STK_EVENT_NOTIFY:
115 OnSendRilEventNotify(event);
116 break;
117 case RadioEvent::RADIO_STK_CALL_SETUP:
118 TELEPHONY_LOGI("StkController[%{public}d]::ProcessEvent(),"
119 " event notify command supplied all the information needed for set up call processing", slotId_);
120 break;
121 case RadioEvent::RADIO_ICC_REFRESH:
122 OnIccRefresh(event);
123 break;
124 case RadioEvent::RADIO_STK_SEND_TERMINAL_RESPONSE:
125 OnSendTerminalResponseResult(event);
126 break;
127 case RadioEvent::RADIO_STK_SEND_ENVELOPE:
128 OnSendEnvelopeCmdResult(event);
129 break;
130 case RadioEvent::RADIO_STK_IS_READY:
131 TELEPHONY_LOGI("StkController[%{public}d]::ProcessEvent() SimStkIsReady done", slotId_);
132 break;
133 case RadioEvent::RADIO_STK_SEND_CALL_SETUP_REQUEST_RESULT:
134 OnSendCallSetupRequestResult(event);
135 break;
136 default:
137 TELEPHONY_LOGE("StkController[%{public}d]::ProcessEvent() unknown event", slotId_);
138 break;
139 }
140 }
141
OnIccStateChanged(const AppExecFwk::InnerEvent::Pointer & event)142 void StkController::OnIccStateChanged(const AppExecFwk::InnerEvent::Pointer &event)
143 {
144 std::shared_ptr<SimStateManager> simStateManager = simStateManager_.lock();
145 if (simStateManager == nullptr) {
146 TELEPHONY_LOGE("StkController[%{public}d]::OnIccStateChanged() simStateManager is nullptr", slotId_);
147 return;
148 }
149 int32_t newState = simStateManager->HasSimCard() ? ICC_CARD_STATE_PRESENT : ICC_CARD_STATE_ABSENT;
150 int32_t oldState = iccCardState_;
151 iccCardState_ = newState;
152 TELEPHONY_LOGI("StkController[%{public}d]::OnIccStateChanged(), oldState: %{public}d newState: %{public}d",
153 slotId_, oldState, newState);
154 if (oldState == ICC_CARD_STATE_PRESENT && newState == ICC_CARD_STATE_ABSENT) {
155 AAFwk::Want want;
156 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_STK_CARD_STATE_CHANGED);
157 want.SetParam(PARAM_SLOTID, slotId_);
158 want.SetParam(PARAM_CARD_STATUS, iccCardState_);
159 bool publishResult = PublishStkEvent(want);
160 TELEPHONY_LOGI("StkController[%{public}d]::OnIccStateChanged() publishResult = %{public}d",
161 slotId_, publishResult);
162 } else if (oldState == ICC_CARD_STATE_ABSENT && newState == ICC_CARD_STATE_PRESENT) {
163 TELEPHONY_LOGI("StkController[%{public}d]::OnIccStateChanged(), call SimStkIsReady()", slotId_);
164 auto event = AppExecFwk::InnerEvent::Get(RadioEvent::RADIO_STK_IS_READY);
165 if (event == nullptr) {
166 TELEPHONY_LOGE("StkController[%{public}d]::OnIccStateChanged() event is nullptr", slotId_);
167 return;
168 }
169 event->SetOwner(shared_from_this());
170 std::shared_ptr<ITelRilManager> telRilManager = telRilManager_.lock();
171 if (telRilManager == nullptr) {
172 TELEPHONY_LOGE("StkController[%{public}d]::OnIccStateChanged() telRilManager is nullptr", slotId_);
173 return;
174 }
175 telRilManager->SimStkIsReady(slotId_, event);
176 }
177 }
178
OnSendRilSessionEnd(const AppExecFwk::InnerEvent::Pointer & event) const179 void StkController::OnSendRilSessionEnd(const AppExecFwk::InnerEvent::Pointer &event) const
180 {
181 AAFwk::Want want;
182 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_STK_SESSION_END);
183 want.SetParam(PARAM_SLOTID, slotId_);
184 bool publishResult = PublishStkEvent(want);
185 TELEPHONY_LOGI("StkController[%{public}d]::OnSendRilSessionEnd() publishResult = %{public}d",
186 slotId_, publishResult);
187 }
188
OnSendRilProactiveCommand(const AppExecFwk::InnerEvent::Pointer & event) const189 void StkController::OnSendRilProactiveCommand(const AppExecFwk::InnerEvent::Pointer &event) const
190 {
191 auto stkData = event->GetSharedObject<std::string>();
192 if (stkData == nullptr) {
193 TELEPHONY_LOGE("StkController[%{public}d]::OnSendRilProactiveCommand() stkData is nullptr", slotId_);
194 return;
195 }
196 std::string cmdData = (std::string)*stkData;
197 AAFwk::Want want;
198 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_STK_COMMAND);
199 want.SetParam(PARAM_SLOTID, slotId_);
200 want.SetParam(PARAM_MSG_CMD, cmdData);
201 bool publishResult = PublishStkEvent(want);
202 TELEPHONY_LOGI("StkController[%{public}d]::OnSendRilProactiveCommand() stkData = %{public}s "
203 "publishResult = %{public}d", slotId_, cmdData.c_str(), publishResult);
204 }
205
OnSendRilAlphaNotify(const AppExecFwk::InnerEvent::Pointer & event) const206 void StkController::OnSendRilAlphaNotify(const AppExecFwk::InnerEvent::Pointer &event) const
207 {
208 auto alphaData = event->GetSharedObject<std::string>();
209 if (alphaData == nullptr) {
210 TELEPHONY_LOGE("StkController[%{public}d]::OnSendRilAlphaNotify() alphaData is nullptr", slotId_);
211 return;
212 }
213 std::string cmdData = (std::string)*alphaData;
214 AAFwk::Want want;
215 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_STK_ALPHA_IDENTIFIER);
216 want.SetParam(PARAM_SLOTID, slotId_);
217 want.SetParam(PARAM_ALPHA_STRING, cmdData);
218 bool publishResult = PublishStkEvent(want);
219 TELEPHONY_LOGI("StkController[%{public}d]::OnSendRilAlphaNotify() alphaData = %{public}s "
220 "publishResult = %{public}d", slotId_, cmdData.c_str(), publishResult);
221 }
222
OnSendRilEventNotify(const AppExecFwk::InnerEvent::Pointer & event) const223 void StkController::OnSendRilEventNotify(const AppExecFwk::InnerEvent::Pointer &event) const
224 {
225 auto eventData = event->GetSharedObject<std::string>();
226 if (eventData == nullptr) {
227 TELEPHONY_LOGE("StkController[%{public}d]::OnSendRilEventNotify() eventData is nullptr", slotId_);
228 return;
229 }
230 std::string cmdData = (std::string)*eventData;
231 AAFwk::Want want;
232 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_STK_COMMAND);
233 want.SetParam(PARAM_SLOTID, slotId_);
234 want.SetParam(PARAM_MSG_CMD, cmdData);
235 bool publishResult = PublishStkEvent(want);
236 TELEPHONY_LOGI("StkController[%{public}d]::OnSendRilEventNotify() eventData = %{public}s "
237 "publishResult = %{public}d", slotId_, cmdData.c_str(), publishResult);
238 }
239
OnIccRefresh(const AppExecFwk::InnerEvent::Pointer & event) const240 void StkController::OnIccRefresh(const AppExecFwk::InnerEvent::Pointer &event) const
241 {
242 auto refreshResult = event->GetSharedObject<int32_t>();
243 if (refreshResult == nullptr) {
244 TELEPHONY_LOGE("StkController[%{public}d]::OnIccRefresh() refreshResult is nullptr", slotId_);
245 return;
246 }
247 int32_t result = (int32_t)*refreshResult;
248 AAFwk::Want want;
249 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_STK_CARD_STATE_CHANGED);
250 want.SetParam(PARAM_SLOTID, slotId_);
251 want.SetParam(PARAM_CARD_STATUS, ICC_CARD_STATE_PRESENT);
252 want.SetParam(PARAM_REFRESH_RESULT, result);
253 bool publishResult = PublishStkEvent(want);
254 TELEPHONY_LOGI("StkController[%{public}d]::OnIccRefresh() refresh result = %{public}d publishResult = %{public}d",
255 slotId_, result, publishResult);
256 }
257
PublishStkEvent(const AAFwk::Want & want) const258 bool StkController::PublishStkEvent(const AAFwk::Want &want) const
259 {
260 EventFwk::CommonEventData data(want);
261 EventFwk::CommonEventPublishInfo publishInfo;
262 publishInfo.SetOrdered(true);
263 return EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
264 }
265
SendTerminalResponseCmd(const std::string & strCmd)266 int32_t StkController::SendTerminalResponseCmd(const std::string &strCmd)
267 {
268 auto event = AppExecFwk::InnerEvent::Get(RadioEvent::RADIO_STK_SEND_TERMINAL_RESPONSE);
269 if (event == nullptr) {
270 TELEPHONY_LOGE("StkController[%{public}d]::SendTerminalResponseCmd() event is nullptr", slotId_);
271 return TELEPHONY_ERR_LOCAL_PTR_NULL;
272 }
273 event->SetOwner(shared_from_this());
274 std::shared_ptr<ITelRilManager> telRilManager = telRilManager_.lock();
275 if (telRilManager == nullptr) {
276 TELEPHONY_LOGE("StkController[%{public}d]::SendTerminalResponseCmd() telRilManager is nullptr", slotId_);
277 return TELEPHONY_ERR_LOCAL_PTR_NULL;
278 }
279
280 std::unique_lock<std::mutex> terminalResponselock(stkMutex_);
281 terminalResponseResult_ = 0;
282 responseFinished_ = false;
283 telRilManager->SendTerminalResponseCmd(slotId_, strCmd, event);
284 while (!responseFinished_) {
285 TELEPHONY_LOGI("StkController[%{public}d]::SendTerminalResponseCmd() wait for the response to finish", slotId_);
286 if (stkCv_.wait_for(terminalResponselock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
287 TELEPHONY_LOGE("StkController[%{public}d]::SendTerminalResponseCmd() wait timeout", slotId_);
288 break;
289 }
290 }
291 if (!responseFinished_) {
292 TELEPHONY_LOGE("ril cmd fail");
293 return TELEPHONY_ERR_RIL_CMD_FAIL;
294 }
295 return TELEPHONY_SUCCESS;
296 }
297
SendEnvelopeCmd(const std::string & strCmd)298 int32_t StkController::SendEnvelopeCmd(const std::string &strCmd)
299 {
300 auto event = AppExecFwk::InnerEvent::Get(RadioEvent::RADIO_STK_SEND_ENVELOPE);
301 if (event == nullptr) {
302 TELEPHONY_LOGE("StkController[%{public}d]::SendEnvelopeCmd() event is nullptr", slotId_);
303 return TELEPHONY_ERR_LOCAL_PTR_NULL;
304 }
305 event->SetOwner(shared_from_this());
306 std::shared_ptr<ITelRilManager> telRilManager = telRilManager_.lock();
307 if (telRilManager == nullptr) {
308 TELEPHONY_LOGE("StkController[%{public}d]::SendEnvelopeCmd() telRilManager is nullptr", slotId_);
309 return TELEPHONY_ERR_LOCAL_PTR_NULL;
310 }
311
312 std::unique_lock<std::mutex> envelopelock(stkMutex_);
313 envelopeResponseResult_ = 0;
314 responseFinished_ = false;
315 telRilManager->SendEnvelopeCmd(slotId_, strCmd, event);
316 while (!responseFinished_) {
317 TELEPHONY_LOGI("StkController[%{public}d]::SendEnvelopeCmd() wait for the response to finish", slotId_);
318 if (stkCv_.wait_for(envelopelock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
319 TELEPHONY_LOGE("StkController[%{public}d]::SendEnvelopeCmd() wait timeout", slotId_);
320 break;
321 }
322 }
323 if (!responseFinished_) {
324 TELEPHONY_LOGE("ril cmd fail");
325 return TELEPHONY_ERR_RIL_CMD_FAIL;
326 }
327 return TELEPHONY_SUCCESS;
328 }
329
SendCallSetupRequestResult(bool accept)330 int32_t StkController::SendCallSetupRequestResult(bool accept)
331 {
332 auto event = AppExecFwk::InnerEvent::Get(RadioEvent::RADIO_STK_SEND_CALL_SETUP_REQUEST_RESULT);
333 if (event == nullptr) {
334 TELEPHONY_LOGE("StkController[%{public}d]::SendCallSetupRequestResult() event is nullptr", slotId_);
335 return TELEPHONY_ERR_FAIL;
336 }
337 event->SetOwner(shared_from_this());
338 std::shared_ptr<ITelRilManager> telRilManager = telRilManager_.lock();
339 if (telRilManager == nullptr) {
340 TELEPHONY_LOGE("StkController[%{public}d]::SendCallSetupRequestResult() telRilManager is nullptr", slotId_);
341 return TELEPHONY_ERR_FAIL;
342 }
343
344 std::unique_lock<std::mutex> callSetupRequestlock(stkMutex_);
345 callSetupResponseResult_ = TELEPHONY_ERR_FAIL;
346 responseFinished_ = false;
347 telRilManager->SendCallSetupRequestResult(slotId_, accept, event);
348 while (!responseFinished_) {
349 TELEPHONY_LOGI("StkController[%{public}d]::SendCallSetupRequestResult() wait for the response to finish",
350 slotId_);
351 if (stkCv_.wait_for(callSetupRequestlock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
352 TELEPHONY_LOGE("StkController[%{public}d]::SendCallSetupRequestResult() wait timeout", slotId_);
353 responseFinished_ = true;
354 }
355 }
356 return callSetupResponseResult_;
357 }
358
OnSendTerminalResponseResult(const AppExecFwk::InnerEvent::Pointer & event)359 void StkController::OnSendTerminalResponseResult(const AppExecFwk::InnerEvent::Pointer &event)
360 {
361 if (event == nullptr) {
362 TELEPHONY_LOGE("StkController[%{public}d]::OnSendTerminalResponseResult() event is nullptr", slotId_);
363 return;
364 }
365 std::shared_ptr<HRilRadioResponseInfo> response = event->GetSharedObject<HRilRadioResponseInfo>();
366 if (response == nullptr) {
367 TELEPHONY_LOGE("StkController[%{public}d]::OnSendTerminalResponseResult() response is nullptr", slotId_);
368 return;
369 }
370 terminalResponseResult_ = response->error == HRilErrType::NONE;
371 TELEPHONY_LOGI("StkController[%{public}d]::OnSendTerminalResponseResult(), result = %{public}d",
372 slotId_, terminalResponseResult_);
373 responseFinished_ = true;
374 stkCv_.notify_one();
375 }
376
OnSendEnvelopeCmdResult(const AppExecFwk::InnerEvent::Pointer & event)377 void StkController::OnSendEnvelopeCmdResult(const AppExecFwk::InnerEvent::Pointer &event)
378 {
379 if (event == nullptr) {
380 TELEPHONY_LOGE("StkController[%{public}d]::OnSendEnvelopeCmdResult() event is nullptr", slotId_);
381 return;
382 }
383 std::shared_ptr<HRilRadioResponseInfo> response = event->GetSharedObject<HRilRadioResponseInfo>();
384 if (response == nullptr) {
385 TELEPHONY_LOGE("StkController[%{public}d]::OnSendEnvelopeCmdResult() response is nullptr", slotId_);
386 return;
387 }
388 envelopeResponseResult_ = response->error == HRilErrType::NONE;
389 TELEPHONY_LOGI("StkController[%{public}d]::OnSendEnvelopeCmdResult(), result = %{public}d",
390 slotId_, envelopeResponseResult_);
391 responseFinished_ = true;
392 stkCv_.notify_one();
393 }
394
OnSendCallSetupRequestResult(const AppExecFwk::InnerEvent::Pointer & event)395 void StkController::OnSendCallSetupRequestResult(const AppExecFwk::InnerEvent::Pointer &event)
396 {
397 if (event == nullptr) {
398 TELEPHONY_LOGE("StkController[%{public}d]::OnSendCallSetupRequestResult() event is nullptr", slotId_);
399 return;
400 }
401 std::shared_ptr<HRilRadioResponseInfo> response = event->GetSharedObject<HRilRadioResponseInfo>();
402 if (response == nullptr) {
403 TELEPHONY_LOGE("StkController[%{public}d]::OnSendCallSetupRequestResult() response is nullptr", slotId_);
404 return;
405 }
406 callSetupResponseResult_ = response->error == HRilErrType::NONE ? TELEPHONY_ERR_SUCCESS : TELEPHONY_ERR_FAIL;
407 TELEPHONY_LOGI("StkController[%{public}d]::OnSendCallSetupRequestResult(), result = %{public}d",
408 slotId_, callSetupResponseResult_);
409 responseFinished_ = true;
410 stkCv_.notify_one();
411 }
412 } // namespace Telephony
413 } // namespace OHOS
414