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.
24 #include <system_info.h>
26 #include "ps_common.h"
27 #include "ps_context.h"
28 #include "ps_master.h"
30 #include "ps_service.h"
31 #include "ps_master_interface.h"
36 #include <co_context.h>
40 /* [Wearable][sap-stack] SAPInterface.h */
41 #define SAP_CONN_TYPE_ALL 0x00
42 #define SAP_CONN_TYPE_BT 0x01
43 #define SAP_CONN_TYPE_MOBILE 0x10 /* scs */
45 #define _PS_CHECK_STRG(master) { \
46 if (G_UNLIKELY(!master->strg)) { \
47 warn("Updating strg"); \
48 master->strg = tcore_server_find_storage(tcore_plugin_ref_server(master->plg), "vconf"); \
52 static void __ps_master_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data);
54 static void __ps_master_handle_ups_mode(ps_modem_t *modem, gchar *request)
56 GSList *contexts = NULL;
59 if (G_UNLIKELY(!modem))
62 info("send dbus %s requeset", request);
63 contexts = modem->contexts;
69 for (index = 0; index < g_slist_length(contexts); index++) {
70 ps_context_t *context = g_slist_nth_data(contexts, index);
71 CoreObject *co_context = _ps_context_ref_co_context(context);
72 int role = tcore_context_get_role(co_context);
74 dbg("context(%p), path(%s), role(%d)", context, _ps_context_ref_path(context), role);
77 err("context is NULL");
81 if (role == CONTEXT_ROLE_INTERNET && context->is_default) {
82 if (!g_strcmp0(request, "IfaceDown"))
83 _ps_context_handle_ifacedown(context);
84 else if (!g_strcmp0(request, "IfaceUp"))
85 _ps_context_handle_ifaceup(context);
86 } else if (role == CONTEXT_ROLE_UNKNOWN || role == CONTEXT_ROLE_USER_DEFINED) {
87 warn("Not supported profile type: %d", role);
90 if (CONTEXT_STATE_ACTIVATED != tcore_context_get_state(co_context))
93 if (!g_strcmp0(request, "InterfaceDown")) {
94 warn("disconnect context request.");
95 _ps_service_deactivate_context(_ps_context_ref_service(context), context);
101 static void __ps_master_register_key_callback(ps_master_t *master, enum tcore_storage_key key)
103 _PS_CHECK_STRG(master);
104 tcore_storage_set_key_callback(master->strg, key, __ps_master_storage_key_callback, master);
107 static void __ps_master_deregister_key_callback(ps_master_t *master, enum tcore_storage_key key)
109 _PS_CHECK_STRG(master);
110 tcore_storage_remove_key_callback(master->strg, key, __ps_master_storage_key_callback);
113 void __remove_master(gpointer data, gpointer user_data)
115 ps_master_t *master = data;
118 info("master:[%p]", master);
123 /*Registering the key callbacks for values in storage settings */
124 __ps_master_deregister_key_callback(master, KEY_TELEPHONY_READY);
125 __ps_master_deregister_key_callback(master, KEY_3G_ENABLE);
126 __ps_master_deregister_key_callback(master, KEY_DATA_ROAMING_SETTING);
127 #if defined(TIZEN_UPS_ENABLED)
128 __ps_master_deregister_key_callback(master, KEY_POWER_SAVING_MODE);
129 __ps_master_deregister_key_callback(master, KEY_PM_STATE);
132 s = tcore_plugin_ref_server(master->plg);
134 tcore_server_remove_notification_hook(s, __on_hook_modem_added);
135 tcore_server_remove_notification_hook(s, __on_hook_modem_removed);
137 /*Need to remove the compelete hash table*/
138 g_hash_table_remove_all(master->modems);
140 /*Need to UNexport and Unref the master Object */
141 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(master->if_obj));
143 g_object_unref(master->if_obj);
145 /*Need to free the memory allocated for the members of the master*/
152 static void __ps_master_process_key_callback(ps_master_t *master, enum tcore_storage_key key, GVariant *tmp)
155 gpointer h_key, h_value;
157 g_hash_table_iter_init(&iter, master->modems);
158 while (g_hash_table_iter_next(&iter, &h_key, &h_value) == TRUE) {
159 if (key == KEY_3G_ENABLE) {
160 gboolean data_allowed = g_variant_get_boolean(tmp);
161 msg("[PSINFO] data_allowed [%d] changed", data_allowed);
162 _ps_modem_set_data_allowed(h_value, data_allowed);
163 } else if (key == KEY_DATA_ROAMING_SETTING) {
164 gboolean roaming_allowed = g_variant_get_boolean(tmp);
165 msg("[PSINFO] roaming_allowed [%d] changed.", roaming_allowed);
166 _ps_modem_set_data_roaming_allowed(h_value, roaming_allowed);
167 } else if (key == KEY_POWER_SAVING_MODE) {
168 gint new_ps_mode = g_variant_get_int32(tmp);
169 gint curr_ps_mode = _ps_modem_get_psmode(h_value);
171 if (curr_ps_mode & POWER_SAVING_MODE_DATA_ALLOWED)
172 new_ps_mode |= POWER_SAVING_MODE_DATA_ALLOWED;
174 info("[PSINFO] curr_ps_mode [0X%x] new_ps_mode[0X%x]", curr_ps_mode, new_ps_mode);
175 _ps_modem_set_psmode(h_value, new_ps_mode);
176 } else if (key == KEY_PM_STATE) {
177 gint pm_state = g_variant_get_int32(tmp);
178 gint ps_mode = _ps_modem_get_psmode(h_value);
180 if (ps_mode != POWER_SAVING_MODE_NORMAL)
181 dbg("current power saving mode: %d, pm_state: %d", ps_mode, pm_state);
183 if (ps_mode & POWER_SAVING_MODE_DATA_ALLOWED) {
184 warn("UPS by FMM: Do not change data network state.");
187 if (pm_state == 3) { /* LCD Off */
188 if (ps_mode > POWER_SAVING_MODE_NORMAL && ps_mode < POWER_SAVING_MODE_WEARABLE) {
189 msg("[PSINFO] LCD OFF. Start Deactivate with power saving [%d]", ps_mode);
190 /* send dbus request pdp context deactivation. */
191 __ps_master_handle_ups_mode(h_value, "IfaceDown");
193 _ps_modem_set_pm_state(h_value, pm_state);
195 } else { /* LCD On or dimming */
196 if (ps_mode > POWER_SAVING_MODE_NORMAL && ps_mode < POWER_SAVING_MODE_WEARABLE) {
197 msg("[PSINFO] pm_state(%d) changed. Start activate with power saving [%d]", pm_state, ps_mode);
198 /* send dbus request pdp context activation. */
199 __ps_master_handle_ups_mode(h_value, "IfaceUp");
201 _ps_modem_set_pm_state(h_value, pm_state);
204 } else if (key == KEY_NETWORK_RESTRICT_MODE) {
205 gboolean b_network_restrict = g_variant_get_boolean(tmp);
206 if (b_network_restrict) {
207 msg("[PSINFO] network restricted mode on");
208 _ps_modem_set_data_allowed(h_value, FALSE);
210 gboolean key_3g_enable = FALSE;
211 msg("[PSINFO] network restricted mode off");
212 key_3g_enable = _ps_master_get_storage_value_bool(master, KEY_3G_ENABLE);
213 _ps_modem_set_data_allowed(h_value, key_3g_enable);
215 #ifdef STORAGE_KEY_WECONN_ALL_CONNECTED
216 } else if (key == KEY_WECONN_ALL_CONNECTED) {
217 int b_wms_connected = g_variant_get_int32(tmp);
218 if (b_wms_connected) {
219 int sap_conn_type = SAP_CONN_TYPE_ALL;
220 sap_conn_type = _ps_master_get_storage_value_int(master, KEY_SAP_CONNECTION_TYPE);
221 if (sap_conn_type == SAP_CONN_TYPE_BT) {
222 msg("[PSINFO][Wearable] Companinon mode. set data allowed FALSE");
223 _ps_modem_set_data_allowed(h_value, FALSE);
226 gboolean key_3g_enable = FALSE;
227 key_3g_enable = _ps_master_get_storage_value_bool(master, KEY_3G_ENABLE);
228 msg("[PSINFO][Wearable] Standalone mode. set data allowed (%d)", key_3g_enable);
229 _ps_modem_set_data_allowed(h_value, key_3g_enable);
232 } else if (key == KEY_TELEPHONY_READY) {
233 gboolean b_telephony_ready = _ps_master_get_storage_value_bool(master, KEY_TELEPHONY_READY);
234 if (b_telephony_ready)
235 ps_master_emit_modem_added_signal(master, h_value);
240 static void __ps_master_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data)
242 GVariant *tmp = NULL;
243 gboolean type_check = FALSE;
244 ps_master_t *master = (ps_master_t *)user_data;
246 g_return_if_fail(master != NULL);
248 tmp = (GVariant *)value;
249 if (G_UNLIKELY(!tmp)) {
250 err("value is null");
256 case KEY_DATA_ROAMING_SETTING:
257 case KEY_NETWORK_RESTRICT_MODE:
258 case KEY_TELEPHONY_READY:
259 type_check = g_variant_is_of_type(tmp, G_VARIANT_TYPE_BOOLEAN);
261 err("wrong variant data type");
262 g_variant_unref(tmp);
267 case KEY_POWER_SAVING_MODE:
269 type_check = g_variant_is_of_type(tmp, G_VARIANT_TYPE_INT32);
271 err("wrong variant data type");
272 g_variant_unref(tmp);
278 warn("unknown key (0x%x)", key);
282 __ps_master_process_key_callback(master, key, tmp);
286 static gboolean __ps_master_create_modem(ps_master_t *master, TcorePlugin *modem_plg)
288 ps_modem_t *modem = NULL, *tmp = NULL;
289 gchar *modem_name = NULL;
290 gchar *cp_name = NULL;
291 CoreObject *co_modem = NULL;
292 gboolean key_telephony_ready;
294 g_return_val_if_fail(master != NULL, FALSE);
296 cp_name = (gchar *)tcore_server_get_cp_name_by_plugin(modem_plg);
297 modem_name = g_strdup_printf("/%s", cp_name);
298 tmp = g_hash_table_lookup(master->modems, modem_name);
300 dbg("modem (%p) already existed", tmp);
305 dbg("create modem(%s) objects", modem_name);
306 co_modem = tcore_plugin_ref_core_object(modem_plg, CORE_OBJECT_TYPE_MODEM);
307 modem = _ps_modem_create_modem(master->conn, master->plg, master, modem_name, co_modem, cp_name);
309 err("fail to create modem");
314 g_hash_table_insert(master->modems, g_strdup(modem_name), modem);
315 info("modem (%p) created at path %s", modem, modem_name);
316 key_telephony_ready = _ps_master_get_storage_value_bool(master, KEY_TELEPHONY_READY);
317 if (key_telephony_ready)
318 ps_master_emit_modem_added_signal(master, modem);
320 warn("Wait for telephony ready");
326 ps_master_t *_ps_master_create_master(GDBusConnection *conn, TcorePlugin *p)
328 ps_master_t *new_master = NULL;
330 dbg("master object create");
331 g_return_val_if_fail(conn != NULL, NULL);
333 /*Initializing the master list for internal referencing*/
334 new_master = g_try_malloc0(sizeof(ps_master_t));
335 if (G_UNLIKELY(!new_master)) {
336 err("Unable to allocate memory for master");
340 new_master->conn = conn;
342 new_master->modems = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_modem_handler);
343 new_master->strg = tcore_server_find_storage(tcore_plugin_ref_server(p), "vconf");
345 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.lte", &new_master->b_lte_supported);
346 info("b_lte_supported: [%s]", new_master->b_lte_supported ? "TRUE" : "FALSE");
348 /*Setting Up the call backs for the interface*/
349 if (!ps_master_setup_interface(new_master)) {
355 /*Registering the key callbacks for values in storage settings */
356 __ps_master_register_key_callback(new_master, KEY_TELEPHONY_READY);
357 __ps_master_register_key_callback(new_master, KEY_3G_ENABLE);
358 __ps_master_register_key_callback(new_master, KEY_DATA_ROAMING_SETTING);
359 #if defined(TIZEN_UPS_ENABLED)
360 __ps_master_register_key_callback(new_master, KEY_POWER_SAVING_MODE);
361 __ps_master_register_key_callback(new_master, KEY_PM_STATE);
363 /* __ps_master_register_key_callback(new_master, KEY_PM_STATE); */
365 /*Alarm manager init*/
366 dbg("init alarm manager.");
367 if (alarmmgr_init("packetservice") != ALARMMGR_RESULT_SUCCESS) {
368 err("Failed to init alarm manager");
372 /*Adding Hook for modem addition laters*/
373 tcore_server_add_notification_hook(tcore_plugin_ref_server(p),
374 TNOTI_SERVER_ADDED_MODEM_PLUGIN, __on_hook_modem_added, new_master);
376 /*Adding Hook for modem removal laters*/
377 tcore_server_add_notification_hook(tcore_plugin_ref_server(p),
378 TNOTI_SERVER_REMOVED_MODEM_PLUGIN, __on_hook_modem_removed, new_master);
380 #ifdef TIZEN_SUPPORT_VOLTE
381 /*Adding Hook for SIM Refreshed laters*/
382 tcore_server_add_notification_hook(tcore_plugin_ref_server(p),
383 TNOTI_SIM_REFRESHED, __on_hook_sim_refresh, new_master);
386 info("Successfully created the master");
390 gboolean _ps_master_create_modems(ps_master_t *master, TcorePlugin *modem_plg)
392 g_return_val_if_fail(master != NULL, FALSE);
395 GSList *modem_list, *iter;
396 Server *s = tcore_plugin_ref_server(master->plg);
398 modem_list = tcore_server_get_modem_plugin_list(s);
399 for (iter = modem_list; iter != NULL; iter = iter->next) {
400 TcorePlugin *modem_p = iter->data;
401 ret = __ps_master_create_modem(master, modem_p);
403 g_slist_free(modem_list);
406 return __ps_master_create_modem(master, modem_plg);
409 gboolean _ps_master_destroy_modem(ps_master_t *master, TcorePlugin *plugin)
414 dbg("destroy modem object");
415 modem_name = g_strdup_printf("/%s", tcore_server_get_cp_name_by_plugin(plugin));
416 modem = g_hash_table_lookup(master->modems, modem_name);
418 warn("modem '%s' doesn't exists", modem_name);
424 info("Destroying modem object for '%s' modem[%p]", modem_name, modem);
425 _ps_modem_destroy_modem(master->conn, modem);
427 if (g_hash_table_remove(master->modems, modem_name) == TRUE)
428 info("Removed modem '%s'", modem_name);
435 gboolean _ps_master_get_storage_value_bool(ps_master_t *master, enum tcore_storage_key key)
437 g_return_val_if_fail(master != NULL, FALSE);
438 _PS_CHECK_STRG(master);
439 return tcore_storage_get_bool(master->strg, key);
442 gint _ps_master_get_storage_value_int(ps_master_t *master, enum tcore_storage_key key)
444 g_return_val_if_fail(master != NULL, FALSE);
445 _PS_CHECK_STRG(master);
446 return tcore_storage_get_int(master->strg, key);
449 char *_ps_master_get_storage_value_string(ps_master_t *master, enum tcore_storage_key key)
451 g_return_val_if_fail(master != NULL, FALSE);
452 _PS_CHECK_STRG(master);
453 return tcore_storage_get_string(master->strg, key);
456 gboolean _ps_master_set_storage_value_bool(ps_master_t *master, enum tcore_storage_key key, gboolean value)
458 g_return_val_if_fail(master != NULL, FALSE);
459 _PS_CHECK_STRG(master);
460 return tcore_storage_set_bool(master->strg, key, value);
463 gboolean _ps_master_set_storage_value_int(ps_master_t *master, enum tcore_storage_key key, gint value)
465 g_return_val_if_fail(master != NULL, FALSE);
466 _PS_CHECK_STRG(master);
467 return tcore_storage_set_int(master->strg, key, value);
470 gboolean _ps_master_set_storage_value_string(ps_master_t *master, enum tcore_storage_key key, char *value)
472 g_return_val_if_fail(master != NULL, FALSE);
473 _PS_CHECK_STRG(master);
474 return tcore_storage_set_string(master->strg, key, value);
477 gboolean _ps_master_set_always_on_control(ps_master_t *master, gboolean enable)
482 g_return_val_if_fail(master != NULL, FALSE);
483 g_return_val_if_fail(master->modems != NULL, FALSE);
485 g_hash_table_iter_init(&iter, master->modems);
486 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
488 ps_modem_t *modem = value;
490 if (!modem || !modem->contexts)
493 for (i = 0; i < g_slist_length(modem->contexts); i++) {
494 ps_context_t *context = (ps_context_t *)g_slist_nth_data(modem->contexts, i);
495 gchar *path = _ps_context_ref_path(context);
497 dbg("context(%s)", path);
498 _ps_context_set_alwayson_enable(context, enable);