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