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