Remove memory leak in CAPI
[framework/api/sim.git] / src / sim.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sim.h>
18 #include <tapi_common.h>
19 #include <TapiUtility.h>
20 #include <ITapiSim.h>
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <dlog.h>
26
27 #include <glib.h>
28 #include <glib-object.h>
29 #include <gio/gio.h>
30
31 #ifdef LOG_TAG
32 #undef LOG_TAG
33 #endif
34 #define LOG_TAG "TIZEN_N_SIM"
35
36 struct tapi_handle {
37         gpointer dbus_connection;
38         char *path;
39         char *cp_name;
40         GHashTable *evt_list;
41         char cookie[20];
42 };
43
44 typedef struct sim_cb_data {
45         sim_state_e previous_state;
46         struct tapi_handle *th;
47         void* cb;
48         void* user_data;
49 } sim_cb_data;
50
51 static struct tapi_handle *ghandle = NULL;
52
53 // Internal Macros
54 #define SIM_CHECK_INPUT_PARAMETER(arg) \
55         if( arg == NULL ) \
56         { \
57                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, SIM_ERROR_INVALID_PARAMETER); \
58                 return SIM_ERROR_INVALID_PARAMETER; \
59         }
60
61 #define SIM_INIT(th) \
62         th = tel_init(NULL); \
63         if (!th) { \
64                 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED); \
65                 return SIM_ERROR_OPERATION_FAILED; \
66         }
67
68 #define SIM_MAKE_CB(ccb,th,callback,user_data)  \
69         ccb = (sim_cb_data*) calloc(sizeof(sim_cb_data), 1);\
70         ccb->th = th; \
71         ccb->cb = (void*) callback;\
72         ccb->user_data = user_data
73
74 static sim_error_e _convert_access_rt_to_sim_error(TelSimAccessResult_t access_rt)
75 {
76         sim_error_e error = SIM_ERROR_NONE;
77         switch (access_rt) {
78                 case TAPI_SIM_ACCESS_SUCCESS:
79                 case TAPI_SIM_ACCESS_FILE_NOT_FOUND:
80                         error = SIM_ERROR_NONE;
81                         break;
82                 case TAPI_SIM_ACCESS_ACCESS_CONDITION_NOT_SATISFIED:
83                 case TAPI_SIM_ACCESS_CARD_ERROR:
84                         error = SIM_ERROR_NOT_AVAILABLE;
85                         break;
86                 case TAPI_SIM_ACCESS_FAILED:
87                 default:
88                         error = SIM_ERROR_OPERATION_FAILED;
89                         break;
90         }
91         return error;
92 }
93
94 int sim_get_icc_id(char** icc_id)
95 {
96         int error_code = SIM_ERROR_NONE;
97         int card_changed = 0;
98         TelSimCardStatus_t sim_card_state = 0x00;
99         struct tapi_handle *th = NULL;
100         GError *gerr = NULL;
101         GVariant *sync_gv = NULL;
102         gchar *iccid = NULL;
103         TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
104
105         SIM_CHECK_INPUT_PARAMETER(icc_id);
106         SIM_INIT(th);
107
108         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
109                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
110                 error_code = SIM_ERROR_NOT_AVAILABLE;
111                 *icc_id = NULL;
112         } else {
113                 sync_gv = g_dbus_connection_call_sync(th->dbus_connection, DBUS_TELEPHONY_SERVICE, th->path,
114                                 DBUS_TELEPHONY_SIM_INTERFACE, "GetICCID", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1,
115                                 NULL, &gerr);
116
117                 if (sync_gv) {
118                         g_variant_get(sync_gv, "(is)", &result, &iccid);
119                         if (result == TAPI_SIM_ACCESS_SUCCESS) {
120                                 if (iccid != NULL && iccid[0] != '\0') {
121                                         *icc_id = g_strdup(iccid);
122                                 } else {
123                                         *icc_id = NULL;
124                                 }
125                         } else {
126                                 error_code = _convert_access_rt_to_sim_error(result);
127                                 *icc_id = NULL;
128                         }
129                         g_free(iccid);
130                 } else {
131                         LOGE("g_dbus_conn failed. error (%s)", gerr->message);
132                         g_error_free(gerr);
133                         error_code = SIM_ERROR_OPERATION_FAILED;
134                         *icc_id = NULL;
135                 }
136                 g_variant_unref(sync_gv);
137         }
138         tel_deinit(th);
139         return error_code;
140 }
141
142 int sim_get_mcc(char** mcc)
143 {
144         TelSimImsiInfo_t sim_imsi_info;
145         int error_code = SIM_ERROR_NONE;
146         int card_changed = 0;
147         TelSimCardStatus_t sim_card_state = 0x00;
148         struct tapi_handle *th = NULL;
149
150         SIM_CHECK_INPUT_PARAMETER(mcc);
151         SIM_INIT(th);
152
153         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
154                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
155                 error_code = SIM_ERROR_NOT_AVAILABLE;
156                 *mcc = NULL;
157         } else {
158                 if (tel_get_sim_imsi(th, &sim_imsi_info) != 0) {
159                         LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
160                         error_code = SIM_ERROR_OPERATION_FAILED;
161                 } else {
162                         *mcc = g_strdup(sim_imsi_info.szMcc);
163                 }
164         }
165         tel_deinit(th);
166         return error_code;
167 }
168
169 int sim_get_mnc(char** mnc)
170 {
171         TelSimImsiInfo_t sim_imsi_info;
172         int error_code = SIM_ERROR_NONE;
173         int card_changed = 0;
174         TelSimCardStatus_t sim_card_state = 0x00;
175         struct tapi_handle *th = NULL;
176
177         SIM_CHECK_INPUT_PARAMETER(mnc);
178         SIM_INIT(th);
179
180         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
181                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
182                 error_code = SIM_ERROR_NOT_AVAILABLE;
183                 *mnc = NULL;
184         } else {
185                 if (tel_get_sim_imsi(th, &sim_imsi_info) != 0) {
186                         LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
187                         error_code = SIM_ERROR_OPERATION_FAILED;
188                 } else {
189                         *mnc = g_strdup(sim_imsi_info.szMnc);
190                 }
191         }
192         tel_deinit(th);
193         return SIM_ERROR_NONE;
194 }
195
196 int sim_get_msin(char** msin)
197 {
198         TelSimImsiInfo_t sim_imsi_info;
199         int error_code = SIM_ERROR_NONE;
200         int card_changed = 0;
201         TelSimCardStatus_t sim_card_state = 0x00;
202         struct tapi_handle *th = NULL;
203
204         SIM_CHECK_INPUT_PARAMETER(msin);
205         SIM_INIT(th);
206
207         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
208                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
209                 error_code = SIM_ERROR_NOT_AVAILABLE;
210                 *msin = NULL;
211         } else {
212                 if (tel_get_sim_imsi(th, &sim_imsi_info) != 0) {
213                         LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
214                         error_code = SIM_ERROR_OPERATION_FAILED;
215                 } else {
216                         *msin = g_strdup(sim_imsi_info.szMsin);
217                 }
218         }
219         tel_deinit(th);
220         return error_code;
221 }
222
223 int sim_get_spn(char** spn)
224 {
225         int error_code = SIM_ERROR_NONE;
226         int card_changed = 0;
227         TelSimCardStatus_t sim_card_state = 0x00;
228         struct tapi_handle *th = NULL;
229         GError *gerr = NULL;
230         GVariant *sync_gv = NULL;
231         TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
232         gchar *spn_str = NULL;
233         guchar dc = 0;
234
235         SIM_CHECK_INPUT_PARAMETER(spn);
236         SIM_INIT(th);
237
238         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
239                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
240                 error_code = SIM_ERROR_NOT_AVAILABLE;
241                 *spn = NULL;
242         } else {
243                 sync_gv = g_dbus_connection_call_sync(th->dbus_connection, DBUS_TELEPHONY_SERVICE, th->path,
244                                 DBUS_TELEPHONY_SIM_INTERFACE, "GetSpn", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1,
245                                 NULL, &gerr);
246
247                 if (sync_gv) {
248                         g_variant_get(sync_gv, "(iys)", &result, &dc, &spn_str);
249                         if (result == TAPI_SIM_ACCESS_SUCCESS) {
250                                 if (spn_str != NULL && spn_str[0] != '\0') {
251                                         *spn = g_strdup(spn_str);
252                                 } else {
253                                         *spn = NULL;
254                                 }
255                         } else {
256                                 error_code = _convert_access_rt_to_sim_error(result);
257                                 *spn = NULL;
258                         }
259                         g_free(spn_str);
260                 } else {
261                         LOGE("g_dbus_conn failed. error (%s)", gerr->message);
262                         g_error_free(gerr);
263                         error_code = SIM_ERROR_OPERATION_FAILED;
264                         *spn = NULL;
265                 }
266                 g_variant_unref(sync_gv);
267         }
268         tel_deinit(th);
269         return error_code;
270 }
271
272 int sim_get_cphs_operator_name(char** full_name, char** short_name)
273 {
274         int error_code = SIM_ERROR_NONE;
275         int card_changed = 0;
276         TelSimCardStatus_t sim_card_state = 0x00;
277         struct tapi_handle *th = NULL;
278         GError *gerr = NULL;
279         GVariant *sync_gv = NULL;
280         TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
281         gchar *full_str = NULL;
282         gchar *short_str = NULL;
283
284         SIM_CHECK_INPUT_PARAMETER(full_name);
285         SIM_CHECK_INPUT_PARAMETER(short_name);
286         SIM_INIT(th);
287
288         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
289                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
290                 error_code = SIM_ERROR_NOT_AVAILABLE;
291                 *full_name = NULL;
292                 *short_name = NULL;
293         } else {
294                 sync_gv = g_dbus_connection_call_sync(th->dbus_connection, DBUS_TELEPHONY_SERVICE, th->path,
295                                 DBUS_TELEPHONY_SIM_INTERFACE, "GetCphsNetName", NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
296                                 -1, NULL, &gerr);
297
298                 if (sync_gv) {
299                         g_variant_get(sync_gv, "(iss)", &result, &full_str, &short_str);
300                         if (result == TAPI_SIM_ACCESS_SUCCESS) {
301                                 if (full_str != NULL && full_str[0] != '\0') {
302                                         *full_name = g_strdup(full_str);
303                                 } else {
304                                         *full_name = NULL;
305                                 }
306
307                                 if (short_str != NULL && short_str[0] != '\0') {
308                                         *full_name = g_strdup(short_str);
309                                 } else {
310                                         *short_name = NULL;
311                                 }
312                         } else {
313                                 error_code = _convert_access_rt_to_sim_error(result);
314                                 *full_name = NULL;
315                                 *short_name = NULL;
316                         }
317                         g_free(full_str);
318                         g_free(short_str);
319                 } else {
320                         LOGE("g_dbus_conn failed. error (%s)", gerr->message);
321                         g_error_free(gerr);
322                         error_code = SIM_ERROR_OPERATION_FAILED;
323                         *full_name = NULL;
324                         *short_name = NULL;
325                 }
326                 g_variant_unref(sync_gv);
327         }
328         tel_deinit(th);
329         return error_code;
330 }
331
332 int sim_get_state(sim_state_e* sim_state)
333 {
334         int card_changed = 0;
335         TelSimCardStatus_t sim_card_state = 0x00;
336         int error_code = SIM_ERROR_NONE;
337         struct tapi_handle *th = NULL;
338
339         SIM_CHECK_INPUT_PARAMETER(sim_state);
340         SIM_INIT(th);
341
342         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0) {
343                 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
344                 error_code = SIM_ERROR_OPERATION_FAILED;
345         } else {
346                 switch (sim_card_state) {
347                         case TAPI_SIM_STATUS_CARD_ERROR:
348                                 *sim_state = SIM_STATE_UNAVAILABLE;
349                                 break;
350                         case TAPI_SIM_STATUS_CARD_NOT_PRESENT:
351                                 *sim_state = SIM_STATE_UNAVAILABLE;
352                                 break;
353                         case TAPI_SIM_STATUS_SIM_INITIALIZING:
354                                 *sim_state = SIM_STATE_UNKNOWN;
355                                 break;
356                         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
357                                 *sim_state = SIM_STATE_AVAILABLE;
358                                 break;
359                         case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
360                                 *sim_state = SIM_STATE_LOCKED;
361                                 break;
362                         case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
363                                 *sim_state = SIM_STATE_LOCKED;
364                                 break;
365                         case TAPI_SIM_STATUS_CARD_BLOCKED:
366                                 *sim_state = SIM_STATE_UNAVAILABLE;
367                                 break;
368                         case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:
369                                 *sim_state = SIM_STATE_LOCKED;
370                                 break;
371                         case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:
372                                 *sim_state = SIM_STATE_LOCKED;
373                                 break;
374                         case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:
375                                 *sim_state = SIM_STATE_LOCKED;
376                                 break;
377                         case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
378                                 *sim_state = SIM_STATE_LOCKED;
379                                 break;
380                         case TAPI_SIM_STATUS_CARD_REMOVED:
381                                 *sim_state = SIM_STATE_UNAVAILABLE;
382                                 break;
383                         case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
384                                 *sim_state = SIM_STATE_LOCKED;
385                                 break;
386                         default:
387                                 *sim_state = SIM_STATE_UNAVAILABLE;
388                                 break;
389                 }
390         }
391
392         tel_deinit(th);
393         return error_code;
394 }
395
396 int sim_get_subscriber_number(char** subscriber_number)
397 {
398         int error_code = SIM_ERROR_NONE;
399         int card_changed = 0;
400         TelSimCardStatus_t sim_card_state = 0x00;
401         struct tapi_handle *th = NULL;
402         GError *gerr = NULL;
403         GVariant *sync_gv = NULL;
404         GVariant *value = NULL;
405         GVariantIter *iter = NULL;
406         GVariantIter *iter_row = NULL;
407         const gchar *key = NULL;
408         const gchar *str_value = NULL;
409         TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
410         TelSimMsisdnList_t list;
411         int i = 0;
412
413         SIM_CHECK_INPUT_PARAMETER(subscriber_number);
414         SIM_INIT(th);
415
416         if (tel_get_sim_init_info(th, &sim_card_state, &card_changed) != 0 || sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
417                 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, SIM_ERROR_NOT_AVAILABLE);
418                 error_code = SIM_ERROR_NOT_AVAILABLE;
419                 *subscriber_number = NULL;
420         } else {
421                 sync_gv = g_dbus_connection_call_sync(th->dbus_connection, DBUS_TELEPHONY_SERVICE, th->path,
422                                 DBUS_TELEPHONY_SIM_INTERFACE, "GetMSISDN", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1,
423                                 NULL, &gerr);
424
425                 if (sync_gv) {
426                         memset(&list, 0, sizeof(TelSimMsisdnList_t));
427                         g_variant_get(sync_gv, "(iaa{sv})", &result, &iter);
428                         list.count = g_variant_iter_n_children(iter);
429
430                         if (result == TAPI_SIM_ACCESS_SUCCESS) {
431                                 i = 0;
432                                 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
433                                         while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
434                                                 if (!g_strcmp0(key, "name")) {
435                                                         str_value = g_variant_get_string(value, NULL);
436                                                         snprintf(list.list[i].name, strlen(str_value) + 1, "%s", str_value);
437                                                 }
438                                                 if (!g_strcmp0(key, "number")) {
439                                                         str_value = g_variant_get_string(value, NULL);
440                                                         snprintf(list.list[i].num, strlen(str_value) + 1, "%s", str_value);
441                                                 }
442                                         }
443                                         i++;
444                                         g_variant_iter_free(iter_row);
445                                 }
446                                 g_variant_iter_free(iter);
447
448                                 if (strlen(list.list[0].num) != 0) {
449                                         *subscriber_number = (char*) malloc(strlen(list.list[0].num) + 1);
450                                         if (*subscriber_number == NULL) {
451                                                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, SIM_ERROR_OUT_OF_MEMORY);
452                                                 error_code = SIM_ERROR_OUT_OF_MEMORY;
453                                         } else {
454                                                 snprintf(*subscriber_number, strlen(list.list[0].num) + 1, "%s",
455                                                                 list.list[0].num);
456                                         }
457                                 } else {
458                                         *subscriber_number = NULL;
459                                 }
460
461                         } else {
462                                 error_code = _convert_access_rt_to_sim_error(result);
463                                 *subscriber_number = NULL;
464                         }
465                 } else {
466                         LOGE("g_dbus_conn failed. error (%s)", gerr->message);
467                         g_error_free(gerr);
468                         error_code = SIM_ERROR_OPERATION_FAILED;
469                         *subscriber_number = NULL;
470                 }
471                 g_variant_unref(sync_gv);
472         }
473         tel_deinit(th);
474         return error_code;
475 }
476
477 static void on_noti_sim_status(struct tapi_handle *handle, const char *noti_id, void *data,
478                 void *user_data)
479 {
480         TelSimCardStatus_t *status = data;
481         sim_cb_data *ccb = user_data;
482         sim_state_e state = SIM_STATE_UNKNOWN;
483         sim_state_changed_cb cb;
484         LOGE("event(%s) receive with status[%d]", TAPI_NOTI_SIM_STATUS, *status);
485
486         switch (*status) {
487                 case TAPI_SIM_STATUS_CARD_ERROR:
488                         state = SIM_STATE_UNAVAILABLE;
489                         break;
490                 case TAPI_SIM_STATUS_CARD_NOT_PRESENT:
491                         state = SIM_STATE_UNAVAILABLE;
492                         break;
493                 case TAPI_SIM_STATUS_SIM_INITIALIZING:
494                         state = SIM_STATE_UNKNOWN;
495                         break;
496                 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
497                         state = SIM_STATE_AVAILABLE;
498                         break;
499                 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
500                         state = SIM_STATE_LOCKED;
501                         break;
502                 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
503                         state = SIM_STATE_LOCKED;
504                         break;
505                 case TAPI_SIM_STATUS_CARD_BLOCKED:
506                         state = SIM_STATE_UNAVAILABLE;
507                         break;
508                 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:
509                         state = SIM_STATE_LOCKED;
510                         break;
511                 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:
512                         state = SIM_STATE_LOCKED;
513                         break;
514                 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:
515                         state = SIM_STATE_LOCKED;
516                         break;
517                 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
518                         state = SIM_STATE_LOCKED;
519                         break;
520                 case TAPI_SIM_STATUS_CARD_REMOVED:
521                         state = SIM_STATE_UNAVAILABLE;
522                         break;
523                 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
524                         state = SIM_STATE_LOCKED;
525                         break;
526                 default:
527                         state = SIM_STATE_UNAVAILABLE;
528                         break;
529         }
530         if (!ccb->cb) {
531                 LOGE("[%s] callback is null", __FUNCTION__);
532                 return;
533         }
534         cb = ccb->cb;
535         cb(state, ccb->user_data);
536 }
537
538 int sim_set_state_changed_cb(sim_state_changed_cb sim_cb, void* user_data)
539 {
540         int error_code = SIM_ERROR_NONE;
541         int ret;
542         sim_cb_data *ccb = NULL;
543
544         SIM_CHECK_INPUT_PARAMETER(sim_cb);
545
546         ghandle = tel_init(NULL);
547         if (!ghandle) {
548                 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
549                 return SIM_ERROR_OPERATION_FAILED;
550         }
551
552         ccb = (sim_cb_data*) calloc(sizeof(sim_cb_data), 1);
553         ccb->th = ghandle;
554         ccb->cb = (void*) sim_cb;
555         ccb->user_data = user_data;
556
557         ret = tel_register_noti_event(ghandle, TAPI_NOTI_SIM_STATUS, on_noti_sim_status, ccb);
558         if (ret != TAPI_API_SUCCESS) error_code = SIM_ERROR_OPERATION_FAILED;
559         return error_code;
560 }
561
562 int sim_unset_state_changed_cb()
563 {
564         int error_code = SIM_ERROR_NONE;
565         int ret;
566
567         if (ghandle == NULL) {
568                 ghandle = tel_init(NULL);
569                 if (!ghandle) {
570                         LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
571                         return SIM_ERROR_OPERATION_FAILED;
572                 }
573         }
574         ret = tel_deregister_noti_event(ghandle, TAPI_NOTI_SIM_STATUS);
575         if (ret != TAPI_API_SUCCESS) error_code = SIM_ERROR_OPERATION_FAILED;
576         return error_code;
577 }