Add python3-setuptools dependency for python 3.12
[platform/core/telephony/tel-plugin-packetservice.git] / src / ps_master.c
1 /*
2  * tel-plugin-packetservice
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: DongHoo Park <donghoo.park@samsung.com>
7  *          Arun Shukla <arun.shukla@samsung.com>
8  *
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  *
21  */
22
23 #include <unistd.h>
24 #include <system_info.h>
25
26 #include "ps_common.h"
27 #include "ps_context.h"
28 #include "ps_master.h"
29 #include "ps_modem.h"
30 #include "ps_service.h"
31 #include "ps_master_interface.h"
32
33 #include <server.h>
34 #include <plugin.h>
35 #include <storage.h>
36 #include <co_context.h>
37
38 #include "ps_log.h"
39
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 */
44
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"); \
49                 } \
50 } \
51
52 static void __ps_master_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data);
53
54 static void __ps_master_handle_ups_mode(ps_modem_t *modem, gchar *request)
55 {
56         GSList *contexts = NULL;
57         unsigned int index;
58
59         if (G_UNLIKELY(!modem))
60                 return;
61
62         info("send dbus %s requeset", request);
63         contexts = modem->contexts;
64         if (!contexts) {
65                 err("no profiles");
66                 return;
67         }
68
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);
73
74                 dbg("context(%p), path(%s), role(%d)", context, _ps_context_ref_path(context), role);
75
76                 if (!context) {
77                         err("context is NULL");
78                         continue;
79                 }
80
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);
88                         continue;
89                 } else {
90                         if (CONTEXT_STATE_ACTIVATED != tcore_context_get_state(co_context))
91                                 continue;
92
93                         if (!g_strcmp0(request, "InterfaceDown")) {
94                                 warn("disconnect context request.");
95                                 _ps_service_deactivate_context(_ps_context_ref_service(context), context);
96                         }
97                 }
98         }
99 }
100
101 static void __ps_master_register_key_callback(ps_master_t *master, enum tcore_storage_key key)
102 {
103         _PS_CHECK_STRG(master);
104         tcore_storage_set_key_callback(master->strg, key, __ps_master_storage_key_callback, master);
105 }
106
107 static void __ps_master_deregister_key_callback(ps_master_t *master, enum tcore_storage_key key)
108 {
109         _PS_CHECK_STRG(master);
110         tcore_storage_remove_key_callback(master->strg, key, __ps_master_storage_key_callback);
111 }
112
113 void __remove_master(gpointer data, gpointer user_data)
114 {
115         ps_master_t *master = data;
116         Server *s;
117
118         info("master:[%p]", master);
119
120         /*Deinit alarm*/
121         alarmmgr_fini();
122
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);
130 #endif
131
132         s = tcore_plugin_ref_server(master->plg);
133
134         tcore_server_remove_notification_hook(s, __on_hook_modem_added);
135         tcore_server_remove_notification_hook(s, __on_hook_modem_removed);
136
137         /*Need to remove the compelete hash table*/
138         g_hash_table_remove_all(master->modems);
139
140         /*Need to UNexport and Unref the master Object */
141         g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(master->if_obj));
142
143         g_object_unref(master->if_obj);
144
145         /*Need to free the memory allocated for the members of the master*/
146         g_free(master);
147         master = NULL;
148
149         dbg("Exiting");
150 }
151
152 static void __ps_master_process_key_callback(ps_master_t *master, enum tcore_storage_key key, GVariant *tmp)
153 {
154         GHashTableIter iter;
155         gpointer h_key, h_value;
156
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);
170
171                         if (curr_ps_mode & POWER_SAVING_MODE_DATA_ALLOWED)
172                                 new_ps_mode |= POWER_SAVING_MODE_DATA_ALLOWED;
173
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);
179
180                         if (ps_mode != POWER_SAVING_MODE_NORMAL)
181                                 dbg("current power saving mode: %d, pm_state: %d", ps_mode, pm_state);
182
183                         if (ps_mode & POWER_SAVING_MODE_DATA_ALLOWED) {
184                                 warn("UPS by FMM: Do not change data network state.");
185                                 return;
186                         }
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");
192                                 } else {
193                                         _ps_modem_set_pm_state(h_value, pm_state);
194                                 }
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");
200                                 } else {
201                                         _ps_modem_set_pm_state(h_value, pm_state);
202                                 }
203                         }
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);
209                         } else {
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);
214                         }
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);
224                                 }
225                         } else {
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);
230                         }
231 #endif
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);
236                 }
237         }
238 }
239
240 static void __ps_master_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data)
241 {
242         GVariant *tmp = NULL;
243         gboolean type_check = FALSE;
244         ps_master_t *master = (ps_master_t *)user_data;
245
246         g_return_if_fail(master != NULL);
247
248         tmp = (GVariant *)value;
249         if (G_UNLIKELY(!tmp)) {
250                 err("value is null");
251                 return;
252         }
253
254         switch (key) {
255         case KEY_3G_ENABLE:
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);
260                 if (!type_check) {
261                         err("wrong variant data type");
262                         g_variant_unref(tmp);
263                         return;
264                 }
265                 break;
266
267         case KEY_POWER_SAVING_MODE:
268         case KEY_PM_STATE:
269                 type_check = g_variant_is_of_type(tmp, G_VARIANT_TYPE_INT32);
270                 if (!type_check) {
271                         err("wrong variant data type");
272                         g_variant_unref(tmp);
273                         return;
274                 }
275                 break;
276
277         default:
278                 warn("unknown key (0x%x)", key);
279                 return;
280         }
281
282         __ps_master_process_key_callback(master, key, tmp);
283
284 }
285
286 static gboolean __ps_master_create_modem(ps_master_t *master, TcorePlugin *modem_plg)
287 {
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;
293
294         g_return_val_if_fail(master != NULL, FALSE);
295
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);
299         if (tmp != NULL) {
300                 dbg("modem (%p) already existed", tmp);
301                 g_free(modem_name);
302                 return FALSE;
303         }
304
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);
308         if (!modem) {
309                 err("fail to create modem");
310                 g_free(modem_name);
311                 return FALSE;
312         }
313
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);
319         else
320                 warn("Wait for telephony ready");
321
322         g_free(modem_name);
323         return TRUE;
324 }
325
326 ps_master_t *_ps_master_create_master(GDBusConnection *conn, TcorePlugin *p)
327 {
328         ps_master_t *new_master = NULL;
329
330         dbg("master object create");
331         g_return_val_if_fail(conn != NULL, NULL);
332
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");
337                 return NULL;
338         }
339
340         new_master->conn = conn;
341         new_master->plg = p;
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");
344
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");
347
348         /*Setting Up the call backs for the interface*/
349         if (!ps_master_setup_interface(new_master)) {
350                 g_free(new_master);
351                 return NULL;
352         }
353
354
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);
362 #endif
363         /* __ps_master_register_key_callback(new_master, KEY_PM_STATE); */
364
365         /*Alarm manager init*/
366         dbg("init alarm manager.");
367         if (alarmmgr_init("packetservice") != ALARMMGR_RESULT_SUCCESS) {
368                 err("Failed to init alarm manager");
369                 g_free(new_master);
370                 return NULL;
371         }
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);
375
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);
379
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);
384 #endif
385
386         info("Successfully created the master");
387         return new_master;
388 }
389
390 gboolean _ps_master_create_modems(ps_master_t *master, TcorePlugin *modem_plg)
391 {
392         g_return_val_if_fail(master != NULL, FALSE);
393
394         if (!modem_plg) {
395                 GSList *modem_list, *iter;
396                 Server *s = tcore_plugin_ref_server(master->plg);
397                 gboolean ret = TRUE;
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);
402                 }
403                 g_slist_free(modem_list);
404                 return ret;
405         } else
406                 return __ps_master_create_modem(master, modem_plg);
407 }
408
409 gboolean _ps_master_destroy_modem(ps_master_t *master, TcorePlugin *plugin)
410 {
411         gchar *modem_name;
412         ps_modem_t *modem;
413
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);
417         if (modem == NULL) {
418                 warn("modem '%s' doesn't exists", modem_name);
419                 g_free(modem_name);
420                 return FALSE;
421         }
422
423         /*  Destroy Modem */
424         info("Destroying modem object for '%s' modem[%p]", modem_name, modem);
425         _ps_modem_destroy_modem(master->conn, modem);
426
427         if (g_hash_table_remove(master->modems, modem_name) == TRUE)
428                 info("Removed modem '%s'", modem_name);
429
430         g_free(modem_name);
431
432         return TRUE;
433 }
434
435 gboolean _ps_master_get_storage_value_bool(ps_master_t *master, enum tcore_storage_key key)
436 {
437         g_return_val_if_fail(master != NULL, FALSE);
438         _PS_CHECK_STRG(master);
439         return tcore_storage_get_bool(master->strg, key);
440 }
441
442 gint _ps_master_get_storage_value_int(ps_master_t *master, enum tcore_storage_key key)
443 {
444         g_return_val_if_fail(master != NULL, FALSE);
445         _PS_CHECK_STRG(master);
446         return tcore_storage_get_int(master->strg, key);
447 }
448
449 char *_ps_master_get_storage_value_string(ps_master_t *master, enum tcore_storage_key key)
450 {
451         g_return_val_if_fail(master != NULL, FALSE);
452         _PS_CHECK_STRG(master);
453         return tcore_storage_get_string(master->strg, key);
454 }
455
456 gboolean _ps_master_set_storage_value_bool(ps_master_t *master, enum tcore_storage_key key, gboolean value)
457 {
458         g_return_val_if_fail(master != NULL, FALSE);
459         _PS_CHECK_STRG(master);
460         return tcore_storage_set_bool(master->strg, key, value);
461 }
462
463 gboolean _ps_master_set_storage_value_int(ps_master_t *master, enum tcore_storage_key key, gint value)
464 {
465         g_return_val_if_fail(master != NULL, FALSE);
466         _PS_CHECK_STRG(master);
467         return tcore_storage_set_int(master->strg, key, value);
468 }
469
470 gboolean _ps_master_set_storage_value_string(ps_master_t *master, enum tcore_storage_key key, char *value)
471 {
472         g_return_val_if_fail(master != NULL, FALSE);
473         _PS_CHECK_STRG(master);
474         return tcore_storage_set_string(master->strg, key, value);
475 }
476
477 gboolean _ps_master_set_always_on_control(ps_master_t *master, gboolean enable)
478 {
479         GHashTableIter iter;
480         gpointer key, value;
481
482         g_return_val_if_fail(master != NULL, FALSE);
483         g_return_val_if_fail(master->modems != NULL, FALSE);
484
485         g_hash_table_iter_init(&iter, master->modems);
486         while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
487                 unsigned int i;
488                 ps_modem_t *modem = value;
489
490                 if (!modem || !modem->contexts)
491                         continue;
492
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);
496                         if (path) {
497                                 dbg("context(%s)", path);
498                                 _ps_context_set_alwayson_enable(context, enable);
499                         }
500                 }
501         }
502         return TRUE;
503 }
504