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