merge with master
[platform/framework/native/telephony.git] / src / FTel_SimStateManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file        FTel_SimStateManagerImpl.cpp
19  * @brief       This is the implementation file for _SimStateManagerImpl class.
20  */
21
22 // Todo: Remove unnecessary headers
23 #include <stdlib.h>
24 #include <string.h>
25 #include <tapi_event.h>
26 #include <tapi_common.h>
27 #include <sim.h>
28 #include <ITapiSim.h>
29 #include <TelSim.h>
30 #include <TapiUtility.h>
31
32 #include <unique_ptr.h>
33 #include <FTelITelephonySimEventListener.h>
34 #include <FTelISimStateManagerGetPinLockSettingResultListener.h>
35 #include <FTelSimStateManager.h>
36 #include <FBaseUtilStringUtil.h>
37 #include <FBaseString.h>
38 #include <FBaseResult.h>
39 #include <FBaseSysLog.h>
40
41 #include "FTel_SimInfoImpl.h"
42 #include "FTel_SimStateManagerImpl.h"
43
44 #include "FTel_SimEvent.h"
45 #include "FTel_SimEventArg.h"
46 #include "FTel_SimManagerEvent.h"
47 #include "FTel_SimManagerEventArg.h"
48 #include "FTel_TelephonyIpcProxy.h"
49 #include "FTel_TelephonyUtility.h"
50
51 using namespace std;
52 using namespace Tizen::System;
53 using namespace Tizen::App;
54 using namespace Tizen::Base;
55 using namespace Tizen::Base::Utility;
56 using namespace Tizen::Base::Collection;
57
58
59 namespace Tizen { namespace Telephony
60 {
61
62 _SimStateManagerImpl::_SimStateManagerImpl(void)
63         : __pHandle(null)
64         , __simState(SIM_STATE_UNKNOWN)
65         , __isInProgress(false)
66         , __pSimEvent(null)
67         , __pSimManagerEvent(null)
68         , __pSimEventListener(null)
69         , __pSimStateManagerGetPinLockSettingResultListener(null)
70 {
71 }
72
73 _SimStateManagerImpl::~_SimStateManagerImpl(void)
74 {
75         if (__pHandle != null)
76         {
77                 tel_deregister_noti_event(__pHandle, TAPI_NOTI_SIM_STATUS);
78                 tel_deinit(__pHandle);
79         }
80 }
81
82 result
83 _SimStateManagerImpl::Construct()
84 {
85         result r = E_SUCCESS;
86         int err = TAPI_API_SUCCESS;
87         TelSimCardStatus_t initStatus = TAPI_SIM_STATUS_UNKNOWN;
88         int cardChanged = 0;
89
90         SysAssertf(__pHandle == null,
91                         "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
92
93         __pHandle = tel_init(null);
94         SysTryReturnResult(NID_TEL, __pHandle != null, E_SYSTEM,
95                         "[%s] A system error has occurred. Failed to initialize TApi library.", GetErrorMessage(E_SYSTEM));
96
97         err = tel_register_noti_event(__pHandle, TAPI_NOTI_SIM_STATUS, OnSimStateChangedCallback, this);
98         SysTryCatch(NID_TEL, err == TAPI_API_SUCCESS, r = E_SYSTEM, E_SYSTEM,
99                         "[%s] A system error has occurred. Failed to register the callback function.", GetErrorMessage(E_SYSTEM));
100
101         err = tel_get_sim_init_info(__pHandle, &initStatus, &cardChanged);
102         SysLog(NID_TEL, "Initial state of SIM card is [%d:%d]", initStatus, cardChanged);
103         SysTryCatch(NID_TEL, err == TAPI_API_SUCCESS, r = E_SYSTEM, E_SYSTEM,
104                         "[%s] A system error has occurred. Failed to get initial state of SIM.", GetErrorMessage(E_SYSTEM));
105
106         switch (initStatus)
107         {
108                 case TAPI_SIM_STATUS_CARD_NOT_PRESENT:                  // fall through
109                 case TAPI_SIM_STATUS_CARD_REMOVED:
110                         __simState = SIM_STATE_ABSENT;
111                         break;
112
113                 case TAPI_SIM_STATUS_SIM_INITIALIZING:
114                         __simState = SIM_STATE_INITIALIZING;
115                         break;
116
117                 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
118                         __simState = SIM_STATE_READY;
119                         break;
120
121                 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
122                         __simState = SIM_STATE_PIN_REQUIRED;
123                         break;
124
125                 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
126                         __simState = SIM_STATE_PUK_REQUIRED;
127                         break;
128
129                 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:                  // fall through
130                 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:                 // fall through
131                 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:                 // fall through
132                 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
133                         __simState = SIM_STATE_NETWORK_LOCKED;
134                         break;
135
136                 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
137                         __simState = SIM_STATE_SIM_LOCKED;
138                         break;
139
140                 case TAPI_SIM_STATUS_CARD_ERROR:                                // fall through
141                 case TAPI_SIM_STATUS_CARD_BLOCKED:                              // fall through
142                 case TAPI_SIM_STATUS_UNKNOWN:                                   // fall through
143                 default :
144                         __simState = SIM_STATE_UNKNOWN;
145                         break;
146         } // switch
147
148         return r;
149
150 CATCH:
151         if (__pHandle != null)
152         {
153                 tel_deinit(__pHandle);
154                 __pHandle = null;
155         }
156
157         return r;
158 }
159
160 void
161 _SimStateManagerImpl::OnSimStateChangedCallback(TapiHandle* pHandle, const char* pNotiId, void* pData, void* pUserData)
162 {
163         SysLog(NID_TEL, "Enter");               // Todo: Remove temporary log
164
165         TelSimCardStatus_t* status = (TelSimCardStatus_t*)pData;
166         SysLog(NID_TEL, "TelSimCardStatus: [%d]", *status);
167
168         _SimStateManagerImpl* pSimStateManagerImpl = static_cast<_SimStateManagerImpl*>(pUserData);
169
170         SimState state = SIM_STATE_UNKNOWN;
171
172         switch (*status)
173         {
174                 case TAPI_SIM_STATUS_CARD_NOT_PRESENT:                  // fall through
175                 case TAPI_SIM_STATUS_CARD_REMOVED:
176                         state = SIM_STATE_ABSENT;
177                         break;
178
179                 case TAPI_SIM_STATUS_SIM_INITIALIZING:
180                         state = SIM_STATE_INITIALIZING;
181                         break;
182
183                 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
184                         state = SIM_STATE_READY;
185                         break;
186
187                 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
188                         state = SIM_STATE_PIN_REQUIRED;
189                         break;
190
191                 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
192                         state = SIM_STATE_PUK_REQUIRED;
193                         break;
194
195                 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:                  // fall through
196                 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:                 // fall through
197                 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:                 // fall through
198                 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
199                         state = SIM_STATE_NETWORK_LOCKED;
200                         break;
201
202                 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
203                         state = SIM_STATE_SIM_LOCKED;
204                         break;
205
206                 case TAPI_SIM_STATUS_CARD_ERROR:                                // fall through
207                 case TAPI_SIM_STATUS_CARD_BLOCKED:                              // fall through
208                 case TAPI_SIM_STATUS_UNKNOWN:                                   // fall through
209                 default :
210                         state = SIM_STATE_UNKNOWN;
211                         break;
212         } // switch
213
214         if (pSimStateManagerImpl->__simState != state)
215         {
216                 pSimStateManagerImpl->__simState = state;
217
218                 _SimEventArg* pEventArg = new (std::nothrow)_SimEventArg(_SIM_EVENT_SIM_STATE_CHANGED, state);
219                 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
220
221                 (void)pSimStateManagerImpl->__pSimEvent->Fire(*pEventArg);
222         }
223
224         SysLog(NID_TEL, "Exit");                // Todo: Remove temporary log
225 }
226
227 void
228 _SimStateManagerImpl::OnGetPinLockSettingCallback(TapiHandle* pHandle, int ret, void* pData, void* pUserData)
229 {
230         result r = E_SUCCESS;
231         bool isEnabled = false;
232
233         TelSimPinOperationResult_t err = (TelSimPinOperationResult_t)ret;
234         SysLog(NID_TEL, "The result of PIN operation is [%d]", err);
235
236         if (err != TAPI_SIM_PIN_OPERATION_SUCCESS)
237         {
238                 r = E_INVALID_STATE;
239         }
240         else
241         {
242                 TelSimFacilityInfo_t* pFacilityInfo = (TelSimFacilityInfo_t*)pData;
243
244                 TelSimLockType_t lockType = pFacilityInfo->type;
245                 TelSimFacilityStatus_t facilityStatus = pFacilityInfo->f_status;
246                 SysLog(NID_TEL, "Lock type is [%d], and facility status is [%d].", lockType, facilityStatus);
247
248                 if (lockType == TAPI_SIM_LOCK_SC && facilityStatus == TAPI_SIM_FACILITY_DISABLED)
249                 {
250                         isEnabled = false;
251                 }
252                 else if (lockType == TAPI_SIM_LOCK_SC && facilityStatus == TAPI_SIM_FACILITY_ENABLED)
253                 {
254                         isEnabled = true;
255                 }
256                 else if (lockType != TAPI_SIM_LOCK_SC || facilityStatus == TAPI_SIM_FACILITY_UNKNOWN)
257                 {
258                         r = E_INVALID_STATE;
259                         isEnabled = false;
260                 }
261         }
262
263         _SimStateManagerImpl* pSimStateManagerImpl = static_cast<_SimStateManagerImpl*>(pUserData);
264         pSimStateManagerImpl->__isInProgress = false;
265
266         _SimManagerEventArg* pEventArg = new (std::nothrow)_SimManagerEventArg(_SIM_MANAGER_EVENT_PIN_LOCK_SETTING_RESULT_RECEIVED, isEnabled, r);
267         SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
268
269         (void)pSimStateManagerImpl->__pSimManagerEvent->Fire(*pEventArg);
270
271         SysLog(NID_TEL, "Exit");                // Todo: Remove temporary log
272 }
273
274 result
275 _SimStateManagerImpl::SetSimEventListener(ITelephonySimEventListener *pListener)
276 {
277         result r = E_SUCCESS;
278
279         if (__pSimEventListener != null)
280         {
281                 __pSimEvent->RemoveListener(*__pSimEventListener);
282                 __pSimEventListener = null;
283         }
284
285         if (__pSimEvent == null && pListener != null)
286         {
287                 std::unique_ptr<_SimEvent> pSimEvent(new (std::nothrow) _SimEvent());
288                 SysTryReturnResult(NID_TEL, pSimEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
289
290                 r = pSimEvent->Construct();
291                 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
292
293                 __pSimEvent = move(pSimEvent);
294         }
295
296         if (pListener != null)
297         {
298                 r = __pSimEvent->AddListener(*pListener, true);
299
300                 if (r == E_SUCCESS)
301                 {
302                         __pSimEventListener = pListener;
303                 }
304         }
305
306         if (r != E_SUCCESS)
307         {
308                 __pSimEvent.reset(null);
309                 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
310         }
311
312         return r;
313 }
314
315 result
316 _SimStateManagerImpl::SetSimStateManagerGetPinLockSettingResultListener(ISimStateManagerGetPinLockSettingResultListener *pListener)
317 {
318         result r = E_SUCCESS;
319
320         if (__pSimStateManagerGetPinLockSettingResultListener != null)
321         {
322                 __pSimManagerEvent->RemoveListener(*__pSimStateManagerGetPinLockSettingResultListener);
323                 __pSimStateManagerGetPinLockSettingResultListener = null;
324         }
325
326         if (__pSimManagerEvent == null && pListener != null)
327         {
328                 std::unique_ptr<_SimManagerEvent> pSimManagerEvent(new (std::nothrow) _SimManagerEvent());
329                 SysTryReturnResult(NID_TEL, pSimManagerEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
330
331                 r = pSimManagerEvent->Construct();
332                 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
333
334                 __pSimManagerEvent = move(pSimManagerEvent);
335         }
336
337         if (pListener != null)
338         {
339                 r = __pSimManagerEvent->AddListener(*pListener, true);
340                 if (r == E_SUCCESS)
341                 {
342                         __pSimStateManagerGetPinLockSettingResultListener = pListener;
343                 }
344         }
345
346         if (r != E_SUCCESS)
347         {
348                 __pSimManagerEvent.reset(null);
349                 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
350         }
351
352         return r;
353 }
354
355 SimState
356 _SimStateManagerImpl::GetSimState(void) const
357 {
358         return __simState;
359 }
360
361 result
362 _SimStateManagerImpl::GetPinLockSetting(ISimStateManagerGetPinLockSettingResultListener* pListener)
363 {
364         result r = E_SUCCESS;
365         int ret;
366
367         SysTryReturnResult(NID_TEL, pListener != null, E_INVALID_ARG, "The specified input parameter is invalid.");
368         SysTryReturnResult(NID_TEL, !__isInProgress, E_IN_PROGRESS, "The previous request is in progress.");
369
370         r = SetSimStateManagerGetPinLockSettingResultListener(pListener);
371         SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to set listener.");
372
373         ret = tel_get_sim_facility(__pHandle, TAPI_SIM_LOCK_SC, OnGetPinLockSettingCallback, this);
374
375         SysTryReturnResult(NID_TEL, ret != TAPI_API_SIM_NOT_FOUND, E_DEVICE_UNAVAILABLE,
376                         "The operation failed due to a missing SIM card.");
377
378         SysTryReturnResult(NID_TEL, ret == TAPI_API_SUCCESS || ret == TAPI_API_SIM_NOT_FOUND, E_SYSTEM,
379                         "A system error has occurred. Failed to get SIM facility.");
380
381         __isInProgress = true;
382
383         return r;
384 }
385
386 result
387 _SimStateManagerImpl::GetSimInfo(SimInfo& simInfo) const
388 {
389         SysAssertf(__pHandle != null, "Not yet constructed. Construct() should be called before use.");
390
391         result r = E_SUCCESS;
392
393         _SimInfoImpl* pSimInfoImpl = _SimInfoImpl::GetInstance(simInfo);
394         if (pSimInfoImpl == null)
395         {
396                 r = simInfo.Construct();
397         }
398         else
399         {
400                 r = pSimInfoImpl->Construct();
401         }
402
403         SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to construct SimInfo.");
404
405         return r;
406 }
407
408 _SimStateManagerImpl*
409 _SimStateManagerImpl::GetInstance(SimStateManager& simStateManager)
410 {
411         return simStateManager.__pSimStateManagerImpl;
412 }
413
414 const _SimStateManagerImpl*
415 _SimStateManagerImpl::GetInstance(const SimStateManager& simStateManager)
416 {
417         return simStateManager.__pSimStateManagerImpl;
418 }
419
420 }} // Tizen::Telephony