SET(SYSCONFDIR "/etc")
endif()
+IF(PREPAID_SIM_APN_SUPPORT)
+ ADD_DEFINITIONS("-DPREPAID_SIM_APN_SUPPORT")
+ENDIF(PREPAID_SIM_APN_SUPPORT)
+
# Set required packages
INCLUDE(FindPkgConfig)
pkg_check_modules(pkgs REQUIRED glib-2.0 gio-2.0 gio-unix-2.0 tcore iniparser vconf alarm-service libxml-2.0
+++ /dev/null
-/*
- * tel-plugin-packetservice
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: DongHoo Park <donghoo.park@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "ps_common.h"
-#include "ps_context.h"
-#include "ps_modem.h"
-#include "ps_service.h"
-#include "ps_master.h"
-#include "ps_tcore_interface.h"
-#include "ps_hook.h"
-
-#include <server.h>
-#include <plugin.h>
-#include <storage.h>
-#include <co_ps.h>
-#include <co_context.h>
-#include <co_modem.h>
-#include <co_sim.h>
-#include <type/network.h>
-#include <co_network.h>
-#include <user_request.h>
-#include <vconf.h>
-#include "ps_log.h"
-
-enum ps_call_state {
- PS_CALL_STATE_RESULT_OK = 0x00,
- PS_CALL_STATE_RESULT_CONNECT = 0x01,
- PS_CALL_STATE_RESULT_NO_CARRIER = 0x03
-};
-
-static void __ps_handle_prop_dnet_connection_status(CoreObject *co_ps, void *user_data)
-{
- const char *value = NULL;
- int context_id;
- guint index;
- ps_service_t *service = (ps_service_t *)user_data;
-
- value = tcore_object_ref_property(co_ps, PROP_DNET_CONNECTION_STATUS);
- ps_info_ex_svc(service, "Dnet connection status = %s", value);
-
- if (!value || strlen(value) == 0)
- return;
-
- if (g_strrstr(value, "disconnected")) {
- for (index = 0; index < g_slist_length(service->contexts); index++) {
- ps_context_t *context = g_slist_nth_data(service->contexts, index);
- CoreObject *co_context = _ps_context_ref_co_context(context);
- if (tcore_context_get_role(co_context) == CONTEXT_ROLE_INTERNET) {
- context_id = value[0];
- ps_info_ex_svc(service, "TNOTI_PS_CALL_STATUS - CID: [%d] State: [%d]", context_id, PS_CALL_STATE_RESULT_NO_CARRIER);
- _ps_context_set_ps_defined(context, FALSE);
- tcore_ps_set_cid_active(co_ps, context_id, FALSE);
- tcore_ps_set_cid_connected(co_ps, context_id, FALSE);
- _ps_context_set_connected(context, FALSE);
- break;
- }
- }
- }
-}
-
-static gboolean __ps_on_prop_changed(CoreObject *co_ps, const void *event_info,
- void *user_data)
-{
- GSList *key = (GSList *)event_info;
-
- if (CORE_OBJECT_KEY_FIND(key, PROP_DNET_CONNECTION_STATUS))
- __ps_handle_prop_dnet_connection_status(co_ps, user_data);
- return TRUE;
-}
-
-static void __ps_modem_cp_reset_handler(ps_modem_t *modem)
-{
- unsigned int index;
-#ifdef TIZEN_SUPPORT_VOLTE
- enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
-#endif
-
- ps_info_ex_modem(modem, "disconnect all contexts");
- /* send deactivation request to clear resources. */
- for (index = 0; index < g_slist_length(modem->contexts); index++) {
- ps_context_t *context = g_slist_nth_data(modem->contexts, index);
- ps_service_t *service = _ps_context_ref_service(context);
- CoreObject *co_context = _ps_context_ref_co_context(context);
- if (service == NULL)
- continue;
-#ifdef TIZEN_SUPPORT_VOLTE
- role = tcore_context_get_role(co_context);
- ps_info_ex_modem(modem, "role(%d)", role);
- if (role == CONTEXT_ROLE_IMS && !tcore_network_get_ims_on_deregistering(_ps_service_ref_co_network(service))) {
- if (_ps_context_deregister_ims(context) == TCORE_RETURN_SUCCESS)
- tcore_context_set_state(co_context, CONTEXT_STATE_DEACTIVATED);
- }
-#endif
- tcore_ps_deactivate_context(_ps_service_ref_co_ps(service), co_context, NULL);
- tcore_context_set_state(co_context, CONTEXT_STATE_DEACTIVATED);
-
- //due to pendig UR needs to clear AP resources
- tcore_ps_clear_context_id(_ps_service_ref_co_ps(service), co_context);
- _ps_context_set_connected(context, FALSE);
-
- }
-#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
- /* check for any pending request in modem queue and respond with error */
- _ps_hook_cp_reset_send_pending_request_response(modem);
-
- /* reset modem flag */
- modem->hook_flag &= PS_NO_PENDING_REQUEST;
-#endif
-}
-
-#ifdef PREPAID_SIM_APN_SUPPORT
-static void __on_call_status_for_prepaid_sim(ps_service_t *service, ps_context_t *def_context, ps_modem_t *modem)
-{
- unsigned char prepaid_cid = 0;
- ps_context_t *prepaid_def_context = NULL;
- unsigned char def_cid = 0;
-
- if (!service) {
- ps_err_ex_svc(service, "service does not exist");
- return;
- }
-
- if (!modem) {
- ps_err_ex_modem(modem, "modem does not exist");
- return;
- }
-
- if (def_context == NULL) {
- def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
- if (def_context) {
- CoreObject *co_context = NULL;
- co_context = _ps_context_ref_co_context(def_context);
- def_cid = tcore_context_get_id(co_context);
- }
- }
-
- prepaid_def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_PREPAID_INTERNET);
- ps_dbg_ex_modem(modem, "prepaid_def_context[%p]", prepaid_def_context);
- if (prepaid_def_context) {
- CoreObject *co_context = NULL;
- co_context = _ps_context_ref_co_context(prepaid_def_context);
- prepaid_cid = tcore_context_get_id(co_context);
- }
- ps_dbg_ex_modem(modem, "prepaid_cid[%d]", prepaid_cid);
-
- /* Has prepaid APN */
- if (prepaid_def_context) {
- ps_master_t * master = NULL;
- ps_context_t *context = NULL;
- int rv = 0;
-
- ps_dbg_ex_modem(modem, "Context id: %d", cstatus->context_id);
- ps_dbg_ex_modem(modem, "retry: %s", retry ? "TRUE" : "FALSE");
-
- if (cstatus->context_id == def_cid) {
- ps_dbg_ex_modem(modem, "Resetting connection time for default context");
- _ps_service_reset_connection_timer(def_context);
-
- /* Connect to default prepaid internet */
- rv = _ps_service_connect_default_prepaid_context(service);
- ps_dbg_ex_modem(modem, "prepaid internet connect - rv[%d]", rv);
- } else if (cstatus->context_id == prepaid_cid) {
- /* Reset connection */
- ps_dbg_ex_modem(modem, "Resetting connection time for prepaid internet context");
- _ps_service_reset_connection_timer(prepaid_def_context);
-
- /* Connect to default internet */
- rv = _ps_service_connect_default_context(service);
- ps_dbg_ex_modem(modem, "default internet connect - rv[%d]", rv);
- }
-
- /* Reset Last connected, Profile ID and Operator vconf keys. */
- ps_dbg_ex_modem(modem, "Reset vconf keys...");
- master = _ps_modem_ref_master(modem);
- _ps_master_set_storage_value_string(master, STORAGE_KEY_TELEPHONY_LAST_CONNECTED_CONTEXT_PLMN, NULL);
- /* Get context*/
- context = _ps_service_return_context_by_cid(service, cstatus->context_id);
- ps_dbg_ex_modem(modem, "context[%p]", context);
- if (context) {
- /* Set profile ID */
- ps_dbg_ex_modem(modem, "Reset profile id");
- _ps_master_set_storage_value_int(master, STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_PROFILE_ID, -1);
- /* set vconf last connected profile */
- ps_dbg_ex_modem(modem, "set vconf last connected profile to FALSE");
- _ps_master_set_storage_value_bool(master, STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_BOOL, FALSE);
- }
- }
-
-}
-#endif
-
-static void __on_hook_status_NO_carrier(ps_modem_t *modem, ps_service_t *service,
- CoreObject *co_ps, struct tnoti_ps_call_status *cstatus)
-{
- ps_context_t *def_context = NULL, *ims_context = NULL;
- unsigned char def_cid = 0, ims_cid = 0;
- int value = 0;
- gboolean retry = TRUE;
-
- if (!modem || !service || !cstatus)
- return;
-
- retry = ps_util_check_permanent_reject_cause(cstatus->result, _ps_modem_get_roaming(modem));
- /* if retry not permitted by network */
- if (FALSE == retry) {
- ps_dbg_ex_modem(modem, "DO NOT RETRY NETWORK CONNECTION AUTOMATICALLY");
- ps_info_ex_modem(modem, "permanent reject cause (%d), roaming(%d)", cstatus->result, _ps_modem_get_roaming(modem));
-
- def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
- if (def_context) {
- CoreObject *co_context = _ps_context_ref_co_context(def_context);
- def_cid = tcore_context_get_id(co_context);
- }
-
- ims_context = _ps_service_return_default_context(service, CONTEXT_ROLE_IMS);
- if (ims_context) {
- CoreObject *co_context = _ps_context_ref_co_context(ims_context);
- ims_cid = tcore_context_get_id(co_context);
- }
- }
-
- _ps_service_set_ps_defined(service, FALSE, cstatus->context_id);
- tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
- tcore_ps_set_cid_connected(co_ps, cstatus->context_id, FALSE);
- _ps_service_set_connected(service, cstatus, FALSE);
-
- if (FALSE == tcore_ps_any_internet_mms_tethering_context_activating_activated(co_ps, &value)) {
- ps_dbg_ex_modem(modem, "No context open connections, publish disconnected signal");
-#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
- /* Handle any pending request if present */
- modem = _ps_service_ref_modem(service);
- _ps_hook_send_pending_user_request(modem);
-#endif
- /* Ensured that set_reset_profile is always done default thread's context */
- if (_ps_modem_get_reset_profile(modem) == TRUE) {
- /* Initiate Reset Profile */
- ps_info_ex_modem(modem, "Profiles are being reset");
- /* Shouldn't invoke set profile directly, as it will remove hooks registered to server while being hook callback*/
- if (NULL == _ps_modem_get_profile_reset_gsource(modem)) {
- GSource *gsource = NULL;
- gsource = ps_util_gsource_dispatch(g_main_context_default(), G_PRIORITY_LOW, (GSourceFunc)_ps_modem_initiate_reset_profile, modem);
- _ps_modem_set_profile_reset_gsource(modem, gsource);
- }
- }
- }
-
-#ifdef PREPAID_SIM_APN_SUPPORT
- __on_call_status_for_prepaid_sim(service, def_context, modem);
-#endif
-
- ps_info_ex_modem(modem, "Any context activating or activated [%d]", value);
- if (FALSE == retry) {
- if (cstatus->context_id == def_cid) {
- _ps_service_reset_connection_timer(def_context);
- _ps_context_set_alwayson_enable(def_context, FALSE);
- } else if (cstatus->context_id == ims_cid) {
- _ps_service_reset_connection_timer(ims_context);
- _ps_context_set_alwayson_enable(ims_context, FALSE);
- }
- }
-}
-
-static enum tcore_hook_return __on_hook_call_status(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_modem_t *modem = NULL;
- ps_service_t *service = user_data;
- CoreObject *co_network;
- CoreObject *co_ps = NULL;
- GSList *co_list;
-
- gboolean b_data_allowed = FALSE;
- gboolean b_roaming_checker = TRUE;
- gboolean b_mms_checker = FALSE;
- gboolean b_ims_checker = FALSE;
- gboolean b_allowed_on_data_off = FALSE;
-
- struct tnoti_ps_call_status *cstatus = data;
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
-
- co_network = _ps_service_ref_co_network(service);
- co_ps = _ps_service_ref_co_ps(service);
- if (co_ps != source) {
- ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
-
- modem = _ps_service_ref_modem(service);
- if (!modem) {
- ps_err_ex_modem(modem, "modem does not exist");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
-
- b_data_allowed = _ps_modem_get_data_allowed(modem);
-
- co_list = tcore_ps_ref_context_by_id(co_ps, cstatus->context_id);
- for (; co_list; co_list = co_list->next) {
- CoreObject *co_context = NULL;
- enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
-
- co_context = co_list->data;
- role = tcore_context_get_role(co_context);
-
- if (role == CONTEXT_ROLE_MMS || role == CONTEXT_ROLE_PREPAID_MMS) {
- b_mms_checker = TRUE;
- break;
- }
- if (role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY || role == CONTEXT_ROLE_IMS_UT) {
- b_ims_checker = TRUE;
- break;
- }
- if (role == CONTEXT_ROLE_BIP || role == CONTEXT_ROLE_FOTA) {
- b_allowed_on_data_off = TRUE;
- break;
- }
- }
-
-#if !defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
- ps_dbg_ex_modem(modem, "csc runtime feature disabled");
- b_mms_checker = FALSE;
-#endif
-
- if (!b_ims_checker && (_ps_modem_get_roaming(modem)) && !(_ps_modem_get_data_roaming_allowed(modem))) {
- ps_info_ex_modem(modem, "roaming network is not allowed");
- b_roaming_checker = FALSE;
- }
-
- ps_info_ex_modem(modem, "data_allowed(%d) call status event cid(%d) state(%d) reason(%d)",
- b_data_allowed, cstatus->context_id, cstatus->state, cstatus->result);
-
- if (!b_roaming_checker || (!b_data_allowed && !b_mms_checker && !b_ims_checker && !b_allowed_on_data_off)) {
- ps_dbg_ex_modem(modem, "mismatched: roaming checker(%d) data_allowed(%d) mms_checker(%d) b_ims_checker(%d)",
- b_roaming_checker, b_data_allowed, b_mms_checker, b_ims_checker);
-
- if (cstatus->state == PS_CALL_STATE_RESULT_OK) {
- /*
- * If attach_apn_complete is FALSE, need to set TRUE.
- * In case of boot-up with roaming-SIM and Data Roaming option disabled,
- * although define process is triggered, 'attach_apn_complete' flag does not set TRUE.
- * So, when Data Roaming option is enabled, pdp activation is not triggered.
- */
- if (service->attach_apn_complete) {
- _ps_service_set_connected(service, cstatus, FALSE);
- tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
- } else {
- _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
- }
- return TCORE_HOOK_RETURN_CONTINUE;
- } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) {
- _ps_service_set_connected(service, cstatus, TRUE);
- _ps_service_disconnect_contexts(service);
- return TCORE_HOOK_RETURN_CONTINUE;
- }
- }
-
- ps_dbg_ex_modem(modem, "service(%p) status(%d)", service, cstatus->state);
- if (cstatus->state == PS_CALL_STATE_RESULT_OK) { /* DEFINE */
- _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
- } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) { /* CONNECTED */
- TReturn rv;
-
- if (tcore_ps_get_cid_active(co_ps, cstatus->context_id) == FALSE) {
- ps_dbg_ex_modem(modem, "DDS scenario");
-
- /* De-activate context */
- rv = tcore_ps_deactivate_contexts(co_ps);
- if (rv != TCORE_RETURN_SUCCESS) {
- ps_err_ex_modem(modem, "fail to deactivation");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
- } else {
- gboolean ret = TRUE;
- gboolean need_deactivate = FALSE;
-
- ret = _ps_service_set_connected(service, cstatus, TRUE);
- tcore_ps_set_cid_connected(co_ps, cstatus->context_id, TRUE);
-
- if (ret == FALSE || (_ps_modem_get_reset_profile(modem) == TRUE))
- need_deactivate = TRUE;
-
-#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
- if (g_queue_get_length(_ps_hook_ref_work_queue(modem)))
- need_deactivate = TRUE;
-#endif
-
- if (need_deactivate) {
- ps_info_ex_modem(modem, "Special request present in queue or pending activation request");
-#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
- if (ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SEARCH) ||
- ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) ||
- ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_PLMN_SELECTION_MODE)) {
- GHashTableIter iter;
- gpointer key, tmp_service;
-
- ps_info_ex_modem(modem, "Network search/selection/cancel searchrequest is in queue");
- g_hash_table_iter_init(&iter, modem->services);
- while (g_hash_table_iter_next(&iter, &key, &tmp_service) == TRUE)
- _ps_service_disconnect_internet_mms_tethering_contexts(tmp_service);
- } else
-#endif
- {
- rv = tcore_ps_deactivate_contexts(co_ps);
- if (rv != TCORE_RETURN_SUCCESS) {
- ps_dbg_ex_modem(modem, "fail to deactivation");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
- }
- }
- }
- } else if (cstatus->state == PS_CALL_STATE_RESULT_NO_CARRIER) { /* DISCONNECTED-NO CARRIER */
- __on_hook_status_NO_carrier(modem, service, co_ps, cstatus);
- } /* disconnected case */
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_dedicated_bearerinfo(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- CoreObject *co_ps = NULL;
- struct tnoti_ps_dedicated_bearer_info *bearer_info = data;
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- co_ps = _ps_service_ref_co_ps(service);
- if (co_ps != source)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- _ps_service_set_context_bearerinfo(service, bearer_info);
- ps_info_ex_svc(service, "dedicated bearer information event");
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_default_data_subscription(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- const struct tnoti_network_default_data_subs *default_data_subs_info = data;
-
- if (default_data_subs_info->default_subs != (enum telephony_network_default_data_subs)tcore_object_ref_subscription_type(_ps_service_ref_co_ps(service)))
- return TCORE_HOOK_RETURN_CONTINUE;
-
- ps_info_ex_svc(service, "'default' data subscription information event");
- _ps_service_connect_default_context(service);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-static enum tcore_hook_return __on_hook_epdg_status(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- const struct tnoti_network_epdg_status *noti = (const struct tnoti_network_epdg_status *)data;
- gboolean available = FALSE;
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
- g_return_val_if_fail(noti != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- if ((noti->status == NETWORK_EPDG_STATUS_AVAILABLE) ||
- (noti->status == NETWORK_EPDG_STATUS_CONNECTED) ||
- (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)) {
- available = TRUE;
- }
-
- ps_info_ex_svc(service, "ePDG: [%s]", ((available == TRUE) ? "AVAILABLE" : "UNAVAILABLE"));
- _ps_service_set_epdg_status(service, available);
-
- if (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)
- _ps_service_set_epdg_ip_configuration(service, noti->cid, noti->ipv4_address, noti->ipv6_address);
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_ipconfiguration(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- CoreObject *co_ps = NULL;
- struct tnoti_ps_pdp_ipconfiguration *devinfo = data;
- char ipv4[16], ipv4_dns_1[16], ipv4_dns_2[16];
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
-
- co_ps = _ps_service_ref_co_ps(service);
- if (co_ps != source) {
- ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
-
- ps_info_ex_svc(service, "ip configuration event");
-
- /*
- * In case IPv4 address is available and DNS address
- * is NOT available, set -
- * DNS 1 - Google DNS
- * DNS 2 - Open DNS
- */
- snprintf(ipv4, 16, "%d.%d.%d.%d",
- devinfo->ip_address[0], devinfo->ip_address[1],
- devinfo->ip_address[2], devinfo->ip_address[3]);
- if (!g_str_equal(ipv4, "0.0.0.0")) {
- snprintf(ipv4_dns_1, 16, "%d.%d.%d.%d",
- devinfo->primary_dns[0], devinfo->primary_dns[1],
- devinfo->primary_dns[2], devinfo->primary_dns[3]);
- if (g_str_equal(ipv4_dns_1, "0.0.0.0")) {
- ps_err_ex_svc(service, "[IPV4]primary dns address is 0");
-
- /* google dns 1st */
- devinfo->primary_dns[0] = 8;
- devinfo->primary_dns[1] = 8;
- devinfo->primary_dns[2] = 8;
- devinfo->primary_dns[3] = 8;
- }
-
- snprintf(ipv4_dns_2, 16, "%d.%d.%d.%d",
- devinfo->secondary_dns[0], devinfo->secondary_dns[1],
- devinfo->secondary_dns[2], devinfo->secondary_dns[3]);
- if (g_str_equal(ipv4_dns_2, "0.0.0.0")) {
- /* open dns 2nd */
- ps_err_ex_svc(service, "[IPV4]secondary dns address is 0");
- devinfo->secondary_dns[0] = 208;
- devinfo->secondary_dns[1] = 67;
- devinfo->secondary_dns[2] = 222;
- devinfo->secondary_dns[3] = 222;
- }
- }
-
- /*
- * In case IPv6 address is available and DNS address
- * is NOT available, set -
- * DNS 1 - Google DNS
- * DNS 2 - Open DNS
- */
- if (devinfo->ipv6_address != NULL) {
- if (devinfo->ipv6_primary_dns == NULL) {
- ps_err_ex_svc(service, "[IPV6]primary dns address is 0");
- devinfo->ipv6_primary_dns = g_strdup("2001:4860:4860::8888");
-
- }
- if (devinfo->ipv6_secondary_dns == NULL) {
- ps_err_ex_svc(service, "[IPV6]secondary dns address is 0");
- devinfo->ipv6_secondary_dns = g_strdup("2620:0:ccc::2");
- }
- }
-
- _ps_service_set_context_devinfo(service, devinfo);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_powered(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
-{
- ps_modem_t *modem = user_data;
- CoreObject *co_modem;
- struct tnoti_modem_power *modem_power = data;
- int power = PS_MODEM_STATE_UNKNOWN;
-
- CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE);
-
- g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
- g_return_val_if_fail(modem_power != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- co_modem = _ps_modem_ref_co_modem(modem);
- if (co_modem != source) {
- ps_dbg_ex_modem(modem, "Notification for other modem!");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
-
- ps_info_ex_modem(modem, "powered event called: state [%d]", modem_power->state);
-
- switch (modem_power->state) {
- case MODEM_STATE_ONLINE:
- power = PS_MODEM_STATE_ONLINE;
- break;
-
- case MODEM_STATE_LOW:
- power = PS_MODEM_STATE_LOW;
- break;
-
- case MODEM_STATE_ERROR:
- case MODEM_STATE_RESET:
- /* Reset hook flag in any present */
- __ps_modem_cp_reset_handler(modem);
- break;
-
- default:
- ps_warn_ex_modem(modem, "Unhandled modem power event.");
- break;
- }
-
- if (power != PS_MODEM_STATE_UNKNOWN)
- _ps_modem_processing_power_enable(modem, power);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_flight(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
-{
- ps_modem_t *modem = user_data;
- struct tnoti_modem_flight_mode *modem_flight = data;
-
- g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
- ps_info_ex_modem(modem, "flight mode event called");
-
- _ps_modem_processing_flight_mode(modem, modem_flight->enable);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_net_register(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- gboolean ps_attached = FALSE;
- struct tnoti_network_registration_status *regist_status = data;
- CoreObject *co_network;
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- co_network = _ps_service_ref_co_network(service);
- if (co_network != source)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- if (regist_status->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
- ps_attached = TRUE;
-
- _ps_modem_set_roaming(_ps_service_ref_modem(service), regist_status->roaming_status);
- _ps_service_processing_network_event(service, ps_attached, regist_status->roaming_status);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_net_change(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- struct tnoti_network_change *network_change = data;
- CoreObject *co_network;
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- co_network = _ps_service_ref_co_network(service);
- if (co_network != source)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- ps_dbg_ex_svc(service, "plmn(%s) act(%d)", network_change->plmn, network_change->act);
- _ps_service_set_access_technology(service, network_change->act);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_net_restricted_state(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data,
- void *user_data)
-{
- ps_service_t *service = user_data;
- struct tnoti_network_restricted_state *network_restricted = data;
- CoreObject *co_network;
-
- g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- co_network = _ps_service_ref_co_network(service);
- if (co_network != source)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- ps_dbg_ex_svc(service, "network restricted state(%d)", network_restricted->restricted_state);
- _ps_service_set_restricted(service, ((network_restricted->restricted_state & NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static enum tcore_hook_return __on_hook_sim_init(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
-{
- struct tnoti_sim_status *sim_data = data;
- ps_modem_t *modem = user_data;
- const gchar *cp_name, *source_cp_name;
-
- ps_info_ex_modem(modem, "sim init event called");
-
- g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
-
- cp_name = _ps_modem_ref_cp_name(modem);
- source_cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
- if (g_strcmp0(cp_name, source_cp_name) != 0) {
- ps_dbg_ex_modem(modem, "Received notification for different Subscription - neglecting the notification!!!");
- return TCORE_HOOK_RETURN_CONTINUE;
- }
-
- ps_info_ex_modem(modem, "sim status is (%d)", sim_data->sim_status);
-
- switch (sim_data->sim_status) {
- case SIM_STATUS_INITIALIZING:
- break;
-
- case SIM_STATUS_INIT_COMPLETED: {
- struct tel_sim_imsi *sim_imsi = NULL;
- enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
- sim_type = tcore_sim_get_type(source);
-
- if (sim_type == SIM_TYPE_NVSIM) {
- ps_info_ex_modem(modem, "initial boot from CDMA network.");
- _ps_modem_processing_sim_complete(modem, TRUE, PS_CDMA_DUMMY_PROFILE_PLMN);
- } else {
- sim_imsi = tcore_sim_get_imsi(source);
- _ps_modem_processing_sim_complete(modem, TRUE, sim_imsi->plmn);
- g_free(sim_imsi);
- }
- }
- break;
-
- case SIM_STATUS_CARD_ERROR: /* FALLTHROUGH */
- case SIM_STATUS_CARD_REMOVED: /* FALLTHROUGH */
- case SIM_STATUS_CARD_CRASHED: /* FALLTHROUGH */
- case SIM_STATUS_CARD_POWEROFF:
- /* Set SIM complete FALSE, operator is not required */
- _ps_modem_processing_sim_complete(modem, FALSE, NULL);
- _ps_modem_processing_no_sim(modem);
- break;
-
- case SIM_STATUS_CARD_NOT_PRESENT:
- _ps_modem_processing_no_sim(modem);
- break;
-
- default:
- ps_dbg_ex_modem(modem, "Unhandled SIM state: [%d]", sim_data->sim_status);
- _ps_modem_processing_no_sim(modem);
- break;
- }
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-
-#ifdef TIZEN_SUPPORT_VOLTE
-static enum tcore_hook_return __on_hook_sim_refresh(Server *s, CoreObject *source,
- enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
-{
- struct tnoti_sim_refresh_stage *sim_data = data;
- ps_modem_t *modem = user_data;
-
- ps_info_ex_modem(modem, "sim stage is (%d)", sim_data->stage);
-
- if (sim_data->stage == SIM_REFRESH_START)
- _ps_modem_processing_sim_refresh(modem);
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-#endif
-
-enum tcore_hook_return __on_hook_modem_added(Server *s,
- CoreObject *source, enum tcore_notification_command command,
- unsigned int data_len, void *data, void *user_data)
-{
- ps_master_t *master = user_data;
- TcorePlugin *plg = data;
-
- if (FALSE == _ps_master_create_modems(master, plg))
- err("[%s] Failed to create modem", tcore_server_get_cp_name_by_plugin(plg));
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-enum tcore_hook_return __on_hook_modem_removed(Server *s,
- CoreObject *source, enum tcore_notification_command command,
- unsigned int data_len, void *data, void *user_data)
-{
- ps_master_t *master = user_data;
- TcorePlugin *plg = data;
-
- if (FALSE == _ps_master_destroy_modem(master, plg))
- err("Failed to destroy modem[%s]", tcore_server_get_cp_name_by_plugin(plg));
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-gboolean _ps_get_co_modem_values(ps_modem_t *modem)
-{
- TcorePlugin *plg;
- CoreObject *co_modem = NULL;
- CoreObject *co_sim = NULL;
- ps_modem_t *ps_modem = modem;
-
- gboolean sim_init = FALSE, flight_mode = FALSE;
- enum modem_state modem_power_state = MODEM_STATE_UNKNOWN;
- int sim_status = 0;
- enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
- struct tel_sim_imsi *sim_imsi = NULL;
- int power = PS_MODEM_STATE_UNKNOWN;
-
- g_return_val_if_fail(ps_modem != NULL, FALSE);
-
- co_modem = _ps_modem_ref_co_modem(ps_modem);
- if (!co_modem)
- return FALSE;
-
- plg = tcore_object_ref_plugin(co_modem);
- if (!plg)
- return FALSE;
-
- co_sim = tcore_plugin_ref_core_object(plg, CORE_OBJECT_TYPE_SIM);
-
- sim_status = tcore_sim_get_status(co_sim);
- if (sim_status == SIM_STATUS_INIT_COMPLETED)
- sim_init = TRUE;
-
- sim_imsi = tcore_sim_get_imsi(co_sim);
- flight_mode = tcore_modem_get_flight_mode_state(co_modem);
- tcore_modem_get_modem_power_state(co_modem, &modem_power_state);
-
- switch (modem_power_state) {
- case MODEM_STATE_ONLINE:
- power = PS_MODEM_STATE_ONLINE;
- break;
-
- case MODEM_STATE_LOW:
- power = PS_MODEM_STATE_LOW;
- break;
-
- case MODEM_STATE_ERROR:
- case MODEM_STATE_RESET:
- default:
- ps_warn_ex_modem(modem, "Unhandled modem power event.");
- break;
- }
-
- _ps_modem_processing_flight_mode(ps_modem, flight_mode);
- if (power != PS_MODEM_STATE_UNKNOWN)
- _ps_modem_processing_power_enable(modem, power);
-
- sim_type = tcore_sim_get_type(co_sim);
-
- if (sim_type == SIM_TYPE_NVSIM)
- _ps_modem_processing_sim_complete(ps_modem, sim_init, PS_CDMA_DUMMY_PROFILE_PLMN);
- else
- _ps_modem_processing_sim_complete(ps_modem, sim_init, sim_imsi->plmn);
- g_free(sim_imsi);
- return TRUE;
-}
-
-gboolean _ps_get_co_network_values(ps_service_t *service)
-{
- CoreObject *co_network = NULL;
- gboolean ps_attached = FALSE;
- gint ps_restricted = 0;
-
- enum telephony_network_service_domain_status ps_status;
- enum telephony_network_access_technology act;
-
- g_return_val_if_fail(service != NULL, FALSE);
-
- co_network = _ps_service_ref_co_network(service);
- ps_dbg_ex_svc(service, "Entered ");
-
- tcore_network_get_service_status(co_network, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
- tcore_network_get_access_technology(co_network, &act);
-
- if (ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
- ps_attached = TRUE;
-
- ps_restricted = tcore_network_get_restricted_state(co_network);
-
- _ps_service_set_restricted(service, ((ps_restricted == NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
- _ps_service_set_roaming(service, tcore_network_get_roaming_state(co_network));
- _ps_service_set_ps_attached(service, ps_attached);
- _ps_service_set_access_technology(service, act);
-
- return TRUE;
-}
-
-gboolean _ps_add_co_ps_event(ps_service_t *service)
-{
- Server *s;
- g_return_val_if_fail(service != NULL, FALSE);
- ps_dbg_ex_svc(service, "Entered ");
- s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
- tcore_server_add_notification_hook(s, TNOTI_PS_CALL_STATUS, __on_hook_call_status, service);
- tcore_server_add_notification_hook(s, TNOTI_PS_PDP_IPCONFIGURATION, __on_hook_ipconfiguration, service);
- tcore_server_add_notification_hook(s, TNOTI_PS_DEDICATED_BEARER_INFO, __on_hook_dedicated_bearerinfo, service);
- tcore_server_add_notification_hook(s, TNOTI_NETWORK_DEFAULT_DATA_SUBSCRIPTION, __on_hook_default_data_subscription, service);
-// tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_BACKOFF_TIMER, __on_hook_gprs_backoff_timer, service);
-// tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_NAS_TIMER, __on_hook_gprs_nas_timer, service);
- tcore_server_add_notification_hook(s, TNOTI_NETWORK_EPDG_STATUS, __on_hook_epdg_status, service);
- tcore_object_add_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed, service);
- return TRUE;
-}
-
-gboolean _ps_add_co_network_event(ps_service_t *service)
-{
- Server *s;
-
- g_return_val_if_fail(service != NULL, FALSE);
-
- s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
-
- tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, __on_hook_net_register, service);
- tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, __on_hook_net_change, service);
- tcore_server_add_notification_hook(s, TNOTI_NETWORK_RESTRICTED_STATE, __on_hook_net_restricted_state, service);
-
- return TRUE;
-}
-
-gboolean _ps_add_co_modem_event(ps_modem_t *modem)
-{
- Server *s = NULL;
-
- g_return_val_if_fail(modem != NULL, FALSE);
-
- s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
-
- tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER, __on_hook_powered, modem);
- tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE, __on_hook_flight, modem);
- tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, __on_hook_sim_init, modem);
-// tcore_server_add_notification_hook(s, TNOTI_SIM_REFRESH_STAGE, __on_hook_sim_refresh, modem);
-#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
- _ps_hook_add_modem_hooks(modem);
-#endif
- return TRUE;
-}
-
-gboolean _ps_free_co_ps_event(ps_service_t *service)
-{
- Server *s;
- g_return_val_if_fail(service != NULL, FALSE);
- ps_dbg_ex_svc(service, "Entered ");
- s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
- tcore_object_del_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed);
- tcore_server_remove_notification_hook(s, __on_hook_call_status);
- tcore_server_remove_notification_hook(s, __on_hook_ipconfiguration);
- tcore_server_remove_notification_hook(s, __on_hook_dedicated_bearerinfo);
- tcore_server_remove_notification_hook(s, __on_hook_default_data_subscription);
-// tcore_server_remove_notification_hook(s, __on_hook_gprs_backoff_timer);
-// tcore_server_remove_notification_hook(s, __on_hook_gprs_nas_timer);
- tcore_server_remove_notification_hook(s, __on_hook_epdg_status);
- return TRUE;
-}
-
-gboolean _ps_free_co_network_event(ps_service_t *service)
-{
- Server *s;
- g_return_val_if_fail(service != NULL, FALSE);
- ps_dbg_ex_svc(service, "Entered");
- s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
- tcore_server_remove_notification_hook(s, __on_hook_net_register);
- tcore_server_remove_notification_hook(s, __on_hook_net_change);
- tcore_server_remove_notification_hook(s, __on_hook_net_restricted_state);
- return TRUE;
-}
-
-gboolean _ps_free_co_modem_event(ps_modem_t *modem)
-{
- Server *s;
- g_return_val_if_fail(modem != NULL, FALSE);
- s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
- tcore_server_remove_notification_hook(s, __on_hook_powered);
- tcore_server_remove_notification_hook(s, __on_hook_flight);
- tcore_server_remove_notification_hook(s, __on_hook_sim_init);
-// tcore_server_remove_notification_hook(s, __on_hook_sim_refresh);
- return TRUE;
-}
-
-gboolean _ps_update_cellular_state_key(ps_service_t *service)
-{
- int current_state = 0;
- int stored_state = 0;
- ps_modem_t *modem;
- ps_master_t *master;
- ps_subs_type subs_type;
- int selected_sim = -1;
-
- g_return_val_if_fail(service != NULL, FALSE);
-
- modem = _ps_service_ref_modem(service);
- master = _ps_modem_ref_master(modem);
- subs_type = _ps_modem_get_subs_type(modem);
-
- ps_dbg_ex_svc(service, "Update cellular state for [SIM%d]", subs_type + 1);
-
- selected_sim = _ps_master_get_storage_value_int(master, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
- if ((selected_sim != -1) && (selected_sim != (int)subs_type)) {
- ps_warn_ex_svc(service, "Update for only [SIM%d] selected by Setting", selected_sim + 1);
- return FALSE;
- }
-
- current_state = _ps_service_check_cellular_state(service);
-
- if (tcore_modem_get_flight_mode_state(modem->co_modem) == TRUE)
- current_state = TELEPHONY_PS_FLIGHT_MODE;
-
- stored_state = _ps_master_get_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE);
- if (current_state != stored_state) {
- ps_info_ex_svc(service, "Cellular state, current: [%d], stored: [%d]", current_state, stored_state);
- _ps_master_set_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE, current_state);
- }
-
- return TRUE;
-}
--- /dev/null
+/*
+ * tel-plugin-packetservice
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: DongHoo Park <donghoo.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "ps_common.h"
+#include "ps_context.h"
+#include "ps_modem.h"
+#include "ps_service.h"
+#include "ps_master.h"
+#include "ps_tcore_interface.h"
+#include "ps_hook.h"
+
+#include <server.h>
+#include <plugin.h>
+#include <storage.h>
+#include <co_ps.h>
+#include <co_context.h>
+#include <co_modem.h>
+#include <co_sim.h>
+#include <type/network.h>
+#include <co_network.h>
+#include <user_request.h>
+#include <vconf.h>
+#include "ps_log.h"
+
+enum ps_call_state {
+ PS_CALL_STATE_RESULT_OK = 0x00,
+ PS_CALL_STATE_RESULT_CONNECT = 0x01,
+ PS_CALL_STATE_RESULT_NO_CARRIER = 0x03
+};
+
+static void __ps_handle_prop_dnet_connection_status(CoreObject *co_ps, void *user_data)
+{
+ const char *value = NULL;
+ int context_id;
+ guint index;
+ ps_service_t *service = (ps_service_t *)user_data;
+
+ value = tcore_object_ref_property(co_ps, PROP_DNET_CONNECTION_STATUS);
+ ps_info_ex_svc(service, "Dnet connection status = %s", value);
+
+ if (!value || strlen(value) == 0)
+ return;
+
+ if (g_strrstr(value, "disconnected")) {
+ for (index = 0; index < g_slist_length(service->contexts); index++) {
+ ps_context_t *context = g_slist_nth_data(service->contexts, index);
+ CoreObject *co_context = _ps_context_ref_co_context(context);
+ if (tcore_context_get_role(co_context) == CONTEXT_ROLE_INTERNET) {
+ context_id = value[0];
+ ps_info_ex_svc(service, "TNOTI_PS_CALL_STATUS - CID: [%d] State: [%d]", context_id, PS_CALL_STATE_RESULT_NO_CARRIER);
+ _ps_context_set_ps_defined(context, FALSE);
+ tcore_ps_set_cid_active(co_ps, context_id, FALSE);
+ tcore_ps_set_cid_connected(co_ps, context_id, FALSE);
+ _ps_context_set_connected(context, FALSE);
+ break;
+ }
+ }
+ }
+}
+
+static gboolean __ps_on_prop_changed(CoreObject *co_ps, const void *event_info,
+ void *user_data)
+{
+ GSList *key = (GSList *)event_info;
+
+ if (CORE_OBJECT_KEY_FIND(key, PROP_DNET_CONNECTION_STATUS))
+ __ps_handle_prop_dnet_connection_status(co_ps, user_data);
+ return TRUE;
+}
+
+static void __ps_modem_cp_reset_handler(ps_modem_t *modem)
+{
+ unsigned int index;
+#ifdef TIZEN_SUPPORT_VOLTE
+ enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
+#endif
+
+ ps_info_ex_modem(modem, "disconnect all contexts");
+ /* send deactivation request to clear resources. */
+ for (index = 0; index < g_slist_length(modem->contexts); index++) {
+ ps_context_t *context = g_slist_nth_data(modem->contexts, index);
+ ps_service_t *service = _ps_context_ref_service(context);
+ CoreObject *co_context = _ps_context_ref_co_context(context);
+ if (service == NULL)
+ continue;
+#ifdef TIZEN_SUPPORT_VOLTE
+ role = tcore_context_get_role(co_context);
+ ps_info_ex_modem(modem, "role(%d)", role);
+ if (role == CONTEXT_ROLE_IMS && !tcore_network_get_ims_on_deregistering(_ps_service_ref_co_network(service))) {
+ if (_ps_context_deregister_ims(context) == TCORE_RETURN_SUCCESS)
+ tcore_context_set_state(co_context, CONTEXT_STATE_DEACTIVATED);
+ }
+#endif
+ tcore_ps_deactivate_context(_ps_service_ref_co_ps(service), co_context, NULL);
+ tcore_context_set_state(co_context, CONTEXT_STATE_DEACTIVATED);
+
+ //due to pendig UR needs to clear AP resources
+ tcore_ps_clear_context_id(_ps_service_ref_co_ps(service), co_context);
+ _ps_context_set_connected(context, FALSE);
+
+ }
+#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
+ /* check for any pending request in modem queue and respond with error */
+ _ps_hook_cp_reset_send_pending_request_response(modem);
+
+ /* reset modem flag */
+ modem->hook_flag &= PS_NO_PENDING_REQUEST;
+#endif
+}
+
+#ifdef PREPAID_SIM_APN_SUPPORT
+static void __on_call_status_for_prepaid_sim(ps_service_t *service, ps_context_t *def_context, ps_modem_t *modem, struct tnoti_ps_call_status *cstatus, gboolean retry)
+{
+ unsigned char prepaid_cid = 0;
+ ps_context_t *prepaid_def_context = NULL;
+ unsigned char def_cid = 0;
+
+ if (!service) {
+ ps_err_ex_svc(service, "service does not exist");
+ return;
+ }
+
+ if (!modem) {
+ ps_err_ex_modem(modem, "modem does not exist");
+ return;
+ }
+
+ if (def_context == NULL) {
+ def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
+ if (def_context) {
+ CoreObject *co_context = NULL;
+ co_context = _ps_context_ref_co_context(def_context);
+ def_cid = tcore_context_get_id(co_context);
+ }
+ }
+
+ prepaid_def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_PREPAID_INTERNET);
+ ps_dbg_ex_modem(modem, "prepaid_def_context[%p]", prepaid_def_context);
+ if (prepaid_def_context) {
+ CoreObject *co_context = NULL;
+ co_context = _ps_context_ref_co_context(prepaid_def_context);
+ prepaid_cid = tcore_context_get_id(co_context);
+ }
+ ps_dbg_ex_modem(modem, "prepaid_cid[%d]", prepaid_cid);
+
+ /* Has prepaid APN */
+ if (prepaid_def_context) {
+ ps_master_t * master = NULL;
+ ps_context_t *context = NULL;
+ int rv = 0;
+
+ ps_dbg_ex_modem(modem, "Context id: %d", cstatus->context_id);
+ ps_dbg_ex_modem(modem, "retry: %s", retry ? "TRUE" : "FALSE");
+
+ if (cstatus->context_id == def_cid) {
+ ps_dbg_ex_modem(modem, "Resetting connection time for default context");
+ _ps_service_reset_connection_timer(def_context);
+
+ /* Connect to default prepaid internet */
+ rv = _ps_service_connect_default_prepaid_context(service);
+ ps_dbg_ex_modem(modem, "prepaid internet connect - rv[%d]", rv);
+ } else if (cstatus->context_id == prepaid_cid) {
+ /* Reset connection */
+ ps_dbg_ex_modem(modem, "Resetting connection time for prepaid internet context");
+ _ps_service_reset_connection_timer(prepaid_def_context);
+
+ /* Connect to default internet */
+ rv = _ps_service_connect_default_context(service);
+ ps_dbg_ex_modem(modem, "default internet connect - rv[%d]", rv);
+ }
+
+ /* Reset Last connected, Profile ID and Operator vconf keys. */
+ ps_dbg_ex_modem(modem, "Reset vconf keys...");
+ master = _ps_modem_ref_master(modem);
+ _ps_master_set_storage_value_string(master, STORAGE_KEY_TELEPHONY_LAST_CONNECTED_CONTEXT_PLMN, NULL);
+ /* Get context*/
+ context = _ps_service_return_context_by_cid(service, cstatus->context_id);
+ ps_dbg_ex_modem(modem, "context[%p]", context);
+ if (context) {
+ /* Set profile ID */
+ ps_dbg_ex_modem(modem, "Reset profile id");
+ _ps_master_set_storage_value_int(master, STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_PROFILE_ID, -1);
+ /* set vconf last connected profile */
+ ps_dbg_ex_modem(modem, "set vconf last connected profile to FALSE");
+ _ps_master_set_storage_value_bool(master, STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_BOOL, FALSE);
+ }
+ }
+}
+#endif
+
+static void __on_hook_status_NO_carrier(ps_modem_t *modem, ps_service_t *service,
+ CoreObject *co_ps, struct tnoti_ps_call_status *cstatus)
+{
+ ps_context_t *def_context = NULL, *ims_context = NULL;
+ unsigned char def_cid = 0, ims_cid = 0;
+ int value = 0;
+ gboolean retry = TRUE;
+
+ if (!modem || !service || !cstatus)
+ return;
+
+ retry = ps_util_check_permanent_reject_cause(cstatus->result, _ps_modem_get_roaming(modem));
+ /* if retry not permitted by network */
+ if (FALSE == retry) {
+ ps_dbg_ex_modem(modem, "DO NOT RETRY NETWORK CONNECTION AUTOMATICALLY");
+ ps_info_ex_modem(modem, "permanent reject cause (%d), roaming(%d)", cstatus->result, _ps_modem_get_roaming(modem));
+
+ def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
+ if (def_context) {
+ CoreObject *co_context = _ps_context_ref_co_context(def_context);
+ def_cid = tcore_context_get_id(co_context);
+ }
+
+ ims_context = _ps_service_return_default_context(service, CONTEXT_ROLE_IMS);
+ if (ims_context) {
+ CoreObject *co_context = _ps_context_ref_co_context(ims_context);
+ ims_cid = tcore_context_get_id(co_context);
+ }
+ }
+
+ _ps_service_set_ps_defined(service, FALSE, cstatus->context_id);
+ tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
+ tcore_ps_set_cid_connected(co_ps, cstatus->context_id, FALSE);
+ _ps_service_set_connected(service, cstatus, FALSE);
+
+ if (FALSE == tcore_ps_any_internet_mms_tethering_context_activating_activated(co_ps, &value)) {
+ ps_dbg_ex_modem(modem, "No context open connections, publish disconnected signal");
+#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
+ /* Handle any pending request if present */
+ modem = _ps_service_ref_modem(service);
+ _ps_hook_send_pending_user_request(modem);
+#endif
+ /* Ensured that set_reset_profile is always done default thread's context */
+ if (_ps_modem_get_reset_profile(modem) == TRUE) {
+ /* Initiate Reset Profile */
+ ps_info_ex_modem(modem, "Profiles are being reset");
+ /* Shouldn't invoke set profile directly, as it will remove hooks registered to server while being hook callback*/
+ if (NULL == _ps_modem_get_profile_reset_gsource(modem)) {
+ GSource *gsource = NULL;
+ gsource = ps_util_gsource_dispatch(g_main_context_default(), G_PRIORITY_LOW, (GSourceFunc)_ps_modem_initiate_reset_profile, modem);
+ _ps_modem_set_profile_reset_gsource(modem, gsource);
+ }
+ }
+ }
+
+#ifdef PREPAID_SIM_APN_SUPPORT
+ __on_call_status_for_prepaid_sim(service, def_context, modem, cstatus, retry);
+#endif
+
+ ps_info_ex_modem(modem, "Any context activating or activated [%d]", value);
+ if (FALSE == retry) {
+ if (cstatus->context_id == def_cid) {
+ _ps_service_reset_connection_timer(def_context);
+ _ps_context_set_alwayson_enable(def_context, FALSE);
+ } else if (cstatus->context_id == ims_cid) {
+ _ps_service_reset_connection_timer(ims_context);
+ _ps_context_set_alwayson_enable(ims_context, FALSE);
+ }
+ }
+}
+
+static enum tcore_hook_return __on_hook_call_status(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_modem_t *modem = NULL;
+ ps_service_t *service = user_data;
+ CoreObject *co_ps = NULL;
+ GSList *co_list;
+
+ gboolean b_data_allowed = FALSE;
+ gboolean b_roaming_checker = TRUE;
+ gboolean b_mms_checker = FALSE;
+ gboolean b_ims_checker = FALSE;
+ gboolean b_allowed_on_data_off = FALSE;
+
+ struct tnoti_ps_call_status *cstatus = data;
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
+
+ co_ps = _ps_service_ref_co_ps(service);
+ if (co_ps != source) {
+ ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ modem = _ps_service_ref_modem(service);
+ if (!modem) {
+ ps_err_ex_modem(modem, "modem does not exist");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ b_data_allowed = _ps_modem_get_data_allowed(modem);
+
+ co_list = tcore_ps_ref_context_by_id(co_ps, cstatus->context_id);
+ for (; co_list; co_list = co_list->next) {
+ CoreObject *co_context = NULL;
+ enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
+
+ co_context = co_list->data;
+ role = tcore_context_get_role(co_context);
+
+ if (role == CONTEXT_ROLE_MMS || role == CONTEXT_ROLE_PREPAID_MMS) {
+ b_mms_checker = TRUE;
+ break;
+ }
+ if (role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY || role == CONTEXT_ROLE_IMS_UT) {
+ b_ims_checker = TRUE;
+ break;
+ }
+ if (role == CONTEXT_ROLE_BIP || role == CONTEXT_ROLE_FOTA) {
+ b_allowed_on_data_off = TRUE;
+ break;
+ }
+ }
+
+#if !defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
+ ps_dbg_ex_modem(modem, "csc runtime feature disabled");
+ b_mms_checker = FALSE;
+#endif
+
+ if (!b_ims_checker && (_ps_modem_get_roaming(modem)) && !(_ps_modem_get_data_roaming_allowed(modem))) {
+ ps_info_ex_modem(modem, "roaming network is not allowed");
+ b_roaming_checker = FALSE;
+ }
+
+ ps_info_ex_modem(modem, "data_allowed(%d) call status event cid(%d) state(%d) reason(%d)",
+ b_data_allowed, cstatus->context_id, cstatus->state, cstatus->result);
+
+ if (!b_roaming_checker || (!b_data_allowed && !b_mms_checker && !b_ims_checker && !b_allowed_on_data_off)) {
+ ps_dbg_ex_modem(modem, "mismatched: roaming checker(%d) data_allowed(%d) mms_checker(%d) b_ims_checker(%d)",
+ b_roaming_checker, b_data_allowed, b_mms_checker, b_ims_checker);
+
+ if (cstatus->state == PS_CALL_STATE_RESULT_OK) {
+ /*
+ * If attach_apn_complete is FALSE, need to set TRUE.
+ * In case of boot-up with roaming-SIM and Data Roaming option disabled,
+ * although define process is triggered, 'attach_apn_complete' flag does not set TRUE.
+ * So, when Data Roaming option is enabled, pdp activation is not triggered.
+ */
+ if (service->attach_apn_complete) {
+ _ps_service_set_connected(service, cstatus, FALSE);
+ tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
+ } else {
+ _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
+ }
+ return TCORE_HOOK_RETURN_CONTINUE;
+ } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) {
+ _ps_service_set_connected(service, cstatus, TRUE);
+ _ps_service_disconnect_contexts(service);
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+ }
+
+ ps_dbg_ex_modem(modem, "service(%p) status(%d)", service, cstatus->state);
+ if (cstatus->state == PS_CALL_STATE_RESULT_OK) { /* DEFINE */
+ _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
+ } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) { /* CONNECTED */
+ TReturn rv;
+
+ if (tcore_ps_get_cid_active(co_ps, cstatus->context_id) == FALSE) {
+ ps_dbg_ex_modem(modem, "DDS scenario");
+
+ /* De-activate context */
+ rv = tcore_ps_deactivate_contexts(co_ps);
+ if (rv != TCORE_RETURN_SUCCESS) {
+ ps_err_ex_modem(modem, "fail to deactivation");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+ } else {
+ gboolean ret = TRUE;
+ gboolean need_deactivate = FALSE;
+
+ ret = _ps_service_set_connected(service, cstatus, TRUE);
+ tcore_ps_set_cid_connected(co_ps, cstatus->context_id, TRUE);
+
+ if (ret == FALSE || (_ps_modem_get_reset_profile(modem) == TRUE))
+ need_deactivate = TRUE;
+
+#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
+ if (g_queue_get_length(_ps_hook_ref_work_queue(modem)))
+ need_deactivate = TRUE;
+#endif
+
+ if (need_deactivate) {
+ ps_info_ex_modem(modem, "Special request present in queue or pending activation request");
+#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
+ if (ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SEARCH) ||
+ ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) ||
+ ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_PLMN_SELECTION_MODE)) {
+ GHashTableIter iter;
+ gpointer key, tmp_service;
+
+ ps_info_ex_modem(modem, "Network search/selection/cancel searchrequest is in queue");
+ g_hash_table_iter_init(&iter, modem->services);
+ while (g_hash_table_iter_next(&iter, &key, &tmp_service) == TRUE)
+ _ps_service_disconnect_internet_mms_tethering_contexts(tmp_service);
+ } else
+#endif
+ {
+ rv = tcore_ps_deactivate_contexts(co_ps);
+ if (rv != TCORE_RETURN_SUCCESS) {
+ ps_dbg_ex_modem(modem, "fail to deactivation");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+ }
+ }
+ }
+ } else if (cstatus->state == PS_CALL_STATE_RESULT_NO_CARRIER) { /* DISCONNECTED-NO CARRIER */
+ __on_hook_status_NO_carrier(modem, service, co_ps, cstatus);
+ } /* disconnected case */
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_dedicated_bearerinfo(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ CoreObject *co_ps = NULL;
+ struct tnoti_ps_dedicated_bearer_info *bearer_info = data;
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ co_ps = _ps_service_ref_co_ps(service);
+ if (co_ps != source)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ _ps_service_set_context_bearerinfo(service, bearer_info);
+ ps_info_ex_svc(service, "dedicated bearer information event");
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_default_data_subscription(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ const struct tnoti_network_default_data_subs *default_data_subs_info = data;
+
+ if (default_data_subs_info->default_subs != (enum telephony_network_default_data_subs)tcore_object_ref_subscription_type(_ps_service_ref_co_ps(service)))
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ ps_info_ex_svc(service, "'default' data subscription information event");
+ _ps_service_connect_default_context(service);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+static enum tcore_hook_return __on_hook_epdg_status(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ const struct tnoti_network_epdg_status *noti = (const struct tnoti_network_epdg_status *)data;
+ gboolean available = FALSE;
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
+ g_return_val_if_fail(noti != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ if ((noti->status == NETWORK_EPDG_STATUS_AVAILABLE) ||
+ (noti->status == NETWORK_EPDG_STATUS_CONNECTED) ||
+ (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)) {
+ available = TRUE;
+ }
+
+ ps_info_ex_svc(service, "ePDG: [%s]", ((available == TRUE) ? "AVAILABLE" : "UNAVAILABLE"));
+ _ps_service_set_epdg_status(service, available);
+
+ if (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)
+ _ps_service_set_epdg_ip_configuration(service, noti->cid, noti->ipv4_address, noti->ipv6_address);
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_ipconfiguration(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ CoreObject *co_ps = NULL;
+ struct tnoti_ps_pdp_ipconfiguration *devinfo = data;
+ char ipv4[16], ipv4_dns_1[16], ipv4_dns_2[16];
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
+
+ co_ps = _ps_service_ref_co_ps(service);
+ if (co_ps != source) {
+ ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ ps_info_ex_svc(service, "ip configuration event");
+
+ /*
+ * In case IPv4 address is available and DNS address
+ * is NOT available, set -
+ * DNS 1 - Google DNS
+ * DNS 2 - Open DNS
+ */
+ snprintf(ipv4, 16, "%d.%d.%d.%d",
+ devinfo->ip_address[0], devinfo->ip_address[1],
+ devinfo->ip_address[2], devinfo->ip_address[3]);
+ if (!g_str_equal(ipv4, "0.0.0.0")) {
+ snprintf(ipv4_dns_1, 16, "%d.%d.%d.%d",
+ devinfo->primary_dns[0], devinfo->primary_dns[1],
+ devinfo->primary_dns[2], devinfo->primary_dns[3]);
+ if (g_str_equal(ipv4_dns_1, "0.0.0.0")) {
+ ps_err_ex_svc(service, "[IPV4]primary dns address is 0");
+
+ /* google dns 1st */
+ devinfo->primary_dns[0] = 8;
+ devinfo->primary_dns[1] = 8;
+ devinfo->primary_dns[2] = 8;
+ devinfo->primary_dns[3] = 8;
+ }
+
+ snprintf(ipv4_dns_2, 16, "%d.%d.%d.%d",
+ devinfo->secondary_dns[0], devinfo->secondary_dns[1],
+ devinfo->secondary_dns[2], devinfo->secondary_dns[3]);
+ if (g_str_equal(ipv4_dns_2, "0.0.0.0")) {
+ /* open dns 2nd */
+ ps_err_ex_svc(service, "[IPV4]secondary dns address is 0");
+ devinfo->secondary_dns[0] = 208;
+ devinfo->secondary_dns[1] = 67;
+ devinfo->secondary_dns[2] = 222;
+ devinfo->secondary_dns[3] = 222;
+ }
+ }
+
+ /*
+ * In case IPv6 address is available and DNS address
+ * is NOT available, set -
+ * DNS 1 - Google DNS
+ * DNS 2 - Open DNS
+ */
+ if (devinfo->ipv6_address != NULL) {
+ if (devinfo->ipv6_primary_dns == NULL) {
+ ps_err_ex_svc(service, "[IPV6]primary dns address is 0");
+ devinfo->ipv6_primary_dns = g_strdup("2001:4860:4860::8888");
+
+ }
+ if (devinfo->ipv6_secondary_dns == NULL) {
+ ps_err_ex_svc(service, "[IPV6]secondary dns address is 0");
+ devinfo->ipv6_secondary_dns = g_strdup("2620:0:ccc::2");
+ }
+ }
+
+ _ps_service_set_context_devinfo(service, devinfo);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_powered(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ ps_modem_t *modem = user_data;
+ CoreObject *co_modem;
+ struct tnoti_modem_power *modem_power = data;
+ int power = PS_MODEM_STATE_UNKNOWN;
+
+ CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE);
+
+ g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
+ g_return_val_if_fail(modem_power != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ co_modem = _ps_modem_ref_co_modem(modem);
+ if (co_modem != source) {
+ ps_dbg_ex_modem(modem, "Notification for other modem!");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ ps_info_ex_modem(modem, "powered event called: state [%d]", modem_power->state);
+
+ switch (modem_power->state) {
+ case MODEM_STATE_ONLINE:
+ power = PS_MODEM_STATE_ONLINE;
+ break;
+
+ case MODEM_STATE_LOW:
+ power = PS_MODEM_STATE_LOW;
+ break;
+
+ case MODEM_STATE_ERROR:
+ case MODEM_STATE_RESET:
+ /* Reset hook flag in any present */
+ __ps_modem_cp_reset_handler(modem);
+ break;
+
+ default:
+ ps_warn_ex_modem(modem, "Unhandled modem power event.");
+ break;
+ }
+
+ if (power != PS_MODEM_STATE_UNKNOWN)
+ _ps_modem_processing_power_enable(modem, power);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_flight(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ ps_modem_t *modem = user_data;
+ struct tnoti_modem_flight_mode *modem_flight = data;
+
+ g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
+ ps_info_ex_modem(modem, "flight mode event called");
+
+ _ps_modem_processing_flight_mode(modem, modem_flight->enable);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_net_register(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ gboolean ps_attached = FALSE;
+ struct tnoti_network_registration_status *regist_status = data;
+ CoreObject *co_network;
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ co_network = _ps_service_ref_co_network(service);
+ if (co_network != source)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ if (regist_status->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
+ ps_attached = TRUE;
+
+ _ps_modem_set_roaming(_ps_service_ref_modem(service), regist_status->roaming_status);
+ _ps_service_processing_network_event(service, ps_attached, regist_status->roaming_status);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_net_change(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ struct tnoti_network_change *network_change = data;
+ CoreObject *co_network;
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ co_network = _ps_service_ref_co_network(service);
+ if (co_network != source)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ ps_dbg_ex_svc(service, "plmn(%s) act(%d)", network_change->plmn, network_change->act);
+ _ps_service_set_access_technology(service, network_change->act);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_net_restricted_state(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data,
+ void *user_data)
+{
+ ps_service_t *service = user_data;
+ struct tnoti_network_restricted_state *network_restricted = data;
+ CoreObject *co_network;
+
+ g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ co_network = _ps_service_ref_co_network(service);
+ if (co_network != source)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ ps_dbg_ex_svc(service, "network restricted state(%d)", network_restricted->restricted_state);
+ _ps_service_set_restricted(service, ((network_restricted->restricted_state & NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return __on_hook_sim_init(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ struct tnoti_sim_status *sim_data = data;
+ ps_modem_t *modem = user_data;
+ const gchar *cp_name, *source_cp_name;
+
+ ps_info_ex_modem(modem, "sim init event called");
+
+ g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ cp_name = _ps_modem_ref_cp_name(modem);
+ source_cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
+ if (g_strcmp0(cp_name, source_cp_name) != 0) {
+ ps_dbg_ex_modem(modem, "Received notification for different Subscription - neglecting the notification!!!");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ ps_info_ex_modem(modem, "sim status is (%d)", sim_data->sim_status);
+
+ switch (sim_data->sim_status) {
+ case SIM_STATUS_INITIALIZING:
+ break;
+
+ case SIM_STATUS_INIT_COMPLETED: {
+ struct tel_sim_imsi *sim_imsi = NULL;
+ enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
+ sim_type = tcore_sim_get_type(source);
+
+ if (sim_type == SIM_TYPE_NVSIM) {
+ ps_info_ex_modem(modem, "initial boot from CDMA network.");
+ _ps_modem_processing_sim_complete(modem, TRUE, PS_CDMA_DUMMY_PROFILE_PLMN);
+ } else {
+ sim_imsi = tcore_sim_get_imsi(source);
+ _ps_modem_processing_sim_complete(modem, TRUE, sim_imsi->plmn);
+ g_free(sim_imsi);
+ }
+ }
+ break;
+
+ case SIM_STATUS_CARD_ERROR: /* FALLTHROUGH */
+ case SIM_STATUS_CARD_REMOVED: /* FALLTHROUGH */
+ case SIM_STATUS_CARD_CRASHED: /* FALLTHROUGH */
+ case SIM_STATUS_CARD_POWEROFF:
+ /* Set SIM complete FALSE, operator is not required */
+ _ps_modem_processing_sim_complete(modem, FALSE, NULL);
+ _ps_modem_processing_no_sim(modem);
+ break;
+
+ case SIM_STATUS_CARD_NOT_PRESENT:
+ _ps_modem_processing_no_sim(modem);
+ break;
+
+ default:
+ ps_dbg_ex_modem(modem, "Unhandled SIM state: [%d]", sim_data->sim_status);
+ _ps_modem_processing_no_sim(modem);
+ break;
+ }
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+
+#ifdef TIZEN_SUPPORT_VOLTE
+static enum tcore_hook_return __on_hook_sim_refresh(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ struct tnoti_sim_refresh_stage *sim_data = data;
+ ps_modem_t *modem = user_data;
+
+ ps_info_ex_modem(modem, "sim stage is (%d)", sim_data->stage);
+
+ if (sim_data->stage == SIM_REFRESH_START)
+ _ps_modem_processing_sim_refresh(modem);
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+#endif
+
+enum tcore_hook_return __on_hook_modem_added(Server *s,
+ CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
+{
+ ps_master_t *master = user_data;
+ TcorePlugin *plg = data;
+
+ if (FALSE == _ps_master_create_modems(master, plg))
+ err("[%s] Failed to create modem", tcore_server_get_cp_name_by_plugin(plg));
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+enum tcore_hook_return __on_hook_modem_removed(Server *s,
+ CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
+{
+ ps_master_t *master = user_data;
+ TcorePlugin *plg = data;
+
+ if (FALSE == _ps_master_destroy_modem(master, plg))
+ err("Failed to destroy modem[%s]", tcore_server_get_cp_name_by_plugin(plg));
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+gboolean _ps_get_co_modem_values(ps_modem_t *modem)
+{
+ TcorePlugin *plg;
+ CoreObject *co_modem = NULL;
+ CoreObject *co_sim = NULL;
+ ps_modem_t *ps_modem = modem;
+
+ gboolean sim_init = FALSE, flight_mode = FALSE;
+ enum modem_state modem_power_state = MODEM_STATE_UNKNOWN;
+ int sim_status = 0;
+ enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
+ struct tel_sim_imsi *sim_imsi = NULL;
+ int power = PS_MODEM_STATE_UNKNOWN;
+
+ g_return_val_if_fail(ps_modem != NULL, FALSE);
+
+ co_modem = _ps_modem_ref_co_modem(ps_modem);
+ if (!co_modem)
+ return FALSE;
+
+ plg = tcore_object_ref_plugin(co_modem);
+ if (!plg)
+ return FALSE;
+
+ co_sim = tcore_plugin_ref_core_object(plg, CORE_OBJECT_TYPE_SIM);
+
+ sim_status = tcore_sim_get_status(co_sim);
+ if (sim_status == SIM_STATUS_INIT_COMPLETED)
+ sim_init = TRUE;
+
+ sim_imsi = tcore_sim_get_imsi(co_sim);
+ flight_mode = tcore_modem_get_flight_mode_state(co_modem);
+ tcore_modem_get_modem_power_state(co_modem, &modem_power_state);
+
+ switch (modem_power_state) {
+ case MODEM_STATE_ONLINE:
+ power = PS_MODEM_STATE_ONLINE;
+ break;
+
+ case MODEM_STATE_LOW:
+ power = PS_MODEM_STATE_LOW;
+ break;
+
+ case MODEM_STATE_ERROR:
+ case MODEM_STATE_RESET:
+ default:
+ ps_warn_ex_modem(modem, "Unhandled modem power event.");
+ break;
+ }
+
+ _ps_modem_processing_flight_mode(ps_modem, flight_mode);
+ if (power != PS_MODEM_STATE_UNKNOWN)
+ _ps_modem_processing_power_enable(modem, power);
+
+ sim_type = tcore_sim_get_type(co_sim);
+
+ if (sim_type == SIM_TYPE_NVSIM)
+ _ps_modem_processing_sim_complete(ps_modem, sim_init, PS_CDMA_DUMMY_PROFILE_PLMN);
+ else
+ _ps_modem_processing_sim_complete(ps_modem, sim_init, sim_imsi->plmn);
+ g_free(sim_imsi);
+ return TRUE;
+}
+
+gboolean _ps_get_co_network_values(ps_service_t *service)
+{
+ CoreObject *co_network = NULL;
+ gboolean ps_attached = FALSE;
+ gint ps_restricted = 0;
+
+ enum telephony_network_service_domain_status ps_status;
+ enum telephony_network_access_technology act;
+
+ g_return_val_if_fail(service != NULL, FALSE);
+
+ co_network = _ps_service_ref_co_network(service);
+ ps_dbg_ex_svc(service, "Entered ");
+
+ tcore_network_get_service_status(co_network, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
+ tcore_network_get_access_technology(co_network, &act);
+
+ if (ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
+ ps_attached = TRUE;
+
+ ps_restricted = tcore_network_get_restricted_state(co_network);
+
+ _ps_service_set_restricted(service, ((ps_restricted == NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
+ _ps_service_set_roaming(service, tcore_network_get_roaming_state(co_network));
+ _ps_service_set_ps_attached(service, ps_attached);
+ _ps_service_set_access_technology(service, act);
+
+ return TRUE;
+}
+
+gboolean _ps_add_co_ps_event(ps_service_t *service)
+{
+ Server *s;
+ g_return_val_if_fail(service != NULL, FALSE);
+ ps_dbg_ex_svc(service, "Entered ");
+ s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
+ tcore_server_add_notification_hook(s, TNOTI_PS_CALL_STATUS, __on_hook_call_status, service);
+ tcore_server_add_notification_hook(s, TNOTI_PS_PDP_IPCONFIGURATION, __on_hook_ipconfiguration, service);
+ tcore_server_add_notification_hook(s, TNOTI_PS_DEDICATED_BEARER_INFO, __on_hook_dedicated_bearerinfo, service);
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_DEFAULT_DATA_SUBSCRIPTION, __on_hook_default_data_subscription, service);
+// tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_BACKOFF_TIMER, __on_hook_gprs_backoff_timer, service);
+// tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_NAS_TIMER, __on_hook_gprs_nas_timer, service);
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_EPDG_STATUS, __on_hook_epdg_status, service);
+ tcore_object_add_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed, service);
+ return TRUE;
+}
+
+gboolean _ps_add_co_network_event(ps_service_t *service)
+{
+ Server *s;
+
+ g_return_val_if_fail(service != NULL, FALSE);
+
+ s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
+
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, __on_hook_net_register, service);
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, __on_hook_net_change, service);
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_RESTRICTED_STATE, __on_hook_net_restricted_state, service);
+
+ return TRUE;
+}
+
+gboolean _ps_add_co_modem_event(ps_modem_t *modem)
+{
+ Server *s = NULL;
+
+ g_return_val_if_fail(modem != NULL, FALSE);
+
+ s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
+
+ tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER, __on_hook_powered, modem);
+ tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE, __on_hook_flight, modem);
+ tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, __on_hook_sim_init, modem);
+// tcore_server_add_notification_hook(s, TNOTI_SIM_REFRESH_STAGE, __on_hook_sim_refresh, modem);
+#ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
+ _ps_hook_add_modem_hooks(modem);
+#endif
+ return TRUE;
+}
+
+gboolean _ps_free_co_ps_event(ps_service_t *service)
+{
+ Server *s;
+ g_return_val_if_fail(service != NULL, FALSE);
+ ps_dbg_ex_svc(service, "Entered ");
+ s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
+ tcore_object_del_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed);
+ tcore_server_remove_notification_hook(s, __on_hook_call_status);
+ tcore_server_remove_notification_hook(s, __on_hook_ipconfiguration);
+ tcore_server_remove_notification_hook(s, __on_hook_dedicated_bearerinfo);
+ tcore_server_remove_notification_hook(s, __on_hook_default_data_subscription);
+// tcore_server_remove_notification_hook(s, __on_hook_gprs_backoff_timer);
+// tcore_server_remove_notification_hook(s, __on_hook_gprs_nas_timer);
+ tcore_server_remove_notification_hook(s, __on_hook_epdg_status);
+ return TRUE;
+}
+
+gboolean _ps_free_co_network_event(ps_service_t *service)
+{
+ Server *s;
+ g_return_val_if_fail(service != NULL, FALSE);
+ ps_dbg_ex_svc(service, "Entered");
+ s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
+ tcore_server_remove_notification_hook(s, __on_hook_net_register);
+ tcore_server_remove_notification_hook(s, __on_hook_net_change);
+ tcore_server_remove_notification_hook(s, __on_hook_net_restricted_state);
+ return TRUE;
+}
+
+gboolean _ps_free_co_modem_event(ps_modem_t *modem)
+{
+ Server *s;
+ g_return_val_if_fail(modem != NULL, FALSE);
+ s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
+ tcore_server_remove_notification_hook(s, __on_hook_powered);
+ tcore_server_remove_notification_hook(s, __on_hook_flight);
+ tcore_server_remove_notification_hook(s, __on_hook_sim_init);
+// tcore_server_remove_notification_hook(s, __on_hook_sim_refresh);
+ return TRUE;
+}
+
+gboolean _ps_update_cellular_state_key(ps_service_t *service)
+{
+ int current_state = 0;
+ int stored_state = 0;
+ ps_modem_t *modem;
+ ps_master_t *master;
+ ps_subs_type subs_type;
+ int selected_sim = -1;
+
+ g_return_val_if_fail(service != NULL, FALSE);
+
+ modem = _ps_service_ref_modem(service);
+ master = _ps_modem_ref_master(modem);
+ subs_type = _ps_modem_get_subs_type(modem);
+
+ ps_dbg_ex_svc(service, "Update cellular state for [SIM%d]", subs_type + 1);
+
+ selected_sim = _ps_master_get_storage_value_int(master, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
+ if ((selected_sim != -1) && (selected_sim != (int)subs_type)) {
+ ps_warn_ex_svc(service, "Update for only [SIM%d] selected by Setting", selected_sim + 1);
+ return FALSE;
+ }
+
+ current_state = _ps_service_check_cellular_state(service);
+
+ if (tcore_modem_get_flight_mode_state(modem->co_modem) == TRUE)
+ current_state = TELEPHONY_PS_FLIGHT_MODE;
+
+ stored_state = _ps_master_get_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE);
+ if (current_state != stored_state) {
+ ps_info_ex_svc(service, "Cellular state, current: [%d], stored: [%d]", current_state, stored_state);
+ _ps_master_set_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE, current_state);
+ }
+
+ return TRUE;
+}