2 * PacketService Control Module
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 "generated-code.h"
26 #include <core_object.h>
28 #include <co_context.h>
31 #define PROP_DEFAULT FALSE
32 #define PROP_DEFAULT_STR NULL
33 #define BOOL2STRING(a) ((a==TRUE) ? ("TRUE"):("FALSE"))
35 #define TIMEOUT_DEFAULT 5
36 #define TIMEOUT_MAX 1800
39 static void __ps_service_emit_property_changed_signal(ps_service_t *service);
40 static void __ps_service_emit_context_added_signal(ps_service_t *service, gpointer context);
41 static void __ps_service_emit_context_removed_signal(ps_service_t *service, gpointer context);
42 static void _ps_service_setup_interface(PacketServiceService *service, ps_service_t *service_data);
44 static char * __ps_service_act2string(enum telephony_network_access_technology act);
45 static gboolean __ps_service_check_connection_option(gpointer service, gpointer context);
46 static int __ps_service_connetion_timeout_handler(alarm_id_t alarm_id, void *context);
48 void __remove_service_handler(gpointer data)
50 ps_service_t *service = data;
54 dbg("Service is Null");
58 /*Need to remove the compelete hash table*/
59 g_hash_table_remove_all(service->contexts);
61 /*Need to UNexport and Unref the master Object */
63 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(service->if_obj));
64 g_object_unref(service->if_obj);
65 service->if_obj = NULL;
68 /*Need to free the memory of the internal structure*/
69 g_free(service->path);
76 static void __ps_service_emit_property_changed_signal(ps_service_t *service)
79 GVariantBuilder property;
81 ps_dbg_ex_co(_ps_service_ref_co_network(service), "get service properties");
83 gv = _ps_service_get_properties(service, &property);
84 packet_service_service_emit_property_changed(service->if_obj, gv);
90 static void __ps_service_emit_context_added_signal(ps_service_t *service, gpointer context)
93 GVariantBuilder property;
95 ps_dbg_ex_co(_ps_service_ref_co_network(service), "get service properties");
97 gv = _ps_context_get_properties(context, &property);
98 packet_service_service_emit_context_added(service->if_obj, gv);
104 static void __ps_service_emit_context_removed_signal(ps_service_t *service, gpointer context)
106 ps_context_t *pscontext = context;
109 packet_service_service_emit_context_removed(service->if_obj, pscontext->path);
115 static char *__ps_service_act2string(enum telephony_network_access_technology act)
118 case NETWORK_ACT_GSM:
119 case NETWORK_ACT_GPRS:
120 case NETWORK_ACT_EGPRS:
121 case NETWORK_ACT_UMTS:
122 case NETWORK_ACT_GSM_UTRAN:
124 case NETWORK_ACT_IS95A:
125 case NETWORK_ACT_IS95B:
126 case NETWORK_ACT_CDMA_1X:
127 case NETWORK_ACT_EVDO_REV0:
128 case NETWORK_ACT_CDMA_1X_EVDO_REV0:
129 case NETWORK_ACT_EVDO_REVA:
130 case NETWORK_ACT_CDMA_1X_EVDO_REVA:
131 case NETWORK_ACT_EVDV:
133 case NETWORK_ACT_LTE:
135 case NETWORK_ACT_UNKNOWN:
143 static gboolean __ps_service_check_connection_option(gpointer object, gpointer context)
145 gboolean b_connect = TRUE;
146 gboolean power = FALSE, sim = FALSE, data = FALSE, flight = FALSE, nw_ops = FALSE;
147 gboolean profile_reset = FALSE;
149 enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
153 ps_service_t *service = object;
154 ps_modem_t *modem = _ps_service_ref_modem(service);
155 CoreObject *co_context = context;
156 CoreObject *co_network = _ps_service_ref_co_network(service);
158 role = tcore_context_get_role(co_context);
159 if(service->roaming){
160 b_connect &=_ps_modem_get_data_roaming_allowed(modem);
163 sim = _ps_modem_get_sim_init(modem);
164 data = _ps_modem_get_data_allowed(modem);
165 flight = _ps_modem_get_flght_mode(modem);
166 hook_flag = _ps_modem_get_hook_flag(modem);
167 profile_reset = _ps_modem_get_reset_profile(modem);
168 if(hook_flag != PS_NO_PENDING_REQUEST)
170 if(PS_MODEM_STATE_ONLINE == _ps_modem_get_power(modem))
176 #if defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
177 ps_dbg_ex_co(co_network, "csc runtime feature enabled");
178 if(role != CONTEXT_ROLE_MMS && role != CONTEXT_ROLE_PREPAID_MMS){
181 char *tmp_apn = NULL;
182 tmp_apn = tcore_context_get_apn(co_context);
183 dbg("csc runtime feature is enabled: apn[%s]", tmp_apn);
184 if(ps_feature_get_bool(PS_FEATURE_OPERATOR_SKT)) {
186 tcore_context_set_apn(co_context, "web.sktelecom.com");
188 tcore_context_set_apn(co_context, "mmsonly.sktelecom.com");
192 if (role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY) {
193 dbg("Do not check data allowed value in case of IMS type");
195 ps_dbg_ex_co(co_network, "csc runtime feature disabled");
200 b_connect &= !flight;
201 b_connect &= !nw_ops;
202 b_connect &= !service->restricted;
203 b_connect &= !profile_reset;
204 #ifndef TIZEN_PS_FORCE_ATTACH_DETACH
205 b_connect &= service->ps_attached;
207 ps_mode = _ps_modem_get_psmode(modem);
210 if(service->initial_pdp_conn == FALSE) {
211 int wifi_state = PS_WIFI_STATE_OFF;
213 Storage *strg = NULL;
215 s = tcore_plugin_ref_server(service->plg);
216 strg = tcore_server_find_storage(s, "vconf");
217 wifi_state = tcore_storage_get_int(strg, KEY_WIFI_STATE);
218 if(wifi_state == PS_WIFI_STATE_CONNECTED) {
219 if (service->wifi_connected_checked == FALSE) {
220 ps_dbg_ex_co(co_network, "DO NOT set PDP retry timer when WiFi connected but PDP never been connected yet.");
222 service->wifi_connected_checked = TRUE;
224 ps_dbg_ex_co(co_network, "Wifi connected state was already checked.");
228 ps_dbg_ex_co(co_network, "b_connect(%d), power(%d), sim init(%d), data allowed(%d), flight mode(%d) restricted(%d) ps_attached(%d), ps_mode(%d), fook_flag(%d)",
229 b_connect, power, sim, data, flight, service->restricted, service->ps_attached, ps_mode, hook_flag);
234 static int __ps_service_connetion_timeout_handler(alarm_id_t alarm_id, void *context)
237 ps_service_t *service = _ps_context_ref_service(context);
238 if(service == NULL) {
239 err("service is NULL!!!");
243 if (service->timer_src > 0) {
244 dbg("remove connection retry timer (%d)", service->timer_src);
245 alarmmgr_remove_alarm(service->timer_src);
246 service->timer_src = 0;
248 rv = _ps_service_activate_context(service, context);
249 ps_dbg_ex_co(_ps_service_ref_co_network(service), "return rv(%d)", rv);
253 static void __ps_service_set_attach_apn(ps_service_t *service)
256 gpointer key, ps_context;
257 CoreObject *co_context;
258 gboolean attach_apn = FALSE;
259 enum co_context_role role;
261 g_hash_table_iter_init(&iter, service->contexts);
262 while (g_hash_table_iter_next(&iter, &key, &ps_context) == TRUE) {
263 co_context = _ps_context_ref_co_context(ps_context);
264 role = tcore_context_get_role(co_context);
265 attach_apn = tcore_context_get_attach_apn(co_context);
267 dbg("Set 'Attach APN' [%p]", co_context);
268 if (role != CONTEXT_ROLE_INTERNET)
269 _ps_context_set_only_attach(ps_context, TRUE);
270 tcore_ps_define_context(service->co_ps, co_context, NULL);
275 gpointer _ps_service_create_service(GDBusConnection *conn, TcorePlugin *p, gpointer p_modem,
276 CoreObject *co_network, CoreObject *co_ps, gchar* path)
278 PacketServiceService *service;
279 GError *error = NULL;
280 ps_service_t *new_service;
282 ps_dbg_ex_co(co_network, "service object create");
283 g_return_val_if_fail(conn != NULL, NULL);
284 g_return_val_if_fail(p_modem != NULL, NULL);
286 /*creating the master object for the interface com.tcore.ps.modem*/
287 service = packet_service_service_skeleton_new();
289 /*Initializing the modem list for internal referencing*/
290 new_service = g_try_malloc0(sizeof(ps_service_t));
291 if(NULL == new_service){
292 ps_err_ex_co(co_network, "Unable to allocate memory for master");
296 new_service->conn = conn;
297 new_service->plg = p;
298 new_service->p_modem = p_modem;
299 new_service->co_network = co_network;
300 new_service->co_ps = co_ps;
301 new_service->path = g_strdup(path);
302 new_service->if_obj = service;
303 new_service->contexts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
305 /*exporting the interface object to the path mention for master*/
306 if(TRUE != g_dbus_interface_skeleton_export((G_DBUS_INTERFACE_SKELETON(service)), conn, path, &error)) {
307 ps_err_ex_co(co_network, "Failed to export interaface with message [%s] & ID[%d] ", error->message, error->code);
311 _ps_hook_co_network_event(new_service);
312 _ps_get_co_network_values(new_service);
313 _ps_hook_co_ps_event(new_service);
315 /*Setting up the interface for the service */
316 _ps_service_setup_interface(service, new_service);
318 new_service->connection_timeout = TIMEOUT_DEFAULT;
319 ps_dbg_ex_co(co_network, "Successfully Created the service");
323 /*To Do: Handle failure case*/
325 g_assert_no_error (error);
329 gboolean _ps_service_ref_context(gpointer object, gpointer context)
332 gchar *s_path = NULL;
333 ps_service_t *service = object;
334 CoreObject *co_network = NULL;
336 dbg("service refer to context");
337 g_return_val_if_fail(service != NULL, FALSE);
339 co_network = _ps_service_ref_co_network(service);
340 s_path = _ps_context_ref_path(context);
341 tmp = g_hash_table_lookup(service->contexts, s_path);
343 ps_dbg_ex_co(co_network, "context(%p) already existed", tmp);
347 _ps_context_set_service(context, service);
348 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
349 g_hash_table_insert(service->contexts, g_strdup(s_path), context);
351 ps_dbg_ex_co(co_network, "context(%p) insert to hash", context);
352 __ps_service_emit_context_added_signal(service, context);
354 //_ps_service_connect_default_context(service);
358 gboolean _ps_service_ref_contexts(gpointer object, GHashTable *contexts, gchar *operator)
362 ps_service_t *service = object;
365 CoreObject *co_network = NULL;
367 dbg("service refer to contexts");
368 g_return_val_if_fail(service != NULL, FALSE);
370 co_network = _ps_service_ref_co_network(service);
371 g_hash_table_iter_init(&iter, contexts);
372 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
373 gchar *s_path = NULL;
375 gboolean f_awo = FALSE;
377 s_path = _ps_context_ref_path(value);
378 tmp = g_hash_table_lookup(service->contexts, s_path);
380 ps_dbg_ex_co(co_network, "context(%p) already existed", tmp);
384 _ps_context_set_service(value, service);
385 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(value));
386 g_hash_table_insert(service->contexts, g_strdup(s_path), value);
388 ps_dbg_ex_co(co_network, "context(%p) insert to hash", value);
389 __ps_service_emit_context_added_signal(service, value);
391 f_awo = _ps_context_get_alwayson_enable(value);
393 rv = _ps_service_define_context(service, value);
394 ps_dbg_ex_co(co_network, "return rv(%d)", rv);
398 _ps_update_cellular_state_key(service);
399 //_ps_service_connect_default_context(service);
403 gboolean _ps_service_unref_context(gpointer object, gpointer context)
405 ps_service_t *service = object;
407 dbg("service unref contexts");
408 g_return_val_if_fail(service != NULL, FALSE);
409 g_return_val_if_fail(context != NULL, FALSE);
411 ps_dbg_ex_co(_ps_service_ref_co_network(service), "remove context(%p) from service(%p)", context, service);
412 tcore_ps_remove_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
413 g_hash_table_remove(service->contexts, _ps_context_ref_path(context));
414 __ps_service_emit_context_removed_signal(service, context);
419 gboolean _ps_service_get_properties_handler(gpointer object, GVariantBuilder *properties)
421 ps_service_t *service = object;
423 dbg("get service properties");
424 g_return_val_if_fail(service != NULL, FALSE);
425 g_return_val_if_fail(properties != NULL, FALSE);
427 g_variant_builder_open(properties, G_VARIANT_TYPE("a{ss}"));
428 g_variant_builder_add(properties, "{ss}", "path", service->path);
429 g_variant_builder_add(properties, "{ss}", "ps_attached", BOOL2STRING(service->ps_attached));
430 g_variant_builder_add(properties, "{ss}", "roaming", BOOL2STRING(service->roaming));
431 g_variant_builder_add(properties, "{ss}", "act", __ps_service_act2string(service->act));
432 g_variant_builder_close(properties);
438 GVariant * _ps_service_get_properties(gpointer object, GVariantBuilder *properties)
440 ps_service_t *service = object;
442 dbg("get service properties ");
443 g_return_val_if_fail(service != NULL, FALSE);
444 g_return_val_if_fail(properties != NULL, FALSE);
446 g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
448 g_variant_builder_add(properties, "{ss}", "path", service->path);
449 g_variant_builder_add(properties, "{ss}", "ps_attached", BOOL2STRING(service->ps_attached));
450 g_variant_builder_add(properties, "{ss}", "roaming", BOOL2STRING(service->roaming));
451 g_variant_builder_add(properties, "{ss}", "act", __ps_service_act2string(service->act));
454 return g_variant_builder_end(properties);
457 gchar* _ps_service_ref_path(gpointer object)
459 ps_service_t *service = object;
460 g_return_val_if_fail(service != NULL, NULL);
462 return service->path;
465 gpointer _ps_service_ref_plugin(gpointer object)
467 ps_service_t *service = object;
468 g_return_val_if_fail(service != NULL, NULL);
473 gpointer _ps_service_ref_co_network(gpointer object)
475 ps_service_t *service = object;
476 g_return_val_if_fail(service != NULL, NULL);
478 return service->co_network;
481 gpointer _ps_service_ref_co_ps(gpointer object)
483 ps_service_t *service = object;
484 g_return_val_if_fail(service != NULL, NULL);
486 return service->co_ps;
489 gpointer _ps_service_ref_modem(gpointer object)
491 ps_service_t *service = object;
492 g_return_val_if_fail(service != NULL, NULL);
494 return service->p_modem;
497 gboolean _ps_service_set_context_info(gpointer object, struct tnoti_ps_pdp_ipconfiguration *devinfo)
499 GSList* contexts = NULL;
500 ps_service_t *service = object;
501 CoreObject *co_context = NULL;
503 dbg("set context info");
504 g_return_val_if_fail(service != NULL, FALSE);
506 contexts = tcore_ps_ref_context_by_id(service->co_ps, devinfo->context_id);
508 ps_dbg_ex_co(_ps_service_ref_co_network(service), "fail to ref context by cid.");
513 co_context = contexts->data;
515 contexts = contexts->next;
519 tcore_context_set_devinfo(co_context, devinfo);
521 contexts = contexts->next;
527 int _ps_service_define_context(gpointer object, gpointer context)
529 ps_service_t *service = object;
530 CoreObject *co_context = NULL;
531 gboolean b_connect = TRUE;
533 dbg("define context(%p)", context);
534 g_return_val_if_fail(service != NULL, FALSE);
536 co_context = (CoreObject *)_ps_context_ref_co_context(context);
538 b_connect = __ps_service_check_connection_option(service, co_context);
540 return TCORE_RETURN_EPERM;
542 return tcore_ps_define_context(service->co_ps, co_context, NULL);
545 int _ps_service_activate_context(gpointer object, gpointer context)
547 ps_service_t *service = object;
548 ps_modem_t *modem = NULL;
549 CoreObject *co_context = NULL;
550 gboolean b_connect = TRUE;
552 int ret = TCORE_RETURN_FAILURE;
553 int default_data_subs = 1;
554 ps_subs_type subs_type = 1;
556 static Storage *strg;
557 CoreObject *co_network = NULL;
559 dbg("activate context(%p)", context);
560 g_return_val_if_fail(service != NULL, FALSE);
562 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
563 strg = tcore_server_find_storage(s, "vconf");
565 co_network = _ps_service_ref_co_network(service);
566 modem = _ps_service_ref_modem(service);
567 if(modem->hook_flag != PS_NO_PENDING_REQUEST){
568 ps_dbg_ex_co(co_network, "Pending request present in queue with flag %x", modem->hook_flag);
569 return TCORE_RETURN_FAILURE;
572 /* Check for default data subscription value if matchs for modem then only activate */
573 subs_type = _ps_modem_get_subs_type(modem);
575 default_data_subs = tcore_storage_get_int(strg, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
576 if ((default_data_subs != -1) && ( default_data_subs != (int)subs_type)) {
577 ps_warn_ex_co(co_network, "activation for only [SIM%d] selected by Setting", default_data_subs + 1);
578 return TCORE_RETURN_FAILURE;
581 co_context = (CoreObject *)_ps_context_ref_co_context(context);
583 b_connect = __ps_service_check_connection_option(service, co_context);
585 return TCORE_RETURN_EPERM;
587 ps_defined = _ps_context_get_ps_defined(context);
589 ps_dbg_ex_co(co_network, "pdp profile is not defined yet, define first. ");
590 ret = tcore_ps_define_context(service->co_ps, co_context, NULL);
593 ps_dbg_ex_co(co_network, "pdp profile is defined, activate context. ");
594 ret = tcore_ps_activate_context(service->co_ps, co_context, NULL);
600 gboolean _ps_service_deactivate_context(gpointer object, gpointer context)
602 ps_service_t *service = object;
603 CoreObject *co_context = NULL;
605 g_return_val_if_fail(service != NULL, FALSE);
606 dbg("deactivate context(%p)", context);
607 co_context = (CoreObject *)_ps_context_ref_co_context(context);
609 return tcore_ps_deactivate_context(service->co_ps, co_context, NULL);
612 void _ps_service_set_retry_timeout_value(gpointer object, int value)
614 ps_service_t *service = object;
615 g_return_if_fail(service != NULL);
617 service->connection_timeout = value;
618 dbg("current timeout (%d)", service->connection_timeout);
622 void _ps_service_connection_timer(gpointer object, gpointer context)
625 gboolean f_awo = FALSE;
626 ps_service_t *service = object;
628 g_return_if_fail(service != NULL);
630 f_awo = _ps_context_get_alwayson_enable(context);
634 if (service->timer_src > 0) {
635 warn("remove connection retry timer (%d)", service->timer_src);
636 alarmmgr_remove_alarm(service->timer_src);
637 service->timer_src = 0;
639 result = alarmmgr_add_alarm_withcb(ALARM_TYPE_VOLATILE, (time_t)(service->connection_timeout),
640 0, __ps_service_connetion_timeout_handler, context, &(service->timer_src));
641 if (result != ALARMMGR_RESULT_SUCCESS) {
642 err("Failed to add alarm(%d)", result);
646 dbg("cellular service timer started timer src(%d), timeout(%d)", service->timer_src, service->connection_timeout);
647 service->connection_timeout = (service->connection_timeout)*2;
648 if(service->connection_timeout >= TIMEOUT_MAX)
649 service->connection_timeout = TIMEOUT_MAX;
654 void _ps_service_reset_connection_timer(gpointer context)
656 gboolean f_awo = FALSE;
657 ps_service_t *service = NULL;
659 f_awo = _ps_context_get_alwayson_enable(context);
663 service = _ps_context_ref_service(context);
664 if(service == NULL) {
665 err("service is NULL!!!");
668 service->connection_timeout = TIMEOUT_DEFAULT;
670 if (service->timer_src > 0) {
671 warn("remove connection retry timer (%d)", service->timer_src);
672 alarmmgr_remove_alarm(service->timer_src);
673 service->timer_src = 0;
679 void _ps_service_remove_contexts(gpointer object)
683 ps_service_t *service = object;
685 dbg("service remove all contexts");
686 g_return_if_fail(service != NULL);
688 g_hash_table_iter_init(&iter, service->contexts);
689 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
690 gpointer co_context = NULL;
692 ps_dbg_ex_co(_ps_service_ref_co_network(service), "key(%s), value(%p) context", key, value);
693 co_context = _ps_context_ref_co_context(value);
695 _ps_service_reset_connection_timer(value);
696 _ps_context_set_alwayson_enable(value, FALSE);
697 _ps_service_deactivate_context(service, value);
698 _ps_context_set_connected(value, FALSE);
699 tcore_ps_remove_context(service->co_ps, co_context);
700 tcore_context_free(co_context);
702 __ps_service_emit_context_removed_signal(service, value);
703 _ps_context_remove_context(value);
706 g_hash_table_remove_all(service->contexts);
710 void _ps_service_disconnect_contexts(gpointer object)
714 ps_service_t *service = object;
716 dbg("service disconnect all contexts");
717 g_return_if_fail(service != NULL);
719 g_hash_table_iter_init(&iter, service->contexts);
720 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
721 _ps_service_reset_connection_timer(value);
722 _ps_service_deactivate_context(service, value);
728 void _ps_service_disconnect_internet_mms_contexts(gpointer object)
732 ps_service_t *service = object;
733 CoreObject *co_context = NULL;
734 enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
736 dbg("Service disconnect Internet/MMS contexts");
737 g_return_if_fail(service != NULL);
739 g_hash_table_iter_init(&iter, service->contexts);
740 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
741 co_context = (CoreObject *)_ps_context_ref_co_context(value);
742 role = tcore_context_get_role(co_context);
745 * Deactivate following type of contexts -
752 case CONTEXT_ROLE_INTERNET:
753 case CONTEXT_ROLE_MMS:
754 case CONTEXT_ROLE_PREPAID_INTERNET:
755 case CONTEXT_ROLE_PREPAID_MMS:
756 _ps_service_reset_connection_timer(value);
757 _ps_service_deactivate_context(service, value);
761 dbg("Need not deactivate for %d PDN type", role);
768 int _ps_service_connect_default_context(gpointer object)
773 ps_service_t *service = object;
775 dbg("service connect default context");
776 g_return_val_if_fail(service != NULL, TCORE_RETURN_FAILURE);
778 g_hash_table_iter_init(&iter, service->contexts);
779 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
780 gboolean f_awo = FALSE;
781 f_awo = _ps_context_get_alwayson_enable(value);
784 _ps_service_reset_connection_timer(value);
785 rv = _ps_service_activate_context(service, value);
786 ps_dbg_ex_co(_ps_service_ref_co_network(service), "return rv(%d)", rv);
794 gpointer _ps_service_return_default_context(gpointer object, int svc_cat_id)
798 ps_service_t *service = object;
800 g_return_val_if_fail(service != NULL, NULL);
802 g_hash_table_iter_init(&iter, service->contexts);
803 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
804 gboolean b_default = FALSE;
805 b_default = _ps_context_get_default_context(value, svc_cat_id);
815 int _ps_service_update_roaming_apn(gpointer object, const char* apn_str)
820 ps_service_t *service = object;
822 g_return_val_if_fail(service != NULL, TCORE_RETURN_FAILURE);
824 g_hash_table_iter_init(&iter, service->contexts);
825 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
826 CoreObject *co_context = NULL;
827 int role = CONTEXT_ROLE_UNKNOWN;
828 char *tmp_apn = NULL, *path = NULL;
830 co_context = (CoreObject *)_ps_context_ref_co_context(value);
831 role = tcore_context_get_role(co_context);
832 tmp_apn = tcore_context_get_apn(co_context);
833 path = _ps_context_ref_path(value);
835 if(role == CONTEXT_ROLE_INTERNET || role == CONTEXT_ROLE_MMS) {
836 dbg("context[%s]}, role[%d], apn[%s] -> apn[%s]", path, role, tmp_apn, apn_str);
837 tcore_context_set_apn(co_context, apn_str);
838 tcore_ps_deactivate_context(service->co_ps, co_context, NULL);
846 gboolean _ps_service_processing_network_event(gpointer object, gboolean ps_attached, gboolean roaming)
848 ps_service_t *service = object;
849 CoreObject *co_network = NULL;
850 gboolean prev_roaming_status;
851 g_return_val_if_fail(service != NULL, FALSE);
854 prev_roaming_status = _ps_service_get_roaming(service);
856 co_network = _ps_service_ref_co_network(service);
857 _ps_service_set_ps_attached(service, ps_attached);
858 _ps_service_set_roaming(service, roaming);
859 _ps_update_cellular_state_key(service);
860 /* Need to set 'Attach APN' for 'ESM Attach' if ps_status is available */
862 __ps_service_set_attach_apn(service);
864 if(prev_roaming_status != _ps_service_get_roaming(service)) {
865 gboolean roaming_allowed = FALSE;
866 roaming_allowed = _ps_modem_get_data_roaming_allowed(service->p_modem);
867 if(!roaming_allowed && roaming) {
868 ps_dbg_ex_co(co_network, "Roaming allowed (%d), Roaming status (%d)", roaming_allowed, roaming);
869 _ps_service_disconnect_contexts(service);
874 if(service->ps_attached)
875 _ps_service_connect_default_context(service);
880 gboolean _ps_service_set_connected(gpointer object, gpointer cstatus, gboolean enabled)
885 gboolean def_awo = FALSE, b_def_conn = FALSE;
886 gpointer def_conn = NULL;
887 gpointer requested_conn = NULL;
889 ps_service_t *service = NULL;
890 struct tnoti_ps_call_status *call_status = NULL;
891 CoreObject * co_network;
892 // gpointer pre_def_conn = NULL;
894 service = (ps_service_t *) object;
895 co_network = _ps_service_ref_co_network(service);
896 call_status = (struct tnoti_ps_call_status *)cstatus;
898 if(enabled && service->initial_pdp_conn == FALSE) {
899 ps_dbg_ex_co(co_network, "Initial PDP connection.");
900 service->initial_pdp_conn = TRUE;
903 g_hash_table_iter_init(&iter, service->contexts);
904 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
906 gboolean b_tmp_def = FALSE;
907 CoreObject *context = NULL;
908 gpointer b_user_data = NULL;
910 context = _ps_context_ref_co_context(value);
911 tmp_cid = tcore_context_get_id(context);
913 if (tmp_cid != call_status->context_id) continue;
915 //if there is default context in disconnected cid, it has to retry auto connection
916 b_tmp_def = _ps_context_get_default_context(value, CONTEXT_ROLE_INTERNET);
918 b_def_conn = b_tmp_def;
921 //if disconnected connection has the user data, it is a priority connection.
922 b_user_data = _ps_context_get_user_data(value);
925 requested_conn = b_user_data;
931 ps_dbg_ex_co(co_network, "Reset socket connections.");
933 tcore_ps_clear_context_id(service->co_ps, context);
934 ipv4 = tcore_context_get_ipv4_addr(context);
935 tcore_util_reset_ipv4_socket(tcore_context_get_ipv4_devname(context), (const char*)ipv4);
938 _ps_context_set_connected(value, enabled);
941 //connect to request profile
942 if(!enabled && requested_conn){
943 ps_dbg_ex_co(co_network, "connect to request profile (%p)", requested_conn);
944 _ps_connection_hdlr(requested_conn);
945 _ps_service_reset_connection_timer(def_conn);
946 _ps_context_reset_user_data(def_conn);
950 //default context and always on is true. - request to connect
952 def_conn = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
953 def_awo = _ps_context_get_alwayson_enable(def_conn);
956 ps_dbg_ex_co(co_network, "there is no always on connection");
960 //always on TRUE and default connection - NORMAL RETRY
961 //always on TRUE and no default connection - WAIT 5 Secs for retry from application
964 _ps_service_connection_timer(service, def_conn);
968 //disconnect from user intention
969 #if defined(CONNECT_DEFAULT_CONNECTION_WITHOUT_TIMER)
970 if(call_status->result == 2000) {
971 ps_dbg_ex_co(co_network, "user intended disconnect / connect default connection without timer");
972 __ps_service_connetion_timeout_handler(service->timer_src, def_conn);
976 //with unexpected disconnection from network/me
977 _ps_service_set_retry_timeout_value(service, TIMEOUT_DEFAULT);
978 _ps_service_connection_timer(service, def_conn);
986 void _ps_service_set_ps_defined(gpointer *object, gboolean value, int cid)
988 ps_service_t *service = (ps_service_t*)object;
990 gpointer key, ps_context;
991 CoreObject *co_network;
992 CoreObject *co_context;
993 unsigned char context_id;
995 g_return_if_fail(service != NULL);
997 co_network = _ps_service_ref_co_network(service);
998 g_hash_table_iter_init(&iter, service->contexts);
999 while (g_hash_table_iter_next(&iter, &key, &ps_context) == TRUE) {
1000 co_context = _ps_context_ref_co_context(ps_context);
1001 context_id = tcore_context_get_id(co_context);
1002 if (context_id == cid) {
1003 gboolean b_only_attach;
1004 /* Set 'ps_defined' */
1005 _ps_context_set_ps_defined(ps_context, value);
1007 b_only_attach = _ps_context_get_only_attach(ps_context);
1008 if (b_only_attach) {
1009 dbg("Do not activate for only attach apn");
1010 _ps_context_set_only_attach(ps_context, FALSE);
1014 /* Activate if define is completed */
1016 ps_dbg_ex_co(co_network, "define is complete, activate context for cid(%d)", cid);
1017 if (_ps_service_activate_context(service, ps_context)
1018 == TCORE_RETURN_SUCCESS) {
1019 dbg("Successful activate context");
1020 tcore_ps_set_cid_active(service->co_ps, cid, TRUE);
1030 gboolean _ps_service_set_ps_attached(gpointer object, gboolean value)
1032 ps_service_t *service = object;
1033 g_return_val_if_fail(service != NULL, FALSE);
1035 service->ps_attached = value;
1036 ps_dbg_ex_co(_ps_service_ref_co_network(service), "service(%p) ps_attached(%d)", service, service->ps_attached);
1037 __ps_service_emit_property_changed_signal(service);
1042 gboolean _ps_service_get_restricted(gpointer object)
1044 ps_service_t *service = object;
1045 g_return_val_if_fail(service != NULL, FALSE);
1047 return service->restricted;
1050 gboolean _ps_service_set_restricted(gpointer object, gboolean value)
1052 ps_service_t *service = object;
1053 g_return_val_if_fail(service != NULL, FALSE);
1055 service->restricted = value;
1056 ps_dbg_ex_co(_ps_service_ref_co_network(service), "service(%p) restricted(%d)", service, service->restricted);
1058 _ps_update_cellular_state_key(service);
1062 gboolean _ps_service_set_number_of_pdn_cnt(gpointer object, gchar *operator)
1066 ps_service_t *service = object;
1067 g_return_val_if_fail(service != NULL, FALSE);
1068 ps_dbg_ex_co(_ps_service_ref_co_network(service), "Entered");
1069 num_of_pdn = _ps_context_get_number_of_pdn(operator, _ps_modem_ref_cp_name(_ps_service_ref_modem(object)));
1070 rv = tcore_ps_set_num_of_pdn(service->co_ps, num_of_pdn);
1072 if(rv != TCORE_RETURN_SUCCESS){
1073 ps_dbg_ex_co(_ps_service_ref_co_network(service), "error to get maximum number of pdn");
1079 gboolean _ps_service_get_roaming(gpointer object)
1081 ps_service_t *service = object;
1082 g_return_val_if_fail(service != NULL, FALSE);
1084 return service->roaming;
1087 gboolean _ps_service_set_roaming(gpointer object, gboolean value)
1089 ps_service_t *service = object;
1090 g_return_val_if_fail(service != NULL, FALSE);
1092 service->roaming = value;
1093 ps_dbg_ex_co(_ps_service_ref_co_network(service), "service(%p) roaming(%d)", service, service->roaming);
1094 __ps_service_emit_property_changed_signal(service);
1099 static void _indicator_cb_dns_reply(GObject *src, GAsyncResult *res, gpointer user_data)
1104 GError *error = NULL;
1106 list = g_resolver_lookup_by_name_finish((GResolver *)src, res, &error);
1108 dbg("fail to get dns resolving");
1110 dbg ("error:%d, %s", error->code, error->message);
1111 g_error_free (error);
1116 for (cur = list; cur; cur = cur->next) {
1118 str_addr = g_inet_address_to_string(addr);
1121 dbg("addr(%s)", str_addr);
1124 g_object_unref(cur->data);
1128 g_object_unref(src);
1133 gboolean _ps_service_set_access_technology(gpointer object,
1134 enum telephony_network_access_technology value)
1136 ps_service_t *service = object;
1137 CoreObject *co_network = NULL;
1138 enum telephony_network_access_technology p_act = 0;
1139 g_return_val_if_fail(service != NULL, FALSE);
1141 co_network = _ps_service_ref_co_network(service);
1142 p_act = service->act;
1143 service->act = value;
1144 ps_dbg_ex_co(co_network, "service(%p) P ACT(%d) Access Technology(%d)", service, p_act, service->act);
1146 if(p_act == NETWORK_ACT_LTE && (service->act >= NETWORK_ACT_GSM && service->act < NETWORK_ACT_LTE) ){
1147 GResolver *r = NULL;
1149 ps_dbg_ex_co(co_network, "send the dns pkt for keeping connection");
1151 r = g_resolver_get_default();
1152 g_resolver_lookup_by_name_async(r, "www.google.com", NULL, _indicator_cb_dns_reply, NULL);
1155 if(service->act > NETWORK_ACT_UNKNOWN && service->act < NETWORK_ACT_NOT_SPECIFIED){
1156 _ps_update_cellular_state_key(service);
1157 _ps_service_connect_default_context(service);
1163 enum telephony_ps_state _ps_service_check_cellular_state(gpointer object)
1165 gboolean state = FALSE;
1166 ps_service_t *service = object;
1167 g_return_val_if_fail(service != NULL, TELEPHONY_PS_NO_SERVICE);
1169 state = _ps_modem_get_flght_mode(service->p_modem);
1171 return TELEPHONY_PS_FLIGHT_MODE;
1174 state = _ps_modem_get_power(service->p_modem);
1176 return TELEPHONY_PS_NO_SERVICE;
1179 state = _ps_modem_get_sim_init(service->p_modem);
1181 return TELEPHONY_PS_NO_SERVICE;
1184 if(service->restricted){
1185 return TELEPHONY_PS_RESTRICTED_SERVICE;
1188 if(!service->ps_attached){
1189 return TELEPHONY_PS_NO_SERVICE;
1192 state = _ps_modem_get_data_allowed(service->p_modem);
1194 return TELEPHONY_PS_3G_OFF;
1197 state = _ps_modem_get_data_roaming_allowed(service->p_modem);
1198 if(service->roaming && !state){
1199 return TELEPHONY_PS_ROAMING_OFF;
1202 return TELEPHONY_PS_ON;
1204 static gboolean on_service_get_properties (PacketServiceService *obj_service,
1205 GDBusMethodInvocation *invocation,
1208 GVariant *gv = NULL;
1209 GVariantBuilder property;
1210 ps_dbg_ex_co(_ps_service_ref_co_network(user_data), "get service properties");
1212 gv = _ps_service_get_properties(user_data, &property);
1213 packet_service_service_complete_get_properties(obj_service, invocation, gv);
1218 on_service_get_context (PacketServiceService *obj_service,
1219 GDBusMethodInvocation *invocation,
1222 GVariantBuilder b_context;
1225 GHashTableIter iter;
1226 gpointer key, value;
1227 ps_service_t *service = user_data;
1228 CoreObject *co_network = _ps_service_ref_co_network(service);
1230 ps_dbg_ex_co(co_network, "modem get contexts interface");
1232 if (service->contexts == NULL) {
1233 ps_err_ex_co(co_network, "No context present for service");
1234 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
1238 g_variant_builder_init(&b_context, G_VARIANT_TYPE("a{sa{ss}}"));
1239 g_hash_table_iter_init(&iter, service->contexts);
1240 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1242 g_variant_builder_open(&b_context,G_VARIANT_TYPE("{sa{ss}}"));
1243 path = _ps_service_ref_path(value);
1245 g_variant_builder_add(&b_context, "s",g_strdup(path));
1246 if(FALSE == _ps_context_get_properties_handler(value, &b_context)){
1247 ps_err_ex_co(co_network, "Failed to get property");
1248 g_variant_builder_close(&b_context);
1249 FAIL_RESPONSE(invocation,PS_ERR_INTERNAL);
1252 g_variant_builder_close(&b_context);
1256 contexts = g_variant_builder_end(&b_context);
1257 packet_service_service_complete_get_contexts(obj_service, invocation,contexts);
1261 static void _ps_service_setup_interface(PacketServiceService *service, ps_service_t *service_data)
1264 g_signal_connect (service,
1265 "handle-get-properties",
1266 G_CALLBACK (on_service_get_properties),
1269 g_signal_connect (service,
1270 "handle-get-contexts",
1271 G_CALLBACK (on_service_get_context),