Synchronized tizen_2.1 branch 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         TelSimCardStatus_t* status = (TelSimCardStatus_t*)pData;
164         SysLog(NID_TEL, "TelSimCardStatus: [%d]", *status);
165
166         _SimStateManagerImpl* pSimStateManagerImpl = static_cast<_SimStateManagerImpl*>(pUserData);
167
168         SimState state = SIM_STATE_UNKNOWN;
169
170         switch (*status)
171         {
172                 case TAPI_SIM_STATUS_CARD_NOT_PRESENT:                  // fall through
173                 case TAPI_SIM_STATUS_CARD_REMOVED:
174                         state = SIM_STATE_ABSENT;
175                         break;
176
177                 case TAPI_SIM_STATUS_SIM_INITIALIZING:
178                         state = SIM_STATE_INITIALIZING;
179                         break;
180
181                 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
182                         state = SIM_STATE_READY;
183                         break;
184
185                 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
186                         state = SIM_STATE_PIN_REQUIRED;
187                         break;
188
189                 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
190                         state = SIM_STATE_PUK_REQUIRED;
191                         break;
192
193                 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:                  // fall through
194                 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:                 // fall through
195                 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:                 // fall through
196                 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
197                         state = SIM_STATE_NETWORK_LOCKED;
198                         break;
199
200                 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
201                         state = SIM_STATE_SIM_LOCKED;
202                         break;
203
204                 case TAPI_SIM_STATUS_CARD_ERROR:                                // fall through
205                 case TAPI_SIM_STATUS_CARD_BLOCKED:                              // fall through
206                 case TAPI_SIM_STATUS_UNKNOWN:                                   // fall through
207                 default :
208                         state = SIM_STATE_UNKNOWN;
209                         break;
210         } // switch
211
212         if (pSimStateManagerImpl->__simState != state)
213         {
214                 pSimStateManagerImpl->__simState = state;
215
216                 _SimEventArg* pEventArg = new (std::nothrow)_SimEventArg(_SIM_EVENT_SIM_STATE_CHANGED, state);
217                 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
218
219                 (void)pSimStateManagerImpl->__pSimEvent->Fire(*pEventArg);
220         }
221 }
222
223 void
224 _SimStateManagerImpl::OnGetPinLockSettingCallback(TapiHandle* pHandle, int ret, void* pData, void* pUserData)
225 {
226         result r = E_SUCCESS;
227         bool isEnabled = false;
228
229         TelSimPinOperationResult_t err = (TelSimPinOperationResult_t)ret;
230         SysLog(NID_TEL, "The result of PIN operation is [%d]", err);
231
232         if (err != TAPI_SIM_PIN_OPERATION_SUCCESS)
233         {
234                 r = E_INVALID_STATE;
235         }
236         else
237         {
238                 TelSimFacilityInfo_t* pFacilityInfo = (TelSimFacilityInfo_t*)pData;
239
240                 TelSimLockType_t lockType = pFacilityInfo->type;
241                 TelSimFacilityStatus_t facilityStatus = pFacilityInfo->f_status;
242                 SysLog(NID_TEL, "Lock type is [%d], and facility status is [%d].", lockType, facilityStatus);
243
244                 if (lockType == TAPI_SIM_LOCK_SC && facilityStatus == TAPI_SIM_FACILITY_DISABLED)
245                 {
246                         isEnabled = false;
247                 }
248                 else if (lockType == TAPI_SIM_LOCK_SC && facilityStatus == TAPI_SIM_FACILITY_ENABLED)
249                 {
250                         isEnabled = true;
251                 }
252                 else if (lockType != TAPI_SIM_LOCK_SC || facilityStatus == TAPI_SIM_FACILITY_UNKNOWN)
253                 {
254                         r = E_INVALID_STATE;
255                         isEnabled = false;
256                 }
257         }
258
259         _SimStateManagerImpl* pSimStateManagerImpl = static_cast<_SimStateManagerImpl*>(pUserData);
260         pSimStateManagerImpl->__isInProgress = false;
261
262         _SimManagerEventArg* pEventArg = new (std::nothrow)_SimManagerEventArg(_SIM_MANAGER_EVENT_PIN_LOCK_SETTING_RESULT_RECEIVED, isEnabled, r);
263         SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
264
265         (void)pSimStateManagerImpl->__pSimManagerEvent->Fire(*pEventArg);
266 }
267
268 result
269 _SimStateManagerImpl::SetSimEventListener(ITelephonySimEventListener *pListener)
270 {
271         result r = E_SUCCESS;
272
273         if (__pSimEventListener != null)
274         {
275                 __pSimEvent->RemoveListener(*__pSimEventListener);
276                 __pSimEventListener = null;
277         }
278
279         if (__pSimEvent == null && pListener != null)
280         {
281                 std::unique_ptr<_SimEvent> pSimEvent(new (std::nothrow) _SimEvent());
282                 SysTryReturnResult(NID_TEL, pSimEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
283
284                 r = pSimEvent->Construct();
285                 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
286
287                 __pSimEvent = move(pSimEvent);
288         }
289
290         if (pListener != null)
291         {
292                 r = __pSimEvent->AddListener(*pListener, true);
293
294                 if (r == E_SUCCESS)
295                 {
296                         __pSimEventListener = pListener;
297                 }
298         }
299
300         if (r != E_SUCCESS)
301         {
302                 __pSimEvent.reset(null);
303                 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
304         }
305
306         return r;
307 }
308
309 result
310 _SimStateManagerImpl::SetSimStateManagerGetPinLockSettingResultListener(ISimStateManagerGetPinLockSettingResultListener *pListener)
311 {
312         result r = E_SUCCESS;
313
314         if (__pSimStateManagerGetPinLockSettingResultListener != null)
315         {
316                 __pSimManagerEvent->RemoveListener(*__pSimStateManagerGetPinLockSettingResultListener);
317                 __pSimStateManagerGetPinLockSettingResultListener = null;
318         }
319
320         if (__pSimManagerEvent == null && pListener != null)
321         {
322                 std::unique_ptr<_SimManagerEvent> pSimManagerEvent(new (std::nothrow) _SimManagerEvent());
323                 SysTryReturnResult(NID_TEL, pSimManagerEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
324
325                 r = pSimManagerEvent->Construct();
326                 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
327
328                 __pSimManagerEvent = move(pSimManagerEvent);
329         }
330
331         if (pListener != null)
332         {
333                 r = __pSimManagerEvent->AddListener(*pListener, true);
334                 if (r == E_SUCCESS)
335                 {
336                         __pSimStateManagerGetPinLockSettingResultListener = pListener;
337                 }
338         }
339
340         if (r != E_SUCCESS)
341         {
342                 __pSimManagerEvent.reset(null);
343                 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
344         }
345
346         return r;
347 }
348
349 SimState
350 _SimStateManagerImpl::GetSimState(void) const
351 {
352         return __simState;
353 }
354
355 result
356 _SimStateManagerImpl::GetPinLockSetting(ISimStateManagerGetPinLockSettingResultListener* pListener)
357 {
358         result r = E_SUCCESS;
359         int ret;
360
361         SysTryReturnResult(NID_TEL, pListener != null, E_INVALID_ARG, "The specified input parameter is invalid.");
362         SysTryReturnResult(NID_TEL, !__isInProgress, E_IN_PROGRESS, "The previous request is in progress.");
363
364         r = SetSimStateManagerGetPinLockSettingResultListener(pListener);
365         SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to set listener.");
366
367         ret = tel_get_sim_facility(__pHandle, TAPI_SIM_LOCK_SC, OnGetPinLockSettingCallback, this);
368
369         SysTryReturnResult(NID_TEL, ret != TAPI_API_SIM_NOT_FOUND, E_DEVICE_UNAVAILABLE,
370                         "The operation failed due to a missing SIM card.");
371
372         SysTryReturnResult(NID_TEL, ret == TAPI_API_SUCCESS || ret == TAPI_API_SIM_NOT_FOUND, E_SYSTEM,
373                         "A system error has occurred. Failed to get SIM facility.");
374
375         __isInProgress = true;
376
377         return r;
378 }
379
380 result
381 _SimStateManagerImpl::GetSimInfo(SimInfo& simInfo) const
382 {
383         SysAssertf(__pHandle != null, "Not yet constructed. Construct() should be called before use.");
384
385         result r = E_SUCCESS;
386
387         _SimInfoImpl* pSimInfoImpl = _SimInfoImpl::GetInstance(simInfo);
388         if (pSimInfoImpl == null)
389         {
390                 r = simInfo.Construct();
391         }
392         else
393         {
394                 r = pSimInfoImpl->Construct();
395         }
396
397         SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to construct SimInfo.");
398
399         return r;
400 }
401
402 _SimStateManagerImpl*
403 _SimStateManagerImpl::GetInstance(SimStateManager& simStateManager)
404 {
405         return simStateManager.__pSimStateManagerImpl;
406 }
407
408 const _SimStateManagerImpl*
409 _SimStateManagerImpl::GetInstance(const SimStateManager& simStateManager)
410 {
411         return simStateManager.__pSimStateManagerImpl;
412 }
413
414 }} // Tizen::Telephony