1 /*
2 * Copyright (C) 2021 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 "call_number_utils.h"
17
18 #include <regex>
19
20 #include "phonenumbers/phonenumber.pb.h"
21 #include "telephony_log_wrapper.h"
22 #include "telephony_types.h"
23 #include "call_manager_errors.h"
24 #include "cellular_call_connection.h"
25
26 namespace OHOS {
27 namespace Telephony {
CallNumberUtils()28 CallNumberUtils::CallNumberUtils() {}
29
~CallNumberUtils()30 CallNumberUtils::~CallNumberUtils() {}
31
FormatPhoneNumber(const std::string & phoneNumber,const std::string & countryCode,std::string & formatNumber)32 int32_t CallNumberUtils::FormatPhoneNumber(
33 const std::string &phoneNumber, const std::string &countryCode, std::string &formatNumber)
34 {
35 if (phoneNumber.empty()) {
36 TELEPHONY_LOGE("phoneNumber is nullptr!");
37 return TELEPHONY_ERR_ARGUMENT_INVALID;
38 }
39 if (phoneNumber.front() == '#' || phoneNumber.front() == '*') {
40 formatNumber = phoneNumber;
41 return TELEPHONY_SUCCESS;
42 }
43 i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
44 if (phoneUtils == nullptr) {
45 TELEPHONY_LOGE("phoneUtils is nullptr");
46 return TELEPHONY_ERR_LOCAL_PTR_NULL;
47 }
48 std::string tmpCode = countryCode;
49 transform(tmpCode.begin(), tmpCode.end(), tmpCode.begin(), ::toupper);
50 i18n::phonenumbers::PhoneNumber parseResult;
51 phoneUtils->ParseAndKeepRawInput(phoneNumber, tmpCode, &parseResult);
52 phoneUtils->FormatInOriginalFormat(parseResult, tmpCode, &formatNumber);
53 if (formatNumber.empty() || formatNumber == "0") {
54 TELEPHONY_LOGE("FormatPhoneNumber failed!");
55 return CALL_ERR_FORMAT_PHONE_NUMBER_FAILED;
56 }
57 return TELEPHONY_SUCCESS;
58 }
59
FormatPhoneNumberToE164(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)60 int32_t CallNumberUtils::FormatPhoneNumberToE164(
61 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
62 {
63 return FormatNumberBase(phoneNumber, countryCode, i18n::phonenumbers::PhoneNumberUtil::E164, formatNumber);
64 }
65
FormatNumberBase(const std::string phoneNumber,std::string countryCode,const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo,std::string & formatNumber)66 int32_t CallNumberUtils::FormatNumberBase(const std::string phoneNumber, std::string countryCode,
67 const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNumber)
68 {
69 if (phoneNumber.empty()) {
70 TELEPHONY_LOGE("phoneNumber is nullptr!");
71 return TELEPHONY_ERR_ARGUMENT_INVALID;
72 }
73 i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
74 if (phoneUtils == nullptr) {
75 TELEPHONY_LOGE("phoneUtils is nullptr");
76 return TELEPHONY_ERR_LOCAL_PTR_NULL;
77 }
78 transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::toupper);
79 i18n::phonenumbers::PhoneNumber parseResult;
80 phoneUtils->Parse(phoneNumber, countryCode, &parseResult);
81 if (phoneUtils->IsValidNumber(parseResult)) {
82 phoneUtils->Format(parseResult, formatInfo, &formatNumber);
83 }
84 if (formatNumber.empty() || formatNumber == "0") {
85 TELEPHONY_LOGE("FormatPhoneNumber failed!");
86 return CALL_ERR_FORMAT_PHONE_NUMBER_FAILED;
87 }
88 return TELEPHONY_SUCCESS;
89 }
90
CheckNumberIsEmergency(const std::string & phoneNumber,const int32_t slotId,bool & enabled)91 int32_t CallNumberUtils::CheckNumberIsEmergency(const std::string &phoneNumber, const int32_t slotId, bool &enabled)
92 {
93 return DelayedSingleton<CellularCallConnection>::GetInstance()->IsEmergencyPhoneNumber(
94 phoneNumber, slotId, enabled);
95 }
96
IsValidSlotId(int32_t slotId) const97 bool CallNumberUtils::IsValidSlotId(int32_t slotId) const
98 {
99 if (SIM_SLOT_COUNT == HAS_A_SLOT) {
100 return slotId == SIM_SLOT_0;
101 }
102 if (SIM_SLOT_COUNT == HAS_TWO_SLOT) {
103 if (slotId == SIM_SLOT_0 || slotId == SIM_SLOT_1) {
104 return true;
105 }
106 }
107 return false;
108 }
109
IsMMICode(const std::string & number)110 bool CallNumberUtils::IsMMICode(const std::string &number)
111 {
112 if (number.empty()) {
113 TELEPHONY_LOGE("number is empty.");
114 return false;
115 }
116 if (RegexMatchMmi(number)) {
117 return true;
118 }
119
120 if (number.back() == '#') {
121 TELEPHONY_LOGI("number is end of #");
122 return true;
123 }
124
125 return false;
126 }
127
RegexMatchMmi(const std::string & number)128 bool CallNumberUtils::RegexMatchMmi(const std::string &number)
129 {
130 std::string symbols =
131 "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)";
132 std::regex pattern(symbols);
133 std::smatch results;
134 if (regex_match(number, results, pattern)) {
135 TELEPHONY_LOGI("regex_match ture");
136 return true;
137 }
138 return false;
139 }
140
RemoveSeparatorsPhoneNumber(const std::string & phoneString)141 std::string CallNumberUtils::RemoveSeparatorsPhoneNumber(const std::string &phoneString)
142 {
143 std::string newString;
144 if (phoneString.empty()) {
145 TELEPHONY_LOGE("RemoveSeparatorsPhoneNumber return, phoneStr is empty.");
146 return newString;
147 }
148 for (char c : phoneString) {
149 if ((c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N' || c == ',' || c == ';') {
150 newString += c;
151 }
152 }
153
154 return newString;
155 }
156
RemovePostDailPhoneNumber(const std::string & phoneString)157 std::string CallNumberUtils::RemovePostDailPhoneNumber(const std::string &phoneString)
158 {
159 std::string newString = "";
160 if (phoneString.empty()) {
161 TELEPHONY_LOGE("RemovePostDailPhoneNumber return, phoneStr is empty.");
162 return newString;
163 }
164 for (char c : phoneString) {
165 if ((c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N') {
166 newString += c;
167 } else if (c == ',' || c == ';') {
168 break;
169 }
170 }
171
172 return newString;
173 }
174 } // namespace Telephony
175 } // namespace OHOS
176