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.
25 #include "ps_common.h"
26 #include "generated-code.h"
32 #include <user_request.h>
33 #include <co_context.h>
35 #define PS_MASTER_PATH "/"
36 #define PROP_DEFAULT FALSE
37 #define PROP_DEFAULT_STR NULL
39 /* [Wearable][sap-stack] SAPInterface.h */
40 #define SAP_CONN_TYPE_ALL 0x00
41 #define SAP_CONN_TYPE_BT 0x01
42 #define SAP_CONN_TYPE_MOBILE 0x10 /* scs */
44 static void __ps_master_emit_modem_added_signal(ps_master_t *master, gpointer modem);
45 /*static void __ps_master_emit_modem_removed_signal(ps_master_t *master, gpointer modem);*/
46 static void _ps_master_setup_interface(PacketServiceMaster *master, ps_master_t *master_data);
48 static void __ps_master_register_key_callback(gpointer master, enum tcore_storage_key key);
49 static void __ps_master_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data);
51 static void __ps_master_handle_ups_mode(gpointer object, gchar *request)
53 ps_modem_t *modem = object;
54 GSList *contexts = NULL;
60 info("send dbus %s requeset", request);
61 contexts = modem->contexts;
62 if (contexts == NULL) {
67 for (index = 0; index < g_slist_length(contexts); index++) {
69 gpointer value = g_slist_nth_data(contexts, index);
70 ps_context_t *pscontext = (ps_context_t *)value;
71 int role = tcore_context_get_role(pscontext->co_context);
73 s_path = _ps_context_ref_path(value);
74 dbg("value(%p), path(%s)", value, s_path);
76 if (role == CONTEXT_ROLE_INTERNET && pscontext->is_default) {
77 if (!g_strcmp0(request, "IfaceDown"))
78 _ps_context_handle_ifacedown(value);
79 else if (!g_strcmp0(request, "IfaceUp"))
80 _ps_context_handle_ifaceup(value);
81 } else if (role == CONTEXT_ROLE_UNKNOWN || role == CONTEXT_ROLE_USER_DEFINED) {
82 warn("Not supported profile type: %d", role);
85 if (CONTEXT_STATE_ACTIVATED != tcore_context_get_state(pscontext->co_context))
88 if (!g_strcmp0(request, "InterfaceDown")) {
89 warn("disconnect context request.");
90 _ps_service_deactivate_context(pscontext->p_service, pscontext);
97 void __remove_master(gpointer data, gpointer user_data)
99 ps_master_t *master = data;
106 /* Remove notification hooks */
107 tcore_server_remove_notification_hook(tcore_plugin_ref_server(master->plg), __on_hook_modem_added);
108 tcore_server_remove_notification_hook(tcore_plugin_ref_server(master->plg), __on_hook_modem_removed);
110 /*Need to remove the compelete hash table*/
111 g_hash_table_remove_all(master->modems);
113 /*Need to UNexport and Unref the master Object */
114 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(master->if_obj));
116 g_object_unref(master->if_obj);
118 /*Need to free the memory allocated for the members of the master*/
119 g_free(master->path);
126 static void __ps_master_emit_modem_added_signal(ps_master_t *master, gpointer modem)
129 GVariantBuilder properties;
131 dbg("get modem properties");
133 gv = _ps_modem_get_properties(modem, &properties);
134 packet_service_master_emit_modem_added(master->if_obj, gv);
140 static void __ps_master_emit_modem_removed_signal(ps_master_t *master, gpointer modem)
142 g_signal_emit(master, signals[SIG_MASTER_MODEM_REMOVED], 0, _ps_modem_ref_path(modem));
143 dbg("master (%p) emit the modem(%p) removed signal", master, modem);
147 static void __ps_master_register_key_callback(gpointer object, enum tcore_storage_key key)
149 ps_master_t *master = (ps_master_t *) object;
150 Server *s = tcore_plugin_ref_server(master->plg);
151 static Storage *strg;
153 strg = tcore_server_find_storage(s, "vconf");
154 tcore_storage_set_key_callback(strg, key, __ps_master_storage_key_callback, object);
159 static void __ps_master_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data)
161 GVariant *tmp = NULL;
163 gpointer h_key, h_value;
164 gboolean type_check = FALSE;
165 ps_master_t *master = (ps_master_t *)user_data;
167 dbg("storage key(%d) callback", key);
168 g_return_if_fail(master != NULL);
170 tmp = (GVariant *)value;
172 err("value is null");
178 case KEY_DATA_ROAMING_SETTING:
179 case KEY_NETWORK_RESTRICT_MODE:
180 case KEY_TELEPHONY_READY:
181 type_check = g_variant_is_of_type(tmp, G_VARIANT_TYPE_BOOLEAN);
183 err("wrong variant data type");
184 g_variant_unref(tmp);
189 case KEY_POWER_SAVING_MODE:
191 #ifdef POWER_SAVING_FEATURE_WEARABLE
192 case KEY_WECONN_ALL_CONNECTED:
194 type_check = g_variant_is_of_type(tmp, G_VARIANT_TYPE_INT32);
196 err("wrong variant data type");
197 g_variant_unref(tmp);
203 warn("unknown key (0x%x)", key);
207 g_hash_table_iter_init(&iter, master->modems);
208 while (g_hash_table_iter_next(&iter, &h_key, &h_value) == TRUE) {
209 if (key == KEY_3G_ENABLE) {
210 gboolean data_allowed = g_variant_get_boolean(tmp);
211 msg("[PSINFO] data_allowed [%d] changed", data_allowed);
212 #if defined(TIZEN_PS_FORCE_ATTACH_DETACH)
213 if (_ps_master_get_storage_value_int(master, KEY_WECONN_ALL_CONNECTED) > 0) {
215 int sap_conn_type = SAP_CONN_TYPE_ALL;
216 sap_conn_type = _ps_master_get_storage_value_int(master, KEY_SAP_CONNECTION_TYPE);
217 if (sap_conn_type == SAP_CONN_TYPE_BT) {
218 warn("[Companion mode] ignore data_allowed.");
224 _ps_modem_set_data_allowed(h_value, data_allowed);
225 } else if (key == KEY_DATA_ROAMING_SETTING) {
226 gboolean roaming_allowed = g_variant_get_boolean(tmp);
227 msg("[PSINFO] roaming_allowed [%d] changed.", roaming_allowed);
228 _ps_modem_set_data_roaming_allowed(h_value, roaming_allowed);
229 } else if (key == KEY_POWER_SAVING_MODE) {
230 gint new_ps_mode = g_variant_get_int32(tmp);
231 gint curr_ps_mode = _ps_modem_get_psmode(h_value);
233 if (curr_ps_mode & POWER_SAVING_MODE_DATA_ALLOWED)
234 new_ps_mode |= POWER_SAVING_MODE_DATA_ALLOWED;
236 info("curr_ps_mode [0X%x] new_ps_mode[0X%x]", curr_ps_mode, new_ps_mode);
237 _ps_modem_set_psmode(h_value, new_ps_mode);
238 } else if (key == KEY_PM_STATE) {
239 gint pm_state = g_variant_get_int32(tmp);
240 gint ps_mode = _ps_modem_get_psmode(h_value);
242 if (ps_mode != POWER_SAVING_MODE_NORMAL)
243 dbg("current power saving mode: %d, pm_state: %d", ps_mode, pm_state);
245 if (ps_mode & POWER_SAVING_MODE_DATA_ALLOWED) {
246 warn("UPS by FMM: Do not change data network state.");
249 if (pm_state == 3) {/* LCD Off */
250 if (ps_mode > POWER_SAVING_MODE_NORMAL && ps_mode < POWER_SAVING_MODE_WEARABLE) {
251 msg("[PSINFO] LCD OFF. Start Deactivate with power saving [%d]", ps_mode);
252 /* send dbus request pdp context deactivation. */
253 __ps_master_handle_ups_mode(h_value, "IfaceDown");
255 } else { /* LCD On or dimming */
256 if (ps_mode > POWER_SAVING_MODE_NORMAL && ps_mode < POWER_SAVING_MODE_WEARABLE) {
257 msg("[PSINFO] pm_state(%d) changed. Start activate with power saving [%d]", pm_state, ps_mode);
258 /* send dbus request pdp context activation. */
259 __ps_master_handle_ups_mode(h_value, "IfaceUp");
262 } else if (key == KEY_NETWORK_RESTRICT_MODE) {
263 gboolean b_network_restrict = g_variant_get_boolean(tmp);
264 if (b_network_restrict) {
265 msg("[PSINFO] network restricted mode on");
266 _ps_modem_set_data_allowed(h_value, FALSE);
268 gboolean key_3g_enable = FALSE;
269 msg("[PSINFO] network restricted mode off");
270 key_3g_enable = _ps_master_get_storage_value_bool(master, KEY_3G_ENABLE);
271 _ps_modem_set_data_allowed(h_value, key_3g_enable);
273 #ifdef STORAGE_KEY_WECONN_ALL_CONNECTED
274 } else if (key == KEY_WECONN_ALL_CONNECTED) {
275 int b_wms_connected = g_variant_get_int32(tmp);
276 if (b_wms_connected) {
277 int sap_conn_type = SAP_CONN_TYPE_ALL;
278 sap_conn_type = _ps_master_get_storage_value_int(master, KEY_SAP_CONNECTION_TYPE);
279 if (sap_conn_type == SAP_CONN_TYPE_BT) {
280 msg("[PSINFO][Wearable] Companinon mode. set data allowed FALSE");
281 _ps_modem_set_data_allowed(h_value, FALSE);
284 gboolean key_3g_enable = FALSE;
285 key_3g_enable = _ps_master_get_storage_value_bool(master, KEY_3G_ENABLE);
286 msg("[PSINFO][Wearable] Standalone mode. set data allowed (%d)", key_3g_enable);
287 _ps_modem_set_data_allowed(h_value, key_3g_enable);
290 } else if (key == KEY_TELEPHONY_READY) {
291 gboolean b_telephony_ready = _ps_master_get_storage_value_bool(master, KEY_TELEPHONY_READY);
292 if (b_telephony_ready)
293 __ps_master_emit_modem_added_signal(master, h_value);
300 gpointer _ps_master_create_master(GDBusConnection *conn, TcorePlugin *p)
302 PacketServiceMaster *master = NULL;
303 ps_master_t *new_master = NULL;
304 GError *error = NULL;
306 dbg("master object create");
307 g_return_val_if_fail(conn != NULL, NULL);
309 /*creating the master object for the interface com.tcore.ps.master*/
310 master = packet_service_master_skeleton_new();
311 g_return_val_if_fail(master != NULL, NULL);
313 /*Alarm manager init*/
314 dbg("init alarm manager.");
315 if (alarmmgr_init("packetservice") != ALARMMGR_RESULT_SUCCESS) {
316 err("Failed to init alarm manager");
320 /*Initializing the master list for internal referencing*/
321 new_master = g_try_malloc0(sizeof(ps_master_t));
322 if (NULL == new_master) {
323 err("Unable to allocate memory for master");
327 new_master->conn = conn;
328 new_master->path = g_strdup(PS_MASTER_PATH);
330 new_master->if_obj = master;
331 new_master->modems = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_modem_handler);
333 /*Setting Up the call backs for the interface*/
334 _ps_master_setup_interface(master, new_master);
336 /*exporting the interface object to the path mention for master*/
337 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(master),
342 g_assert_no_error(error);
344 /*Registering the key callbacks for values in storage settings */
345 __ps_master_register_key_callback(new_master, KEY_TELEPHONY_READY);
346 __ps_master_register_key_callback(new_master, KEY_3G_ENABLE);
347 __ps_master_register_key_callback(new_master, KEY_DATA_ROAMING_SETTING);
348 #if defined(TIZEN_UPS_ENABLED)
349 __ps_master_register_key_callback(new_master, KEY_POWER_SAVING_MODE);
350 __ps_master_register_key_callback(new_master, KEY_PM_STATE);
352 /* __ps_master_register_key_callback(new_master, KEY_PM_STATE); */
353 #if defined(TIZEN_PS_FORCE_ATTACH_DETACH)
354 __ps_master_register_key_callback(new_master, KEY_WECONN_ALL_CONNECTED);
357 /*Adding Hook for modem addition laters*/
358 tcore_server_add_notification_hook(tcore_plugin_ref_server(p),
359 TNOTI_SERVER_ADDED_MODEM_PLUGIN, __on_hook_modem_added, new_master);
361 /*Adding Hook for modem removal laters*/
362 tcore_server_add_notification_hook(tcore_plugin_ref_server(p),
363 TNOTI_SERVER_REMOVED_MODEM_PLUGIN, __on_hook_modem_removed, new_master);
365 info("Successfully created the master");
369 err("Unable to create master");
370 g_object_unref(master);
374 gboolean _ps_master_create_modems(gpointer object, TcorePlugin *modem_plg)
377 gpointer modem = NULL, tmp = NULL;
378 ps_master_t *master = NULL;
379 CoreObject *co_modem = NULL;
380 gchar *modem_name = NULL;
381 gchar *cp_name = NULL;
382 gboolean key_telephony_ready;
384 g_return_val_if_fail(object != NULL, FALSE);
385 dbg("create modem objects");
387 master = (ps_master_t *)object;
388 key_telephony_ready = _ps_master_get_storage_value_bool(master, KEY_TELEPHONY_READY);
390 cp_name = (gchar *)tcore_server_get_cp_name_by_plugin(modem_plg);
391 modem_name = g_strdup_printf("/%s", cp_name);
392 tmp = g_hash_table_lookup(master->modems, modem_name);
394 dbg("modem (%p) already existed", tmp);
399 co_modem = tcore_plugin_ref_core_object(modem_plg, CORE_OBJECT_TYPE_MODEM);
401 modem = _ps_modem_create_modem(master->conn, master->plg,
402 master, modem_name, co_modem, cp_name);
404 err("fail to create modem");
409 g_hash_table_insert(master->modems, g_strdup(modem_name), modem);
410 info("modem (%p) created at path %s", modem , modem_name);
412 if (key_telephony_ready) {
413 __ps_master_emit_modem_added_signal(master, modem);
415 warn("Wait for telephony ready");
421 /*Need to walk through all modem if any present before packet service intialization*/
423 TcorePlugin *p = NULL;
424 GSList *plist_head = NULL;
425 GSList *plist = NULL;
426 GSList *modemlist_head = NULL;
427 GSList *modemlist = NULL;
429 s = tcore_plugin_ref_server(master->plg);
430 plist_head = tcore_server_get_modem_plugin_list(s);
433 warn("Modem plugin is not present");
441 modemlist_head = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_MODEM);
442 if (!modemlist_head) {
443 warn("Found no modem core-objects");
447 modemlist = modemlist_head;
449 co_modem = modemlist->data;
450 cp_name = (gchar *)tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_modem));
451 modem_name = g_strdup_printf("/%s", cp_name);
452 tmp = g_hash_table_lookup(master->modems, modem_name);
454 dbg("modem (%p) already existed", tmp);
455 modemlist = modemlist->next;
460 modem = _ps_modem_create_modem(master->conn, master->plg, master, modem_name, co_modem, cp_name);
462 err("Fail to create modem ");
463 modemlist = modemlist->next;
468 g_hash_table_insert(master->modems, g_strdup(modem_name), modem);
469 info("modem (%p) created at path %s", modem , modem_name);
470 if (key_telephony_ready) {
471 __ps_master_emit_modem_added_signal(master, modem);
473 warn("Wait for telephony ready");
476 modemlist = modemlist->next;
478 g_slist_free(modemlist_head);
482 g_slist_free(plist_head);
487 gboolean _ps_master_destroy_modem(gpointer object, TcorePlugin *plugin)
489 ps_master_t *master = NULL;
494 dbg("destroy modem object");
496 master = (ps_master_t *)object;
498 modem_name = g_strdup_printf("/%s",
499 tcore_server_get_cp_name_by_plugin(plugin));
501 modem = g_hash_table_lookup(master->modems, modem_name);
503 warn("modem '%s' doesn't exists", modem_name);
509 info("Destroying modem object for '%s' modem[%p]", modem_name, modem);
510 _ps_modem_destroy_modem(master->conn, modem);
512 if (g_hash_table_remove(master->modems, modem_name) == TRUE)
513 info("Removed modem '%s'", modem_name);
520 gboolean _ps_master_get_storage_value_bool(gpointer object, enum tcore_storage_key key)
523 Storage *strg = NULL;
524 ps_master_t *master = object;
526 g_return_val_if_fail(master != NULL, FALSE);
527 s = tcore_plugin_ref_server(master->plg);
528 strg = tcore_server_find_storage(s, "vconf");
530 return tcore_storage_get_bool(strg, key);;
533 gint _ps_master_get_storage_value_int(gpointer object, enum tcore_storage_key key)
536 Storage *strg = NULL;
537 ps_master_t *master = object;
539 g_return_val_if_fail(master != NULL, FALSE);
540 s = tcore_plugin_ref_server(master->plg);
541 strg = tcore_server_find_storage(s, "vconf");
543 return tcore_storage_get_int(strg, key);;
546 gboolean _ps_master_set_storage_value_bool(gpointer object, enum tcore_storage_key key, gboolean value)
549 Storage *strg = NULL;
550 ps_master_t *master = object;
552 g_return_val_if_fail(master != NULL, FALSE);
553 s = tcore_plugin_ref_server(master->plg);
554 strg = tcore_server_find_storage(s, "vconf");
556 return tcore_storage_set_bool(strg, key, value);
559 gboolean _ps_master_set_storage_value_int(gpointer object, enum tcore_storage_key key, gint value)
562 Storage *strg = NULL;
563 ps_master_t *master = object;
565 g_return_val_if_fail(master != NULL, FALSE);
566 s = tcore_plugin_ref_server(master->plg);
567 strg = tcore_server_find_storage(s, "vconf");
569 return tcore_storage_set_int(strg, key, value);
572 gboolean _ps_master_set_always_on_control(gpointer user_data, gboolean enable)
574 ps_master_t *master = user_data;
578 g_return_val_if_fail(master != NULL, FALSE);
579 g_return_val_if_fail(master->modems != NULL, FALSE);
583 g_hash_table_iter_init(&iter, master->modems);
584 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
586 ps_modem_t *modem = value;
590 if (modem->contexts == NULL)
593 for (i = 0; i < g_slist_length(modem->contexts); i++) {
594 ps_context_t *context = (ps_context_t*)g_slist_nth_data(modem->contexts, i);
595 gchar *path = _ps_context_ref_path(context);
597 dbg("context(%s)", path);
598 _ps_context_set_alwayson_enable(context, enable);
605 static gboolean on_master_get_modems(PacketServiceMaster *obj_master,
606 GDBusMethodInvocation *invocation,
609 GVariantBuilder b_modem;
614 ps_master_t *master = user_data;
618 if (master->modems == NULL) {
619 err("No modem Present");
620 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
624 g_variant_builder_init(&b_modem, G_VARIANT_TYPE("a{sa{ss}}"));
626 g_hash_table_iter_init(&iter, master->modems);
627 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
629 path = _ps_modem_ref_path(value);
630 dbg("modem path [%s]", path);
632 g_variant_builder_open(&b_modem, G_VARIANT_TYPE("{sa{ss}}"));
633 g_variant_builder_add(&b_modem, "s", path);
634 if (FALSE == _ps_modem_get_properties_handler(value, &b_modem)) {
635 err("Unable to get the modem properties");
636 g_variant_builder_close(&b_modem);
637 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
640 g_variant_builder_close(&b_modem);
642 modems = g_variant_builder_end(&b_modem);
644 packet_service_master_complete_get_modems(obj_master, invocation, modems);
648 static gboolean on_master_set_alwayson(PacketServiceMaster *obj_master,
649 GDBusMethodInvocation *invocation,
653 gboolean result = FALSE;
656 result = _ps_master_set_always_on_control(user_data, enable);
658 packet_service_master_complete_set_alwayson(obj_master, invocation, result);
660 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
664 static void _ps_master_setup_interface(PacketServiceMaster *master, ps_master_t *master_data)
668 g_signal_connect(master,
670 G_CALLBACK(on_master_get_modems),
673 g_signal_connect(master,
674 "handle-set-alwayson",
675 G_CALLBACK(on_master_set_alwayson),