2 * tel-plugin-packetservice
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: DongHoo Park <donghoo.park@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include "ps_common.h"
23 #include "ps_context.h"
25 #include "ps_service.h"
26 #include "ps_master.h"
27 #include "ps_tcore_interface.h"
34 #include <co_context.h>
37 #include <type/network.h>
38 #include <co_network.h>
39 #include <user_request.h>
44 PS_CALL_STATE_RESULT_OK = 0x00,
45 PS_CALL_STATE_RESULT_CONNECT = 0x01,
46 PS_CALL_STATE_RESULT_NO_CARRIER = 0x03
49 static void __ps_handle_prop_dnet_connection_status(CoreObject *co_ps, void *user_data)
51 const char *value = NULL;
54 ps_service_t *service = (ps_service_t *)user_data;
56 value = tcore_object_ref_property(co_ps, PROP_DNET_CONNECTION_STATUS);
57 ps_info_ex_svc(service, "Dnet connection status = %s", value);
59 if (!value || strlen(value) == 0)
62 if (g_strrstr(value, "disconnected")) {
63 for (index = 0; index < g_slist_length(service->contexts); index++) {
64 ps_context_t *context = g_slist_nth_data(service->contexts, index);
65 CoreObject *co_context = _ps_context_ref_co_context(context);
66 if (tcore_context_get_role(co_context) == CONTEXT_ROLE_INTERNET) {
67 context_id = value[0];
68 ps_info_ex_svc(service, "TNOTI_PS_CALL_STATUS - CID: [%d] State: [%d]", context_id, PS_CALL_STATE_RESULT_NO_CARRIER);
69 _ps_context_set_ps_defined(context, FALSE);
70 tcore_ps_set_cid_active(co_ps, context_id, FALSE);
71 tcore_ps_set_cid_connected(co_ps, context_id, FALSE);
72 _ps_context_set_connected(context, FALSE);
79 static gboolean __ps_on_prop_changed(CoreObject *co_ps, const void *event_info,
82 GSList *key = (GSList *)event_info;
84 if (CORE_OBJECT_KEY_FIND(key, PROP_DNET_CONNECTION_STATUS))
85 __ps_handle_prop_dnet_connection_status(co_ps, user_data);
89 static void __ps_modem_cp_reset_handler(ps_modem_t *modem)
92 #ifdef TIZEN_SUPPORT_VOLTE
93 enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
96 ps_info_ex_modem(modem, "disconnect all contexts");
97 /* send deactivation request to clear resources. */
98 for (index = 0; index < g_slist_length(modem->contexts); index++) {
99 ps_context_t *context = g_slist_nth_data(modem->contexts, index);
100 ps_service_t *service = _ps_context_ref_service(context);
101 CoreObject *co_context = _ps_context_ref_co_context(context);
104 #ifdef TIZEN_SUPPORT_VOLTE
105 role = tcore_context_get_role(co_context);
106 ps_info_ex_modem(modem, "role(%d)", role);
107 if (role == CONTEXT_ROLE_IMS && !tcore_network_get_ims_on_deregistering(_ps_service_ref_co_network(service))) {
108 if (_ps_context_deregister_ims(context) == TCORE_RETURN_SUCCESS)
109 tcore_context_set_state(co_context, CONTEXT_STATE_DEACTIVATED);
112 tcore_ps_deactivate_context(_ps_service_ref_co_ps(service), co_context, NULL);
113 tcore_context_set_state(co_context, CONTEXT_STATE_DEACTIVATED);
115 //due to pendig UR needs to clear AP resources
116 tcore_ps_clear_context_id(_ps_service_ref_co_ps(service), co_context);
117 _ps_context_set_connected(context, FALSE);
120 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
121 /* check for any pending request in modem queue and respond with error */
122 _ps_hook_cp_reset_send_pending_request_response(modem);
124 /* reset modem flag */
125 modem->hook_flag &= PS_NO_PENDING_REQUEST;
129 #ifdef PREPAID_SIM_APN_SUPPORT
130 static void __on_call_status_for_prepaid_sim(ps_service_t *service, ps_context_t *def_context, ps_modem_t *modem)
132 unsigned char prepaid_cid = 0;
133 ps_context_t *prepaid_def_context = NULL;
134 unsigned char def_cid = 0;
137 ps_err_ex_svc(service, "service does not exist");
142 ps_err_ex_modem(modem, "modem does not exist");
146 if (def_context == NULL) {
147 def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
149 CoreObject *co_context = NULL;
150 co_context = _ps_context_ref_co_context(def_context);
151 def_cid = tcore_context_get_id(co_context);
155 prepaid_def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_PREPAID_INTERNET);
156 ps_dbg_ex_modem(modem, "prepaid_def_context[%p]", prepaid_def_context);
157 if (prepaid_def_context) {
158 CoreObject *co_context = NULL;
159 co_context = _ps_context_ref_co_context(prepaid_def_context);
160 prepaid_cid = tcore_context_get_id(co_context);
162 ps_dbg_ex_modem(modem, "prepaid_cid[%d]", prepaid_cid);
164 /* Has prepaid APN */
165 if (prepaid_def_context) {
166 ps_master_t * master = NULL;
167 ps_context_t *context = NULL;
170 ps_dbg_ex_modem(modem, "Context id: %d", cstatus->context_id);
171 ps_dbg_ex_modem(modem, "retry: %s", retry ? "TRUE" : "FALSE");
173 if (cstatus->context_id == def_cid) {
174 ps_dbg_ex_modem(modem, "Resetting connection time for default context");
175 _ps_service_reset_connection_timer(def_context);
177 /* Connect to default prepaid internet */
178 rv = _ps_service_connect_default_prepaid_context(service);
179 ps_dbg_ex_modem(modem, "prepaid internet connect - rv[%d]", rv);
180 } else if (cstatus->context_id == prepaid_cid) {
181 /* Reset connection */
182 ps_dbg_ex_modem(modem, "Resetting connection time for prepaid internet context");
183 _ps_service_reset_connection_timer(prepaid_def_context);
185 /* Connect to default internet */
186 rv = _ps_service_connect_default_context(service);
187 ps_dbg_ex_modem(modem, "default internet connect - rv[%d]", rv);
190 /* Reset Last connected, Profile ID and Operator vconf keys. */
191 ps_dbg_ex_modem(modem, "Reset vconf keys...");
192 master = _ps_modem_ref_master(modem);
193 _ps_master_set_storage_value_string(master, STORAGE_KEY_TELEPHONY_LAST_CONNECTED_CONTEXT_PLMN, NULL);
195 context = _ps_service_return_context_by_cid(service, cstatus->context_id);
196 ps_dbg_ex_modem(modem, "context[%p]", context);
199 ps_dbg_ex_modem(modem, "Reset profile id");
200 _ps_master_set_storage_value_int(master, STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_PROFILE_ID, -1);
201 /* set vconf last connected profile */
202 ps_dbg_ex_modem(modem, "set vconf last connected profile to FALSE");
203 _ps_master_set_storage_value_bool(master, STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_BOOL, FALSE);
210 static void __on_hook_status_NO_carrier(ps_modem_t *modem, ps_service_t *service,
211 CoreObject *co_ps, struct tnoti_ps_call_status *cstatus)
213 ps_context_t *def_context = NULL, *ims_context = NULL;
214 unsigned char def_cid = 0, ims_cid = 0;
216 gboolean retry = TRUE;
218 if (!modem || !service || !cstatus)
221 retry = ps_util_check_permanent_reject_cause(cstatus->result, _ps_modem_get_roaming(modem));
222 /* if retry not permitted by network */
223 if (FALSE == retry) {
224 ps_dbg_ex_modem(modem, "DO NOT RETRY NETWORK CONNECTION AUTOMATICALLY");
225 ps_info_ex_modem(modem, "permanent reject cause (%d), roaming(%d)", cstatus->result, _ps_modem_get_roaming(modem));
227 def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
229 CoreObject *co_context = _ps_context_ref_co_context(def_context);
230 def_cid = tcore_context_get_id(co_context);
233 ims_context = _ps_service_return_default_context(service, CONTEXT_ROLE_IMS);
235 CoreObject *co_context = _ps_context_ref_co_context(ims_context);
236 ims_cid = tcore_context_get_id(co_context);
240 _ps_service_set_ps_defined(service, FALSE, cstatus->context_id);
241 tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
242 tcore_ps_set_cid_connected(co_ps, cstatus->context_id, FALSE);
243 _ps_service_set_connected(service, cstatus, FALSE);
245 if (FALSE == tcore_ps_any_internet_mms_tethering_context_activating_activated(co_ps, &value)) {
246 ps_dbg_ex_modem(modem, "No context open connections, publish disconnected signal");
247 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
248 /* Handle any pending request if present */
249 modem = _ps_service_ref_modem(service);
250 _ps_hook_send_pending_user_request(modem);
252 /* Ensured that set_reset_profile is always done default thread's context */
253 if (_ps_modem_get_reset_profile(modem) == TRUE) {
254 /* Initiate Reset Profile */
255 ps_info_ex_modem(modem, "Profiles are being reset");
256 /* Shouldn't invoke set profile directly, as it will remove hooks registered to server while being hook callback*/
257 if (NULL == _ps_modem_get_profile_reset_gsource(modem)) {
258 GSource *gsource = NULL;
259 gsource = ps_util_gsource_dispatch(g_main_context_default(), G_PRIORITY_LOW, (GSourceFunc)_ps_modem_initiate_reset_profile, modem);
260 _ps_modem_set_profile_reset_gsource(modem, gsource);
265 #ifdef PREPAID_SIM_APN_SUPPORT
266 __on_call_status_for_prepaid_sim(service, def_context, modem);
269 ps_info_ex_modem(modem, "Any context activating or activated [%d]", value);
270 if (FALSE == retry) {
271 if (cstatus->context_id == def_cid) {
272 _ps_service_reset_connection_timer(def_context);
273 _ps_context_set_alwayson_enable(def_context, FALSE);
274 } else if (cstatus->context_id == ims_cid) {
275 _ps_service_reset_connection_timer(ims_context);
276 _ps_context_set_alwayson_enable(ims_context, FALSE);
281 static enum tcore_hook_return __on_hook_call_status(Server *s, CoreObject *source,
282 enum tcore_notification_command command, unsigned int data_len, void *data,
285 ps_modem_t *modem = NULL;
286 ps_service_t *service = user_data;
287 CoreObject *co_network;
288 CoreObject *co_ps = NULL;
291 gboolean b_data_allowed = FALSE;
292 gboolean b_roaming_checker = TRUE;
293 gboolean b_mms_checker = FALSE;
294 gboolean b_ims_checker = FALSE;
295 gboolean b_allowed_on_data_off = FALSE;
297 struct tnoti_ps_call_status *cstatus = data;
299 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
301 co_network = _ps_service_ref_co_network(service);
302 co_ps = _ps_service_ref_co_ps(service);
303 if (co_ps != source) {
304 ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
305 return TCORE_HOOK_RETURN_CONTINUE;
308 modem = _ps_service_ref_modem(service);
310 ps_err_ex_modem(modem, "modem does not exist");
311 return TCORE_HOOK_RETURN_CONTINUE;
314 b_data_allowed = _ps_modem_get_data_allowed(modem);
316 co_list = tcore_ps_ref_context_by_id(co_ps, cstatus->context_id);
317 for (; co_list; co_list = co_list->next) {
318 CoreObject *co_context = NULL;
319 enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
321 co_context = co_list->data;
322 role = tcore_context_get_role(co_context);
324 if (role == CONTEXT_ROLE_MMS || role == CONTEXT_ROLE_PREPAID_MMS) {
325 b_mms_checker = TRUE;
328 if (role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY || role == CONTEXT_ROLE_IMS_UT) {
329 b_ims_checker = TRUE;
332 if (role == CONTEXT_ROLE_BIP || role == CONTEXT_ROLE_FOTA) {
333 b_allowed_on_data_off = TRUE;
338 #if !defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
339 ps_dbg_ex_modem(modem, "csc runtime feature disabled");
340 b_mms_checker = FALSE;
343 if (!b_ims_checker && (_ps_modem_get_roaming(modem)) && !(_ps_modem_get_data_roaming_allowed(modem))) {
344 ps_info_ex_modem(modem, "roaming network is not allowed");
345 b_roaming_checker = FALSE;
348 ps_info_ex_modem(modem, "data_allowed(%d) call status event cid(%d) state(%d) reason(%d)",
349 b_data_allowed, cstatus->context_id, cstatus->state, cstatus->result);
351 if (!b_roaming_checker || (!b_data_allowed && !b_mms_checker && !b_ims_checker && !b_allowed_on_data_off)) {
352 ps_dbg_ex_modem(modem, "mismatched: roaming checker(%d) data_allowed(%d) mms_checker(%d) b_ims_checker(%d)",
353 b_roaming_checker, b_data_allowed, b_mms_checker, b_ims_checker);
355 if (cstatus->state == PS_CALL_STATE_RESULT_OK) {
357 * If attach_apn_complete is FALSE, need to set TRUE.
358 * In case of boot-up with roaming-SIM and Data Roaming option disabled,
359 * although define process is triggered, 'attach_apn_complete' flag does not set TRUE.
360 * So, when Data Roaming option is enabled, pdp activation is not triggered.
362 if (service->attach_apn_complete) {
363 _ps_service_set_connected(service, cstatus, FALSE);
364 tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
366 _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
368 return TCORE_HOOK_RETURN_CONTINUE;
369 } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) {
370 _ps_service_set_connected(service, cstatus, TRUE);
371 _ps_service_disconnect_contexts(service);
372 return TCORE_HOOK_RETURN_CONTINUE;
376 ps_dbg_ex_modem(modem, "service(%p) status(%d)", service, cstatus->state);
377 if (cstatus->state == PS_CALL_STATE_RESULT_OK) { /* DEFINE */
378 _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
379 } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) { /* CONNECTED */
382 if (tcore_ps_get_cid_active(co_ps, cstatus->context_id) == FALSE) {
383 ps_dbg_ex_modem(modem, "DDS scenario");
385 /* De-activate context */
386 rv = tcore_ps_deactivate_contexts(co_ps);
387 if (rv != TCORE_RETURN_SUCCESS) {
388 ps_err_ex_modem(modem, "fail to deactivation");
389 return TCORE_HOOK_RETURN_CONTINUE;
393 gboolean need_deactivate = FALSE;
395 ret = _ps_service_set_connected(service, cstatus, TRUE);
396 tcore_ps_set_cid_connected(co_ps, cstatus->context_id, TRUE);
398 if (ret == FALSE || (_ps_modem_get_reset_profile(modem) == TRUE))
399 need_deactivate = TRUE;
401 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
402 if (g_queue_get_length(_ps_hook_ref_work_queue(modem)))
403 need_deactivate = TRUE;
406 if (need_deactivate) {
407 ps_info_ex_modem(modem, "Special request present in queue or pending activation request");
408 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
409 if (ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SEARCH) ||
410 ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) ||
411 ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_PLMN_SELECTION_MODE)) {
413 gpointer key, tmp_service;
415 ps_info_ex_modem(modem, "Network search/selection/cancel searchrequest is in queue");
416 g_hash_table_iter_init(&iter, modem->services);
417 while (g_hash_table_iter_next(&iter, &key, &tmp_service) == TRUE)
418 _ps_service_disconnect_internet_mms_tethering_contexts(tmp_service);
422 rv = tcore_ps_deactivate_contexts(co_ps);
423 if (rv != TCORE_RETURN_SUCCESS) {
424 ps_dbg_ex_modem(modem, "fail to deactivation");
425 return TCORE_HOOK_RETURN_CONTINUE;
430 } else if (cstatus->state == PS_CALL_STATE_RESULT_NO_CARRIER) { /* DISCONNECTED-NO CARRIER */
431 __on_hook_status_NO_carrier(modem, service, co_ps, cstatus);
432 } /* disconnected case */
434 return TCORE_HOOK_RETURN_CONTINUE;
437 #if 0 // TODO: libtcore need to be updated
438 static enum tcore_hook_return __on_hook_gprs_backoff_timer(Server *s, CoreObject *source,
439 enum tcore_notification_command command, unsigned int data_len, void *data,
442 ps_service_t *service = user_data;
443 CoreObject *co_context = NULL;
444 CoreObject *co_ps = NULL;
445 struct tnoti_ps_backoff_timer *backoff = data;
446 unsigned int retryArray[] = { 0, };
448 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
450 co_ps = _ps_service_ref_co_ps(service);
452 return TCORE_HOOK_RETURN_CONTINUE;
454 ps_dbg_ex_svc(service, "cid(%d) apn(%s) result(%d) retry_time(%d)", backoff->context_id, backoff->apn, backoff->result, backoff->retry_time);
455 if (!strlen(backoff->apn)) {
456 ps_warn_ex_svc(service, "Invalid APN");
457 return TCORE_HOOK_RETURN_CONTINUE;
460 co_context = tcore_ps_ref_context_by_apn(co_ps, backoff->apn);
462 ps_warn_ex_svc(service, "Couldn't find matched context from apn(%s)", backoff->apn);
463 return TCORE_HOOK_RETURN_CONTINUE;
466 if (backoff->retry_time != 0xFFFFFFFF && backoff->retry_time > 0) {
467 if (backoff->retry_time > 72 * 60 * 60)
468 backoff->retry_time = 72 * 60 * 60;
470 ps_info_ex_svc(service, "retry_time(%d) was set", backoff->retry_time);
471 retryArray[0] = backoff->retry_time;
472 tcore_context_set_max_retry_count(co_context, 1);
473 tcore_context_set_retry_timer_array(co_context, retryArray, 1);
476 if (backoff->result == PS_PDP_REJ_TIMER_T3396_DEACTIVATED) {
477 ps_info_ex_svc(service, "T3396_DEACTIVATED, PDN.apn(%s)", backoff->apn);
478 tcore_context_set_throttled_apn(co_context, TRUE);
479 } else if (backoff->result == PS_PDP_REJ_TIMER_T3396_STOPPED) {
480 ps_err_ex_svc(service, "T3396_STOPPED, PDN.apn(%s)", backoff->apn);
481 tcore_context_set_throttled_apn(co_context, FALSE);
482 _ps_service_connect_default_context(service);
485 return TCORE_HOOK_RETURN_CONTINUE;
489 #if 0 // TODO: libtcore need to be updated
490 static enum tcore_hook_return __on_hook_gprs_nas_timer(Server *s, CoreObject *source,
491 enum tcore_notification_command command, unsigned int data_len, void *data,
494 ps_service_t *service = user_data;
495 struct tnoti_ps_nas_timer *nas_timer = data;
497 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
499 if (nas_timer->timer_type == 0x01) { /*T3346*/
500 if (nas_timer->timer_status == PS_NAS_TIMER_STATE_START) {
501 ps_info_ex_svc(service, "T3346 START(%d)", nas_timer->timer_status);
502 _ps_service_handling_nas_timer(service, nas_timer->timer_status);
503 } else if (nas_timer->timer_status == PS_NAS_TIMER_STATE_STOP
504 || nas_timer->timer_status == PS_NAS_TIMER_STATE_EXPIRE) {
505 ps_info_ex_svc(service, "T3346 STOP(%d)", nas_timer->timer_status);
506 _ps_service_handling_nas_timer(service, nas_timer->timer_status);
510 return TCORE_HOOK_RETURN_CONTINUE;
514 static enum tcore_hook_return __on_hook_dedicated_bearerinfo(Server *s, CoreObject *source,
515 enum tcore_notification_command command, unsigned int data_len, void *data,
518 ps_service_t *service = user_data;
519 CoreObject *co_ps = NULL;
520 struct tnoti_ps_dedicated_bearer_info *bearer_info = data;
522 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
524 co_ps = _ps_service_ref_co_ps(service);
526 return TCORE_HOOK_RETURN_CONTINUE;
528 _ps_service_set_context_bearerinfo(service, bearer_info);
529 ps_info_ex_svc(service, "dedicated bearer information event");
530 return TCORE_HOOK_RETURN_CONTINUE;
533 static enum tcore_hook_return __on_hook_default_data_subscription(Server *s, CoreObject *source,
534 enum tcore_notification_command command, unsigned int data_len, void *data,
537 ps_service_t *service = user_data;
538 const struct tnoti_network_default_data_subs *default_data_subs_info = data;
540 if (default_data_subs_info->default_subs != (enum telephony_network_default_data_subs)tcore_object_ref_subscription_type(_ps_service_ref_co_ps(service)))
541 return TCORE_HOOK_RETURN_CONTINUE;
543 ps_info_ex_svc(service, "'default' data subscription information event");
544 _ps_service_connect_default_context(service);
546 return TCORE_HOOK_RETURN_CONTINUE;
548 static enum tcore_hook_return __on_hook_epdg_status(Server *s, CoreObject *source,
549 enum tcore_notification_command command, unsigned int data_len, void *data,
552 ps_service_t *service = user_data;
553 const struct tnoti_network_epdg_status *noti = (const struct tnoti_network_epdg_status *)data;
554 gboolean available = FALSE;
556 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
557 g_return_val_if_fail(noti != NULL, TCORE_HOOK_RETURN_CONTINUE);
559 if ((noti->status == NETWORK_EPDG_STATUS_AVAILABLE) ||
560 (noti->status == NETWORK_EPDG_STATUS_CONNECTED) ||
561 (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)) {
565 ps_info_ex_svc(service, "ePDG: [%s]", ((available == TRUE) ? "AVAILABLE" : "UNAVAILABLE"));
566 _ps_service_set_epdg_status(service, available);
568 if (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)
569 _ps_service_set_epdg_ip_configuration(service, noti->cid, noti->ipv4_address, noti->ipv6_address);
570 return TCORE_HOOK_RETURN_CONTINUE;
573 static enum tcore_hook_return __on_hook_ipconfiguration(Server *s, CoreObject *source,
574 enum tcore_notification_command command, unsigned int data_len, void *data,
577 ps_service_t *service = user_data;
578 CoreObject *co_ps = NULL;
579 struct tnoti_ps_pdp_ipconfiguration *devinfo = data;
580 char ipv4[16], ipv4_dns_1[16], ipv4_dns_2[16];
582 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
584 co_ps = _ps_service_ref_co_ps(service);
585 if (co_ps != source) {
586 ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
587 return TCORE_HOOK_RETURN_CONTINUE;
590 ps_info_ex_svc(service, "ip configuration event");
593 * In case IPv4 address is available and DNS address
594 * is NOT available, set -
598 snprintf(ipv4, 16, "%d.%d.%d.%d",
599 devinfo->ip_address[0], devinfo->ip_address[1],
600 devinfo->ip_address[2], devinfo->ip_address[3]);
601 if (!g_str_equal(ipv4, "0.0.0.0")) {
602 snprintf(ipv4_dns_1, 16, "%d.%d.%d.%d",
603 devinfo->primary_dns[0], devinfo->primary_dns[1],
604 devinfo->primary_dns[2], devinfo->primary_dns[3]);
605 if (g_str_equal(ipv4_dns_1, "0.0.0.0")) {
606 ps_err_ex_svc(service, "[IPV4]primary dns address is 0");
609 devinfo->primary_dns[0] = 8;
610 devinfo->primary_dns[1] = 8;
611 devinfo->primary_dns[2] = 8;
612 devinfo->primary_dns[3] = 8;
615 snprintf(ipv4_dns_2, 16, "%d.%d.%d.%d",
616 devinfo->secondary_dns[0], devinfo->secondary_dns[1],
617 devinfo->secondary_dns[2], devinfo->secondary_dns[3]);
618 if (g_str_equal(ipv4_dns_2, "0.0.0.0")) {
620 ps_err_ex_svc(service, "[IPV4]secondary dns address is 0");
621 devinfo->secondary_dns[0] = 208;
622 devinfo->secondary_dns[1] = 67;
623 devinfo->secondary_dns[2] = 222;
624 devinfo->secondary_dns[3] = 222;
629 * In case IPv6 address is available and DNS address
630 * is NOT available, set -
634 if (devinfo->ipv6_address != NULL) {
635 if (devinfo->ipv6_primary_dns == NULL) {
636 ps_err_ex_svc(service, "[IPV6]primary dns address is 0");
637 devinfo->ipv6_primary_dns = g_strdup("2001:4860:4860::8888");
640 if (devinfo->ipv6_secondary_dns == NULL) {
641 ps_err_ex_svc(service, "[IPV6]secondary dns address is 0");
642 devinfo->ipv6_secondary_dns = g_strdup("2620:0:ccc::2");
646 _ps_service_set_context_devinfo(service, devinfo);
648 return TCORE_HOOK_RETURN_CONTINUE;
651 static enum tcore_hook_return __on_hook_powered(Server *s, CoreObject *source,
652 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
654 ps_modem_t *modem = user_data;
655 CoreObject *co_modem;
656 struct tnoti_modem_power *modem_power = data;
657 int power = PS_MODEM_STATE_UNKNOWN;
659 CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE);
661 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
662 g_return_val_if_fail(modem_power != NULL, TCORE_HOOK_RETURN_CONTINUE);
664 co_modem = _ps_modem_ref_co_modem(modem);
665 if (co_modem != source) {
666 ps_dbg_ex_modem(modem, "Notification for other modem!");
667 return TCORE_HOOK_RETURN_CONTINUE;
670 ps_info_ex_modem(modem, "powered event called: state [%d]", modem_power->state);
672 switch (modem_power->state) {
673 case MODEM_STATE_ONLINE:
674 power = PS_MODEM_STATE_ONLINE;
677 case MODEM_STATE_LOW:
678 power = PS_MODEM_STATE_LOW;
681 case MODEM_STATE_ERROR:
682 case MODEM_STATE_RESET:
683 /* Reset hook flag in any present */
684 __ps_modem_cp_reset_handler(modem);
688 ps_warn_ex_modem(modem, "Unhandled modem power event.");
692 if (power != PS_MODEM_STATE_UNKNOWN)
693 _ps_modem_processing_power_enable(modem, power);
695 return TCORE_HOOK_RETURN_CONTINUE;
698 static enum tcore_hook_return __on_hook_flight(Server *s, CoreObject *source,
699 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
701 ps_modem_t *modem = user_data;
702 struct tnoti_modem_flight_mode *modem_flight = data;
704 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
705 ps_info_ex_modem(modem, "flight mode event called");
707 _ps_modem_processing_flight_mode(modem, modem_flight->enable);
709 return TCORE_HOOK_RETURN_CONTINUE;
712 static enum tcore_hook_return __on_hook_net_register(Server *s, CoreObject *source,
713 enum tcore_notification_command command, unsigned int data_len, void *data,
716 ps_service_t *service = user_data;
717 gboolean ps_attached = FALSE;
718 struct tnoti_network_registration_status *regist_status = data;
719 CoreObject *co_network;
721 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
723 co_network = _ps_service_ref_co_network(service);
724 if (co_network != source)
725 return TCORE_HOOK_RETURN_CONTINUE;
727 if (regist_status->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
730 _ps_modem_set_roaming(_ps_service_ref_modem(service), regist_status->roaming_status);
731 _ps_service_processing_network_event(service, ps_attached, regist_status->roaming_status);
733 return TCORE_HOOK_RETURN_CONTINUE;
736 static enum tcore_hook_return __on_hook_net_change(Server *s, CoreObject *source,
737 enum tcore_notification_command command, unsigned int data_len, void *data,
740 ps_service_t *service = user_data;
741 struct tnoti_network_change *network_change = data;
742 CoreObject *co_network;
744 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
746 co_network = _ps_service_ref_co_network(service);
747 if (co_network != source)
748 return TCORE_HOOK_RETURN_CONTINUE;
750 ps_dbg_ex_svc(service, "plmn(%s) act(%d)", network_change->plmn, network_change->act);
751 _ps_service_set_access_technology(service, network_change->act);
753 return TCORE_HOOK_RETURN_CONTINUE;
756 static enum tcore_hook_return __on_hook_net_restricted_state(Server *s, CoreObject *source,
757 enum tcore_notification_command command, unsigned int data_len, void *data,
760 ps_service_t *service = user_data;
761 struct tnoti_network_restricted_state *network_restricted = data;
762 CoreObject *co_network;
764 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
766 co_network = _ps_service_ref_co_network(service);
767 if (co_network != source)
768 return TCORE_HOOK_RETURN_CONTINUE;
770 ps_dbg_ex_svc(service, "network restricted state(%d)", network_restricted->restricted_state);
771 _ps_service_set_restricted(service, ((network_restricted->restricted_state & NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
773 return TCORE_HOOK_RETURN_CONTINUE;
776 static enum tcore_hook_return __on_hook_sim_init(Server *s, CoreObject *source,
777 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
779 struct tnoti_sim_status *sim_data = data;
780 ps_modem_t *modem = user_data;
781 const gchar *cp_name, *source_cp_name;
783 ps_info_ex_modem(modem, "sim init event called");
785 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
787 cp_name = _ps_modem_ref_cp_name(modem);
788 source_cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
789 if (g_strcmp0(cp_name, source_cp_name) != 0) {
790 ps_dbg_ex_modem(modem, "Received notification for different Subscription - neglecting the notification!!!");
791 return TCORE_HOOK_RETURN_CONTINUE;
794 ps_info_ex_modem(modem, "sim status is (%d)", sim_data->sim_status);
796 switch (sim_data->sim_status) {
797 case SIM_STATUS_INITIALIZING:
800 case SIM_STATUS_INIT_COMPLETED: {
801 struct tel_sim_imsi *sim_imsi = NULL;
802 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
803 sim_type = tcore_sim_get_type(source);
805 if (sim_type == SIM_TYPE_NVSIM) {
806 ps_info_ex_modem(modem, "initial boot from CDMA network.");
807 _ps_modem_processing_sim_complete(modem, TRUE, PS_CDMA_DUMMY_PROFILE_PLMN);
809 sim_imsi = tcore_sim_get_imsi(source);
810 _ps_modem_processing_sim_complete(modem, TRUE, sim_imsi->plmn);
816 case SIM_STATUS_CARD_ERROR: /* FALLTHROUGH */
817 case SIM_STATUS_CARD_REMOVED: /* FALLTHROUGH */
818 case SIM_STATUS_CARD_CRASHED: /* FALLTHROUGH */
819 case SIM_STATUS_CARD_POWEROFF:
820 /* Set SIM complete FALSE, operator is not required */
821 _ps_modem_processing_sim_complete(modem, FALSE, NULL);
822 _ps_modem_processing_no_sim(modem);
825 case SIM_STATUS_CARD_NOT_PRESENT:
826 _ps_modem_processing_no_sim(modem);
830 ps_dbg_ex_modem(modem, "Unhandled SIM state: [%d]", sim_data->sim_status);
831 _ps_modem_processing_no_sim(modem);
835 return TCORE_HOOK_RETURN_CONTINUE;
838 #if 0 // TODO: libtcore need to be updated
839 static enum tcore_hook_return __on_hook_sim_refresh(Server *s, CoreObject *source,
840 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
842 struct tnoti_sim_refresh_stage *sim_data = data;
843 ps_modem_t *modem = user_data;
845 ps_info_ex_modem(modem, "sim stage is (%d)", sim_data->stage);
847 if (sim_data->stage == SIM_REFRESH_START)
848 _ps_modem_processing_sim_refresh(modem);
849 return TCORE_HOOK_RETURN_CONTINUE;
853 enum tcore_hook_return __on_hook_modem_added(Server *s,
854 CoreObject *source, enum tcore_notification_command command,
855 unsigned int data_len, void *data, void *user_data)
857 ps_master_t *master = user_data;
858 TcorePlugin *plg = data;
860 if (FALSE == _ps_master_create_modems(master, plg))
861 err("[%s] Failed to create modem", tcore_server_get_cp_name_by_plugin(plg));
863 return TCORE_HOOK_RETURN_CONTINUE;
866 enum tcore_hook_return __on_hook_modem_removed(Server *s,
867 CoreObject *source, enum tcore_notification_command command,
868 unsigned int data_len, void *data, void *user_data)
870 ps_master_t *master = user_data;
871 TcorePlugin *plg = data;
873 if (FALSE == _ps_master_destroy_modem(master, plg))
874 err("Failed to destroy modem[%s]", tcore_server_get_cp_name_by_plugin(plg));
876 return TCORE_HOOK_RETURN_CONTINUE;
879 gboolean _ps_get_co_modem_values(ps_modem_t *modem)
882 CoreObject *co_modem = NULL;
883 CoreObject *co_sim = NULL;
884 ps_modem_t *ps_modem = modem;
886 gboolean sim_init = FALSE, flight_mode = FALSE;
887 enum modem_state modem_power_state = MODEM_STATE_UNKNOWN;
889 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
890 struct tel_sim_imsi *sim_imsi = NULL;
891 int power = PS_MODEM_STATE_UNKNOWN;
893 g_return_val_if_fail(ps_modem != NULL, FALSE);
895 co_modem = _ps_modem_ref_co_modem(ps_modem);
899 plg = tcore_object_ref_plugin(co_modem);
903 co_sim = tcore_plugin_ref_core_object(plg, CORE_OBJECT_TYPE_SIM);
905 sim_status = tcore_sim_get_status(co_sim);
906 if (sim_status == SIM_STATUS_INIT_COMPLETED)
909 sim_imsi = tcore_sim_get_imsi(co_sim);
910 flight_mode = tcore_modem_get_flight_mode_state(co_modem);
911 tcore_modem_get_modem_power_state(co_modem, &modem_power_state);
913 switch (modem_power_state) {
914 case MODEM_STATE_ONLINE:
915 power = PS_MODEM_STATE_ONLINE;
918 case MODEM_STATE_LOW:
919 power = PS_MODEM_STATE_LOW;
922 case MODEM_STATE_ERROR:
923 case MODEM_STATE_RESET:
925 ps_warn_ex_modem(modem, "Unhandled modem power event.");
929 _ps_modem_processing_flight_mode(ps_modem, flight_mode);
930 if (power != PS_MODEM_STATE_UNKNOWN)
931 _ps_modem_processing_power_enable(modem, power);
933 sim_type = tcore_sim_get_type(co_sim);
935 if (sim_type == SIM_TYPE_NVSIM)
936 _ps_modem_processing_sim_complete(ps_modem, sim_init, PS_CDMA_DUMMY_PROFILE_PLMN);
938 _ps_modem_processing_sim_complete(ps_modem, sim_init, sim_imsi->plmn);
943 gboolean _ps_get_co_network_values(ps_service_t *service)
945 CoreObject *co_network = NULL;
946 gboolean ps_attached = FALSE;
947 gint ps_restricted = 0;
949 enum telephony_network_service_domain_status ps_status;
950 enum telephony_network_access_technology act;
952 g_return_val_if_fail(service != NULL, FALSE);
954 co_network = _ps_service_ref_co_network(service);
955 ps_dbg_ex_svc(service, "Entered ");
957 tcore_network_get_service_status(co_network, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
958 tcore_network_get_access_technology(co_network, &act);
960 if (ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
963 ps_restricted = tcore_network_get_restricted_state(co_network);
965 _ps_service_set_restricted(service, ((ps_restricted == NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
966 _ps_service_set_roaming(service, tcore_network_get_roaming_state(co_network));
967 _ps_service_set_ps_attached(service, ps_attached);
968 _ps_service_set_access_technology(service, act);
973 gboolean _ps_add_co_ps_event(ps_service_t *service)
976 g_return_val_if_fail(service != NULL, FALSE);
977 ps_dbg_ex_svc(service, "Entered ");
978 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
979 tcore_server_add_notification_hook(s, TNOTI_PS_CALL_STATUS, __on_hook_call_status, service);
980 tcore_server_add_notification_hook(s, TNOTI_PS_PDP_IPCONFIGURATION, __on_hook_ipconfiguration, service);
981 tcore_server_add_notification_hook(s, TNOTI_PS_DEDICATED_BEARER_INFO, __on_hook_dedicated_bearerinfo, service);
982 tcore_server_add_notification_hook(s, TNOTI_NETWORK_DEFAULT_DATA_SUBSCRIPTION, __on_hook_default_data_subscription, service);
983 // tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_BACKOFF_TIMER, __on_hook_gprs_backoff_timer, service);
984 // tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_NAS_TIMER, __on_hook_gprs_nas_timer, service);
985 tcore_server_add_notification_hook(s, TNOTI_NETWORK_EPDG_STATUS, __on_hook_epdg_status, service);
986 tcore_object_add_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed, service);
990 gboolean _ps_add_co_network_event(ps_service_t *service)
994 g_return_val_if_fail(service != NULL, FALSE);
996 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
998 tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, __on_hook_net_register, service);
999 tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, __on_hook_net_change, service);
1000 tcore_server_add_notification_hook(s, TNOTI_NETWORK_RESTRICTED_STATE, __on_hook_net_restricted_state, service);
1005 gboolean _ps_add_co_modem_event(ps_modem_t *modem)
1009 g_return_val_if_fail(modem != NULL, FALSE);
1011 s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
1013 tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER, __on_hook_powered, modem);
1014 tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE, __on_hook_flight, modem);
1015 tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, __on_hook_sim_init, modem);
1016 // tcore_server_add_notification_hook(s, TNOTI_SIM_REFRESH_STAGE, __on_hook_sim_refresh, modem);
1017 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
1018 _ps_hook_add_modem_hooks(modem);
1023 gboolean _ps_free_co_ps_event(ps_service_t *service)
1026 g_return_val_if_fail(service != NULL, FALSE);
1027 ps_dbg_ex_svc(service, "Entered ");
1028 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
1029 tcore_object_del_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed);
1030 tcore_server_remove_notification_hook(s, __on_hook_call_status);
1031 tcore_server_remove_notification_hook(s, __on_hook_ipconfiguration);
1032 tcore_server_remove_notification_hook(s, __on_hook_dedicated_bearerinfo);
1033 tcore_server_remove_notification_hook(s, __on_hook_default_data_subscription);
1034 // tcore_server_remove_notification_hook(s, __on_hook_gprs_backoff_timer);
1035 // tcore_server_remove_notification_hook(s, __on_hook_gprs_nas_timer);
1036 tcore_server_remove_notification_hook(s, __on_hook_epdg_status);
1040 gboolean _ps_free_co_network_event(ps_service_t *service)
1043 g_return_val_if_fail(service != NULL, FALSE);
1044 ps_dbg_ex_svc(service, "Entered");
1045 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
1046 tcore_server_remove_notification_hook(s, __on_hook_net_register);
1047 tcore_server_remove_notification_hook(s, __on_hook_net_change);
1048 tcore_server_remove_notification_hook(s, __on_hook_net_restricted_state);
1052 gboolean _ps_free_co_modem_event(ps_modem_t *modem)
1055 g_return_val_if_fail(modem != NULL, FALSE);
1056 s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
1057 tcore_server_remove_notification_hook(s, __on_hook_powered);
1058 tcore_server_remove_notification_hook(s, __on_hook_flight);
1059 tcore_server_remove_notification_hook(s, __on_hook_sim_init);
1060 // tcore_server_remove_notification_hook(s, __on_hook_sim_refresh);
1064 gboolean _ps_update_cellular_state_key(ps_service_t *service)
1066 int current_state = 0;
1067 int stored_state = 0;
1069 ps_master_t *master;
1070 ps_subs_type subs_type;
1071 int selected_sim = -1;
1073 g_return_val_if_fail(service != NULL, FALSE);
1075 modem = _ps_service_ref_modem(service);
1076 master = _ps_modem_ref_master(modem);
1077 subs_type = _ps_modem_get_subs_type(modem);
1079 ps_dbg_ex_svc(service, "Update cellular state for [SIM%d]", subs_type + 1);
1081 selected_sim = _ps_master_get_storage_value_int(master, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
1082 if ((selected_sim != -1) && (selected_sim != (int)subs_type)) {
1083 ps_warn_ex_svc(service, "Update for only [SIM%d] selected by Setting", selected_sim + 1);
1087 current_state = _ps_service_check_cellular_state(service);
1089 if (tcore_modem_get_flight_mode_state(modem->co_modem) == TRUE)
1090 current_state = TELEPHONY_PS_FLIGHT_MODE;
1092 stored_state = _ps_master_get_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE);
1093 if (current_state != stored_state) {
1094 ps_info_ex_svc(service, "Cellular state, current: [%d], stored: [%d]", current_state, stored_state);
1095 _ps_master_set_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE, current_state);