blob: d173c71419dfea1a3915e831047da4e9b916b1c4 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <log/log.h>
17#include <set>
18#include <stdexcept>
19
20#include "Proxycontroller.h"
21#include "common.h"
22#include "network.h"
23#include "data.h"
24#include "bitset"
25#include "utils.h"
26#include "WorldPhoneUtil.h"
27
28#define LOG_TAG "DEMO_Proxy_controller"
29
30constexpr int Proxy_controller::EVENT_NOTIFICATION_RC_CHANGED;
31constexpr int Proxy_controller::EVENT_START_RC_RESPONSE;
32constexpr int Proxy_controller::EVENT_APPLY_RC_RESPONSE;
33constexpr int Proxy_controller::EVENT_FINISH_RC_RESPONSE;
34constexpr int Proxy_controller::EVENT_TIMEOUT;
35
36const int Proxy_controller::SET_RC_STATUS_IDLE = 0;
37const int Proxy_controller::SET_RC_STATUS_STARTING = 1;
38const int Proxy_controller::SET_RC_STATUS_STARTED = 2;
39const int Proxy_controller::SET_RC_STATUS_APPLYING = 3;
40const int Proxy_controller::SET_RC_STATUS_SUCCESS = 4;
41const int Proxy_controller::SET_RC_STATUS_FAIL = 5;
42
43const std::string Proxy_controller::PROPERTY_CAPABILITY_SWITCH = "persist.vendor.radio.simswitch";
44const std::string Proxy_controller::PROPERTY_CAPABILITY_SWITCH_STATE = "persist.vendor.radio.simswitchstate";
45
46// event 1-5 is defined in ProxyController
47const int Proxy_controller::EVENT_RADIO_AVAILABLE = 6;
48const int Proxy_controller::EVENT_RIL_CONNECTED = 7;
49
50// marker for retry cause
51const int Proxy_controller::RC_RETRY_CAUSE_NONE = 0;
52const int Proxy_controller::RC_RETRY_CAUSE_WORLD_MODE_SWITCHING = 1;
53const int Proxy_controller::RC_RETRY_CAUSE_CAPABILITY_SWITCHING = 2;
54const int Proxy_controller::RC_RETRY_CAUSE_IN_CALL = 3;
55const int Proxy_controller::RC_RETRY_CAUSE_RADIO_UNAVAILABLE = 4;
56const int Proxy_controller::RC_RETRY_CAUSE_AIRPLANE_MODE = 5;
57const int Proxy_controller::RC_RETRY_CAUSE_RESULT_ERROR = 6;
58
59 // marker for switch conditions pre-checking
60const int Proxy_controller::RC_DO_SWITCH = 0;
61const int Proxy_controller::RC_NO_NEED_SWITCH = 1;
62const int Proxy_controller::RC_CANNOT_SWITCH = 2;
63
64Proxy_controller* Proxy_controller::sInstance = nullptr;
65 // The entire transaction must complete within this amount of time
66 // or a FINISH will be issued to each Logical Modem with the old
67 // Radio Access Family.
68const int Proxy_controller::SET_RC_TIMEOUT_WAITING_MSEC = (45 * 1000);
69
70Proxy_controller::Proxy_controller() :mRadioCapabilitySessionId(0), mTransactionFailed(false){
71 //***** Class Variables
72 mIsCapSwitching = false;
73 mHasRegisterWorldModeReceiver = false;
74 mHasRegisterPhoneStateReceiver = false;
75 mHasRegisterEccStateReceiver = false;
76 mIsRildReconnected = false;
77 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
78 // Exception counter
79 onExceptionCount = 0;
80 clearTransaction();
81}
82
83Proxy_controller::~Proxy_controller() {
84 // TODO Auto-generated destructor stub
85}
86
87Proxy_controller::Handle_thread::Handle_thread(): m_looper(NULL){
88 RLOGD("RequestHandleThread created");
89}
90
91Proxy_controller::Handle_thread::~Handle_thread() {
92 RLOGD("RequestHandleThread destroyed");
93}
94
95sp<Looper> Proxy_controller::Handle_thread::getLooper() {
96 return m_looper;
97}
98
99bool Proxy_controller::Handle_thread::threadLoop() {
100 RLOGD("Handler threadLoop");
101 m_looper = Looper::prepare(0);
102 int result;
103 do {
104 result = m_looper->pollAll(-1);
105 RLOGD("Handler threadLoop, pull message result = %d", result);
106 } while (result == Looper::POLL_WAKE || result == Looper::POLL_CALLBACK);
107 return true;
108}
109
110Proxy_controller::Request_message::Request_message(): what(0), slot(-1),e(RIL_E_SUCCESS), is_rc_set(true),id(-1){
111
112}
113
114void Proxy_controller::init() {
115 handle_thread = new Handle_thread();
116 handle_thread->run();
117}
118
119Proxy_controller *Proxy_controller::getInstance() {
120 if (sInstance == NULL) {
121 sInstance = new Proxy_controller();
122 sInstance->init();
123 }
124 return sInstance;
125}
126
127sp<Proxy_controller::Request_handler> Proxy_controller::sendMessage(sp<Request_message> msg, int delayms) {
128 RLOGD("sendMessage msg what=%d delayms=%d", msg->what, delayms);
129 // Create a handler to handle this message
130 sp<Request_handler> handler = new Request_handler(this);
131 handler->msg = msg;
132 // Sand message to looper
133 if(handle_thread.get()) {
134 sp<Looper> looper = handle_thread->getLooper();
135 if(looper.get()) {
136 if (delayms > 0) {
137 looper->sendMessageDelayed(ms2ns(delayms),handler, handler->m_dummyMsg);
138 } else {
139 looper->sendMessage(handler, handler->m_dummyMsg);
140 }
141 } else {
142 RLOGD("looper");
143 }
144 } else {
145 RLOGD("handle_thread");
146 }
147
148 return handler;
149}
150
151void Proxy_controller::handle_request_resp(RIL_RadioCapability* cap, RIL_Errno e, int slot) {
152 if(m_eventId[slot] < 0) {
153 RLOGD("handle_request_resp cap is null.m_eventId[%d]=%d", slot, m_eventId[slot]);
154 return;
155 }
156 RLOGD("handle_request_resp what[%d]: %d , phase: %d", slot,m_eventId[slot], cap->phase);
157 // Create a request message
158 sp<Request_message> msg = new Request_message();
159 msg->what = m_eventId[slot];
160 if(cap != NULL) {
161 msg->cap = (*cap);
162 } else {
163 msg->is_rc_set = false;
164 RLOGD("handle_request_resp[slot%d]: cap is null", slot);
165 }
166 msg->e = e;
167 msg->slot = slot;
168 RLOGD("handle_request_resp logicalModemUuid: %s , phase: %d, rat: %d, session: %d, status: %d, version: %d",
169 msg->cap.logicalModemUuid, msg->cap.phase, msg->cap.rat, msg->cap.session, msg->cap.status, msg->cap.version);
170 sendMessage(msg, 0);
171}
172
173void Proxy_controller::issueFinish(int sessionId) {
174 m_mutex.lock();
175 for (int i = 0; i < SIM_COUNT; i++) {
176 RLOGD("issueFinish: phoneId=%d sessionId= %d mTransactionFailed=%d", i, sessionId, mTransactionFailed);
177 mRadioAccessFamilyStatusCounter++;
178 sendRadioCapabilityRequest(
179 i,
180 sessionId,
181 RadioCapabilityPhase(RC_PHASE_FINISH),
182 (mTransactionFailed ? mOldRadioAccessFamily[i] :
183 mNewRadioAccessFamily[i]),
184 (mTransactionFailed ? mCurrentLogicalModemIds[i] :
185 mNewLogicalModemIds[i]),
186 (mTransactionFailed ? RadioCapabilityStatus(RC_STATUS_FAIL) :
187 RadioCapabilityStatus(RC_STATUS_SUCCESS)),
188 EVENT_FINISH_RC_RESPONSE);
189 if (mTransactionFailed) {
190 RLOGD("issueFinish: phoneId: %d status: FAIL", i);
191 // At least one failed, mark them all failed.
192 mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_FAIL;
193 }
194 }
195 m_mutex.unlock();
196}
197
198void Proxy_controller::onStartRadioCapabilityResponse(sp<Request_message> msg) {
199 m_mutex.lock();
200
201 RIL_RadioCapability rc = msg->cap;
202 if ((rc.session != mRadioCapabilitySessionId.load())) {
203 RLOGD("onStartRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
204 mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
205 return;
206 }
207 mRadioAccessFamilyStatusCounter--;
208 int id = msg->slot;
209 if (msg->e != RIL_E_SUCCESS) {
210 RLOGD("onStartRadioCapabilityResponse: Error response session=%d", rc.session);
211 RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=FAIL", id);
212 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
213 mTransactionFailed = true;
214 } else {
215 RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=STARTED", id);
216 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED;
217 }
218
219 if (mRadioAccessFamilyStatusCounter == 0) {
220 /**
221 std::set<std::string> modemsInUse;
222 for (auto modemId : mNewLogicalModemIds) {
223 if (!(modemsInUse.insert(modemId).second)) {
224 mTransactionFailed = true;
225 RLOGD("ERROR: sending down the same id for different phones");
226 }
227 }
228 **/
229 RLOGD("onStartRadioCapabilityResponse: success=%d", !mTransactionFailed);
230 if (mTransactionFailed) {
231 // Sends a variable number of requests, so don't resetRadioAccessFamilyCounter
232 // here.
233 m_mutex.unlock();
234 issueFinish(mRadioCapabilitySessionId.load());
235 return;
236 } else {
237 // All logical modem accepted the new radio access family, issue the APPLY
238 resetRadioAccessFamilyStatusCounter();
239 for (int i = 0; i < SIM_COUNT; i++) {
240 sendRadioCapabilityRequest(
241 i,
242 mRadioCapabilitySessionId.load(),
243 RadioCapabilityPhase(RC_PHASE_APPLY),
244 mNewRadioAccessFamily[i],
245 mNewLogicalModemIds[i],
246 RadioCapabilityStatus(RC_STATUS_NONE),
247 EVENT_APPLY_RC_RESPONSE);
248
249 RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=APPLYING", i);
250 mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_APPLYING;
251 }
252 }
253 }
254 m_mutex.unlock();
255}
256
257void Proxy_controller::onApplyRadioCapabilityErrorHandler(sp<Request_message> msg){
258
259}
260void Proxy_controller::onApplyExceptionHandler(sp<Request_message> msg){
261
262}
263
264void Proxy_controller::onApplyRadioCapabilityResponse(sp<Request_message> msg) {
265 RIL_RadioCapability rc = msg->cap;
266 if ((rc.session != mRadioCapabilitySessionId.load())) {
267 RLOGD("onApplyRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
268 mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
269 /// M: handle rc error, retry sim switch if possible. @{
270 onApplyRadioCapabilityErrorHandler(msg);
271 /// @}
272 return;
273 }
274 RLOGD("onApplyRadioCapabilityResponse: rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
275 mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
276 if (msg->e != RIL_E_SUCCESS) {
277 m_mutex.lock();
278 RLOGD("onApplyRadioCapabilityResponse: Error response session=%d",rc.session);
279 int id = msg->slot;
280 /// M: handle exception, retry sim switch if possible. @{
281 onApplyExceptionHandler(msg);
282 /// @}
283 RLOGD("onApplyRadioCapabilityResponse: phoneId=%d status=FAIL", id);
284 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
285 mTransactionFailed = true;
286 m_mutex.unlock();
287 } else {
288 RLOGD("onApplyRadioCapabilityResponse: Valid start expecting notification rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
289 mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
290 }
291}
292
293void Proxy_controller::handle_message_notify(RIL_RadioCapability* cap,int slot) {
294 sp<Request_message> msg = new Request_message();
295 msg->what = EVENT_NOTIFICATION_RC_CHANGED;
296 if(cap != NULL) {
297 msg->cap = (*cap);
298 } else {
299 msg->is_rc_set = false;
300 RLOGD("handle_request_resp[slot%d]: cap is null", slot);
301 }
302 msg->slot = slot;
303 RLOGD("handle_request_resp logicalModemUuid: %s , phase: %d, rat: %d, session: %d, status: %d, version: %d",
304 msg->cap.logicalModemUuid, msg->cap.phase, msg->cap.rat, msg->cap.session, msg->cap.status, msg->cap.version);
305 sendMessage(msg, 0);
306}
307
308void Proxy_controller::onNotificationRadioCapabilityChanged(sp<Request_message> msg) {
309 RIL_RadioCapability rc = msg->cap;
310 if (msg->is_rc_set == false || (rc.session != mRadioCapabilitySessionId.load())) {
311 RLOGD("onNotificationRadioCapabilityChanged: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
312 mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
313 return;
314 }
315 m_mutex.lock();
316 RLOGD("onNotificationRadioCapabilityChanged: rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
317 rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
318
319 int id = msg->slot;
320 if (msg-> e != RIL_E_SUCCESS ||
321 (rc.status == RadioCapabilityStatus(RC_STATUS_FAIL))) {
322 RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d status=FAIL", id);
323 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
324 mTransactionFailed = true;
325 } else {
326 RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d status=SUCCESS(%d)", id, !mTransactionFailed);
327 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_SUCCESS;
328 // The modems may have been restarted and forgotten this
329
330 RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_ALLOW_DATA, OTHER, (RIL_SOCKET_ID)id);
331
332 int switch_id = get_default_sim_data_for_switch();
333 RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d switch_id=%d", id, switch_id);
334 char* argv[2] = {"RIL_REQUEST_ALLOW_DATA","0"};
335 if(id == switch_id) {
336 argv[1] = "1";
337 }
338 setDataAllowed(2, argv, RIL_SOCKET_ID(id), info);
339 }
340
341 mRadioAccessFamilyStatusCounter--;
342 if (mRadioAccessFamilyStatusCounter == 0) {
343 RLOGD("onNotificationRadioCapabilityChanged: APPLY URC success=%d",!mTransactionFailed);
344 m_mutex.unlock();
345 issueFinish(mRadioCapabilitySessionId.load());
346 return;
347 }
348 m_mutex.unlock();
349}
350
351void Proxy_controller::completeRadioCapabilityTransaction() {
352 RLOGD("completeRadioCapabilityTransaction: success=%d" , !mTransactionFailed);
353 if (!mTransactionFailed) {
354
355
356 // make messages about the old transaction obsolete (specifically the timeout)
357 //mRadioCapabilitySessionId++;
358
359 // Reinitialize
360 clearTransaction();
361 android::emResultNotify("default data slot switch success\n");
362 } else {
363 android::emResultNotify("default data slot switch fail, now retry\n");
364 // now revert.
365 mTransactionFailed = false;
366 std::vector<RIL_RadioAccessFamily> rafs = {RAF_UNKNOWN, RAF_UNKNOWN};
367 for (int phoneId = 0; phoneId < SIM_COUNT; phoneId++) {
368 rafs[phoneId] = (RIL_RadioAccessFamily)mOldRadioAccessFamily[phoneId];
369 }
370 doSetRadioCapabilities(rafs);
371 }
372
373}
374
375void Proxy_controller::onFinishRadioCapabilityResponse(sp<Request_message> msg){
376 RIL_RadioCapability rc = msg->cap;;
377 if (msg->is_rc_set == false || (rc.session != mRadioCapabilitySessionId.load())) {
378 RLOGD("onFinishRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
379 mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
380 return;
381 }
382 m_mutex.lock();
383 RLOGD("onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter=%d",mRadioAccessFamilyStatusCounter);
384 mRadioAccessFamilyStatusCounter--;
385 if (mRadioAccessFamilyStatusCounter == 0) {
386 m_mutex.unlock();
387 completeRadioCapabilityTransaction();
388 return;
389 }
390 m_mutex.unlock();
391}
392
393void Proxy_controller::onTimeoutRadioCapability(sp<Request_message> msg){
394 if (msg->id != mRadioCapabilitySessionId.load()) {
395 RLOGD("RadioCapability timeout: Ignore msg->id=%d != mRadioCapabilitySessionId.load()=%d", msg->id,mRadioCapabilitySessionId.load());
396 return;
397 }
398
399 m_mutex.lock();
400 // timed-out. Clean up as best we can
401 for (int i = 0; i < SIM_COUNT; i++) {
402 RLOGD("RadioCapability timeout: mSetRadioAccessFamilyStatus[%d]=%d",i,mSetRadioAccessFamilyStatus[i]);
403 }
404
405 // Increment the sessionId as we are completing the transaction below
406 // so we don't want it completed when the FINISH phase is done.
407 mRadioCapabilitySessionId++;
408
409 // Reset the status counter as existing session failed
410 mRadioAccessFamilyStatusCounter = 0;
411
412 // send FINISH request with fail status and then uniqueDifferentId
413 mTransactionFailed = true;
414 m_mutex.unlock();
415 issueFinish(mRadioCapabilitySessionId.load());
416}
417
418void Proxy_controller::Request_handler::sendMessage(sp<Request_message> msg, int delayms) {
419 RLOGD("Proxy_controller::Request_handler, sendMessage msg what=%d delayms=%d", msg->what, delayms);
420 // Sand message to looper
421 this->msg = msg;
422 if (delayms > 0) {
423 proxy_controller->handle_thread->getLooper()->sendMessageDelayed(ms2ns(delayms),
424 this, this->m_dummyMsg);
425 } else {
426 proxy_controller->handle_thread->getLooper()->sendMessage(this, this->m_dummyMsg);
427 }
428 return ;
429}
430
431void Proxy_controller::Request_handler::handleMessage(const Message& message) {
432
433 RLOGD("handleMessage msg->what: %d", msg->what);
434 switch( msg->what){
435 case EVENT_START_RC_RESPONSE:
436 {
437 proxy_controller->onStartRadioCapabilityResponse(msg);
438 break;
439 }
440 case EVENT_APPLY_RC_RESPONSE:
441 {
442 proxy_controller->onApplyRadioCapabilityResponse(msg);
443 break;
444 }
445 case EVENT_NOTIFICATION_RC_CHANGED:
446 {
447 proxy_controller->onNotificationRadioCapabilityChanged(msg);
448 break;
449 }
450 case EVENT_FINISH_RC_RESPONSE:
451 {
452 proxy_controller->onFinishRadioCapabilityResponse(msg);
453 break;
454 }
455 case EVENT_TIMEOUT:
456 {
457 proxy_controller->onTimeoutRadioCapability(msg);
458 break;
459 }
460 default:
461 break;
462 }
463}
464
465void Proxy_controller::clearTransaction() {
466 RLOGD("clearTransaction");
467 m_mutex.lock();
468 mSetRadioAccessFamilyStatus.clear();
469 mOldRadioAccessFamily.clear();
470 mNewRadioAccessFamily.clear();
471 m_eventId.clear();
472 mCurrentLogicalModemIds.clear();
473 mNewLogicalModemIds.clear();
474 for (int i = 0; i < 2; i++) {
475 RLOGD("clearTransaction: phoneId=%d status=IDLE",i);
476 mSetRadioAccessFamilyStatus.push_back(SET_RC_STATUS_IDLE);
477 mOldRadioAccessFamily.push_back(0);
478 mNewRadioAccessFamily.push_back(0);
479 mCurrentLogicalModemIds.push_back("");
480 mNewLogicalModemIds.push_back("");
481 mTransactionFailed = false;
482 m_eventId.push_back(-1);
483 }
484 if(handle_thread.get()) {
485 sp<Looper> looper = handle_thread->getLooper();
486 if(looper.get()) {
487 if(timeout_handle.get()) {
488 looper->removeMessages(timeout_handle);
489 } else {
490 RLOGD("clearTransaction,timeout_handle");
491 }
492 } else {
493 RLOGD("clearTransaction,looper");
494 }
495 } else {
496 RLOGD("clearTransaction,handle_thread");
497 }
498 m_mutex.unlock();
499}
500
501int Proxy_controller::checkRadioCapabilitySwitchConditions(std::vector<RIL_RadioAccessFamily> rafs) {
502 m_mutex.lock();
503 mNextRafs = rafs;
504
505 // check if still switching
506 if (mIsCapSwitching == true) {
507 //throw new RuntimeException("is still switching");
508 RLOGD("keep it and return,because capability swithing");
509 mSetRafRetryCause = RC_RETRY_CAUSE_CAPABILITY_SWITCHING;
510 return RC_NO_NEED_SWITCH;
511 } else if (mSetRafRetryCause == RC_RETRY_CAUSE_CAPABILITY_SWITCHING) {
512 RLOGD("setCapability, mIsCapSwitching is not switching, can switch");
513 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
514 }
515 mIsCapSwitching = true;
516 m_mutex.lock();
517
518 // check if capability switch disabled
519 if (utils::mtk_property_get_bool("ro.vendor.mtk_disable_cap_switch", false) == true) {
520 mNextRafs.clear();
521 completeRadioCapabilityTransaction();
522 RLOGD("skip switching because mtk_disable_cap_switch is true");
523 return RC_NO_NEED_SWITCH;
524 }
525 // check FTA mode
526 if (utils::mtk_property_get_int32("vendor.gsm.gcf.testmode", 0) == 2) {
527 mNextRafs.clear();
528 completeRadioCapabilityTransaction();
529 RLOGD("skip switching because FTA mode");
530 return RC_NO_NEED_SWITCH;
531 }
532 // check EM disable mode
533 if (utils::mtk_property_get_int32("persist.vendor.radio.simswitch.emmode", 1) == 0) {
534 mNextRafs.clear();
535 completeRadioCapabilityTransaction();
536 RLOGD("skip switching because EM disable mode");
537 return RC_NO_NEED_SWITCH;
538 }
539
540 // check world mode switching
541 if (WorldPhoneUtil::isWorldPhoneSupport()) {
542 if (!WorldPhoneUtil::isWorldModeSupport()) {
543 if (/*ModemSwitchHandler.isModemTypeSwitching()*/!isRadioAvailable((RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id())) {
544 RLOGD("world mode switching.");
545 if (!mHasRegisterWorldModeReceiver) {
546 mHasRegisterWorldModeReceiver = true;
547 }
548 mSetRafRetryCause = RC_RETRY_CAUSE_WORLD_MODE_SWITCHING;
549 m_mutex.lock();
550 mIsCapSwitching = false;
551 m_mutex.unlock();
552 return RC_CANNOT_SWITCH;
553 }
554 } else if (mSetRafRetryCause == RC_RETRY_CAUSE_WORLD_MODE_SWITCHING) {
555 if (mHasRegisterWorldModeReceiver) {
556 mHasRegisterWorldModeReceiver = false;
557 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
558 }
559 }
560 }
561
562 // check call state
563 if (!(is_call_state_idle(0) || is_call_state_idle(1))) {
564 //throw new RuntimeException("in call, fail to set RAT for phones");
565 RLOGD("setCapability in calling, fail to set RAT for phones");
566 if (!mHasRegisterPhoneStateReceiver) {
567 mHasRegisterPhoneStateReceiver = true;
568 }
569 mSetRafRetryCause = RC_RETRY_CAUSE_IN_CALL;
570 m_mutex.lock();
571 mIsCapSwitching = false;
572 m_mutex.unlock();
573 return RC_CANNOT_SWITCH;
574 } else if (isEccInProgress()) {
575 RLOGD("setCapability in ECC, fail to set RAT for phones");
576 if (!mHasRegisterEccStateReceiver) {
577 mHasRegisterEccStateReceiver = true;
578 }
579 mSetRafRetryCause = RC_RETRY_CAUSE_IN_CALL;
580 m_mutex.lock();
581 mIsCapSwitching = false;
582 m_mutex.unlock();
583 return RC_CANNOT_SWITCH;
584 } else if (mSetRafRetryCause == RC_RETRY_CAUSE_IN_CALL) {
585 if (mHasRegisterPhoneStateReceiver) {
586 mHasRegisterPhoneStateReceiver = false;
587 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
588 }
589 if (mHasRegisterEccStateReceiver) {
590 mHasRegisterEccStateReceiver = false;
591 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
592 }
593 }
594
595 // check radio available
596 for (int i = 0; i < SIM_COUNT; i++) {
597 if (!isRadioAvailable((RIL_SOCKET_ID)i)) {
598 //throw new RuntimeException("Phone" + i + " is not available");
599 mSetRafRetryCause = RC_RETRY_CAUSE_RADIO_UNAVAILABLE;
600 //mCi[i].registerForAvailable(mMtkHandler, EVENT_RADIO_AVAILABLE, null);
601 RLOGD("setCapability fail,Phone%d is not available", i);
602 m_mutex.lock();
603 mIsCapSwitching = false;
604 m_mutex.unlock();
605 return RC_CANNOT_SWITCH;
606 } else if (mSetRafRetryCause == RC_RETRY_CAUSE_RADIO_UNAVAILABLE) {
607 //mCi[i].unregisterForAvailable(mMtkHandler);
608 if (i == SIM_COUNT - 1) {
609 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
610 }
611 }
612 }
613
614 int switchStatus = utils::mtk_property_get_int32(PROPERTY_CAPABILITY_SWITCH.c_str(), 1);
615 // check parameter
616 bool bIsboth3G = false;
617 bool bIsMajorPhone = false;
618 int newMajorPhoneId = 0;
619 for (int i = 0; i < rafs.size(); i++) {
620 bIsMajorPhone = false;
621 if ((rafs[i] & RIL_RadioAccessFamily::RAF_GPRS) > 0) {
622 bIsMajorPhone = true;
623 }
624
625 if (bIsMajorPhone) {
626 newMajorPhoneId = i;
627 if (newMajorPhoneId == (switchStatus - 1)) {
628 RLOGD("no change, skip setRadioCapability");
629 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
630 mNextRafs.clear();
631 completeRadioCapabilityTransaction();
632 return RC_NO_NEED_SWITCH;
633 }
634 if (bIsboth3G) {
635 RLOGD("set more than one 3G phone, fail");
636 m_mutex.lock();
637 mIsCapSwitching = false;
638 m_mutex.unlock();
639 throw std::runtime_error("input parameter is incorrect");
640 } else {
641 bIsboth3G = true;
642 }
643 }
644 }
645 if (bIsboth3G == false) {
646 m_mutex.lock();
647 mIsCapSwitching = false;
648 m_mutex.unlock();
649 throw std::runtime_error("input parameter is incorrect - no 3g phone");
650 }
651
652 // check operator spec
653 if (!isNeedSimSwitch(newMajorPhoneId, SIM_COUNT)) {
654 RLOGD("check sim card type and skip setRadioCapability");
655 mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
656 mNextRafs.clear();
657 completeRadioCapabilityTransaction();
658 return RC_NO_NEED_SWITCH;
659 }
660
661// if (!WorldPhoneUtil::isWorldModeSupport() && WorldPhoneUtil::isWorldPhoneSupport()) {
662// WorldPhoneUtil.getWorldPhone().notifyRadioCapabilityChange(newMajorPhoneId);
663// }
664 RLOGD("checkRadioCapabilitySwitchConditions, do switch");
665 return RC_DO_SWITCH;
666}
667
668bool Proxy_controller::isEccInProgress() {
669 bool inEcm = utils::mtk_property_get_bool("ril.cdma.inecmmode", false);
670 return inEcm;
671}
672
673bool Proxy_controller::isNeedSimSwitch(int majorPhoneId, int phoneNum) {
674 RLOGD("OMisNeedSimSwitch, majorPhoneId = %d ", majorPhoneId);
675 return !Radio_capability_switch_util::isSkipCapabilitySwitch(majorPhoneId, phoneNum);
676}
677
678bool Proxy_controller::set_Radio_Capability(std::vector<RIL_RadioAccessFamily> rafs) {
679 if (rafs.size() != SIM_COUNT) {
680 RLOGD("Length of input rafs must equal to total phone count");
681 }
682 // Check if there is any ongoing transaction and throw an exception if there
683 // is one as this is a programming error.
684 m_mutex.lock();
685 for (int i = 0; i < rafs.size(); i++) {
686 if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_IDLE) {
687 // TODO: The right behaviour is to cancel previous request and send this.
688 RLOGE("setRadioCapability: Phone[%d] is not idle. Rejecting request.", i);
689 return false;
690 }
691 }
692 m_mutex.unlock();
693
694 // Clear to be sure we're in the initial state
695 clearTransaction();
696
697 return doSetRadioCapabilities(rafs);
698}
699
700void Proxy_controller::resetRadioAccessFamilyStatusCounter() {
701 mRadioAccessFamilyStatusCounter = SIM_COUNT;
702}
703
704std::string Proxy_controller::getLogicalModemIdFromRaf(int raf) {
705 std::string modemUui;
706
707 for (int phoneId = 0; phoneId < SIM_COUNT; phoneId++) {
708 if (get_radio_capa(phoneId).rat == raf) {
709 modemUui = get_radio_capa(phoneId).logicalModemUuid;
710 break;
711 }
712 }
713 return modemUui;
714}
715
716void Proxy_controller::sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase,
717 int radioFamily, std::string logicalModemId, int status, int eventId){
718 RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_SET_RADIO_CAPABILITY, OTHER, (RIL_SOCKET_ID)phoneId);
719
720 char* argv[7] = {"RIL_REQUEST_SET_RADIO_CAPABILITY",
721 const_cast<char*>(std::to_string(RIL_RADIO_CAPABILITY_VERSION).c_str()),
722 const_cast<char*>(std::to_string(sessionId).c_str()),
723 const_cast<char*>(std::to_string(rcPhase).c_str()),
724 const_cast<char*>(std::to_string(radioFamily).c_str()),
725 const_cast<char*>(logicalModemId.c_str()),
726 const_cast<char*>(std::to_string(status).c_str())
727 };
728 setRadioCapability(7, argv,(RIL_SOCKET_ID)phoneId, info);
729 m_eventId[phoneId] = eventId;
730}
731
732bool Proxy_controller::doSetRadioCapabilities(std::vector<RIL_RadioAccessFamily> rafs) {
733 // A new sessionId for this transaction
734 mRadioCapabilitySessionId++;
735 // Start timer to make sure all phones respond within a specific time interval.
736 // Will send FINISH if a timeout occurs.
737 sp<Request_message> msg = new Request_message();
738 msg->what = EVENT_TIMEOUT;
739 msg->id = mRadioCapabilitySessionId.load();
740 timeout_handle = sendMessage(msg, SET_RC_TIMEOUT_WAITING_MSEC);
741
742 m_mutex.lock();
743 RLOGD("setRadioCapability: new request session id=%d", mRadioCapabilitySessionId.load());
744 resetRadioAccessFamilyStatusCounter();
745 for (int i = 0; i < rafs.size(); i++) {
746 RLOGD("setRadioCapability: phoneId=%d status=STARTING", i);
747 mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_STARTING;
748 mOldRadioAccessFamily[i] = get_radio_capa(i).rat;
749 int requestedRaf = rafs[i];
750 // TODO Set the new radio access family to the maximum of the requested & supported
751 // int supportedRaf = mPhones[i].getRadioAccessFamily();
752 // mNewRadioAccessFamily[i] = requestedRaf & supportedRaf;
753 mNewRadioAccessFamily[i] = requestedRaf;
754
755 mCurrentLogicalModemIds[i] = get_radio_capa(i).logicalModemUuid;
756 // get the logical mode corresponds to new raf requested and pass the
757 // same as part of SET_RADIO_CAP APPLY phase
758 mNewLogicalModemIds[i] = getLogicalModemIdFromRaf(requestedRaf);
759 RLOGD("setRadioCapability: mOldRadioAccessFamily[%d]=%d", i,mOldRadioAccessFamily[i]);
760 RLOGD("setRadioCapability: mNewRadioAccessFamily[%d]=%d", i,mNewRadioAccessFamily[i]);
761 sendRadioCapabilityRequest(
762 i,
763 mRadioCapabilitySessionId.load(),
764 RadioCapabilityPhase(RC_PHASE_START),
765 mOldRadioAccessFamily[i],
766 mCurrentLogicalModemIds[i],
767 RadioCapabilityStatus(RC_STATUS_NONE),
768 EVENT_START_RC_RESPONSE);
769 }
770 m_mutex.unlock();
771 return true;
772}