• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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