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;
132 PsService *service = object;
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);
141 b_connect &= !flight;
142 b_connect &= !service->restricted;
144 dbg("power(%d), sim init(%d), data allowed(%d), flight mode(%d) ",
145 power, sim, data, flight);
150 static gboolean __ps_service_connetion_timeout_handler(gpointer context)
153 PsService *service = NULL;
155 service = _ps_context_ref_service(context);
156 rv = _ps_service_activate_context(service, context);
157 dbg("return rv(%d)", rv);
162 gpointer _ps_service_create_service(GDBusConnection *conn, TcorePlugin *p, gpointer p_modem,
163 CoreObject *co_network, CoreObject *co_ps, gchar* path)
165 PacketServiceService *service;
166 GError *error = NULL;
167 PsService *new_service;
169 dbg("service object create");
170 tcore_check_return_value(conn != NULL, NULL);
171 tcore_check_return_value(p_modem != NULL, NULL);
173 /*creating the master object for the interface com.tcore.ps.modem*/
174 service = packet_service_service_skeleton_new();
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");
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);
192 _ps_hook_co_network_event(new_service);
193 _ps_get_co_network_values(new_service);
194 _ps_hook_co_ps_event(new_service);
196 /*Setting up the interface for the service */
197 _ps_service_setup_interface(service, new_service);
199 /*exporting the interface object to the path mention for master*/
200 g_dbus_interface_skeleton_export((G_DBUS_INTERFACE_SKELETON(service)),
205 g_assert_no_error (error);
207 connection_timeout = TIMEOUT_DEFAULT;
208 dbg("Successfully Created the service");
212 /*To Do: Handle failure case*/
216 gboolean _ps_service_ref_context(gpointer object, gpointer context)
219 gchar *s_path = NULL;
220 PsService *service = object;
222 dbg("service refer to context");
223 tcore_check_return_value(service != NULL, FALSE);
225 s_path = _ps_context_ref_path(context);
226 tmp = g_hash_table_lookup(service->contexts, s_path);
228 dbg("context(%p) already existed", tmp);
232 /* Setting service */
233 _ps_context_set_service(context, service);
235 /* Add Context to PS Core object */
236 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
238 /* Insert conetxt to Hash Table */
239 g_hash_table_insert(service->contexts, g_strdup(s_path), context);
241 dbg("context(%p) insert to hash", context);
243 /* Emit Context added signal */
244 __ps_service_emit_context_added_signal(service, context);
246 //_ps_service_connect_default_context(service);
250 gboolean _ps_service_ref_contexts(gpointer object, GHashTable *contexts, gchar *operator)
254 PsService *service = object;
258 dbg("service refer to contexts");
259 tcore_check_return_value(service != NULL, FALSE);
261 g_hash_table_iter_init(&iter, contexts);
262 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
263 gchar *s_path = NULL;
265 gboolean f_awo = FALSE;
267 s_path = _ps_context_ref_path(value);
268 dbg("Path: [%s]", s_path);
271 tmp = g_hash_table_lookup(service->contexts, s_path);
273 dbg("context(%p) already existed", tmp);
277 /* Setting service */
278 _ps_context_set_service(value, service);
280 /* Add Context to PS Core object */
281 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(value));
283 /* Insert context to Service Hash Table */
284 g_hash_table_insert(service->contexts, g_strdup(s_path), value);
286 dbg("Inserted context to Hash table - context [%p]", value);
288 /* Emit Context added signal */
289 __ps_service_emit_context_added_signal(service, value);
291 f_awo = _ps_context_get_alwayson_enable(value);
293 rv = _ps_service_define_context(service, value);
294 dbg("return rv(%d)", rv);
298 /* Update cellular state key */
299 _ps_update_cellular_state_key(service);
304 gboolean _ps_service_unref_context(gpointer object, gpointer context)
306 PsService *service = object;
308 dbg("service unref contexts");
309 tcore_check_return_value(service != NULL, FALSE);
310 tcore_check_return_value(context != NULL, FALSE);
312 dbg("remove context(%p) from service(%p)", context, service);
314 /* Remove Context from PS Core object */
315 tcore_ps_remove_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
317 /* Remove context to Hash Table */
318 g_hash_table_remove(service->contexts, _ps_context_ref_path(context));
320 /* Emit Context Remove signal */
321 __ps_service_emit_context_removed_signal(service, context);
326 gboolean _ps_service_get_properties_handler(gpointer object, GVariantBuilder *properties)
328 PsService *service = object;
330 dbg("get service properties");
331 tcore_check_return_value(service != NULL, FALSE);
332 tcore_check_return_value(properties != NULL, FALSE);
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);
344 GVariant * _ps_service_get_properties(gpointer object, GVariantBuilder *properties)
346 PsService *service = object;
348 dbg("get service properties");
349 tcore_check_return_value(service != NULL, FALSE);
350 tcore_check_return_value(properties != NULL, FALSE);
352 g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
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)));
359 return g_variant_builder_end(properties);
362 gchar* _ps_service_ref_path(gpointer object)
364 PsService *service = object;
365 tcore_check_return_value(service != NULL, NULL);
367 return service->path;
370 gpointer _ps_service_ref_plugin(gpointer object)
372 PsService *service = object;
373 tcore_check_return_value(service != NULL, NULL);
378 gpointer _ps_service_ref_co_network(gpointer object)
380 PsService *service = object;
381 tcore_check_return_value(service != NULL, NULL);
383 return service->co_network;
386 gpointer _ps_service_ref_co_ps(gpointer object)
388 PsService *service = object;
389 tcore_check_return_value(service != NULL, NULL);
391 return service->co_ps;
394 gpointer _ps_service_ref_modem(gpointer object)
396 PsService *service = object;
397 tcore_check_return_value(service != NULL, NULL);
399 return service->p_modem;
402 gboolean _ps_service_set_context_info(gpointer object, TcorePsPdpIpConf *devinfo)
404 GSList* contexts = NULL;
405 PsService *service = object;
407 dbg("Set context information");
409 tcore_check_return_value(service != NULL, FALSE);
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");
419 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
420 CoreObject *co_context = NULL;
422 co_context = contexts->data;
423 if (NULL == co_context) {
424 err("Context is NULL");
428 /* Set device information */
429 tcore_context_set_devinfo(co_context, devinfo);
435 gint _ps_service_define_context(gpointer object, gpointer context)
437 PsService *service = object;
438 CoreObject *co_context = NULL;
439 gboolean b_connect = TRUE;
442 dbg("define context(%p)", context);
443 tcore_check_return_value(service != NULL, TEL_RETURN_FAILURE);
445 co_context = (CoreObject *)_ps_context_ref_co_context(context);
447 b_connect = __ps_service_check_connection_option(service, co_context);
449 return TEL_RETURN_FAILURE;
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 *),
461 gint _ps_service_activate_context(gpointer object, gpointer context)
463 PsService *service = object;
464 CoreObject *co_context = NULL;
465 gboolean b_connect = TRUE;
467 gint ret = TEL_RETURN_FAILURE;
469 dbg("Activate context [0x%x]", context);
470 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
472 co_context = (CoreObject *)_ps_context_ref_co_context(context);
474 b_connect = __ps_service_check_connection_option(service, co_context);
476 err("Connection option failed");
477 return TEL_RETURN_FAILURE;
480 ps_defined = _ps_context_get_ps_defined(context);
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 *),
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 *),
498 gint _ps_service_deactivate_context(gpointer object, gpointer context)
500 PsService *service = object;
501 CoreObject *co_context = NULL;
502 TelReturn ret = TEL_RETURN_FAILURE ;
504 dbg("deactivate context(%p)", context);
505 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
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 *),
516 void _ps_service_set_retry_timeout_value(int value)
518 connection_timeout = value;
519 dbg("current timeout (%d)", connection_timeout);
522 void _ps_service_connection_timer(gpointer object, gpointer context)
524 gboolean f_awo = FALSE;
526 f_awo = _ps_context_get_alwayson_enable(context);
530 if (timer_src != 0) {
531 dbg("remove connection retry timer (%d)", timer_src);
532 g_source_remove(timer_src);
536 timer_src = g_timeout_add_seconds(connection_timeout, __ps_service_connetion_timeout_handler, context);
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;
544 void _ps_service_reset_connection_timer(gpointer context)
546 gboolean f_awo = FALSE;
548 f_awo = _ps_context_get_alwayson_enable(context);
549 dbg("Always ON: [%s]", (f_awo ? "YES" : "NO"));
553 connection_timeout = TIMEOUT_DEFAULT;
555 if (timer_src != 0) {
556 dbg("Remove connection Retry timer [%d]", timer_src);
558 g_source_remove(timer_src);
563 void _ps_service_remove_contexts(gpointer object)
567 PsService *service = object;
569 dbg("service remove all contexts");
570 tcore_check_return(service != NULL);
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;
576 dbg("key(%s), value(%p) context", key, value);
577 co_context = _ps_context_ref_co_context(value);
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);
586 __ps_service_emit_context_removed_signal(service, value);
587 _ps_context_remove_context(value);
590 g_hash_table_remove_all(service->contexts);
593 void _ps_service_disconnect_contexts(gpointer object)
597 PsService *service = object;
599 dbg("service disconnect all contexts");
600 tcore_check_return(service != NULL);
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);
609 gint _ps_service_connect_default_context(gpointer object)
611 gint rv = TEL_RETURN_FAILURE;
614 PsService *service = object;
616 dbg("service connect default context");
617 tcore_check_return_value(service != NULL, TEL_RETURN_INVALID_PARAMETER);
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);
625 _ps_service_reset_connection_timer(value);
627 /* Activate Context */
628 rv = _ps_service_activate_context(service, value);
629 dbg("return rv(%d)", rv);
637 gpointer _ps_service_return_default_context(gpointer object)
641 PsService *service = object;
643 tcore_check_return_value(service != NULL, NULL);
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);
658 gboolean _ps_service_processing_network_event(gpointer object, 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);
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);
676 if (service->ps_attached)
677 _ps_service_connect_default_context(service);
682 gboolean _ps_service_set_connected(gpointer object, gint context_id, gboolean enabled)
687 PsService *service = NULL;
689 service = (PsService *) object;
690 g_hash_table_iter_init(&iter, service->contexts);
691 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
693 CoreObject *context = NULL;
695 context = _ps_context_ref_co_context(value);
696 tcore_context_get_id(context, &tmp_cid);
698 if (tmp_cid != (guint)context_id) continue;
701 dbg("Reset socket connections.");
702 tcore_ps_clear_context_id(service->co_ps, context);
705 _ps_context_set_connected(value, enabled);
711 void _ps_service_set_ps_defined(gpointer *object, gboolean value, int cid)
713 PsService *service = (PsService*)object;
717 tcore_check_return(service != NULL);
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);
726 dbg("define is complete, activate context for cid(%d)", cid);
727 rv = _ps_service_activate_context(service, out);
734 gboolean _ps_service_set_ps_attached(gpointer object, gboolean value)
736 PsService *service = object;
737 tcore_check_return_value(service != NULL, FALSE);
739 service->ps_attached = value;
740 dbg("service(%p) ps_attached(%d)", service, service->ps_attached);
745 gboolean _ps_service_get_restricted(gpointer object)
747 PsService *service = object;
748 tcore_check_return_value(service != NULL, FALSE);
750 return service->restricted;
753 gboolean _ps_service_set_restricted(gpointer object, gboolean value)
755 PsService *service = object;
756 tcore_check_return_value(service != NULL, FALSE);
758 service->restricted = value;
759 dbg("service(%p) restricted(%d)", service, service->restricted);
761 _ps_update_cellular_state_key(service);
766 gboolean _ps_service_set_number_of_pdn_cnt(gpointer object, gchar *operator)
770 PsService *service = object;
771 tcore_check_return_value(service != NULL, FALSE);
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);
776 if (rv != TEL_RETURN_SUCCESS) {
777 dbg("error to get maximum number of pdn");
784 gboolean _ps_service_get_roaming(gpointer object)
786 PsService *service = object;
787 tcore_check_return_value(service != NULL, FALSE);
789 return service->roaming;
792 gboolean _ps_service_set_roaming(gpointer object, gboolean value)
794 PsService *service = object;
795 tcore_check_return_value(service != NULL, FALSE);
797 service->roaming = value;
798 dbg("service(%p) roaming(%d)", service, service->roaming);
799 __ps_service_emit_property_changed_signal(service);
804 static void _indicator_cb_dns_reply(GObject *src, GAsyncResult *res, gpointer user_data)
809 GError *error = NULL;
811 list = g_resolver_lookup_by_name_finish((GResolver *)src, res, &error);
813 dbg("fail to get dns resolving");
815 dbg ("error:%d, %s", error->code, error->message);
816 g_error_free (error);
821 for (cur = list; cur; cur = cur->next) {
823 str_addr = g_inet_address_to_string(addr);
826 dbg("addr(%s)", str_addr);
829 g_object_unref(cur->data);
837 gboolean _ps_service_set_access_technology(gpointer object,
840 PsService *service = object;
841 TelNetworkAct p_act = 0;
842 tcore_check_return_value(service != NULL, FALSE);
844 p_act = service->act;
845 service->act = value;
846 dbg("service(%p) P ACT(%d) Access Technology(%d)", service, p_act, service->act);
848 if (p_act == TEL_NETWORK_ACT_LTE
849 && (service->act >= TEL_NETWORK_ACT_GSM
850 && service->act < TEL_NETWORK_ACT_LTE)) {
853 dbg("send the dns pkt for keeping connection");
855 r = g_resolver_get_default();
856 g_resolver_lookup_by_name_async(r, "www.google.com", NULL, _indicator_cb_dns_reply, NULL);
859 if (service->act > TEL_NETWORK_ACT_UNKNOWN) {
860 _ps_update_cellular_state_key(service);
861 _ps_service_connect_default_context(service);
867 TcorePsState _ps_service_check_cellular_state(gpointer object)
869 gboolean state = FALSE;
870 PsService *service = object;
871 tcore_check_return_value(service != NULL, TCORE_PS_STATE_NO_SERVICE);
873 state = _ps_modem_get_power(service->p_modem);
876 return TCORE_PS_STATE_NO_SERVICE;
879 state = _ps_modem_get_sim_init(service->p_modem);
882 return TCORE_PS_STATE_NO_SERVICE;
885 state = _ps_modem_get_flght_mode(service->p_modem);
887 dbg("FLIGHT MODE ON");
888 return TCORE_PS_STATE_FLIGHT_MODE;
891 if (!service->ps_attached) {
893 return TCORE_PS_STATE_NO_SERVICE;
896 state = _ps_modem_get_data_allowed(service->p_modem);
899 return TCORE_PS_STATE_3G_OFF;
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;
908 return TCORE_PS_STATE_ON;
910 static gboolean on_service_get_properties (PacketServiceService *obj_service,
911 GDBusMethodInvocation *invocation, gpointer user_data)
914 GVariantBuilder property;
915 dbg("get service properties");
917 gv = _ps_service_get_properties(user_data, &property);
918 packet_service_service_complete_get_properties(obj_service, invocation, gv);
922 static gboolean on_service_get_context (PacketServiceService *obj_service,
923 GDBusMethodInvocation *invocation, gpointer user_data)
925 GVariantBuilder b_context;
930 PsService *service = user_data;
932 dbg("modem get contexts interface");
934 if (service->contexts == NULL) {
935 err("No context present for service");
936 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
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) {
944 g_variant_builder_open(&b_context,G_VARIANT_TYPE("{sa{ss}}"));
945 path = _ps_service_ref_path(value);
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);
954 g_variant_builder_close(&b_context);
958 contexts = g_variant_builder_end(&b_context);
959 packet_service_service_complete_get_contexts(obj_service, invocation,contexts);
963 static void _ps_service_setup_interface(PacketServiceService *service,
964 PsService *service_data)
967 g_signal_connect (service,
968 "handle-get-properties",
969 G_CALLBACK (on_service_get_properties),
972 g_signal_connect (service,
973 "handle-get-contexts",
974 G_CALLBACK (on_service_get_context),