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, struct tnoti_ps_call_status *cstatus, gboolean retry)
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);
209 static void __on_hook_status_NO_carrier(ps_modem_t *modem, ps_service_t *service,
210 CoreObject *co_ps, struct tnoti_ps_call_status *cstatus)
212 ps_context_t *def_context = NULL, *ims_context = NULL;
213 unsigned char def_cid = 0, ims_cid = 0;
215 gboolean retry = TRUE;
217 if (!modem || !service || !cstatus)
220 retry = ps_util_check_permanent_reject_cause(cstatus->result, _ps_modem_get_roaming(modem));
221 /* if retry not permitted by network */
222 if (FALSE == retry) {
223 ps_dbg_ex_modem(modem, "DO NOT RETRY NETWORK CONNECTION AUTOMATICALLY");
224 ps_info_ex_modem(modem, "permanent reject cause (%d), roaming(%d)", cstatus->result, _ps_modem_get_roaming(modem));
226 def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
228 CoreObject *co_context = _ps_context_ref_co_context(def_context);
229 def_cid = tcore_context_get_id(co_context);
232 ims_context = _ps_service_return_default_context(service, CONTEXT_ROLE_IMS);
234 CoreObject *co_context = _ps_context_ref_co_context(ims_context);
235 ims_cid = tcore_context_get_id(co_context);
239 _ps_service_set_ps_defined(service, FALSE, cstatus->context_id);
240 tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
241 tcore_ps_set_cid_connected(co_ps, cstatus->context_id, FALSE);
242 _ps_service_set_connected(service, cstatus, FALSE);
244 if (FALSE == tcore_ps_any_internet_mms_tethering_context_activating_activated(co_ps, &value)) {
245 ps_dbg_ex_modem(modem, "No context open connections, publish disconnected signal");
246 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
247 /* Handle any pending request if present */
248 modem = _ps_service_ref_modem(service);
249 _ps_hook_send_pending_user_request(modem);
251 /* Ensured that set_reset_profile is always done default thread's context */
252 if (_ps_modem_get_reset_profile(modem) == TRUE) {
253 /* Initiate Reset Profile */
254 ps_info_ex_modem(modem, "Profiles are being reset");
255 /* Shouldn't invoke set profile directly, as it will remove hooks registered to server while being hook callback*/
256 if (NULL == _ps_modem_get_profile_reset_gsource(modem)) {
257 GSource *gsource = NULL;
258 gsource = ps_util_gsource_dispatch(g_main_context_default(), G_PRIORITY_LOW, (GSourceFunc)_ps_modem_initiate_reset_profile, modem);
259 _ps_modem_set_profile_reset_gsource(modem, gsource);
264 #ifdef PREPAID_SIM_APN_SUPPORT
265 __on_call_status_for_prepaid_sim(service, def_context, modem, cstatus, retry);
268 ps_info_ex_modem(modem, "Any context activating or activated [%d]", value);
269 if (FALSE == retry) {
270 if (cstatus->context_id == def_cid) {
271 _ps_service_reset_connection_timer(def_context);
272 _ps_context_set_alwayson_enable(def_context, FALSE);
273 } else if (cstatus->context_id == ims_cid) {
274 _ps_service_reset_connection_timer(ims_context);
275 _ps_context_set_alwayson_enable(ims_context, FALSE);
280 static enum tcore_hook_return __on_hook_call_status(Server *s, CoreObject *source,
281 enum tcore_notification_command command, unsigned int data_len, void *data,
284 ps_modem_t *modem = NULL;
285 ps_service_t *service = user_data;
286 CoreObject *co_ps = NULL;
289 gboolean b_data_allowed = FALSE;
290 gboolean b_roaming_checker = TRUE;
291 gboolean b_mms_checker = FALSE;
292 gboolean b_ims_checker = FALSE;
293 gboolean b_allowed_on_data_off = FALSE;
295 struct tnoti_ps_call_status *cstatus = data;
297 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
299 co_ps = _ps_service_ref_co_ps(service);
300 if (co_ps != source) {
301 ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
302 return TCORE_HOOK_RETURN_CONTINUE;
305 modem = _ps_service_ref_modem(service);
307 ps_err_ex_modem(modem, "modem does not exist");
308 return TCORE_HOOK_RETURN_CONTINUE;
311 b_data_allowed = _ps_modem_get_data_allowed(modem);
313 co_list = tcore_ps_ref_context_by_id(co_ps, cstatus->context_id);
314 for (; co_list; co_list = co_list->next) {
315 CoreObject *co_context = NULL;
316 enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
318 co_context = co_list->data;
319 role = tcore_context_get_role(co_context);
321 if (role == CONTEXT_ROLE_MMS || role == CONTEXT_ROLE_PREPAID_MMS) {
322 b_mms_checker = TRUE;
325 if (role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY || role == CONTEXT_ROLE_IMS_UT) {
326 b_ims_checker = TRUE;
329 if (role == CONTEXT_ROLE_BIP || role == CONTEXT_ROLE_FOTA) {
330 b_allowed_on_data_off = TRUE;
335 #if !defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
336 ps_dbg_ex_modem(modem, "csc runtime feature disabled");
337 b_mms_checker = FALSE;
340 if (!b_ims_checker && (_ps_modem_get_roaming(modem)) && !(_ps_modem_get_data_roaming_allowed(modem))) {
341 ps_info_ex_modem(modem, "roaming network is not allowed");
342 b_roaming_checker = FALSE;
345 ps_info_ex_modem(modem, "data_allowed(%d) call status event cid(%d) state(%d) reason(%d)",
346 b_data_allowed, cstatus->context_id, cstatus->state, cstatus->result);
348 if (!b_roaming_checker || (!b_data_allowed && !b_mms_checker && !b_ims_checker && !b_allowed_on_data_off)) {
349 ps_dbg_ex_modem(modem, "mismatched: roaming checker(%d) data_allowed(%d) mms_checker(%d) b_ims_checker(%d)",
350 b_roaming_checker, b_data_allowed, b_mms_checker, b_ims_checker);
352 if (cstatus->state == PS_CALL_STATE_RESULT_OK) {
354 * If attach_apn_complete is FALSE, need to set TRUE.
355 * In case of boot-up with roaming-SIM and Data Roaming option disabled,
356 * although define process is triggered, 'attach_apn_complete' flag does not set TRUE.
357 * So, when Data Roaming option is enabled, pdp activation is not triggered.
359 if (service->attach_apn_complete) {
360 _ps_service_set_connected(service, cstatus, FALSE);
361 tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
363 _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
365 return TCORE_HOOK_RETURN_CONTINUE;
366 } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) {
367 _ps_service_set_connected(service, cstatus, TRUE);
368 _ps_service_disconnect_contexts(service);
369 return TCORE_HOOK_RETURN_CONTINUE;
373 ps_dbg_ex_modem(modem, "service(%p) status(%d)", service, cstatus->state);
374 if (cstatus->state == PS_CALL_STATE_RESULT_OK) { /* DEFINE */
375 _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
376 } else if (cstatus->state == PS_CALL_STATE_RESULT_CONNECT) { /* CONNECTED */
379 if (tcore_ps_get_cid_active(co_ps, cstatus->context_id) == FALSE) {
380 ps_dbg_ex_modem(modem, "DDS scenario");
382 /* De-activate context */
383 rv = tcore_ps_deactivate_contexts(co_ps);
384 if (rv != TCORE_RETURN_SUCCESS) {
385 ps_err_ex_modem(modem, "fail to deactivation");
386 return TCORE_HOOK_RETURN_CONTINUE;
390 gboolean need_deactivate = FALSE;
392 ret = _ps_service_set_connected(service, cstatus, TRUE);
393 tcore_ps_set_cid_connected(co_ps, cstatus->context_id, TRUE);
395 if (ret == FALSE || (_ps_modem_get_reset_profile(modem) == TRUE))
396 need_deactivate = TRUE;
398 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
399 if (g_queue_get_length(_ps_hook_ref_work_queue(modem)))
400 need_deactivate = TRUE;
403 if (need_deactivate) {
404 ps_info_ex_modem(modem, "Special request present in queue or pending activation request");
405 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
406 if (ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SEARCH) ||
407 ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) ||
408 ps_util_peek_waiting_job(_ps_hook_ref_work_queue(modem), TREQ_NETWORK_SET_PLMN_SELECTION_MODE)) {
410 gpointer key, tmp_service;
412 ps_info_ex_modem(modem, "Network search/selection/cancel searchrequest is in queue");
413 g_hash_table_iter_init(&iter, modem->services);
414 while (g_hash_table_iter_next(&iter, &key, &tmp_service) == TRUE)
415 _ps_service_disconnect_internet_mms_tethering_contexts(tmp_service);
419 rv = tcore_ps_deactivate_contexts(co_ps);
420 if (rv != TCORE_RETURN_SUCCESS) {
421 ps_dbg_ex_modem(modem, "fail to deactivation");
422 return TCORE_HOOK_RETURN_CONTINUE;
427 } else if (cstatus->state == PS_CALL_STATE_RESULT_NO_CARRIER) { /* DISCONNECTED-NO CARRIER */
428 __on_hook_status_NO_carrier(modem, service, co_ps, cstatus);
429 } /* disconnected case */
431 return TCORE_HOOK_RETURN_CONTINUE;
434 static enum tcore_hook_return __on_hook_dedicated_bearerinfo(Server *s, CoreObject *source,
435 enum tcore_notification_command command, unsigned int data_len, void *data,
438 ps_service_t *service = user_data;
439 CoreObject *co_ps = NULL;
440 struct tnoti_ps_dedicated_bearer_info *bearer_info = data;
442 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
444 co_ps = _ps_service_ref_co_ps(service);
446 return TCORE_HOOK_RETURN_CONTINUE;
448 _ps_service_set_context_bearerinfo(service, bearer_info);
449 ps_info_ex_svc(service, "dedicated bearer information event");
450 return TCORE_HOOK_RETURN_CONTINUE;
453 static enum tcore_hook_return __on_hook_default_data_subscription(Server *s, CoreObject *source,
454 enum tcore_notification_command command, unsigned int data_len, void *data,
457 ps_service_t *service = user_data;
458 const struct tnoti_network_default_data_subs *default_data_subs_info = data;
460 if (default_data_subs_info->default_subs != (enum telephony_network_default_data_subs)tcore_object_ref_subscription_type(_ps_service_ref_co_ps(service)))
461 return TCORE_HOOK_RETURN_CONTINUE;
463 ps_info_ex_svc(service, "'default' data subscription information event");
464 _ps_service_connect_default_context(service);
466 return TCORE_HOOK_RETURN_CONTINUE;
468 static enum tcore_hook_return __on_hook_epdg_status(Server *s, CoreObject *source,
469 enum tcore_notification_command command, unsigned int data_len, void *data,
472 ps_service_t *service = user_data;
473 const struct tnoti_network_epdg_status *noti = (const struct tnoti_network_epdg_status *)data;
474 gboolean available = FALSE;
476 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
477 g_return_val_if_fail(noti != NULL, TCORE_HOOK_RETURN_CONTINUE);
479 if ((noti->status == NETWORK_EPDG_STATUS_AVAILABLE) ||
480 (noti->status == NETWORK_EPDG_STATUS_CONNECTED) ||
481 (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)) {
485 ps_info_ex_svc(service, "ePDG: [%s]", ((available == TRUE) ? "AVAILABLE" : "UNAVAILABLE"));
486 _ps_service_set_epdg_status(service, available);
488 if (noti->status == NETWORK_EPDG_STATUS_HO_LTE_TO_IWLAN)
489 _ps_service_set_epdg_ip_configuration(service, noti->cid, noti->ipv4_address, noti->ipv6_address);
490 return TCORE_HOOK_RETURN_CONTINUE;
493 static enum tcore_hook_return __on_hook_ipconfiguration(Server *s, CoreObject *source,
494 enum tcore_notification_command command, unsigned int data_len, void *data,
497 ps_service_t *service = user_data;
498 CoreObject *co_ps = NULL;
499 struct tnoti_ps_pdp_ipconfiguration *devinfo = data;
500 char ipv4[16], ipv4_dns_1[16], ipv4_dns_2[16];
502 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
504 co_ps = _ps_service_ref_co_ps(service);
505 if (co_ps != source) {
506 ps_warn_ex_svc(service, "Received notification for different Subscription - neglecting the notification!!!");
507 return TCORE_HOOK_RETURN_CONTINUE;
510 ps_info_ex_svc(service, "ip configuration event");
513 * In case IPv4 address is available and DNS address
514 * is NOT available, set -
518 snprintf(ipv4, 16, "%d.%d.%d.%d",
519 devinfo->ip_address[0], devinfo->ip_address[1],
520 devinfo->ip_address[2], devinfo->ip_address[3]);
521 if (!g_str_equal(ipv4, "0.0.0.0")) {
522 snprintf(ipv4_dns_1, 16, "%d.%d.%d.%d",
523 devinfo->primary_dns[0], devinfo->primary_dns[1],
524 devinfo->primary_dns[2], devinfo->primary_dns[3]);
525 if (g_str_equal(ipv4_dns_1, "0.0.0.0")) {
526 ps_err_ex_svc(service, "[IPV4]primary dns address is 0");
529 devinfo->primary_dns[0] = 8;
530 devinfo->primary_dns[1] = 8;
531 devinfo->primary_dns[2] = 8;
532 devinfo->primary_dns[3] = 8;
535 snprintf(ipv4_dns_2, 16, "%d.%d.%d.%d",
536 devinfo->secondary_dns[0], devinfo->secondary_dns[1],
537 devinfo->secondary_dns[2], devinfo->secondary_dns[3]);
538 if (g_str_equal(ipv4_dns_2, "0.0.0.0")) {
540 ps_err_ex_svc(service, "[IPV4]secondary dns address is 0");
541 devinfo->secondary_dns[0] = 208;
542 devinfo->secondary_dns[1] = 67;
543 devinfo->secondary_dns[2] = 222;
544 devinfo->secondary_dns[3] = 222;
549 * In case IPv6 address is available and DNS address
550 * is NOT available, set -
554 if (devinfo->ipv6_address != NULL) {
555 if (devinfo->ipv6_primary_dns == NULL) {
556 ps_err_ex_svc(service, "[IPV6]primary dns address is 0");
557 devinfo->ipv6_primary_dns = g_strdup("2001:4860:4860::8888");
560 if (devinfo->ipv6_secondary_dns == NULL) {
561 ps_err_ex_svc(service, "[IPV6]secondary dns address is 0");
562 devinfo->ipv6_secondary_dns = g_strdup("2620:0:ccc::2");
566 _ps_service_set_context_devinfo(service, devinfo);
568 return TCORE_HOOK_RETURN_CONTINUE;
571 static enum tcore_hook_return __on_hook_powered(Server *s, CoreObject *source,
572 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
574 ps_modem_t *modem = user_data;
575 CoreObject *co_modem;
576 struct tnoti_modem_power *modem_power = data;
577 int power = PS_MODEM_STATE_UNKNOWN;
579 CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE);
581 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
582 g_return_val_if_fail(modem_power != NULL, TCORE_HOOK_RETURN_CONTINUE);
584 co_modem = _ps_modem_ref_co_modem(modem);
585 if (co_modem != source) {
586 ps_dbg_ex_modem(modem, "Notification for other modem!");
587 return TCORE_HOOK_RETURN_CONTINUE;
590 ps_info_ex_modem(modem, "powered event called: state [%d]", modem_power->state);
592 switch (modem_power->state) {
593 case MODEM_STATE_ONLINE:
594 power = PS_MODEM_STATE_ONLINE;
597 case MODEM_STATE_LOW:
598 power = PS_MODEM_STATE_LOW;
601 case MODEM_STATE_ERROR:
602 case MODEM_STATE_RESET:
603 /* Reset hook flag in any present */
604 __ps_modem_cp_reset_handler(modem);
608 ps_warn_ex_modem(modem, "Unhandled modem power event.");
612 if (power != PS_MODEM_STATE_UNKNOWN)
613 _ps_modem_processing_power_enable(modem, power);
615 return TCORE_HOOK_RETURN_CONTINUE;
618 static enum tcore_hook_return __on_hook_flight(Server *s, CoreObject *source,
619 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
621 ps_modem_t *modem = user_data;
622 struct tnoti_modem_flight_mode *modem_flight = data;
624 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
625 ps_info_ex_modem(modem, "flight mode event called");
627 _ps_modem_processing_flight_mode(modem, modem_flight->enable);
629 return TCORE_HOOK_RETURN_CONTINUE;
632 static enum tcore_hook_return __on_hook_net_register(Server *s, CoreObject *source,
633 enum tcore_notification_command command, unsigned int data_len, void *data,
636 ps_service_t *service = user_data;
637 gboolean ps_attached = FALSE;
638 struct tnoti_network_registration_status *regist_status = data;
639 CoreObject *co_network;
641 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
643 co_network = _ps_service_ref_co_network(service);
644 if (co_network != source)
645 return TCORE_HOOK_RETURN_CONTINUE;
647 if (regist_status->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
650 _ps_modem_set_roaming(_ps_service_ref_modem(service), regist_status->roaming_status);
651 _ps_service_processing_network_event(service, ps_attached, regist_status->roaming_status);
653 return TCORE_HOOK_RETURN_CONTINUE;
656 static enum tcore_hook_return __on_hook_net_change(Server *s, CoreObject *source,
657 enum tcore_notification_command command, unsigned int data_len, void *data,
660 ps_service_t *service = user_data;
661 struct tnoti_network_change *network_change = data;
662 CoreObject *co_network;
664 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
666 co_network = _ps_service_ref_co_network(service);
667 if (co_network != source)
668 return TCORE_HOOK_RETURN_CONTINUE;
670 ps_dbg_ex_svc(service, "plmn(%s) act(%d)", network_change->plmn, network_change->act);
671 _ps_service_set_access_technology(service, network_change->act);
673 return TCORE_HOOK_RETURN_CONTINUE;
676 static enum tcore_hook_return __on_hook_net_restricted_state(Server *s, CoreObject *source,
677 enum tcore_notification_command command, unsigned int data_len, void *data,
680 ps_service_t *service = user_data;
681 struct tnoti_network_restricted_state *network_restricted = data;
682 CoreObject *co_network;
684 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
686 co_network = _ps_service_ref_co_network(service);
687 if (co_network != source)
688 return TCORE_HOOK_RETURN_CONTINUE;
690 ps_dbg_ex_svc(service, "network restricted state(%d)", network_restricted->restricted_state);
691 _ps_service_set_restricted(service, ((network_restricted->restricted_state & NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
693 return TCORE_HOOK_RETURN_CONTINUE;
696 static enum tcore_hook_return __on_hook_sim_init(Server *s, CoreObject *source,
697 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
699 struct tnoti_sim_status *sim_data = data;
700 ps_modem_t *modem = user_data;
701 const gchar *cp_name, *source_cp_name;
703 ps_info_ex_modem(modem, "sim init event called");
705 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
707 cp_name = _ps_modem_ref_cp_name(modem);
708 source_cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
709 if (g_strcmp0(cp_name, source_cp_name) != 0) {
710 ps_dbg_ex_modem(modem, "Received notification for different Subscription - neglecting the notification!!!");
711 return TCORE_HOOK_RETURN_CONTINUE;
714 ps_info_ex_modem(modem, "sim status is (%d)", sim_data->sim_status);
716 switch (sim_data->sim_status) {
717 case SIM_STATUS_INITIALIZING:
720 case SIM_STATUS_INIT_COMPLETED: {
721 struct tel_sim_imsi *sim_imsi = NULL;
722 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
723 sim_type = tcore_sim_get_type(source);
725 if (sim_type == SIM_TYPE_NVSIM) {
726 ps_info_ex_modem(modem, "initial boot from CDMA network.");
727 _ps_modem_processing_sim_complete(modem, TRUE, PS_CDMA_DUMMY_PROFILE_PLMN);
729 sim_imsi = tcore_sim_get_imsi(source);
730 _ps_modem_processing_sim_complete(modem, TRUE, sim_imsi->plmn);
736 case SIM_STATUS_CARD_ERROR: /* FALLTHROUGH */
737 case SIM_STATUS_CARD_REMOVED: /* FALLTHROUGH */
738 case SIM_STATUS_CARD_CRASHED: /* FALLTHROUGH */
739 case SIM_STATUS_CARD_POWEROFF:
740 /* Set SIM complete FALSE, operator is not required */
741 _ps_modem_processing_sim_complete(modem, FALSE, NULL);
742 _ps_modem_processing_no_sim(modem);
745 case SIM_STATUS_CARD_NOT_PRESENT:
746 _ps_modem_processing_no_sim(modem);
750 ps_dbg_ex_modem(modem, "Unhandled SIM state: [%d]", sim_data->sim_status);
751 _ps_modem_processing_no_sim(modem);
755 return TCORE_HOOK_RETURN_CONTINUE;
759 #ifdef TIZEN_SUPPORT_VOLTE
760 static enum tcore_hook_return __on_hook_sim_refresh(Server *s, CoreObject *source,
761 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
763 struct tnoti_sim_refresh_stage *sim_data = data;
764 ps_modem_t *modem = user_data;
766 ps_info_ex_modem(modem, "sim stage is (%d)", sim_data->stage);
768 if (sim_data->stage == SIM_REFRESH_START)
769 _ps_modem_processing_sim_refresh(modem);
770 return TCORE_HOOK_RETURN_CONTINUE;
774 enum tcore_hook_return __on_hook_modem_added(Server *s,
775 CoreObject *source, enum tcore_notification_command command,
776 unsigned int data_len, void *data, void *user_data)
778 ps_master_t *master = user_data;
779 TcorePlugin *plg = data;
781 if (FALSE == _ps_master_create_modems(master, plg))
782 err("[%s] Failed to create modem", tcore_server_get_cp_name_by_plugin(plg));
784 return TCORE_HOOK_RETURN_CONTINUE;
787 enum tcore_hook_return __on_hook_modem_removed(Server *s,
788 CoreObject *source, enum tcore_notification_command command,
789 unsigned int data_len, void *data, void *user_data)
791 ps_master_t *master = user_data;
792 TcorePlugin *plg = data;
794 if (FALSE == _ps_master_destroy_modem(master, plg))
795 err("Failed to destroy modem[%s]", tcore_server_get_cp_name_by_plugin(plg));
797 return TCORE_HOOK_RETURN_CONTINUE;
800 gboolean _ps_get_co_modem_values(ps_modem_t *modem)
803 CoreObject *co_modem = NULL;
804 CoreObject *co_sim = NULL;
805 ps_modem_t *ps_modem = modem;
807 gboolean sim_init = FALSE, flight_mode = FALSE;
808 enum modem_state modem_power_state = MODEM_STATE_UNKNOWN;
810 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
811 struct tel_sim_imsi *sim_imsi = NULL;
812 int power = PS_MODEM_STATE_UNKNOWN;
814 g_return_val_if_fail(ps_modem != NULL, FALSE);
816 co_modem = _ps_modem_ref_co_modem(ps_modem);
820 plg = tcore_object_ref_plugin(co_modem);
824 co_sim = tcore_plugin_ref_core_object(plg, CORE_OBJECT_TYPE_SIM);
826 sim_status = tcore_sim_get_status(co_sim);
827 if (sim_status == SIM_STATUS_INIT_COMPLETED)
830 sim_imsi = tcore_sim_get_imsi(co_sim);
831 flight_mode = tcore_modem_get_flight_mode_state(co_modem);
832 tcore_modem_get_modem_power_state(co_modem, &modem_power_state);
834 switch (modem_power_state) {
835 case MODEM_STATE_ONLINE:
836 power = PS_MODEM_STATE_ONLINE;
839 case MODEM_STATE_LOW:
840 power = PS_MODEM_STATE_LOW;
843 case MODEM_STATE_ERROR:
844 case MODEM_STATE_RESET:
846 ps_warn_ex_modem(modem, "Unhandled modem power event.");
850 _ps_modem_processing_flight_mode(ps_modem, flight_mode);
851 if (power != PS_MODEM_STATE_UNKNOWN)
852 _ps_modem_processing_power_enable(modem, power);
854 sim_type = tcore_sim_get_type(co_sim);
856 if (sim_type == SIM_TYPE_NVSIM)
857 _ps_modem_processing_sim_complete(ps_modem, sim_init, PS_CDMA_DUMMY_PROFILE_PLMN);
859 _ps_modem_processing_sim_complete(ps_modem, sim_init, sim_imsi->plmn);
864 gboolean _ps_get_co_network_values(ps_service_t *service)
866 CoreObject *co_network = NULL;
867 gboolean ps_attached = FALSE;
868 gint ps_restricted = 0;
870 enum telephony_network_service_domain_status ps_status;
871 enum telephony_network_access_technology act;
873 g_return_val_if_fail(service != NULL, FALSE);
875 co_network = _ps_service_ref_co_network(service);
876 ps_dbg_ex_svc(service, "Entered ");
878 tcore_network_get_service_status(co_network, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
879 tcore_network_get_access_technology(co_network, &act);
881 if (ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
884 ps_restricted = tcore_network_get_restricted_state(co_network);
886 _ps_service_set_restricted(service, ((ps_restricted == NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
887 _ps_service_set_roaming(service, tcore_network_get_roaming_state(co_network));
888 _ps_service_set_ps_attached(service, ps_attached);
889 _ps_service_set_access_technology(service, act);
894 gboolean _ps_add_co_ps_event(ps_service_t *service)
897 g_return_val_if_fail(service != NULL, FALSE);
898 ps_dbg_ex_svc(service, "Entered ");
899 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
900 tcore_server_add_notification_hook(s, TNOTI_PS_CALL_STATUS, __on_hook_call_status, service);
901 tcore_server_add_notification_hook(s, TNOTI_PS_PDP_IPCONFIGURATION, __on_hook_ipconfiguration, service);
902 tcore_server_add_notification_hook(s, TNOTI_PS_DEDICATED_BEARER_INFO, __on_hook_dedicated_bearerinfo, service);
903 tcore_server_add_notification_hook(s, TNOTI_NETWORK_DEFAULT_DATA_SUBSCRIPTION, __on_hook_default_data_subscription, service);
904 // tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_BACKOFF_TIMER, __on_hook_gprs_backoff_timer, service);
905 // tcore_server_add_notification_hook(s, TNOTI_PS_GPRS_NAS_TIMER, __on_hook_gprs_nas_timer, service);
906 tcore_server_add_notification_hook(s, TNOTI_NETWORK_EPDG_STATUS, __on_hook_epdg_status, service);
907 tcore_object_add_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed, service);
911 gboolean _ps_add_co_network_event(ps_service_t *service)
915 g_return_val_if_fail(service != NULL, FALSE);
917 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
919 tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, __on_hook_net_register, service);
920 tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, __on_hook_net_change, service);
921 tcore_server_add_notification_hook(s, TNOTI_NETWORK_RESTRICTED_STATE, __on_hook_net_restricted_state, service);
926 gboolean _ps_add_co_modem_event(ps_modem_t *modem)
930 g_return_val_if_fail(modem != NULL, FALSE);
932 s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
934 tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER, __on_hook_powered, modem);
935 tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE, __on_hook_flight, modem);
936 tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, __on_hook_sim_init, modem);
937 // tcore_server_add_notification_hook(s, TNOTI_SIM_REFRESH_STAGE, __on_hook_sim_refresh, modem);
938 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
939 _ps_hook_add_modem_hooks(modem);
944 gboolean _ps_free_co_ps_event(ps_service_t *service)
947 g_return_val_if_fail(service != NULL, FALSE);
948 ps_dbg_ex_svc(service, "Entered ");
949 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
950 tcore_object_del_callback(_ps_service_ref_co_ps(service), CORE_OBJECT_EVENT_PROPERTY_CHANGED, __ps_on_prop_changed);
951 tcore_server_remove_notification_hook(s, __on_hook_call_status);
952 tcore_server_remove_notification_hook(s, __on_hook_ipconfiguration);
953 tcore_server_remove_notification_hook(s, __on_hook_dedicated_bearerinfo);
954 tcore_server_remove_notification_hook(s, __on_hook_default_data_subscription);
955 // tcore_server_remove_notification_hook(s, __on_hook_gprs_backoff_timer);
956 // tcore_server_remove_notification_hook(s, __on_hook_gprs_nas_timer);
957 tcore_server_remove_notification_hook(s, __on_hook_epdg_status);
961 gboolean _ps_free_co_network_event(ps_service_t *service)
964 g_return_val_if_fail(service != NULL, FALSE);
965 ps_dbg_ex_svc(service, "Entered");
966 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
967 tcore_server_remove_notification_hook(s, __on_hook_net_register);
968 tcore_server_remove_notification_hook(s, __on_hook_net_change);
969 tcore_server_remove_notification_hook(s, __on_hook_net_restricted_state);
973 gboolean _ps_free_co_modem_event(ps_modem_t *modem)
976 g_return_val_if_fail(modem != NULL, FALSE);
977 s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
978 tcore_server_remove_notification_hook(s, __on_hook_powered);
979 tcore_server_remove_notification_hook(s, __on_hook_flight);
980 tcore_server_remove_notification_hook(s, __on_hook_sim_init);
981 // tcore_server_remove_notification_hook(s, __on_hook_sim_refresh);
985 gboolean _ps_update_cellular_state_key(ps_service_t *service)
987 int current_state = 0;
988 int stored_state = 0;
991 ps_subs_type subs_type;
992 int selected_sim = -1;
994 g_return_val_if_fail(service != NULL, FALSE);
996 modem = _ps_service_ref_modem(service);
997 master = _ps_modem_ref_master(modem);
998 subs_type = _ps_modem_get_subs_type(modem);
1000 ps_dbg_ex_svc(service, "Update cellular state for [SIM%d]", subs_type + 1);
1002 selected_sim = _ps_master_get_storage_value_int(master, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
1003 if ((selected_sim != -1) && (selected_sim != (int)subs_type)) {
1004 ps_warn_ex_svc(service, "Update for only [SIM%d] selected by Setting", selected_sim + 1);
1008 current_state = _ps_service_check_cellular_state(service);
1010 if (tcore_modem_get_flight_mode_state(modem->co_modem) == TRUE)
1011 current_state = TELEPHONY_PS_FLIGHT_MODE;
1013 stored_state = _ps_master_get_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE);
1014 if (current_state != stored_state) {
1015 ps_info_ex_svc(service, "Cellular state, current: [%d], stored: [%d]", current_state, stored_state);
1016 _ps_master_set_storage_value_int(master, STORAGE_KEY_CELLULAR_STATE, current_state);