1/*
2 * Copyright (C) 2023 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 "mms_apn_info.h"
17
18#include "core_manager_inner.h"
19#include "pdp_profile_data.h"
20#include "string_utils.h"
21#include "telephony_log_wrapper.h"
22
23namespace OHOS {
24namespace Telephony {
25const std::string PDP_PROFILE_NET_URI = "datashare:///com.ohos.pdpprofileability/net/pdp_profile?simId=";
26const std::string MMS_APN_TYPE = "mms";
27const std::string ALL_APN_TYPE = "*";
28
29MmsApnInfo::MmsApnInfo(int32_t slotId) : slotId_(slotId)
30{
31    getMmsApn();
32}
33
34MmsApnInfo::~MmsApnInfo() {}
35
36void MmsApnInfo::getMmsApn()
37{
38    std::shared_ptr<DataShare::DataShareHelper> helper = CreatePdpProfileHelper();
39    if (helper == nullptr) {
40        TELEPHONY_LOGE("getMmsApn helper is nullptr");
41        return;
42    }
43    PdpProfileSelect(helper);
44}
45
46std::shared_ptr<DataShare::DataShareHelper> MmsApnInfo::CreatePdpProfileHelper()
47{
48    if (mmsPdpProfileDataAbilityHelper == nullptr) {
49        mmsPdpProfileDataAbilityHelper = CreateDataAHelper(TELEPHONY_SMS_MMS_SYS_ABILITY_ID, PDP_PROFILE_URI);
50    }
51    return mmsPdpProfileDataAbilityHelper;
52}
53
54std::shared_ptr<DataShare::DataShareHelper> MmsApnInfo::CreateDataAHelper(
55    int32_t systemAbilityId, const std::string &dataAbilityUri) const
56{
57    auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
58    if (saManager == nullptr) {
59        TELEPHONY_LOGE("Get system ability mgr failed");
60        return nullptr;
61    }
62    auto remoteObj = saManager->GetSystemAbility(systemAbilityId);
63    if (remoteObj == nullptr) {
64        TELEPHONY_LOGE("GetSystemAbility Service Failed");
65        return nullptr;
66    }
67    return DataShare::DataShareHelper::Creator(remoteObj, dataAbilityUri);
68}
69
70bool MmsApnInfo::SplitAndMatchApnTypes(std::string apn)
71{
72    std::vector<std::string> apns;
73    size_t pos = 0;
74    size_t found = 0;
75    while ((found = apn.find(',', pos)) != std::string::npos) {
76        apns.push_back(apn.substr(pos, found - pos));
77        pos = found + 1;
78    }
79    apns.push_back(apn.substr(pos));
80
81    for (size_t i = 0; i < apns.size(); i++) {
82        if (apns[i] == MMS_APN_TYPE || (apns[i] == ALL_APN_TYPE && apns.size() == 1)) {
83            TELEPHONY_LOGI("ApnType match success");
84            return true;
85        }
86    }
87    return false;
88}
89
90bool MmsApnInfo::GetMmsApnValue(
91    std::shared_ptr<DataShare::ResultSet> resultSet, int count, std::string &homeUrlVal, std::string &mmsIPAddressVal)
92{
93    int columnIndex;
94    std::string apn;
95    for (int row = 0; row < count; row++) {
96        resultSet->GoToRow(row);
97        resultSet->GetColumnIndex(PdpProfileData::APN_TYPES, columnIndex);
98        resultSet->GetString(columnIndex, apn);
99        if (SplitAndMatchApnTypes(apn)) {
100            resultSet->GetColumnIndex(PdpProfileData::HOME_URL, columnIndex);
101            resultSet->GetString(columnIndex, homeUrlVal);
102            resultSet->GetColumnIndex(PdpProfileData::MMS_IP_ADDRESS, columnIndex);
103            resultSet->GetString(columnIndex, mmsIPAddressVal);
104            return true;
105        }
106    }
107    return false;
108}
109
110void MmsApnInfo::PdpProfileSelect(const std::shared_ptr<DataShare::DataShareHelper> &helper)
111{
112    int32_t simId = CoreManagerInner::GetInstance().GetSimId(slotId_);
113    Uri uri(static_cast<std::string>(PDP_PROFILE_NET_URI) + std::to_string(simId));
114    std::vector<std::string> colume;
115    DataShare::DataSharePredicates predicates;
116    std::u16string operatorNumeric;
117    CoreManagerInner::GetInstance().GetSimOperatorNumeric(slotId_, operatorNumeric);
118    std::string mccmnc = StringUtils::ToUtf8(operatorNumeric);
119    if (mccmnc.empty()) {
120        TELEPHONY_LOGE("mccmnc is empty");
121        return;
122    }
123    TELEPHONY_LOGI("query mms apn data base");
124    predicates.EqualTo(PdpProfileData::MCCMNC, mccmnc);
125    auto resultSet = helper->Query(uri, predicates, colume);
126    if (resultSet == nullptr) {
127        TELEPHONY_LOGE("resultSet nullptr");
128        helper->Release();
129        return;
130    }
131    int count;
132    resultSet->GetRowCount(count);
133    if (count <= 0) {
134        TELEPHONY_LOGE("count: %{public}d null return", count);
135        resultSet->Close();
136        helper->Release();
137        return;
138    }
139    std::string homeUrlVal;
140    std::string mmsIPAddressVal;
141    if (GetMmsApnValue(resultSet, count, homeUrlVal, mmsIPAddressVal)) {
142        setMmscUrl(homeUrlVal);
143        setMmsProxyAddressAndProxyPort(mmsIPAddressVal);
144    } else {
145        TELEPHONY_LOGI("homeUrlVal and mmsIPAddressVal not matched");
146    }
147    resultSet->Close();
148    helper->Release();
149}
150
151std::string MmsApnInfo::getMmscUrl()
152{
153    return mmscUrl_;
154}
155
156void MmsApnInfo::setMmscUrl(std::string mmscUrl)
157{
158    mmscUrl_ = mmscUrl;
159}
160
161std::string MmsApnInfo::getMmsProxyAddressAndProxyPort()
162{
163    return mmsProxyAddressAndProxyPort_;
164}
165
166void MmsApnInfo::setMmsProxyAddressAndProxyPort(std::string mmsProxyAddressAndProxyPort)
167{
168    mmsProxyAddressAndProxyPort_ = mmsProxyAddressAndProxyPort;
169}
170} // namespace Telephony
171} // namespace OHOS