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 /* Add Context to PS Core object */
241 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
243 /* Insert conetxt to Hash Table */
244 g_hash_table_insert(service->contexts, g_strdup(s_path), context);
246 dbg("context(%p) insert to hash", context);
248 /* Emit Context added signal */
249 __ps_service_emit_context_added_signal(service, context);
251 //_ps_service_connect_default_context(service);
255 gboolean _ps_service_ref_contexts(gpointer object, GHashTable *contexts, gchar *operator)
259 PsService *service = object;
263 dbg("service refer to contexts");
264 tcore_check_return_value(service != NULL, FALSE);
266 g_hash_table_iter_init(&iter, contexts);
267 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
268 gchar *s_path = NULL;
270 gboolean f_awo = FALSE;
272 s_path = _ps_context_ref_path(value);
273 dbg("Path: [%s]", s_path);
276 tmp = g_hash_table_lookup(service->contexts, s_path);
278 dbg("context(%p) already existed", tmp);
282 /* Setting service */
283 _ps_context_set_service(value, service);
285 /* Add Context to PS Core object */
286 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(value));
288 /* Insert context to Service Hash Table */
289 g_hash_table_insert(service->contexts, g_strdup(s_path), value);
291 dbg("Inserted context to Hash table - context [%p]", value);
293 /* Emit Context added signal */
294 __ps_service_emit_context_added_signal(service, value);
296 f_awo = _ps_context_get_alwayson_enable(value);
298 rv = _ps_service_define_context(service, value);
299 dbg("return rv(%d)", rv);
303 /* Update cellular state key */
304 _ps_update_cellular_state_key(service);
309 gboolean _ps_service_unref_context(gpointer object, gpointer context)
311 PsService *service = object;
313 dbg("service unref contexts");
314 tcore_check_return_value(service != NULL, FALSE);
315 tcore_check_return_value(context != NULL, FALSE);
317 dbg("remove context(%p) from service(%p)", context, service);
319 /* Remove Context from PS Core object */
320 tcore_ps_remove_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
322 /* Remove context to Hash Table */
323 g_hash_table_remove(service->contexts, _ps_context_ref_path(context));
325 /* Emit Context Remove signal */
326 __ps_service_emit_context_removed_signal(service, context);
331 gboolean _ps_service_get_properties_handler(gpointer object, GVariantBuilder *properties)
333 PsService *service = object;
335 dbg("get service properties");
336 tcore_check_return_value(service != NULL, FALSE);
337 tcore_check_return_value(properties != NULL, FALSE);
339 g_variant_builder_open(properties, G_VARIANT_TYPE("a{ss}"));
340 g_variant_builder_add(properties, "{ss}", "path", g_strdup(service->path));
341 g_variant_builder_add(properties, "{ss}", "ps_attached", g_strdup(BOOL2STRING(service->ps_attached)));
342 g_variant_builder_add(properties, "{ss}", "roaming", g_strdup(BOOL2STRING(service->roaming)));
343 g_variant_builder_add(properties, "{ss}", "act", g_strdup(__ps_service_act2string(service->act)));
344 g_variant_builder_close(properties);
349 GVariant * _ps_service_get_properties(gpointer object, GVariantBuilder *properties)
351 PsService *service = object;
353 dbg("get service properties");
354 tcore_check_return_value(service != NULL, FALSE);
355 tcore_check_return_value(properties != NULL, FALSE);
357 g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
359 g_variant_builder_add(properties, "{ss}", "path", g_strdup(service->path));
360 g_variant_builder_add(properties, "{ss}", "ps_attached", g_strdup(BOOL2STRING(service->ps_attached)));
361 g_variant_builder_add(properties, "{ss}", "roaming", g_strdup(BOOL2STRING(service->roaming)));
362 g_variant_builder_add(properties, "{ss}", "act", g_strdup(__ps_service_act2string(service->act)));
364 return g_variant_builder_end(properties);
367 gchar* _ps_service_ref_path(gpointer object)
369 PsService *service = object;
370 tcore_check_return_value(service != NULL, NULL);
372 return service->path;
375 gpointer _ps_service_ref_plugin(gpointer object)
377 PsService *service = object;
378 tcore_check_return_value(service != NULL, NULL);
383 gpointer _ps_service_ref_co_network(gpointer object)
385 PsService *service = object;
386 tcore_check_return_value(service != NULL, NULL);
388 return service->co_network;
391 gpointer _ps_service_ref_co_ps(gpointer object)
393 PsService *service = object;
394 tcore_check_return_value(service != NULL, NULL);
396 return service->co_ps;
399 gpointer _ps_service_ref_modem(gpointer object)
401 PsService *service = object;
402 tcore_check_return_value(service != NULL, NULL);
404 return service->p_modem;
407 gboolean _ps_service_set_context_info(gpointer object, TcorePsPdpIpConf *devinfo)
409 GSList* contexts = NULL;
410 PsService *service = object;
412 dbg("Set context information");
414 tcore_check_return_value(service != NULL, FALSE);
417 dbg("Context ID: [%d]", devinfo->context_id);
418 tcore_ps_ref_context_by_id(service->co_ps, devinfo->context_id, &contexts);
419 if (NULL == contexts) {
420 err("Failed to refer context");
424 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
425 CoreObject *co_context = NULL;
427 co_context = contexts->data;
428 if (NULL == co_context) {
429 err("Context is NULL");
433 /* Set device information */
434 tcore_context_set_devinfo(co_context, devinfo);
440 gint _ps_service_define_context(gpointer object, gpointer context)
442 PsService *service = object;
443 CoreObject *co_context = NULL;
444 gboolean b_connect = TRUE;
447 dbg("define context(%p)", context);
448 tcore_check_return_value(service != NULL, TEL_RETURN_FAILURE);
450 co_context = (CoreObject *)_ps_context_ref_co_context(context);
452 b_connect = __ps_service_check_connection_option(service, co_context);
454 return TEL_RETURN_FAILURE;
458 ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
459 TCORE_COMMAND_PS_DEFINE_CONTEXT,
460 &co_context, sizeof(CoreObject *),
466 gint _ps_service_activate_context(gpointer object, gpointer context)
468 PsService *service = object;
469 CoreObject *co_context = NULL;
470 gboolean b_connect = TRUE;
472 gint ret = TEL_RETURN_FAILURE;
474 dbg("Activate context [0x%x]", context);
475 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
477 co_context = (CoreObject *)_ps_context_ref_co_context(context);
479 b_connect = __ps_service_check_connection_option(service, co_context);
481 err("Connection option failed");
482 return TEL_RETURN_FAILURE;
485 ps_defined = _ps_context_get_ps_defined(context);
487 dbg("PDP profile is NOT defined!!! Need to define it first... co_context: [%p]");
488 ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
489 TCORE_COMMAND_PS_DEFINE_CONTEXT,
490 &co_context, sizeof(CoreObject *),
493 dbg("PDP profile is defined!!! Activate context...");
494 ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
495 TCORE_COMMAND_PS_ACTIVATE_CONTEXT,
496 &co_context, sizeof(CoreObject *),
503 gint _ps_service_deactivate_context(gpointer object, gpointer context)
505 PsService *service = object;
506 CoreObject *co_context = NULL;
507 TelReturn ret = TEL_RETURN_FAILURE ;
509 dbg("deactivate context(%p)", context);
510 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
512 co_context = (CoreObject *)_ps_context_ref_co_context(context);
513 ret = tcore_plugin_dispatch_request(tcore_object_ref_plugin(service->co_ps), TRUE,
514 TCORE_COMMAND_PS_DEACTIVATE_CONTEXT,
515 &co_context, sizeof(CoreObject *),
521 void _ps_service_set_retry_timeout_value(int value)
523 connection_timeout = value;
524 dbg("current timeout (%d)", connection_timeout);
527 void _ps_service_connection_timer(gpointer object, gpointer context)
529 gboolean f_awo = FALSE;
531 f_awo = _ps_context_get_alwayson_enable(context);
535 if (timer_src != 0) {
536 dbg("remove connection retry timer (%d)", timer_src);
537 g_source_remove(timer_src);
541 timer_src = g_timeout_add_seconds(connection_timeout, __ps_service_connetion_timeout_handler, context);
543 dbg("cellular service timer started timer src(%d), timeout(%d)", timer_src, connection_timeout);
544 connection_timeout = connection_timeout*2;
545 if (connection_timeout >= TIMEOUT_MAX)
546 connection_timeout = TIMEOUT_DEFAULT;
549 void _ps_service_reset_connection_timer(gpointer context)
551 gboolean f_awo = FALSE;
553 f_awo = _ps_context_get_alwayson_enable(context);
554 dbg("Always ON: [%s]", (f_awo ? "YES" : "NO"));
558 connection_timeout = TIMEOUT_DEFAULT;
560 if (timer_src != 0) {
561 dbg("Remove connection Retry timer [%d]", timer_src);
563 g_source_remove(timer_src);
568 void _ps_service_remove_contexts(gpointer object)
572 PsService *service = object;
574 dbg("service remove all contexts");
575 tcore_check_return(service != NULL);
577 g_hash_table_iter_init(&iter, service->contexts);
578 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
579 gpointer co_context = NULL;
581 dbg("key(%s), value(%p) context", key, value);
582 co_context = _ps_context_ref_co_context(value);
584 _ps_service_reset_connection_timer(value);
585 _ps_context_set_alwayson_enable(value, FALSE);
586 _ps_service_deactivate_context(service, value);
587 _ps_context_set_connected(value, FALSE);
588 tcore_ps_remove_context(service->co_ps, co_context);
589 tcore_context_free(co_context);
591 __ps_service_emit_context_removed_signal(service, value);
592 _ps_context_remove_context(value);
595 g_hash_table_remove_all(service->contexts);
598 void _ps_service_disconnect_contexts(gpointer object)
602 PsService *service = object;
604 dbg("service disconnect all contexts");
605 tcore_check_return(service != NULL);
607 g_hash_table_iter_init(&iter, service->contexts);
608 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
609 _ps_service_reset_connection_timer(value);
610 _ps_service_deactivate_context(service, value);
614 gint _ps_service_connect_default_context(gpointer object)
616 gint rv = TEL_RETURN_FAILURE;
619 PsService *service = object;
621 dbg("service connect default context");
622 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
624 g_hash_table_iter_init(&iter, service->contexts);
625 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
626 gboolean f_awo = FALSE;
627 f_awo = _ps_context_get_alwayson_enable(value);
630 _ps_service_reset_connection_timer(value);
632 /* Activate Context */
633 rv = _ps_service_activate_context(service, value);
634 dbg("return rv(%d)", rv);
642 gpointer _ps_service_return_default_context(gpointer object)
646 PsService *service = object;
648 tcore_check_return_value(service != NULL, NULL);
650 g_hash_table_iter_init(&iter, service->contexts);
651 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
652 gboolean b_default = FALSE;
653 b_default = _ps_context_get_default_internet(value);
663 gboolean _ps_service_processing_network_event(gpointer object,
664 gboolean ps_attached, gboolean roaming)
666 PsService *service = object;
667 tcore_check_return_value(service != NULL, FALSE);
669 _ps_service_set_ps_attached(service, ps_attached);
670 _ps_update_cellular_state_key(service);
672 if (service->roaming != roaming) {
673 gboolean roaming_allowed = FALSE;
674 _ps_service_set_roaming(service, roaming);
675 roaming_allowed = _ps_modem_get_data_roaming_allowed(service->p_modem);
676 if (!roaming_allowed && roaming) {
677 dbg("Roaming allowed (%d), Roaming status (%d)", roaming_allowed, roaming);
678 _ps_service_disconnect_contexts(service);
683 if (service->ps_attached)
684 _ps_service_connect_default_context(service);
689 gboolean _ps_service_set_connected(gpointer object, gint context_id, gboolean enabled)
694 PsService *service = NULL;
696 service = (PsService *) object;
697 g_hash_table_iter_init(&iter, service->contexts);
698 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
700 CoreObject *context = NULL;
702 context = _ps_context_ref_co_context(value);
703 tcore_context_get_id(context, &tmp_cid);
705 if (tmp_cid != (guint)context_id) continue;
708 dbg("Reset socket connections.");
709 tcore_ps_clear_context_id(service->co_ps, context);
712 _ps_context_set_connected(value, enabled);
718 void _ps_service_set_ps_defined(gpointer *object, gboolean value, int cid)
720 PsService *service = (PsService*)object;
724 tcore_check_return(service != NULL);
726 g_hash_table_iter_init(&iter, service->contexts);
727 while (g_hash_table_iter_next(&iter, &key, &out) == TRUE) {
728 gboolean r_actvate = 0;
729 r_actvate = _ps_context_set_ps_defined(out, value, cid);
733 dbg("define is complete, activate context for cid(%d)", cid);
734 rv = _ps_service_activate_context(service, out);
741 gboolean _ps_service_set_ps_attached(gpointer object, gboolean value)
743 PsService *service = object;
744 tcore_check_return_value(service != NULL, FALSE);
746 service->ps_attached = value;
747 dbg("service(%p) ps_attached(%d)", service, service->ps_attached);
752 gboolean _ps_service_get_restricted(gpointer object)
754 PsService *service = object;
755 tcore_check_return_value(service != NULL, FALSE);
757 return service->restricted;
760 gboolean _ps_service_set_restricted(gpointer object, gboolean value)
762 PsService *service = object;
763 tcore_check_return_value(service != NULL, FALSE);
765 service->restricted = value;
766 dbg("service(%p) restricted(%d)", service, service->restricted);
768 _ps_update_cellular_state_key(service);
773 gboolean _ps_service_set_number_of_pdn_cnt(gpointer object, gchar *operator)
777 PsService *service = object;
778 tcore_check_return_value(service != NULL, FALSE);
780 num_of_pdn = _ps_context_get_number_of_pdn(operator);
781 rv = tcore_ps_set_num_of_pdn(service->co_ps, num_of_pdn);
783 if (rv != TEL_RETURN_SUCCESS) {
784 dbg("error to get maximum number of pdn");
791 gboolean _ps_service_get_roaming(gpointer object)
793 PsService *service = object;
794 tcore_check_return_value(service != NULL, FALSE);
796 return service->roaming;
799 gboolean _ps_service_set_roaming(gpointer object, gboolean value)
801 PsService *service = object;
802 tcore_check_return_value(service != NULL, FALSE);
804 service->roaming = value;
805 dbg("service(%p) roaming(%d)", service, service->roaming);
806 __ps_service_emit_property_changed_signal(service);
811 static void _indicator_cb_dns_reply(GObject *src, GAsyncResult *res, gpointer user_data)
816 GError *error = NULL;
818 list = g_resolver_lookup_by_name_finish((GResolver *)src, res, &error);
820 dbg("fail to get dns resolving");
822 dbg ("error:%d, %s", error->code, error->message);
823 g_error_free (error);
828 for (cur = list; cur; cur = cur->next) {
830 str_addr = g_inet_address_to_string(addr);
833 dbg("addr(%s)", str_addr);
836 g_object_unref(cur->data);
844 gboolean _ps_service_set_access_technology(gpointer object,
847 PsService *service = object;
848 TelNetworkAct p_act = 0;
849 tcore_check_return_value(service != NULL, FALSE);
851 p_act = service->act;
852 service->act = value;
853 dbg("service(%p) P ACT(%d) Access Technology(%d)", service, p_act, service->act);
855 if (p_act == TEL_NETWORK_ACT_LTE
856 && (service->act >= TEL_NETWORK_ACT_GSM
857 && service->act < TEL_NETWORK_ACT_LTE)) {
860 dbg("send the dns pkt for keeping connection");
862 r = g_resolver_get_default();
863 g_resolver_lookup_by_name_async(r, "www.google.com", NULL, _indicator_cb_dns_reply, NULL);
866 if (service->act > TEL_NETWORK_ACT_UNKNOWN) {
867 _ps_update_cellular_state_key(service);
868 _ps_service_connect_default_context(service);
874 TcorePsState _ps_service_check_cellular_state(gpointer object)
876 gboolean state = FALSE;
877 PsService *service = object;
878 tcore_check_return_value(service != NULL, TCORE_PS_STATE_NO_SERVICE);
880 state = _ps_modem_get_power(service->p_modem);
883 return TCORE_PS_STATE_NO_SERVICE;
886 state = _ps_modem_get_sim_init(service->p_modem);
889 return TCORE_PS_STATE_NO_SERVICE;
892 state = _ps_modem_get_flght_mode(service->p_modem);
894 dbg("FLIGHT MODE ON");
895 return TCORE_PS_STATE_FLIGHT_MODE;
898 if (!service->ps_attached) {
900 return TCORE_PS_STATE_NO_SERVICE;
903 state = _ps_modem_get_data_allowed(service->p_modem);
906 return TCORE_PS_STATE_3G_OFF;
909 state = _ps_modem_get_data_roaming_allowed(service->p_modem);
911 if (service->roaming && !state) {
912 dbg("DATA ROAMING OFF");
913 return TCORE_PS_STATE_ROAMING_OFF;
916 return TCORE_PS_STATE_ON;
918 static gboolean on_service_get_properties (PacketServiceService *obj_service,
919 GDBusMethodInvocation *invocation, gpointer user_data)
922 GVariantBuilder property;
923 dbg("get service properties");
925 gv = _ps_service_get_properties(user_data, &property);
926 packet_service_service_complete_get_properties(obj_service, invocation, gv);
930 static gboolean on_service_get_context (PacketServiceService *obj_service,
931 GDBusMethodInvocation *invocation, gpointer user_data)
933 GVariantBuilder b_context;
938 PsService *service = user_data;
940 dbg("modem get contexts interface");
942 if (service->contexts == NULL) {
943 err("No context present for service");
944 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
948 g_variant_builder_init(&b_context, G_VARIANT_TYPE("a{sa{ss}}"));
949 g_hash_table_iter_init(&iter, service->contexts);
950 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
952 g_variant_builder_open(&b_context,G_VARIANT_TYPE("{sa{ss}}"));
953 path = _ps_service_ref_path(value);
955 g_variant_builder_add(&b_context, "s",g_strdup(path));
956 if (FALSE == _ps_context_get_properties_handler(value, &b_context)) {
957 err("Failed to get property");
958 g_variant_builder_close(&b_context);
959 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
962 g_variant_builder_close(&b_context);
966 contexts = g_variant_builder_end(&b_context);
967 packet_service_service_complete_get_contexts(obj_service, invocation,contexts);
971 static void _ps_service_setup_interface(PacketServiceService *service,
972 PsService *service_data)
975 g_signal_connect (service,
976 "handle-get-properties",
977 G_CALLBACK (on_service_get_properties),
980 g_signal_connect (service,
981 "handle-get-contexts",
982 G_CALLBACK (on_service_get_context),