Merge from 2.2
[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                 if (pSimStateManagerImpl->__pSimEvent != null)
217                 {
218
219                         _SimEventArg* pEventArg = new (std::nothrow)_SimEventArg(_SIM_EVENT_SIM_STATE_CHANGED, state);
220                         SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
221
222                         (void)pSimStateManagerImpl->__pSimEvent->Fire(*pEventArg);
223                 }
224         }
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
267         if (pSimStateManagerImpl->__pSimManagerEvent != null)
268         {
269                 _SimManagerEventArg* pEventArg = new (std::nothrow)_SimManagerEventArg(_SIM_MANAGER_EVENT_PIN_LOCK_SETTING_RESULT_RECEIVED, isEnabled, r);
270                 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
271
272                 (void)pSimStateManagerImpl->__pSimManagerEvent->Fire(*pEventArg);
273         }
274 }
275
276 result
277 _SimStateManagerImpl::SetSimEventListener(ITelephonySimEventListener *pListener)
278 {
279         result r = E_SUCCESS;
280
281         if (__pSimEventListener != null)
282         {
283                 __pSimEvent->RemoveListener(*__pSimEventListener);
284                 __pSimEventListener = null;
285         }
286
287         if (__pSimEvent == null && pListener != null)
288         {
289                 std::unique_ptr<_SimEvent> pSimEvent(new (std::nothrow) _SimEvent());
290                 SysTryReturnResult(NID_TEL, pSimEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
291
292                 r = pSimEvent->Construct();
293                 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
294
295                 __pSimEvent = move(pSimEvent);
296         }
297
298         if (pListener != null)
299         {
300                 r = __pSimEvent->AddListener(*pListener, true);
301
302                 if (r == E_SUCCESS)
303                 {
304                         __pSimEventListener = pListener;
305                 }
306         }
307
308         if (r != E_SUCCESS)
309         {
310                 __pSimEvent.reset(null);
311                 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
312         }
313
314         return r;
315 }
316
317 result
318 _SimStateManagerImpl::SetSimStateManagerGetPinLockSettingResultListener(ISimStateManagerGetPinLockSettingResultListener *pListener)
319 {
320         result r = E_SUCCESS;
321
322         if (__pSimStateManagerGetPinLockSettingResultListener != null)
323         {
324                 __pSimManagerEvent->RemoveListener(*__pSimStateManagerGetPinLockSettingResultListener);
325                 __pSimStateManagerGetPinLockSettingResultListener = null;
326         }
327
328         if (__pSimManagerEvent == null && pListener != null)
329         {
330                 std::unique_ptr<_SimManagerEvent> pSimManagerEvent(new (std::nothrow) _SimManagerEvent());
331                 SysTryReturnResult(NID_TEL, pSimManagerEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
332
333                 r = pSimManagerEvent->Construct();
334                 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
335
336                 __pSimManagerEvent = move(pSimManagerEvent);
337         }
338
339         if (pListener != null)
340         {
341                 r = __pSimManagerEvent->AddListener(*pListener, true);
342                 if (r == E_SUCCESS)
343                 {
344                         __pSimStateManagerGetPinLockSettingResultListener = pListener;
345                 }
346         }
347
348         if (r != E_SUCCESS)
349         {
350                 __pSimManagerEvent.reset(null);
351                 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
352         }
353
354         return r;
355 }
356
357 SimState
358 _SimStateManagerImpl::GetSimState(void) const
359 {
360         ClearLastResult();
361
362         return __simState;
363 }
364
365 result
366 _SimStateManagerImpl::GetPinLockSetting(ISimStateManagerGetPinLockSettingResultListener* pListener)
367 {
368         result r = E_SUCCESS;
369         int ret;
370
371         SysTryReturnResult(NID_TEL, pListener != null, E_INVALID_ARG, "The specified input parameter is invalid.");
372         SysTryReturnResult(NID_TEL, !__isInProgress, E_IN_PROGRESS, "The previous request is in progress.");
373
374         r = SetSimStateManagerGetPinLockSettingResultListener(pListener);
375         SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to set listener.");
376
377         ret = tel_get_sim_facility(__pHandle, TAPI_SIM_LOCK_SC, OnGetPinLockSettingCallback, this);
378
379         SysTryReturnResult(NID_TEL, ret != TAPI_API_SIM_NOT_FOUND, E_DEVICE_UNAVAILABLE,
380                         "The operation failed due to a missing SIM card.");
381
382         SysTryReturnResult(NID_TEL, ret == TAPI_API_SUCCESS || ret == TAPI_API_SIM_NOT_FOUND, E_SYSTEM,
383                         "A system error has occurred. Failed to get SIM facility.");
384
385         __isInProgress = true;
386
387         return r;
388 }
389
390 result
391 _SimStateManagerImpl::GetSimInfo(SimInfo& simInfo) const
392 {
393         SysAssertf(__pHandle != null, "Not yet constructed. Construct() should be called before use.");
394
395         result r = E_SUCCESS;
396
397         _SimInfoImpl* pSimInfoImpl = _SimInfoImpl::GetInstance(simInfo);
398         if (pSimInfoImpl == null)
399         {
400                 r = simInfo.Construct();
401         }
402         else
403         {
404                 r = pSimInfoImpl->Construct();
405         }
406
407         SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_DEVICE_UNAVAILABLE, "The operation failed due to a missing SIM card.");
408
409         return r;
410 }
411
412 _SimStateManagerImpl*
413 _SimStateManagerImpl::GetInstance(SimStateManager& simStateManager)
414 {
415         return simStateManager.__pSimStateManagerImpl;
416 }
417
418 const _SimStateManagerImpl*
419 _SimStateManagerImpl::GetInstance(const SimStateManager& simStateManager)
420 {
421         return simStateManager.__pSimStateManagerImpl;
422 }
423
424 }} // Tizen::Telephony