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 formatNumber = "";
55 }
56 return TELEPHONY_SUCCESS;
57 }
58
FormatPhoneNumberToE164(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)59 int32_t CallNumberUtils::FormatPhoneNumberToE164(
60 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
61 {
62 return FormatNumberBase(phoneNumber, countryCode, i18n::phonenumbers::PhoneNumberUtil::E164, formatNumber);
63 }
64
FormatPhoneNumberToNational(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)65 int32_t CallNumberUtils::FormatPhoneNumberToNational(
66 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
67 {
68 int32_t ret = FormatNumberBase(phoneNumber, countryCode,
69 i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL, formatNumber);
70 ProcessSpace(formatNumber);
71 return ret;
72 }
73
FormatPhoneNumberToInternational(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)74 int32_t CallNumberUtils::FormatPhoneNumberToInternational(
75 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
76 {
77 int32_t ret = FormatNumberBase(phoneNumber, countryCode,
78 i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL, formatNumber);
79 ProcessSpace(formatNumber);
80 return ret;
81 }
82
FormatNumberBase(const std::string phoneNumber,std::string countryCode,const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo,std::string & formatNumber)83 int32_t CallNumberUtils::FormatNumberBase(const std::string phoneNumber, std::string countryCode,
84 const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNumber)
85 {
86 if (phoneNumber.empty()) {
87 TELEPHONY_LOGE("phoneNumber is nullptr!");
88 return TELEPHONY_ERR_ARGUMENT_INVALID;
89 }
90 i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
91 if (phoneUtils == nullptr) {
92 TELEPHONY_LOGE("phoneUtils is nullptr");
93 return TELEPHONY_ERR_LOCAL_PTR_NULL;
94 }
95 transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::toupper);
96 i18n::phonenumbers::PhoneNumber parseResult;
97 phoneUtils->Parse(phoneNumber, countryCode, &parseResult);
98 if (phoneUtils->IsValidNumber(parseResult) || HasBCPhoneNumber(phoneNumber)) {
99 phoneUtils->Format(parseResult, formatInfo, &formatNumber);
100 }
101 return TELEPHONY_SUCCESS;
102 }
103
ProcessSpace(std::string & number)104 void CallNumberUtils::ProcessSpace(std::string &number)
105 {
106 std::string word;
107 std::stringstream streamNum(number);
108 std::string store;
109 while (streamNum >> word) {
110 store += word;
111 }
112 number = store;
113 }
114
CheckNumberIsEmergency(const std::string & phoneNumber,const int32_t slotId,bool & enabled)115 int32_t CallNumberUtils::CheckNumberIsEmergency(const std::string &phoneNumber, const int32_t slotId, bool &enabled)
116 {
117 return DelayedSingleton<CellularCallConnection>::GetInstance()->IsEmergencyPhoneNumber(
118 phoneNumber, slotId, enabled);
119 }
120
IsValidSlotId(int32_t slotId) const121 bool CallNumberUtils::IsValidSlotId(int32_t slotId) const
122 {
123 if (SIM_SLOT_COUNT == HAS_A_SLOT) {
124 return slotId == SIM_SLOT_0;
125 }
126 if (SIM_SLOT_COUNT == HAS_TWO_SLOT) {
127 if (slotId == SIM_SLOT_0 || slotId == SIM_SLOT_1) {
128 return true;
129 }
130 }
131 return false;
132 }
133
IsMMICode(const std::string & number)134 bool CallNumberUtils::IsMMICode(const std::string &number)
135 {
136 if (number.empty()) {
137 TELEPHONY_LOGE("number is empty.");
138 return false;
139 }
140 if (RegexMatchMmi(number)) {
141 return true;
142 }
143
144 if (number.back() == '#') {
145 TELEPHONY_LOGI("number is end of #");
146 return true;
147 }
148
149 return false;
150 }
151
RegexMatchMmi(const std::string & number)152 bool CallNumberUtils::RegexMatchMmi(const std::string &number)
153 {
154 std::string symbols =
155 "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)";
156 std::regex pattern(symbols);
157 std::smatch results;
158 if (regex_match(number, results, pattern)) {
159 TELEPHONY_LOGI("regex_match ture");
160 return true;
161 }
162 return false;
163 }
164
RemoveSeparatorsPhoneNumber(const std::string & phoneString)165 std::string CallNumberUtils::RemoveSeparatorsPhoneNumber(const std::string &phoneString)
166 {
167 std::string newString;
168 if (phoneString.empty()) {
169 TELEPHONY_LOGE("RemoveSeparatorsPhoneNumber return, phoneStr is empty.");
170 return newString;
171 }
172 for (char c : phoneString) {
173 if ((c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N' || c == ',' || c == ';') {
174 newString += c;
175 }
176 }
177
178 return newString;
179 }
180
RemovePostDialPhoneNumber(const std::string & phoneString)181 std::string CallNumberUtils::RemovePostDialPhoneNumber(const std::string &phoneString)
182 {
183 std::string newString = "";
184 if (phoneString.empty()) {
185 TELEPHONY_LOGE("RemovePostDialPhoneNumber return, phoneStr is empty.");
186 return newString;
187 }
188 for (char c : phoneString) {
189 if ((c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N') {
190 newString += c;
191 } else if (c == ',' || c == ';') {
192 break;
193 }
194 }
195
196 return newString;
197 }
198
HasAlphabetInPhoneNum(const std::string & inputValue)199 bool CallNumberUtils::HasAlphabetInPhoneNum(const std::string &inputValue)
200 {
201 if (inputValue.empty()) {
202 TELEPHONY_LOGE("HasAlphabetInPhoneNum return, input is empty.");
203 return true;
204 }
205 for (char c : inputValue) {
206 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) {
207 TELEPHONY_LOGE("The Phone Number contains letter");
208 return true;
209 }
210 }
211 TELEPHONY_LOGI("The Phone Number is valid");
212 return false;
213 }
214
HasBCPhoneNumber(const std::string & phoneNumber)215 bool CallNumberUtils::HasBCPhoneNumber(const std::string &phoneNumber)
216 {
217 int32_t phoneNumberStart = 0;
218 int32_t phoneNumberStartLength = 3;
219 size_t bCNumberLength = 11;
220 std::string bCNumberStart = "192";
221 if (phoneNumber.length() == bCNumberLength &&
222 phoneNumber.substr(phoneNumberStart, phoneNumberStartLength) == bCNumberStart) {
223 return true;
224 }
225 return false;
226 }
227 } // namespace Telephony
228 } // namespace OHOS
229