2 * tel-plugin-packetservice
4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "generated-code.h"
22 #include <core_object.h>
24 #include <co_context.h>
27 #define PROP_DEFAULT FALSE
28 #define PROP_DEFAULT_STR NULL
29 #define BOOL2STRING(a) ((a == TRUE) ? ("TRUE"):("FALSE"))
31 #define TIMEOUT_DEFAULT 5
32 #define TIMEOUT_MAX 1280
34 guint connection_timeout;
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);
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);
46 void __remove_service_handler(gpointer data)
48 PsService *service = data;
52 dbg("Service is Null");
56 /*Need to remove the compelete hash table*/
57 g_hash_table_remove_all(service->contexts);
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;
66 /*Need to free the memory of the internal structure*/
67 g_free(service->path);
71 static void __ps_service_emit_property_changed_signal(PsService *service)
74 GVariantBuilder property;
76 dbg("get service properties");
78 gv = _ps_service_get_properties(service, &property);
79 packet_service_service_emit_property_changed(service->if_obj, gv);
84 static void __ps_service_emit_context_added_signal(PsService *service, gpointer context)
87 GVariantBuilder property;
89 dbg("get service properties");
91 gv = _ps_context_get_properties(context, &property);
92 packet_service_service_emit_context_added(service->if_obj, gv);
97 static void __ps_service_emit_context_removed_signal(PsService *service, gpointer context)
99 PsContext *pscontext = context;
102 packet_service_service_emit_context_removed(service->if_obj, pscontext->path);
107 static char *__ps_service_act2string(TelNetworkAct 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:
116 case TEL_NETWORK_ACT_LTE:
118 case TEL_NETWORK_ACT_UNKNOWN:
126 static gboolean __ps_service_check_connection_option(gpointer object, gpointer context)
128 gboolean b_connect = TRUE;
129 gboolean power, sim, data, flight;
130 PsService *service = object;
132 power = _ps_modem_get_power(service->p_modem);
135 sim = _ps_modem_get_sim_init(service->p_modem);
138 data = _ps_modem_get_data_allowed(service->p_modem);
141 if (service->roaming)
142 b_connect &= _ps_modem_get_data_roaming_allowed(service->p_modem);
144 flight = _ps_modem_get_flght_mode(service->p_modem);
145 b_connect &= !flight;
147 b_connect &= !service->restricted;
149 dbg("power(%d), sim init(%d), data allowed(%d), flight mode(%d) ",
150 power, sim, data, flight);
155 static gboolean __ps_service_connetion_timeout_handler(gpointer context)
158 PsService *service = NULL;
160 service = _ps_context_ref_service(context);
161 rv = _ps_service_activate_context(service, context);
162 dbg("return rv(%d)", rv);
167 gpointer _ps_service_create_service(GDBusConnection *conn, TcorePlugin *p, gpointer p_modem,
168 CoreObject *co_network, CoreObject *co_ps, gchar* path)
170 PacketServiceService *service;
171 GError *error = NULL;
172 PsService *new_service;
174 dbg("service object create");
175 tcore_check_return_value(conn != NULL, NULL);
176 tcore_check_return_value(p_modem != NULL, NULL);
178 /*creating the master object for the interface com.tcore.ps.modem*/
179 service = packet_service_service_skeleton_new();
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");
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);
197 _ps_hook_co_network_event(new_service);
198 _ps_get_co_network_values(new_service);
199 _ps_hook_co_ps_event(new_service);
201 /*Setting up the interface for the service */
202 _ps_service_setup_interface(service, new_service);
204 /*exporting the interface object to the path mention for master*/
205 g_dbus_interface_skeleton_export((G_DBUS_INTERFACE_SKELETON(service)),
210 g_assert_no_error (error);
212 connection_timeout = TIMEOUT_DEFAULT;
213 dbg("Successfully Created the service");
217 /*To Do: Handle failure case*/
221 gboolean _ps_service_ref_context(gpointer object, gpointer context)
224 gchar *s_path = NULL;
225 PsService *service = object;
227 dbg("service refer to context");
228 tcore_check_return_value(service != NULL, FALSE);
230 s_path = _ps_context_ref_path(context);
231 tmp = g_hash_table_lookup(service->contexts, s_path);
233 dbg("context(%p) already existed", tmp);
237 /* Setting service */
238 _ps_context_set_service(context, service);
240 /* Insert conetxt to Hash Table */
241 g_hash_table_insert(service->contexts, g_strdup(s_path), context);
243 dbg("context(%p) insert to hash", context);
245 /* Emit Context added signal */
246 __ps_service_emit_context_added_signal(service, context);
248 //_ps_service_connect_default_context(service);
252 gboolean _ps_service_ref_contexts(gpointer object, GHashTable *contexts, gchar *operator)
256 PsService *service = object;
260 dbg("service refer to contexts");
261 tcore_check_return_value(service != NULL, FALSE);
263 g_hash_table_iter_init(&iter, contexts);
264 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
265 gchar *s_path = NULL;
267 gboolean f_awo = FALSE;
269 s_path = _ps_context_ref_path(value);
270 dbg("Path: [%s]", s_path);
273 tmp = g_hash_table_lookup(service->contexts, s_path);
275 dbg("context(%p) already existed", tmp);
279 /* Setting service */
280 _ps_context_set_service(value, service);
282 /* Insert context to Service Hash Table */
283 g_hash_table_insert(service->contexts, g_strdup(s_path), value);
285 dbg("Inserted context to Hash table - context [%p]", value);
287 /* Emit Context added signal */
288 __ps_service_emit_context_added_signal(service, value);
290 f_awo = _ps_context_get_alwayson_enable(value);
292 rv = _ps_service_define_context(service, value);
293 dbg("return rv(%d)", rv);
297 /* Update cellular state key */
298 _ps_update_cellular_state_key(service);
303 gboolean _ps_service_unref_context(gpointer object, gpointer context)
305 PsService *service = object;
307 dbg("service unref contexts");
308 tcore_check_return_value(service != NULL, FALSE);
309 tcore_check_return_value(context != NULL, FALSE);
311 dbg("remove context(%p) from service(%p)", context, service);
313 /* Remove Context from PS Core object */
314 //tcore_ps_remove_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
316 /* Remove context to Hash Table */
317 g_hash_table_remove(service->contexts, _ps_context_ref_path(context));
319 /* Emit Context Remove signal */
320 __ps_service_emit_context_removed_signal(service, context);
325 gboolean _ps_service_get_properties_handler(gpointer object, GVariantBuilder *properties)
327 PsService *service = object;
329 dbg("get service properties");
330 tcore_check_return_value(service != NULL, FALSE);
331 tcore_check_return_value(properties != NULL, FALSE);
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);
343 GVariant * _ps_service_get_properties(gpointer object, GVariantBuilder *properties)
345 PsService *service = object;
347 dbg("get service properties");
348 tcore_check_return_value(service != NULL, FALSE);
349 tcore_check_return_value(properties != NULL, FALSE);
351 g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
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)));
358 return g_variant_builder_end(properties);
361 gchar* _ps_service_ref_path(gpointer object)
363 PsService *service = object;
364 tcore_check_return_value(service != NULL, NULL);
366 return service->path;
369 gpointer _ps_service_ref_plugin(gpointer object)
371 PsService *service = object;
372 tcore_check_return_value(service != NULL, NULL);
377 gpointer _ps_service_ref_co_network(gpointer object)
379 PsService *service = object;
380 tcore_check_return_value(service != NULL, NULL);
382 return service->co_network;
385 gpointer _ps_service_ref_co_ps(gpointer object)
387 PsService *service = object;
388 tcore_check_return_value(service != NULL, NULL);
390 return service->co_ps;
393 gpointer _ps_service_ref_modem(gpointer object)
395 PsService *service = object;
396 tcore_check_return_value(service != NULL, NULL);
398 return service->p_modem;
401 gboolean _ps_service_set_context_info(gpointer object, TcorePsPdpIpConf *devinfo)
403 GSList* contexts = NULL;
404 PsService *service = object;
406 dbg("Set context information");
408 tcore_check_return_value(service != NULL, FALSE);
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");
418 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
419 CoreObject *co_context = NULL;
421 co_context = contexts->data;
422 if (NULL == co_context) {
423 err("Context is NULL");
427 /* Set device information */
428 tcore_context_set_devinfo(co_context, devinfo);
434 gint _ps_service_define_context(gpointer object, gpointer context)
436 PsService *service = object;
437 CoreObject *co_context = NULL;
438 gboolean b_connect = TRUE;
441 dbg("define context(%p)", context);
442 tcore_check_return_value(service != NULL, TEL_RETURN_FAILURE);
444 co_context = (CoreObject *)_ps_context_ref_co_context(context);
446 b_connect = __ps_service_check_connection_option(service, co_context);
448 return TEL_RETURN_FAILURE;
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 *),
460 gint _ps_service_activate_context(gpointer object, gpointer context)
462 PsService *service = object;
463 CoreObject *co_context = NULL;
464 gboolean b_connect = TRUE;
466 gint ret = TEL_RETURN_FAILURE;
468 dbg("Activate context [0x%x]", context);
469 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
471 co_context = (CoreObject *)_ps_context_ref_co_context(context);
473 b_connect = __ps_service_check_connection_option(service, co_context);
475 err("Connection option failed");
476 return TEL_RETURN_FAILURE;
479 ps_defined = _ps_context_get_ps_defined(context);
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 *),
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 *),
497 gint _ps_service_deactivate_context(gpointer object, gpointer context)
499 PsService *service = object;
500 CoreObject *co_context = NULL;
501 TelReturn ret = TEL_RETURN_FAILURE ;
503 dbg("deactivate context(%p)", context);
504 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
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 *),
515 void _ps_service_set_retry_timeout_value(int value)
517 connection_timeout = value;
518 dbg("current timeout (%d)", connection_timeout);
521 void _ps_service_connection_timer(gpointer object, gpointer context)
523 gboolean f_awo = FALSE;
525 f_awo = _ps_context_get_alwayson_enable(context);
529 if (timer_src != 0) {
530 dbg("remove connection retry timer (%d)", timer_src);
531 g_source_remove(timer_src);
535 timer_src = g_timeout_add_seconds(connection_timeout, __ps_service_connetion_timeout_handler, context);
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;
543 void _ps_service_reset_connection_timer(gpointer context)
545 gboolean f_awo = FALSE;
547 f_awo = _ps_context_get_alwayson_enable(context);
548 dbg("Always ON: [%s]", (f_awo ? "YES" : "NO"));
552 connection_timeout = TIMEOUT_DEFAULT;
554 if (timer_src != 0) {
555 dbg("Remove connection Retry timer [%d]", timer_src);
557 g_source_remove(timer_src);
562 void _ps_service_remove_contexts(gpointer object)
566 PsService *service = object;
568 dbg("service remove all contexts");
569 tcore_check_return(service != NULL);
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;
575 dbg("key(%s), value(%p) context", key, value);
576 co_context = _ps_context_ref_co_context(value);
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);
585 __ps_service_emit_context_removed_signal(service, value);
586 _ps_context_remove_context(value);
589 g_hash_table_remove_all(service->contexts);
592 void _ps_service_disconnect_contexts(gpointer object)
596 PsService *service = object;
598 dbg("service disconnect all contexts");
599 tcore_check_return(service != NULL);
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);
608 gint _ps_service_connect_default_context(gpointer object)
610 gint rv = TEL_RETURN_FAILURE;
613 PsService *service = object;
615 dbg("service connect default context");
616 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
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);
624 _ps_service_reset_connection_timer(value);
626 /* Activate Context */
627 rv = _ps_service_activate_context(service, value);
628 dbg("return rv(%d)", rv);
636 gpointer _ps_service_return_default_context(gpointer object)
640 PsService *service = object;
642 tcore_check_return_value(service != NULL, NULL);
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);
657 gboolean _ps_service_processing_network_event(gpointer object,
658 gboolean ps_attached, gboolean roaming)
660 PsService *service = object;
661 tcore_check_return_value(service != NULL, FALSE);
663 _ps_service_set_ps_attached(service, ps_attached);
664 _ps_update_cellular_state_key(service);
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);
677 if (service->ps_attached)
678 _ps_service_connect_default_context(service);
683 gboolean _ps_service_set_connected(gpointer object, gint context_id, gboolean enabled)
688 PsService *service = NULL;
690 service = (PsService *) object;
691 g_hash_table_iter_init(&iter, service->contexts);
692 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
694 CoreObject *context = NULL;
696 context = _ps_context_ref_co_context(value);
697 tcore_context_get_id(context, &tmp_cid);
699 if (tmp_cid != (guint)context_id) continue;
702 dbg("Reset socket connections.");
703 tcore_ps_clear_context_id(service->co_ps, context);
706 _ps_context_set_connected(value, enabled);
712 void _ps_service_set_ps_defined(gpointer *object, gboolean value, int cid)
714 PsService *service = (PsService*)object;
718 tcore_check_return(service != NULL);
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);
727 dbg("define is complete, activate context for cid(%d)", cid);
728 rv = _ps_service_activate_context(service, out);
735 gboolean _ps_service_set_ps_attached(gpointer object, gboolean value)
737 PsService *service = object;
738 tcore_check_return_value(service != NULL, FALSE);
740 service->ps_attached = value;
741 dbg("service(%p) ps_attached(%d)", service, service->ps_attached);
746 gboolean _ps_service_get_restricted(gpointer object)
748 PsService *service = object;
749 tcore_check_return_value(service != NULL, FALSE);
751 return service->restricted;
754 gboolean _ps_service_set_restricted(gpointer object, gboolean value)
756 PsService *service = object;
757 tcore_check_return_value(service != NULL, FALSE);
759 service->restricted = value;
760 dbg("service(%p) restricted(%d)", service, service->restricted);
762 _ps_update_cellular_state_key(service);
767 gboolean _ps_service_set_number_of_pdn_cnt(gpointer object, gchar *operator)
771 PsService *service = object;
772 tcore_check_return_value(service != NULL, FALSE);
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);
777 if (rv != TEL_RETURN_SUCCESS) {
778 dbg("error to get maximum number of pdn");
785 gboolean _ps_service_get_roaming(gpointer object)
787 PsService *service = object;
788 tcore_check_return_value(service != NULL, FALSE);
790 return service->roaming;
793 gboolean _ps_service_set_roaming(gpointer object, gboolean value)
795 PsService *service = object;
796 tcore_check_return_value(service != NULL, FALSE);
798 service->roaming = value;
799 dbg("service(%p) roaming(%d)", service, service->roaming);
800 __ps_service_emit_property_changed_signal(service);
805 static void _indicator_cb_dns_reply(GObject *src, GAsyncResult *res, gpointer user_data)
810 GError *error = NULL;
812 list = g_resolver_lookup_by_name_finish((GResolver *)src, res, &error);
814 dbg("fail to get dns resolving");
816 dbg ("error:%d, %s", error->code, error->message);
817 g_error_free (error);
822 for (cur = list; cur; cur = cur->next) {
824 str_addr = g_inet_address_to_string(addr);
827 dbg("addr(%s)", str_addr);
830 g_object_unref(cur->data);
838 gboolean _ps_service_set_access_technology(gpointer object,
841 PsService *service = object;
842 TelNetworkAct p_act = 0;
843 tcore_check_return_value(service != NULL, FALSE);
845 p_act = service->act;
846 service->act = value;
847 dbg("service(%p) P ACT(%d) Access Technology(%d)", service, p_act, service->act);
849 if (p_act == TEL_NETWORK_ACT_LTE
850 && (service->act >= TEL_NETWORK_ACT_GSM
851 && service->act < TEL_NETWORK_ACT_LTE)) {
854 dbg("send the dns pkt for keeping connection");
856 r = g_resolver_get_default();
857 g_resolver_lookup_by_name_async(r, "www.google.com", NULL, _indicator_cb_dns_reply, NULL);
860 if (service->act > TEL_NETWORK_ACT_UNKNOWN) {
861 _ps_update_cellular_state_key(service);
862 _ps_service_connect_default_context(service);
868 TcorePsState _ps_service_check_cellular_state(gpointer object)
870 gboolean state = FALSE;
871 PsService *service = object;
872 tcore_check_return_value(service != NULL, TCORE_PS_STATE_NO_SERVICE);
874 state = _ps_modem_get_power(service->p_modem);
877 return TCORE_PS_STATE_NO_SERVICE;
880 state = _ps_modem_get_sim_init(service->p_modem);
883 return TCORE_PS_STATE_NO_SERVICE;
886 state = _ps_modem_get_flght_mode(service->p_modem);
888 dbg("FLIGHT MODE ON");
889 return TCORE_PS_STATE_FLIGHT_MODE;
892 if (!service->ps_attached) {
894 return TCORE_PS_STATE_NO_SERVICE;
897 state = _ps_modem_get_data_allowed(service->p_modem);
900 return TCORE_PS_STATE_3G_OFF;
903 state = _ps_modem_get_data_roaming_allowed(service->p_modem);
905 if (service->roaming && !state) {
906 dbg("DATA ROAMING OFF");
907 return TCORE_PS_STATE_ROAMING_OFF;
910 return TCORE_PS_STATE_ON;
912 static gboolean on_service_get_properties (PacketServiceService *obj_service,
913 GDBusMethodInvocation *invocation, gpointer user_data)
916 GVariantBuilder property;
917 dbg("get service properties");
919 gv = _ps_service_get_properties(user_data, &property);
920 packet_service_service_complete_get_properties(obj_service, invocation, gv);
924 static gboolean on_service_get_context (PacketServiceService *obj_service,
925 GDBusMethodInvocation *invocation, gpointer user_data)
927 GVariantBuilder b_context;
932 PsService *service = user_data;
934 dbg("modem get contexts interface");
936 if (service->contexts == NULL) {
937 err("No context present for service");
938 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
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) {
946 g_variant_builder_open(&b_context,G_VARIANT_TYPE("{sa{ss}}"));
947 path = _ps_service_ref_path(value);
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);
956 g_variant_builder_close(&b_context);
960 contexts = g_variant_builder_end(&b_context);
961 packet_service_service_complete_get_contexts(obj_service, invocation,contexts);
965 static void _ps_service_setup_interface(PacketServiceService *service,
966 PsService *service_data)
969 g_signal_connect (service,
970 "handle-get-properties",
971 G_CALLBACK (on_service_get_properties),
974 g_signal_connect (service,
975 "handle-get-contexts",
976 G_CALLBACK (on_service_get_context),