Fix data roaming setting
[platform/core/telephony/tel-plugin-packetservice.git] / src / service.c
1 /*
2  * tel-plugin-packetservice
3  *
4  * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include "ps.h"
20 #include "generated-code.h"
21
22 #include <core_object.h>
23 #include <co_ps.h>
24 #include <co_context.h>
25
26
27 #define PROP_DEFAULT    FALSE
28 #define PROP_DEFAULT_STR   NULL
29 #define BOOL2STRING(a)  ((a == TRUE) ? ("TRUE"):("FALSE"))
30
31 #define TIMEOUT_DEFAULT         5
32 #define TIMEOUT_MAX                     1280
33
34 guint connection_timeout;
35 guint timer_src;
36
37 static void __ps_service_emit_property_changed_signal(PsService *service);
38 static void __ps_service_emit_context_added_signal(PsService *service, gpointer context);
39 static void __ps_service_emit_context_removed_signal(PsService *service, gpointer context);
40 static void _ps_service_setup_interface(PacketServiceService *service, PsService *service_data);
41
42 static char *__ps_service_act2string(TelNetworkAct act);
43 static gboolean __ps_service_check_connection_option(gpointer service, gpointer context);
44 static gboolean __ps_service_connetion_timeout_handler(gpointer user_data);
45
46 void __remove_service_handler(gpointer data)
47 {
48         PsService *service = data;
49
50         dbg("Entered");
51         if (!service) {
52                 dbg("Service is Null");
53                 return;
54         }
55
56         /*Need to remove the compelete hash table*/
57         g_hash_table_remove_all(service->contexts);
58
59         /*Need to UNexport and Unref the master Object */
60         if (service->if_obj) {
61                 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(service->if_obj));
62                 g_object_unref(service->if_obj);
63                 service->if_obj = NULL;
64         }
65
66         /*Need to free the memory of the internal structure*/
67         g_free(service->path);
68         g_free(service);
69 }
70
71 static void __ps_service_emit_property_changed_signal(PsService *service)
72 {
73         GVariant *gv = NULL;
74         GVariantBuilder property;
75
76         dbg("get service properties");
77
78         gv = _ps_service_get_properties(service, &property);
79         packet_service_service_emit_property_changed(service->if_obj, gv);
80
81         dbg("Exiting");
82 }
83
84 static void __ps_service_emit_context_added_signal(PsService *service, gpointer context)
85 {
86         GVariant *gv = NULL;
87         GVariantBuilder property;
88
89         dbg("get service properties");
90
91         gv = _ps_context_get_properties(context, &property);
92         packet_service_service_emit_context_added(service->if_obj, gv);
93
94         dbg("Exiting");
95 }
96
97 static void __ps_service_emit_context_removed_signal(PsService *service, gpointer context)
98 {
99         PsContext *pscontext = context;
100
101         dbg("Entered");
102         packet_service_service_emit_context_removed(service->if_obj, pscontext->path);
103
104         dbg("Exiting");
105 }
106
107 static char *__ps_service_act2string(TelNetworkAct act)
108 {
109         switch (act) {
110                 case TEL_NETWORK_ACT_GSM:
111                 case TEL_NETWORK_ACT_GPRS:
112                 case TEL_NETWORK_ACT_EGPRS:
113                 case TEL_NETWORK_ACT_UMTS:
114                 case TEL_NETWORK_ACT_GSM_AND_UMTS:
115                         return "GSM";
116                 case TEL_NETWORK_ACT_LTE:
117                         return "LTE";
118                 case TEL_NETWORK_ACT_UNKNOWN:
119                 default:
120                         return "unknown";
121         }
122
123         return NULL;
124 }
125
126 static gboolean __ps_service_check_connection_option(gpointer object, gpointer context)
127 {
128         gboolean b_connect = TRUE;
129         gboolean power, sim, data, flight;
130         PsService *service = object;
131
132         power = _ps_modem_get_power(service->p_modem);
133         b_connect &= power;
134
135         sim = _ps_modem_get_sim_init(service->p_modem);
136         b_connect &= sim;
137
138         data = _ps_modem_get_data_allowed(service->p_modem);
139         b_connect &= data;
140
141         if (service->roaming)
142                 b_connect &= _ps_modem_get_data_roaming_allowed(service->p_modem);
143
144         flight = _ps_modem_get_flght_mode(service->p_modem);
145         b_connect &= !flight;
146
147         b_connect &= !service->restricted;
148
149         dbg("power(%d), sim init(%d), data allowed(%d), flight mode(%d) ",
150                 power, sim, data, flight);
151
152         return b_connect;
153 }
154
155 static gboolean __ps_service_connetion_timeout_handler(gpointer context)
156 {
157         gint rv = 0;
158         PsService *service = NULL;
159
160         service = _ps_context_ref_service(context);
161         rv = _ps_service_activate_context(service, context);
162         dbg("return rv(%d)", rv);
163
164         return FALSE;
165 }
166
167 gpointer _ps_service_create_service(GDBusConnection *conn, TcorePlugin *p, gpointer p_modem,
168                 CoreObject *co_network, CoreObject *co_ps, gchar* path)
169 {
170         PacketServiceService *service;
171         GError *error = NULL;
172         PsService *new_service;
173
174         dbg("service object create");
175         tcore_check_return_value(conn != NULL, NULL);
176         tcore_check_return_value(p_modem != NULL, NULL);
177
178         /*creating the master object for the interface com.tcore.ps.modem*/
179         service = packet_service_service_skeleton_new();
180
181         /*Initializing the modem list for internal referencing*/
182         new_service = g_try_malloc0(sizeof(PsService));
183         if (NULL == new_service) {
184                 err("Unable to allocate memory for master");
185                 goto FAILURE;
186         }
187
188         new_service->conn = conn;
189         new_service->plg = p;
190         new_service->p_modem = p_modem;
191         new_service->co_network = co_network;
192         new_service->co_ps = co_ps;
193         new_service->path = g_strdup(path);
194         new_service->if_obj = service;
195         new_service->contexts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
196
197         _ps_hook_co_network_event(new_service);
198         _ps_get_co_network_values(new_service);
199         _ps_hook_co_ps_event(new_service);
200
201         /*Setting up the interface for the service */
202         _ps_service_setup_interface(service, new_service);
203
204         /*exporting the interface object to the path mention for master*/
205         g_dbus_interface_skeleton_export((G_DBUS_INTERFACE_SKELETON(service)),
206                         conn,
207                         path,
208                         &error);
209
210         g_assert_no_error (error);
211
212         connection_timeout = TIMEOUT_DEFAULT;
213         dbg("Successfully Created the service");
214         return new_service;
215
216 FAILURE:
217         /*To Do: Handle failure case*/
218         return NULL;
219 }
220
221 gboolean _ps_service_ref_context(gpointer object, gpointer context)
222 {
223         gpointer tmp = NULL;
224         gchar *s_path = NULL;
225         PsService *service = object;
226
227         dbg("service refer to context");
228         tcore_check_return_value(service != NULL, FALSE);
229
230         s_path = _ps_context_ref_path(context);
231         tmp = g_hash_table_lookup(service->contexts, s_path);
232         if (tmp != NULL) {
233                 dbg("context(%p) already existed", tmp);
234                 return FALSE;
235         }
236
237         /* Setting service */
238         _ps_context_set_service(context, service);
239
240         /* Add Context to PS Core object */
241         tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
242
243         /* Insert conetxt to Hash Table */
244         g_hash_table_insert(service->contexts, g_strdup(s_path), context);
245
246         dbg("context(%p) insert to hash", context);
247
248         /* Emit Context added signal */
249         __ps_service_emit_context_added_signal(service, context);
250
251         //_ps_service_connect_default_context(service);
252         return TRUE;
253 }
254
255 gboolean _ps_service_ref_contexts(gpointer object, GHashTable *contexts, gchar *operator)
256 {
257         GHashTableIter iter;
258         gpointer key, value;
259         PsService *service = object;
260         gboolean ret = TRUE;
261         gint rv;
262
263         dbg("service refer to contexts");
264         tcore_check_return_value(service != NULL, FALSE);
265
266         g_hash_table_iter_init(&iter, contexts);
267         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
268                 gchar *s_path = NULL;
269                 gpointer tmp = NULL;
270                 gboolean f_awo = FALSE;
271
272                 s_path = _ps_context_ref_path(value);
273                 dbg("Path: [%s]", s_path);
274
275                 /* Hash lookup */
276                 tmp = g_hash_table_lookup(service->contexts, s_path);
277                 if (tmp != NULL) {
278                         dbg("context(%p) already existed", tmp);
279                         continue;
280                 }
281
282                 /* Setting service */
283                 _ps_context_set_service(value, service);
284
285                 /* Add Context to PS Core object */
286                 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(value));
287
288                 /* Insert context to Service  Hash Table */
289                 g_hash_table_insert(service->contexts, g_strdup(s_path), value);
290
291                 dbg("Inserted context to Hash table - context [%p]", value);
292
293                 /* Emit Context added signal */
294                 __ps_service_emit_context_added_signal(service, value);
295
296                 f_awo = _ps_context_get_alwayson_enable(value);
297                 if (f_awo) {
298                         rv = _ps_service_define_context(service, value);
299                         dbg("return rv(%d)", rv);
300                 }
301         }
302
303         /* Update cellular state key */
304         _ps_update_cellular_state_key(service);
305
306         return ret;
307 }
308
309 gboolean _ps_service_unref_context(gpointer object, gpointer context)
310 {
311         PsService *service = object;
312
313         dbg("service unref contexts");
314         tcore_check_return_value(service != NULL, FALSE);
315         tcore_check_return_value(context != NULL, FALSE);
316
317         dbg("remove context(%p) from service(%p)", context, service);
318
319         /* Remove Context from PS Core object */
320         tcore_ps_remove_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
321
322         /* Remove context to Hash Table */
323         g_hash_table_remove(service->contexts, _ps_context_ref_path(context));
324
325         /* Emit Context Remove signal */
326         __ps_service_emit_context_removed_signal(service, context);
327
328         return TRUE;
329 }
330
331 gboolean _ps_service_get_properties_handler(gpointer object, GVariantBuilder *properties)
332 {
333         PsService *service = object;
334
335         dbg("get service properties");
336         tcore_check_return_value(service != NULL, FALSE);
337         tcore_check_return_value(properties != NULL, FALSE);
338
339         g_variant_builder_open(properties, G_VARIANT_TYPE("a{ss}"));
340         g_variant_builder_add(properties, "{ss}", "path", g_strdup(service->path));
341         g_variant_builder_add(properties, "{ss}", "ps_attached", g_strdup(BOOL2STRING(service->ps_attached)));
342         g_variant_builder_add(properties, "{ss}", "roaming", g_strdup(BOOL2STRING(service->roaming)));
343         g_variant_builder_add(properties, "{ss}", "act", g_strdup(__ps_service_act2string(service->act)));
344         g_variant_builder_close(properties);
345
346         return TRUE;
347 }
348
349 GVariant * _ps_service_get_properties(gpointer object, GVariantBuilder *properties)
350 {
351         PsService *service = object;
352
353         dbg("get service properties");
354         tcore_check_return_value(service != NULL, FALSE);
355         tcore_check_return_value(properties != NULL, FALSE);
356
357         g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
358
359         g_variant_builder_add(properties, "{ss}", "path", g_strdup(service->path));
360         g_variant_builder_add(properties, "{ss}", "ps_attached", g_strdup(BOOL2STRING(service->ps_attached)));
361         g_variant_builder_add(properties, "{ss}", "roaming", g_strdup(BOOL2STRING(service->roaming)));
362         g_variant_builder_add(properties, "{ss}", "act", g_strdup(__ps_service_act2string(service->act)));
363
364         return g_variant_builder_end(properties);
365 }
366
367 gchar* _ps_service_ref_path(gpointer object)
368 {
369         PsService *service = object;
370         tcore_check_return_value(service != NULL, NULL);
371
372         return service->path;
373 }
374
375 gpointer _ps_service_ref_plugin(gpointer object)
376 {
377         PsService *service = object;
378         tcore_check_return_value(service != NULL, NULL);
379
380         return service->plg;
381 }
382
383 gpointer _ps_service_ref_co_network(gpointer object)
384 {
385         PsService *service = object;
386         tcore_check_return_value(service != NULL, NULL);
387
388         return service->co_network;
389 }
390
391 gpointer _ps_service_ref_co_ps(gpointer object)
392 {
393         PsService *service = object;
394         tcore_check_return_value(service != NULL, NULL);
395
396         return service->co_ps;
397 }
398
399 gpointer _ps_service_ref_modem(gpointer object)
400 {
401         PsService *service = object;
402         tcore_check_return_value(service != NULL, NULL);
403
404         return service->p_modem;
405 }
406
407 gboolean _ps_service_set_context_info(gpointer object, TcorePsPdpIpConf *devinfo)
408 {
409         GSList* contexts = NULL;
410         PsService *service = object;
411
412         dbg("Set context information");
413
414         tcore_check_return_value(service != NULL, FALSE);
415
416         /* Refer context */
417         dbg("Context ID: [%d]", devinfo->context_id);
418         tcore_ps_ref_context_by_id(service->co_ps, devinfo->context_id, &contexts);
419         if (NULL == contexts) {
420                 err("Failed to refer context");
421                 return FALSE;
422         }
423
424         for (; contexts != NULL; contexts = g_slist_next(contexts)) {
425                 CoreObject *co_context = NULL;
426
427                 co_context = contexts->data;
428                 if (NULL == co_context) {
429                         err("Context is NULL");
430                         continue;
431                 }
432
433                 /* Set device information */
434                 tcore_context_set_devinfo(co_context, devinfo);
435         }
436
437         return TRUE;
438 }
439
440 gint _ps_service_define_context(gpointer object, gpointer context)
441 {
442         PsService *service = object;
443         CoreObject *co_context = NULL;
444         gboolean b_connect = TRUE;
445         TelReturn ret;
446
447         dbg("define context(%p)", context);
448         tcore_check_return_value(service != NULL, TEL_RETURN_FAILURE);
449
450         co_context = (CoreObject *)_ps_context_ref_co_context(context);
451
452         b_connect = __ps_service_check_connection_option(service, co_context);
453         if (!b_connect) {
454                 return TEL_RETURN_FAILURE;
455
456         }
457
458         ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
459                 TCORE_COMMAND_PS_DEFINE_CONTEXT,
460                 &co_context, sizeof(CoreObject *),
461                 NULL, NULL);
462
463         return ret;
464 }
465
466 gint _ps_service_activate_context(gpointer object, gpointer context)
467 {
468         PsService *service = object;
469         CoreObject *co_context = NULL;
470         gboolean b_connect = TRUE;
471         gboolean ps_defined;
472         gint ret = TEL_RETURN_FAILURE;
473
474         dbg("Activate context [0x%x]", context);
475         tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
476
477         co_context = (CoreObject *)_ps_context_ref_co_context(context);
478
479         b_connect = __ps_service_check_connection_option(service, co_context);
480         if (!b_connect) {
481                 err("Connection option failed");
482                 return TEL_RETURN_FAILURE;
483         }
484
485         ps_defined = _ps_context_get_ps_defined(context);
486         if (!ps_defined) {
487                 dbg("PDP profile is NOT defined!!! Need to define it first... co_context: [%p]");
488                 ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
489                         TCORE_COMMAND_PS_DEFINE_CONTEXT,
490                         &co_context, sizeof(CoreObject *),
491                         NULL, NULL);
492         } else {
493                 dbg("PDP profile is defined!!! Activate context...");
494                 ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
495                         TCORE_COMMAND_PS_ACTIVATE_CONTEXT,
496                         &co_context, sizeof(CoreObject *),
497                         NULL, NULL);
498         }
499
500         return ret;
501 }
502
503 gint _ps_service_deactivate_context(gpointer object, gpointer context)
504 {
505         PsService *service = object;
506         CoreObject *co_context = NULL;
507         TelReturn ret = TEL_RETURN_FAILURE ;
508
509         dbg("deactivate context(%p)", context);
510         tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
511
512         co_context = (CoreObject *)_ps_context_ref_co_context(context);
513         ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
514                 TCORE_COMMAND_PS_DEACTIVATE_CONTEXT,
515                 &co_context, sizeof(CoreObject *),
516                 NULL, NULL);
517
518         return ret;
519 }
520
521 void _ps_service_set_retry_timeout_value(int value)
522 {
523         connection_timeout = value;
524         dbg("current timeout (%d)", connection_timeout);
525 }
526
527 void _ps_service_connection_timer(gpointer object, gpointer context)
528 {
529         gboolean f_awo = FALSE;
530
531         f_awo = _ps_context_get_alwayson_enable(context);
532         if (!f_awo)
533                 return;
534
535         if (timer_src != 0) {
536                 dbg("remove connection retry timer (%d)", timer_src);
537                 g_source_remove(timer_src);
538                 timer_src = 0;
539         }
540
541         timer_src = g_timeout_add_seconds(connection_timeout, __ps_service_connetion_timeout_handler, context);
542
543         dbg("cellular service timer started timer src(%d), timeout(%d)", timer_src, connection_timeout);
544         connection_timeout = connection_timeout*2;
545         if (connection_timeout >= TIMEOUT_MAX)
546                 connection_timeout = TIMEOUT_DEFAULT;
547 }
548
549 void _ps_service_reset_connection_timer(gpointer context)
550 {
551         gboolean f_awo = FALSE;
552
553         f_awo = _ps_context_get_alwayson_enable(context);
554         dbg("Always ON: [%s]", (f_awo ? "YES" : "NO"));
555         if(f_awo == FALSE)
556                 return;
557
558         connection_timeout = TIMEOUT_DEFAULT;
559
560         if (timer_src != 0) {
561                 dbg("Remove connection Retry timer [%d]", timer_src);
562
563                 g_source_remove(timer_src);
564                 timer_src = 0;
565         }
566 }
567
568 void _ps_service_remove_contexts(gpointer object)
569 {
570         GHashTableIter iter;
571         gpointer key, value;
572         PsService *service = object;
573
574         dbg("service remove all contexts");
575         tcore_check_return(service != NULL);
576
577         g_hash_table_iter_init(&iter, service->contexts);
578         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
579                 gpointer co_context = NULL;
580
581                 dbg("key(%s), value(%p) context", key, value);
582                 co_context = _ps_context_ref_co_context(value);
583
584                 _ps_service_reset_connection_timer(value);
585                 _ps_context_set_alwayson_enable(value, FALSE);
586                 _ps_service_deactivate_context(service, value);
587                 _ps_context_set_connected(value, FALSE);
588                 tcore_ps_remove_context(service->co_ps, co_context);
589                 tcore_context_free(co_context);
590
591                 __ps_service_emit_context_removed_signal(service, value);
592                 _ps_context_remove_context(value);
593         }
594
595         g_hash_table_remove_all(service->contexts);
596 }
597
598 void _ps_service_disconnect_contexts(gpointer object)
599 {
600         GHashTableIter iter;
601         gpointer key, value;
602         PsService *service = object;
603
604         dbg("service disconnect all contexts");
605         tcore_check_return(service != NULL);
606
607         g_hash_table_iter_init(&iter, service->contexts);
608         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
609                 _ps_service_reset_connection_timer(value);
610                 _ps_service_deactivate_context(service, value);
611         }
612 }
613
614 gint _ps_service_connect_default_context(gpointer object)
615 {
616         gint rv = TEL_RETURN_FAILURE;
617         GHashTableIter iter;
618         gpointer key, value;
619         PsService *service = object;
620
621         dbg("service connect default context");
622         tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
623
624         g_hash_table_iter_init(&iter, service->contexts);
625         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
626                 gboolean f_awo = FALSE;
627                 f_awo = _ps_context_get_alwayson_enable(value);
628
629                 if (f_awo) {
630                         _ps_service_reset_connection_timer(value);
631
632                         /* Activate Context */
633                         rv = _ps_service_activate_context(service, value);
634                         dbg("return rv(%d)", rv);
635                         break;
636                 }
637         }
638
639         return rv;
640 }
641
642 gpointer _ps_service_return_default_context(gpointer object)
643 {
644         GHashTableIter iter;
645         gpointer key, value;
646         PsService *service = object;
647
648         tcore_check_return_value(service != NULL, NULL);
649
650         g_hash_table_iter_init(&iter, service->contexts);
651         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
652                 gboolean b_default = FALSE;
653                 b_default = _ps_context_get_default_internet(value);
654
655                 if (b_default) {
656                         return value;
657                 }
658         }
659
660         return NULL;
661 }
662
663 gboolean _ps_service_processing_network_event(gpointer object,
664         gboolean ps_attached, gboolean roaming)
665 {
666         PsService *service = object;
667         tcore_check_return_value(service != NULL, FALSE);
668
669         _ps_service_set_ps_attached(service, ps_attached);
670         _ps_update_cellular_state_key(service);
671
672         if (service->roaming != roaming) {
673                 gboolean roaming_allowed = FALSE;
674                 _ps_service_set_roaming(service, roaming);
675                 roaming_allowed = _ps_modem_get_data_roaming_allowed(service->p_modem);
676                 if (!roaming_allowed && roaming) {
677                         dbg("Roaming allowed (%d), Roaming status (%d)", roaming_allowed, roaming);
678                         _ps_service_disconnect_contexts(service);
679                         return TRUE;
680                 }
681         }
682
683         if (service->ps_attached)
684                 _ps_service_connect_default_context(service);
685
686         return TRUE;
687 }
688
689 gboolean _ps_service_set_connected(gpointer object, gint context_id, gboolean enabled)
690 {
691         GHashTableIter iter;
692         gpointer key, value;
693
694         PsService *service = NULL;
695
696         service = (PsService *) object;
697         g_hash_table_iter_init(&iter, service->contexts);
698         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
699                 guint tmp_cid;
700                 CoreObject *context = NULL;
701
702                 context = _ps_context_ref_co_context(value);
703                 tcore_context_get_id(context, &tmp_cid);
704
705                 if (tmp_cid != (guint)context_id) continue;
706
707                 if (!enabled) {
708                         dbg("Reset socket connections.");
709                         tcore_ps_clear_context_id(service->co_ps, context);
710                 }
711
712                 _ps_context_set_connected(value, enabled);
713         }
714
715         return TRUE;
716 }
717
718 void _ps_service_set_ps_defined(gpointer *object, gboolean value, int cid)
719 {
720         PsService *service = (PsService*)object;
721         GHashTableIter iter;
722         gpointer key, out;
723
724         tcore_check_return(service != NULL);
725
726         g_hash_table_iter_init(&iter, service->contexts);
727         while (g_hash_table_iter_next(&iter, &key, &out) == TRUE) {
728                 gboolean r_actvate = 0;
729                 r_actvate = _ps_context_set_ps_defined(out, value, cid);
730                 r_actvate &= value;
731                 if (r_actvate) {
732                         int rv;
733                         dbg("define is complete, activate context for cid(%d)", cid);
734                         rv = _ps_service_activate_context(service, out);
735                         dbg("rv(%d)", rv);
736                         break;
737                 }
738         }
739 }
740
741 gboolean _ps_service_set_ps_attached(gpointer object, gboolean value)
742 {
743         PsService *service = object;
744         tcore_check_return_value(service != NULL, FALSE);
745
746         service->ps_attached = value;
747         dbg("service(%p) ps_attached(%d)", service, service->ps_attached);
748
749         return TRUE;
750 }
751
752 gboolean _ps_service_get_restricted(gpointer object)
753 {
754         PsService *service = object;
755         tcore_check_return_value(service != NULL, FALSE);
756
757         return service->restricted;
758 }
759
760 gboolean _ps_service_set_restricted(gpointer object, gboolean value)
761 {
762         PsService *service = object;
763         tcore_check_return_value(service != NULL, FALSE);
764
765         service->restricted = value;
766         dbg("service(%p) restricted(%d)", service, service->restricted);
767
768         _ps_update_cellular_state_key(service);
769         return TRUE;
770 }
771
772 #if 0
773 gboolean _ps_service_set_number_of_pdn_cnt(gpointer object, gchar *operator)
774 {
775         int rv = 0;
776         int num_of_pdn = 0;
777         PsService *service = object;
778         tcore_check_return_value(service != NULL, FALSE);
779         dbg("Entered");
780         num_of_pdn = _ps_context_get_number_of_pdn(operator);
781         rv = tcore_ps_set_num_of_pdn(service->co_ps, num_of_pdn);
782
783         if (rv != TEL_RETURN_SUCCESS) {
784                 dbg("error to get maximum number of pdn");
785         }
786         dbg("Exiting");
787         return TRUE;
788 }
789 #endif
790
791 gboolean _ps_service_get_roaming(gpointer object)
792 {
793         PsService *service = object;
794         tcore_check_return_value(service != NULL, FALSE);
795
796         return service->roaming;
797 }
798
799 gboolean _ps_service_set_roaming(gpointer object, gboolean value)
800 {
801         PsService *service = object;
802         tcore_check_return_value(service != NULL, FALSE);
803
804         service->roaming = value;
805         dbg("service(%p) roaming(%d)", service, service->roaming);
806         __ps_service_emit_property_changed_signal(service);
807
808         return TRUE;
809 }
810
811 static void _indicator_cb_dns_reply(GObject *src, GAsyncResult *res, gpointer user_data)
812 {
813         GList *list, *cur;
814         GInetAddress *addr;
815         gchar *str_addr;
816         GError *error = NULL;
817
818         list = g_resolver_lookup_by_name_finish((GResolver *)src, res, &error);
819         if (!list) {
820                 dbg("fail to get dns resolving");
821                 if (error) {
822                         dbg ("error:%d, %s", error->code, error->message);
823                         g_error_free (error);
824                 }
825                 return;
826         }
827
828         for (cur = list; cur; cur = cur->next) {
829                 addr = cur->data;
830                 str_addr = g_inet_address_to_string(addr);
831                 if (!str_addr)
832                         continue;
833                 dbg("addr(%s)", str_addr);
834
835                 g_free(str_addr);
836                 g_object_unref(cur->data);
837                 break;
838         }
839
840         g_object_unref(src);
841         g_list_free(list);
842 }
843
844 gboolean _ps_service_set_access_technology(gpointer object,
845                 TelNetworkAct value)
846 {
847         PsService *service = object;
848         TelNetworkAct p_act = 0;
849         tcore_check_return_value(service != NULL, FALSE);
850
851         p_act = service->act;
852         service->act = value;
853         dbg("service(%p) P ACT(%d) Access Technology(%d)", service, p_act, service->act);
854
855         if (p_act == TEL_NETWORK_ACT_LTE
856                         && (service->act >= TEL_NETWORK_ACT_GSM
857                         && service->act < TEL_NETWORK_ACT_LTE)) {
858                 GResolver *r = NULL;
859
860                 dbg("send the dns pkt for keeping connection");
861
862                 r = g_resolver_get_default();
863                 g_resolver_lookup_by_name_async(r, "www.google.com", NULL, _indicator_cb_dns_reply, NULL);
864         }
865
866         if (service->act > TEL_NETWORK_ACT_UNKNOWN) {
867                 _ps_update_cellular_state_key(service);
868                 _ps_service_connect_default_context(service);
869         }
870
871         return TRUE;
872 }
873
874 TcorePsState _ps_service_check_cellular_state(gpointer object)
875 {
876         gboolean state = FALSE;
877         PsService *service = object;
878         tcore_check_return_value(service != NULL, TCORE_PS_STATE_NO_SERVICE);
879
880         state = _ps_modem_get_power(service->p_modem);
881         if (!state) {
882                 dbg("NO SERVICE");
883                 return TCORE_PS_STATE_NO_SERVICE;
884         }
885
886         state = _ps_modem_get_sim_init(service->p_modem);
887         if (!state) {
888                 dbg("NO SERVICE");
889                 return TCORE_PS_STATE_NO_SERVICE;
890         }
891
892         state = _ps_modem_get_flght_mode(service->p_modem);
893         if (state) {
894                 dbg("FLIGHT MODE ON");
895                 return TCORE_PS_STATE_FLIGHT_MODE;
896         }
897
898         if (!service->ps_attached) {
899                 dbg("NO SERVICE");
900                 return TCORE_PS_STATE_NO_SERVICE;
901         }
902
903         state = _ps_modem_get_data_allowed(service->p_modem);
904         if (!state) {
905                 dbg("DATA OFF");
906                 return TCORE_PS_STATE_3G_OFF;
907         }
908
909         state = _ps_modem_get_data_roaming_allowed(service->p_modem);
910
911         if (service->roaming && !state) {
912                 dbg("DATA ROAMING OFF");
913                 return TCORE_PS_STATE_ROAMING_OFF;
914         }
915
916         return TCORE_PS_STATE_ON;
917 }
918 static gboolean on_service_get_properties (PacketServiceService *obj_service,
919         GDBusMethodInvocation *invocation, gpointer user_data)
920 {
921         GVariant *gv = NULL;
922         GVariantBuilder property;
923         dbg("get service properties");
924
925         gv = _ps_service_get_properties(user_data, &property);
926         packet_service_service_complete_get_properties(obj_service, invocation, gv);
927         return TRUE;
928 }
929
930 static gboolean on_service_get_context (PacketServiceService *obj_service,
931         GDBusMethodInvocation *invocation, gpointer user_data)
932 {
933         GVariantBuilder b_context;
934         GVariant *contexts;
935
936         GHashTableIter iter;
937         gpointer key, value;
938         PsService *service = user_data;
939
940         dbg("modem get contexts interface");
941
942         if (service->contexts == NULL) {
943                 err("No context present for service");
944                 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
945                 return TRUE;
946         }
947
948         g_variant_builder_init(&b_context, G_VARIANT_TYPE("a{sa{ss}}"));
949         g_hash_table_iter_init(&iter, service->contexts);
950         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
951                 gchar *path = NULL;
952                 g_variant_builder_open(&b_context,G_VARIANT_TYPE("{sa{ss}}"));
953                 path = _ps_service_ref_path(value);
954
955                 g_variant_builder_add(&b_context, "s",g_strdup(path));
956                 if (FALSE == _ps_context_get_properties_handler(value, &b_context)) {
957                         err("Failed to get property");
958                         g_variant_builder_close(&b_context);
959                         FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
960                         return TRUE;
961                 }
962                 g_variant_builder_close(&b_context);
963
964         }
965
966         contexts = g_variant_builder_end(&b_context);
967         packet_service_service_complete_get_contexts(obj_service, invocation,contexts);
968         return TRUE;
969 }
970
971 static void _ps_service_setup_interface(PacketServiceService *service,
972         PsService *service_data)
973 {
974         dbg("Entered");
975         g_signal_connect (service,
976                 "handle-get-properties",
977                 G_CALLBACK (on_service_get_properties),
978                 service_data);
979
980         g_signal_connect (service,
981                 "handle-get-contexts",
982                 G_CALLBACK (on_service_get_context),
983                 service_data);
984
985         dbg("Exiting");
986 }