• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "cellular_call_supplement.h"
17 
18 #include "cellular_call_register.h"
19 #include "cellular_call_service.h"
20 #include "ims_error.h"
21 #include "mmi_code_message.h"
22 #include "securec.h"
23 #include "standardize_utils.h"
24 #include "telephony_log_wrapper.h"
25 #include "telephony_ext_wrapper.h"
26 #ifdef SECURITY_GUARDE_ENABLE
27 #include "cellular_call_hisysevent.h"
28 #endif
29 
30 namespace OHOS {
31 namespace Telephony {
32 const int32_t NUM_PRESENTATION_ALLOWED = 0;
33 const int32_t NUM_PRESENTATION_RESTRICTED = 1;
34 const int32_t ACTIVATE_ACTION = 1;
35 const int32_t DEACTIVATE_ACTION = 2;
36 const int32_t USSD_MODE_NOTIFY = 0;
37 const int32_t USSD_MODE_REQUEST = 1;
38 const int32_t USSD_MODE_NW_RELEASE = 2;
39 const int32_t USSD_SUCCESS = 0;
40 const int32_t USSD_FAILED = 2;
41 const int32_t RESULT_SUCCESS = 0;
42 const int32_t MMI_CODE_FAILED = 1;
43 const int32_t PIN_PUK_MIN = 4;
44 const int32_t PIN_PUK_MAX = 8;
45 const std::string BARR_ALL_OUTGOING_CALLS = "AO";
46 const std::string BARR_OUTGOING_INTERNATIONAL_CALLS = "OI";
47 const std::string BARR_OUTGOING_INTERNATIONAL_CALLS_EXCLUDING_HOME = "OX";
48 const std::string BARR_ALL_INCOMING_CALLS = "AI";
49 const std::string BARR_INCOMING_CALLS_OUTSIDE_HOME = "IR";
50 const std::string ALL_BARRING_SERVICES = "AB";
51 const std::string ALL_OUTGOING_BARRING_SERVICES = "AG";
52 const std::string ALL_INCOMING_BARRING_SERVICES = "AC";
53 
operator ""_hash(char const * p,size_t s)54 constexpr unsigned long long operator"" _hash(char const *p, size_t s)
55 {
56     return StandardizeUtils::HashCompileTime(p);
57 }
58 
HandleClip(int32_t slotId,const MMIData & mmiData)59 void CellularCallSupplement::HandleClip(int32_t slotId, const MMIData &mmiData)
60 {
61     const std::string interrogate = "*#";
62     const std::string activate = "*";
63     const std::string deactivate = "#";
64     if (mmiData.actionString.empty()) {
65         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
66         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
67         return;
68     }
69     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
70     if (handler == nullptr) {
71         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
72         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
73         return;
74     }
75     int32_t result = TELEPHONY_ERROR;
76     auto utCommand = std::make_shared<SsRequestCommand>();
77     int32_t index;
78     handler->RequestSsRequestCommandIndex(index);
79     if (mmiData.actionString == activate) {
80         utCommand->action = ACTIVATE_ACTION;
81         result = supplementRequestIms_.SetClipRequest(slotId, ACTIVATE_ACTION, index);
82     } else if (mmiData.actionString == deactivate) {
83         utCommand->action = DEACTIVATE_ACTION;
84         result = supplementRequestIms_.SetClipRequest(slotId, DEACTIVATE_ACTION, index);
85     } else if (mmiData.actionString == interrogate) {
86         if (NeedUseImsToHandle(slotId)) {
87             result = supplementRequestIms_.GetClipRequest(slotId, index);
88         } else {
89             result = supplementRequestCs_.GetClipRequest(slotId, index);
90         }
91     }
92     if (result != TELEPHONY_SUCCESS) {
93         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
94     } else {
95         handler->SaveSsRequestCommand(utCommand, index);
96     }
97 }
98 
HandleClir(int32_t slotId,const MMIData & mmiData)99 void CellularCallSupplement::HandleClir(int32_t slotId, const MMIData &mmiData)
100 {
101     const std::string interrogate = "*#";
102     const std::string activate = "*";
103     const std::string deactivate = "#";
104     if (mmiData.actionString.empty()) {
105         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
106         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
107         return;
108     }
109     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
110     if (handler == nullptr) {
111         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
112         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
113         return;
114     }
115     int32_t result = TELEPHONY_ERROR;
116     auto utCommand = std::make_shared<SsRequestCommand>();
117     int32_t index;
118     handler->RequestSsRequestCommandIndex(index);
119     if (mmiData.actionString == activate) {
120         utCommand->action = ACTIVATE_ACTION;
121         if (NeedUseImsToHandle(slotId)) {
122             result = supplementRequestIms_.SetClirRequest(slotId, ACTIVATE_ACTION, index);
123         } else {
124             result = supplementRequestCs_.SetClirRequest(slotId, ACTIVATE_ACTION, index);
125         }
126     } else if (mmiData.actionString == deactivate) {
127         utCommand->action = DEACTIVATE_ACTION;
128         if (NeedUseImsToHandle(slotId)) {
129             result = supplementRequestIms_.SetClirRequest(slotId, DEACTIVATE_ACTION, index);
130         } else {
131             result = supplementRequestCs_.SetClirRequest(slotId, DEACTIVATE_ACTION, index);
132         }
133     } else if (mmiData.actionString == interrogate) {
134         if (NeedUseImsToHandle(slotId)) {
135             result = supplementRequestIms_.GetClirRequest(slotId, index);
136         } else {
137             result = supplementRequestCs_.GetClirRequest(slotId, index);
138         }
139     }
140     if (result != TELEPHONY_SUCCESS) {
141         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
142     } else {
143         handler->SaveSsRequestCommand(utCommand, index);
144     }
145 }
146 
HandleColr(int32_t slotId,const MMIData & mmiData)147 void CellularCallSupplement::HandleColr(int32_t slotId, const MMIData &mmiData)
148 {
149     const std::string interrogate = "*#";
150     const std::string activate = "*";
151     const std::string deactivate = "#";
152     if (mmiData.actionString.empty()) {
153         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
154         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
155         return;
156     }
157     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
158     if (handler == nullptr) {
159         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
160         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
161         return;
162     }
163     int32_t result = TELEPHONY_ERROR;
164     auto utCommand = std::make_shared<SsRequestCommand>();
165     int32_t index;
166     handler->RequestSsRequestCommandIndex(index);
167     if (mmiData.actionString == activate) {
168         utCommand->action = ACTIVATE_ACTION;
169         if (NeedUseImsToHandle(slotId)) {
170             result = supplementRequestIms_.SetColrRequest(slotId, NUM_PRESENTATION_ALLOWED, index);
171         }
172     } else if (mmiData.actionString == deactivate) {
173         utCommand->action = DEACTIVATE_ACTION;
174         if (NeedUseImsToHandle(slotId)) {
175             result = supplementRequestIms_.SetColrRequest(slotId, NUM_PRESENTATION_RESTRICTED, index);
176         }
177     } else if (mmiData.actionString == interrogate) {
178         if (NeedUseImsToHandle(slotId)) {
179             result = supplementRequestIms_.GetColrRequest(slotId, index);
180         }
181     }
182     if (result != TELEPHONY_SUCCESS) {
183         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
184     } else {
185         handler->SaveSsRequestCommand(utCommand, index);
186     }
187 }
188 
HandleColp(int32_t slotId,const MMIData & mmiData)189 void CellularCallSupplement::HandleColp(int32_t slotId, const MMIData &mmiData)
190 {
191     const std::string interrogate = "*#";
192     const std::string activate = "*";
193     const std::string deactivate = "#";
194     if (mmiData.actionString.empty()) {
195         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
196         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
197         return;
198     }
199     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
200     if (handler == nullptr) {
201         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
202         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
203         return;
204     }
205     int32_t result = TELEPHONY_ERROR;
206     auto utCommand = std::make_shared<SsRequestCommand>();
207     int32_t index;
208     handler->RequestSsRequestCommandIndex(index);
209     if (mmiData.actionString == activate) {
210         utCommand->action = ACTIVATE_ACTION;
211         if (NeedUseImsToHandle(slotId)) {
212             result = supplementRequestIms_.SetColpRequest(slotId, ACTIVATE_ACTION, index);
213         }
214     } else if (mmiData.actionString == deactivate) {
215         utCommand->action = DEACTIVATE_ACTION;
216         if (NeedUseImsToHandle(slotId)) {
217             result = supplementRequestIms_.SetColpRequest(slotId, DEACTIVATE_ACTION, index);
218         }
219     } else if (mmiData.actionString == interrogate) {
220         if (NeedUseImsToHandle(slotId)) {
221             result = supplementRequestIms_.GetColpRequest(slotId, index);
222         }
223     }
224     if (result != TELEPHONY_SUCCESS) {
225         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
226     } else {
227         handler->SaveSsRequestCommand(utCommand, index);
228     }
229 }
230 
HandleCallTransfer(int32_t slotId,const MMIData & mmiData)231 void CellularCallSupplement::HandleCallTransfer(int32_t slotId, const MMIData &mmiData)
232 {
233     const std::string interrogate = "*#";
234     int32_t serviceCode = ObtainServiceCode(mmiData.serviceInfoB);
235     int32_t cause = ObtainCause(mmiData.serviceCode);
236     if (!mmiData.actionString.empty() && mmiData.actionString == interrogate) {
237         HandleGetCallTransfer(slotId, cause);
238         return;
239     }
240     std::string phoneNumber = mmiData.serviceInfoA;
241     if (mmiData.actionString.empty()) {
242         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
243         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
244         return;
245     }
246     CallTransferSettingType callTransferAction;
247     int32_t result = ObtainCallTrasferAction(mmiData.actionString.c_str(), phoneNumber, callTransferAction);
248     if (result != TELEPHONY_SUCCESS) {
249         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
250         return;
251     }
252     HandleSetCallTransfer(slotId, serviceCode, cause, phoneNumber, callTransferAction);
253 }
254 
ObtainServiceCode(const std::string & serviceInfoB)255 int32_t CellularCallSupplement::ObtainServiceCode(const std::string &serviceInfoB)
256 {
257     if (serviceInfoB.empty()) {
258         TELEPHONY_LOGI("serviceInfoB is empty!");
259         return NONE;
260     }
261     int32_t intServiceInfoB = atoi(serviceInfoB.c_str());
262     switch (intServiceInfoB) {
263         case ALL_TELE_SERVICES:
264             return SHORT_MESSAGE_SERVICE + FAX + VOICE;
265         case TELE_SERVICES:
266             return VOICE;
267         case ALL_DATA_TELE_SERVICES:
268             return SHORT_MESSAGE_SERVICE + FAX;
269         case FACSIMILE_SERVICES:
270             return FAX;
271         case SHORT_MESSAGE_SERVICES:
272             return SHORT_MESSAGE_SERVICE;
273         case ALL_TELE_SERVICES_EXCEPT_SMS:
274             return FAX + VOICE;
275         case ALL_BEARER_SERVICES:
276             return DATA_CIRCUIT_ASYNC + DATA_CIRCUIT_SYNC;
277         case ALL_ASYNC_SERVICES:
278             return DEDICATED_PAD_ACCESS + DATA_CIRCUIT_ASYNC;
279         case ALL_SYNC_SERVICES:
280             return DEDICATED_PACKET_ACCESS + DATA_CIRCUIT_SYNC;
281         case ALL_DATA_CIRCUIT_SYNC:
282             return DATA_CIRCUIT_SYNC;
283         case ALL_DATA_CIRCUIT_ASYNC:
284             return DATA_CIRCUIT_ASYNC;
285         case ALL_GPRS_BEARER_SERVICES:
286             return DEDICATED_PACKET_ACCESS;
287         default:
288             TELEPHONY_LOGE("serviceInfoB out of range, please check!");
289             return NONE;
290     }
291 }
292 
ObtainCallTrasferAction(const char * actionString,const std::string & phoneNumber,CallTransferSettingType & callTransferAction)293 int32_t CellularCallSupplement::ObtainCallTrasferAction(
294     const char *actionString, const std::string &phoneNumber, CallTransferSettingType &callTransferAction)
295 {
296     // 3GPP TS 24.082 V4.0.0 (2001-03) 1 Call Forwarding Unconditional (CFU)
297     // 3GPP TS 24.082 V4.0.0 (2001-03) 2 Call Forwarding on mobile subscriber Busy (CFB)
298     // 3GPP TS 24.082 V4.0.0 (2001-03) 3 Call Forwarding on No Reply (CFNRy)
299     // 3GPP TS 24.082 V4.0.0 (2001-03) 4 Call Forwarding on mobile subscriber Not Reachable (CFNRc)
300     switch (StandardizeUtils::Hash_(actionString)) {
301         case "*"_hash:
302             if (phoneNumber.empty()) {
303                 callTransferAction = CallTransferSettingType::CALL_TRANSFER_ENABLE;
304             } else {
305                 callTransferAction = CallTransferSettingType::CALL_TRANSFER_REGISTRATION;
306             }
307             break;
308         case "#"_hash:
309             callTransferAction = CallTransferSettingType::CALL_TRANSFER_DISABLE;
310             break;
311         case "**"_hash:
312             callTransferAction = CallTransferSettingType::CALL_TRANSFER_REGISTRATION;
313             break;
314         case "##"_hash:
315             callTransferAction = CallTransferSettingType::CALL_TRANSFER_ERASURE;
316             break;
317         default:
318             TELEPHONY_LOGE("actionString out of range, please check!");
319             return TELEPHONY_ERR_ARGUMENT_MISMATCH;
320     }
321     return TELEPHONY_SUCCESS;
322 }
323 
ObtainCause(const std::string & actionStr)324 int32_t CellularCallSupplement::ObtainCause(const std::string &actionStr)
325 {
326     if (actionStr.empty()) {
327         TELEPHONY_LOGE("actionStr is empty!");
328         return TELEPHONY_ERROR;
329     }
330 
331     /*
332      * 3GPP TS 22.030 V4.0.0 (2001-03) Annex B (normative): Codes for defined Supplementary Services
333      * CFU	                21
334      * CF Busy	            67
335      * CF No Reply	        61
336      * CF Not Reachable 	62
337      * all CF		        002
338      * all conditional CF	004
339      */
340     switch (StandardizeUtils::Hash_(actionStr.c_str())) {
341         case "21"_hash:
342             return static_cast<int32_t>(CallTransferType::TRANSFER_TYPE_UNCONDITIONAL);
343         case "67"_hash:
344             return static_cast<int32_t>(CallTransferType::TRANSFER_TYPE_BUSY);
345         case "61"_hash:
346             return static_cast<int32_t>(CallTransferType::TRANSFER_TYPE_NO_REPLY);
347         case "62"_hash:
348             return static_cast<int32_t>(CallTransferType::TRANSFER_TYPE_NOT_REACHABLE);
349         default:
350             TELEPHONY_LOGE("actionStr out of range!");
351             return TELEPHONY_ERROR;
352     }
353 }
354 
HandleGetCallTransfer(int32_t slotId,int32_t cause)355 void CellularCallSupplement::HandleGetCallTransfer(int32_t slotId, int32_t cause)
356 {
357     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
358     if (handler == nullptr) {
359         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
360         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
361         return;
362     }
363     auto utCommand = std::make_shared<SsRequestCommand>();
364     utCommand->cfReason = cause;
365     int32_t index;
366     handler->RequestSsRequestCommandIndex(index);
367     int32_t result = TELEPHONY_ERROR;
368     if (NeedUseImsToHandle(slotId)) {
369         result = supplementRequestIms_.GetCallTransferRequest(slotId, cause, index);
370     } else {
371         result = supplementRequestCs_.GetCallTransferRequest(slotId, cause, index);
372     }
373     if (result != TELEPHONY_SUCCESS) {
374         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
375     } else {
376         handler->SaveSsRequestCommand(utCommand, index);
377     }
378 }
379 
HandleSetCallTransfer(int32_t slotId,int32_t serviceCode,int32_t cause,const std::string & phoneNumber,CallTransferSettingType callTransferAction)380 void CellularCallSupplement::HandleSetCallTransfer(int32_t slotId, int32_t serviceCode, int32_t cause,
381     const std::string &phoneNumber, CallTransferSettingType callTransferAction)
382 {
383     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
384     if (handler == nullptr) {
385         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
386         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
387         return;
388     }
389 #ifdef SECURITY_GUARDE_ENABLE
390     if (callTransferAction == CallTransferSettingType::CALL_TRANSFER_REGISTRATION ||
391         callTransferAction == CallTransferSettingType::CALL_TRANSFER_ERASURE) {
392         uint8_t state = callTransferAction == CallTransferSettingType::CALL_TRANSFER_ERASURE ? 0 : 1;
393         CellularCallHiSysEvent::WriteCallTansferEvent(state);
394     }
395 #endif
396     auto utCommand = std::make_shared<SsRequestCommand>();
397     utCommand->cfReason = cause;
398     utCommand->cfAction = static_cast<int32_t>(callTransferAction);
399     utCommand->action = static_cast<int32_t>(callTransferAction);
400     utCommand->number = phoneNumber;
401     int32_t index;
402     handler->RequestSsRequestCommandIndex(index);
403     int32_t result = TELEPHONY_ERROR;
404     if (NeedUseImsToHandle(slotId)) {
405         CallTransferInfo cfInfo;
406         if (memcpy_s(cfInfo.transferNum, kMaxNumberLen, phoneNumber.c_str(), phoneNumber.length()) != EOK) {
407             TELEPHONY_LOGE("[slot%{public}d] memcpy_s failed!", slotId);
408             ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
409             return;
410         }
411         cfInfo.settingType = callTransferAction;
412         cfInfo.type = static_cast<CallTransferType>(cause);
413         // set the time as default min, this mean the time will not use at IMS
414         cfInfo.startHour = MIN_HOUR;
415         cfInfo.startMinute = MIN_MINUTE;
416         cfInfo.endHour = MIN_HOUR;
417         cfInfo.endMinute = MIN_MINUTE;
418         result = supplementRequestIms_.SetCallTransferRequest(slotId, cfInfo, serviceCode, index);
419     } else {
420         CallTransferParam callTransferParam;
421         callTransferParam.mode = static_cast<int32_t>(callTransferAction);
422         callTransferParam.reason = cause;
423         callTransferParam.number = phoneNumber;
424         callTransferParam.classx = serviceCode;
425         result = supplementRequestCs_.SetCallTransferRequest(slotId, callTransferParam, index);
426     }
427     if (result != TELEPHONY_SUCCESS) {
428         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
429     } else {
430         handler->SaveSsRequestCommand(utCommand, index);
431     }
432 }
433 
HandleCallRestriction(int32_t slotId,const MMIData & mmiData)434 void CellularCallSupplement::HandleCallRestriction(int32_t slotId, const MMIData &mmiData)
435 {
436     std::string infoA = mmiData.serviceInfoA;
437     std::string facType = ObtainBarringInstallation(mmiData.serviceCode);
438     const std::string interrogate = "*#";
439     const std::string activate = "*";
440     const std::string deactivate = "#";
441     if (mmiData.actionString.empty()) {
442         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
443         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
444         return;
445     }
446     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
447     if (handler == nullptr) {
448         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
449         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
450         return;
451     }
452     auto utCommand = std::make_shared<SsRequestCommand>();
453     utCommand->facility = facType;
454     int32_t index;
455     handler->RequestSsRequestCommandIndex(index);
456     int32_t result = TELEPHONY_ERROR;
457     if (mmiData.actionString == interrogate) {
458         if (NeedUseImsToHandle(slotId)) {
459             result = supplementRequestIms_.GetCallRestrictionRequest(slotId, facType, index);
460         } else {
461             result = supplementRequestCs_.GetCallRestrictionRequest(slotId, facType, index);
462         }
463     } else if (mmiData.actionString == activate || mmiData.actionString == deactivate) {
464         utCommand->enable = mmiData.actionString == activate;
465         size_t cpyLen = strlen(infoA.c_str()) + 1;
466         size_t maxCpyLen = sizeof(utCommand->password);
467         if (strcpy_s(utCommand->password, cpyLen > maxCpyLen ? maxCpyLen : cpyLen, infoA.c_str()) != EOK) {
468             TELEPHONY_LOGE("[slot%{public}d] strcpy_s fail.", slotId);
469             return;
470         }
471         if (NeedUseImsToHandle(slotId)) {
472             result = supplementRequestIms_.SetCallRestrictionRequest(
473                 slotId, facType, mmiData.actionString == activate, infoA, index);
474         } else {
475             result = supplementRequestCs_.SetCallRestrictionRequest(
476                 slotId, facType, mmiData.actionString == activate, infoA, index);
477         }
478     }
479     if (result != TELEPHONY_SUCCESS) {
480         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
481     } else {
482         handler->SaveSsRequestCommand(utCommand, index);
483     }
484 }
485 
ObtainBarringInstallation(const std::string & serviceInfoC)486 std::string CellularCallSupplement::ObtainBarringInstallation(const std::string &serviceInfoC)
487 {
488     if (serviceInfoC.empty()) {
489         TELEPHONY_LOGE("serviceInfoC is empty!");
490         return std::string();
491     }
492 
493     /*
494      * 27007-430_2001 7.4	Facility lock +CLCK
495      *  Supplementary	Service Service	Code	SIA	SIB	SIC
496      * 	22.088
497      * 	BAOC	            33	                 PW	BS	-
498      * 	BAOIC	            331	                 PW	BS	-
499      * 	BAOIC exc home	    332	                 PW	BS	-
500      * 	BAIC	            35	                 PW	BS	-
501      * 	BAIC roaming	    351	                 PW	BS	-
502      *  all Barring Serv.   330	                 PW	BS	-
503      *  Outg. Barr. Serv.   333	                 PW	BS
504      *  Inc. Barr. Serv.	353	                 PW	BS
505      */
506     switch (StandardizeUtils::Hash_(serviceInfoC.c_str())) {
507         case "33"_hash:
508             // "AO"	BAOC (Barr All Outgoing Calls) (refer 3GPP TS 22.088 [6] clause 1)
509             return BARR_ALL_OUTGOING_CALLS;
510         case "331"_hash:
511             // "OI"	BOIC (Barr Outgoing International Calls) (refer 3GPP TS 22.088 [6] clause 1)
512             return BARR_OUTGOING_INTERNATIONAL_CALLS;
513         case "332"_hash:
514             // "OX"	BOIC exHC (Barr Outgoing International Calls except to Home Country)
515             // (refer 3GPP TS 22.088 [6] clause 1)
516             return BARR_OUTGOING_INTERNATIONAL_CALLS_EXCLUDING_HOME;
517         case "351"_hash:
518             // "IR"	BIC Roam (Barr Incoming Calls when Roaming outside the home country)
519             // (refer 3GPP TS 22.088 [6] clause 2)
520             return BARR_INCOMING_CALLS_OUTSIDE_HOME;
521         case "35"_hash:
522             // "AI"	BAIC (Barr All Incoming Calls) (refer 3GPP TS 22.088 [6] clause 2)
523             return BARR_ALL_INCOMING_CALLS;
524         case "330"_hash:
525             // "AB"	All Barring services (refer 3GPP TS 22.030 [19]) (applicable only for <mode>=0)
526             return ALL_BARRING_SERVICES;
527         case "333"_hash:
528             // "AG"	All outGoing barring services (refer 3GPP TS 22.030 [19]) (applicable only for <mode>=0)
529             return ALL_OUTGOING_BARRING_SERVICES;
530         case "353"_hash:
531             // "AC"	All inComing barring services (refer 3GPP TS 22.030 [19]) (applicable only for <mode>=0)
532             return ALL_INCOMING_BARRING_SERVICES;
533         default:
534             TELEPHONY_LOGE("serviceInfoC out of range!");
535             return std::string();
536     }
537 }
538 
HandleCallWaiting(int32_t slotId,const MMIData & mmiData)539 void CellularCallSupplement::HandleCallWaiting(int32_t slotId, const MMIData &mmiData)
540 {
541     if (mmiData.actionString.empty()) {
542         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVALID_MMI_CODE);
543         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
544         return;
545     }
546     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
547     if (handler == nullptr) {
548         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
549         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
550         return;
551     }
552     const std::string activate = "*";
553     const std::string deactivate = "#";
554     const std::string interrogate = "*#";
555     int32_t result = TELEPHONY_ERROR;
556     int32_t classType = ObtainServiceCode(mmiData.serviceInfoA);
557     auto utCommand = std::make_shared<SsRequestCommand>();
558     utCommand->classType = classType;
559     int32_t index;
560     handler->RequestSsRequestCommandIndex(index);
561     if (mmiData.actionString == activate || mmiData.actionString == deactivate) {
562         utCommand->enable = mmiData.actionString == activate;
563         utCommand->action = mmiData.actionString == activate;
564         if (NeedUseImsToHandle(slotId)) {
565             result =
566                 supplementRequestIms_.SetCallWaitingRequest(slotId, mmiData.actionString == activate, classType, index);
567         } else {
568             result =
569                 supplementRequestCs_.SetCallWaitingRequest(slotId, mmiData.actionString == activate, classType, index);
570         }
571     } else if (mmiData.actionString == interrogate) {
572         if (NeedUseImsToHandle(slotId)) {
573             result = supplementRequestIms_.GetCallWaitingRequest(slotId, index);
574         } else {
575             result = supplementRequestCs_.GetCallWaitingRequest(slotId, index);
576         }
577     }
578     if (result != TELEPHONY_SUCCESS) {
579         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
580     } else {
581         handler->SaveSsRequestCommand(utCommand, index);
582     }
583 }
584 
EventGetCallWaiting(const CallWaitResult & waitingInfo,const std::string & message,int32_t flag)585 void CellularCallSupplement::EventGetCallWaiting(
586     const CallWaitResult &waitingInfo, const std::string &message, int32_t flag)
587 {
588     CallWaitResponse callWaitResponse;
589     callWaitResponse.result = waitingInfo.result.result;
590     if (callWaitResponse.result == IMS_ERROR_UT_NO_CONNECTION) {
591         callWaitResponse.result = CALL_ERR_UT_NO_CONNECTION;
592     }
593 
594     /*
595      * <n> (sets/shows the result code presentation status in the TA):
596      * 0	disable
597      * 1	enable
598      */
599     callWaitResponse.status = waitingInfo.status;
600     callWaitResponse.classCw = waitingInfo.classCw;
601     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
602     if (callRegister == nullptr) {
603         TELEPHONY_LOGE("callRegister is null.");
604         return;
605     }
606     if (flag == SS_FROM_MMI_CODE) {
607         std::string successMessage = GET_CALL_WAITING_SUCCESS;
608         CreateGetCallWaitingResultMessage(successMessage, callWaitResponse);
609         MmiCodeInfo mmiCodeInfo;
610         mmiCodeInfo.result = callWaitResponse.result;
611         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
612             TELEPHONY_LOGE("strcpy_s fail");
613         }
614         mmiCodeInfo.mmiCodeType = SC_WAIT;
615         mmiCodeInfo.action = SUB_TYPE_QUERY;
616         mmiCodeInfo.status = waitingInfo.status;
617         mmiCodeInfo.classCw = waitingInfo.classCw;
618         ReportMmiCodeMessage(mmiCodeInfo);
619     } else {
620         callRegister->ReportGetWaitingResult(callWaitResponse);
621     }
622 }
623 
EventSetCallWaiting(int32_t result,const std::string & message,int32_t flag,int32_t action)624 void CellularCallSupplement::EventSetCallWaiting(int32_t result,
625     const std::string &message, int32_t flag, int32_t action)
626 {
627     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
628     if (callRegister == nullptr) {
629         TELEPHONY_LOGE("callRegister is null.");
630         return;
631     }
632     if (flag == SS_FROM_MMI_CODE) {
633         MmiCodeInfo mmiCodeInfo;
634         mmiCodeInfo.result = result;
635         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
636             TELEPHONY_LOGE("strcpy_s fail");
637         }
638         mmiCodeInfo.mmiCodeType = SC_WAIT;
639         mmiCodeInfo.action = action ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
640 
641         ReportMmiCodeMessage(mmiCodeInfo);
642     } else {
643         callRegister->ReportSetWaitingResult(result);
644     }
645 }
646 
EventGetCallTransferInfo(const CallForwardQueryInfoList & cFQueryList,const std::string & message,int32_t flag)647 void CellularCallSupplement::EventGetCallTransferInfo(
648     const CallForwardQueryInfoList &cFQueryList, const std::string &message, int32_t flag)
649 {
650     if (cFQueryList.result.result != TELEPHONY_SUCCESS && cFQueryList.callSize == 0) {
651         CallForwardQueryResult failResult;
652         failResult.result = cFQueryList.result.result;
653         failResult.reason = cFQueryList.result.reason;
654         BuildCallForwardQueryInfo(failResult, message, flag);
655     }
656     for (auto queryResult : cFQueryList.calls) {
657         TELEPHONY_LOGI("data: status %{public}d, classx %{public}d, reason %{public}d", queryResult.status,
658             queryResult.classx, queryResult.reason);
659         if (queryResult.classx > 0 && (static_cast<uint32_t>(queryResult.classx) & ServiceClassType::VOICE) != 0) {
660             BuildCallForwardQueryInfo(queryResult, message, flag);
661         }
662     }
663 }
664 
BuildCallForwardQueryInfo(const CallForwardQueryResult & queryResult,const std::string & message,int32_t flag)665 void CellularCallSupplement::BuildCallForwardQueryInfo(
666     const CallForwardQueryResult &queryResult, const std::string &message, int32_t flag)
667 {
668     // 3GPP TS 27.007 V3.9.0 (2001-06) 7.11	Call forwarding number and conditions +CCFC
669     CallTransferResponse response;
670     if (memset_s(&response, sizeof(response), 0, sizeof(response)) != EOK) {
671         TELEPHONY_LOGE("memset_s fail.");
672         return;
673     }
674     // <number>: string type phone number of forwarding address in format specified by <type>
675     if (strcpy_s(response.number, sizeof(response.number), queryResult.number.c_str()) != EOK) {
676         TELEPHONY_LOGE(" strcpy_s fail.");
677         return;
678     }
679     response.result = queryResult.result;
680     /*
681      * <status>:0	not active;    1	  active
682      * */
683     response.status = queryResult.status;
684     /*
685      * <classx> is a sum of integers each representing a class of information (default 7):
686      * 1	voice (telephony)
687      * 2	data (refers to all bearer services)
688      * 4	fax (facsimile services)
689      * 8	short message service
690      * 16	data circuit sync
691      * 32	data circuit async
692      * 64	dedicated packet access
693      * 128	dedicated PAD access
694      */
695     response.classx = queryResult.classx;
696     // <type>: type of address octet in integer format (refer GSM 04.08 [8] subclause 10.5.4.7);
697     // default 145 when dialling string includes international access code character "+", otherwise 129
698     response.type = queryResult.type;
699     response.reason = queryResult.reason;
700     response.time = queryResult.time;
701     response.startHour = queryResult.startHour;
702     response.startMinute = queryResult.startMinute;
703     response.endHour = queryResult.endHour;
704     response.endMinute = queryResult.endMinute;
705     if (flag == SS_FROM_MMI_CODE) {
706         std::string successMessage = GET_CALL_TRANSFER_SUCCESS;
707         CreateGetCallTransferResultMessage(successMessage, response);
708         MmiCodeInfo mmiCodeInfo;
709         mmiCodeInfo.mmiCodeType = SC_CFU;
710         mmiCodeInfo.action = SUB_TYPE_QUERY;
711         mmiCodeInfo.result = queryResult.result;
712         mmiCodeInfo.classCw = queryResult.classx;
713         mmiCodeInfo.reason = queryResult.reason;
714         mmiCodeInfo.status = queryResult.status;
715         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
716             TELEPHONY_LOGE("strcpy_s fail");
717         }
718         mmiCodeInfo.time = queryResult.time;
719         ReportMmiCodeMessage(mmiCodeInfo);
720     } else {
721         auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
722         if (callRegister == nullptr) {
723             TELEPHONY_LOGE("callRegister is null.");
724             return;
725         }
726         callRegister->ReportGetTransferResult(response);
727     }
728 }
729 
EventSetCallTransferInfo(int32_t result,const std::string & message,int32_t flag,int32_t action)730 void CellularCallSupplement::EventSetCallTransferInfo(int32_t result, const std::string &message, int32_t flag,
731     int32_t action)
732 {
733     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
734     if (callRegister == nullptr) {
735         TELEPHONY_LOGE("callRegister is null.");
736         return;
737     }
738 
739     if (flag == SS_FROM_MMI_CODE) {
740         MmiCodeInfo mmiCodeInfo;
741         mmiCodeInfo.result = result;
742         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
743             TELEPHONY_LOGE("strcpy_s fail");
744         }
745         mmiCodeInfo.mmiCodeType = SC_CFU;
746         mmiCodeInfo.action = action ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
747         ReportMmiCodeMessage(mmiCodeInfo);
748     } else {
749         callRegister->ReportSetTransferResult(result);
750     }
751 }
752 
EventGetCallRestriction(const CallRestrictionResult & result,const std::string & message,int32_t flag)753 void CellularCallSupplement::EventGetCallRestriction(
754     const CallRestrictionResult &result, const std::string &message, int32_t flag)
755 {
756     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
757     if (callRegister == nullptr) {
758         TELEPHONY_LOGE("callRegister is null.");
759         return;
760     }
761     CallRestrictionResponse response;
762     response.result = result.result.result;
763     if (response.result == IMS_ERROR_UT_NO_CONNECTION) {
764         response.result = CALL_ERR_UT_NO_CONNECTION;
765     }
766 
767     /*
768      * <status>:0	not active    1	  active
769      */
770     response.status = result.status;
771     response.classCw = result.classCw;
772 
773     if (flag == SS_FROM_MMI_CODE) {
774         std::string successMessage = GET_CALL_RESTRICTION_SUCCESS;
775         MmiCodeInfo mmiCodeInfo;
776         mmiCodeInfo.result = response.result;
777         mmiCodeInfo.mmiCodeType = SC_CLIP;
778         mmiCodeInfo.action = SUB_TYPE_QUERY;
779         mmiCodeInfo.status = response.status;
780         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
781             TELEPHONY_LOGE("strcpy_s fail");
782         }
783         ReportMmiCodeMessage(mmiCodeInfo);
784     } else {
785         callRegister->ReportGetRestrictionResult(response);
786     }
787 }
788 
EventSetCallRestriction(int32_t result,const std::string & message,int32_t flag,int32_t action)789 void CellularCallSupplement::EventSetCallRestriction(int32_t result, const std::string &message, int32_t flag,
790     int32_t action)
791 {
792     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
793     if (callRegister == nullptr) {
794         TELEPHONY_LOGE("callRegister is null.");
795         return;
796     }
797     if (flag == SS_FROM_MMI_CODE) {
798         MmiCodeInfo mmiCodeInfo;
799         mmiCodeInfo.result = result;
800         mmiCodeInfo.mmiCodeType = SC_CLIP;
801         mmiCodeInfo.action = action ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
802         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
803             TELEPHONY_LOGE("strcpy_s fail");
804         }
805         ReportMmiCodeMessage(mmiCodeInfo);
806     } else {
807         callRegister->ReportSetRestrictionResult(result);
808     }
809 }
810 
EventSetBarringPassword(int32_t result,const std::string & message,int32_t flag)811 void CellularCallSupplement::EventSetBarringPassword(int32_t result, const std::string &message, int32_t flag)
812 {
813     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
814     if (callRegister == nullptr) {
815         TELEPHONY_LOGE("callRegister is null.");
816         return;
817     }
818     if (flag == SS_FROM_MMI_CODE) {
819         MmiCodeInfo mmiCodeInfo;
820         mmiCodeInfo.result = result;
821         mmiCodeInfo.mmiCodeType = SC_BAOC;
822         mmiCodeInfo.action = SUB_TYPE_ACTIVE;
823         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
824             TELEPHONY_LOGE("strcpy_s fail");
825         }
826         ReportMmiCodeMessage(mmiCodeInfo);
827     } else {
828         callRegister->ReportSetBarringPasswordResult(result);
829     }
830 }
831 
SetCallTransferInfo(int32_t slotId,const CallTransferInfo & cfInfo)832 int32_t CellularCallSupplement::SetCallTransferInfo(int32_t slotId, const CallTransferInfo &cfInfo)
833 {
834     int32_t result = CheckSetCallTransferInfo(cfInfo);
835     RadioResponseInfo responseInfo;
836     responseInfo.error = ErrType::ERR_GENERIC_FAILURE;
837     if (result != TELEPHONY_SUCCESS) {
838         return result;
839     }
840     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
841     if (handler == nullptr) {
842         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
843         return TELEPHONY_ERR_LOCAL_PTR_NULL;
844     }
845 
846     std::string dialString(cfInfo.transferNum);
847     auto utCommand = std::make_shared<SsRequestCommand>();
848     utCommand->flag = SS_FROM_SETTING_MENU;
849     utCommand->number = dialString;
850     utCommand->cfAction = static_cast<int32_t>(cfInfo.settingType);
851     utCommand->cfReason = static_cast<int32_t>(cfInfo.type);
852     utCommand->classType = ServiceClassType::VOICE;
853     if (NeedUseImsToHandle(slotId)) {
854         return SetCallTransferInfoByIms(slotId, cfInfo, utCommand);
855     }
856 
857     if (!PhoneTypeGsmOrNot(slotId)) {
858         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
859         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
860     }
861 
862     CallTransferParam callTransferParam;
863     callTransferParam.mode = static_cast<int32_t>(cfInfo.settingType);
864     callTransferParam.reason = static_cast<int32_t>(cfInfo.type);
865     callTransferParam.number = dialString;
866     callTransferParam.classx = ServiceClassType::VOICE;
867     int32_t index;
868     handler->RequestSsRequestCommandIndex(index);
869     result = supplementRequestCs_.SetCallTransferRequest(slotId, callTransferParam, index);
870     if (result == TELEPHONY_SUCCESS) {
871         handler->SaveSsRequestCommand(utCommand, index);
872     }
873     return result;
874 }
875 
CheckSetCallTransferInfo(const CallTransferInfo & cfInfo)876 int32_t CellularCallSupplement::CheckSetCallTransferInfo(const CallTransferInfo &cfInfo)
877 {
878     if (strlen(cfInfo.transferNum) == 0) {
879         TELEPHONY_LOGE("transferNum is empty!");
880         return TELEPHONY_ERR_ARGUMENT_INVALID;
881     }
882 
883     /*
884      * <reason>:
885      * 0   unconditional
886      * 1   mobile busy
887      * 2   no reply
888      * 3   not reachable
889      * 4   all call forwarding (refer 3GPP TS 22.030 [19])
890      * 5   all conditional call forwarding (refer 3GPP TS 22.030 [19])
891      * <mode>:
892      * 0   disable
893      * 1   enable
894      * 2   query status
895      * 3   registration
896      * 4   erasure
897      */
898     if (cfInfo.type > CallTransferType::TRANSFER_TYPE_NOT_REACHABLE ||
899         cfInfo.type < CallTransferType::TRANSFER_TYPE_UNCONDITIONAL ||
900         cfInfo.settingType > CallTransferSettingType::CALL_TRANSFER_ERASURE ||
901         cfInfo.settingType < CallTransferSettingType::CALL_TRANSFER_DISABLE) {
902         TELEPHONY_LOGE("parameter out of range!");
903         return CALL_ERR_PARAMETER_OUT_OF_RANGE;
904     }
905     return TELEPHONY_SUCCESS;
906 }
907 
SetCallTransferInfoByIms(int32_t slotId,const CallTransferInfo & cfInfo,const std::shared_ptr<SsRequestCommand> & command)908 int32_t CellularCallSupplement::SetCallTransferInfoByIms(
909     int32_t slotId, const CallTransferInfo &cfInfo, const std::shared_ptr<SsRequestCommand> &command)
910 {
911     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
912     RadioResponseInfo responseInfo;
913     responseInfo.error = ErrType::ERR_GENERIC_FAILURE;
914     if (handler == nullptr) {
915         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
916         return TELEPHONY_ERR_LOCAL_PTR_NULL;
917     }
918     int32_t index;
919     handler->RequestSsRequestCommandIndex(index);
920     int32_t result = supplementRequestIms_.SetCallTransferRequest(slotId, cfInfo, ServiceClassType::VOICE, index);
921     if (result == TELEPHONY_SUCCESS) {
922         handler->SaveSsRequestCommand(command, index);
923     }
924     return result;
925 }
926 
CanSetCallTransferTime(int32_t slotId,bool & result)927 int32_t CellularCallSupplement::CanSetCallTransferTime(int32_t slotId, bool &result)
928 {
929     if (!moduleServiceUtils_.NeedCallImsService()) {
930         return CALL_ERR_RESOURCE_UNAVAILABLE;
931     }
932     int32_t ret = TELEPHONY_SUCCESS;
933     ret = supplementRequestIms_.CanSetCallTransferTime(slotId, result);
934     return ret;
935 }
936 
GetCallTransferInfo(int32_t slotId,CallTransferType type)937 int32_t CellularCallSupplement::GetCallTransferInfo(int32_t slotId, CallTransferType type)
938 {
939     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
940     if (handler == nullptr) {
941         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
942         return TELEPHONY_ERR_LOCAL_PTR_NULL;
943     }
944     int32_t result = TELEPHONY_ERROR;
945     auto utCommand = std::make_shared<SsRequestCommand>();
946     utCommand->flag = SS_FROM_SETTING_MENU;
947     utCommand->cfReason = static_cast<int32_t>(type);
948     int32_t index;
949     if (NeedUseImsToHandle(slotId)) {
950         handler->RequestSsRequestCommandIndex(index);
951         result = supplementRequestIms_.GetCallTransferRequest(slotId, static_cast<int32_t>(type), index);
952         if (result == TELEPHONY_SUCCESS) {
953             handler->SaveSsRequestCommand(utCommand, index);
954         }
955         return result;
956     }
957     if (!PhoneTypeGsmOrNot(slotId)) {
958         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
959         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
960     }
961 
962     /*
963      * When querying the status of a network service (<mode>=2) the response line for 'not active' case
964      * (<status>=0) should be returned only if service is not active for any <class>
965      */
966     handler->RequestSsRequestCommandIndex(index);
967     result = supplementRequestCs_.GetCallTransferRequest(slotId, static_cast<int32_t>(type), index);
968     if (result == TELEPHONY_SUCCESS) {
969         handler->SaveSsRequestCommand(utCommand, index);
970     }
971     return result;
972 }
973 
PhoneTypeGsmOrNot(int32_t slotId)974 bool CellularCallSupplement::PhoneTypeGsmOrNot(int32_t slotId)
975 {
976     return moduleServiceUtils_.GetNetworkStatus(slotId) == PhoneType::PHONE_TYPE_IS_GSM;
977 }
978 
NeedUseImsToHandle(int32_t slotId)979 bool CellularCallSupplement::NeedUseImsToHandle(int32_t slotId)
980 {
981     return moduleServiceUtils_.NeedCallImsService();
982 }
983 
SetCallWaiting(int32_t slotId,bool activate)984 int32_t CellularCallSupplement::SetCallWaiting(int32_t slotId, bool activate)
985 {
986     RadioResponseInfo responseInfo;
987     responseInfo.error = ErrType::ERR_GENERIC_FAILURE;
988     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
989     if (handler == nullptr) {
990         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
991         return TELEPHONY_ERR_LOCAL_PTR_NULL;
992     }
993     int32_t classType = ServiceClassType::VOICE;
994     CellularCallConfig config;
995     classType = config.GetCallWaitingServiceClassConfig(slotId);
996     int32_t result = TELEPHONY_ERROR;
997     auto utCommand = std::make_shared<SsRequestCommand>();
998     utCommand->flag = SS_FROM_SETTING_MENU;
999     utCommand->classType = classType;
1000     utCommand->enable = activate;
1001     utCommand->action = activate;
1002     int32_t index;
1003     if (NeedUseImsToHandle(slotId)) {
1004         handler->RequestSsRequestCommandIndex(index);
1005         result = supplementRequestIms_.SetCallWaitingRequest(slotId, activate, classType, index);
1006         if (result == TELEPHONY_SUCCESS) {
1007             handler->SaveSsRequestCommand(utCommand, index);
1008         }
1009         return result;
1010     }
1011     /*
1012      * <n> (sets/shows the result code presentation status in the TA):
1013      * 0	disable
1014      * 1	enable
1015      */
1016     if (!PhoneTypeGsmOrNot(slotId)) {
1017         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
1018         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
1019     }
1020     handler->RequestSsRequestCommandIndex(index);
1021     result = supplementRequestCs_.SetCallWaitingRequest(slotId, activate, classType, index);
1022     if (result == TELEPHONY_SUCCESS) {
1023         handler->SaveSsRequestCommand(utCommand, index);
1024     }
1025     return result;
1026 }
1027 
GetCallWaiting(int32_t slotId)1028 int32_t CellularCallSupplement::GetCallWaiting(int32_t slotId)
1029 {
1030     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
1031     if (handler == nullptr) {
1032         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
1033         return TELEPHONY_ERR_LOCAL_PTR_NULL;
1034     }
1035     int32_t result = TELEPHONY_ERROR;
1036     auto utCommand = std::make_shared<SsRequestCommand>();
1037     utCommand->flag = SS_FROM_SETTING_MENU;
1038     int32_t index;
1039     if (NeedUseImsToHandle(slotId)) {
1040         handler->RequestSsRequestCommandIndex(index);
1041         result = supplementRequestIms_.GetCallWaitingRequest(slotId, index);
1042         if (result == TELEPHONY_SUCCESS) {
1043             handler->SaveSsRequestCommand(utCommand, index);
1044         }
1045         return result;
1046     }
1047     if (!PhoneTypeGsmOrNot(slotId)) {
1048         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
1049         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
1050     }
1051     handler->RequestSsRequestCommandIndex(index);
1052     result = supplementRequestCs_.GetCallWaitingRequest(slotId, index);
1053     if (result == TELEPHONY_SUCCESS) {
1054         handler->SaveSsRequestCommand(utCommand, index);
1055     }
1056     return result;
1057 }
1058 
SetCallRestriction(int32_t slotId,const CallRestrictionInfo & cRInfo)1059 int32_t CellularCallSupplement::SetCallRestriction(int32_t slotId, const CallRestrictionInfo &cRInfo)
1060 {
1061     RadioResponseInfo responseInfo;
1062     responseInfo.error = ErrType::ERR_GENERIC_FAILURE;
1063     std::string fac;
1064     int32_t result = CheckCallRestrictionType(fac, cRInfo.fac);
1065     if (result != TELEPHONY_SUCCESS) {
1066         return result;
1067     }
1068     if (cRInfo.mode < CallRestrictionMode::RESTRICTION_MODE_DEACTIVATION ||
1069         cRInfo.mode > CallRestrictionMode::RESTRICTION_MODE_ACTIVATION) {
1070         TELEPHONY_LOGE("[slot%{public}d] mode parameter out of range!", slotId);
1071         return CALL_ERR_PARAMETER_OUT_OF_RANGE;
1072     }
1073     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
1074     if (handler == nullptr) {
1075         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
1076         return TELEPHONY_ERR_LOCAL_PTR_NULL;
1077     }
1078     std::string info(cRInfo.password);
1079     auto utCommand = std::make_shared<SsRequestCommand>();
1080     utCommand->flag = SS_FROM_SETTING_MENU;
1081     utCommand->facility = fac;
1082     utCommand->enable = static_cast<int32_t>(cRInfo.mode);
1083     utCommand->action = static_cast<int32_t>(cRInfo.mode);
1084     size_t cpyLen = strlen(info.c_str()) + 1;
1085     size_t maxCpyLen = sizeof(utCommand->password);
1086     if (strcpy_s(utCommand->password, cpyLen > maxCpyLen ? maxCpyLen : cpyLen, info.c_str()) != EOK) {
1087         TELEPHONY_LOGE("[slot%{public}d] strcpy_s fail.", slotId);
1088         return TELEPHONY_ERR_STRCPY_FAIL;
1089     }
1090     int32_t index;
1091     if (NeedUseImsToHandle(slotId)) {
1092         return SetCallRestrictionByIms(slotId, fac, static_cast<int32_t>(cRInfo.mode), info, utCommand);
1093     }
1094     if (!PhoneTypeGsmOrNot(slotId)) {
1095         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
1096         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
1097     }
1098     handler->RequestSsRequestCommandIndex(index);
1099     result =
1100         supplementRequestCs_.SetCallRestrictionRequest(slotId, fac, static_cast<int32_t>(cRInfo.mode), info, index);
1101     if (result == TELEPHONY_SUCCESS) {
1102         handler->SaveSsRequestCommand(utCommand, index);
1103     }
1104     return result;
1105 }
1106 
SetCallRestrictionByIms(int32_t slotId,std::string & fac,int32_t mode,std::string & pw,const std::shared_ptr<SsRequestCommand> & command)1107 int32_t CellularCallSupplement::SetCallRestrictionByIms(
1108     int32_t slotId, std::string &fac, int32_t mode, std::string &pw, const std::shared_ptr<SsRequestCommand> &command)
1109 {
1110     RadioResponseInfo responseInfo;
1111     responseInfo.error = ErrType::ERR_GENERIC_FAILURE;
1112     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
1113     if (handler == nullptr) {
1114         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
1115         return TELEPHONY_ERR_LOCAL_PTR_NULL;
1116     }
1117     int32_t index;
1118     handler->RequestSsRequestCommandIndex(index);
1119     int32_t result = supplementRequestIms_.SetCallRestrictionRequest(slotId, fac, mode, pw, index);
1120     if (result == TELEPHONY_SUCCESS) {
1121         handler->SaveSsRequestCommand(command, index);
1122     }
1123     return result;
1124 }
1125 
GetCallRestriction(int32_t slotId,CallRestrictionType facType)1126 int32_t CellularCallSupplement::GetCallRestriction(int32_t slotId, CallRestrictionType facType)
1127 {
1128     std::string fac;
1129     int32_t result = CheckCallRestrictionType(fac, facType);
1130     if (result != TELEPHONY_SUCCESS) {
1131         return result;
1132     }
1133     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
1134     if (handler == nullptr) {
1135         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
1136         return TELEPHONY_ERR_LOCAL_PTR_NULL;
1137     }
1138     auto utCommand = std::make_shared<SsRequestCommand>();
1139     utCommand->flag = SS_FROM_SETTING_MENU;
1140     utCommand->facility = fac;
1141     int32_t index;
1142     if (NeedUseImsToHandle(slotId)) {
1143         handler->RequestSsRequestCommandIndex(index);
1144         result = supplementRequestIms_.GetCallRestrictionRequest(slotId, fac, index);
1145         if (result == TELEPHONY_SUCCESS) {
1146             handler->SaveSsRequestCommand(utCommand, index);
1147         }
1148         return result;
1149     }
1150     if (!PhoneTypeGsmOrNot(slotId)) {
1151         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
1152         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
1153     }
1154     handler->RequestSsRequestCommandIndex(index);
1155     result = supplementRequestCs_.GetCallRestrictionRequest(slotId, fac, index);
1156     if (result == TELEPHONY_SUCCESS) {
1157         handler->SaveSsRequestCommand(utCommand, index);
1158     }
1159     return result;
1160 }
1161 
SetBarringPassword(int32_t slotId,CallRestrictionType facType,const char * oldPassword,const char * newPassword)1162 int32_t CellularCallSupplement::SetBarringPassword(
1163     int32_t slotId, CallRestrictionType facType, const char *oldPassword, const char *newPassword)
1164 {
1165     std::string fac;
1166     int32_t result = CheckCallRestrictionType(fac, facType);
1167     if (result != TELEPHONY_SUCCESS) {
1168         return result;
1169     }
1170     auto handler = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
1171     if (handler == nullptr) {
1172         TELEPHONY_LOGE("[slot%{public}d] handler is nullptr!", slotId);
1173         return TELEPHONY_ERR_LOCAL_PTR_NULL;
1174     }
1175     auto utCommand = std::make_shared<SsRequestCommand>();
1176     utCommand->flag = SS_FROM_SETTING_MENU;
1177     utCommand->facility = fac;
1178     if (!PhoneTypeGsmOrNot(slotId)) {
1179         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
1180         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
1181     }
1182     int32_t index;
1183     handler->RequestSsRequestCommandIndex(index);
1184     result = supplementRequestCs_.SetBarringPasswordRequest(slotId, fac, index, oldPassword, newPassword);
1185     if (result == TELEPHONY_SUCCESS) {
1186         handler->SaveSsRequestCommand(utCommand, index);
1187     }
1188     return result;
1189 }
1190 
CheckCallRestrictionType(std::string & fac,const CallRestrictionType & facType)1191 int32_t CellularCallSupplement::CheckCallRestrictionType(std::string &fac, const CallRestrictionType &facType)
1192 {
1193     /*
1194      * <fac> values reserved by the present document:
1195      * "SC"	SIM (lock SIM/UICC card) (SIM/UICC asks password in ME power up and when this lock command issued)
1196      * "AO"	BAOC (Barr All Outgoing Calls) (refer 3GPP TS 22.088 [6] clause 1)
1197      * "OI"	BOIC (Barr Outgoing International Calls) (refer 3GPP TS 22.088 [6] clause 1)
1198      * "OX"	BOIC exHC (Barr Outgoing International Calls except to Home Country) (refer 3GPP TS 22.088 [6] clause 1)
1199      * "AI"	BAIC (Barr All Incoming Calls) (refer 3GPP TS 22.088 [6] clause 2)
1200      * "IR"	BIC Roam (Barr Incoming Calls when Roaming outside the home country) (refer 3GPP TS 22.088 [6] clause 2)
1201      * "AB"	All Barring services (refer 3GPP TS 22.030 [19]) (applicable only for <mode>=0)
1202      * "AG"	All outGoing barring services (refer 3GPP TS 22.030 [19]) (applicable only for <mode>=0)
1203      * "AC"	All inComing barring services (refer 3GPP TS 22.030 [19]) (applicable only for <mode>=0)
1204      */
1205     switch (facType) {
1206         case CallRestrictionType::RESTRICTION_TYPE_ALL_OUTGOING:
1207             fac = BARR_ALL_OUTGOING_CALLS;
1208             break;
1209         case CallRestrictionType::RESTRICTION_TYPE_INTERNATIONAL:
1210             fac = BARR_OUTGOING_INTERNATIONAL_CALLS;
1211             break;
1212         case CallRestrictionType::RESTRICTION_TYPE_INTERNATIONAL_EXCLUDING_HOME:
1213             fac = BARR_OUTGOING_INTERNATIONAL_CALLS_EXCLUDING_HOME;
1214             break;
1215         case CallRestrictionType::RESTRICTION_TYPE_ALL_INCOMING:
1216             fac = BARR_ALL_INCOMING_CALLS;
1217             break;
1218         case CallRestrictionType::RESTRICTION_TYPE_ROAMING_INCOMING:
1219             fac = BARR_INCOMING_CALLS_OUTSIDE_HOME;
1220             break;
1221         case CallRestrictionType::RESTRICTION_TYPE_ALL_CALLS:
1222             fac = ALL_BARRING_SERVICES;
1223             break;
1224         case CallRestrictionType::RESTRICTION_TYPE_OUTGOING_SERVICES:
1225             fac = ALL_OUTGOING_BARRING_SERVICES;
1226             break;
1227         case CallRestrictionType::RESTRICTION_TYPE_INCOMING_SERVICES:
1228             fac = ALL_INCOMING_BARRING_SERVICES;
1229             break;
1230         default:
1231             TELEPHONY_LOGE("parameter out of range!");
1232             return CALL_ERR_PARAMETER_OUT_OF_RANGE;
1233     }
1234     return TELEPHONY_SUCCESS;
1235 }
1236 
EventGetClip(const GetClipResult & getClipResult,const std::string & message,int32_t flag)1237 void CellularCallSupplement::EventGetClip(const GetClipResult &getClipResult, const std::string &message, int32_t flag)
1238 {
1239     ClipResponse clipResponse;
1240     clipResponse.result = getClipResult.result.result;
1241     if (clipResponse.result == IMS_ERROR_UT_NO_CONNECTION) {
1242         clipResponse.result = CALL_ERR_UT_NO_CONNECTION;
1243     }
1244     clipResponse.action = getClipResult.action;
1245     clipResponse.clipStat = getClipResult.clipStat;
1246     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1247     if (callRegister == nullptr) {
1248         TELEPHONY_LOGE("callRegister is null.");
1249         return;
1250     }
1251 
1252     if (flag == SS_FROM_MMI_CODE) {
1253         std::string successMessage = GET_CLIP_SUCCESS;
1254         MmiCodeInfo mmiCodeInfo;
1255         mmiCodeInfo.result = clipResponse.result;
1256         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), successMessage.c_str()) != EOK) {
1257             TELEPHONY_LOGE("strcpy_s fail.");
1258         }
1259         mmiCodeInfo.mmiCodeType = SC_CLIP;
1260         mmiCodeInfo.action = SUB_TYPE_QUERY;
1261         mmiCodeInfo.status = clipResponse.clipStat;
1262         ReportMmiCodeMessage(mmiCodeInfo);
1263     } else {
1264         callRegister->ReportGetClipResult(clipResponse);
1265     }
1266 }
1267 
EventSetClip(int32_t result,const std::string & message,int32_t flag,int32_t action)1268 void CellularCallSupplement::EventSetClip(int32_t result, const std::string &message, int32_t flag, int32_t action)
1269 {
1270     if (flag == SS_FROM_MMI_CODE) {
1271         MmiCodeInfo mmiCodeInfo;
1272         mmiCodeInfo.result = result;
1273         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
1274             TELEPHONY_LOGE("strcpy_s fail.");
1275         }
1276         mmiCodeInfo.mmiCodeType = SC_CLIP;
1277         mmiCodeInfo.action = action == ACTIVATE_ACTION ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
1278         ReportMmiCodeMessage(mmiCodeInfo);
1279     } else {
1280         TELEPHONY_LOGE("report the result of GetColp failed since the flag %{public}d was wrong", flag);
1281     }
1282 }
1283 
EventGetClir(const GetClirResult & result,const std::string & message,int32_t flag)1284 void CellularCallSupplement::EventGetClir(const GetClirResult &result, const std::string &message, int32_t flag)
1285 {
1286     ClirResponse response;
1287     // 3GPP TS 27.007 V3.9.0 (2001-06) 7.7	Calling line identification restriction +CLIR
1288     response.result = result.result.result;
1289     if (response.result == IMS_ERROR_UT_NO_CONNECTION) {
1290         response.result = CALL_ERR_UT_NO_CONNECTION;
1291     }
1292     response.action = result.action;
1293     response.clirStat = result.clirStat;
1294     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1295     if (callRegister == nullptr) {
1296         TELEPHONY_LOGE("callRegister is null.");
1297         return;
1298     }
1299     if (flag == SS_FROM_MMI_CODE) {
1300         std::string successMessage = GET_CLIR_SUCCESS;
1301         MmiCodeInfo mmiCodeInfo;
1302         mmiCodeInfo.result = response.result;
1303         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), successMessage.c_str()) != EOK) {
1304             TELEPHONY_LOGE("strcpy_s fail.");
1305         }
1306         mmiCodeInfo.mmiCodeType = SC_CLIR;
1307         mmiCodeInfo.action = SUB_TYPE_QUERY;
1308         mmiCodeInfo.status = response.clirStat;
1309         mmiCodeInfo.classCw = response.action;
1310         ReportMmiCodeMessage(mmiCodeInfo);
1311     } else {
1312         callRegister->ReportGetClirResult(response);
1313     }
1314 }
1315 
EventSetClir(int32_t result,const std::string & message,int32_t flag,int32_t action)1316 void CellularCallSupplement::EventSetClir(int32_t result, const std::string &message, int32_t flag, int32_t action)
1317 {
1318     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1319     if (callRegister == nullptr) {
1320         TELEPHONY_LOGE("callRegister is null.");
1321         return;
1322     }
1323     if (flag == SS_FROM_MMI_CODE) {
1324         MmiCodeInfo mmiCodeInfo;
1325         mmiCodeInfo.result = result;
1326         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
1327             TELEPHONY_LOGE("strcpy_s fail.");
1328         }
1329         mmiCodeInfo.mmiCodeType = SC_CLIR;
1330         mmiCodeInfo.action = action == ACTIVATE_ACTION ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
1331         ReportMmiCodeMessage(mmiCodeInfo);
1332     } else {
1333         callRegister->ReportSetClirResult(result);
1334     }
1335 }
1336 
EventGetColr(const GetColrResult & result,const std::string & message,int32_t flag)1337 void CellularCallSupplement::EventGetColr(const GetColrResult &result, const std::string &message, int32_t flag)
1338 {
1339     ColrResponse response;
1340     response.result = result.result.result;
1341     if (response.result == IMS_ERROR_UT_NO_CONNECTION) {
1342         response.result = CALL_ERR_UT_NO_CONNECTION;
1343     }
1344     response.action = result.action;
1345     response.colrStat = result.colrStat;
1346     if (flag == SS_FROM_MMI_CODE) {
1347         std::string successMessage = GET_COLR_SUCCESS;
1348         MmiCodeInfo mmiCodeInfo;
1349         mmiCodeInfo.result = response.result;
1350         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), successMessage.c_str()) != EOK) {
1351             TELEPHONY_LOGE("strcpy_s fail.");
1352         }
1353         mmiCodeInfo.mmiCodeType = SC_COLR;
1354         mmiCodeInfo.action = SUB_TYPE_QUERY;
1355         mmiCodeInfo.status = response.colrStat;
1356         ReportMmiCodeMessage(mmiCodeInfo);
1357     } else {
1358         TELEPHONY_LOGE("report the result of GetColp failed since the flag %{public}d was wrong", flag);
1359     }
1360 }
1361 
EventSetColr(int32_t result,const std::string & message,int32_t flag,int32_t action)1362 void CellularCallSupplement::EventSetColr(int32_t result, const std::string &message, int32_t flag, int32_t action)
1363 {
1364     if (flag == SS_FROM_MMI_CODE) {
1365         MmiCodeInfo mmiCodeInfo;
1366         mmiCodeInfo.result = result;
1367         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
1368             TELEPHONY_LOGE("strcpy_s fail.");
1369         }
1370         mmiCodeInfo.mmiCodeType = SC_COLR;
1371         mmiCodeInfo.action = action == ACTIVATE_ACTION ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
1372         ReportMmiCodeMessage(mmiCodeInfo);
1373     } else {
1374         TELEPHONY_LOGE("report the result of GetColp failed since the flag %{public}d was wrong", flag);
1375     }
1376 }
1377 
EventGetColp(const GetColpResult & result,const std::string & message,int32_t flag)1378 void CellularCallSupplement::EventGetColp(const GetColpResult &result, const std::string &message, int32_t flag)
1379 {
1380     ColpResponse response;
1381     response.result = result.result.result;
1382     if (response.result == IMS_ERROR_UT_NO_CONNECTION) {
1383         response.result = CALL_ERR_UT_NO_CONNECTION;
1384     }
1385     response.action = result.action;
1386     response.colpStat = result.colpStat;
1387     if (flag == SS_FROM_MMI_CODE) {
1388         std::string successMessage = GET_COLP_SUCCESS;
1389         MmiCodeInfo mmiCodeInfo;
1390         mmiCodeInfo.result = response.result;
1391         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), successMessage.c_str()) != EOK) {
1392             TELEPHONY_LOGE("strcpy_s fail.");
1393         }
1394         mmiCodeInfo.mmiCodeType = SC_COLP;
1395         mmiCodeInfo.action = SUB_TYPE_QUERY;
1396         mmiCodeInfo.status = response.colpStat;
1397         ReportMmiCodeMessage(mmiCodeInfo);
1398     } else {
1399         TELEPHONY_LOGE("report the result of GetColp failed since the flag %{public}d was wrong", flag);
1400     }
1401 }
1402 
EventSetColp(int32_t result,const std::string & message,int32_t flag,int32_t action)1403 void CellularCallSupplement::EventSetColp(int32_t result, const std::string &message, int32_t flag, int32_t action)
1404 {
1405     if (flag == SS_FROM_MMI_CODE) {
1406         MmiCodeInfo mmiCodeInfo;
1407         mmiCodeInfo.result = result;
1408         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), message.c_str()) != EOK) {
1409             TELEPHONY_LOGE("strcpy_s fail.");
1410         }
1411         mmiCodeInfo.mmiCodeType = SC_COLP;
1412         mmiCodeInfo.action = action == ACTIVATE_ACTION ? SUB_TYPE_ACTIVE : SUB_TYPE_DEACTIVE;
1413         ReportMmiCodeMessage(mmiCodeInfo);
1414     } else {
1415         TELEPHONY_LOGE("report the result of GetColp failed since the flag %{public}d was wrong", flag);
1416     }
1417 }
1418 
SendUssd(int32_t slotId,const std::string & msg)1419 int32_t CellularCallSupplement::SendUssd(int32_t slotId, const std::string &msg)
1420 {
1421     int32_t result = TELEPHONY_SUCCESS;
1422     result = supplementRequestCs_.SendUssdRequest(slotId, msg);
1423     if (result != TELEPHONY_SUCCESS) {
1424         MmiCodeInfo mmiCodeInfo;
1425         mmiCodeInfo.result = USSD_FAILED;
1426         mmiCodeInfo.mmiCodeType = SC_USSD;
1427         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), GENERIC_FAILURE.c_str()) != EOK) {
1428             TELEPHONY_LOGE("strcpy_s fail.");
1429         }
1430         ReportMmiCodeMessage(mmiCodeInfo);
1431     }
1432     return result;
1433 }
1434 
EventSendUssd(const RadioResponseInfo & responseInfo)1435 void CellularCallSupplement::EventSendUssd(const RadioResponseInfo &responseInfo)
1436 {
1437     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1438     if (callRegister == nullptr) {
1439         TELEPHONY_LOGE("callRegister is null.");
1440         return;
1441     }
1442     callRegister->ReportSendUssdResult(static_cast<int32_t>(responseInfo.error));
1443     if (responseInfo.error == ErrType::NONE) {
1444         return;
1445     }
1446     MmiCodeInfo mmiCodeInfo;
1447     mmiCodeInfo.result = USSD_FAILED;
1448     mmiCodeInfo.mmiCodeType = SC_USSD;
1449     ReportMmiCodeMessage(mmiCodeInfo);
1450 }
1451 
EventSsNotify(SsNoticeInfo & ssNoticeInfo)1452 void CellularCallSupplement::EventSsNotify(SsNoticeInfo &ssNoticeInfo)
1453 {
1454     MmiCodeInfo mmiCodeInfo;
1455     mmiCodeInfo.result = ssNoticeInfo.result;
1456     switch (ssNoticeInfo.requestType) {
1457         case static_cast<int32_t>(SsRequestType::SS_ACTIVATION):
1458         case static_cast<int32_t>(SsRequestType::SS_DEACTIVATION):
1459         case static_cast<int32_t>(SsRequestType::SS_REGISTRATION):
1460         case static_cast<int32_t>(SsRequestType::SS_ERASURE):
1461         case static_cast<int32_t>(SsRequestType::SS_INTERROGATION):
1462             GetMessage(mmiCodeInfo, ssNoticeInfo);
1463             break;
1464         default:
1465             TELEPHONY_LOGE("Invaid requestType in SS Data!");
1466             return;
1467     }
1468 
1469     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1470     if (callRegister == nullptr) {
1471         TELEPHONY_LOGE("callRegister is null.");
1472         return;
1473     }
1474     callRegister->ReportMmiCodeResult(mmiCodeInfo);
1475 }
1476 
GetMessage(MmiCodeInfo & mmiCodeInfo,const SsNoticeInfo & ssNoticeInfo)1477 void CellularCallSupplement::GetMessage(MmiCodeInfo &mmiCodeInfo, const SsNoticeInfo &ssNoticeInfo)
1478 {
1479     if (ssNoticeInfo.result != 0) {
1480         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), QUERY_SS_FAILED.c_str()) != EOK) {
1481             TELEPHONY_LOGE("strcpy_s QUERY_SS_FAILED fail.");
1482         }
1483         return;
1484     }
1485     switch (ssNoticeInfo.serviceType) {
1486         case (unsigned int)CallTransferType::TRANSFER_TYPE_UNCONDITIONAL: {
1487             if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message),
1488                 TRANSFER_UNCONDITIONAL_SUCCESS.c_str()) != EOK) {
1489                 TELEPHONY_LOGE("strcpy_s TRANSFER_UNCONDITIONAL_SUCCESS fail.");
1490                 return;
1491             }
1492             break;
1493         }
1494         case (unsigned int)CallTransferType::TRANSFER_TYPE_BUSY: {
1495             if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), TRANSFER_BUSY_SUCCESS.c_str()) != EOK) {
1496                 TELEPHONY_LOGE("strcpy_s TRANSFER_BUSY_SUCCESS fail.");
1497                 return;
1498             }
1499             break;
1500         }
1501         case (unsigned int)CallTransferType::TRANSFER_TYPE_NO_REPLY: {
1502             if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), TRANSFER_NO_REPLYL_SUCCESS.c_str()) != EOK) {
1503                 TELEPHONY_LOGE("strcpy_s TRANSFER_NO_REPLYL_SUCCESS fail.");
1504                 return;
1505             }
1506             break;
1507         }
1508         case (unsigned int)CallTransferType::TRANSFER_TYPE_NOT_REACHABLE: {
1509             if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message),
1510                 TRANSFER_NOT_REACHABLE_SUCCESS.c_str()) != EOK) {
1511                 TELEPHONY_LOGE("strcpy_s TRANSFER_NOT_REACHABLE_SUCCESS fail.");
1512                 return;
1513             }
1514             break;
1515         }
1516         default: {
1517             if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), QUERY_SS_SUCCESS.c_str()) != EOK) {
1518                 TELEPHONY_LOGE("strcpy_s QUERY_SS_SUCCESS fail.");
1519                 return;
1520             }
1521         }
1522     }
1523 }
1524 
EventUssdNotify(UssdNoticeInfo & ussdNoticeInfo,int32_t slotId)1525 void CellularCallSupplement::EventUssdNotify(UssdNoticeInfo &ussdNoticeInfo, int32_t slotId)
1526 {
1527     if (TELEPHONY_EXT_WRAPPER.isEmptyMmiResultFiltered_ != nullptr) {
1528         if (ussdNoticeInfo.str.empty() && TELEPHONY_EXT_WRAPPER.isEmptyMmiResultFiltered_(slotId)) {
1529             TELEPHONY_LOGI("[slot%{public}d] remove mmi success", slotId);
1530             return;
1531         }
1532     }
1533     if (TELEPHONY_EXT_WRAPPER.unescapeHtmlCode_ != nullptr) {
1534         TELEPHONY_EXT_WRAPPER.unescapeHtmlCode_(slotId, ussdNoticeInfo.str);
1535     }
1536     MmiCodeInfo mmiCodeInfo;
1537     mmiCodeInfo.mmiCodeType = SC_USSD;
1538     mmiCodeInfo.action = slotId;
1539     bool isUssdError = ussdNoticeInfo.m != USSD_MODE_NOTIFY && ussdNoticeInfo.m != USSD_MODE_REQUEST;
1540     if (TELEPHONY_EXT_WRAPPER.isUssdReleaseMsgFiltered_ != nullptr) {
1541         if (TELEPHONY_EXT_WRAPPER.isUssdReleaseMsgFiltered_(slotId)) {
1542             TELEPHONY_LOGI("[slot%{public}d] ussd ok for network release", slotId);
1543             isUssdError &= (ussdNoticeInfo.m != USSD_MODE_NW_RELEASE);
1544         }
1545     }
1546     if (!isUssdError && !ussdNoticeInfo.str.empty()) {
1547         mmiCodeInfo.result = ussdNoticeInfo.m;
1548         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), ussdNoticeInfo.str.c_str()) != EOK) {
1549             TELEPHONY_LOGE("strcpy_s ussdNoticeInfo.str fail.");
1550             return;
1551         }
1552     } else if (isUssdError && !(ussdNoticeInfo.m == USSD_MODE_NW_RELEASE)) {
1553         mmiCodeInfo.result = USSD_FAILED;
1554         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), INVALID_MMI_CODE.c_str()) != EOK) {
1555             TELEPHONY_LOGE("strcpy_s INVALID_MMI_CODE fail.");
1556             return;
1557         }
1558     } else {
1559         mmiCodeInfo.result = USSD_SUCCESS;
1560         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), ussdNoticeInfo.str.c_str()) != EOK) {
1561             TELEPHONY_LOGE("strcpy_s INVALID_MMI_CODE fail.");
1562             return;
1563         }
1564         TELEPHONY_LOGI("vaild ussd notify.");
1565     }
1566 
1567     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1568     if (callRegister == nullptr) {
1569         TELEPHONY_LOGE("callRegister is null.");
1570         return;
1571     }
1572     callRegister->ReportMmiCodeResult(mmiCodeInfo);
1573 }
1574 
EventSetPinPuk(const PinPukResponse & pinPukResponse)1575 void CellularCallSupplement::EventSetPinPuk(const PinPukResponse &pinPukResponse)
1576 {
1577     MmiCodeInfo mmiCodeInfo;
1578     mmiCodeInfo.result = pinPukResponse.result;
1579     std::string messageTemp = std::to_string(pinPukResponse.remain);
1580     if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), messageTemp.c_str()) != EOK) {
1581         TELEPHONY_LOGE("strcpy_s messageTemp fail.");
1582     }
1583     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1584     if (callRegister == nullptr) {
1585         TELEPHONY_LOGE("callRegister is null.");
1586         return;
1587     }
1588     callRegister->ReportMmiCodeResult(mmiCodeInfo);
1589 }
1590 
AlterPinPassword(int32_t slotId,const MMIData & mmiData)1591 void CellularCallSupplement::AlterPinPassword(int32_t slotId, const MMIData &mmiData)
1592 {
1593     if (mmiData.actionString.empty()) {
1594         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
1595         return;
1596     }
1597 
1598     std::string oldPin = mmiData.serviceInfoA;
1599     std::string newPin = mmiData.serviceInfoB;
1600     std::string newPinCheck = mmiData.serviceInfoC;
1601     if (!IsVaildPinOrPuk(newPin, newPinCheck)) {
1602         return;
1603     }
1604     int32_t result = TELEPHONY_SUCCESS;
1605     result = supplementRequestCs_.AlterPinPassword(slotId, newPin, oldPin);
1606     if (result != TELEPHONY_SUCCESS) {
1607         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
1608     }
1609 }
1610 
UnlockPuk(int32_t slotId,const MMIData & mmiData)1611 void CellularCallSupplement::UnlockPuk(int32_t slotId, const MMIData &mmiData)
1612 {
1613     if (mmiData.actionString.empty()) {
1614         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
1615         return;
1616     }
1617     std::string puk = mmiData.serviceInfoA;
1618     std::string newPin = mmiData.serviceInfoB;
1619     std::string newPinCheck = mmiData.serviceInfoC;
1620     if (!IsVaildPinOrPuk(newPin, newPinCheck)) {
1621         return;
1622     }
1623     int32_t result = TELEPHONY_SUCCESS;
1624     result = supplementRequestCs_.UnlockPuk(slotId, newPin, puk);
1625     if (result != TELEPHONY_SUCCESS) {
1626         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
1627     }
1628 }
1629 
AlterPin2Password(int32_t slotId,const MMIData & mmiData)1630 void CellularCallSupplement::AlterPin2Password(int32_t slotId, const MMIData &mmiData)
1631 {
1632     if (mmiData.actionString.empty()) {
1633         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
1634         return;
1635     }
1636 
1637     std::string oldPin2 = mmiData.serviceInfoA;
1638     std::string newPin2 = mmiData.serviceInfoB;
1639     std::string newPin2Check = mmiData.serviceInfoC;
1640     if (!IsVaildPinOrPuk(newPin2, newPin2Check)) {
1641         return;
1642     }
1643     int32_t result = TELEPHONY_SUCCESS;
1644     result = supplementRequestCs_.AlterPin2Password(slotId, newPin2, oldPin2);
1645     if (result != TELEPHONY_SUCCESS) {
1646         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
1647     }
1648 }
1649 
UnlockPuk2(int32_t slotId,const MMIData & mmiData)1650 void CellularCallSupplement::UnlockPuk2(int32_t slotId, const MMIData &mmiData)
1651 {
1652     if (mmiData.actionString.empty()) {
1653         TELEPHONY_LOGE("[slot%{public}d] actionString is empty!", slotId);
1654         return;
1655     }
1656 
1657     std::string puk2 = mmiData.serviceInfoA;
1658     std::string newPin2 = mmiData.serviceInfoB;
1659     std::string newPin2Check = mmiData.serviceInfoC;
1660     if (!IsVaildPinOrPuk(newPin2, newPin2Check)) {
1661         return;
1662     }
1663     int32_t result = TELEPHONY_SUCCESS;
1664     result = supplementRequestCs_.UnlockPuk2(slotId, newPin2, puk2);
1665     if (result != TELEPHONY_SUCCESS) {
1666         ReportMmiCodeMessage(MMI_CODE_FAILED, "", GENERIC_FAILURE);
1667     }
1668 }
1669 
IsVaildPinOrPuk(std::string newPinOrPuk,std::string newPinOrPukCheck)1670 bool CellularCallSupplement::IsVaildPinOrPuk(std::string newPinOrPuk, std::string newPinOrPukCheck)
1671 {
1672     if (newPinOrPuk != newPinOrPukCheck) {
1673         ReportMmiCodeMessage(MMI_CODE_FAILED, "", MIS_MATCH_PIN_PUK);
1674         return false;
1675     } else if (static_cast<int32_t>(newPinOrPuk.length()) < PIN_PUK_MIN ||
1676                static_cast<int32_t>(newPinOrPuk.length()) > PIN_PUK_MAX) {
1677         ReportMmiCodeMessage(MMI_CODE_FAILED, "", INVAILD_PIN_PUK);
1678         return false;
1679     } else {
1680         TELEPHONY_LOGI("Check Pin or Puk success.");
1681     }
1682     return true;
1683 }
1684 
ReportMmiCodeMessage(int32_t result,const std::string successMsg,const std::string failedMsg)1685 void CellularCallSupplement::ReportMmiCodeMessage(
1686     int32_t result, const std::string successMsg, const std::string failedMsg)
1687 {
1688     MmiCodeInfo mmiCodeInfo;
1689     mmiCodeInfo.result = result;
1690     if (result == RESULT_SUCCESS) {
1691         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), successMsg.c_str()) != EOK) {
1692             TELEPHONY_LOGE("strcpy_s fail.");
1693             return;
1694         }
1695     } else {
1696         if (strcpy_s(mmiCodeInfo.message, sizeof(mmiCodeInfo.message), failedMsg.c_str()) != EOK) {
1697             TELEPHONY_LOGE("strcpy_s fail.");
1698             return;
1699         }
1700     }
1701     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1702     if (callRegister == nullptr) {
1703         TELEPHONY_LOGE("callRegister is null.");
1704         return;
1705     }
1706     callRegister->ReportMmiCodeResult(mmiCodeInfo);
1707 }
1708 
CloseUnFinishedUssd(int32_t slotId)1709 int32_t CellularCallSupplement::CloseUnFinishedUssd(int32_t slotId)
1710 {
1711     if (!PhoneTypeGsmOrNot(slotId)) {
1712         TELEPHONY_LOGE("[slot%{public}d] network type is not supported!", slotId);
1713         return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
1714     }
1715     return supplementRequestCs_.CloseUnFinishedUssdRequest(slotId);
1716 }
1717 
EventCloseUnFinishedUssd(const RadioResponseInfo & responseInfo)1718 void CellularCallSupplement::EventCloseUnFinishedUssd(const RadioResponseInfo &responseInfo)
1719 {
1720     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1721     if (callRegister == nullptr) {
1722         TELEPHONY_LOGE("callRegister is null.");
1723         return;
1724     }
1725     int32_t result = TELEPHONY_ERROR;
1726     if (responseInfo.error == ErrType::NONE) {
1727         result = TELEPHONY_SUCCESS;
1728     } else {
1729         result = TELEPHONY_ERR_RIL_CMD_FAIL;
1730     }
1731     callRegister->ReportCloseUnFinishedUssdResult(result);
1732 }
1733 
ReportMmiCodeMessage(const MmiCodeInfo & mmiCodeInfo)1734 void CellularCallSupplement::ReportMmiCodeMessage(const MmiCodeInfo &mmiCodeInfo)
1735 {
1736     auto callRegister = DelayedSingleton<CellularCallRegister>::GetInstance();
1737     if (callRegister == nullptr) {
1738         TELEPHONY_LOGE("callRegister is null.");
1739         return;
1740     }
1741     callRegister->ReportMmiCodeResult(mmiCodeInfo);
1742 }
1743 } // namespace Telephony
1744 } // namespace OHOS
1745