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