Add method for GetPsismsc
[platform/core/telephony/tel-plugin-dbus_tapi.git] / src / dtapi_sim.c
1 /*
2  * tel-plugin-dbus-tapi
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24
25 #include <glib.h>
26
27 #include <tcore.h>
28 #include <server.h>
29 #include <plugin.h>
30 #include <user_request.h>
31 #include <co_sim.h>
32
33 #include "generated-code.h"
34 #include "dtapi_common.h"
35
36 /*
37  * Error message to application (DBUS)
38  */
39 #define DBUS_SIM_STATUS_ERROR                           "SIM STATUS ERROR"
40 #define DBUS_SIM_NOT_FOUND                              "SIM NOT FOUND"
41 #define DBUS_SIM_PERM_BLOCKED                           "SIM PERM BLOCKED"
42 #define DBUS_SIM_CARD_ERROR                             "SIM CARD ERROR"
43 #define DBUS_SIM_NOT_INITIALIZED                        "SIM NOT INITIALIZED"
44 #define DBUS_SIM_INIT_COMPLETED                 "SIM INIT COMPLETED"
45 #define DBUS_SIM_LOCKED                         "SIM LOCKED"
46 #define DBUS_SIM_NOT_READY                              "SIM NOT READY"
47 #define DBUS_SIM_RESPONSE_DATA_ERROR            "SIM RESPONSE DATA ERROR"
48 #define DBUS_SIM_SERVICE_IS_DISABLED                    "SIM SERVICE IS DISABLED"
49 #define DBUS_SIM_SERVICE_NOT_SUPPORTED_FOR_NVSIM        "SERVICE NOT SUPPORTED FOR NVSIM"
50
51 #define DBUS_SIM_GET_COSIM(invocation, co_sim, server) do { \
52         co_sim = __get_sim_co_by_cp_name(server, GET_CP_NAME(invocation)); \
53         if (!co_sim) { \
54                 err("[%s] SIM Core object is NULL", GET_CP_NAME(invocation)); \
55                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED); \
56                 return TRUE; \
57         } \
58 } while (0)
59
60 #define DBUS_SIM_CHECK_SIM_STATUS(invocation, op_type, co_sim) do { \
61         if (__check_sim_state(op_type, tcore_sim_get_status(co_sim)) == FALSE) { \
62                 err("[%s] Invalid SIM status", GET_CP_NAME(invocation)); \
63                 __return_fail_response(invocation, tcore_sim_get_status(co_sim)); \
64                 return TRUE; \
65         } \
66 } while (0)
67
68 #define DBUS_SIM_CHECK_SIM_TYPE(co_sim, request) do { \
69         if (tcore_sim_get_type(co_sim) == SIM_TYPE_NVSIM) { \
70                 err("[%s] is not supported for NVSIM", request); \
71                 FAIL_RESPONSE(invocation, DBUS_SIM_SERVICE_NOT_SUPPORTED_FOR_NVSIM); \
72                 return TRUE; \
73         } \
74 } while (0)
75
76 #define DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, op_type, co_sim) do { \
77         gboolean b_cphs = FALSE; \
78         b_cphs = tcore_sim_get_cphs_status(co_sim); \
79         if (b_cphs && op_type != GET_MSISDN) { \
80                 dbg("[%s] CPHS SIM... Do not check SST", GET_CP_NAME(invocation)); \
81         } else { \
82                 struct tel_sim_service_table* svct = tcore_sim_get_service_table(co_sim); \
83                 if (svct != NULL) { \
84                         if (__check_sim_service_table(op_type, svct) == FALSE) { \
85                                 err("[%s] 'Service' is disabled in SST", GET_CP_NAME(invocation)); \
86                                 FAIL_RESPONSE(invocation, DBUS_SIM_SERVICE_IS_DISABLED); \
87                                 free(svct); \
88                                 return TRUE; \
89                         } else { \
90                                 dbg("[%s] Request to modem", GET_CP_NAME(invocation)); \
91                                 free(svct); \
92                         } \
93                 } \
94         } \
95 } while (0)
96
97 #define DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation) do { \
98         if (ret != TCORE_RETURN_SUCCESS) { \
99                 if (ret == TCORE_RETURN_SIM_DISABLED_IN_SST) { \
100                         err("[%s] 'Service' is disabled in SST", GET_CP_NAME(invocation)); \
101                         FAIL_RESPONSE(invocation, DBUS_SIM_SERVICE_IS_DISABLED); \
102                 } else { \
103                         err("[%s] Dispatch request failed: [0x%x]", GET_CP_NAME(invocation), ret); \
104                         FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED); \
105                 } \
106         } \
107 } while (0)
108
109 enum dbus_tapi_sim_gdbus_method_name {
110         /* EF Get */
111         GET_INIT_STATUS = 1,
112         GET_CARD_TYPE,
113         GET_IMSI,
114         GET_ECC,
115         GET_ICCID = 5,
116         GET_LANGUAGE,
117         SET_LANGUAGE,
118         GET_CALL_FORWARDING,
119         SET_CALL_FORWARDING,
120         GET_MESSAGE_WAITING = 10,
121         SET_MESSAGE_WAITING,
122         GET_MAILBOX,
123         SET_MAILBOX,
124         GET_CPHS_INFO,
125         GET_SVCT = 15,
126         GET_MSISDN,
127         GET_OPLMWACT,
128         GET_SPN,
129         GET_CPHS_NET_NAME,
130         GET_PSISMSC,
131
132         /* Misc */
133         AUTHENTICATION = 21,
134         VERIFY_SEC,
135         VERIFY_PUK,
136         CHANGE_PIN,
137         DISABLE_FACILITY,
138         ENABLE_FACILITY = 26,
139         GET_FACILITY,
140         GET_LOCK_INFO,
141         TRANSFER_APDU,
142         GET_ATR,
143         GET_FIELDS = 31, /* for get various data at once */
144         GET_GID,
145         SET_POWERSTATE,
146         GET_IMPI,
147         GET_IMPU,
148         GET_DOMAIN = 36,
149         GET_PCSCF,
150         GET_APP_LIST,
151         GET_ISIM_SERVICE_TABLE,
152         ACCESS_RSIM_IO,
153         GET_CDMAIMSI,
154
155         /* Notification */
156         STATUS = 100,
157         REFRESHED,
158 };
159
160 static gboolean __is_sim_status_valid(enum tel_sim_status sim_status)
161 {
162         switch (sim_status) {
163         case SIM_STATUS_INIT_COMPLETED:
164         case SIM_STATUS_INITIALIZING:
165         case SIM_STATUS_PIN_REQUIRED:
166         case SIM_STATUS_PUK_REQUIRED:
167         case SIM_STATUS_LOCK_REQUIRED:
168         case SIM_STATUS_CARD_BLOCKED:
169         case SIM_STATUS_NCK_REQUIRED:
170         case SIM_STATUS_NSCK_REQUIRED:
171         case SIM_STATUS_SPCK_REQUIRED:
172         case SIM_STATUS_CCK_REQUIRED:
173                 return TRUE;
174         default:
175                 return FALSE;
176         }
177 }
178
179 static CoreObject *__get_sim_co_by_cp_name(Server *server, char *cp_name)
180 {
181         TcorePlugin *plugin;
182
183         if (!server) {
184                 err("server is NULL");
185                 return NULL;
186         }
187
188         plugin = tcore_server_find_plugin(server, cp_name);
189         return tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
190 }
191
192 static CoreObject* __get_sim_co_from_ur(Server *server, UserRequest *ur)
193 {
194         CoreObject *co_sim;
195         char *modem_name;
196
197         modem_name = tcore_user_request_get_modem_name(ur);
198         if (!modem_name) {
199                 err("Modem name is NULL");
200                 return NULL;
201         }
202
203         co_sim = __get_sim_co_by_cp_name(server, modem_name);
204         free(modem_name);
205
206         return co_sim;
207 }
208
209 static gboolean __check_sim_state(enum dbus_tapi_sim_gdbus_method_name method,
210         enum tel_sim_status sim_status)
211 {
212         gboolean ret = TRUE;
213
214         if ((int)sim_status < SIM_STATUS_CARD_ERROR) {
215                 err("SIM status is NOT valid");
216                 return FALSE;
217         }
218
219         switch (method) {
220         case GET_CARD_TYPE:
221         case GET_ECC:
222         case GET_ICCID:
223         case GET_LANGUAGE:
224         case GET_CPHS_INFO:
225         case GET_SPN:
226         case AUTHENTICATION:
227         case GET_ATR:
228         /* Regarding Lock facilities */
229         case CHANGE_PIN:
230         case ENABLE_FACILITY:
231         case DISABLE_FACILITY:
232         case GET_FACILITY:
233         case GET_LOCK_INFO:
234         case VERIFY_SEC:
235         case VERIFY_PUK:
236                 switch (sim_status) {
237                 case SIM_STATUS_CARD_ERROR: /* FALLTHROUGH */
238                 case SIM_STATUS_CARD_BLOCKED: /* FALLTHROUGH */
239                 case SIM_STATUS_CARD_NOT_PRESENT: /* FALLTHROUGH */
240                 case SIM_STATUS_CARD_REMOVED: /* FALLTHROUGH */
241                 case SIM_STATUS_UNKNOWN: /* FALLTHROUGH */
242                 case SIM_STATUS_CARD_POWEROFF:
243                         ret = FALSE;
244                 break;
245
246                 default:
247                 break;
248                 }
249         break;
250         case TRANSFER_APDU:
251         case ACCESS_RSIM_IO:
252                 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT
253                                 || sim_status == SIM_STATUS_CARD_REMOVED
254                                 || sim_status == SIM_STATUS_UNKNOWN
255                                 || sim_status == SIM_STATUS_CARD_POWEROFF) {
256                         ret = FALSE;
257                 }
258                 break;
259         case GET_IMSI:
260         case GET_SVCT:
261         case GET_MSISDN:
262         case GET_OPLMWACT:
263         case GET_PSISMSC:
264         case GET_CPHS_NET_NAME:
265         case GET_CALL_FORWARDING:
266         case SET_CALL_FORWARDING:
267         case GET_MESSAGE_WAITING:
268         case SET_MESSAGE_WAITING:
269         case GET_MAILBOX:
270         case SET_MAILBOX:
271         case SET_LANGUAGE:
272         case GET_FIELDS:
273         case GET_IMPI:
274         case GET_IMPU:
275         case GET_GID:
276         case GET_DOMAIN:
277         case GET_PCSCF:
278         case GET_APP_LIST:
279         case GET_ISIM_SERVICE_TABLE:
280         case GET_CDMAIMSI:
281                 if (sim_status != SIM_STATUS_INIT_COMPLETED)
282                         ret = FALSE;
283         break;
284
285         case SET_POWERSTATE:
286                 switch (sim_status) {
287                 case SIM_STATUS_INIT_COMPLETED: /* FALLTHROUGH */
288                 case SIM_STATUS_INITIALIZING: /* FALLTHROUGH */
289                 case SIM_STATUS_PIN_REQUIRED: /* FALLTHROUGH */
290                 case SIM_STATUS_CARD_BLOCKED: /* FALLTHROUGH */
291                 case SIM_STATUS_CARD_POWEROFF:
292                 break;
293
294                 default:
295                         ret = FALSE;
296                 break;
297                 }
298         break;
299
300         case GET_INIT_STATUS:
301         case STATUS:
302         case REFRESHED:
303         default:
304                 err("Unhandled/Unknown operation: [%d]", method);
305         break;
306         }
307
308         return ret;
309 }
310
311 static gboolean __check_sim_service_table(enum dbus_tapi_sim_gdbus_method_name method,
312         struct tel_sim_service_table *svct)
313 {
314         enum tel_sim_type sim_type = svct->sim_type;
315
316         gboolean ret = TRUE;
317
318         switch (method) {
319         case GET_MSISDN:
320                 if (!(sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MSISDN])
321                                 && !(sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MSISDN]))
322                         ret = FALSE;
323         break;
324
325         case GET_CALL_FORWARDING:
326         case SET_CALL_FORWARDING:
327                 if (!(sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_CFIS])
328                                 && !(sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_CFIS]))
329                         ret = FALSE;
330         break;
331
332         case GET_MESSAGE_WAITING:
333         case SET_MESSAGE_WAITING:
334                 if (!(sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MWIS])
335                                 && !(sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MWIS]))
336                         ret = FALSE;
337         break;
338
339         case GET_MAILBOX:
340         case SET_MAILBOX:
341                 if (!(sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MBDN]) &&
342                                 !(sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MBDN]))
343                         ret = FALSE;
344         break;
345
346         default:
347                 err("Unhandled/Unknown operation: [%d]", method);
348         break;
349         }
350
351         return ret;
352 }
353
354 static void __return_fail_response(GDBusMethodInvocation *invocation,
355         enum tel_sim_status sim_status)
356 {
357         dbg("[%s] SIM Status: [%d]", GET_CP_NAME(invocation), sim_status);
358
359         switch (sim_status) {
360         case SIM_STATUS_CARD_NOT_PRESENT:
361         case SIM_STATUS_CARD_REMOVED:
362                 FAIL_RESPONSE(invocation, DBUS_SIM_NOT_FOUND);
363         break;
364
365         case SIM_STATUS_CARD_BLOCKED:
366                 FAIL_RESPONSE(invocation, DBUS_SIM_PERM_BLOCKED);
367         break;
368
369         case SIM_STATUS_CARD_ERROR:
370         case SIM_STATUS_CARD_CRASHED:
371                 FAIL_RESPONSE(invocation, DBUS_SIM_CARD_ERROR);
372         break;
373
374         case SIM_STATUS_INITIALIZING:
375                 FAIL_RESPONSE(invocation, DBUS_SIM_NOT_INITIALIZED);
376         break;
377
378         case SIM_STATUS_INIT_COMPLETED:
379                 FAIL_RESPONSE(invocation, DBUS_SIM_INIT_COMPLETED);
380         break;
381
382         case SIM_STATUS_PIN_REQUIRED:
383         case SIM_STATUS_PUK_REQUIRED:
384         case SIM_STATUS_NCK_REQUIRED:
385         case SIM_STATUS_NSCK_REQUIRED:
386         case SIM_STATUS_SPCK_REQUIRED:
387         case SIM_STATUS_CCK_REQUIRED:
388         case SIM_STATUS_LOCK_REQUIRED:
389                 FAIL_RESPONSE(invocation, DBUS_SIM_LOCKED);
390         break;
391
392         case SIM_STATUS_UNKNOWN:
393                 FAIL_RESPONSE(invocation, DBUS_SIM_NOT_READY);
394         break;
395
396         default:
397                 dbg("Unhandled/Unknown status: [%d]", sim_status);
398                 FAIL_RESPONSE(invocation, DBUS_SIM_STATUS_ERROR);
399         break;
400         }
401 }
402
403 static gint __convert_sim_facility_type(enum tel_sim_facility_type type)
404 {
405         gint f_type = 0;
406
407         switch (type) {
408         case SIM_FACILITY_PS:
409                 f_type = 1;
410         break;
411
412         case SIM_FACILITY_SC:
413                 f_type = 3;
414         break;
415
416         case SIM_FACILITY_FD:
417                 f_type = 4;
418         break;
419
420         case SIM_FACILITY_PN:
421                 f_type = 5;
422         break;
423
424         case SIM_FACILITY_PU:
425                 f_type = 6;
426         break;
427
428         case SIM_FACILITY_PP:
429                 f_type = 7;
430         break;
431
432         case SIM_FACILITY_PC:
433                 f_type = 8;
434         break;
435
436         default:
437                 err("Unhandled/Unknown Facility type: [0x%x]", type);
438         break;
439         }
440
441         return f_type;
442 }
443
444 static gboolean on_sim_get_init_status(TelephonySim *sim,
445         GDBusMethodInvocation *invocation, gpointer user_data)
446 {
447         struct custom_data *ctx = user_data;
448         enum tel_sim_status sim_status = SIM_STATUS_UNKNOWN;
449         gboolean sim_changed = FALSE;
450         CoreObject *co_sim = NULL;
451
452         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
453
454         sim_status = tcore_sim_get_status(co_sim);
455         sim_changed = tcore_sim_get_identification(co_sim);
456         dbg("[%s] SIM - Status: [%d] Changed: [%s]",
457                 GET_CP_NAME(invocation),
458                 sim_status, (sim_changed ? "YES" : "NO"));
459
460         telephony_sim_complete_get_init_status(sim,
461                 invocation, sim_status, sim_changed);
462
463         return TRUE;
464 }
465
466 static gboolean on_sim_get_card_type(TelephonySim *sim,
467         GDBusMethodInvocation *invocation, gpointer user_data)
468 {
469         struct custom_data *ctx = user_data;
470         enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
471         CoreObject *co_sim = NULL;
472
473         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
474         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_CARD_TYPE, co_sim);
475
476         sim_type = tcore_sim_get_type(co_sim);
477         dbg("[%s] SIM Card type: [%s]",  GET_CP_NAME(invocation),
478                 (sim_type == SIM_TYPE_GSM ? "GSM" :
479                 (sim_type == SIM_TYPE_USIM ? "USIM" :
480                 (sim_type == SIM_TYPE_RUIM ? "RUIM" :
481                 (sim_type == SIM_TYPE_NVSIM ? "NVSIM" :
482                 (sim_type == SIM_TYPE_ISIM ? "ISIM" :
483                 "UNKNOWN"))))));
484
485         telephony_sim_complete_get_card_type(sim,
486                 invocation, sim_type);
487
488         return TRUE;
489 }
490
491 static gboolean on_sim_get_imsi(TelephonySim *sim,
492         GDBusMethodInvocation *invocation, gpointer user_data)
493 {
494         struct custom_data *ctx = user_data;
495         struct tel_sim_imsi *imsi;
496         CoreObject *co_sim = NULL;
497
498         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
499         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_IMSI, co_sim);
500
501         imsi = tcore_sim_get_imsi(co_sim);
502         if (!imsi) {
503                 FAIL_RESPONSE(invocation, DBUS_SIM_RESPONSE_DATA_ERROR);
504         } else {
505                 dbg("[%s] IMSI - PLMN: [%s] MSIN: [%cX%cX%cX%cX%cX]", GET_CP_NAME(invocation),
506                         imsi->plmn, imsi->msin[0], imsi->msin[2], imsi->msin[4], imsi->msin[6], imsi->msin[8]);
507
508                 telephony_sim_complete_get_imsi(sim,
509                         invocation, imsi->plmn, imsi->msin);
510
511                 g_free(imsi);
512         }
513
514         return TRUE;
515 }
516
517 static gboolean on_sim_get_ecc(TelephonySim *sim,
518         GDBusMethodInvocation *invocation, gpointer user_data)
519 {
520         struct custom_data *ctx = user_data;
521         CoreObject *co_sim = NULL;
522         struct tel_sim_ecc_list *ecc_list = NULL;
523
524         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
525         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_ECC, co_sim);
526         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get ECC");
527
528         ecc_list = tcore_sim_get_ecc_list(co_sim);
529         if (!ecc_list) {
530                 struct custom_data *ctx = user_data;
531
532                 dbg("[%s] ECC list is NULL - Request to Modem.", GET_CP_NAME(invocation));
533
534                 /* Dispatch request */
535                 dtapi_dispatch_request(ctx, sim, invocation,
536                         TREQ_SIM_GET_ECC,
537                         NULL, 0);
538         } else {
539                 GVariant *gv = NULL;
540                 GVariantBuilder b;
541                 int i;
542
543                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
544                 for (i = 0; i < ecc_list->ecc_count; i++) {
545                         dbg("[%s] ECC[%d] - Category: [0x%x] Number: [%s] String: [%s]",
546                                 GET_CP_NAME(invocation), i,
547                                 ecc_list->ecc[i].ecc_category,
548                                 ecc_list->ecc[i].ecc_num,
549                                 ecc_list->ecc[i].ecc_string);
550                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
551                         g_variant_builder_add(&b, "{sv}", "category",
552                                 g_variant_new_int32(ecc_list->ecc[i].ecc_category));
553                         g_variant_builder_add(&b, "{sv}", "number",
554                                 g_variant_new_string(ecc_list->ecc[i].ecc_num));
555                         g_variant_builder_add(&b, "{sv}", "name",
556                                 g_variant_new_string(ecc_list->ecc[i].ecc_string));
557                         g_variant_builder_close(&b);
558                 }
559                 gv = g_variant_builder_end(&b);
560                 if (!gv)
561                         err("ecc gv is NULL");
562
563                 telephony_sim_complete_get_ecc(sim,
564                         invocation, gv);
565
566                 g_free(ecc_list);
567         }
568
569         return TRUE;
570 }
571
572 static gboolean on_sim_get_iccid(TelephonySim *sim,
573         GDBusMethodInvocation *invocation, gpointer user_data)
574 {
575         struct custom_data *ctx = user_data;
576         CoreObject *co_sim = NULL;
577         struct tel_sim_iccid* iccid = NULL;
578
579         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
580         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_ICCID, co_sim);
581         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get ICCID");
582
583         iccid = tcore_sim_get_iccid(co_sim);
584         if (!iccid) {
585                 /* Dispatch request */
586                 dtapi_dispatch_request(ctx, sim, invocation,
587                         TREQ_SIM_GET_ICCID,
588                         NULL, 0);
589         } else {
590                 dbg("[%s] ICCID: [%s]", GET_CP_NAME(invocation),
591                         iccid->iccid);
592
593                 telephony_sim_complete_get_iccid(sim,
594                         invocation, SIM_ACCESS_SUCCESS, iccid->iccid);
595
596                 g_free(iccid);
597         }
598
599         return TRUE;
600 }
601
602 static gboolean on_sim_get_language(TelephonySim *sim,
603         GDBusMethodInvocation *invocation, gpointer user_data)
604 {
605         struct custom_data *ctx = user_data;
606         CoreObject *co_sim = NULL;
607
608         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
609         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_LANGUAGE, co_sim);
610         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get Language");
611
612         /* Dispatch request */
613         dtapi_dispatch_request(ctx, sim, invocation,
614                 TREQ_SIM_GET_LANGUAGE,
615                 NULL, 0);
616
617         return TRUE;
618 }
619
620 static gboolean on_sim_set_language(TelephonySim *sim,
621         GDBusMethodInvocation *invocation, gint language, gpointer user_data)
622 {
623         struct custom_data *ctx = user_data;
624         CoreObject *co_sim = NULL;
625         struct treq_sim_set_language req;
626
627         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
628         DBUS_SIM_CHECK_SIM_STATUS(invocation, SET_LANGUAGE, co_sim);
629         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Set Language");
630
631         memset(&req, 0x0, sizeof(struct treq_sim_set_language));
632
633         req.language = language;
634
635         dbg("[%s] Language: [0x%02x]", GET_CP_NAME(invocation),
636                 req.language);
637
638         /* Dispatch request */
639         dtapi_dispatch_request(ctx, sim, invocation,
640                 TREQ_SIM_SET_LANGUAGE,
641                 &req, sizeof(struct treq_sim_set_language));
642
643         return TRUE;
644 }
645
646 static gboolean on_sim_get_call_forwarding(TelephonySim *sim,
647         GDBusMethodInvocation *invocation, gpointer user_data)
648 {
649         struct custom_data *ctx = user_data;
650         CoreObject *co_sim = NULL;
651         TReturn ret;
652
653         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
654         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_CALL_FORWARDING, co_sim);
655         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get Call Forwarding");
656         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, GET_CALL_FORWARDING, co_sim);
657
658         /* Dispatch request */
659         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
660                 TREQ_SIM_GET_CALLFORWARDING,
661                 NULL, 0);
662         DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
663
664         return TRUE;
665 }
666
667 static gboolean on_sim_set_call_forwarding(TelephonySim *sim,
668         GDBusMethodInvocation *invocation,
669         gboolean  cphs,
670         gint rec_index,
671         gint msp_num,
672         guchar cfu_status,
673         gint ton, gint npi, const gchar *number,
674         gint cc2_id, gint ext7_id,
675         gboolean cphs_line1, gboolean cphs_line2,
676         gboolean cphs_fax, gboolean cphs_data, gpointer user_data)
677 {
678         struct custom_data *ctx = user_data;
679         CoreObject *co_sim = NULL;
680         struct treq_sim_set_callforwarding req;
681         TReturn ret;
682
683         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
684         DBUS_SIM_CHECK_SIM_STATUS(invocation, SET_CALL_FORWARDING, co_sim);
685         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Set Call Forwarding");
686         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, SET_CALL_FORWARDING, co_sim);
687
688         memset(&req, 0x0, sizeof(struct treq_sim_set_callforwarding));
689
690         req.b_cphs = cphs;
691         if (req.b_cphs) {
692                 req.cphs_cf.b_line1 = cphs_line1;
693                 req.cphs_cf.b_line2 = cphs_line2;
694                 req.cphs_cf.b_fax = cphs_fax;
695                 req.cphs_cf.b_data = cphs_data;
696
697                 dbg("[%s] b_line1: [%d] b_line2: [%d] b_fax: [%d] b_data: [%d]",
698                         GET_CP_NAME(invocation),
699                         req.cphs_cf.b_line1, req.cphs_cf.b_line2,
700                         req.cphs_cf.b_fax, req.cphs_cf.b_data);
701         } else {
702                 req.cf.rec_index = rec_index;
703                 req.cf.msp_num = msp_num;
704                 req.cf.cfu_status = cfu_status;
705                 req.cf.ton = ton;
706                 req.cf.npi = npi;
707                 memcpy(&req.cf.cfu_num, number, (strlen(number) <= SIM_XDN_NUMBER_LEN_MAX ? strlen(number) : SIM_XDN_NUMBER_LEN_MAX));
708                 req.cf.cc2_id = cc2_id;
709                 req.cf.ext7_id = ext7_id;
710
711                 dbg("[%s] rec_index: [%d] msp_num: [%d] cfu_status: [0x%x] " \
712                         "ton: [%d] npi: [%d] cfu_num: [%s] cc2_id: [%d] ext7_id: [%d]",
713                         GET_CP_NAME(invocation), req.cf.rec_index,
714                         req.cf.msp_num, req.cf.cfu_status, req.cf.ton,
715                         req.cf.npi, req.cf.cfu_num, req.cf.cc2_id, req.cf.ext7_id);
716         }
717
718         /* Dispatch request */
719         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
720                 TREQ_SIM_SET_CALLFORWARDING,
721                 &req, sizeof(struct treq_sim_set_callforwarding));
722         DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
723
724         return TRUE;
725 }
726
727 static gboolean on_sim_get_message_waiting(TelephonySim *sim,
728         GDBusMethodInvocation *invocation, gpointer user_data)
729 {
730         struct custom_data *ctx = user_data;
731         CoreObject *co_sim = NULL;
732         TReturn ret;
733
734         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
735         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_MESSAGE_WAITING, co_sim);
736         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get Message Waiting");
737         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, GET_MESSAGE_WAITING, co_sim);
738
739         /* Dispatch request */
740         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
741                 TREQ_SIM_GET_MESSAGEWAITING,
742                 NULL, 0);
743         DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
744
745         return TRUE;
746 }
747
748 static gboolean on_sim_set_message_waiting(TelephonySim *sim,
749         GDBusMethodInvocation *invocation,
750         gboolean  cphs,
751         gint rec_index,
752         guchar indicator_status,
753         gint voice_cnt, gint fax_cnt,
754         gint email_cnt, gint other_cnt,
755         gint video_cnt,
756         gboolean cphs_voice1, gboolean cphs_voice2,
757         gboolean cphs_fax, gboolean cphs_data, gpointer user_data)
758 {
759         struct custom_data *ctx = user_data;
760         TReturn ret;
761         CoreObject *co_sim = NULL;
762         struct treq_sim_set_messagewaiting req;
763
764         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
765         DBUS_SIM_CHECK_SIM_STATUS(invocation, SET_MESSAGE_WAITING, co_sim);
766         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Set Message Waiting");
767         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, SET_MESSAGE_WAITING, co_sim);
768
769         memset(&req, 0x0, sizeof(struct treq_sim_set_messagewaiting));
770
771         req.b_cphs = cphs;
772
773         if (req.b_cphs) {
774                 req.cphs_mw.b_voice1 = cphs_voice1;
775                 req.cphs_mw.b_voice2 = cphs_voice2;
776                 req.cphs_mw.b_fax = cphs_fax;
777                 req.cphs_mw.b_data = cphs_data;
778
779                 dbg("[%s] b_voice1: [%d] b_voice2: [%d] b_fax: [%d] b_data:[%d]",
780                         GET_CP_NAME(invocation),
781                         req.cphs_mw.b_voice1, req.cphs_mw.b_voice2,
782                         req.cphs_mw.b_fax, req.cphs_mw.b_data);
783         } else {
784                 req.mw.rec_index = rec_index;
785                 req.mw.indicator_status = indicator_status;
786                 req.mw.voice_count = voice_cnt;
787                 req.mw.fax_count = fax_cnt;
788                 req.mw.email_count = email_cnt;
789                 req.mw.other_count = other_cnt;
790                 req.mw.video_count = video_cnt;
791
792                 dbg("[%s] rec_index: [%d] indicator_status: [0x%x] voice_count: [%d] " \
793                         "fax_count: [%d] email_count: [%d] other_count: [%d] video_count: [%d]",
794                         GET_CP_NAME(invocation),
795                         req.mw.rec_index, req.mw.indicator_status,
796                         req.mw.voice_count, req.mw.fax_count,
797                         req.mw.email_count, req.mw.other_count,
798                         req.mw.video_count);
799         }
800
801         /* Dispatch request */
802         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
803                 TREQ_SIM_SET_MESSAGEWAITING,
804                 &req, sizeof(struct treq_sim_set_messagewaiting));
805         DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
806
807         return TRUE;
808 }
809
810 static gboolean on_sim_get_mailbox(TelephonySim *sim,
811         GDBusMethodInvocation *invocation, gpointer user_data)
812 {
813         struct custom_data *ctx = user_data;
814         TReturn ret;
815         CoreObject *co_sim = NULL;
816
817         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
818         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_MAILBOX, co_sim);
819         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get Mailbox");
820         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, GET_MAILBOX, co_sim);
821
822         /* Dispatch request */
823         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
824                 TREQ_SIM_GET_MAILBOX,
825                 NULL, 0);
826         DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
827
828         return TRUE;
829 }
830
831 static gboolean on_sim_set_mailbox(TelephonySim *sim,
832         GDBusMethodInvocation *invocation,
833         gboolean cphs,
834         gint mb_type, gint rec_index,
835         gint profile_number,
836         gint alpha_id_max_len, const gchar *alpha_id,
837         gint ton, gint npi, const gchar *number,
838         gint cc_id, gint ext1_id, gpointer user_data)
839 {
840         struct custom_data *ctx = user_data;
841         TReturn ret;
842         CoreObject *co_sim = NULL;
843         struct treq_sim_set_mailbox req;
844
845         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
846         DBUS_SIM_CHECK_SIM_STATUS(invocation, SET_MAILBOX, co_sim);
847         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Set Mailbox");
848         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, SET_MAILBOX, co_sim);
849
850         memset(&req, 0x0, sizeof(struct treq_sim_set_mailbox));
851
852         req.b_cphs = cphs;
853
854         req.mb_info.mb_type = mb_type;
855         req.mb_info.rec_index = rec_index;
856         req.mb_info.profile_number = profile_number;
857         req.mb_info.number_info.alpha_id_max_len = alpha_id_max_len;
858         if (strlen(alpha_id))
859                 memcpy(&req.mb_info.number_info.alpha_id, alpha_id, (strlen(alpha_id) <= SIM_XDN_ALPHA_ID_LEN_MAX ? strlen(alpha_id) : SIM_XDN_ALPHA_ID_LEN_MAX));
860         req.mb_info.number_info.ton = ton;
861         req.mb_info.number_info.npi = npi;
862         if (strlen(number))
863                 memcpy(&req.mb_info.number_info.num, number, (strlen(number) <= SIM_XDN_NUMBER_LEN_MAX ? strlen(number) : SIM_XDN_NUMBER_LEN_MAX));
864         req.mb_info.number_info.cc_id = cc_id;
865         req.mb_info.number_info.ext1_id = ext1_id;
866
867         dbg("[%s] b_cphs: [%d] mb_type: [%d] rec_index: [%d] " \
868                 "profile_number: [%d] alpha_id_max_len: [%d] alpha_id: [%s] " \
869                 "ton: [%d] npi: [%d] num: [%s] cc_id: [%d] ext1_id: [%d]",
870                 GET_CP_NAME(invocation),
871                 req.b_cphs,
872                 req.mb_info.mb_type, req.mb_info.rec_index,
873                 req.mb_info.profile_number,
874                 req.mb_info.number_info.alpha_id_max_len,
875                 req.mb_info.number_info.alpha_id,
876                 req.mb_info.number_info.ton, req.mb_info.number_info.npi,
877                 req.mb_info.number_info.num,
878                 req.mb_info.number_info.cc_id, req.mb_info.number_info.ext1_id);
879
880         /* Dispatch request */
881         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
882                 TREQ_SIM_SET_MAILBOX,
883                 &req, sizeof(struct treq_sim_set_mailbox));
884         DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
885
886         return TRUE;
887 }
888
889 static gboolean on_sim_get_cphsinfo(TelephonySim *sim,
890         GDBusMethodInvocation *invocation, gpointer user_data)
891 {
892         struct custom_data *ctx = user_data;
893         CoreObject *co_sim = NULL;
894
895         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
896         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_CPHS_INFO, co_sim);
897         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get CPHS Info");
898
899         /* Dispatch request */
900         dtapi_dispatch_request(ctx, sim, invocation,
901                 TREQ_SIM_GET_CPHS_INFO,
902                 NULL, 0);
903
904         return TRUE;
905 }
906
907 static gboolean on_sim_get_service_table(TelephonySim *sim,
908         GDBusMethodInvocation *invocation, gpointer user_data)
909 {
910         struct custom_data *ctx = user_data;
911         CoreObject *co_sim = NULL;
912         struct tel_sim_service_table *svct = NULL;
913
914         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
915         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_SVCT, co_sim);
916         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get SVCT");
917
918         svct = tcore_sim_get_service_table(co_sim);
919         if (!svct) {
920                 struct custom_data *ctx = user_data;
921
922                 dbg("[%s] NOT cached - Request to modem",
923                         GET_CP_NAME(invocation));
924
925                 /* Dispatch request */
926                 dtapi_dispatch_request(ctx, sim, invocation,
927                         TREQ_SIM_GET_SERVICE_TABLE,
928                         NULL, 0);
929         } else {
930                 GVariantBuilder builder;
931                 GVariant * inner_gv = NULL;
932                 GVariant *svct_gv = NULL;
933                 int i = 0;
934
935                 dbg("[%s] GET_SERVICE_TABLE", GET_CP_NAME(invocation));
936
937                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
938                 if (svct->sim_type == SIM_TYPE_GSM) {
939                         for (i = 0; i < SIM_SST_SERVICE_CNT_MAX; i++)
940                                 g_variant_builder_add(&builder, "y",
941                                         svct->table.sst.service[i]);
942                 } else if (svct->sim_type == SIM_TYPE_USIM) {
943                         for (i = 0; i < SIM_UST_SERVICE_CNT_MAX; i++)
944                                 g_variant_builder_add(&builder, "y",
945                                         svct->table.ust.service[i]);
946                 }
947                 /*
948                  * Todo: new interface such as tel_get_sim_cdma_service_table(CDMA or CSIM) like tel_get_sim_isim_service_table() is needed.
949                  * Because it's not possible to distiguish client want GSM service table or CDMA service table with one interface.
950                  *
951                  * Or we can extend current 'struct tel_sim_service_table' to get sst/ust & cst simultaneously.
952                  */
953                 else {
954                         err("[%s] Unknown SIM type: [%d]", GET_CP_NAME(invocation), svct->sim_type);
955                 }
956                 inner_gv = g_variant_builder_end(&builder);
957                 svct_gv = g_variant_new("v", inner_gv);
958
959                 telephony_sim_complete_get_service_table(sim,
960                         invocation, SIM_ACCESS_SUCCESS, svct->sim_type, svct_gv);
961
962                 free(svct);
963         }
964
965         return TRUE;
966 }
967
968 static gboolean on_sim_get_msisdn(TelephonySim *sim,
969         GDBusMethodInvocation *invocation, gpointer user_data)
970 {
971         struct custom_data *ctx = user_data;
972         CoreObject *co_sim = NULL;
973         struct tel_sim_msisdn_list *msisdn_list = NULL;
974         gboolean read_from_modem = FALSE;
975
976         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
977         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_MSISDN, co_sim);
978         DBUS_SIM_CHECK_SIM_SERVICE_TABLE(invocation, GET_MSISDN, co_sim);
979
980         if (SIM_TYPE_NVSIM == tcore_sim_get_type(co_sim)) {
981                 dbg("NV SIM, don't use cached MSISDN");
982                 read_from_modem = TRUE;
983         } else {
984                 msisdn_list = tcore_sim_get_msisdn_list(co_sim);
985                 if (msisdn_list)
986                         read_from_modem = FALSE;
987                 else
988                         read_from_modem = TRUE;
989         }
990
991         if (read_from_modem) {
992                 TReturn ret;
993
994                 dbg("[%s] NOT cached - Request to modem", GET_CP_NAME(invocation));
995
996                 /* Dispatch request */
997                 ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
998                         TREQ_SIM_GET_MSISDN,
999                         NULL, 0);
1000                 DBUS_SIM_CHECK_DISPATCH_RET(ret, invocation);
1001         } else {
1002                 GVariant *gv = NULL;
1003                 int i;
1004                 GVariantBuilder b;
1005
1006                 dbg("[%s] MSISDN count: [%d]",
1007                         GET_CP_NAME(invocation), msisdn_list->count);
1008
1009                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1010                 for (i = 0; i < msisdn_list->count; i++) {
1011                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
1012                         g_variant_builder_add(&b, "{sv}", "name",
1013                                 g_variant_new_string((const gchar *)msisdn_list->msisdn[i].name));
1014                         if (msisdn_list->msisdn[i].ton == SIM_TON_INTERNATIONAL) {
1015                                 unsigned char *tmp = (unsigned char *)calloc(SIM_MSISDN_NUMBER_LEN_MAX + 1, 1);
1016                                 if (tmp != NULL) {
1017                                         tmp[0] = '+';
1018
1019                                         strncpy((char *)tmp+1,
1020                                                 (const char*)msisdn_list->msisdn[i].num,
1021                                                 SIM_MSISDN_NUMBER_LEN_MAX - 1);
1022                                         tmp[SIM_MSISDN_NUMBER_LEN_MAX] = '\0';
1023
1024                                         g_variant_builder_add(&b, "{sv}", "number",
1025                                                 g_variant_new_string((const gchar *)tmp));
1026
1027                                         free(tmp);
1028                                 } else {
1029                                         warn("Memory allocation failed");
1030                                         g_variant_builder_add(&b, "{sv}", "number",
1031                                                 g_variant_new_string((const gchar *)msisdn_list->msisdn[i].num));
1032                                 }
1033                         } else {
1034                                 g_variant_builder_add(&b, "{sv}", "number",
1035                                         g_variant_new_string((const gchar *)msisdn_list->msisdn[i].num));
1036                         }
1037                         g_variant_builder_close(&b);
1038                 }
1039                 gv = g_variant_builder_end(&b);
1040
1041                 telephony_sim_complete_get_msisdn(sim,
1042                         invocation, SIM_ACCESS_SUCCESS, gv);
1043
1044                 g_free(msisdn_list);
1045         }
1046
1047         return TRUE;
1048 }
1049
1050 static gboolean on_sim_get_oplmnwact(TelephonySim *sim,
1051         GDBusMethodInvocation *invocation, gpointer user_data)
1052 {
1053         struct custom_data *ctx = user_data;
1054         CoreObject *co_sim = NULL;
1055
1056         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1057         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_OPLMWACT, co_sim);
1058         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get OPLMNWACT");
1059
1060         /* Dispatch request */
1061         dtapi_dispatch_request(ctx, sim, invocation,
1062                 TREQ_SIM_GET_OPLMNWACT,
1063                 NULL, 0);
1064
1065         return TRUE;
1066 }
1067
1068 static gboolean on_sim_get_psismsc(TelephonySim *sim,
1069         GDBusMethodInvocation *invocation, gpointer user_data)
1070 {
1071         struct custom_data *ctx = user_data;
1072         CoreObject *co_sim = NULL;
1073
1074         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1075         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_PSISMSC, co_sim);
1076         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get PSISMSC");
1077
1078         /* Dispatch request */
1079         dtapi_dispatch_request(ctx, sim, invocation,
1080                 TREQ_SIM_GET_PSISMSC,
1081                 NULL, 0);
1082
1083         return TRUE;
1084 }
1085
1086 static gboolean on_sim_get_spn(TelephonySim *sim,
1087         GDBusMethodInvocation *invocation, gpointer user_data)
1088 {
1089         struct custom_data *ctx = user_data;
1090         CoreObject *co_sim = NULL;
1091         struct tel_sim_spn* spn = NULL;
1092
1093         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1094         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_SPN, co_sim);
1095         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get SPN");
1096
1097         spn = tcore_sim_get_spn(co_sim);
1098         if (!spn) {
1099                 dbg("[%s] NOT cached - Request to modem", GET_CP_NAME(invocation));
1100
1101                 /* Dispatch request */
1102                 dtapi_dispatch_request(ctx, sim, invocation,
1103                         TREQ_SIM_GET_SPN,
1104                         NULL, 0);
1105         } else {
1106                 dbg("[%s] Display condition: [%d] SPN: [%s]",
1107                         GET_CP_NAME(invocation),
1108                         spn->display_condition, (const gchar *)spn->spn);
1109
1110                 telephony_sim_complete_get_spn(sim, invocation, SIM_ACCESS_SUCCESS,
1111                         spn->display_condition, (const gchar *)spn->spn);
1112
1113                 g_free(spn);
1114         }
1115         return TRUE;
1116 }
1117
1118 static gboolean on_sim_get_cphs_netname(TelephonySim *sim,
1119         GDBusMethodInvocation *invocation, gpointer user_data)
1120 {
1121         struct custom_data *ctx = user_data;
1122         CoreObject *co_sim = NULL;
1123         struct tel_sim_cphs_netname *cphs_netname = NULL;
1124
1125         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1126         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_CPHS_NET_NAME, co_sim);
1127         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get CPHS Net Name");
1128
1129         cphs_netname = tcore_sim_get_cphs_netname(co_sim);
1130         if (!cphs_netname) {
1131                 dbg("[%s] NOT cached - Request to modem", GET_CP_NAME(invocation));
1132
1133                 /* Dispatch request */
1134                 dtapi_dispatch_request(ctx, sim, invocation,
1135                         TREQ_SIM_GET_CPHS_NETNAME,
1136                         NULL, 0);
1137         } else {
1138                 dbg("[%s] Full name: [%s] Short name: [%s]",
1139                         GET_CP_NAME(invocation),
1140                         (const gchar *)cphs_netname->full_name,
1141                         (const gchar *)cphs_netname->short_name);
1142
1143                 telephony_sim_complete_get_cphs_net_name(sim,
1144                         invocation, SIM_ACCESS_SUCCESS,
1145                         (const gchar *)cphs_netname->full_name,
1146                         (const gchar *)cphs_netname->short_name);
1147
1148                 g_free(cphs_netname);
1149         }
1150
1151         return TRUE;
1152 }
1153
1154 static gboolean on_sim_get_gid(TelephonySim *sim,
1155         GDBusMethodInvocation *invocation, gpointer user_data)
1156 {
1157         struct custom_data *ctx = user_data;
1158         CoreObject *co_sim = NULL;
1159
1160         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1161         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_GID, co_sim);
1162         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get GID");
1163
1164         /* Dispatch request */
1165         dtapi_dispatch_request(ctx, sim, invocation,
1166                 TREQ_SIM_GET_GID,
1167                 NULL, 0);
1168
1169         return TRUE;
1170 }
1171
1172 static gboolean on_sim_authentication(TelephonySim *sim,
1173         GDBusMethodInvocation *invocation, gint auth_type,
1174         GVariant *rand, GVariant *autn, gpointer user_data)
1175 {
1176         struct custom_data *ctx = user_data;
1177         GVariantIter *iter = NULL;
1178         GVariant *rand_gv = NULL;
1179         GVariant *autn_gv = NULL;
1180         guchar rt_i;
1181         int i = 0;
1182         TReturn ret;
1183         CoreObject *co_sim = NULL;
1184         struct treq_sim_req_authentication req;
1185
1186         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1187         DBUS_SIM_CHECK_SIM_STATUS(invocation, AUTHENTICATION, co_sim);
1188
1189         memset(&req, 0x0, sizeof(struct treq_sim_req_authentication));
1190
1191         req.auth_type = auth_type;
1192
1193         rand_gv = g_variant_get_variant(rand);
1194         g_variant_get(rand_gv, "ay", &iter);
1195         while (g_variant_iter_loop(iter, "y", &rt_i)) {
1196                 req.rand_data[i] = rt_i;
1197                 i++;
1198         }
1199         g_variant_iter_free(iter);
1200         g_variant_unref(rand_gv);
1201
1202         req.rand_length = (unsigned int)i;
1203
1204         i = 0;
1205         autn_gv = g_variant_get_variant(autn);
1206         g_variant_get(autn_gv, "ay", &iter);
1207         while (g_variant_iter_loop(iter, "y", &rt_i)) {
1208                 req.autn_data[i] = rt_i;
1209                 i++;
1210         }
1211         g_variant_iter_free(iter);
1212         g_variant_unref(autn_gv);
1213
1214         req.autn_length = (unsigned int)i;
1215
1216         dbg("[%s] Authentication - type: [0x%02x] RAND len: [%d] AUTN len: [%d]",
1217                 GET_CP_NAME(invocation),
1218                 req.auth_type, req.rand_length, req.autn_length);
1219
1220         /* Dispatch request */
1221         ret = dtapi_dispatch_request_ex(ctx, sim, invocation,
1222                 TREQ_SIM_REQ_AUTHENTICATION,
1223                 &req, sizeof(struct treq_sim_req_authentication));
1224         if (ret != TCORE_RETURN_SUCCESS) {
1225                 GVariantBuilder builder;
1226                 GVariant *ak = NULL;
1227                 GVariant *cp = NULL;
1228                 GVariant *it = NULL;
1229                 GVariant *resp = NULL;
1230                 GVariant *ak_gv = NULL;
1231                 GVariant *cp_gv = NULL;
1232                 GVariant *it_gv = NULL;
1233                 GVariant *resp_gv = NULL;
1234
1235                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
1236                 ak = g_variant_builder_end(&builder);
1237                 ak_gv = g_variant_new("v", ak);
1238
1239                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
1240                 cp = g_variant_builder_end(&builder);
1241                 cp_gv = g_variant_new("v", cp);
1242
1243                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
1244                 it = g_variant_builder_end(&builder);
1245                 it_gv = g_variant_new("v", it);
1246
1247                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
1248                 resp = g_variant_builder_end(&builder);
1249                 resp_gv = g_variant_new("v", resp);
1250
1251                 telephony_sim_complete_authentication(sim,
1252                         invocation, SIM_ACCESS_FAILED,
1253                         0, 0, ak_gv, cp_gv, it_gv, resp_gv);
1254         }
1255
1256         return TRUE;
1257 }
1258
1259 static gboolean on_sim_verify_sec(TelephonySim *sim,
1260         GDBusMethodInvocation *invocation,
1261         gint pin_type, const gchar *pin, gpointer user_data)
1262 {
1263         struct custom_data *ctx = user_data;
1264         CoreObject *co_sim = NULL;
1265         struct treq_sim_verify_pins req;
1266
1267         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1268         DBUS_SIM_CHECK_SIM_STATUS(invocation, VERIFY_SEC, co_sim);
1269         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Verify Sec");
1270
1271         memset(&req, 0x0, sizeof(struct treq_sim_verify_pins));
1272
1273         req.pin_type = pin_type;
1274         req.pin_length = (strlen(pin) <= SIM_PIN_LEN_MAX) ? strlen(pin) : SIM_PIN_LEN_MAX;
1275         memcpy(req.pin, pin, req.pin_length);
1276
1277         dbg("[%s] PIN - type: [0x%02x] len: [%d]",
1278                 GET_CP_NAME(invocation),
1279                 req.pin_type, req.pin_length);
1280
1281         /* Dispatch request */
1282         dtapi_dispatch_request(ctx, sim, invocation,
1283                 TREQ_SIM_VERIFY_PINS,
1284                 &req, sizeof(struct treq_sim_verify_pins));
1285
1286         return TRUE;
1287 }
1288
1289 static gboolean on_sim_verify_puk(TelephonySim *sim,
1290         GDBusMethodInvocation *invocation,
1291         gint puk_type, const gchar *puk,
1292         const gchar *new_pin, gpointer user_data)
1293 {
1294         struct custom_data *ctx = user_data;
1295         CoreObject *co_sim = NULL;
1296         struct treq_sim_verify_puks req;
1297
1298         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1299         DBUS_SIM_CHECK_SIM_STATUS(invocation, VERIFY_PUK, co_sim);
1300         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Verify PUK");
1301
1302         memset(&req, 0x0, sizeof(struct treq_sim_verify_puks));
1303
1304         req.puk_type = puk_type;
1305         req.puk_length = (strlen(puk) <= SIM_PIN_LEN_MAX) ? strlen(puk) : SIM_PIN_LEN_MAX;
1306         memcpy(req.puk, puk, req.puk_length);
1307         req.pin_length = (strlen(new_pin) <= SIM_PIN_LEN_MAX) ? strlen(new_pin) : SIM_PIN_LEN_MAX;
1308         memcpy(req.pin, new_pin, req.pin_length);
1309
1310         dbg("[%s] PUK - type: [0x%02x] len: [%d] PIN len: [%d]",
1311                 GET_CP_NAME(invocation), req.puk_type,
1312                 req.puk_length, req.pin_length);
1313
1314         /* Dispatch request */
1315         dtapi_dispatch_request(ctx, sim, invocation,
1316                 TREQ_SIM_VERIFY_PUKS,
1317                 &req, sizeof(struct treq_sim_verify_puks));
1318
1319         return TRUE;
1320 }
1321
1322 static gboolean on_sim_change_pin(TelephonySim *sim,
1323         GDBusMethodInvocation *invocation,
1324         gint pin_type, const gchar *old_pin, const gchar *new_pin,
1325         gpointer user_data)
1326 {
1327         struct custom_data *ctx = user_data;
1328         CoreObject *co_sim = NULL;
1329         struct treq_sim_change_pins req;
1330
1331         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1332         DBUS_SIM_CHECK_SIM_STATUS(invocation, CHANGE_PIN, co_sim);
1333         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Change PIN");
1334
1335         memset(&req, 0x0, sizeof(struct treq_sim_change_pins));
1336
1337         req.type = pin_type;
1338         req.old_pin_length = (strlen(old_pin) <= SIM_PIN_LEN_MAX) ? strlen(old_pin) : SIM_PIN_LEN_MAX;
1339         memcpy(req.old_pin, old_pin, req.old_pin_length);
1340         req.new_pin_length = (strlen(new_pin) <= SIM_PIN_LEN_MAX) ? strlen(new_pin) : SIM_PIN_LEN_MAX;
1341         memcpy(req.new_pin, new_pin, req.new_pin_length);
1342
1343         dbg("[%s] PIN - type: [0x%02x] Old PIN len: [%d] New PIN len: [%d]",
1344                 GET_CP_NAME(invocation), req.type,
1345                 req.old_pin_length, req.new_pin_length);
1346
1347         /* Dispatch request */
1348         dtapi_dispatch_request(ctx, sim, invocation,
1349                 TREQ_SIM_CHANGE_PINS,
1350                 &req, sizeof(struct treq_sim_change_pins));
1351
1352         return TRUE;
1353 }
1354
1355 static gboolean on_sim_disable_facility(TelephonySim *sim,
1356         GDBusMethodInvocation *invocation,
1357         gint facility_type, const gchar *password, gpointer user_data)
1358 {
1359         struct custom_data *ctx = user_data;
1360         struct treq_sim_disable_facility req;
1361         CoreObject *co_sim = NULL;
1362
1363         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1364         DBUS_SIM_CHECK_SIM_STATUS(invocation, DISABLE_FACILITY, co_sim);
1365         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Diable Facility");
1366
1367         memset(&req, 0x0, sizeof(struct treq_sim_disable_facility));
1368
1369         dbg("[%s] facility_type: [%d]", GET_CP_NAME(invocation), facility_type);
1370         switch (facility_type) {
1371         case 1:
1372                 req.type = SIM_FACILITY_PS;
1373         break;
1374
1375         case 3:
1376                 req.type = SIM_FACILITY_SC;
1377         break;
1378
1379         case 4:
1380                 req.type = SIM_FACILITY_FD;
1381         break;
1382
1383         case 5:
1384                 req.type = SIM_FACILITY_PN;
1385         break;
1386
1387         case 6:
1388                 req.type = SIM_FACILITY_PU;
1389         break;
1390
1391         case 7:
1392                 req.type = SIM_FACILITY_PP;
1393         break;
1394
1395         case 8:
1396                 req.type = SIM_FACILITY_PC;
1397         break;
1398
1399         default:
1400                 err("Unhandled/Unknown Facility type: [0x%x]", facility_type);
1401
1402                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
1403
1404                 return TRUE;
1405         }
1406
1407         req.password_length = (strlen(password) <= SIM_FACILITY_PW_LEN_MAX) ? strlen(password) : SIM_FACILITY_PW_LEN_MAX;
1408         memcpy(req.password, password, req.password_length);
1409
1410         dbg("[%s] Facility - type: [0x%02x] Passowrd len: [%d]",
1411                 GET_CP_NAME(invocation),
1412                 req.type, req.password_length);
1413
1414         /* Dispatch request */
1415         dtapi_dispatch_request(ctx, sim, invocation,
1416                 TREQ_SIM_DISABLE_FACILITY,
1417                 &req, sizeof(struct treq_sim_disable_facility));
1418
1419         return TRUE;
1420 }
1421
1422 static gboolean on_sim_enable_facility(TelephonySim *sim, GDBusMethodInvocation *invocation,
1423             gint facility_type,
1424             const gchar *password,
1425                 gpointer user_data)
1426 {
1427         struct custom_data *ctx = user_data;
1428         struct treq_sim_enable_facility req;
1429         CoreObject *co_sim = NULL;
1430
1431         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1432         DBUS_SIM_CHECK_SIM_STATUS(invocation, ENABLE_FACILITY, co_sim);
1433         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Enable Facility");
1434
1435         memset(&req, 0x0, sizeof(struct treq_sim_enable_facility));
1436
1437         dbg("[%s] facility_type: [%d]", GET_CP_NAME(invocation), facility_type);
1438         switch (facility_type) {
1439         case 1:
1440                 req.type = SIM_FACILITY_PS;
1441         break;
1442
1443         case 3:
1444                 req.type = SIM_FACILITY_SC;
1445         break;
1446
1447         case 4:
1448                 req.type = SIM_FACILITY_FD;
1449         break;
1450
1451         case 5:
1452                 req.type = SIM_FACILITY_PN;
1453         break;
1454
1455         case 6:
1456                 req.type = SIM_FACILITY_PU;
1457         break;
1458
1459         case 7:
1460                 req.type = SIM_FACILITY_PP;
1461         break;
1462
1463         case 8:
1464                 req.type = SIM_FACILITY_PC;
1465         break;
1466
1467         default:
1468                 err("Unhandled/Unknown Facility type: [0x%x]", facility_type);
1469
1470                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
1471
1472                 return TRUE;
1473         }
1474
1475         req.password_length = (strlen(password) <= SIM_FACILITY_PW_LEN_MAX) ? strlen(password) : SIM_FACILITY_PW_LEN_MAX;
1476         memcpy(req.password, password, req.password_length);
1477
1478         dbg("[%s] Facility - type: [0x%02x] Passowrd len: [%d]",
1479                 GET_CP_NAME(invocation),
1480                 req.type, req.password_length);
1481
1482         /* Dispatch request */
1483         dtapi_dispatch_request(ctx, sim, invocation,
1484                 TREQ_SIM_ENABLE_FACILITY,
1485                 &req, sizeof(struct treq_sim_enable_facility));
1486
1487         return TRUE;
1488 }
1489
1490 static gboolean on_sim_get_facility(TelephonySim *sim,
1491         GDBusMethodInvocation *invocation,
1492         gint facility_type, gpointer user_data)
1493 {
1494         struct custom_data *ctx = user_data;
1495         struct treq_sim_get_facility_status req;
1496         CoreObject *co_sim = NULL;
1497
1498         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1499         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_FACILITY, co_sim);
1500         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get Facility");
1501
1502         memset(&req, 0x0, sizeof(struct treq_sim_get_facility_status));
1503
1504         dbg("[%s] facility_type: [%d]", GET_CP_NAME(invocation), facility_type);
1505
1506         switch (facility_type) {
1507         case 1:
1508                 req.type = SIM_FACILITY_PS;
1509         break;
1510
1511         case 3:
1512                 req.type = SIM_FACILITY_SC;
1513         break;
1514
1515         case 4:
1516                 req.type = SIM_FACILITY_FD;
1517         break;
1518
1519         case 5:
1520                 req.type = SIM_FACILITY_PN;
1521         break;
1522
1523         case 6:
1524                 req.type = SIM_FACILITY_PU;
1525         break;
1526
1527         case 7:
1528                 req.type = SIM_FACILITY_PP;
1529         break;
1530
1531         case 8:
1532                 req.type = SIM_FACILITY_PC;
1533         break;
1534
1535         default:
1536                 err("Unhandled/Unknown Facility type: [0x%x]", facility_type);
1537
1538                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
1539
1540                 return TRUE;
1541         }
1542
1543         /* Dispatch request */
1544         dtapi_dispatch_request(ctx, sim, invocation,
1545                 TREQ_SIM_GET_FACILITY_STATUS,
1546                 &req, sizeof(struct treq_sim_get_facility_status));
1547
1548         return TRUE;
1549 }
1550
1551 static gboolean on_sim_get_lock_info(TelephonySim *sim,
1552         GDBusMethodInvocation *invocation,
1553         gint facility_type, gpointer user_data)
1554 {
1555         struct custom_data *ctx = user_data;
1556         CoreObject *co_sim = NULL;
1557         struct treq_sim_get_lock_info req;
1558
1559         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1560         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_LOCK_INFO, co_sim);
1561         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get Lock Info");
1562
1563         memset(&req, 0x0, sizeof(struct treq_sim_get_lock_info));
1564
1565         dbg("[%s] facility_type: [%d]", GET_CP_NAME(invocation), facility_type);
1566         switch (facility_type) {
1567         case 1:
1568                 req.type = SIM_FACILITY_PS;
1569         break;
1570
1571         case 3:
1572                 req.type = SIM_FACILITY_SC;
1573         break;
1574
1575         case 4:
1576                 req.type = SIM_FACILITY_FD;
1577         break;
1578
1579         case 5:
1580                 req.type = SIM_FACILITY_PN;
1581         break;
1582
1583         case 6:
1584                 req.type = SIM_FACILITY_PU;
1585         break;
1586
1587         case 7:
1588                 req.type = SIM_FACILITY_PP;
1589         break;
1590
1591         case 8:
1592                 req.type = SIM_FACILITY_PC;
1593         break;
1594
1595         default:
1596                 err("Unhandled/Unknown Facility type: [0x%x]", facility_type);
1597
1598                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
1599
1600                 return TRUE;
1601         }
1602
1603         /* Dispatch request */
1604         dtapi_dispatch_request(ctx, sim, invocation,
1605                 TREQ_SIM_GET_LOCK_INFO,
1606                 &req, sizeof(struct treq_sim_get_lock_info));
1607
1608         return TRUE;
1609 }
1610
1611 static gboolean on_sim_transfer_apdu(TelephonySim *sim,
1612         GDBusMethodInvocation *invocation,
1613         GVariant *apdu, gpointer user_data)
1614 {
1615         struct custom_data *ctx = user_data;
1616         struct treq_sim_transmit_apdu req;
1617         GVariantIter *iter = NULL;
1618         GVariant *inner_gv = NULL;
1619         guchar rt_i;
1620         CoreObject *co_sim = NULL;
1621         int i = 0;
1622
1623         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1624         DBUS_SIM_CHECK_SIM_STATUS(invocation, TRANSFER_APDU, co_sim);
1625         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Transfer APDU");
1626
1627         memset(&req, 0x0, sizeof(struct treq_sim_transmit_apdu));
1628
1629         inner_gv = g_variant_get_variant(apdu);
1630
1631         g_variant_get(inner_gv, "ay", &iter);
1632         while (g_variant_iter_loop(iter, "y", &rt_i)) {
1633                 req.apdu[i] = rt_i;
1634                 i++;
1635         }
1636         req.apdu_length = (unsigned int)i;
1637         g_variant_iter_free(iter);
1638         //g_variant_unref(inner_gv);
1639         //g_variant_unref(apdu);
1640
1641         tcore_util_hex_dump("[APDU_REQ] ", req.apdu_length, req.apdu);
1642
1643         /* Dispatch request */
1644         dtapi_dispatch_request(ctx, sim, invocation,
1645                 TREQ_SIM_TRANSMIT_APDU,
1646                 &req, sizeof(struct treq_sim_transmit_apdu));
1647
1648         return TRUE;
1649 }
1650
1651 static gboolean on_sim_access_rsim_io(TelephonySim *sim,
1652         GDBusMethodInvocation *invocation, gint field,
1653         GVariant *rsimio, gint rec_index, gpointer user_data)
1654 {
1655         struct custom_data *ctx = user_data;
1656         struct treq_sim_access_rsim_io req;
1657         GVariantIter *iter = NULL;
1658         GVariant *inner_gv = NULL;
1659         guchar rt_i;
1660         CoreObject *co_sim = NULL;
1661         int i = 0;
1662
1663
1664         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1665         DBUS_SIM_CHECK_SIM_STATUS(invocation, ACCESS_RSIM_IO, co_sim);
1666         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Access Rsim IO");
1667
1668         memset(&req, 0x0, sizeof(struct treq_sim_access_rsim_io));
1669         req.field = field;
1670         req.rec_index = rec_index;
1671
1672         inner_gv = g_variant_get_variant(rsimio);
1673
1674         g_variant_get(inner_gv, "ay", &iter);
1675         while (g_variant_iter_loop(iter, "y", &rt_i)) {
1676                 req.data[i] = rt_i;
1677                 i++;
1678         }
1679         req.data_len = (unsigned int)i;
1680         g_variant_iter_free(iter);
1681         //g_variant_unref(inner_gv);
1682         //g_variant_unref(rsimio);
1683
1684         dbg("ef_id[%x], rec_index[%d]", req.field, req.rec_index);
1685         tcore_util_hex_dump("[RSIM_IO] ", req.data_len, req.data);
1686
1687         /* Dispatch request */
1688         dtapi_dispatch_request(ctx, sim, invocation,
1689                 TREQ_SIM_ACCESS_RSIM_IO,
1690                 &req, sizeof(struct treq_sim_access_rsim_io));
1691
1692         return TRUE;
1693 }
1694
1695 static gboolean on_sim_get_atr(TelephonySim *sim,
1696         GDBusMethodInvocation *invocation, gpointer user_data)
1697 {
1698         struct custom_data *ctx = user_data;
1699         CoreObject *co_sim = NULL;
1700
1701         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1702         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_ATR, co_sim);
1703         DBUS_SIM_CHECK_SIM_TYPE(co_sim, "Get ATR");
1704
1705         /* Dispatch request */
1706         dtapi_dispatch_request(ctx, sim, invocation,
1707                 TREQ_SIM_GET_ATR,
1708                 NULL, 0);
1709
1710         return TRUE;
1711 }
1712
1713 static gboolean on_sim_get_fields(TelephonySim *sim,
1714         GDBusMethodInvocation *invocation, gpointer user_data)
1715 {
1716         struct custom_data *ctx = user_data;
1717         struct tel_sim_imsi *n_imsi = NULL;
1718         CoreObject *co_sim = NULL;
1719         GVariantBuilder b;
1720         GVariant *gv_fields = NULL;
1721
1722         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1723
1724         g_variant_builder_init(&b, G_VARIANT_TYPE("a{svv}}"));
1725
1726         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_IMSI, co_sim);
1727
1728         n_imsi = tcore_sim_get_imsi(co_sim);
1729         if (n_imsi != NULL) {
1730                 g_variant_builder_add(&b, "{svv}", "imsi",
1731                         g_variant_new_string("plmn"),
1732                         g_variant_new_string(n_imsi->plmn));
1733                 g_variant_builder_add(&b, "{svv}", "imsi",
1734                         g_variant_new_string("msin"),
1735                         g_variant_new_string(n_imsi->msin));
1736                 free(n_imsi);
1737         }
1738
1739         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_ICCID, co_sim);
1740         g_variant_builder_add(&b, "{svv}", "iccid",
1741                 g_variant_new_string(""), g_variant_new_string(""));
1742
1743         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_MSISDN, co_sim);
1744         g_variant_builder_add(&b, "{svv}", "msisdn",
1745                 g_variant_new_string("name"), g_variant_new_string("number"));
1746
1747         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_SPN, co_sim);
1748         g_variant_builder_add(&b, "{svv}", "spn",
1749                 g_variant_new_uint16(255), g_variant_new_string("network name"));
1750
1751         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_INIT_STATUS, co_sim);
1752         g_variant_builder_add(&b, "{svv}", "init_status",
1753                 g_variant_new_uint16(0), g_variant_new_boolean(TRUE));
1754
1755         gv_fields = g_variant_builder_end(&b);
1756
1757         telephony_sim_complete_get_fields(sim,
1758                 invocation, 0, gv_fields);
1759
1760         return TRUE;
1761 }
1762
1763 static gboolean on_sim_set_power_state(TelephonySim *sim,
1764         GDBusMethodInvocation *invocation, gint state, gpointer user_data)
1765 {
1766         struct custom_data *ctx = user_data;
1767         CoreObject *co_sim = NULL;
1768         struct treq_sim_set_powerstate req;
1769         enum tel_sim_status present_sim_status;
1770
1771         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1772         DBUS_SIM_CHECK_SIM_STATUS(invocation, SET_POWERSTATE, co_sim);
1773
1774         memset(&req, 0x0, sizeof(struct treq_sim_set_powerstate));
1775
1776         req.state = state;
1777         dbg("[%s] Requested SIM Power state: [%d]",
1778                 GET_CP_NAME(invocation), req.state);
1779
1780         present_sim_status = tcore_sim_get_status(co_sim);
1781         if ((present_sim_status == SIM_STATUS_CARD_POWEROFF && state == SIM_POWER_OFF)
1782                 || (present_sim_status != SIM_STATUS_CARD_POWEROFF && state == SIM_POWER_ON)) {
1783                 dbg("SIM already %s", (state ? "ON" : "OFF"));
1784                 telephony_sim_complete_set_powerstate(sim, invocation, SIM_POWER_SET_SUCCESS);
1785                 return TRUE;
1786         }
1787
1788         /* Dispatch request */
1789         dtapi_dispatch_request(ctx, sim, invocation,
1790                 TREQ_SIM_SET_POWERSTATE,
1791                 &req, sizeof(struct treq_sim_set_powerstate));
1792
1793         return TRUE;
1794 }
1795
1796 static gboolean on_sim_get_impi(TelephonySim *sim,
1797         GDBusMethodInvocation *invocation, gpointer user_data)
1798 {
1799         struct custom_data *ctx = user_data;
1800         CoreObject *co_sim = NULL;
1801         char *impi = NULL;
1802
1803         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1804         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_IMPI, co_sim);
1805
1806         impi = tcore_sim_get_isim_impi(co_sim);
1807         if (!impi) {
1808                 /* Dispatch request */
1809                 dtapi_dispatch_request(ctx, sim, invocation,
1810                         TREQ_SIM_GET_IMPI,
1811                         NULL, 0);
1812         } else {
1813                 telephony_sim_complete_get_impi(sim,
1814                         invocation, SIM_ACCESS_SUCCESS, impi);
1815
1816                 g_free(impi);
1817         }
1818
1819         return TRUE;
1820 }
1821
1822 static gboolean on_sim_get_impu(TelephonySim *sim,
1823         GDBusMethodInvocation *invocation, gpointer user_data)
1824 {
1825         struct custom_data *ctx = user_data;
1826         CoreObject *co_sim = NULL;
1827
1828         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1829         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_IMPU, co_sim);
1830
1831         /* Dispatch request */
1832         dtapi_dispatch_request(ctx, sim, invocation,
1833                 TREQ_SIM_GET_IMPU,
1834                 NULL, 0);
1835
1836         return TRUE;
1837 }
1838
1839 static gboolean on_sim_get_domain(TelephonySim *sim,
1840         GDBusMethodInvocation *invocation, gpointer user_data)
1841 {
1842         struct custom_data *ctx = user_data;
1843         CoreObject *co_sim = NULL;
1844
1845         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1846         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_DOMAIN, co_sim);
1847
1848         /* Dispatch request */
1849         dtapi_dispatch_request(ctx, sim, invocation,
1850                 TREQ_SIM_GET_DOMAIN,
1851                 NULL, 0);
1852
1853         return TRUE;
1854 }
1855
1856 static gboolean on_sim_get_pcscf(TelephonySim *sim,
1857         GDBusMethodInvocation *invocation, gpointer user_data)
1858 {
1859         struct custom_data *ctx = user_data;
1860         CoreObject *co_sim = NULL;
1861
1862         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1863         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_PCSCF, co_sim);
1864
1865         /* Dispatch request */
1866         dtapi_dispatch_request(ctx, sim, invocation,
1867                 TREQ_SIM_GET_PCSCF,
1868                 NULL, 0);
1869
1870         return TRUE;
1871 }
1872
1873 static gboolean on_sim_get_app_list(TelephonySim *sim,
1874         GDBusMethodInvocation *invocation, gpointer user_data)
1875 {
1876         struct custom_data *ctx = user_data;
1877         CoreObject *co_sim = NULL;
1878         unsigned char app_list = 0;
1879
1880         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1881         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_APP_LIST, co_sim);
1882
1883         app_list = tcore_sim_get_app_list(co_sim);
1884
1885         telephony_sim_complete_get_app_list(sim,
1886                 invocation, app_list);
1887
1888         return TRUE;
1889 }
1890
1891 static gboolean on_sim_get_isim_service_table(TelephonySim *sim,
1892         GDBusMethodInvocation *invocation, gpointer user_data)
1893 {
1894         struct custom_data *ctx = user_data;
1895         struct tel_sim_ist *ist = NULL;
1896         CoreObject *co_sim = NULL;
1897
1898         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1899         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_ISIM_SERVICE_TABLE, co_sim);
1900
1901         ist = tcore_sim_get_isim_service_table(co_sim);
1902         if (ist) {
1903                 GVariantBuilder builder;
1904                 GVariant *ist_gv = NULL;
1905                 GVariant *inner_gv = NULL;
1906                 int i;
1907
1908                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
1909                 for (i = 0; i < SIM_IST_SERVICE_CNT_MAX; i++)
1910                         g_variant_builder_add(&builder, "y", ist->service[i]);
1911                 inner_gv = g_variant_builder_end(&builder);
1912                 ist_gv = g_variant_new("v", inner_gv);
1913
1914                 telephony_sim_complete_get_isim_service_table(sim, invocation,
1915                         SIM_ACCESS_SUCCESS, ist_gv);
1916
1917                 g_free(ist);
1918         } else {
1919                 /* Dispatch request */
1920                 dtapi_dispatch_request(ctx, sim, invocation,
1921                         TREQ_SIM_GET_ISIM_SERVICE_TABLE,
1922                         NULL, 0);
1923         }
1924
1925         return TRUE;
1926 }
1927
1928 static gboolean on_sim_get_cdmaimsi(TelephonySim *sim,
1929         GDBusMethodInvocation *invocation, gpointer user_data)
1930 {
1931         struct custom_data *ctx = user_data;
1932         CoreObject *co_sim = NULL;
1933
1934         DBUS_SIM_GET_COSIM(invocation, co_sim, ctx->server);
1935         DBUS_SIM_CHECK_SIM_STATUS(invocation, GET_CDMAIMSI, co_sim);
1936
1937         /* Dispatch request */
1938         dtapi_dispatch_request(ctx, sim, invocation,
1939                 TREQ_SIM_GET_CDMAIMSI,
1940                 NULL, 0);
1941
1942         return TRUE;
1943 }
1944
1945 gboolean dbus_plugin_setup_sim_interface(TelephonyObjectSkeleton *object,
1946         struct custom_data *ctx)
1947 {
1948         TelephonySim *sim;
1949
1950         sim = telephony_sim_skeleton_new();
1951         telephony_object_skeleton_set_sim(object, sim);
1952         g_object_unref(sim);
1953
1954         dbg("sim = %p", sim);
1955
1956         /*
1957          * Register signal handlers for SIM interface
1958          */
1959         g_signal_connect(sim,
1960                 "handle-get-init-status",
1961                 G_CALLBACK(on_sim_get_init_status), ctx);
1962
1963         g_signal_connect(sim,
1964                 "handle-get-card-type",
1965                 G_CALLBACK(on_sim_get_card_type), ctx);
1966
1967         g_signal_connect(sim,
1968                 "handle-get-imsi",
1969                 G_CALLBACK(on_sim_get_imsi), ctx);
1970
1971         g_signal_connect(sim,
1972                 "handle-get-ecc",
1973                 G_CALLBACK(on_sim_get_ecc), ctx);
1974
1975         g_signal_connect(sim,
1976                 "handle-get-iccid",
1977                 G_CALLBACK(on_sim_get_iccid), ctx);
1978
1979         g_signal_connect(sim,
1980                 "handle-get-language",
1981                 G_CALLBACK(on_sim_get_language), ctx);
1982
1983         g_signal_connect(sim,
1984                 "handle-set-language",
1985                 G_CALLBACK(on_sim_set_language), ctx);
1986
1987         g_signal_connect(sim,
1988                 "handle-get-call-forwarding",
1989                 G_CALLBACK(on_sim_get_call_forwarding), ctx);
1990
1991         g_signal_connect(sim,
1992                 "handle-set-call-forwarding",
1993                 G_CALLBACK(on_sim_set_call_forwarding), ctx);
1994
1995         g_signal_connect(sim,
1996                 "handle-get-message-waiting",
1997                 G_CALLBACK(on_sim_get_message_waiting), ctx);
1998
1999         g_signal_connect(sim,
2000                 "handle-set-message-waiting",
2001                 G_CALLBACK(on_sim_set_message_waiting), ctx);
2002
2003         g_signal_connect(sim,
2004                 "handle-get-mailbox",
2005                 G_CALLBACK(on_sim_get_mailbox), ctx);
2006
2007         g_signal_connect(sim,
2008                 "handle-set-mailbox",
2009                 G_CALLBACK(on_sim_set_mailbox), ctx);
2010
2011         g_signal_connect(sim,
2012                 "handle-get-cphsinfo",
2013                 G_CALLBACK(on_sim_get_cphsinfo), ctx);
2014
2015         g_signal_connect(sim,
2016                 "handle-get-service-table",
2017                 G_CALLBACK(on_sim_get_service_table), ctx);
2018
2019         g_signal_connect(sim,
2020                 "handle-get-msisdn",
2021                 G_CALLBACK(on_sim_get_msisdn), ctx);
2022
2023         g_signal_connect(sim,
2024                 "handle-get-oplmnwact",
2025                 G_CALLBACK(on_sim_get_oplmnwact), ctx);
2026
2027         g_signal_connect(sim,
2028                 "handle-get-psismsc",
2029                 G_CALLBACK(on_sim_get_psismsc), ctx);
2030
2031         g_signal_connect(sim,
2032                 "handle-get-spn",
2033                 G_CALLBACK(on_sim_get_spn), ctx);
2034
2035         g_signal_connect(sim,
2036                 "handle-get-cphs-net-name",
2037                 G_CALLBACK(on_sim_get_cphs_netname), ctx);
2038
2039         g_signal_connect(sim,
2040                 "handle-get-gid",
2041                 G_CALLBACK(on_sim_get_gid), ctx);
2042
2043         g_signal_connect(sim,
2044                 "handle-authentication",
2045                 G_CALLBACK(on_sim_authentication), ctx);
2046
2047         g_signal_connect(sim,
2048                 "handle-verify-sec",
2049                 G_CALLBACK(on_sim_verify_sec), ctx);
2050
2051         g_signal_connect(sim,
2052                 "handle-verify-puk",
2053                 G_CALLBACK(on_sim_verify_puk), ctx);
2054
2055         g_signal_connect(sim,
2056                 "handle-change-pin",
2057                 G_CALLBACK(on_sim_change_pin), ctx);
2058
2059         g_signal_connect(sim,
2060                 "handle-disable-facility",
2061                 G_CALLBACK(on_sim_disable_facility), ctx);
2062
2063         g_signal_connect(sim,
2064                 "handle-enable-facility",
2065                 G_CALLBACK(on_sim_enable_facility), ctx);
2066
2067         g_signal_connect(sim,
2068                 "handle-get-facility",
2069                 G_CALLBACK(on_sim_get_facility), ctx);
2070
2071         g_signal_connect(sim,
2072                 "handle-get-lock-info",
2073                 G_CALLBACK(on_sim_get_lock_info), ctx);
2074
2075         g_signal_connect(sim,
2076                 "handle-transfer-apdu",
2077                 G_CALLBACK(on_sim_transfer_apdu), ctx);
2078
2079         g_signal_connect(sim,
2080                 "handle-access-rsim-io",
2081                 G_CALLBACK(on_sim_access_rsim_io), ctx);
2082
2083         g_signal_connect(sim,
2084                 "handle-get-atr",
2085                 G_CALLBACK(on_sim_get_atr), ctx);
2086
2087         g_signal_connect(sim,
2088                 "handle-get-fields",
2089                 G_CALLBACK(on_sim_get_fields), ctx);
2090
2091         g_signal_connect(sim,
2092                 "handle-set-powerstate",
2093                 G_CALLBACK(on_sim_set_power_state), ctx);
2094
2095         g_signal_connect(sim,
2096                 "handle-get-impi",
2097                 G_CALLBACK(on_sim_get_impi), ctx);
2098
2099         g_signal_connect(sim,
2100                 "handle-get-impu",
2101                 G_CALLBACK(on_sim_get_impu), ctx);
2102
2103         g_signal_connect(sim,
2104                 "handle-get-domain",
2105                 G_CALLBACK(on_sim_get_domain), ctx);
2106
2107         g_signal_connect(sim,
2108                 "handle-get-pcscf",
2109                 G_CALLBACK(on_sim_get_pcscf), ctx);
2110
2111         g_signal_connect(sim,
2112                 "handle-get-app-list",
2113                 G_CALLBACK(on_sim_get_app_list), ctx);
2114
2115         g_signal_connect(sim,
2116                 "handle-get-isim-service-table",
2117                 G_CALLBACK(on_sim_get_isim_service_table), ctx);
2118
2119         g_signal_connect(sim,
2120                 "handle-get-cdmaimsi",
2121                 G_CALLBACK(on_sim_get_cdmaimsi), ctx);
2122
2123         /*
2124          * Initialize DBUS property
2125          */
2126         telephony_sim_set_cf_state(sim, FALSE);
2127
2128         return TRUE;
2129 }
2130
2131 gboolean dbus_plugin_sim_response(struct custom_data *ctx,
2132         UserRequest *ur, struct dbus_request_info *dbus_info,
2133         enum tcore_response_command command, unsigned int data_len, const void *data)
2134 {
2135         char *cpname = GET_CP_NAME(dbus_info->invocation);
2136
2137         switch (command) {
2138         case TRESP_SIM_GET_ECC: {
2139                 const struct tresp_sim_read *resp_read = data;
2140                 CoreObject *co_sim = NULL;
2141                 GVariant *gv = NULL;
2142                 GVariantBuilder b;
2143                 int i = 0;
2144
2145                 dbg("[%s] SIM_GET_ECC - Result: [%s])", cpname,
2146                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2147
2148                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2149                 if (!co_sim) {
2150                         err("SIM Core object is NULL");
2151                         return FALSE;
2152                 }
2153
2154                 if (resp_read->result == SIM_ACCESS_SUCCESS)
2155                         tcore_sim_set_ecc_list(co_sim, &resp_read->data.ecc);
2156                 else if (resp_read->result == SIM_ACCESS_FILE_NOT_FOUND)
2157                         tcore_sim_set_ecc_list(co_sim, NULL);
2158
2159                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2160                 for (i = 0; i < resp_read->data.ecc.ecc_count; i++) {
2161                         dbg("[%s] ecc[%d] : ecc_category=[0x%x], ecc_num=[%s], " \
2162                                 "ecc_string=[%s]", cpname, i,
2163                                 resp_read->data.ecc.ecc[i].ecc_category,
2164                                 resp_read->data.ecc.ecc[i].ecc_num,
2165                                 resp_read->data.ecc.ecc[i].ecc_string);
2166
2167                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2168                         g_variant_builder_add(&b, "{sv}", "category",
2169                                 g_variant_new_int32(resp_read->data.ecc.ecc[i].ecc_category));
2170                         g_variant_builder_add(&b, "{sv}", "number",
2171                                 g_variant_new_string(resp_read->data.ecc.ecc[i].ecc_num));
2172                         g_variant_builder_add(&b, "{sv}", "name",
2173                                 g_variant_new_string(resp_read->data.ecc.ecc[i].ecc_string));
2174                         g_variant_builder_close(&b);
2175                 }
2176                 gv = g_variant_builder_end(&b);
2177
2178                 telephony_sim_complete_get_ecc(dbus_info->interface_object,
2179                         dbus_info->invocation, gv);
2180         }
2181         break;
2182
2183         case TRESP_SIM_GET_ICCID: {
2184                 const struct tresp_sim_read *resp_read = data;
2185                 CoreObject *co_sim = NULL;
2186
2187                 dbg("[%s] SIM_GET_ICCID - Result: [%s] ICCID: [%s])", cpname,
2188                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2189                          resp_read->data.iccid.iccid);
2190
2191                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2192                 if (!co_sim) {
2193                         err("SIM Core object is NULL");
2194                         return FALSE;
2195                 }
2196
2197                 if (resp_read->result == SIM_ACCESS_SUCCESS)
2198                         tcore_sim_set_iccid(co_sim, &resp_read->data.iccid);
2199                 else if (resp_read->result == SIM_ACCESS_FILE_NOT_FOUND)
2200                         tcore_sim_set_iccid(co_sim, NULL);
2201
2202                 telephony_sim_complete_get_iccid(dbus_info->interface_object,
2203                         dbus_info->invocation, resp_read->result,
2204                         resp_read->data.iccid.iccid);
2205         }
2206         break;
2207
2208         case TRESP_SIM_GET_LANGUAGE: {
2209                 const struct tresp_sim_read *resp_read = data;
2210
2211                 dbg("[%s] SIM_GET_LANGUAGE - Result: [%s] Language: [0x%2x]", cpname,
2212                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2213                         resp_read->data.language.language[0]);
2214
2215                 telephony_sim_complete_get_language(dbus_info->interface_object,
2216                         dbus_info->invocation, resp_read->result,
2217                         resp_read->data.language.language[0]);
2218         }
2219         break;
2220
2221         case TRESP_SIM_SET_LANGUAGE: {
2222                 const struct tresp_sim_set_data *resp_set_data = data;
2223
2224                 dbg("[%s] SIM_SET_LANGUAGE - Result: [%s]", cpname,
2225                         (resp_set_data->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2226
2227                 telephony_sim_complete_set_language(dbus_info->interface_object,
2228                         dbus_info->invocation, resp_set_data->result);
2229         }
2230         break;
2231
2232         case TRESP_SIM_GET_CALLFORWARDING: {
2233                 const struct tresp_sim_read *resp_read = data;
2234                 GVariant *gv_cf = NULL;
2235                 GVariant *gv_cphs_cf = NULL;
2236                 GVariantBuilder b;
2237
2238                 dbg("[%s] SIM_GET_CALLFORWARDING - Result: [%s] CPHS: [%s]",
2239                         cpname, (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2240                         (resp_read->data.cf.b_cphs ? "Yes" : "No"));
2241
2242                 if (resp_read->data.cf.b_cphs) {
2243                         dbg("[%s] b_line1[%d], b_line2[%d], b_fax[%d], b_data[%d]",
2244                                 cpname, resp_read->data.cf.cphs_cf.b_line1,
2245                                 resp_read->data.cf.cphs_cf.b_line2,
2246                                 resp_read->data.cf.cphs_cf.b_fax,
2247                                 resp_read->data.cf.cphs_cf.b_data);
2248
2249                         g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
2250                         g_variant_builder_add(&b, "{sv}", "b_line1",
2251                                 g_variant_new_boolean(resp_read->data.cf.cphs_cf.b_line1));
2252                         g_variant_builder_add(&b, "{sv}", "b_line2",
2253                                 g_variant_new_boolean(resp_read->data.cf.cphs_cf.b_line2));
2254                         g_variant_builder_add(&b, "{sv}", "b_fax",
2255                                 g_variant_new_boolean(resp_read->data.cf.cphs_cf.b_fax));
2256                         g_variant_builder_add(&b, "{sv}", "b_data",
2257                                 g_variant_new_boolean(resp_read->data.cf.cphs_cf.b_data));
2258                         gv_cphs_cf = g_variant_builder_end(&b);
2259
2260                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2261                         gv_cf = g_variant_builder_end(&b);
2262
2263                 } else {
2264                         int i = 0;
2265
2266                         dbg("[%s] Profile count: [%d]", cpname, resp_read->data.cf.cf_list.profile_count);
2267
2268                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2269                         for (i = 0; i < resp_read->data.cf.cf_list.profile_count; i++) {
2270                                 dbg("[%s] [%d] : rec_index[0x%x], msp_num[0x%x], " \
2271                                         "cfu_status[0x%x], cfu_num[%s], ton[0x%x], " \
2272                                         "npi[0x%x], cc2_id[0x%x], ext7_id[0x%x]", cpname, i,
2273                                         resp_read->data.cf.cf_list.cf[i].rec_index,
2274                                         resp_read->data.cf.cf_list.cf[i].msp_num,
2275                                         resp_read->data.cf.cf_list.cf[i].cfu_status,
2276                                         resp_read->data.cf.cf_list.cf[i].cfu_num,
2277                                         resp_read->data.cf.cf_list.cf[i].ton,
2278                                         resp_read->data.cf.cf_list.cf[i].npi,
2279                                         resp_read->data.cf.cf_list.cf[i].cc2_id,
2280                                         resp_read->data.cf.cf_list.cf[i].ext7_id);
2281
2282                                 g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2283                                 g_variant_builder_add(&b, "{sv}", "rec_index",
2284                                         g_variant_new_int32(resp_read->data.cf.cf_list.cf[i].rec_index));
2285                                 g_variant_builder_add(&b, "{sv}", "msp_num",
2286                                         g_variant_new_byte(resp_read->data.cf.cf_list.cf[i].msp_num));
2287                                 g_variant_builder_add(&b, "{sv}", "cfu_status",
2288                                         g_variant_new_byte(resp_read->data.cf.cf_list.cf[i].cfu_status));
2289                                 g_variant_builder_add(&b, "{sv}", "cfu_num",
2290                                         g_variant_new_string(resp_read->data.cf.cf_list.cf[i].cfu_num));
2291                                 g_variant_builder_add(&b, "{sv}", "ton",
2292                                         g_variant_new_int32(resp_read->data.cf.cf_list.cf[i].ton));
2293                                 g_variant_builder_add(&b, "{sv}", "npi",
2294                                         g_variant_new_int32(resp_read->data.cf.cf_list.cf[i].npi));
2295                                 g_variant_builder_add(&b, "{sv}", "cc2_id",
2296                                         g_variant_new_byte(resp_read->data.cf.cf_list.cf[i].cc2_id));
2297                                 g_variant_builder_add(&b, "{sv}", "ext7_id",
2298                                         g_variant_new_byte(resp_read->data.cf.cf_list.cf[i].ext7_id));
2299                                 g_variant_builder_close(&b);
2300                         }
2301                         gv_cf = g_variant_builder_end(&b);
2302
2303                         g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
2304                         gv_cphs_cf = g_variant_builder_end(&b);
2305                 }
2306
2307                 telephony_sim_complete_get_call_forwarding(dbus_info->interface_object,
2308                         dbus_info->invocation, resp_read->result,
2309                         resp_read->data.cf.b_cphs, gv_cf, gv_cphs_cf);
2310         }
2311         break;
2312
2313         case TRESP_SIM_SET_CALLFORWARDING: {
2314                 const struct tresp_sim_set_data *resp_set_data = data;
2315
2316                 dbg("[%s] SIM_SET_CALLFORWARDING - Result: [%s]", cpname,
2317                         (resp_set_data->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2318
2319                 telephony_sim_complete_set_call_forwarding(dbus_info->interface_object,
2320                         dbus_info->invocation, resp_set_data->result);
2321         }
2322         break;
2323
2324         case TRESP_SIM_GET_MESSAGEWAITING: {
2325                 const struct tresp_sim_read *resp_read = data;
2326                 GVariant *gv_mw = NULL;
2327                 GVariant *gv_cphs_mw = NULL;
2328                 GVariantBuilder b;
2329
2330                 dbg("[%s] SIM_GET_MESSAGEWAITING - Result: [%s] CPHS: [%s]",
2331                         cpname, (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2332                         (resp_read->data.mw.b_cphs ? "Yes" : "No"));
2333
2334                 if (resp_read->data.mw.b_cphs) {
2335                         dbg("[%s] b_voice1[%d], b_voice2[%d], b_fax[%d], b_data[%d]",
2336                                 cpname, resp_read->data.mw.cphs_mw.b_voice1,
2337                                 resp_read->data.mw.cphs_mw.b_voice2,
2338                                 resp_read->data.mw.cphs_mw.b_fax,
2339                                 resp_read->data.mw.cphs_mw.b_data);
2340
2341                         g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
2342                         g_variant_builder_add(&b, "{sv}", "b_voice1",
2343                                 g_variant_new_boolean(resp_read->data.mw.cphs_mw.b_voice1));
2344                         g_variant_builder_add(&b, "{sv}", "b_voice2",
2345                                 g_variant_new_boolean(resp_read->data.mw.cphs_mw.b_voice2));
2346                         g_variant_builder_add(&b, "{sv}", "b_fax",
2347                                 g_variant_new_boolean(resp_read->data.mw.cphs_mw.b_fax));
2348                         g_variant_builder_add(&b, "{sv}", "b_data",
2349                                 g_variant_new_boolean(resp_read->data.mw.cphs_mw.b_data));
2350                         gv_cphs_mw = g_variant_builder_end(&b);
2351
2352                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2353                         gv_mw = g_variant_builder_end(&b);
2354
2355                 } else {
2356                         int i = 0;
2357
2358                         dbg("[%s] Profile count: [%d]", cpname,
2359                                 resp_read->data.mw.mw_list.profile_count);
2360
2361                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2362                         for (i = 0; i < resp_read->data.mw.mw_list.profile_count; i++) {
2363                                 dbg("[%s] mw[%d] : rec_index[0x%x], indicator_status[0x%x], " \
2364                                         "voice_count[0x%x], fax_count[0x%x] email_count[0x%x], " \
2365                                         "other_count[0x%x], video_count[0x%x]", cpname, i,
2366                                         resp_read->data.mw.mw_list.mw[i].rec_index,
2367                                         resp_read->data.mw.mw_list.mw[i].indicator_status,
2368                                         resp_read->data.mw.mw_list.mw[i].voice_count,
2369                                         resp_read->data.mw.mw_list.mw[i].fax_count,
2370                                         resp_read->data.mw.mw_list.mw[i].email_count,
2371                                         resp_read->data.mw.mw_list.mw[i].other_count,
2372                                         resp_read->data.mw.mw_list.mw[i].video_count);
2373
2374                                 g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2375                                 g_variant_builder_add(&b, "{sv}", "rec_index",
2376                                         g_variant_new_int32(resp_read->data.mw.mw_list.mw[i].rec_index));
2377                                 g_variant_builder_add(&b, "{sv}", "indicator_status",
2378                                         g_variant_new_byte(resp_read->data.mw.mw_list.mw[i].indicator_status));
2379                                 g_variant_builder_add(&b, "{sv}", "voice_count",
2380                                         g_variant_new_int32(resp_read->data.mw.mw_list.mw[i].voice_count));
2381                                 g_variant_builder_add(&b, "{sv}", "fax_count",
2382                                         g_variant_new_int32(resp_read->data.mw.mw_list.mw[i].fax_count));
2383                                 g_variant_builder_add(&b, "{sv}", "email_count",
2384                                         g_variant_new_int32(resp_read->data.mw.mw_list.mw[i].email_count));
2385                                 g_variant_builder_add(&b, "{sv}", "other_count",
2386                                         g_variant_new_int32(resp_read->data.mw.mw_list.mw[i].other_count));
2387                                 g_variant_builder_add(&b, "{sv}", "video_count",
2388                                         g_variant_new_int32(resp_read->data.mw.mw_list.mw[i].video_count));
2389                                 g_variant_builder_close(&b);
2390                         }
2391                         gv_mw = g_variant_builder_end(&b);
2392                         g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
2393                         gv_cphs_mw = g_variant_builder_end(&b);
2394                 }
2395
2396                 telephony_sim_complete_get_message_waiting(dbus_info->interface_object,
2397                         dbus_info->invocation, resp_read->result,
2398                         resp_read->data.mw.b_cphs, gv_mw, gv_cphs_mw);
2399         }
2400         break;
2401
2402         case TRESP_SIM_SET_MESSAGEWAITING: {
2403                 const struct tresp_sim_set_data *resp_set_data = data;
2404
2405                 dbg("[%s] SIM_SET_MESSAGEWAITING - Result: [%s]",
2406                         cpname, (resp_set_data->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2407
2408                 telephony_sim_complete_set_message_waiting(dbus_info->interface_object,
2409                         dbus_info->invocation, resp_set_data->result);
2410         }
2411         break;
2412
2413         case TRESP_SIM_GET_MAILBOX: {
2414                 const struct tresp_sim_read *resp_read = data;
2415                 GVariant *gv = NULL;
2416                 GVariantBuilder b;
2417                 int i = 0;
2418
2419                 dbg("[%s] SIM_GET_MAILBOX - Result: [%s] CPHS: [%s] Count: [%d])",
2420                         cpname, (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2421                         (resp_read->data.mb.b_cphs ? "Yes" : "No"),
2422                         resp_read->data.mb.count);
2423
2424                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2425                 for (i = 0; i < resp_read->data.mb.count; i++) {
2426                         dbg("[%s] mb[%d] : rec_index[%d], profile_number[%d], mb_type[%d], " \
2427                                 "alpha_id_max_len[%d]alpha_id[%s], ton[%d], npi[%d], num[%s], " \
2428                                 "cc_id[%d], ext1_id[%d]", cpname, i,
2429                                 resp_read->data.mb.mb[i].rec_index, resp_read->data.mb.mb[i].profile_number,
2430                                 resp_read->data.mb.mb[i].mb_type, resp_read->data.mb.mb[i].number_info.alpha_id_max_len,
2431                                 resp_read->data.mb.mb[i].number_info.alpha_id, resp_read->data.mb.mb[i].number_info.ton,
2432                                 resp_read->data.mb.mb[i].number_info.npi, resp_read->data.mb.mb[i].number_info.num,
2433                                 resp_read->data.mb.mb[i].number_info.cc_id, resp_read->data.mb.mb[i].number_info.ext1_id);
2434
2435                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2436                         g_variant_builder_add(&b, "{sv}", "rec_index",
2437                         g_variant_new_int32(resp_read->data.mb.mb[i].rec_index));
2438                         g_variant_builder_add(&b, "{sv}", "profile_num",
2439                         g_variant_new_int32(resp_read->data.mb.mb[i].profile_number));
2440                         g_variant_builder_add(&b, "{sv}", "mb_type",
2441                         g_variant_new_int32(resp_read->data.mb.mb[i].mb_type));
2442                         g_variant_builder_add(&b, "{sv}", "alpha_id_max_len",
2443                         g_variant_new_int32(resp_read->data.mb.mb[i].number_info.alpha_id_max_len));
2444                         g_variant_builder_add(&b, "{sv}", "alpha_id",
2445                         g_variant_new_string(resp_read->data.mb.mb[i].number_info.alpha_id));
2446                         g_variant_builder_add(&b, "{sv}", "ton",
2447                         g_variant_new_int32(resp_read->data.mb.mb[i].number_info.ton));
2448                         g_variant_builder_add(&b, "{sv}", "npi",
2449                         g_variant_new_int32(resp_read->data.mb.mb[i].number_info.npi));
2450                         g_variant_builder_add(&b, "{sv}", "num",
2451                         g_variant_new_string(resp_read->data.mb.mb[i].number_info.num));
2452                         g_variant_builder_add(&b, "{sv}", "cc_id",
2453                         g_variant_new_byte(resp_read->data.mb.mb[i].number_info.cc_id));
2454                         g_variant_builder_add(&b, "{sv}", "ext1_id",
2455                         g_variant_new_byte(resp_read->data.mb.mb[i].number_info.ext1_id));
2456                         g_variant_builder_close(&b);
2457                 }
2458
2459                 gv = g_variant_builder_end(&b);
2460
2461                 telephony_sim_complete_get_mailbox(dbus_info->interface_object, dbus_info->invocation,
2462                         resp_read->result, resp_read->data.mb.b_cphs, gv);
2463         }
2464         break;
2465
2466         case TRESP_SIM_SET_MAILBOX: {
2467                 const struct tresp_sim_set_data *resp_set_data = data;
2468
2469                 dbg("[%s] SIM_SET_MAILBOX - Result: [%s]", cpname,
2470                         (resp_set_data->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2471
2472                 telephony_sim_complete_set_mailbox(dbus_info->interface_object,
2473                         dbus_info->invocation, resp_set_data->result);
2474         }
2475         break;
2476
2477         case TRESP_SIM_GET_CPHS_INFO: {
2478                 const struct tresp_sim_read *resp_read = data;
2479
2480                 dbg("[%s] SIM_GET_CPHS_INFO - Result: [%s]", cpname,
2481                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2482
2483                 telephony_sim_complete_get_cphsinfo(dbus_info->interface_object,
2484                         dbus_info->invocation, resp_read->result,
2485                         resp_read->data.cphs.CphsPhase,
2486                         resp_read->data.cphs.CphsServiceTable.bOperatorNameShortForm,
2487                         resp_read->data.cphs.CphsServiceTable.bMailBoxNumbers,
2488                         resp_read->data.cphs.CphsServiceTable.bServiceStringTable,
2489                         resp_read->data.cphs.CphsServiceTable.bCustomerServiceProfile,
2490                         resp_read->data.cphs.CphsServiceTable.bInformationNumbers);
2491         }
2492         break;
2493
2494         case TRESP_SIM_GET_SERVICE_TABLE: {
2495                 const struct tresp_sim_read *resp_read = data;
2496                 CoreObject *co_sim = NULL;
2497                 GVariantBuilder builder;
2498                 GVariant * inner_gv = NULL;
2499                 GVariant *svct_gv = NULL;
2500                 int i = 0;
2501
2502                 dbg("[%s] SIM_GET_SERVICE_TABLE - Result: [%s]", cpname,
2503                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2504
2505                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2506                 if (!co_sim) {
2507                         err("SIM Core object is NULL");
2508                         return FALSE;
2509                 }
2510
2511                 if (resp_read->result == SIM_ACCESS_SUCCESS)
2512                         tcore_sim_set_service_table(co_sim, &resp_read->data.svct);
2513                 else if (resp_read->result == SIM_ACCESS_FILE_NOT_FOUND)
2514                         tcore_sim_set_service_table(co_sim, NULL);
2515
2516                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2517                 if (resp_read->data.svct.sim_type == SIM_TYPE_GSM) {
2518                         for (i = 0; i < SIM_SST_SERVICE_CNT_MAX; i++)
2519                                 g_variant_builder_add(&builder, "y",
2520                                         resp_read->data.svct.table.sst.service[i]);
2521                 } else if (resp_read->data.svct.sim_type == SIM_TYPE_USIM) {
2522                         for (i = 0; i < SIM_UST_SERVICE_CNT_MAX; i++)
2523                                 g_variant_builder_add(&builder, "y",
2524                                         resp_read->data.svct.table.ust.service[i]);
2525                 }
2526                 /*
2527                  * Todo: new interface such as tel_get_sim_cdma_service_table(CDMA or CSIM) like tel_get_sim_isim_service_table() is needed.
2528                  * Because it's not possible to distiguish client want GSM service table or CDMA service table with one interface.
2529                  *
2530                  * Or we can extend current 'struct tel_sim_service_table' to get sst/ust & cst simultaneously.
2531                  */
2532                 else {
2533                         dbg("unknown sim type[%d].", resp_read->data.svct.sim_type);
2534                 }
2535                 inner_gv = g_variant_builder_end(&builder);
2536                 svct_gv = g_variant_new("v", inner_gv);
2537
2538                 telephony_sim_complete_get_service_table(dbus_info->interface_object,
2539                         dbus_info->invocation, resp_read->result,
2540                         resp_read->data.svct.sim_type, svct_gv);
2541         }
2542         break;
2543
2544         case TRESP_SIM_GET_SPN: {
2545                 const struct tresp_sim_read *resp_read = data;
2546                 CoreObject *co_sim = NULL;
2547
2548                 dbg("[%s] SIM_GET_SPN - Result: [%s] Display condition: [%d] SPN: [%s]",
2549                         cpname, (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2550                         resp_read->data.spn.display_condition, (const gchar *)resp_read->data.spn.spn);
2551
2552                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2553                 if (!co_sim) {
2554                         err("SIM Core object is NULL");
2555                         return FALSE;
2556                 }
2557
2558                 if (resp_read->result == SIM_ACCESS_SUCCESS)
2559                         tcore_sim_set_spn(co_sim, &resp_read->data.spn);
2560                 else if (resp_read->result == SIM_ACCESS_FILE_NOT_FOUND)
2561                         tcore_sim_set_spn(co_sim, NULL);
2562
2563                 telephony_sim_complete_get_spn(dbus_info->interface_object,
2564                         dbus_info->invocation, resp_read->result,
2565                         resp_read->data.spn.display_condition,
2566                         (const gchar *)resp_read->data.spn.spn);
2567         }
2568         break;
2569
2570         case TRESP_SIM_GET_CPHS_NETNAME: {
2571                 const struct tresp_sim_read *resp_read = data;
2572                 CoreObject *co_sim = NULL;
2573
2574                 dbg("[%s] SIM_GET_CPHS_NETNAME - Result: [%s]", cpname,
2575                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2576
2577                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2578                 if (!co_sim) {
2579                         err("SIM Core object is NULL");
2580                         return FALSE;
2581                 }
2582
2583                 if (resp_read->result == SIM_ACCESS_SUCCESS)
2584                         tcore_sim_set_cphs_netname(co_sim, &resp_read->data.cphs_net);
2585                 else if (resp_read->result == SIM_ACCESS_FILE_NOT_FOUND)
2586                         tcore_sim_set_cphs_netname(co_sim, NULL);
2587
2588                 telephony_sim_complete_get_cphs_net_name(dbus_info->interface_object,
2589                         dbus_info->invocation, resp_read->result,
2590                         (const gchar *)resp_read->data.cphs_net.full_name,
2591                         (const gchar *)resp_read->data.cphs_net.short_name);
2592         }
2593         break;
2594
2595         case TRESP_SIM_GET_GID: {
2596                 const struct tresp_sim_read *resp_read = data;
2597                 GVariantBuilder builder;
2598                 GVariant *inner_gv = NULL;
2599                 GVariant *gid_gv = NULL;
2600                 int i = 0;
2601
2602                 dbg("[%s] SIM_GET_GID - Result: [%s]", cpname,
2603                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2604
2605                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2606                 for (i = 0; i < resp_read->data.gid.GroupIdentifierLen; i++)
2607                         g_variant_builder_add(&builder, "y", resp_read->data.gid.szGroupIdentifier[i]);
2608                 inner_gv = g_variant_builder_end(&builder);
2609                 gid_gv = g_variant_new("v", inner_gv);
2610
2611                 telephony_sim_complete_get_gid(dbus_info->interface_object,
2612                         dbus_info->invocation, resp_read->result,
2613                         resp_read->data.gid.GroupIdentifierLen, gid_gv);
2614         }
2615         break;
2616
2617         case TRESP_SIM_GET_MSISDN:{
2618                 const struct tresp_sim_read *resp_read = data;
2619                 CoreObject *co_sim = NULL;
2620                 GVariant *gv = NULL;
2621                 GVariantBuilder b;
2622                 int i = 0;
2623
2624                 dbg("[%s] SIM_GET_MSISDN - Result: [%s]", cpname,
2625                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2626
2627                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2628                 if (!co_sim) {
2629                         err("SIM Core object is NULL");
2630                         return FALSE;
2631                 }
2632
2633                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2634                 if (resp_read->result == SIM_ACCESS_SUCCESS)
2635                         tcore_sim_set_msisdn_list(co_sim, &resp_read->data.msisdn_list);
2636                 else if (resp_read->result == SIM_ACCESS_FILE_NOT_FOUND)
2637                         tcore_sim_set_msisdn_list(co_sim, NULL);
2638
2639                 for (i = 0; i < resp_read->data.msisdn_list.count; i++) {
2640                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2641                         g_variant_builder_add(&b, "{sv}", "name",
2642                                 g_variant_new_string((const gchar *)resp_read->data.msisdn_list.msisdn[i].name));
2643                         if (resp_read->data.msisdn_list.msisdn[i].ton == SIM_TON_INTERNATIONAL) {
2644                                 unsigned char *tmp = (unsigned char *)calloc(SIM_MSISDN_NUMBER_LEN_MAX + 1, 1);
2645                                 if (tmp != NULL) {
2646                                         tmp[0] = '+';
2647
2648                                         strncpy((char *)tmp + 1,
2649                                                 (const char*)resp_read->data.msisdn_list.msisdn[i].num,
2650                                                 SIM_MSISDN_NUMBER_LEN_MAX - 1);
2651                                         tmp[SIM_MSISDN_NUMBER_LEN_MAX] = '\0';
2652
2653                                         g_variant_builder_add(&b, "{sv}", "number",
2654                                                 g_variant_new_string((const gchar *)tmp));
2655                                         free(tmp);
2656                                 } else {
2657                                         dbg("Memory allocation failed");
2658
2659                                         g_variant_builder_add(&b, "{sv}", "number",
2660                                                 g_variant_new_string((const gchar *)resp_read->data.msisdn_list.msisdn[i].num));
2661                                 }
2662                         } else {
2663                                 g_variant_builder_add(&b, "{sv}", "number",
2664                                         g_variant_new_string((const gchar *)resp_read->data.msisdn_list.msisdn[i].num));
2665                         }
2666                         g_variant_builder_close(&b);
2667                 }
2668                 gv = g_variant_builder_end(&b);
2669
2670                 telephony_sim_complete_get_msisdn(dbus_info->interface_object,
2671                         dbus_info->invocation, resp_read->result, gv);
2672         }
2673         break;
2674
2675         case TRESP_SIM_GET_OPLMNWACT: {
2676                 const struct tresp_sim_read *resp_read = data;
2677                 GVariant *gv = NULL;
2678                 GVariantBuilder b;
2679                 int i = 0;
2680
2681                 dbg("[%s] SIM_GET_OPLMNWACT - Result: [%s]", cpname,
2682                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2683
2684                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2685                 for (i = 0; i < resp_read->data.opwa.opwa_count; i++) {
2686                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2687                         g_variant_builder_add(&b, "{sv}", "plmn",
2688                                 g_variant_new_string((const gchar *)resp_read->data.opwa.opwa[i].plmn));
2689                         g_variant_builder_add(&b, "{sv}", "b_umts",
2690                                 g_variant_new_boolean(resp_read->data.opwa.opwa[i].b_umts));
2691                         g_variant_builder_add(&b, "{sv}", "b_gsm",
2692                                 g_variant_new_boolean(resp_read->data.opwa.opwa[i].b_gsm));
2693                         g_variant_builder_close(&b);
2694                 }
2695                 gv = g_variant_builder_end(&b);
2696
2697                 telephony_sim_complete_get_oplmnwact(dbus_info->interface_object,
2698                         dbus_info->invocation, resp_read->result, gv);
2699         }
2700         break;
2701
2702         case TRESP_SIM_GET_PSISMSC:{
2703                 const struct tresp_sim_read *resp_read = data;
2704                 CoreObject *co_sim = NULL;
2705
2706                 dbg("[%s] SIM_GET_PSISMSC - Result: [%s], URIDATA[%s]", cpname,
2707                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2708                         (resp_read->data.psismsc.uridata != NULL ? resp_read->data.psismsc.uridata : "NULL"));
2709
2710                 co_sim = __get_sim_co_from_ur(ctx->server, ur);
2711                 if (!co_sim) {
2712                         err("SIM Core object is NULL");
2713                         return FALSE;
2714                 }
2715
2716                 /* Added check to send empty string in case request is successful and value is NULL. To be checked and updated if need be */
2717                 if (resp_read->result == SIM_ACCESS_SUCCESS && !resp_read->data.psismsc.uridata) {
2718                         telephony_sim_complete_get_psismsc(dbus_info->interface_object,
2719                                 dbus_info->invocation, resp_read->result, "");
2720                 }
2721                 else {
2722                         telephony_sim_complete_get_psismsc(dbus_info->interface_object,
2723                                 dbus_info->invocation, resp_read->result, (const gchar *)resp_read->data.psismsc.uridata);
2724                 }
2725         }
2726         break;
2727
2728         case TRESP_SIM_REQ_AUTHENTICATION: {
2729                 const struct tresp_sim_req_authentication *resp_auth = data;
2730                 GVariantBuilder builder;
2731                 GVariant *ak = NULL;
2732                 GVariant *cp = NULL;
2733                 GVariant *it = NULL;
2734                 GVariant *resp = NULL;
2735                 GVariant *ak_gv = NULL;
2736                 GVariant *cp_gv = NULL;
2737                 GVariant *it_gv = NULL;
2738                 GVariant *resp_gv = NULL;
2739                 int i = 0;
2740
2741                 dbg("[%s] SIM_REQ_AUTHENTICATION - Result: [%s]", cpname,
2742                         (resp_auth->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2743
2744                 tcore_util_hex_dump("[AUTH_KEY] ",
2745                         resp_auth->authentication_key_length, resp_auth->authentication_key);
2746                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2747                 for (i = 0; i < (int)resp_auth->authentication_key_length; i++)
2748                         g_variant_builder_add(&builder, "y", resp_auth->authentication_key[i]);
2749                 ak = g_variant_builder_end(&builder);
2750                 ak_gv = g_variant_new("v", ak);
2751
2752                 tcore_util_hex_dump("[CIPHER_DATA] ",
2753                         resp_auth->cipher_length, resp_auth->cipher_data);
2754                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2755                 for (i = 0; i < (int)resp_auth->cipher_length; i++)
2756                         g_variant_builder_add(&builder, "y", resp_auth->cipher_data[i]);
2757                 cp = g_variant_builder_end(&builder);
2758                 cp_gv = g_variant_new("v", cp);
2759
2760                 tcore_util_hex_dump("[INTEGRITY_DATA] ",
2761                         resp_auth->integrity_length, resp_auth->integrity_data);
2762                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2763                 for (i = 0; i < (int)resp_auth->integrity_length; i++)
2764                         g_variant_builder_add(&builder, "y", resp_auth->integrity_data[i]);
2765                 it = g_variant_builder_end(&builder);
2766                 it_gv = g_variant_new("v", it);
2767
2768                 tcore_util_hex_dump("[RESP_DATA] ",
2769                         resp_auth->resp_length, resp_auth->resp_data);
2770                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2771                 for (i = 0; i < (int)resp_auth->resp_length; i++)
2772                         g_variant_builder_add(&builder, "y", resp_auth->resp_data[i]);
2773                 resp = g_variant_builder_end(&builder);
2774                 resp_gv = g_variant_new("v", resp);
2775
2776                 telephony_sim_complete_authentication(dbus_info->interface_object,
2777                         dbus_info->invocation, resp_auth->result,
2778                         resp_auth->auth_type, resp_auth->auth_result,
2779                         ak_gv, cp_gv, it_gv, resp_gv);
2780         }
2781         break;
2782
2783         case TRESP_SIM_VERIFY_PINS: {
2784                 const struct tresp_sim_verify_pins *resp_verify_pins = data;
2785
2786                 dbg("[%s] SIM_VERIFY_PINS - Result: [%s] PIN Type: [%d] Re-try count: [%d]",
2787                         cpname, (resp_verify_pins->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2788                         resp_verify_pins->pin_type, resp_verify_pins->retry_count);
2789
2790                 telephony_sim_complete_verify_sec(dbus_info->interface_object,
2791                         dbus_info->invocation, resp_verify_pins->result,
2792                         resp_verify_pins->pin_type, resp_verify_pins->retry_count);
2793         }
2794         break;
2795
2796         case TRESP_SIM_VERIFY_PUKS: {
2797                 const struct tresp_sim_verify_puks *resp_verify_puks = data;
2798
2799                 dbg("[%s] SIM_VERIFY_PUKS - Result: [%s] PIN Type: [%d] Re-try count: [%d]",
2800                         cpname, (resp_verify_puks->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2801                         resp_verify_puks->pin_type, resp_verify_puks->retry_count);
2802
2803                 telephony_sim_complete_verify_puk(dbus_info->interface_object,
2804                         dbus_info->invocation, resp_verify_puks->result,
2805                         resp_verify_puks->pin_type, resp_verify_puks->retry_count);
2806         }
2807         break;
2808
2809         case TRESP_SIM_CHANGE_PINS: {
2810                 const struct tresp_sim_change_pins *resp_change_pins = data;
2811
2812                 dbg("[%s] SIM_CHANGE_PINS - Result: [%s] PIN Type: [%d] Re-try count: [%d]",
2813                         cpname, (resp_change_pins->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2814                         resp_change_pins->pin_type, resp_change_pins->retry_count);
2815
2816                 telephony_sim_complete_change_pin(dbus_info->interface_object,
2817                         dbus_info->invocation, resp_change_pins->result,
2818                         resp_change_pins->pin_type, resp_change_pins->retry_count);
2819         }
2820         break;
2821
2822         case TRESP_SIM_DISABLE_FACILITY: {
2823                 const struct tresp_sim_disable_facility *resp_dis_facility = data;
2824                 gint f_type = 0;
2825
2826                 dbg("[%s] SIM_DISABLE_FACILITY - Result: [%s] Type: [%d] Re-try count: [%d]",
2827                         cpname, (resp_dis_facility->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2828                         resp_dis_facility->type, resp_dis_facility->retry_count);
2829
2830                 f_type = __convert_sim_facility_type(resp_dis_facility->type);
2831
2832                 telephony_sim_complete_disable_facility(dbus_info->interface_object,
2833                         dbus_info->invocation, resp_dis_facility->result,
2834                         f_type, resp_dis_facility->retry_count);
2835         }
2836         break;
2837
2838         case TRESP_SIM_ENABLE_FACILITY: {
2839                 const struct tresp_sim_enable_facility *resp_en_facility = data;
2840                 gint f_type = 0;
2841
2842                 dbg("[%s] SIM_ENABLE_FACILITY - Result: [%s] Type: [%d] Re-try count: [%d]",
2843                         cpname, (resp_en_facility->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2844                         resp_en_facility->type, resp_en_facility->retry_count);
2845
2846                 f_type = __convert_sim_facility_type(resp_en_facility->type);
2847
2848                 telephony_sim_complete_enable_facility(dbus_info->interface_object,
2849                         dbus_info->invocation, resp_en_facility->result,
2850                         f_type, resp_en_facility->retry_count);
2851         }
2852         break;
2853
2854         case TRESP_SIM_GET_FACILITY_STATUS: {
2855                 const struct tresp_sim_get_facility_status *resp_get_facility = data;
2856                 gint f_type = 0;
2857
2858                 dbg("[%s] SIM_GET_FACILITY_STATUS - Result: [%s] Type: [%d] Enable: [%s]",
2859                         cpname, (resp_get_facility->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2860                         resp_get_facility->type,
2861                         (resp_get_facility->b_enable ? "Yes" : "No"));
2862
2863                 f_type = __convert_sim_facility_type(resp_get_facility->type);
2864
2865                 telephony_sim_complete_get_facility(dbus_info->interface_object,
2866                         dbus_info->invocation, resp_get_facility->result,
2867                         f_type, resp_get_facility->b_enable);
2868         }
2869         break;
2870
2871         case TRESP_SIM_GET_LOCK_INFO: {
2872                 const struct tresp_sim_get_lock_info *resp_lock = data;
2873                 gint f_type = 0;
2874
2875                 dbg("[%s] SIM_GET_LOCK_INFO - Result: [%s] Type: [%d] Re-try count: [%d]",
2876                         cpname, (resp_lock->result == SIM_PIN_OPERATION_SUCCESS ? "Success" : "Fail"),
2877                         resp_lock->type, resp_lock->retry_count);
2878
2879                 f_type = __convert_sim_facility_type(resp_lock->type);
2880
2881                 telephony_sim_complete_get_lock_info(dbus_info->interface_object,
2882                         dbus_info->invocation, resp_lock->result,
2883                         f_type, resp_lock->lock_status, resp_lock->retry_count);
2884         }
2885         break;
2886
2887         case TRESP_SIM_TRANSMIT_APDU: {
2888                 const struct tresp_sim_transmit_apdu *resp_apdu = data;
2889                 GVariantBuilder builder;
2890                 GVariant * apdu_gv = NULL;
2891                 GVariant *inner_gv = NULL;
2892                 int i = 0;
2893
2894                 dbg("[%s] SIM_TRANSMIT_APDU - Result: [%s]", cpname,
2895                         (resp_apdu->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2896
2897                 tcore_util_hex_dump("[APDU_RESP] ",
2898                         resp_apdu->apdu_resp_length, resp_apdu->apdu_resp);
2899
2900                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2901                 for (i = 0; i < (int)resp_apdu->apdu_resp_length; i++)
2902                         g_variant_builder_add(&builder, "y", resp_apdu->apdu_resp[i]);
2903                 inner_gv = g_variant_builder_end(&builder);
2904                 apdu_gv = g_variant_new("v", inner_gv);
2905
2906                 telephony_sim_complete_transfer_apdu(dbus_info->interface_object,
2907                         dbus_info->invocation, resp_apdu->result, apdu_gv);
2908         }
2909         break;
2910
2911         case TRESP_SIM_ACCESS_RSIM_IO: {
2912                 const struct tresp_sim_set_data *resp_set_data = data;
2913
2914                 dbg("[%s] SIM_ACCESS_RSIM_IO - Result: [%s]", cpname,
2915                         (resp_set_data->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2916
2917                 telephony_sim_complete_access_rsim_io(dbus_info->interface_object,
2918                         dbus_info->invocation, resp_set_data->result);
2919         }
2920         break;
2921
2922         case TRESP_SIM_GET_ATR:{
2923                 const struct tresp_sim_get_atr *resp_get_atr = data;
2924                 GVariantBuilder builder;
2925                 GVariant * atr_gv = NULL;
2926                 GVariant *inner_gv = NULL;
2927                 int i = 0;
2928
2929                 dbg("[%s] SIM_GET_ATR - Result: [%s]", cpname,
2930                         (resp_get_atr->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2931
2932                 tcore_util_hex_dump("[ATR_RESP] ",
2933                         resp_get_atr->atr_length, resp_get_atr->atr);
2934
2935                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
2936                 for (i = 0; i < (int)resp_get_atr->atr_length; i++)
2937                         g_variant_builder_add(&builder, "y", resp_get_atr->atr[i]);
2938                 inner_gv = g_variant_builder_end(&builder);
2939                 atr_gv = g_variant_new("v", inner_gv);
2940
2941                 telephony_sim_complete_get_atr(dbus_info->interface_object,
2942                         dbus_info->invocation, resp_get_atr->result, atr_gv);
2943         }
2944         break;
2945
2946         case TRESP_SIM_SET_POWERSTATE: {
2947                 const struct tresp_sim_set_powerstate *resp_power = data;
2948
2949                 info("[%s] SIM_SET_POWERSTATE - Result: [%s]", cpname,
2950                         (resp_power->result == SIM_POWER_SET_SUCCESS ? "Success" : "Fail"));
2951
2952                 telephony_sim_complete_set_powerstate(dbus_info->interface_object,
2953                         dbus_info->invocation, resp_power->result);
2954         }
2955         break;
2956
2957         case TRESP_SIM_GET_IMPI: {
2958                 const struct tresp_sim_read *resp_read = data;
2959
2960                 dbg("[%s] SIM_GET_IMPI - Result: [%s]", cpname,
2961                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2962
2963                 telephony_sim_complete_get_impi(dbus_info->interface_object,
2964                         dbus_info->invocation, resp_read->result,
2965                         resp_read->data.impi.impi);
2966         }
2967         break;
2968
2969         case TRESP_SIM_GET_IMPU: {
2970                 const struct tresp_sim_read *resp_read = data;
2971                 GVariant *gv = NULL;
2972                 GVariantBuilder b;
2973                 unsigned int i;
2974
2975                 dbg("[%s] SIM_GET_IMPU - Result: [%s] IMPU count: [%d]", cpname,
2976                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
2977                         resp_read->data.impu_list.count);
2978
2979                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
2980                 for (i = 0; i < resp_read->data.impu_list.count; i++) {
2981                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
2982                         g_variant_builder_add(&b, "{sv}", "impu",
2983                                 g_variant_new_string(resp_read->data.impu_list.impu[i].impu));
2984                         g_variant_builder_close(&b);
2985                 }
2986                 gv = g_variant_builder_end(&b);
2987
2988                 telephony_sim_complete_get_impu(dbus_info->interface_object,
2989                         dbus_info->invocation, resp_read->result, gv);
2990         }
2991         break;
2992
2993         case TRESP_SIM_GET_DOMAIN: {
2994                 const struct tresp_sim_read *resp_read = data;
2995
2996                 dbg("[%s] SIM_GET_DOMAIN - Result: [%s]", cpname,
2997                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
2998
2999                 telephony_sim_complete_get_domain(dbus_info->interface_object,
3000                         dbus_info->invocation, resp_read->result,
3001                         resp_read->data.domain.domain);
3002         }
3003         break;
3004
3005         case TRESP_SIM_GET_PCSCF: {
3006                 const struct tresp_sim_read *resp_read = data;
3007                 GVariant *gv = NULL;
3008                 GVariantBuilder b;
3009                 unsigned int i;
3010
3011                 dbg("[%s] SIM_GET_PCSCF - Result: [%s]", cpname,
3012                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
3013
3014                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
3015                 for (i = 0; i < resp_read->data.pcscf_list.count; i++) {
3016                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
3017                         g_variant_builder_add(&b, "{sv}", "type",
3018                                 g_variant_new_int32(resp_read->data.pcscf_list.pcscf[i].type));
3019                         g_variant_builder_add(&b, "{sv}", "pcscf",
3020                                 g_variant_new_string(resp_read->data.pcscf_list.pcscf[i].pcscf));
3021                         g_variant_builder_close(&b);
3022                 }
3023                 gv = g_variant_builder_end(&b);
3024
3025                 telephony_sim_complete_get_pcscf(dbus_info->interface_object,
3026                         dbus_info->invocation, resp_read->result, gv);
3027         }
3028         break;
3029
3030         case TRESP_SIM_GET_ISIM_SERVICE_TABLE: {
3031                 const struct tresp_sim_read *resp_read = data;
3032                 GVariantBuilder builder;
3033                 GVariant *ist_gv = NULL;
3034                 GVariant *inner_gv = NULL;
3035                 int i;
3036
3037                 dbg("[%s] SIM_GET_ISIM_SERVICE_TABLE - Result: [%s]", cpname,
3038                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"));
3039
3040                 g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
3041                 for (i = 0; i < SIM_IST_SERVICE_CNT_MAX; i++)
3042                         g_variant_builder_add(&builder, "y", resp_read->data.ist.service[i]);
3043                 inner_gv = g_variant_builder_end(&builder);
3044                 ist_gv = g_variant_new("v", inner_gv);
3045
3046                 telephony_sim_complete_get_isim_service_table(dbus_info->interface_object,
3047                         dbus_info->invocation, resp_read->result, ist_gv);
3048         }
3049         break;
3050
3051         case TRESP_SIM_GET_CDMAIMSI: {
3052                 const struct tresp_sim_read *resp_read = data;
3053
3054                 dbg("[%s] SIM_GET_CDMAIMSI - Result: [%s] IMSI provision[%d] min: [%s]", cpname,
3055                         (resp_read->result == SIM_ACCESS_SUCCESS ? "Success" : "Fail"),
3056                         resp_read->data.imsim.provisioned, (const gchar *)resp_read->data.imsim.min);
3057
3058                 telephony_sim_complete_get_cdmaimsi(dbus_info->interface_object,
3059                         dbus_info->invocation, resp_read->result,
3060                         resp_read->data.imsim.provisioned,
3061                         (const gchar *)resp_read->data.imsim.min);
3062         }
3063         break;
3064
3065         default:
3066                 err("Unhandled/Unknown Response: [0x%x]", command);
3067         break;
3068         }
3069
3070         return TRUE;
3071 }
3072
3073 gboolean dbus_plugin_sim_notification(struct custom_data *ctx,
3074         CoreObject *source, TelephonyObjectSkeleton *object,
3075         enum tcore_notification_command command, unsigned int data_len, const void *data)
3076 {
3077         TelephonySim *sim;
3078         const char *cp_name;
3079         enum dbus_tapi_sim_slot_id slot_id = SIM_SLOT_PRIMARY;
3080
3081         cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
3082
3083         sim = telephony_object_peek_sim(TELEPHONY_OBJECT(object));
3084         if (sim == NULL) {
3085                 err("sim object is NULL!!!");
3086                 return FALSE;
3087         }
3088
3089         switch (command) {
3090         case TNOTI_SIM_STATUS: {
3091                 const struct tnoti_sim_status *n_sim_status = data;
3092                 int count = 0;
3093
3094                 info("[%s] SIM_STATUS - [%d]", cp_name,
3095                         n_sim_status->sim_status);
3096
3097 #ifdef ENABLE_KPI_LOGS
3098                 if (n_sim_status->sim_status == SIM_STATUS_INIT_COMPLETED)
3099                         TIME_CHECK("[%s] SIM Initialized", cp_name);
3100 #endif
3101
3102                 telephony_sim_emit_status(sim, n_sim_status->sim_status);
3103
3104                 slot_id = get_sim_slot_id_by_cp_name(cp_name);
3105                 if (slot_id == SIM_SLOT_PRIMARY)
3106                         ctx->sim1_status = n_sim_status->sim_status;
3107                 else if (slot_id == SIM_SLOT_SECONDARY)
3108                         ctx->sim2_status = n_sim_status->sim_status;
3109                 else
3110                         warn("NOT handled Slot ID: [%d]", slot_id);
3111
3112                 if (__is_sim_status_valid(ctx->sim1_status))
3113                         count++;
3114
3115                 if (__is_sim_status_valid(ctx->sim2_status))
3116                         count++;
3117 // Temporary block duplicated count checking. (SIM event is coming before dbus acquired)
3118 //              if (ctx->valid_sim_count != count) {
3119                         ctx->valid_sim_count = count;
3120
3121                         telephony_manager_emit_sim_inserted(ctx->mgr, count);
3122 //              }
3123         }
3124         break;
3125
3126         case TNOTI_SIM_REFRESHED: {
3127                 const struct tnoti_sim_refreshed *n_sim_refreshed = data;
3128
3129                 info("[%s] SIM_REFRESHED - b_full_file_changed: [%s] changed_file_count: [%d]",
3130                         cp_name, (n_sim_refreshed->b_full_file_changed ? "YES" : "NO"),
3131                         n_sim_refreshed->file_list.file_count);
3132
3133                 telephony_sim_emit_refreshed(sim, n_sim_refreshed->cmd_type);
3134         }
3135         break;
3136
3137         case TNOTI_SIM_REFRESH_STAGE: {
3138                 const struct tnoti_sim_refresh_stage *n_sim_refresh_stage = data;
3139
3140                 info("[%s] SIM_REFRESH_STAGE - stage[%d]", cp_name, n_sim_refresh_stage->stage);
3141
3142                 telephony_sim_emit_refresh_stage(sim, n_sim_refresh_stage->stage);
3143         }
3144         break;
3145
3146         case TNOTI_SIM_CALL_FORWARD_STATE: {
3147                 const struct tnoti_sim_call_forward_state *info = data;
3148
3149                 info("[%s] SIM_CALL_FORWARD_STATE - Call Forwarding: [%s]",
3150                         cp_name, info->b_forward ? "ON" : "OFF");
3151
3152                 telephony_sim_set_cf_state(sim, info->b_forward);
3153         }
3154         break;
3155
3156         default:
3157                 err("Unhandled/Unknown Notification: [0x%x]", command);
3158         break;
3159         }
3160
3161         return TRUE;
3162 }
3163