1d95e75fdSopenharmony_ci/* 2d95e75fdSopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 3d95e75fdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d95e75fdSopenharmony_ci * you may not use this file except in compliance with the License. 5d95e75fdSopenharmony_ci * You may obtain a copy of the License at 6d95e75fdSopenharmony_ci * 7d95e75fdSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d95e75fdSopenharmony_ci * 9d95e75fdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d95e75fdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d95e75fdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d95e75fdSopenharmony_ci * See the License for the specific language governing permissions and 13d95e75fdSopenharmony_ci * limitations under the License. 14d95e75fdSopenharmony_ci */ 15d95e75fdSopenharmony_ci 16d95e75fdSopenharmony_ci#include "mmi_code_utils.h" 17d95e75fdSopenharmony_ci 18d95e75fdSopenharmony_ci#include <regex> 19d95e75fdSopenharmony_ci 20d95e75fdSopenharmony_ci#include "cellular_call_supplement.h" 21d95e75fdSopenharmony_ci#include "standardize_utils.h" 22d95e75fdSopenharmony_ci#include "telephony_log_wrapper.h" 23d95e75fdSopenharmony_ci 24d95e75fdSopenharmony_cinamespace OHOS { 25d95e75fdSopenharmony_cinamespace Telephony { 26d95e75fdSopenharmony_ci// 3GPP TS 22.030 V16.0.0 (2020-07) 6.5.3.2 Handling of not-implemented supplementary services 27d95e75fdSopenharmony_ciconstexpr unsigned long long operator"" _hash(char const *p, size_t s) 28d95e75fdSopenharmony_ci{ 29d95e75fdSopenharmony_ci return StandardizeUtils::HashCompileTime(p); 30d95e75fdSopenharmony_ci} 31d95e75fdSopenharmony_ci 32d95e75fdSopenharmony_cibool MMICodeUtils::IsNeedExecuteMmi(const std::string &analyseString, bool isNeedUseIms) 33d95e75fdSopenharmony_ci{ 34d95e75fdSopenharmony_ci isNeedUseIms_ = isNeedUseIms; 35d95e75fdSopenharmony_ci if (analyseString.empty()) { 36d95e75fdSopenharmony_ci TELEPHONY_LOGE("analyseString is empty."); 37d95e75fdSopenharmony_ci return false; 38d95e75fdSopenharmony_ci } 39d95e75fdSopenharmony_ci if (RegexMatchMmi(analyseString)) { 40d95e75fdSopenharmony_ci return true; 41d95e75fdSopenharmony_ci } 42d95e75fdSopenharmony_ci 43d95e75fdSopenharmony_ci // 3GPP TS 22.030 V16.0.0 (2020-07) 6.5.3.2 Handling of not-implemented supplementary services 44d95e75fdSopenharmony_ci if ((analyseString.front() == '*' || analyseString.front() == '#') && analyseString.back() == '#') { 45d95e75fdSopenharmony_ci TELEPHONY_LOGI("analyseString start with * or # and end with #"); 46d95e75fdSopenharmony_ci mmiData_.fullString = analyseString; 47d95e75fdSopenharmony_ci return true; 48d95e75fdSopenharmony_ci } 49d95e75fdSopenharmony_ci 50d95e75fdSopenharmony_ci return false; 51d95e75fdSopenharmony_ci} 52d95e75fdSopenharmony_ci 53d95e75fdSopenharmony_civoid InitCallTransferMmiCodeFunc(std::map<std::uint64_t, 54d95e75fdSopenharmony_ci std::function<void(CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData)>> &mmiCodeFunc) 55d95e75fdSopenharmony_ci{ 56d95e75fdSopenharmony_ci /** 57d95e75fdSopenharmony_ci * "21" Deal with unconditional transfer 58d95e75fdSopenharmony_ci * "61" Handling no answer transfer 59d95e75fdSopenharmony_ci * "62" Handling no signal transfer 60d95e75fdSopenharmony_ci * "67" Deal with busy transfer 61d95e75fdSopenharmony_ci * "002" Process all transfers 62d95e75fdSopenharmony_ci * "004" Handle transfer under all conditions 63d95e75fdSopenharmony_ci */ 64d95e75fdSopenharmony_ci mmiCodeFunc["21"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 65d95e75fdSopenharmony_ci supplement->HandleCallTransfer(slotId, mmiData); 66d95e75fdSopenharmony_ci }; 67d95e75fdSopenharmony_ci mmiCodeFunc["61"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 68d95e75fdSopenharmony_ci supplement->HandleCallTransfer(slotId, mmiData); 69d95e75fdSopenharmony_ci }; 70d95e75fdSopenharmony_ci mmiCodeFunc["62"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 71d95e75fdSopenharmony_ci supplement->HandleCallTransfer(slotId, mmiData); 72d95e75fdSopenharmony_ci }; 73d95e75fdSopenharmony_ci mmiCodeFunc["67"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 74d95e75fdSopenharmony_ci supplement->HandleCallTransfer(slotId, mmiData); 75d95e75fdSopenharmony_ci }; 76d95e75fdSopenharmony_ci mmiCodeFunc["002"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 77d95e75fdSopenharmony_ci supplement->HandleCallTransfer(slotId, mmiData); 78d95e75fdSopenharmony_ci }; 79d95e75fdSopenharmony_ci mmiCodeFunc["004"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 80d95e75fdSopenharmony_ci supplement->HandleCallTransfer(slotId, mmiData); 81d95e75fdSopenharmony_ci }; 82d95e75fdSopenharmony_ci} 83d95e75fdSopenharmony_ci 84d95e75fdSopenharmony_civoid InitCallRestrictionCodeFunc(std::map<std::uint64_t, 85d95e75fdSopenharmony_ci std::function<void(CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData)>> &mmiCodeFunc) 86d95e75fdSopenharmony_ci{ 87d95e75fdSopenharmony_ci /** 88d95e75fdSopenharmony_ci * "33" Processing limits all outgoing calls 89d95e75fdSopenharmony_ci * "330" Processing all restrictions 90d95e75fdSopenharmony_ci * "331" Processing limits all international calls 91d95e75fdSopenharmony_ci * "332" Handling international outgoing calls belonging to foreign countries when roaming is 92d95e75fdSopenharmony_ci * restricted 93d95e75fdSopenharmony_ci * "333" Processing limits outgoing calls 94d95e75fdSopenharmony_ci * "35" Processing limits all incoming calls 95d95e75fdSopenharmony_ci * "351" Handle all incoming calls when roaming is restricted 96d95e75fdSopenharmony_ci * "353" Processing limits incoming calls 97d95e75fdSopenharmony_ci */ 98d95e75fdSopenharmony_ci mmiCodeFunc["33"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 99d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 100d95e75fdSopenharmony_ci }; 101d95e75fdSopenharmony_ci mmiCodeFunc["330"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 102d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 103d95e75fdSopenharmony_ci }; 104d95e75fdSopenharmony_ci mmiCodeFunc["331"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 105d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 106d95e75fdSopenharmony_ci }; 107d95e75fdSopenharmony_ci mmiCodeFunc["332"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 108d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 109d95e75fdSopenharmony_ci }; 110d95e75fdSopenharmony_ci mmiCodeFunc["333"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 111d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 112d95e75fdSopenharmony_ci }; 113d95e75fdSopenharmony_ci mmiCodeFunc["35"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 114d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 115d95e75fdSopenharmony_ci }; 116d95e75fdSopenharmony_ci mmiCodeFunc["351"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 117d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 118d95e75fdSopenharmony_ci }; 119d95e75fdSopenharmony_ci mmiCodeFunc["353"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 120d95e75fdSopenharmony_ci supplement->HandleCallRestriction(slotId, mmiData); 121d95e75fdSopenharmony_ci }; 122d95e75fdSopenharmony_ci} 123d95e75fdSopenharmony_ci 124d95e75fdSopenharmony_civoid InitAdditionalMmiCodeFunc(std::map<std::uint64_t, 125d95e75fdSopenharmony_ci std::function<void(CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData)>> &mmiCodeFunc) 126d95e75fdSopenharmony_ci{ 127d95e75fdSopenharmony_ci /** 128d95e75fdSopenharmony_ci * "30" Processing caller ID 129d95e75fdSopenharmony_ci * "31" Processing calling number display 130d95e75fdSopenharmony_ci * "04" Change pin password 131d95e75fdSopenharmony_ci * "05" Use puk unlock sim and change pin password 132d95e75fdSopenharmony_ci * "042" Change pin2 password 133d95e75fdSopenharmony_ci * "052" Use puk2 unlock sim and change pin2 password 134d95e75fdSopenharmony_ci * "43" Handling call waiting 135d95e75fdSopenharmony_ci */ 136d95e75fdSopenharmony_ci mmiCodeFunc["30"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 137d95e75fdSopenharmony_ci supplement->HandleClip(slotId, mmiData); 138d95e75fdSopenharmony_ci }; 139d95e75fdSopenharmony_ci mmiCodeFunc["31"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 140d95e75fdSopenharmony_ci supplement->HandleClir(slotId, mmiData); 141d95e75fdSopenharmony_ci }; 142d95e75fdSopenharmony_ci mmiCodeFunc["04"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 143d95e75fdSopenharmony_ci supplement->AlterPinPassword(slotId, mmiData); 144d95e75fdSopenharmony_ci }; 145d95e75fdSopenharmony_ci mmiCodeFunc["05"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 146d95e75fdSopenharmony_ci supplement->UnlockPuk(slotId, mmiData); 147d95e75fdSopenharmony_ci }; 148d95e75fdSopenharmony_ci mmiCodeFunc["042"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 149d95e75fdSopenharmony_ci supplement->AlterPin2Password(slotId, mmiData); 150d95e75fdSopenharmony_ci }; 151d95e75fdSopenharmony_ci mmiCodeFunc["052"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 152d95e75fdSopenharmony_ci supplement->UnlockPuk2(slotId, mmiData); 153d95e75fdSopenharmony_ci }; 154d95e75fdSopenharmony_ci mmiCodeFunc["43"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 155d95e75fdSopenharmony_ci supplement->HandleCallWaiting(slotId, mmiData); 156d95e75fdSopenharmony_ci }; 157d95e75fdSopenharmony_ci} 158d95e75fdSopenharmony_ci 159d95e75fdSopenharmony_civoid InitImsMmiCodeFunc(std::map<std::uint64_t, 160d95e75fdSopenharmony_ci std::function<void(CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData)>> &mmiCodeFunc) 161d95e75fdSopenharmony_ci{ 162d95e75fdSopenharmony_ci /** 163d95e75fdSopenharmony_ci * "76" Connected line identification presentation 164d95e75fdSopenharmony_ci * "77" Connected line identification restriction 165d95e75fdSopenharmony_ci */ 166d95e75fdSopenharmony_ci mmiCodeFunc["76"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 167d95e75fdSopenharmony_ci supplement->HandleColp(slotId, mmiData); 168d95e75fdSopenharmony_ci }; 169d95e75fdSopenharmony_ci mmiCodeFunc["77"_hash] = [](CellularCallSupplement *supplement, int32_t slotId, const MMIData &mmiData) { 170d95e75fdSopenharmony_ci supplement->HandleColr(slotId, mmiData); 171d95e75fdSopenharmony_ci }; 172d95e75fdSopenharmony_ci} 173d95e75fdSopenharmony_ci 174d95e75fdSopenharmony_cibool MMICodeUtils::ExecuteMmiCode(int32_t slotId) 175d95e75fdSopenharmony_ci{ 176d95e75fdSopenharmony_ci using MmiCodeFunc = 177d95e75fdSopenharmony_ci std::function<void(CellularCallSupplement * supplement, int32_t slotId, const MMIData &mmiData)>; 178d95e75fdSopenharmony_ci std::map<std::uint64_t, MmiCodeFunc> mmiCodeFunc; 179d95e75fdSopenharmony_ci InitCallTransferMmiCodeFunc(mmiCodeFunc); 180d95e75fdSopenharmony_ci InitCallRestrictionCodeFunc(mmiCodeFunc); 181d95e75fdSopenharmony_ci InitAdditionalMmiCodeFunc(mmiCodeFunc); 182d95e75fdSopenharmony_ci if (isNeedUseIms_) { 183d95e75fdSopenharmony_ci InitImsMmiCodeFunc(mmiCodeFunc); 184d95e75fdSopenharmony_ci } 185d95e75fdSopenharmony_ci 186d95e75fdSopenharmony_ci CellularCallSupplement supplement; 187d95e75fdSopenharmony_ci if (!mmiData_.serviceCode.empty()) { 188d95e75fdSopenharmony_ci auto serviceCode = StandardizeUtils::Hash_(mmiData_.serviceCode.c_str()); 189d95e75fdSopenharmony_ci // "03" Processing network password 190d95e75fdSopenharmony_ci if (serviceCode == "03"_hash) { 191d95e75fdSopenharmony_ci return true; 192d95e75fdSopenharmony_ci } 193d95e75fdSopenharmony_ci auto itFunc = mmiCodeFunc.find(serviceCode); 194d95e75fdSopenharmony_ci if (itFunc != mmiCodeFunc.end()) { 195d95e75fdSopenharmony_ci auto func = itFunc->second; 196d95e75fdSopenharmony_ci if (func != nullptr) { 197d95e75fdSopenharmony_ci func(&supplement, slotId, mmiData_); 198d95e75fdSopenharmony_ci return true; 199d95e75fdSopenharmony_ci } 200d95e75fdSopenharmony_ci } 201d95e75fdSopenharmony_ci TELEPHONY_LOGI("Function not found, need check serviceCode."); 202d95e75fdSopenharmony_ci } 203d95e75fdSopenharmony_ci if (!mmiData_.fullString.empty()) { 204d95e75fdSopenharmony_ci TELEPHONY_LOGD("fullString is not empty."); 205d95e75fdSopenharmony_ci supplement.SendUssd(slotId, mmiData_.fullString); 206d95e75fdSopenharmony_ci return true; 207d95e75fdSopenharmony_ci } 208d95e75fdSopenharmony_ci 209d95e75fdSopenharmony_ci TELEPHONY_LOGW("default case, need check."); 210d95e75fdSopenharmony_ci return false; 211d95e75fdSopenharmony_ci} 212d95e75fdSopenharmony_ci 213d95e75fdSopenharmony_cibool MMICodeUtils::RegexMatchMmi(const std::string &analyseString) 214d95e75fdSopenharmony_ci{ 215d95e75fdSopenharmony_ci std::string symbols = 216d95e75fdSopenharmony_ci "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)"; 217d95e75fdSopenharmony_ci std::regex pattern(symbols); 218d95e75fdSopenharmony_ci std::smatch results; 219d95e75fdSopenharmony_ci if (regex_match(analyseString, results, pattern)) { 220d95e75fdSopenharmony_ci TELEPHONY_LOGD("regex_match ture"); 221d95e75fdSopenharmony_ci 222d95e75fdSopenharmony_ci /** 223d95e75fdSopenharmony_ci * The following sequence of functions shall be used for the control of Supplementary Services: 224d95e75fdSopenharmony_ci * SELECT: Entry of the procedure information (may be a digit or a sequence of characters). 225d95e75fdSopenharmony_ci * SEND: Transmission of the information to the network. 226d95e75fdSopenharmony_ci * INDICATION: Call progress indications. 227d95e75fdSopenharmony_ci */ 228d95e75fdSopenharmony_ci int32_t fullString = 1; 229d95e75fdSopenharmony_ci int32_t action = 2; 230d95e75fdSopenharmony_ci // 3GPP TS 22.030 V4.0.0 (2001-03) 6.5.2 Structure of the MMI 231d95e75fdSopenharmony_ci // This structure consists of the following parts: 232d95e75fdSopenharmony_ci // Service Code, SC( (2 or 3 digits) 233d95e75fdSopenharmony_ci // Supplementary Information, SI (variable length). 234d95e75fdSopenharmony_ci int32_t serviceCode = 3; 235d95e75fdSopenharmony_ci int32_t sia = 5; 236d95e75fdSopenharmony_ci int32_t sib = 7; 237d95e75fdSopenharmony_ci int32_t sic = 9; 238d95e75fdSopenharmony_ci int32_t pwdConfirm = 11; 239d95e75fdSopenharmony_ci int32_t dialingNumber = 12; 240d95e75fdSopenharmony_ci mmiData_.fullString = results.str(fullString); 241d95e75fdSopenharmony_ci mmiData_.actionString = results.str(action); 242d95e75fdSopenharmony_ci mmiData_.serviceCode = results.str(serviceCode); 243d95e75fdSopenharmony_ci mmiData_.serviceInfoA = results.str(sia); 244d95e75fdSopenharmony_ci mmiData_.serviceInfoB = results.str(sib); 245d95e75fdSopenharmony_ci mmiData_.serviceInfoC = results.str(sic); 246d95e75fdSopenharmony_ci mmiData_.pwdString = results.str(pwdConfirm); 247d95e75fdSopenharmony_ci mmiData_.dialString = results.str(dialingNumber); 248d95e75fdSopenharmony_ci 249d95e75fdSopenharmony_ci /* 3GPP TS 22.030 V4.0.0 (2001-03) 6.5.2 Structure of the MMI 250d95e75fdSopenharmony_ci * The procedure always starts with *, #, **, ## or *# and is finished by #. 251d95e75fdSopenharmony_ci * Each part within the procedure is separated by *. 252d95e75fdSopenharmony_ci */ 253d95e75fdSopenharmony_ci if (analyseString.back() == '#' && !mmiData_.dialString.empty() && mmiData_.dialString.back() == '#') { 254d95e75fdSopenharmony_ci mmiData_.fullString = analyseString; 255d95e75fdSopenharmony_ci } 256d95e75fdSopenharmony_ci return true; 257d95e75fdSopenharmony_ci } 258d95e75fdSopenharmony_ci return false; 259d95e75fdSopenharmony_ci} 260d95e75fdSopenharmony_ci 261d95e75fdSopenharmony_ciMMIData MMICodeUtils::GetMMIData() 262d95e75fdSopenharmony_ci{ 263d95e75fdSopenharmony_ci return mmiData_; 264d95e75fdSopenharmony_ci} 265d95e75fdSopenharmony_ci} // namespace Telephony 266d95e75fdSopenharmony_ci} // namespace OHOS 267