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