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