add exception code for g_variant_iter_free()
[profile/ivi/tel-plugin-dbus_tapi.git] / src / network.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <pthread.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <time.h>
7 #include <glib.h>
8 #include <glib-object.h>
9 #include <gio/gio.h>
10
11 #include <tcore.h>
12 #include <server.h>
13 #include <plugin.h>
14 #include <hal.h>
15 #include <communicator.h>
16 #include <storage.h>
17 #include <queue.h>
18 #include <user_request.h>
19 #include <co_network.h>
20 #include <co_sim.h>
21 #include <co_ps.h>
22
23 #include "generated-code.h"
24 #include "common.h"
25
26
27 static char *_get_network_name_by_plmn(CoreObject *o, const char *plmn)
28 {
29         struct tcore_network_operator_info *noi = NULL;
30         char mcc[4] = { 0, };
31         char mnc[4] = { 0, };
32
33         if (!plmn)
34                 return NULL;
35
36         snprintf(mcc, 4, "%s", plmn);
37         snprintf(mnc, 4, "%s", plmn+3);
38
39         if (mnc[2] == '#')
40                 mnc[2] = '\0';
41
42         noi = tcore_network_operator_info_find(o, mcc, mnc);
43         if (noi) {
44                 dbg("%s-%s: country=[%s], oper=[%s]", mcc, mnc, noi->country, noi->name);
45                 return noi->name;
46         }
47         else {
48                 dbg("%s-%s: no network operator name", mcc, mnc);
49         }
50
51         return NULL;
52 }
53
54
55 static enum tcore_hook_return on_hook_location_cellinfo(Server *s, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
56 {
57         const struct tnoti_network_location_cellinfo *info = data;
58         TelephonyNetwork *network = user_data;
59
60         if (!network)
61                 return TCORE_HOOK_RETURN_CONTINUE;
62
63         telephony_network_set_lac(network, info->lac);
64         telephony_network_set_cell_id(network, info->cell_id);
65
66         return TCORE_HOOK_RETURN_CONTINUE;
67 }
68
69 static enum tcore_hook_return on_hook_icon_info(Server *s, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
70 {
71         const struct tnoti_network_icon_info *info = data;
72         TelephonyNetwork *network = user_data;
73
74         if (!network)
75                 return TCORE_HOOK_RETURN_CONTINUE;
76
77         telephony_network_set_rssi(network, info->rssi);
78
79         return TCORE_HOOK_RETURN_CONTINUE;
80 }
81
82 static enum tcore_hook_return on_hook_registration_status(Server *s, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
83 {
84         const struct tnoti_network_registration_status *info = data;
85         TelephonyNetwork *network = user_data;
86
87         if (!network)
88                 return TCORE_HOOK_RETURN_CONTINUE;
89
90         telephony_network_set_circuit_status(network, info->cs_domain_status);
91         telephony_network_set_packet_status(network, info->ps_domain_status);
92         telephony_network_set_service_type(network, info->service_type);
93         telephony_network_set_roaming_status(network, info->roaming_status);
94
95         switch (info->service_type) {
96                 case NETWORK_SERVICE_TYPE_UNKNOWN:
97                 case NETWORK_SERVICE_TYPE_NO_SERVICE:
98                         telephony_network_set_network_name(network, "No Service");
99                         break;
100
101                 case NETWORK_SERVICE_TYPE_EMERGENCY:
102                         telephony_network_set_network_name(network, "EMERGENCY");
103                         break;
104
105                 case NETWORK_SERVICE_TYPE_SEARCH:
106                         telephony_network_set_network_name(network, "Searching...");
107                         break;
108
109                 default:
110                         break;
111         }
112
113         return TCORE_HOOK_RETURN_CONTINUE;
114 }
115
116 static enum tcore_hook_return on_hook_change(Server *s, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
117 {
118         const struct tnoti_network_change *info = data;
119         TelephonyNetwork *network = user_data;
120         struct tcore_network_operator_info *noi = NULL;
121         char mcc[4] = { 0, };
122         char mnc[4] = { 0, };
123         enum telephony_network_service_type svc_type;
124         enum tcore_network_name_priority network_name_priority;
125         char *tmp;
126
127         if (!network)
128                 return TCORE_HOOK_RETURN_CONTINUE;
129
130         telephony_network_set_plmn(network, info->plmn);
131         telephony_network_set_lac(network, info->gsm.lac);
132
133         snprintf(mcc, 4, "%s", info->plmn);
134         snprintf(mnc, 4, "%s", info->plmn+3);
135
136         if (mnc[2] == '#')
137                 mnc[2] = '\0';
138
139         tcore_network_get_network_name_priority(source, &network_name_priority);
140         telephony_network_set_name_priority(network, network_name_priority);
141
142         tmp = tcore_network_get_network_name(source, TCORE_NETWORK_NAME_TYPE_SPN);
143         if (tmp) {
144                 telephony_network_set_spn_name(network, tmp);
145                 free(tmp);
146         }
147
148         tcore_network_get_service_type(source, &svc_type);
149         switch(svc_type) {
150                 case NETWORK_SERVICE_TYPE_UNKNOWN:
151                 case NETWORK_SERVICE_TYPE_NO_SERVICE:
152                         telephony_network_set_network_name(network, "No Service");
153                         break;
154
155                 case NETWORK_SERVICE_TYPE_EMERGENCY:
156                         telephony_network_set_network_name(network, "EMERGENCY");
157                         break;
158
159                 case NETWORK_SERVICE_TYPE_SEARCH:
160                         telephony_network_set_network_name(network, "Searching...");
161                         break;
162
163                 default:
164                         tmp = tcore_network_get_network_name(source, TCORE_NETWORK_NAME_TYPE_SHORT);
165                         if (tmp) {
166                                 telephony_network_set_network_name(network, tmp);
167                                 free(tmp);
168                         }
169                         else {
170                                 /* pre-defined table */
171                                 noi = tcore_network_operator_info_find(source, mcc, mnc);
172                                 if (noi) {
173                                         dbg("%s-%s: country=[%s], oper=[%s]", mcc, mnc, noi->country, noi->name);
174                                         dbg("NWNAME = pre-define table[%s]", noi->name);
175                                         telephony_network_set_network_name(network, noi->name);
176                                 }
177                                 else {
178                                         dbg("%s-%s: no network operator name", mcc, mnc);
179                                         telephony_network_set_network_name(network, info->plmn);
180                                 }
181                         }
182                         break;
183         }
184
185         return TCORE_HOOK_RETURN_CONTINUE;
186 }
187
188 static enum tcore_hook_return on_hook_ps_protocol_status(Server *s, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
189 {
190         const struct tnoti_ps_protocol_status *info = data;
191         TelephonyNetwork *network = user_data;
192
193         if (!network)
194                 return TCORE_HOOK_RETURN_CONTINUE;
195
196         telephony_network_set_network_type(network, info->status);
197
198         return TCORE_HOOK_RETURN_CONTINUE;
199 }
200
201 static gboolean
202 on_network_search (TelephonyNetwork *network,
203                 GDBusMethodInvocation *invocation,
204                 gpointer user_data)
205 {
206 #if 1
207         struct custom_data *ctx = user_data;
208         UserRequest *ur = NULL;
209         TReturn ret;
210
211         ur = MAKE_UR(ctx, network, invocation);
212         tcore_user_request_set_data(ur, 0, NULL);
213         tcore_user_request_set_command(ur, TREQ_NETWORK_SEARCH);
214         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
215         if (ret != TCORE_RETURN_SUCCESS) {
216                 telephony_network_complete_search(network, invocation, NULL, ret);
217                 tcore_user_request_unref(ur);
218         }
219 #else
220         /* Dummy return */
221         GVariant *result = NULL;
222         GVariantBuilder b;
223         int i;
224         char *buf;
225
226         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
227
228         for (i = 0; i < 3; i++) {
229                 g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
230
231                 g_variant_builder_add(&b, "{sv}", "plmn", g_variant_new_string("45001"));
232                 g_variant_builder_add(&b, "{sv}", "act", g_variant_new_int32(4));
233                 g_variant_builder_add(&b, "{sv}", "type", g_variant_new_int32(2));
234                 g_variant_builder_add(&b, "{sv}", "name", g_variant_new_string("Samsung"));
235
236                 g_variant_builder_close(&b);
237         }
238
239         result = g_variant_builder_end(&b);
240
241         telephony_network_complete_search(network, invocation, result, 0);
242         g_variant_unref(result);
243 #endif
244
245         return TRUE;
246 }
247
248 static gboolean
249 on_network_search_cancel (TelephonyNetwork *network,
250                 GDBusMethodInvocation *invocation,
251                 gpointer user_data)
252 {
253         struct custom_data *ctx = user_data;
254         UserRequest *ur = NULL;
255         TReturn ret;
256
257         ur = MAKE_UR(ctx, network, invocation);
258         tcore_user_request_set_data(ur, 0, NULL);
259         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH);
260         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
261         if (ret != TCORE_RETURN_SUCCESS) {
262                 telephony_network_complete_search_cancel(network, invocation, ret);
263                 tcore_user_request_unref(ur);
264         }
265
266         return TRUE;
267 }
268
269 static gboolean
270 on_network_get_selection_mode (TelephonyNetwork *network,
271                 GDBusMethodInvocation *invocation,
272                 gpointer user_data)
273 {
274         struct custom_data *ctx = user_data;
275         UserRequest *ur = NULL;
276         TReturn ret;
277
278         ur = MAKE_UR(ctx, network, invocation);
279         tcore_user_request_set_data(ur, 0, NULL);
280         tcore_user_request_set_command(ur, TREQ_NETWORK_GET_PLMN_SELECTION_MODE);
281         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
282         if (ret != TCORE_RETURN_SUCCESS) {
283                 telephony_network_complete_get_selection_mode(network, invocation, -1, ret);
284                 tcore_user_request_unref(ur);
285         }
286
287         return TRUE;
288 }
289
290 static gboolean
291 on_network_set_selection_mode (TelephonyNetwork *network,
292                 GDBusMethodInvocation *invocation,
293                 gint mode,
294                 const gchar *plmn,
295                 gint act,
296                 gpointer user_data)
297 {
298         struct treq_network_set_plmn_selection_mode req;
299         struct custom_data *ctx = user_data;
300         UserRequest *ur = NULL;
301         TReturn ret;
302
303         memset(&req, 0, sizeof(struct treq_network_set_plmn_selection_mode));
304
305         if (mode == 0) {
306                 /* Automatic */
307                 req.mode = NETWORK_SELECT_MODE_GSM_AUTOMATIC;
308         }
309         else if (mode == 1) {
310                 /* Manual */
311                 req.mode = NETWORK_SELECT_MODE_GSM_MANUAL;
312                 snprintf(req.plmn, 7, "%s", plmn);
313                 if (strlen(plmn) <= 5)
314                         req.plmn[5] = '#';
315                 req.act = act;
316         }
317         else {
318                 telephony_network_complete_set_selection_mode(network, invocation, -1);
319                 return TRUE;
320         }
321
322         dbg("mode = %d, plmn = [%s], act = %d",
323                         req.mode, req.plmn, req.act);
324
325         ur = MAKE_UR(ctx, network, invocation);
326
327         tcore_user_request_set_data(ur, sizeof(struct treq_network_set_plmn_selection_mode), &req);
328         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_PLMN_SELECTION_MODE);
329         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
330         if (ret != TCORE_RETURN_SUCCESS) {
331                 telephony_network_complete_set_selection_mode(network, invocation, ret);
332                 tcore_user_request_unref(ur);
333         }
334
335         return TRUE;
336 }
337
338
339 static gboolean
340 on_network_set_service_domain (TelephonyNetwork *network,
341                 GDBusMethodInvocation *invocation,
342                 gint domain,
343                 gpointer user_data)
344 {
345         struct treq_network_set_service_domain req;
346         struct custom_data *ctx = user_data;
347         UserRequest *ur = NULL;
348         TReturn ret;
349
350         ur = MAKE_UR(ctx, network, invocation);
351
352         req.domain = domain;
353
354         tcore_user_request_set_data(ur, sizeof(struct treq_network_set_service_domain), &req);
355         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_SERVICE_DOMAIN);
356         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
357         if (ret != TCORE_RETURN_SUCCESS) {
358                 telephony_network_complete_set_service_domain(network, invocation, ret);
359                 tcore_user_request_unref(ur);
360         }
361
362         return TRUE;
363 }
364
365 static gboolean
366 on_network_get_service_domain (TelephonyNetwork *network,
367                 GDBusMethodInvocation *invocation,
368                 gpointer user_data)
369 {
370         struct custom_data *ctx = user_data;
371         UserRequest *ur = NULL;
372         TReturn ret;
373
374         ur = MAKE_UR(ctx, network, invocation);
375         tcore_user_request_set_data(ur, 0, NULL);
376         tcore_user_request_set_command(ur, TREQ_NETWORK_GET_SERVICE_DOMAIN);
377         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
378         if (ret != TCORE_RETURN_SUCCESS) {
379                 telephony_network_complete_get_service_domain(network, invocation, -1, ret);
380                 tcore_user_request_unref(ur);
381         }
382
383         return TRUE;
384 }
385
386 static gboolean
387 on_network_set_band (TelephonyNetwork *network,
388                 GDBusMethodInvocation *invocation,
389                 gint band,
390                 gint mode,
391                 gpointer user_data)
392 {
393         struct treq_network_set_band req;
394         struct custom_data *ctx = user_data;
395         UserRequest *ur = NULL;
396         TReturn ret;
397
398         ur = MAKE_UR(ctx, network, invocation);
399
400         req.mode = mode;
401         req.band = band;
402
403         tcore_user_request_set_data(ur, sizeof(struct treq_network_set_band), &req);
404         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_BAND);
405         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
406         if (ret != TCORE_RETURN_SUCCESS) {
407                 telephony_network_complete_set_band(network, invocation, ret);
408                 tcore_user_request_unref(ur);
409         }
410
411         return TRUE;
412 }
413
414 static gboolean
415 on_network_get_band (TelephonyNetwork *network,
416                 GDBusMethodInvocation *invocation,
417                 gpointer user_data)
418 {
419         struct custom_data *ctx = user_data;
420         UserRequest *ur = NULL;
421         TReturn ret;
422
423         ur = MAKE_UR(ctx, network, invocation);
424         tcore_user_request_set_data(ur, 0, NULL);
425         tcore_user_request_set_command(ur, TREQ_NETWORK_GET_BAND);
426         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
427         if (ret != TCORE_RETURN_SUCCESS) {
428                 telephony_network_complete_get_band(network, invocation, -1, -1, ret);
429                 tcore_user_request_unref(ur);
430         }
431
432         return TRUE;
433 }
434
435 static gboolean
436 on_network_set_mode (TelephonyNetwork *network,
437                 GDBusMethodInvocation *invocation,
438                 gint mode,
439                 gpointer user_data)
440 {
441         struct treq_network_set_mode req;
442         struct custom_data *ctx = user_data;
443         UserRequest *ur = NULL;
444         TReturn ret;
445
446         ur = MAKE_UR(ctx, network, invocation);
447
448         req.mode = mode;
449
450         tcore_user_request_set_data(ur, sizeof(struct treq_network_set_mode), &req);
451         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_MODE);
452         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
453         if (ret != TCORE_RETURN_SUCCESS) {
454                 telephony_network_complete_set_mode(network, invocation, ret);
455                 tcore_user_request_unref(ur);
456         }
457
458         return TRUE;
459 }
460
461 static gboolean
462 on_network_get_mode (TelephonyNetwork *network,
463                 GDBusMethodInvocation *invocation,
464                 gpointer user_data)
465 {
466         struct custom_data *ctx = user_data;
467         UserRequest *ur = NULL;
468         TReturn ret;
469
470         ur = MAKE_UR(ctx, network, invocation);
471         tcore_user_request_set_data(ur, 0, NULL);
472         tcore_user_request_set_command(ur, TREQ_NETWORK_GET_MODE);
473         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
474         if (ret != TCORE_RETURN_SUCCESS) {
475                 telephony_network_complete_get_mode(network, invocation, -1, ret);
476                 tcore_user_request_unref(ur);
477         }
478
479         return TRUE;
480 }
481
482 static gboolean
483 on_network_set_preferred_plmn (TelephonyNetwork *network,
484                 GDBusMethodInvocation *invocation,
485                 gint mode,
486                 gint ef_index,
487                 gint act,
488                 const gchar *plmn,
489                 gpointer user_data)
490 {
491         struct treq_network_set_preferred_plmn req;
492         struct custom_data *ctx = user_data;
493         UserRequest *ur = NULL;
494         TReturn ret;
495
496         ur = MAKE_UR(ctx, network, invocation);
497
498         req.operation = mode;
499         req.ef_index = ef_index;
500         req.act = act;
501
502         memcpy(req.plmn, plmn, 6);
503
504         if (strlen(plmn) <= 5) {
505                 req.plmn[5] = '#';
506         }
507
508         tcore_user_request_set_data(ur, sizeof(struct treq_network_set_preferred_plmn), &req);
509         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_PREFERRED_PLMN);
510         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
511         if (ret != TCORE_RETURN_SUCCESS) {
512                 telephony_network_complete_set_preferred_plmn(network, invocation, ret);
513                 tcore_user_request_unref(ur);
514         }
515
516         return TRUE;
517 }
518
519 static gboolean
520 on_network_get_preferred_plmn (TelephonyNetwork *network,
521                 GDBusMethodInvocation *invocation,
522                 gpointer user_data)
523 {
524         struct custom_data *ctx = user_data;
525         UserRequest *ur = NULL;
526         TReturn ret;
527
528         ur = MAKE_UR(ctx, network, invocation);
529         tcore_user_request_set_data(ur, 0, NULL);
530         tcore_user_request_set_command(ur, TREQ_NETWORK_GET_PREFERRED_PLMN);
531         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
532         if (ret != TCORE_RETURN_SUCCESS) {
533                 telephony_network_complete_get_preferred_plmn(network, invocation, NULL, ret);
534                 tcore_user_request_unref(ur);
535         }
536
537         return TRUE;
538 }
539
540 static gboolean
541 on_network_get_serving_network (TelephonyNetwork *network,
542                 GDBusMethodInvocation *invocation,
543                 gpointer user_data)
544 {
545         struct custom_data *ctx = user_data;
546         UserRequest *ur = NULL;
547         TReturn ret;
548
549         ur = MAKE_UR(ctx, network, invocation);
550         tcore_user_request_set_data(ur, 0, NULL);
551         tcore_user_request_set_command(ur, TREQ_NETWORK_GET_SERVING_NETWORK);
552         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
553         if (ret != TCORE_RETURN_SUCCESS) {
554                 telephony_network_complete_get_serving_network(network, invocation, 0, NULL, 0, ret);
555                 tcore_user_request_unref(ur);
556         }
557
558         return TRUE;
559 }
560
561 gboolean dbus_plugin_setup_network_interface(TelephonyObjectSkeleton *object, struct custom_data *ctx)
562 {
563         TelephonyNetwork *network;
564
565         network = telephony_network_skeleton_new();
566         telephony_object_skeleton_set_network(object, network);
567         g_object_unref(network);
568
569         g_signal_connect (network,
570                         "handle-search",
571                         G_CALLBACK (on_network_search),
572                         ctx);
573
574         g_signal_connect (network,
575                         "handle-search-cancel",
576                         G_CALLBACK (on_network_search_cancel),
577                         ctx);
578
579         g_signal_connect (network,
580                         "handle-set-selection-mode",
581                         G_CALLBACK (on_network_set_selection_mode),
582                         ctx);
583
584         g_signal_connect (network,
585                         "handle-get-selection-mode",
586                         G_CALLBACK (on_network_get_selection_mode),
587                         ctx);
588
589         g_signal_connect (network,
590                         "handle-set-service-domain",
591                         G_CALLBACK (on_network_set_service_domain),
592                         ctx);
593
594         g_signal_connect (network,
595                         "handle-get-service-domain",
596                         G_CALLBACK (on_network_get_service_domain),
597                         ctx);
598
599         g_signal_connect (network,
600                         "handle-set-band",
601                         G_CALLBACK (on_network_set_band),
602                         ctx);
603
604         g_signal_connect (network,
605                         "handle-get-band",
606                         G_CALLBACK (on_network_get_band),
607                         ctx);
608
609         g_signal_connect (network,
610                         "handle-set-mode",
611                         G_CALLBACK (on_network_set_mode),
612                         ctx);
613
614         g_signal_connect (network,
615                         "handle-get-mode",
616                         G_CALLBACK (on_network_get_mode),
617                         ctx);
618
619         g_signal_connect (network,
620                         "handle-set-preferred-plmn",
621                         G_CALLBACK (on_network_set_preferred_plmn),
622                         ctx);
623
624         g_signal_connect (network,
625                         "handle-get-preferred-plmn",
626                         G_CALLBACK (on_network_get_preferred_plmn),
627                         ctx);
628
629         g_signal_connect (network,
630                         "handle-get-serving-network",
631                         G_CALLBACK (on_network_get_serving_network),
632                         ctx);
633
634         tcore_server_add_notification_hook(ctx->server, TNOTI_NETWORK_LOCATION_CELLINFO, on_hook_location_cellinfo, network);
635         tcore_server_add_notification_hook(ctx->server, TNOTI_NETWORK_ICON_INFO, on_hook_icon_info, network);
636         tcore_server_add_notification_hook(ctx->server, TNOTI_NETWORK_REGISTRATION_STATUS, on_hook_registration_status, network);
637         tcore_server_add_notification_hook(ctx->server, TNOTI_NETWORK_CHANGE, on_hook_change, network);
638         tcore_server_add_notification_hook(ctx->server, TNOTI_PS_PROTOCOL_STATUS, on_hook_ps_protocol_status, network);
639
640         return TRUE;
641 }
642
643 gboolean dbus_plugin_network_response(struct custom_data *ctx, UserRequest *ur, struct dbus_request_info *dbus_info, enum tcore_response_command command, unsigned int data_len, const void *data)
644 {
645         const struct tresp_network_search *resp_network_search = data;
646         const struct tresp_network_get_plmn_selection_mode *resp_get_plmn_selection_mode = data;
647         const struct tresp_network_set_plmn_selection_mode *resp_set_plmn_selection_mode = data;
648         const struct tresp_network_set_service_domain *resp_set_service_domain = data;
649         const struct tresp_network_get_service_domain *resp_get_service_domain = data;
650         const struct tresp_network_set_band *resp_set_band = data;
651         const struct tresp_network_get_band *resp_get_band = data;
652         const struct tresp_network_set_preferred_plmn *resp_set_preferred_plmn = data;
653         const struct tresp_network_get_preferred_plmn *resp_get_preferred_plmn = data;
654         const struct tresp_network_get_serving_network *resp_get_serving_network = data;
655         const struct tresp_network_set_mode *resp_set_mode = data;
656         const struct tresp_network_get_mode *resp_get_mode = data;
657
658         int i = 0;
659         char *buf;
660
661         GSList *co_list;
662         CoreObject *co_network;
663         char *modem_name = NULL;
664         TcorePlugin *p = NULL;
665
666         modem_name = tcore_user_request_get_modem_name(ur);
667         if (!modem_name)
668                 return FALSE;
669
670         p = tcore_server_find_plugin(ctx->server, modem_name);
671         free(modem_name);
672         if (!p)
673                 return FALSE;
674
675         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_NETWORK);
676         if (!co_list) {
677                 return FALSE;
678         }
679
680         co_network = (CoreObject *)co_list->data;
681         g_slist_free(co_list);
682
683         if (!co_network) {
684                 return FALSE;
685         }
686
687         switch (command) {
688                 case TRESP_NETWORK_SEARCH: {
689                         GVariant *result = NULL;
690                         GVariantBuilder b;
691
692                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
693
694                         for (i = 0; i < resp_network_search->list_count; i++) {
695                                 g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
696
697                                 g_variant_builder_add(&b, "{sv}", "plmn", g_variant_new_string(resp_network_search->list[i].plmn));
698                                 g_variant_builder_add(&b, "{sv}", "act", g_variant_new_int32(resp_network_search->list[i].act));
699                                 g_variant_builder_add(&b, "{sv}", "type", g_variant_new_int32(resp_network_search->list[i].status));
700
701                                 if (strlen(resp_network_search->list[i].name) > 0) {
702                                         g_variant_builder_add(&b, "{sv}", "name", g_variant_new_string(resp_network_search->list[i].name));
703                                 }
704                                 else {
705                                         buf = _get_network_name_by_plmn(co_network, resp_network_search->list[i].plmn);
706                                         if (buf)
707                                                 g_variant_builder_add(&b, "{sv}", "name", g_variant_new_string(buf));
708                                         else
709                                                 g_variant_builder_add(&b, "{sv}", "name", g_variant_new_string(resp_network_search->list[i].plmn));
710                                 }
711
712                                 g_variant_builder_close(&b);
713                         }
714
715                         result = g_variant_builder_end(&b);
716
717                         telephony_network_complete_search(dbus_info->interface_object, dbus_info->invocation, result, 0);
718                 }
719
720                         break;
721
722                 case TRESP_NETWORK_SET_PLMN_SELECTION_MODE:
723                         dbg("receive TRESP_SET_PLMN_SELECTION_MODE");
724                         dbg("resp->result = %d", resp_set_plmn_selection_mode->result);
725                         telephony_network_complete_set_selection_mode(dbus_info->interface_object, dbus_info->invocation, resp_set_plmn_selection_mode->result);
726                         break;
727
728                 case TRESP_NETWORK_GET_PLMN_SELECTION_MODE:
729                         dbg("receive TRESP_GET_PLMN_SELECTION_MODE");
730                         dbg("resp->mode = %d", resp_get_plmn_selection_mode->mode);
731                         switch (resp_get_plmn_selection_mode->mode) {
732                                 case NETWORK_SELECT_MODE_GLOBAL_AUTOMATIC:
733                                 case NETWORK_SELECT_MODE_GSM_AUTOMATIC:
734                                         telephony_network_complete_get_selection_mode(dbus_info->interface_object, dbus_info->invocation, 0, 0);
735                                         break;
736
737                                 case NETWORK_SELECT_MODE_GSM_MANUAL:
738                                         telephony_network_complete_get_selection_mode(dbus_info->interface_object, dbus_info->invocation, 1, 0);
739                                         break;
740
741                                 default:
742                                         telephony_network_complete_get_selection_mode(dbus_info->interface_object, dbus_info->invocation, -1, -1);
743                                         break;
744                         }
745                         break;
746
747                 case TRESP_NETWORK_SET_SERVICE_DOMAIN:
748                         dbg("receive TRESP_NETWORK_SET_SERVICE_DOMAIN");
749                         dbg("resp->result = %d", resp_set_service_domain->result);
750                         telephony_network_complete_set_service_domain(dbus_info->interface_object, dbus_info->invocation, resp_set_service_domain->result);
751                         break;
752
753                 case TRESP_NETWORK_GET_SERVICE_DOMAIN:
754                         dbg("receive TRESP_NETWORK_GET_SERVICE_DOMAIN");
755                         dbg("resp->domain = %d", resp_get_service_domain->domain);
756                         telephony_network_complete_get_service_domain(dbus_info->interface_object, dbus_info->invocation, resp_get_service_domain->domain, 0);
757                         break;
758
759                 case TRESP_NETWORK_SET_BAND:
760                         dbg("receive TRESP_NETWORK_SET_BAND");
761                         dbg("resp->result = %d", resp_set_band->result);
762                         telephony_network_complete_set_band(dbus_info->interface_object, dbus_info->invocation, resp_set_band->result);
763                         break;
764
765                 case TRESP_NETWORK_GET_BAND:
766                         dbg("receive TRESP_NETWORK_GET_BAND");
767                         dbg("resp->mode = %d", resp_get_band->mode);
768                         dbg("resp->band = %d", resp_get_band->band);
769                         telephony_network_complete_get_band(dbus_info->interface_object, dbus_info->invocation, resp_get_band->band, resp_get_band->mode, 0);
770                         break;
771
772                 case TRESP_NETWORK_SET_MODE:
773                         dbg("receive TRESP_NETWORK_SET_MODE");
774                         dbg("resp->result = %d", resp_set_mode->result);
775                         telephony_network_complete_set_mode(dbus_info->interface_object, dbus_info->invocation, resp_set_mode->result);
776                         break;
777
778                 case TRESP_NETWORK_GET_MODE:
779                         dbg("receive TRESP_NETWORK_GET_MODE");
780                         dbg("resp->mode = %d", resp_get_mode->mode);
781                         telephony_network_complete_get_mode(dbus_info->interface_object, dbus_info->invocation, resp_get_mode->mode, resp_get_mode->result);
782                         break;
783
784                 case TRESP_NETWORK_SET_PREFERRED_PLMN:
785                         dbg("receive TRESP_NETWORK_SET_PREFERRED_PLMN");
786                         dbg("resp->result = %d", resp_set_preferred_plmn->result);
787                         telephony_network_complete_set_preferred_plmn(dbus_info->interface_object, dbus_info->invocation, resp_set_preferred_plmn->result);
788                         break;
789
790                 case TRESP_NETWORK_GET_PREFERRED_PLMN:
791                         dbg("receive TRESP_NETWORK_GET_PREFERRED_PLMN");
792                         {
793                                 GVariant *result = NULL;
794                                 GVariantBuilder b;
795
796                                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
797
798                                 for (i = 0; i < resp_get_preferred_plmn->list_count; i++) {
799                                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
800
801                                         g_variant_builder_add(&b, "{sv}", "plmn",
802                                                         g_variant_new_string(resp_get_preferred_plmn->list[i].plmn));
803                                         g_variant_builder_add(&b, "{sv}", "act", g_variant_new_int32(resp_get_preferred_plmn->list[i].act));
804                                         g_variant_builder_add(&b, "{sv}", "index",
805                                                         g_variant_new_int32(resp_get_preferred_plmn->list[i].ef_index));
806
807                                         buf = _get_network_name_by_plmn(co_network, resp_get_preferred_plmn->list[i].plmn);
808                                         if (buf)
809                                                 g_variant_builder_add(&b, "{sv}", "name", g_variant_new_string(buf));
810                                         else
811                                                 g_variant_builder_add(&b, "{sv}", "name",
812                                                                 g_variant_new_string(resp_get_preferred_plmn->list[i].plmn));
813
814                                         g_variant_builder_close(&b);
815                                 }
816
817                                 result = g_variant_builder_end(&b);
818
819                                 telephony_network_complete_get_preferred_plmn(dbus_info->interface_object, dbus_info->invocation,
820                                                 result, 0);
821                         }
822                         break;
823
824                 case TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH:
825                         dbg("receive TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH");
826                         telephony_network_complete_search_cancel(dbus_info->interface_object, dbus_info->invocation, 0);
827                         break;
828
829                 case TRESP_NETWORK_GET_SERVING_NETWORK:
830                         dbg("receive TRESP_NETWORK_GET_SERVING_NETWORK");
831                         dbg("resp->act = %d", resp_get_serving_network->act);
832                         dbg("resp->plmn = %s", resp_get_serving_network->plmn);
833                         dbg("resp->lac = %d", resp_get_serving_network->gsm.lac);
834                         telephony_network_complete_get_serving_network(dbus_info->interface_object, dbus_info->invocation,
835                                         resp_get_serving_network->act,
836                                         resp_get_serving_network->plmn,
837                                         resp_get_serving_network->gsm.lac,
838                                         0);
839                         break;
840
841                 default:
842                         dbg("not handled cmd[0x%x]", command);
843                         break;
844         }
845
846         return TRUE;
847 }
848
849 gboolean dbus_plugin_network_notification(struct custom_data *ctx, const char *plugin_name, TelephonyObjectSkeleton *object, enum tcore_notification_command command, unsigned int data_len, const void *data)
850 {
851         TelephonyNetwork *network;
852         const struct tnoti_network_registration_status *registration = data;
853         const struct tnoti_network_change *change = data;
854         const struct tnoti_network_icon_info *icon_info = data;
855         const struct tnoti_network_timeinfo *time_info = data;
856         const struct tnoti_network_identity *identity = data;
857         const struct tnoti_network_location_cellinfo *location = data;
858
859         if (!object) {
860                 dbg("object is NULL");
861                 return FALSE;
862         }
863
864         network = telephony_object_peek_network(TELEPHONY_OBJECT(object));
865         dbg("network = %p", network);
866
867         switch (command) {
868                 case TNOTI_NETWORK_REGISTRATION_STATUS:
869                         telephony_network_emit_registration_status(network,
870                                         registration->cs_domain_status,
871                                         registration->ps_domain_status,
872                                         registration->service_type,
873                                         registration->roaming_status);
874                         break;
875
876                 case TNOTI_NETWORK_CHANGE:
877                         telephony_network_emit_change(network,
878                                         change->act,
879                                         change->plmn,
880                                         change->gsm.lac);
881                         break;
882
883                 case TNOTI_NETWORK_ICON_INFO:
884                         telephony_network_emit_info(network,
885                                         icon_info->rssi,
886                                         icon_info->battery);
887                         break;
888
889                 case TNOTI_NETWORK_TIMEINFO:
890                         telephony_network_emit_time_info(network,
891                                         time_info->year,
892                                         time_info->month,
893                                         time_info->day,
894                                         time_info->hour,
895                                         time_info->minute,
896                                         time_info->second,
897                                         time_info->wday,
898                                         time_info->gmtoff,
899                                         time_info->dstoff,
900                                         time_info->isdst,
901                                         time_info->plmn);
902                         break;
903
904                 case TNOTI_NETWORK_IDENTITY:
905                         telephony_network_emit_identity(network,
906                                         identity->plmn,
907                                         identity->short_name,
908                                         identity->full_name);
909                         break;
910
911                 case TNOTI_NETWORK_LOCATION_CELLINFO:
912                         telephony_network_emit_cell_info(network,
913                                         location->lac,
914                                         location->cell_id);
915                         break;
916
917                 default:
918                         dbg("not handled cmd[0x%x]", command);
919                         break;
920         }
921
922         return TRUE;
923 }
924