2 * tel-plugin-packetservice
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: DongHoo Park <donghoo.park@samsung.com>
7 * Arun Shukla <arun.shukla@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 #include "ps_common.h"
24 #include "generated-code.h"
28 #include <user_request.h>
29 #include <core_object.h>
30 #include <co_context.h>
33 #define PROP_DEFAULT FALSE
34 #define PROP_DEFAULT_STR NULL
36 struct ps_thread_data {
41 static void __ps_modem_emit_property_changed_signal(ps_modem_t *modem);
42 static void __ps_modem_emit_service_added_signal(ps_modem_t *modem, gpointer service);
43 /*static void __ps_modem_emit_service_removed_signal(ps_modem_t *modem, gpointer service);*/
44 static void _ps_modem_setup_interface(PacketServiceModem *modem, ps_modem_t *modem_data);
46 static void __ps_modem_create_service(GDBusConnection *conn, TcorePlugin *p,
47 gpointer modem, CoreObject *co_modem);
48 static void __ps_modem_remove_service(ps_modem_t *modem, gpointer service);
49 static void __ps_modem_get_ps_setting_from_storage(ps_modem_t *object);
50 static void __ps_modem_processing_modem_event(gpointer object);
52 static gboolean __ps_modem_set_powered(ps_modem_t *modem, int value);
53 static gboolean __ps_modem_set_sim_complete(ps_modem_t *modem, gboolean value, gchar *operator);
55 static gboolean __ps_modem_thread_finish_cb(gpointer data)
57 struct ps_thread_data *thread_data = data;
63 err("thread_data is NULL !!");
67 modem = thread_data->modem;
69 dbg("Thread %p return is complete", thread_data->selfi);
71 _ps_get_co_modem_values(thread_data->modem);
72 _ps_modem_set_reset_profile(thread_data->modem, FALSE);
73 packet_service_modem_complete_reset_profile(thread_data->modem->if_obj, thread_data->modem->invocation, TRUE);
75 g_thread_join(thread_data->selfi);
76 dbg("Clean up of thread %p is complete", thread_data->selfi);
77 thread_data->modem->invocation = NULL;
78 _ps_modem_remove_profile_reset_gsource(thread_data->modem);
79 thread_data->modem = NULL;
80 thread_data->selfi = NULL;
83 /* Try to re-connect default contexts after reset profile is complete */
84 g_hash_table_iter_init(&iter, modem->services);
85 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE)
86 _ps_service_connect_default_context(value);
91 static gpointer __ps_modem_regenerate_database(gpointer data)
94 ps_modem_t *modem = data;
95 struct ps_thread_data *thread_data = NULL;
97 thread_data = g_try_malloc0(sizeof(*thread_data));
99 err("mamory alloc is fail !!!");
102 thread_data->modem = modem;
103 thread_data->selfi = g_thread_self();
105 _ps_context_reset_profile_table(modem->cp_name);
106 /* Re-generate global APN database */
107 if (g_str_has_suffix(modem->cp_name, "1"))
108 rv = ps_util_system_command("/usr/bin/sqlite3 /opt/dbspace/.dnet2.db < /usr/share/ps-plugin/dnet_db_init.sql");
110 rv = ps_util_system_command("/usr/bin/sqlite3 /opt/dbspace/.dnet.db < /usr/share/ps-plugin/dnet_db_init.sql");
111 ps_dbg_ex_co(modem->co_modem, "system command sent, rv(%d)", rv);
112 rv = _ps_context_fill_profile_table_from_ini_file(modem->cp_name);
114 if (TRUE == ps_util_thread_dispatch(g_main_context_default(), G_PRIORITY_LOW, (GSourceFunc)__ps_modem_thread_finish_cb, thread_data))
115 dbg("Thread %p processing is complete", thread_data->selfi);
120 void __remove_modem_handler(gpointer data)
122 ps_modem_t *modem = data;
124 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "Entered");
126 dbg("Modem is NULL");
130 __ps_modem_cp_reset_send_pending_request_response(modem);
132 /*Need to remove the compelete hash table*/
133 g_hash_table_remove_all(modem->services);
135 /*Need to UNexport and Unref the master Object */
136 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(modem->if_obj));
138 g_object_unref(modem->if_obj);
140 /*Need to free memory allocated for the internal structure*/
141 g_queue_free(modem->work_queue);
143 g_free(modem->operator);
144 g_free(modem->cp_name);
146 _ps_modem_remove_profile_reset_gsource(modem);
154 static void __ps_modem_emit_property_changed_signal(ps_modem_t *modem)
157 GVariantBuilder properties;
159 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "get modem properties");
161 gv = _ps_modem_get_properties(modem, &properties);
162 packet_service_modem_emit_property_changed(modem->if_obj, gv);
167 static void __ps_modem_emit_service_added_signal(ps_modem_t *modem, gpointer service)
170 GVariantBuilder property;
172 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "get service properties");
174 gv = _ps_service_get_properties(service, &property);
175 packet_service_modem_emit_service_added(modem->if_obj, gv);
178 /* blocked may be used later
179 static void __ps_modem_emit_service_removed_signal(ps_modem_t *modem, gpointer service)
181 ps_service_t *psservice = service;
182 packet_service_modem_emit_service_removed(modem->if_obj, psservice->path);
187 static void __ps_modem_create_service(GDBusConnection *conn, TcorePlugin *p,
188 gpointer modem, CoreObject *co_modem)
190 gchar *t_path = NULL;
191 GObject *object = NULL;
193 CoreObject *co_ps = NULL;
194 CoreObject *co_network = NULL;
195 TcorePlugin *target_plg = NULL;
197 target_plg = tcore_object_ref_plugin(co_modem);
198 co_ps = tcore_plugin_ref_core_object(target_plg, CORE_OBJECT_TYPE_PS);
199 co_network = tcore_plugin_ref_core_object(target_plg, CORE_OBJECT_TYPE_NETWORK);
200 if (!co_ps || !co_network)
203 t_path = g_strdup_printf("%s/%s", _ps_modem_ref_path(modem), "umts_ps");
204 if (NULL != g_hash_table_lookup(((ps_modem_t *) modem)->services, t_path)) {
205 ps_dbg_ex_co(co_modem, "service (%s) already exist!!!", t_path);
209 ps_dbg_ex_co(co_modem, "service path (%s)", t_path);
210 object = _ps_service_create_service(conn, p, modem, co_network, co_ps, t_path);
211 if (object == NULL) {
212 ps_err_ex_co(co_modem, "Failed to create service ");
217 g_hash_table_insert(((ps_modem_t *) modem)->services, g_strdup(t_path), object);
218 ps_dbg_ex_co(co_modem, "service (%p) insert to hash", object);
219 __ps_modem_emit_service_added_signal((ps_modem_t *) modem, object);
225 static void __ps_modem_remove_service(ps_modem_t *modem, gpointer service)
227 ps_service_t *psservice = service;
229 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "Entered");
231 /*Unexporting the interface for the modem*/
232 if (psservice->if_obj) {
233 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(psservice->if_obj));
234 g_object_unref(psservice->if_obj);
235 psservice->if_obj = NULL;
238 g_hash_table_remove(modem->services, _ps_service_ref_path(service));
240 dbg("Successfully removed the service from the modem");
244 static gboolean __ps_modem_set_powered(ps_modem_t *modem, gboolean value)
246 g_return_val_if_fail(modem != NULL, FALSE);
248 modem->powered = value;
249 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) powered(%d)", modem, modem->powered);
250 __ps_modem_emit_property_changed_signal(modem);
254 static gboolean __ps_modem_set_sim_complete(ps_modem_t *modem, gboolean value, gchar *operator)
256 g_return_val_if_fail(modem != NULL, FALSE);
258 /* Update SIM init status */
259 modem->sim_init = value;
260 if (value && operator != NULL && !modem->operator)
261 modem->operator = g_strdup(operator);
262 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem [%p] SIM-Init [%s]", modem, (modem->sim_init ? "INITIALIZED" : "UNINITIALIZED"));
264 __ps_modem_emit_property_changed_signal(modem);
269 static gboolean __ps_modem_set_flght_mode(ps_modem_t *modem, gboolean value)
271 g_return_val_if_fail(modem != NULL, FALSE);
273 modem->flight_mode = value;
274 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) flight_mode(%d)", modem, modem->flight_mode);
275 __ps_modem_emit_property_changed_signal(modem);
276 __ps_modem_processing_modem_event(modem);
281 static void __ps_modem_get_ps_setting_from_storage(ps_modem_t *object)
283 gboolean key_3g_enable = FALSE, key_roaming_allowed = FALSE;
284 gboolean key_nw_restrict_mode = FALSE;
285 gint key_ps_mode = 0;
286 ps_modem_t *modem = NULL;
287 CoreObject *co_modem;
288 #if defined(TIZEN_UPS_ENABLED)
289 struct treq_modem_set_flightmode data = {0};
292 modem = (ps_modem_t *) object;
293 co_modem = _ps_modem_ref_co_modem(modem);
294 key_3g_enable = _ps_master_get_storage_value_bool(modem->p_master, KEY_3G_ENABLE);
295 key_roaming_allowed = _ps_master_get_storage_value_bool(modem->p_master, KEY_DATA_ROAMING_SETTING);
296 key_ps_mode = _ps_master_get_storage_value_int(modem->p_master, KEY_POWER_SAVING_MODE);
297 key_nw_restrict_mode = _ps_master_get_storage_value_bool(modem->p_master, KEY_NETWORK_RESTRICT_MODE);
299 _ps_modem_set_data_allowed(modem, key_3g_enable);
300 _ps_modem_set_data_roaming_allowed(modem, key_roaming_allowed);
302 #if defined(TIZEN_UPS_ENABLED)
303 _ps_modem_set_psmode(modem, key_ps_mode);
304 if (key_ps_mode == POWER_SAVING_MODE_NORMAL) {
305 dbg("set flight mode off");
307 } else if (key_ps_mode == POWER_SAVING_MODE_WEARABLE) {
308 dbg("set flight mode on");
311 err("Not supported");
314 _ps_modem_send_filght_mode_request(modem, &data);
317 ps_dbg_ex_co(co_modem, "data allowed(%d) roaming allowed(%d) power saving mode(%d), network restrict mode (%d)",
318 key_3g_enable, key_roaming_allowed, key_ps_mode, key_nw_restrict_mode);
322 static void __ps_modem_processing_modem_event(gpointer object)
324 ps_modem_t *modem = object;
327 #ifdef PREPAID_SIM_APN_SUPPORT
331 g_return_if_fail(modem != NULL);
333 if (!modem->services)
336 g_hash_table_iter_init(&iter, modem->services);
337 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
338 gboolean s_roaming = FALSE;
340 s_roaming = _ps_service_get_roaming(value);
341 _ps_update_cellular_state_key(value);
343 if (modem->powered == PS_MODEM_STATE_OFFLINE) {
344 _ps_service_remove_contexts(value);
345 _ps_free_co_ps_event(value);
346 _ps_free_co_network_event(value);
347 __ps_modem_remove_service(modem, value);
351 if (modem->flight_mode || (s_roaming && !modem->roaming_allowed)) {
352 _ps_service_disconnect_contexts(value);
354 } else if (!modem->data_allowed) {
355 _ps_service_disconnect_internet_mms_contexts(value);
359 /* only available case */
360 #ifdef PREPAID_SIM_APN_SUPPORT
361 ret = _ps_service_connect_last_connected_context(value);
364 return; /* No need to activate default context */
366 _ps_service_connect_default_context(value);
372 gpointer _ps_modem_create_modem(GDBusConnection *conn, TcorePlugin *p, gpointer master,
373 char *modem_name, gpointer co_modem , gchar *cp_name)
375 PacketServiceModem *modem;
376 ps_modem_t *new_modem;
377 GError *error = NULL;
379 ps_dbg_ex_co(co_modem, "modem object create");
380 g_return_val_if_fail(conn != NULL, NULL);
381 g_return_val_if_fail(master != NULL, NULL);
383 /*creating the master object for the interface com.tcore.ps.modem*/
384 modem = packet_service_modem_skeleton_new();
386 /*Initializing the modem list for internal referencing*/
387 new_modem = g_try_malloc0(sizeof(ps_modem_t));
388 if (NULL == new_modem) {
389 ps_err_ex_co(co_modem, "Unable to allocate memory for modem");
393 /*Add work queue to keep user request in case of handling active PDP context*/
394 new_modem->hook_flag = 0x00;
395 new_modem->work_queue = g_queue_new();
396 if (NULL == new_modem->work_queue) {
397 ps_err_ex_co(co_modem, "Unable to get work queue for modem");
402 new_modem->conn = conn;
403 new_modem->p_master = master;
405 new_modem->co_modem = co_modem;
406 new_modem->path = g_strdup(modem_name);
407 new_modem->cp_name = g_strdup(cp_name);
408 new_modem->if_obj = modem;
409 new_modem->services = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_service_handler);
411 __ps_modem_get_ps_setting_from_storage(new_modem);
412 _ps_hook_co_modem_event(new_modem);
413 _ps_get_co_modem_values(new_modem);
415 /*Setting the interface call backs functions*/
416 _ps_modem_setup_interface(modem, new_modem);
418 /*exporting the interface object to the path mention for modem*/
419 g_dbus_interface_skeleton_export((G_DBUS_INTERFACE_SKELETON(modem)),
424 g_assert_no_error(error);
426 /* Adding hooks for special Network Requests */
427 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
429 ps_handle_hook, new_modem);
430 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
431 TREQ_NETWORK_SET_PLMN_SELECTION_MODE,
432 ps_handle_hook, new_modem);
433 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
434 TREQ_NETWORK_SET_MODE,
435 ps_handle_hook, new_modem);
436 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
437 TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH,
438 ps_handle_hook, new_modem);
439 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
440 TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION,
441 ps_handle_hook, new_modem);
442 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
443 TREQ_SIM_SET_POWERSTATE,
444 ps_handle_hook, new_modem);
445 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
446 TREQ_MODEM_SET_FLIGHTMODE,
447 ps_handle_hook, new_modem);
448 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
449 TREQ_MODEM_POWER_OFF,
450 ps_handle_hook, new_modem);
451 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
452 TREQ_MODEM_POWER_LOW,
453 ps_handle_hook, new_modem);
454 tcore_server_add_request_hook(tcore_plugin_ref_server(p),
456 ps_handle_hook, new_modem);
458 ps_err_ex_co(co_modem, "Successfully created the modem");
462 void _ps_modem_destroy_modem(GDBusConnection *conn, gpointer object)
464 ps_modem_t *modem = object;
468 GSList *list_iter = NULL;
470 g_return_if_fail(modem != NULL);
472 if (modem->services == NULL)
475 dbg("Clearing all services");
476 g_hash_table_iter_init(&iter, modem->services);
477 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
478 /* Update Cellular state */
479 _ps_service_set_ps_attached(value, FALSE);
480 _ps_update_cellular_state_key(value);
482 /* Remove contexts */
483 _ps_service_remove_contexts(value);
486 _ps_free_co_ps_event(value);
487 _ps_free_co_network_event(value);
489 /* To avoid hashtable assertion */
490 list = g_slist_append(list, value);
493 for (list_iter = list; list_iter; list_iter = g_slist_next(list_iter)) {
494 /* Remove services */
495 __ps_modem_remove_service(modem, list_iter->data);
498 g_slist_free(modem->contexts);
500 /* Clear modem hooks */
501 _ps_free_co_modem_event(modem);
504 gboolean _ps_modem_send_filght_mode_request(gpointer value, void *data)
506 CoreObject *co_modem = NULL, *co_ps = NULL;
507 UserRequest *ur = NULL;
508 ps_modem_t *modem = value;
511 co_modem = _ps_modem_ref_co_modem(modem);
512 co_ps = tcore_plugin_ref_core_object(tcore_object_ref_plugin(co_modem), CORE_OBJECT_TYPE_PS);
513 /* deactivate contexts first. */
514 rv = tcore_ps_deactivate_contexts(co_ps);
515 if (rv != TCORE_RETURN_SUCCESS)
516 ps_dbg_ex_co(co_ps, "fail to deactivation");
518 tcore_ps_set_online(co_ps, FALSE);
520 ur = tcore_user_request_new(NULL, NULL);
521 tcore_user_request_set_data(ur, sizeof(struct treq_modem_set_flightmode), data);
522 tcore_user_request_set_command(ur, TREQ_MODEM_SET_FLIGHTMODE);
523 if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_modem, ur)) {
524 err("fail to send user request");
525 tcore_user_request_unref(ur);
531 gboolean _ps_modem_processing_flight_mode(gpointer object, gboolean enable)
533 ps_modem_t *modem = object;
535 g_return_val_if_fail(modem != NULL, FALSE);
537 if (modem->flight_mode == enable)
540 __ps_modem_set_flght_mode(modem, enable);
544 gboolean _ps_modem_processing_power_enable(gpointer object, int modem_state)
546 ps_modem_t *modem = object;
548 g_return_val_if_fail(modem != NULL, FALSE);
550 dbg("modem->powered [%d], Modem->sim_init [%d], modem_state [%d]",
551 modem->powered, modem->sim_init, modem_state);
553 if (modem->powered == modem_state)
556 __ps_modem_set_powered(modem, modem_state);
558 if (modem_state == PS_MODEM_STATE_ONLINE) {
559 __ps_modem_create_service(modem->conn, modem->plg, modem, modem->co_modem);
560 if (modem->sim_init == TRUE && modem->operator != NULL) {
561 GSList *contexts = (GSList*)_ps_modem_ref_contexts(modem);
563 if (contexts != NULL) {
566 warn("[WARN] contexts exist, SIM init complete before Modem Power On event.");
567 g_hash_table_iter_init(&iter, modem->services);
568 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
569 _ps_service_set_number_of_pdn_cnt(value, modem->operator);
570 _ps_service_ref_contexts(value, contexts, modem->operator);
571 _ps_service_set_attach_apn(value);
575 } else if (modem_state == PS_MODEM_STATE_OFFLINE) {
576 __ps_modem_processing_modem_event(modem);
577 /* SIM init should be set to FALSE during CP silent reset.
578 * and will be updated when SIM initialized complete notification is received.
584 gboolean _ps_modem_processing_sim_complete(gpointer object, gboolean complete, gchar *operator)
586 ps_modem_t *modem = object;
587 CoreObject *co_modem;
588 g_return_val_if_fail(modem != NULL, FALSE);
590 co_modem = _ps_modem_ref_co_modem(modem);
591 ps_dbg_ex_co(co_modem, "Entered: sim_init[%d]", modem->sim_init);
593 if (modem->sim_init == complete && !modem->reset_profile) {
594 ps_dbg_ex_co(co_modem, "No change in SIM state");
597 gboolean different_sim = FALSE;
599 if (operator && (g_strcmp0(modem->operator, operator) != 0)) {
600 ps_dbg_ex_co(co_modem, "Previous operator: [%s] Present operator: [%s]", modem->operator, operator);
601 g_free(modem->operator);
603 modem->operator = g_strdup(operator);
604 different_sim = TRUE;
608 /* free modem operator */
609 if (FALSE == complete) {
610 g_free(modem->operator);
611 modem->operator = NULL;
614 /* Update SIM state */
615 __ps_modem_set_sim_complete(modem, complete, operator);
616 /* Tizen Telephony makes dummy profile for CDMA by default */
617 _ps_context_create_cdma_profile(modem->operator, modem->cp_name);
619 /* Modem power off notification coming due to which profile are removed */
620 /* and needed to be re inserted in db with sim off notification */
622 * Context table creation
624 * Create context if -
626 * Initialzed SIM is different (if same SIM is re-initialized then need not create context)
627 * Delete context if sim_init = FALSE;
628 * This will be coming when SIM power off or CARD error is received.
630 if (modem->sim_init == TRUE) {
631 if ((different_sim || modem->reset_profile) && (modem->operator != NULL)) {
634 ps_dbg_ex_co(co_modem, "Creating Hash table...");
635 contexts = _ps_context_create_hashtable(object, modem->roaming);
636 if (contexts != NULL) {
640 g_hash_table_iter_init(&iter, modem->services);
641 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
642 _ps_service_set_number_of_pdn_cnt(value, modem->operator);
643 _ps_service_ref_contexts(value, contexts, modem->operator);
644 _ps_service_set_attach_apn(value);
647 ps_dbg_ex_co(co_modem, "Failed to create HASH table");
655 if (!modem->services)
658 g_hash_table_iter_init(&iter, modem->services);
659 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
660 ps_dbg_ex_co(co_modem, "Remove contexts on service(%p)", value);
661 _ps_service_remove_contexts(value);
670 gboolean _ps_modem_set_reset_profile(gpointer object, gboolean value)
672 ps_modem_t *modem = object;
674 g_return_val_if_fail(modem != NULL, FALSE);
676 modem->reset_profile = value;
677 dbg("modem(%p) reset_profile(%d)", modem, modem->reset_profile);
681 gboolean _ps_modem_get_reset_profile(gpointer object)
683 ps_modem_t *modem = object;
685 g_return_val_if_fail(modem != NULL, FALSE);
687 dbg("modem(%p) reset_profile(%d)", modem, modem->reset_profile);
689 return modem->reset_profile;
692 GSource *_ps_modem_get_profile_reset_gsource(gpointer object)
694 ps_modem_t *modem = object;
696 g_return_val_if_fail(modem != NULL, NULL);
698 return modem->reset_profile_gsource;
701 gboolean _ps_modem_set_profile_reset_gsource(gpointer object, GSource *source)
703 ps_modem_t *modem = object;
705 g_return_val_if_fail(modem != NULL, FALSE);
707 modem->reset_profile_gsource = source;
712 gboolean _ps_modem_remove_profile_reset_gsource(gpointer object)
714 ps_modem_t *modem = object;
716 g_return_val_if_fail(modem != NULL, FALSE);
718 if (NULL != modem->reset_profile_gsource) {
719 g_source_unref(modem->reset_profile_gsource);
720 modem->reset_profile_gsource = NULL;
726 gboolean _ps_modem_set_sim_enabled(gpointer object, gboolean value)
728 ps_modem_t *modem = object;
730 g_return_val_if_fail(modem != NULL, FALSE);
732 modem->sim_init = value;
733 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) sim_enabled(%d)", modem, modem->sim_init);
737 gboolean _ps_modem_set_data_allowed(gpointer object, gboolean value)
739 ps_modem_t *modem = object;
741 g_return_val_if_fail(modem != NULL, FALSE);
743 modem->data_allowed = value;
744 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) data allowed(%d)", modem, modem->data_allowed);
745 __ps_modem_emit_property_changed_signal(modem);
746 __ps_modem_processing_modem_event(modem);
751 gboolean _ps_modem_get_data_allowed(gpointer object)
753 ps_modem_t *modem = object;
754 g_return_val_if_fail(modem != NULL, FALSE);
756 return modem->data_allowed;
759 gboolean _ps_modem_set_data_roaming_allowed(gpointer object, gboolean roaming_allowed)
761 ps_modem_t *modem = object;
763 g_return_val_if_fail(modem != NULL, FALSE);
765 modem->roaming_allowed = roaming_allowed;
766 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) roaming allowed(%d)", modem, modem->roaming_allowed);
767 __ps_modem_emit_property_changed_signal(modem);
769 if (!modem->services)
773 __ps_modem_processing_modem_event(modem);
778 gboolean _ps_modem_set_psmode(gpointer object, gint value)
780 ps_modem_t *modem = object;
782 g_return_val_if_fail(modem != NULL, FALSE);
784 modem->ps_mode = value;
785 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) power saving mode(%d)", modem, modem->ps_mode);
790 gboolean _ps_modem_get_roaming(gpointer object)
792 ps_modem_t *modem = object;
793 g_return_val_if_fail(modem != NULL, FALSE);
795 return modem->roaming;
798 void _ps_modem_set_roaming(gpointer object, gboolean value)
800 ps_modem_t *modem = object;
801 g_return_if_fail(modem != NULL);
803 modem->roaming = value;
804 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) roaming(%d)", modem, modem->roaming);
809 gint _ps_modem_get_roaming_apn_support(gpointer object)
811 ps_modem_t *modem = object;
813 g_return_val_if_fail(modem != NULL, FALSE);
815 return modem->roaming_apn_support;
818 void _ps_modem_set_roaming_apn_support(gpointer object, gboolean value)
820 ps_modem_t *modem = object;
821 g_return_if_fail(modem != NULL);
823 modem->roaming_apn_support = value;
824 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "modem(%p) roaming_apn_support(%d)", modem, modem->roaming);
827 gint _ps_modem_get_psmode(gpointer object)
829 ps_modem_t *modem = object;
831 g_return_val_if_fail(modem != NULL, FALSE);
833 return modem->ps_mode;
836 guchar _ps_modem_get_hook_flag(gpointer object)
838 ps_modem_t *modem = object;
840 g_return_val_if_fail(modem != NULL, FALSE);
842 return modem->hook_flag;
845 gboolean _ps_modem_get_data_roaming_allowed(gpointer object)
847 ps_modem_t *modem = object;
848 g_return_val_if_fail(modem != NULL, FALSE);
850 return modem->roaming_allowed;
853 gboolean _ps_modem_get_flght_mode(gpointer object)
855 ps_modem_t *modem = object;
856 g_return_val_if_fail(modem != NULL, FALSE);
858 return modem->flight_mode;
861 void _ps_modem_set_flght_mode_ups(gpointer object, gboolean value)
863 ps_modem_t *modem = object;
864 g_return_if_fail(modem != NULL);
866 modem->flight_mode_ups = value;
867 dbg("modem(%p) flight_mode_ups(%d)", modem, modem->flight_mode_ups);
872 gboolean _ps_modem_get_flght_mode_ups(gpointer object)
874 ps_modem_t *modem = object;
875 g_return_val_if_fail(modem != NULL, FALSE);
877 return modem->flight_mode_ups;
880 gboolean _ps_modem_get_sim_init(gpointer object)
882 ps_modem_t *modem = object;
883 g_return_val_if_fail(modem != NULL, FALSE);
885 return modem->sim_init;
888 gboolean _ps_modem_get_power(gpointer object)
890 ps_modem_t *modem = object;
891 g_return_val_if_fail(modem != NULL, FALSE);
893 return modem->powered;
896 char *_ps_modem_ref_operator(gpointer object)
898 ps_modem_t *modem = object;
899 g_return_val_if_fail(modem != NULL, FALSE);
901 return modem->operator;
904 ps_subs_type _ps_modem_get_subs_type(gpointer object)
906 ps_modem_t *modem = object;
907 const gchar *cp_name;
909 g_return_val_if_fail(modem != NULL, FALSE);
911 cp_name = modem->cp_name;
912 if (g_str_has_suffix(cp_name, "0"))
913 return PS_SUBS_PRIMARY;
914 else if (g_str_has_suffix(cp_name, "1"))
915 return PS_SUBS_SECONDARY;
916 else if (g_str_has_suffix(cp_name, "2"))
917 return PS_SUBS_TERTIARY;
922 gboolean _ps_modem_get_properties_handler(gpointer object, GVariantBuilder *properties)
924 ps_modem_t *modem = object;
926 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "get modem properties");
927 g_return_val_if_fail(modem != NULL, FALSE);
928 g_return_val_if_fail(properties != NULL, FALSE);
930 g_variant_builder_open(properties, G_VARIANT_TYPE("a{ss}"));
931 g_variant_builder_add(properties, "{ss}", "path", modem->path);
934 g_variant_builder_add(properties, "{ss}", "operator", modem->operator);
935 g_variant_builder_add(properties, "{ss}", "powered", BOOL2STRING(modem->powered));
936 g_variant_builder_add(properties, "{ss}", "sim_init", BOOL2STRING(modem->sim_init));
937 g_variant_builder_add(properties, "{ss}", "flight_mode", BOOL2STRING(modem->flight_mode));
938 g_variant_builder_add(properties, "{ss}", "roaming_allowed", BOOL2STRING(modem->roaming_allowed));
939 g_variant_builder_add(properties, "{ss}", "data_allowed", BOOL2STRING(modem->data_allowed));
940 g_variant_builder_close(properties);
946 GVariant *_ps_modem_get_properties(gpointer object, GVariantBuilder *properties)
948 ps_modem_t *modem = object;
950 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "get modem properties");
951 g_return_val_if_fail(modem != NULL, FALSE);
952 g_return_val_if_fail(properties != NULL, FALSE);
954 g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
956 g_variant_builder_add(properties, "{ss}", "path", modem->path);
959 g_variant_builder_add(properties, "{ss}", "operator", modem->operator);
960 g_variant_builder_add(properties, "{ss}", "powered", BOOL2STRING(modem->powered));
961 g_variant_builder_add(properties, "{ss}", "sim_init", BOOL2STRING(modem->sim_init));
962 g_variant_builder_add(properties, "{ss}", "flight_mode", BOOL2STRING(modem->flight_mode));
963 g_variant_builder_add(properties, "{ss}", "roaming_allowed", BOOL2STRING(modem->roaming_allowed));
964 g_variant_builder_add(properties, "{ss}", "data_allowed", BOOL2STRING(modem->data_allowed));
967 return g_variant_builder_end(properties);
970 GHashTable *_ps_modem_ref_services(gpointer object)
972 ps_modem_t *modem = object;
973 g_return_val_if_fail(modem != NULL, NULL);
975 return modem->services;
978 char *_ps_modem_ref_path(gpointer object)
980 ps_modem_t *modem = object;
981 g_return_val_if_fail(modem != NULL, NULL);
986 gpointer _ps_modem_ref_plugin(gpointer object)
988 ps_modem_t *modem = object;
989 g_return_val_if_fail(modem != NULL, NULL);
994 gpointer _ps_modem_ref_dbusconn(gpointer object)
996 ps_modem_t *modem = object;
997 g_return_val_if_fail(modem != NULL, NULL);
1002 gpointer _ps_modem_ref_co_modem(gpointer object)
1004 ps_modem_t *modem = object;
1005 g_return_val_if_fail(modem != NULL, NULL);
1007 return modem->co_modem;
1010 gpointer _ps_modem_ref_work_queue(gpointer object)
1012 ps_modem_t *modem = object;
1013 g_return_val_if_fail(modem != NULL, NULL);
1015 return modem->work_queue;
1018 gchar *_ps_modem_ref_cp_name(gpointer object)
1020 ps_modem_t *modem = object;
1021 g_return_val_if_fail(modem != NULL, NULL);
1023 return modem->cp_name;
1026 gpointer _ps_modem_ref_contexts(gpointer object)
1028 ps_modem_t *modem = object;
1029 g_return_val_if_fail(modem != NULL, NULL);
1030 return modem->contexts;
1033 static gboolean on_modem_get_properties(PacketServiceModem *obj_modem,
1034 GDBusMethodInvocation *invocation,
1037 GVariant *gv = NULL;
1038 GVariantBuilder properties;
1039 ps_modem_t *modem = user_data;
1040 TcorePlugin *p = (modem) ? modem->plg : NULL;
1041 PsPrivInfo *priv_info = tcore_plugin_ref_user_data(p);
1042 cynara *p_cynara = (priv_info) ? priv_info->p_cynara : NULL;
1044 if (!ps_util_check_access_control(p_cynara, invocation, AC_PS_PUBLIC, "r"))
1047 dbg("get modem properties");
1049 gv = _ps_modem_get_properties(user_data, &properties);
1050 packet_service_modem_complete_get_properties(obj_modem, invocation, gv);
1054 static gboolean on_modem_get_services(PacketServiceModem *obj_modem,
1055 GDBusMethodInvocation *invocation,
1058 GVariantBuilder b_service;
1061 GHashTableIter iter;
1062 gpointer key, value;
1063 ps_modem_t *modem = user_data;
1064 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
1065 TcorePlugin *p = (modem) ? modem->plg : NULL;
1066 PsPrivInfo *priv_info = tcore_plugin_ref_user_data(p);
1067 cynara *p_cynara = (priv_info) ? priv_info->p_cynara : NULL;
1069 if (!ps_util_check_access_control(p_cynara, invocation, AC_PS_PUBLIC, "r"))
1072 ps_dbg_ex_co(co_modem, "modem get service interface");
1074 if (modem->services == NULL) {
1075 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1079 g_variant_builder_init(&b_service, G_VARIANT_TYPE("a{sa{ss}}"));
1080 g_hash_table_iter_init(&iter, modem->services);
1081 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1084 g_variant_builder_open(&b_service, G_VARIANT_TYPE("{sa{ss}}"));
1085 path = _ps_service_ref_path(value);
1086 ps_dbg_ex_co(co_modem, "path added [%s]", path);
1087 g_variant_builder_add(&b_service, "s", g_strdup(path));
1088 if (FALSE == _ps_service_get_properties_handler(value, &b_service)) {
1089 g_variant_builder_close(&b_service);
1090 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1093 g_variant_builder_close(&b_service);
1096 services = g_variant_builder_end(&b_service);
1097 packet_service_modem_complete_get_services(obj_modem, invocation, services);
1101 static gboolean on_modem_go_dormant_all(PacketServiceModem *obj_modem,
1102 GDBusMethodInvocation *invocation,
1107 GHashTableIter iter;
1108 gpointer key, value;
1109 ps_modem_t *modem = user_data;
1110 TcorePlugin *p = (modem) ? modem->plg : NULL;
1111 PsPrivInfo *priv_info = tcore_plugin_ref_user_data(p);
1112 cynara *p_cynara = (priv_info) ? priv_info->p_cynara : NULL;
1114 if (!ps_util_check_access_control(p_cynara, invocation, AC_PS_PRIVATE, "w"))
1117 dbg("modem go dormant all interface");
1119 if (modem->services == NULL) {
1120 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1124 g_hash_table_iter_init(&iter, modem->services);
1125 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1126 ps_service_t *service = value;
1127 dbg("service (%p), send dormant request, ", service);
1128 result = tcore_ps_send_dormant_request(service->co_ps, NULL);
1131 packet_service_modem_complete_go_dormant_all(obj_modem, invocation, result);
1135 static gboolean on_modem_get_profile_list(PacketServiceModem *obj_modem,
1136 GDBusMethodInvocation *invocation,
1139 int profile_index = 0;
1141 guint len = 0, index;
1142 gchar **strv = NULL;
1143 GSList *profiles = NULL;
1144 ps_modem_t *modem = user_data;
1145 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
1146 TcorePlugin *p = (modem) ? modem->plg : NULL;
1147 PsPrivInfo *priv_info = tcore_plugin_ref_user_data(p);
1148 cynara *p_cynara = (priv_info) ? priv_info->p_cynara : NULL;
1150 if (!ps_util_check_access_control(p_cynara, invocation, AC_PS_PUBLIC, "r"))
1153 ps_dbg_ex_co(co_modem, "master get the profile list");
1155 if (modem->contexts == NULL) {
1156 ps_err_ex_co(co_modem, "no profiles");
1157 FAIL_RESPONSE(invocation, PS_ERR_NO_PROFILE);
1161 for (index = 0; index < g_slist_length(modem->contexts); index++) {
1162 gchar *s_path = NULL;
1163 gpointer value = g_slist_nth_data(modem->contexts, index);
1165 s_path = _ps_context_ref_path(value);
1166 ps_dbg_ex_co(co_modem, "value(%p), path(%s)", value, s_path);
1168 profiles = g_slist_append(profiles, g_strdup((const char *)s_path));
1171 if (profiles == NULL) {
1172 ps_dbg_ex_co(co_modem, "no profiles");
1173 FAIL_RESPONSE(invocation, PS_ERR_NO_PROFILE);
1177 len = g_slist_length(profiles);
1178 strv = g_new(gchar *, len+1);
1181 strv[profile_index] = g_strdup(profiles->data);
1184 profiles = profiles->next;
1186 strv[profile_index] = NULL;
1188 packet_service_modem_complete_get_profile_list(obj_modem,
1189 invocation, (const gchar *const *)strv);
1192 profiles = g_slist_nth(profiles, 0);
1193 g_slist_free_full(profiles, g_free);
1198 static gboolean on_modem_add_profile(PacketServiceModem *obj_modem,
1199 GDBusMethodInvocation *invocation,
1203 GVariantIter g_iter;
1207 gboolean rv = FALSE;
1208 gchar *operator = NULL;
1209 ps_modem_t *modem = user_data;
1210 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
1211 GHashTable *profile_property = NULL;
1212 TcorePlugin *p = (modem) ? modem->plg : NULL;
1213 PsPrivInfo *priv_info = tcore_plugin_ref_user_data(p);
1214 cynara *p_cynara = (priv_info) ? priv_info->p_cynara : NULL;
1216 if (!ps_util_check_access_control(p_cynara, invocation, AC_PS_PROFILE, "w"))
1219 ps_dbg_ex_co(co_modem, "add profile request");
1221 operator = _ps_modem_ref_operator(modem);
1224 ps_dbg_ex_co(co_modem, "there is no active modem");
1225 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1229 /*Create a hash table for the profile property as all fucntion already use ghash table */
1230 profile_property = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1231 g_variant_iter_init(&g_iter, property);
1232 while (g_variant_iter_next(&g_iter, "{ss}", &g_key, &g_value)) {
1234 ps_dbg_ex_co(co_modem, " '%s' value '%s'", g_key, g_value);
1235 g_hash_table_insert(profile_property, g_strdup(g_key), g_strdup(g_value));
1236 /* must free data for ourselves */
1241 rv = _ps_context_add_context(modem, operator, profile_property);
1243 ps_err_ex_co(co_modem, "Failed to add the Profile");
1244 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1245 g_hash_table_destroy(profile_property);
1249 packet_service_modem_complete_add_profile(obj_modem, invocation, TRUE);
1251 g_hash_table_destroy(profile_property);
1256 gboolean _ps_modem_initiate_reset_profile(gpointer value)
1258 CoreObject *co_modem;
1259 ps_modem_t *modem = value;
1260 GHashTableIter iter;
1261 gpointer key, key_value;
1263 g_return_val_if_fail(modem != NULL, FALSE);
1265 co_modem = _ps_modem_ref_co_modem(modem);
1267 ps_dbg_ex_co(co_modem, "Reseting the hash table");
1268 /* Remove contexts through only service. */
1269 g_hash_table_iter_init(&iter, modem->services);
1270 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1271 ps_dbg_ex_co(co_modem, "Remove contexts on service(%p)", value);
1272 _ps_service_remove_contexts(value);
1275 if (modem->type == 0) {
1277 gchar *name = g_strdup_printf("REGEN-DB-%s", modem->cp_name);
1279 thread = g_thread_new(name, __ps_modem_regenerate_database, modem);
1281 if (thread == NULL) {
1282 dbg("Thread is not created");
1283 FAIL_RESPONSE(modem->invocation , PS_ERR_INTERNAL);
1284 _ps_modem_remove_profile_reset_gsource(modem);
1286 dbg("Thread(%p) is created", thread);
1291 /* Create contexts again. */
1292 _ps_get_co_modem_values(modem);
1293 _ps_modem_set_reset_profile(modem, FALSE);
1294 packet_service_modem_complete_reset_profile(modem->if_obj, modem->invocation, TRUE);
1295 modem->invocation = NULL;
1297 _ps_modem_remove_profile_reset_gsource(modem);
1299 /* Try to re-connect default contexts after reset profile is complete */
1300 g_hash_table_iter_init(&iter, modem->services);
1301 while (g_hash_table_iter_next(&iter, &key, &key_value) == TRUE) {
1302 /* only available case */
1303 _ps_service_connect_default_context(key_value);
1306 ps_dbg_ex_co(co_modem, "Exiting");
1310 static gboolean on_modem_reset_profile(PacketServiceModem *obj_modem,
1311 GDBusMethodInvocation *invocation,
1316 gboolean contexts_active;
1317 ps_modem_t *modem = user_data;
1318 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
1321 TcorePlugin *p = (modem) ? modem->plg : NULL;
1322 PsPrivInfo *priv_info = tcore_plugin_ref_user_data(p);
1323 cynara *p_cynara = (priv_info) ? priv_info->p_cynara : NULL;
1325 if (!ps_util_check_access_control(p_cynara, invocation, AC_PS_PROFILE, "w"))
1328 ps_dbg_ex_co(co_modem, "reset profile request type(%d)", type);
1330 if (_ps_modem_get_reset_profile(modem) == TRUE) {
1331 ps_err_ex_co(co_modem, "Reset Profile is already in Progress");
1332 packet_service_modem_complete_reset_profile(obj_modem, invocation, FALSE);
1333 ps_dbg_ex_co(co_modem, "Exiting");
1337 _ps_modem_set_reset_profile(modem, TRUE);
1339 co_ps = tcore_plugin_ref_core_object(tcore_object_ref_plugin(_ps_modem_ref_co_modem(modem)),
1340 CORE_OBJECT_TYPE_PS);
1342 modem->invocation = invocation;
1345 contexts_active = tcore_ps_any_context_activating_activated(co_ps, &state);
1347 if (contexts_active == TRUE) {
1348 ps_dbg_ex_co(co_modem, "Contexts are in [%d] state", state);
1349 if (state == CONTEXT_STATE_ACTIVATED) {
1350 ps_dbg_ex_co(co_modem, "Contexts are in Actived state. Sending Diconnect Notification to all connected contexts");
1351 rv = tcore_ps_deactivate_contexts(co_ps);
1352 if (rv != TCORE_RETURN_SUCCESS)
1353 ps_dbg_ex_co(co_modem, "fail to deactivation");
1354 } else if (state == CONTEXT_STATE_ACTIVATING) {
1355 ps_dbg_ex_co(co_modem, "Contexts are in Activating state. Wait for them to connect");
1358 ps_dbg_ex_co(co_modem, "No contexts are in activating or activated state");
1359 ps_dbg_ex_co(co_modem, "Profiles reset is being initiated");
1360 _ps_modem_initiate_reset_profile(modem);
1367 static void _ps_modem_setup_interface(PacketServiceModem *modem, ps_modem_t *modem_data)
1369 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem_data), "Entered");
1371 g_signal_connect(modem,
1372 "handle-get-properties",
1373 G_CALLBACK(on_modem_get_properties),
1376 g_signal_connect(modem,
1377 "handle-get-services",
1378 G_CALLBACK(on_modem_get_services),
1381 g_signal_connect(modem,
1382 "handle-go-dormant-all",
1383 G_CALLBACK(on_modem_go_dormant_all),
1386 g_signal_connect(modem,
1387 "handle-get-profile-list",
1388 G_CALLBACK(on_modem_get_profile_list),
1391 g_signal_connect(modem,
1392 "handle-add-profile",
1393 G_CALLBACK(on_modem_add_profile),
1396 g_signal_connect(modem,
1397 "handle-reset-profile",
1398 G_CALLBACK(on_modem_reset_profile),