• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "mmi_code_utils.h"
17 
18 #include <regex>
19 
20 #include "cellular_call_supplement.h"
21 #include "standardize_utils.h"
22 #include "telephony_log_wrapper.h"
23 
24 namespace OHOS {
25 namespace Telephony {
26 // 3GPP TS 22.030 V16.0.0 (2020-07) 6.5.3.2	Handling of not-implemented supplementary services
operator ""_hash(char const * p,size_t s)27 constexpr unsigned long long operator"" _hash(char const *p, size_t s)
28 {
29     return StandardizeUtils::HashCompileTime(p);
30 }
31 
IsNeedExecuteMmi(const std::string & analyseString,bool isNeedUseIms)32 bool MMICodeUtils::IsNeedExecuteMmi(const std::string &analyseString, bool isNeedUseIms)
33 {
34     isNeedUseIms_ = isNeedUseIms;
35     if (analyseString.empty()) {
36         TELEPHONY_LOGE("analyseString is empty.");
37         return false;
38     }
39     if (RegexMatchMmi(analyseString)) {
40         return true;
41     }
42 
43     // 3GPP TS 22.030 V16.0.0 (2020-07) 6.5.3.2	Handling of not-implemented supplementary services
44     if (analyseString.back() == '#') {
45         TELEPHONY_LOGI("analyseString is end of #");
46         mmiData_.fullString = analyseString;
47         return true;
48     }
49 
50     return false;
51 }
52 
InitMmiCodeFunc(std::map<std::uint64_t,void (CellularCallSupplement::*)(int32_t slotId,const MMIData & mmiData)> & mmiCodeFunc)53 void InitMmiCodeFunc(std::map<std::uint64_t,
54     void (CellularCallSupplement::*)(int32_t slotId, const MMIData &mmiData)> &mmiCodeFunc)
55 {
56     /**
57      * "30" Processing caller ID
58      * "31" Processing calling number display
59      * "21" Deal with unconditional transfer
60      * "61" Handling no answer transfer
61      * "62" Handling no signal transfer
62      * "67" Deal with busy transfer
63      * "002" Process all transfers
64      * "004" Handle transfer under all conditions
65      * "33" Processing limits all outgoing calls
66      * "330" Processing all restrictions
67      * "331" Processing limits all international calls
68      * "332" Handling international outgoing calls belonging to foreign countries when roaming is
69      * restricted
70      * "333" Processing limits outgoing calls
71      * "35" Processing limits all incoming calls
72      * "351" Handle all incoming calls when roaming is restricted
73      * "353" Processing limits incoming calls
74      * "43" Handling call waiting
75      * "04" Change pin password
76      * "05" Use puk unlock sim and change pin password
77      * "042" Change pin2 password
78      * "052" Use puk2 unlock sim and change pin2 password
79      */
80     mmiCodeFunc["30"_hash] = &CellularCallSupplement::HandleClip;
81     mmiCodeFunc["31"_hash] = &CellularCallSupplement::HandleClir;
82     mmiCodeFunc["21"_hash] = &CellularCallSupplement::HandleCallTransfer;
83     mmiCodeFunc["61"_hash] = &CellularCallSupplement::HandleCallTransfer;
84     mmiCodeFunc["62"_hash] = &CellularCallSupplement::HandleCallTransfer;
85     mmiCodeFunc["67"_hash] = &CellularCallSupplement::HandleCallTransfer;
86     mmiCodeFunc["002"_hash] = &CellularCallSupplement::HandleCallTransfer;
87     mmiCodeFunc["004"_hash] = &CellularCallSupplement::HandleCallTransfer;
88     mmiCodeFunc["33"_hash] = &CellularCallSupplement::HandleCallRestriction;
89     mmiCodeFunc["330"_hash] = &CellularCallSupplement::HandleCallRestriction;
90     mmiCodeFunc["331"_hash] = &CellularCallSupplement::HandleCallRestriction;
91     mmiCodeFunc["332"_hash] = &CellularCallSupplement::HandleCallRestriction;
92     mmiCodeFunc["333"_hash] = &CellularCallSupplement::HandleCallRestriction;
93     mmiCodeFunc["35"_hash] = &CellularCallSupplement::HandleCallRestriction;
94     mmiCodeFunc["351"_hash] = &CellularCallSupplement::HandleCallRestriction;
95     mmiCodeFunc["353"_hash] = &CellularCallSupplement::HandleCallRestriction;
96     mmiCodeFunc["43"_hash] = &CellularCallSupplement::HandleCallWaiting;
97     mmiCodeFunc["04"_hash] = &CellularCallSupplement::AlterPinPassword;
98     mmiCodeFunc["05"_hash] = &CellularCallSupplement::UnlockPuk;
99     mmiCodeFunc["042"_hash] = &CellularCallSupplement::AlterPin2Password;
100     mmiCodeFunc["052"_hash] = &CellularCallSupplement::UnlockPuk2;
101 }
102 
InitImsMmiCodeFunc(std::map<std::uint64_t,void (CellularCallSupplement::*)(int32_t slotId,const MMIData & mmiData)> & mmiCodeFunc)103 void InitImsMmiCodeFunc(
104     std::map<std::uint64_t, void (CellularCallSupplement::*)(int32_t slotId, const MMIData &mmiData)> &mmiCodeFunc)
105 {
106     /**
107      * "76" Connected line identification presentation
108      * "77" Connected line identification restriction
109      */
110     mmiCodeFunc["76"_hash] = &CellularCallSupplement::HandleColp;
111     mmiCodeFunc["77"_hash] = &CellularCallSupplement::HandleColr;
112 }
113 
ExecuteMmiCode(int32_t slotId)114 bool MMICodeUtils::ExecuteMmiCode(int32_t slotId)
115 {
116     using MmiCodeFunc = void (CellularCallSupplement::*)(int32_t slotId, const MMIData &mmiData);
117     std::map<std::uint64_t, MmiCodeFunc> mmiCodeFunc;
118     InitMmiCodeFunc(mmiCodeFunc);
119     if (isNeedUseIms_) {
120         InitImsMmiCodeFunc(mmiCodeFunc);
121     }
122 
123     CellularCallSupplement supplement;
124     if (!mmiData_.serviceCode.empty()) {
125         auto serviceCode = StandardizeUtils::Hash_(mmiData_.serviceCode.c_str());
126         // "03" Processing network password
127         if (serviceCode == "03"_hash) {
128             return true;
129         }
130         auto itFunc = mmiCodeFunc.find(serviceCode);
131         if (itFunc != mmiCodeFunc.end()) {
132             auto func = itFunc->second;
133             if (func != nullptr) {
134                 (supplement.*func)(slotId, mmiData_);
135                 return true;
136             }
137         }
138         TELEPHONY_LOGI("Function not found, need check serviceCode.");
139     }
140     if (!mmiData_.fullString.empty()) {
141         TELEPHONY_LOGD("fullString is not empty.");
142         supplement.SendUssd(slotId, mmiData_.fullString);
143         return true;
144     }
145 
146     TELEPHONY_LOGW("default case, need check.");
147     return false;
148 }
149 
RegexMatchMmi(const std::string & analyseString)150 bool MMICodeUtils::RegexMatchMmi(const std::string &analyseString)
151 {
152     std::string symbols =
153         "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)";
154     std::regex pattern(symbols);
155     std::smatch results;
156     if (regex_match(analyseString, results, pattern)) {
157         TELEPHONY_LOGD("regex_match ture");
158 
159         /**
160          * The following sequence of functions shall be used for the control of Supplementary Services:
161          *  SELECT:	Entry of the procedure information (may be a digit or a sequence of characters).
162          *  SEND: Transmission of the information to the network.
163          *  INDICATION:	Call progress indications.
164          */
165         int32_t fullString = 1;
166         int32_t action = 2;
167         // 3GPP TS 22.030 V4.0.0 (2001-03)  6.5.2 Structure of the MMI
168         // This structure consists of the following parts:
169         //     Service Code, SC( (2 or 3 digits)
170         //     Supplementary Information, SI (variable length).
171         int32_t serviceCode = 3;
172         int32_t sia = 5;
173         int32_t sib = 7;
174         int32_t sic = 9;
175         int32_t pwdConfirm = 11;
176         int32_t dialingNumber = 12;
177         mmiData_.fullString = results.str(fullString);
178         mmiData_.actionString = results.str(action);
179         mmiData_.serviceCode = results.str(serviceCode);
180         mmiData_.serviceInfoA = results.str(sia);
181         mmiData_.serviceInfoB = results.str(sib);
182         mmiData_.serviceInfoC = results.str(sic);
183         mmiData_.pwdString = results.str(pwdConfirm);
184         mmiData_.dialString = results.str(dialingNumber);
185 
186         /* 3GPP TS 22.030 V4.0.0 (2001-03)  6.5.2 Structure of the MMI
187          * The procedure always starts with *, #, **, ## or *# and is finished by #.
188          * Each part within the procedure is separated by *.
189          */
190         if (analyseString.back() == '#' && !mmiData_.dialString.empty() && mmiData_.dialString.back() == '#') {
191             mmiData_.fullString = analyseString;
192         }
193         return true;
194     }
195     return false;
196 }
197 
GetMMIData()198 MMIData MMICodeUtils::GetMMIData()
199 {
200     return mmiData_;
201 }
202 } // namespace Telephony
203 } // namespace OHOS
204