1/*
2 * Copyright (C) 2021-2024 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 "sms_persist_helper.h"
17
18#include <sstream>
19#include "ability_manager_interface.h"
20#include "if_system_ability_manager.h"
21#include "iservice_registry.h"
22#include "parameter.h"
23#include "phonenumbers/phonenumber.pb.h"
24#include "resource_manager.h"
25#include "string_utils.h"
26#include "system_ability.h"
27#include "system_ability_definition.h"
28#include "telephony_errors.h"
29#include "telephony_log_wrapper.h"
30
31
32namespace OHOS {
33namespace Telephony {
34constexpr static uint8_t SMS_TYPE_CDMA = 2;
35const std::string SMS_URI = "datashare:///com.ohos.smsmmsability";
36const std::string SMS_SUBSECTION = "datashare:///com.ohos.smsmmsability/sms_mms/sms_subsection";
37const std::string SMS_MMS_INFO = "datashare:///com.ohos.smsmmsability/sms_mms/sms_mms_info";
38const std::string SMS_SESSION = "datashare:///com.ohos.smsmmsability/sms_mms/session";
39const std::string CONTACT_URI = "datashare:///com.ohos.contactsdataability";
40const std::string CONTACT_BLOCK = "datashare:///com.ohos.contactsdataability/contacts/contact_blocklist";
41const std::string CONTACT_DATA = "datashare:///com.ohos.contactsdataability/contacts/contact_data";
42const std::string RAW_CONTACT = "datashare:///com.ohos.contactsdataability/contacts/raw_contact";
43const std::string ISO_COUNTRY_CODE = "CN";
44const std::string PHONE_NUMBER = "phone_number";
45const std::string DETAIL_INFO = "detail_info";
46const std::string TYPE_ID = "type_id";
47std::string ID = "id";
48const std::string RAW_CONTACT_ID = "raw_contact_id";
49const std::string CONTACTED_COUNT = "contacted_count";
50const std::string LASTEST_CONTACTED_TIME = "lastest_contacted_time";
51constexpr static uint8_t TYPE_ID_VALUE = 5;
52const std::string PREFIX = "+86";
53const std::string NUMBER_START_STR = "192";
54
55SmsPersistHelper::SmsPersistHelper() {}
56
57SmsPersistHelper::~SmsPersistHelper() {}
58
59std::shared_ptr<DataShare::DataShareHelper> SmsPersistHelper::CreateDataShareHelper(const std::string &uri)
60{
61    auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
62    if (saManager == nullptr) {
63        TELEPHONY_LOGE(" Get system ability mgr failed.");
64        return nullptr;
65    }
66    auto remoteObj = saManager->GetSystemAbility(TELEPHONY_SMS_MMS_SYS_ABILITY_ID);
67    if (remoteObj == nullptr) {
68        TELEPHONY_LOGE("GetSystemAbility Service Failed.");
69        return nullptr;
70    }
71    return DataShare::DataShareHelper::Creator(remoteObj, uri);
72}
73
74bool SmsPersistHelper::Insert(DataShare::DataShareValuesBucket &values, uint16_t &dataBaseId)
75{
76    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
77    if (helper == nullptr) {
78        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
79        return false;
80    }
81    Uri uri(SMS_SUBSECTION);
82    int ret = helper->Insert(uri, values);
83    helper->Release();
84    dataBaseId = ret;
85    return ret >= 0 ? true : false;
86}
87
88bool SmsPersistHelper::Insert(std::string tableUri, DataShare::DataShareValuesBucket &values)
89{
90    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
91    if (helper == nullptr) {
92        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
93        return false;
94    }
95    Uri uri(tableUri);
96    int ret = helper->Insert(uri, values);
97    helper->Release();
98    return ret >= 0 ? true : false;
99}
100
101bool SmsPersistHelper::Insert(std::string tableUri, DataShare::DataShareValuesBucket &values, uint16_t &id)
102{
103    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
104    if (helper == nullptr) {
105        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
106        return false;
107    }
108    Uri uri(tableUri);
109    int ret = helper->Insert(uri, values);
110    helper->Release();
111    id = ret;
112    return ret >= 0;
113}
114
115bool SmsPersistHelper::QuerySession(
116    DataShare::DataSharePredicates &predicates, uint16_t &sessionId, uint16_t &messageCount)
117{
118    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
119    if (helper == nullptr) {
120        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
121        return false;
122    }
123    Uri uri(SMS_SESSION);
124    std::vector<std::string> columns;
125    auto resultSet = helper->Query(uri, predicates, columns);
126    if (resultSet == nullptr) {
127        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
128        helper->Release();
129        return false;
130    }
131    resultSet->GoToFirstRow();
132    int32_t columnInt;
133    int columnIndex;
134    resultSet->GetColumnIndex("id", columnIndex);
135    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
136        sessionId = columnInt;
137    }
138    resultSet->GetColumnIndex("message_count", columnIndex);
139    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
140        messageCount = columnInt;
141        resultSet->Close();
142        helper->Release();
143        return true;
144    }
145    resultSet->Close();
146    helper->Release();
147    return false;
148}
149
150bool SmsPersistHelper::UpdateSms(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
151{
152    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
153    if (helper == nullptr) {
154        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
155        return false;
156    }
157    Uri uri(SMS_MMS_INFO);
158    int ret = helper->Update(uri, predicates, values);
159    helper->Release();
160    return ret >= 0;
161}
162
163bool SmsPersistHelper::QuerySmsMmsForId(DataShare::DataSharePredicates &predicates, uint16_t &dataBaseId)
164{
165    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
166    if (helper == nullptr) {
167        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
168        return false;
169    }
170    Uri uri(SMS_MMS_INFO);
171    std::vector<std::string> columns;
172    auto resultSet = helper->Query(uri, predicates, columns);
173    if (resultSet == nullptr) {
174        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
175        helper->Release();
176        return false;
177    }
178    resultSet->GoToFirstRow();
179    int32_t columnInt;
180    int columnIndex;
181    resultSet->GetColumnIndex(SmsMmsInfo::MSG_ID, columnIndex);
182    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
183        dataBaseId = columnInt;
184    }
185    resultSet->Close();
186    helper->Release();
187    return true;
188}
189
190bool SmsPersistHelper::Update(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
191{
192    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
193    if (helper == nullptr) {
194        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
195        return false;
196    }
197    Uri uri(SMS_SESSION);
198    int ret = helper->Update(uri, predicates, values);
199    helper->Release();
200    return ret >= 0 ? true : false;
201}
202
203bool SmsPersistHelper::Query(DataShare::DataSharePredicates &predicates, std::vector<SmsReceiveIndexer> &indexers)
204{
205    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
206    if (helper == nullptr) {
207        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
208        return false;
209    }
210    Uri uri(SMS_SUBSECTION);
211    std::vector<std::string> columns;
212    auto resultSet = helper->Query(uri, predicates, columns);
213    if (resultSet == nullptr) {
214        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
215        helper->Release();
216        return false;
217    }
218
219    int resultSetNum = resultSet->GoToFirstRow();
220    TELEPHONY_LOGE("resultSetNum is %{public}d before cycle", resultSetNum);
221    while (resultSetNum == 0) {
222        SmsReceiveIndexer indexer;
223        ResultSetConvertToIndexer(indexer, resultSet);
224        indexers.push_back(indexer);
225        resultSetNum = resultSet->GoToNextRow();
226        TELEPHONY_LOGE("resultSetNum is %{public}d in cycle", resultSetNum);
227    }
228    resultSet->Close();
229    helper->Release();
230    return true;
231}
232
233bool SmsPersistHelper::QueryMaxGroupId(DataShare::DataSharePredicates &predicates, uint16_t &maxGroupId)
234{
235    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
236    if (helper == nullptr) {
237        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
238        return false;
239    }
240    Uri uri(SMS_MMS_INFO);
241    std::vector<std::string> columns;
242    auto resultSet = helper->Query(uri, predicates, columns);
243    if (resultSet == nullptr) {
244        TELEPHONY_LOGE("Query Result Set nullptr Failed.");
245        helper->Release();
246        return false;
247    }
248
249    int32_t columnInt;
250    int columnIndex;
251    resultSet->GoToLastRow();
252    resultSet->GetColumnIndex(SmsMmsInfo::GROUP_ID, columnIndex);
253    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
254        maxGroupId = columnInt;
255    }
256    resultSet->Close();
257    helper->Release();
258    return true;
259}
260
261bool SmsPersistHelper::Delete(DataShare::DataSharePredicates &predicates)
262{
263    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(SMS_URI);
264    if (helper == nullptr) {
265        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
266        return false;
267    }
268    Uri uri(SMS_SUBSECTION);
269    int ret = helper->Delete(uri, predicates);
270    helper->Release();
271    return ret >= 0 ? true : false;
272}
273
274bool SmsPersistHelper::QueryBlockPhoneNumber(const std::string &phoneNum)
275{
276    bool result = false;
277    if (phoneNum.empty()) {
278        return result;
279    }
280    return result;
281}
282
283int32_t SmsPersistHelper::FormatSmsNumber(const std::string &num, std::string countryCode,
284    const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNum)
285{
286    if (num.empty()) {
287        TELEPHONY_LOGE("num is nullptr!");
288        return TELEPHONY_ERR_ARGUMENT_INVALID;
289    }
290    i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
291    if (phoneUtils == nullptr) {
292        TELEPHONY_LOGE("phoneUtils is nullptr");
293        return TELEPHONY_ERR_LOCAL_PTR_NULL;
294    }
295    transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::toupper);
296    i18n::phonenumbers::PhoneNumber parseResult;
297    phoneUtils->Parse(num, countryCode, &parseResult);
298    if (phoneUtils->IsValidNumber(parseResult)) {
299        phoneUtils->Format(parseResult, formatInfo, &formatNum);
300    } else {
301        std::string numTemp = "";
302        numTemp.assign(num);
303        CbnFormat(numTemp, formatInfo, formatNum);
304    }
305    if (formatNum.empty() || formatNum == "0") {
306        return TELEPHONY_ERROR;
307    }
308    TrimSpace(formatNum);
309    return TELEPHONY_SUCCESS;
310}
311
312void SmsPersistHelper::CbnFormat(std::string &numTemp,
313    const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNum)
314{
315    TELEPHONY_LOGD("into CbnFormat");
316    uint8_t minLength = 3;
317    if (numTemp.size() < minLength) {
318        TELEPHONY_LOGD("Phonenumber is too short");
319        return;
320    }
321    if (numTemp.substr(0, NUMBER_START_STR.size()) == NUMBER_START_STR ||
322        numTemp.substr(PREFIX.size(), NUMBER_START_STR.size()) == NUMBER_START_STR) {
323        if (formatInfo == i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL) {
324            if (numTemp.substr(0, PREFIX.size()) == PREFIX) {
325                numTemp.erase(0, PREFIX.size());
326                formatNum.assign(numTemp);
327                return;
328            }
329            formatNum.assign(numTemp);
330            return;
331        }
332        if (formatInfo == i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL) {
333            if (numTemp.substr(0, PREFIX.size()) == PREFIX) {
334                formatNum.assign(numTemp);
335                return;
336            }
337            formatNum.assign(PREFIX + numTemp);
338        }
339    }
340}
341
342void SmsPersistHelper::TrimSpace(std::string &num)
343{
344    std::string word;
345    std::stringstream streamNum(num);
346    std::string store;
347    while (streamNum >> word) {
348        store += word;
349    }
350    num = store;
351}
352
353bool SmsPersistHelper::UpdateContact(const std::string &address)
354{
355    bool result = false;
356    if (address.empty()) {
357        TELEPHONY_LOGE("address empty");
358        return result;
359    }
360    int32_t rawCountId = 0;
361    int32_t contactedCount = 0;
362    bool ret = QueryContactedCount(address, rawCountId, contactedCount);
363    if (!ret) {
364        TELEPHONY_LOGE("get contacted count fail");
365        return result;
366    }
367    TELEPHONY_LOGI("rawCountId:%{public}d, contactedCount:%{public}d", rawCountId, contactedCount);
368    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
369    if (helper == nullptr) {
370        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
371        return false;
372    }
373    std::time_t timep;
374    int64_t currentTime = time(&timep);
375    Uri uri(RAW_CONTACT);
376    DataShare::DataSharePredicates predicates;
377    predicates.EqualTo(ID, rawCountId);
378    DataShare::DataShareValuesBucket bucket;
379    bucket.Put(CONTACTED_COUNT, contactedCount + 1);
380    bucket.Put(LASTEST_CONTACTED_TIME, std::to_string(currentTime));
381    auto updateValue = helper->Update(uri, predicates, bucket);
382    TELEPHONY_LOGI("updateValue:%{public}d", updateValue);
383    helper->Release();
384    return updateValue >= 0 ? true : false;
385}
386
387bool SmsPersistHelper::QueryContactedCount(const std::string &address, int32_t &rawCountId, int32_t &contactedCount)
388{
389    bool ret = QueryRawContactId(address, rawCountId);
390    if (!ret) {
391        TELEPHONY_LOGE("no sms address in contact");
392        return ret;
393    }
394    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
395    if (helper == nullptr) {
396        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
397        return false;
398    }
399    Uri uri(RAW_CONTACT);
400    std::vector<std::string> columns;
401    DataShare::DataSharePredicates predicates;
402    predicates.EqualTo(ID, rawCountId);
403    auto resultSet = helper->Query(uri, predicates, columns);
404    bool result = false;
405    if (resultSet == nullptr) {
406        TELEPHONY_LOGE("result set nullptr.");
407        helper->Release();
408        return result;
409    }
410    int32_t count = 0;
411    if (resultSet->GetRowCount(count) == 0 && count != 0) {
412        resultSet->GoToFirstRow();
413        int columnIndex;
414        resultSet->GetColumnIndex(CONTACTED_COUNT, columnIndex);
415        if (resultSet->GetInt(columnIndex, contactedCount) == 0) {
416            result = true;
417        }
418    }
419    resultSet->Close();
420    helper->Release();
421    return result;
422}
423
424bool SmsPersistHelper::QueryRawContactId(const std::string &address, int32_t &rawCountId)
425{
426    std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
427    if (helper == nullptr) {
428        TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
429        return false;
430    }
431    Uri uri(CONTACT_DATA);
432    std::vector<std::string> columns;
433    DataShare::DataSharePredicates predicates;
434    std::string nationalNum;
435    std::string internationalNum;
436    int32_t ret = FormatSmsNumber(
437        address, ISO_COUNTRY_CODE, i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL, nationalNum);
438    if (ret != TELEPHONY_SUCCESS) {
439        TELEPHONY_LOGE("Phone Number format Failed.");
440        nationalNum = address;
441    }
442    ret = FormatSmsNumber(address, ISO_COUNTRY_CODE,
443        i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL, internationalNum);
444    if (ret != TELEPHONY_SUCCESS) {
445        TELEPHONY_LOGE("Phone Number format Failed.");
446        internationalNum = address;
447    }
448    predicates.EqualTo(DETAIL_INFO, nationalNum)->Or()->EqualTo(DETAIL_INFO, internationalNum);
449    predicates.EqualTo(TYPE_ID, TYPE_ID_VALUE);
450    auto resultSet = helper->Query(uri, predicates, columns);
451    bool result = false;
452    if (resultSet == nullptr) {
453        TELEPHONY_LOGE("result set nullptr.");
454        helper->Release();
455        return result;
456    }
457    int32_t count = 0;
458    if (resultSet->GetRowCount(count) == 0 && count != 0) {
459        resultSet->GoToFirstRow();
460        int columnIndex;
461        resultSet->GetColumnIndex(RAW_CONTACT_ID, columnIndex);
462        if (resultSet->GetInt(columnIndex, rawCountId) == 0) {
463            result = true;
464        }
465    }
466    resultSet->Close();
467    helper->Release();
468    return result;
469}
470
471bool SmsPersistHelper::QueryParamBoolean(const std::string key, bool defValue)
472{
473    const int PARAM_SIZE = 64;
474    char paramOutBuff[PARAM_SIZE] = { 0 };
475    std::string defStrValue = defValue ? "1" : "0";
476    std::string paramValue(defStrValue);
477
478    int retLen = GetParameter(key.c_str(), defStrValue.c_str(), paramOutBuff, PARAM_SIZE);
479    if (retLen > 0) {
480        paramOutBuff[retLen] = '\0';
481        paramValue.assign(paramOutBuff, retLen);
482    }
483
484    TELEPHONY_LOGI("QueryParamBoolean: %{public}zu : %{public}s", paramValue.size(), paramValue.c_str());
485    if ((paramValue == std::string("1")) || (paramValue == std::string("y")) || (paramValue == std::string("yes")) ||
486        (paramValue == std::string("on")) || (paramValue == std::string("true"))) {
487        return true;
488    } else if ((paramValue == std::string("0")) || (paramValue == std::string("n")) ||
489               (paramValue == std::string("no")) || (paramValue == std::string("off")) ||
490               (paramValue == std::string("false"))) {
491        return false;
492    }
493    return defValue;
494}
495
496void SmsPersistHelper::ConvertIntToIndexer(
497    SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
498{
499    int32_t columnInt;
500    int columnIndex;
501    resultSet->GetColumnIndex(SmsSubsection::FORMAT, columnIndex);
502    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
503        info.SetIsCdma(columnInt == SMS_TYPE_CDMA);
504    }
505
506    resultSet->GetColumnIndex(SmsSubsection::SMS_SUBSECTION_ID, columnIndex);
507    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
508        info.SetMsgRefId(columnInt);
509    }
510
511    resultSet->GetColumnIndex(SmsSubsection::SIZE, columnIndex);
512    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
513        info.SetMsgCount(columnInt);
514    }
515
516    resultSet->GetColumnIndex(SmsSubsection::SUBSECTION_INDEX, columnIndex);
517    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
518        info.SetMsgSeqId(columnInt);
519    }
520
521    resultSet->GetColumnIndex(SmsSubsection::DEST_PORT, columnIndex);
522    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
523        info.SetDestPort(columnInt);
524    }
525
526    resultSet->GetColumnIndex(SmsSubsection::ID, columnIndex);
527    if (resultSet->GetInt(columnIndex, columnInt) == 0) {
528        info.SetDataBaseId(columnInt);
529    }
530}
531
532void SmsPersistHelper::ConvertStringToIndexer(
533    SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
534{
535    int columnIndex;
536    std::string columnValue;
537    resultSet->GetColumnIndex(SmsSubsection::RECEIVER_NUMBER, columnIndex);
538    if (resultSet->GetString(columnIndex, columnValue) == 0) {
539        info.SetVisibleAddress(columnValue);
540    }
541    resultSet->GetColumnIndex(SmsSubsection::SENDER_NUMBER, columnIndex);
542    if (resultSet->GetString(columnIndex, columnValue) == 0) {
543        info.SetOriginatingAddress(columnValue);
544    }
545    resultSet->GetColumnIndex(SmsSubsection::START_TIME, columnIndex);
546    if (resultSet->GetString(columnIndex, columnValue) == 0) {
547        std::istringstream str(columnValue);
548        int64_t columnValueInt64 = 0;
549        str >> columnValueInt64;
550        info.SetTimestamp(columnValueInt64);
551    }
552    resultSet->GetColumnIndex(SmsSubsection::END_TIME, columnIndex);
553    if (resultSet->GetString(columnIndex, columnValue) == 0) {
554        std::istringstream str(columnValue);
555        int64_t columnValueInt64 = 0;
556        str >> columnValueInt64;
557        info.SetTimestamp(columnValueInt64);
558    }
559    resultSet->GetColumnIndex(SmsSubsection::REW_PUD, columnIndex);
560    if (resultSet->GetString(columnIndex, columnValue) == 0) {
561        info.SetPdu(StringUtils::HexToByteVector(columnValue));
562    }
563}
564
565void SmsPersistHelper::ResultSetConvertToIndexer(
566    SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
567{
568    ConvertIntToIndexer(info, resultSet);
569    ConvertStringToIndexer(info, resultSet);
570}
571} // namespace Telephony
572} // namespace OHOS
573