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 #ifndef OHOS_SIM_DIALLING_NUMBERS_HANDLER_H
17 #define OHOS_SIM_DIALLING_NUMBERS_HANDLER_H
18 
19 #include <thread>
20 #include <unordered_map>
21 
22 #include "dialling_numbers_info.h"
23 #include "icc_file_controller.h"
24 #include "sim_data_type.h"
25 #include "sim_number_decode.h"
26 #include "sim_utils.h"
27 #include "tel_event_handler.h"
28 
29 namespace OHOS {
30 namespace Telephony {
31 enum {
32     MSG_SIM_OBTAIN_ADN_DONE = 1,
33     MSG_SIM_OBTAIN_ALL_ADN_DONE = 2,
34     MSG_SIM_OBTAIN_LINEAR_FILE_SIZE_DONE = 3,
35     MSG_SIM_RENEW_ADN_DONE = 4
36 };
37 
38 enum {
39     // 3gpp ts51.011 10.5.1
40     BCD_NUMBER_BYTES = 0,
41     TON_NPI_NUMBER = 1,
42     DIALING_NUMBERS_BEGIN = 2,
43     DIALING_NUMBERS_END = 11,
44     MORE_FILE_ID = 12,
45     EXTRA_FILE_ID = 13
46 };
47 
48 enum {
49     MORE_FILE_TYPE_DATA = 0x02,
50     MORE_FILE_FLAG = 0x03,
51     MAX_MORE_PARTY_LENGTH = 0xa
52 };
53 
54 struct DiallingNumberLoadRequest {
55 public:
DiallingNumberLoadRequestDiallingNumberLoadRequest56     DiallingNumberLoadRequest(int serialId, int fileId, int exId, int indexNum, const std::string &pin2Str,
57         const AppExecFwk::InnerEvent::Pointer &pointer) : elementaryFileId(fileId), extFileId(exId),
58         pin2(pin2Str), index(indexNum), loadId(serialId)
59     {
60         callPointer = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(pointer));
61     }
SetResultDiallingNumberLoadRequest62     void SetResult(std::shared_ptr<void> result)
63     {
64         this->result = result;
65     }
GetResultDiallingNumberLoadRequest66     std::shared_ptr<void> GetResult()
67     {
68         return this->result;
69     }
70 
SetExceptionDiallingNumberLoadRequest71     void SetException(std::shared_ptr<void> exception)
72     {
73         this->exception = exception;
74     }
75 
GetExceptionDiallingNumberLoadRequest76     std::shared_ptr<void> GetException()
77     {
78         return this->exception;
79     }
80 
SetElementaryFileIdDiallingNumberLoadRequest81     void SetElementaryFileId(int id)
82     {
83         this->elementaryFileId = id;
84     }
85 
GetElementaryFileIdDiallingNumberLoadRequest86     int GetElementaryFileId()
87     {
88         return this->elementaryFileId;
89     }
90 
SetExEFDiallingNumberLoadRequest91     void SetExEF(int ef)
92     {
93         this->extFileId = ef;
94     }
95 
GetExEFDiallingNumberLoadRequest96     int GetExEF()
97     {
98         return this->extFileId;
99     }
100 
SetIndexDiallingNumberLoadRequest101     void SetIndex(int index)
102     {
103         this->index = index;
104     }
105 
GetIndexDiallingNumberLoadRequest106     int GetIndex()
107     {
108         return this->index;
109     }
110 
SetPin2DiallingNumberLoadRequest111     void SetPin2(std::string pin2Code)
112     {
113         this->pin2 = pin2Code;
114     }
115 
GetPin2DiallingNumberLoadRequest116     std::string GetPin2()
117     {
118         return this->pin2;
119     }
120 
SetIsDeleteDiallingNumberLoadRequest121     void SetIsDelete(bool del)
122     {
123         this->isDelete = del;
124     }
125 
GetIsDeleteDiallingNumberLoadRequest126     bool GetIsDelete()
127     {
128         return this->isDelete;
129     }
130 
SetLoadIdDiallingNumberLoadRequest131     void SetLoadId(int id)
132     {
133         this->loadId = id;
134     }
135 
GetLoadIdDiallingNumberLoadRequest136     int GetLoadId()
137     {
138         return this->loadId;
139     }
GetCallerDiallingNumberLoadRequest140     AppExecFwk::InnerEvent::Pointer &GetCaller()
141     {
142         return callPointer;
143     }
HasCountDiallingNumberLoadRequest144     bool HasCount()
145     {
146         return moreFileToGet != 0;
147     }
InitCountDiallingNumberLoadRequest148     void InitCount()
149     {
150         moreFileToGet = INIT_COUNT;
151     }
CountUpDiallingNumberLoadRequest152     void CountUp()
153     {
154         ++moreFileToGet;
155     }
CountDownDiallingNumberLoadRequest156     void CountDown()
157     {
158         --moreFileToGet;
159     }
ClearCountDiallingNumberLoadRequest160     void ClearCount()
161     {
162         moreFileToGet = 0;
163     }
164 
165 private:
166     int elementaryFileId = 0;
167     int extFileId = 0;
168     int moreFileToGet = 0;
169     std::string pin2 = "";
170     int index = 0;
171     int loadId = 0;
172     bool isDelete = false;
173     std::shared_ptr<void> result = nullptr;
174     std::shared_ptr<void> exception = nullptr;
175     AppExecFwk::InnerEvent::Pointer &callPointer = nullptr_;
176     AppExecFwk::InnerEvent::Pointer nullptr_ = AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
177     const int INIT_COUNT = 1;
178 };
179 struct DiallingNumberUpdateInfor {
180     std::shared_ptr<DiallingNumbersInfo> diallingNumber = nullptr;
181     int index = 0;
182     int fileId = 0;
183     int extFile = 0;
184     std::string pin2 = "";
185     bool isDel = false;
186 };
187 class IccDiallingNumbersHandler : public TelEventHandler {
188 public:
189     explicit IccDiallingNumbersHandler(std::shared_ptr<IccFileController> fh);
190     ~IccDiallingNumbersHandler();
191     void GetDiallingNumbers(int ef, int extensionEF, int recordNumber, AppExecFwk::InnerEvent::Pointer &response);
192     void GetAllDiallingNumbers(int ef, int extensionEF, AppExecFwk::InnerEvent::Pointer &response);
193     void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event);
194     void UpdateDiallingNumbers(const DiallingNumberUpdateInfor &infor, AppExecFwk::InnerEvent::Pointer &response);
GetNextSerialId()195     static int GetNextSerialId()
196     {
197         return nextSerialId_++;
198     }
199     static std::atomic_int nextSerialId_;
200     static std::unordered_map<int, std::shared_ptr<DiallingNumberLoadRequest>> requestMap_;
201     static std::shared_ptr<DiallingNumberLoadRequest> FindLoadRequest(int serial);
202     static void ClearLoadRequest(int serial);
203     static std::shared_ptr<DiallingNumberLoadRequest> CreateLoadRequest(int fileId,
204         int exId, int indexNum, const std::string &pin2Str, const AppExecFwk::InnerEvent::Pointer &result);
205     void UpdateFileController(const std::shared_ptr<IccFileController> &fileController);
206 
207 protected:
208     std::shared_ptr<IccFileController> fileController_;
209     std::string GetFilePath(int elementaryFileId);
210     // 3GPP TS 51.011 V4.1.0 section 10.7 files of gsm
211     const std::string MASTER_FILE_SIM = "3F00";
212     const std::string DEDICATED_FILE_TELECOM = "7F10";
213 
214 private:
215     using ProcessFunc = std::function<void(const AppExecFwk::InnerEvent::Pointer &event, int &id)>;
216     std::map<int, ProcessFunc> memberFuncMap_;
217     AppExecFwk::InnerEvent::Pointer BuildCallerInfo(int eventId, int loadId);
218     AppExecFwk::InnerEvent::Pointer BuildCallerInfo(int eventId, std::shared_ptr<void> pobj, int loadId);
219     void ProcessDiallingNumberAllLoadDone(const AppExecFwk::InnerEvent::Pointer &event, int &id);
220     void ProcessDiallingNumber(const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest,
221         const std::shared_ptr<MultiRecordResult> &object);
222     void ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer &event, int &id);
223     void ProcessLinearSizeDone(const AppExecFwk::InnerEvent::Pointer &event, int &id);
224     void ProcessUpdateRecordDone(const AppExecFwk::InnerEvent::Pointer &event, int &id);
225     bool SendBackResult(int loadId);
226     void FetchDiallingNumberContent(
227         const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, const std::string &recordData);
228     std::shared_ptr<unsigned char> CreateSavingSequence(
229         const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, int dataLength);
230     std::shared_ptr<unsigned char> CreateNameSequence(const std::u16string &name, int &seqLength);
231     std::shared_ptr<RadioResponseInfo> MakeExceptionResult(int code);
232     void FillNumberFiledForDiallingNumber(
233         std::shared_ptr<unsigned char> diallingNumber, const std::string &number, int dataLength);
234     bool FormatNameAndNumber(std::shared_ptr<DiallingNumbersInfo> &diallingNumber, bool isDel);
235     void SendUpdateCommand(const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, int length,
236         const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest, int loadId);
237     void InitFuncMap();
238     const int RECORD_LENGTH = 28;
239     const int LENGTH_RATE = 2;
240     const int INVALID_LENGTH = 49;
241     const static int32_t PRE_BYTES_NUM = 14;
242     const static int32_t MAX_NUMBER_SIZE_BYTES = 11;
243     const static int32_t EXT_FILE_BITYES_NUM = 13;
244 };
245 } // namespace Telephony
246 } // namespace OHOS
247 
248 #endif // OHOS_SIM_DIALLING_NUMBERS_HANDLER_H
249