2 * PacketService Control Module
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.
28 #include <co_context.h>
31 #include <type/network.h>
32 #include <co_network.h>
33 #ifdef POWER_SAVING_FEATURE_WEARABLE
36 #include <user_request.h>
38 #define TIMEOUT_MAX 1280
41 PS_CALL_STATE_RESULT_OK = 0x00,
42 PS_CALL_STATE_RESULT_CONNECT = 0x01,
43 PS_CALL_STATE_RESULT_NO_CARRIER = 0x03
46 struct work_queue_data {
51 static void __ps_modem_set_hook_flag(ps_modem_t *modem ,enum tcore_request_command cmd);
52 static void __ps_modem_get_mode_pref_change(ps_modem_t* modem, UserRequest *ur);
55 #ifdef POWER_SAVING_FEATURE_WEARABLE
56 static gboolean __ps_is_any_call_in_progress(TcorePlugin *plugin, __ps_call_flow_type type, enum tcore_notification_command command);
57 static enum tcore_hook_return __on_hook_voice_call_status(Server *s, CoreObject *co_call,
58 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data);
62 static gboolean ps_util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur)
64 struct work_queue_data *wqd;
69 wqd = calloc(sizeof(struct work_queue_data), 1);
75 g_queue_push_tail(queue, wqd);
77 dbg("id = %d, ur = 0x%x", wqd->id, wqd->ur);
81 static guint ps_util_get_count_waiting_job(GQueue *queue, unsigned int id)
85 struct work_queue_data *wqd = NULL;
90 dbg("job count: %d", g_queue_get_length(queue));
93 wqd = g_queue_peek_nth(queue, i);
102 } while (wqd != NULL);
104 dbg("count: %d, id = %d", count, id);
109 static UserRequest *ps_util_pop_waiting_job(GQueue *queue, unsigned int id)
113 struct work_queue_data *wqd;
118 dbg("before waiting job count: %d", g_queue_get_length(queue));
121 wqd = g_queue_peek_nth(queue, i);
126 wqd = g_queue_pop_nth(queue, i);
131 } while (wqd != NULL);
133 dbg("after waiting job count: %d", g_queue_get_length(queue));
144 static gboolean __ps_check_pdp_permanent_reject_cause(int cause)
148 // default ME's policy (same with Android OS 4.4)
149 if(ps_feature_get_bool(PS_FEATURE_OPERATOR_NA_ATT) ||
150 ps_feature_get_bool(PS_FEATURE_OPERATOR_NA_TMO) ||
151 ps_feature_get_bool(PS_FEATURE_OPERATOR_SKT) ||
152 ps_feature_get_bool(PS_FEATURE_OPERATOR_KT)) {
154 case PS_PDP_PERMANENT_REJECT_OPERATOR_DETERMINED_BARRING:
155 case PS_PDP_PERMANENT_REJECT_UNKNOWN_APN:
156 case PS_PDP_PERMANENT_REJECT_UNKNOWN_PDP:
157 case PS_PDP_PERMANENT_REJECT_AUTH_FAILED:
158 case PS_PDP_PERMANENT_REJECT_GGSN_REJECT:
159 case PS_PDP_PERMANENT_REJECT_OPTION_NOT_SUPPORTED:
160 case PS_PDP_PERMANENT_REJECT_OPTION_UNSUBSCRIBED: {
161 dbg("Permanent reject cause");
168 if(ps_feature_get_bool(PS_FEATURE_OPERATOR_KT)) {
170 case PS_PDP_PERMANENT_REJECT_NSAPI_ALREADY_USED:
171 case PS_PDP_PERMANENT_REJECT_PROTOCOL_ERROR:{
172 dbg("Permanent reject cause");
179 if(ps_feature_get_bool(PS_FEATURE_OPERATOR_SKT)) {
181 case PS_PDP_PERMANENT_REJECT_LLC_SNDCP_FAILURE:
182 case PS_PDP_PERMANENT_REJECT_OPTION_TEMP_OOO:
183 case PS_PDP_PERMANENT_REJECT_NSAPI_ALREADY_USED:
184 case PS_PDP_PERMANENT_REJECT_IP_V4_ONLY_ALLOWED:
185 case PS_PDP_PERMANENT_REJECT_IP_V6_ONLY_ALLOWED:
186 case PS_PDP_PERMANENT_REJECT_SINGLE_ADDR_BEARER_ONLY:
187 case PS_PDP_PERMANENT_REJECT_MESSAGE_INCORRECT_SEMANTIC:
188 case PS_PDP_PERMANENT_REJECT_INVALID_MANDATORY_INFO:
189 case PS_PDP_PERMANENT_REJECT_MESSAGE_TYPE_UNSUPPORTED:
190 case PS_PDP_PERMANENT_REJECT_MSG_TYPE_NONCOMPATIBLE_STATE:
191 case PS_PDP_PERMANENT_REJECT_UNKNOWN_INFO_ELEMENT:
192 case PS_PDP_PERMANENT_REJECT_CONDITIONAL_IE_ERROR:
193 case PS_PDP_PERMANENT_REJECT_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE:
194 case PS_PDP_PERMANENT_REJECT_PROTOCOL_ERROR:
195 case PS_PDP_PERMANENT_REJECT_APN_TYPE_CONFLICT: {
196 dbg("Permanent reject cause");
206 static gboolean __ps_set_network_mode(int mode, void *data)
209 gboolean roaming = FALSE;
210 struct treq_network_set_mode req;
212 UserRequest *ur = NULL;
213 ps_modem_t *modem = data;
215 GSList *co_list = NULL;
216 CoreObject *co_network = NULL;
218 co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
219 CORE_OBJECT_TYPE_NETWORK);
221 if (G_UNLIKELY(co_list == NULL)) {
225 memset(&req,0,sizeof(struct treq_network_set_mode));
227 co_network = (CoreObject *) co_list->data;
229 dbg("current network mode (%d)", c_mode);
231 if(modem->data_allowed) {
232 c_mode |= NETWORK_MODE_LTE;
235 c_mode &= ~NETWORK_MODE_LTE;
237 dbg("network mode(%d) - data allowed(%d)", c_mode, modem->data_allowed);
239 roaming = tcore_network_get_roaming_state(co_network);
240 if(modem->data_allowed && roaming) {
241 c_mode &= ~NETWORK_MODE_LTE;
243 dbg("network mode(%d) - roaming(%d)", c_mode, roaming);
245 dbg("candidate mode(%d), current mode(%d)", c_mode, mode);
247 dbg("mode is the same as before, do not send");
248 g_slist_free(co_list);
254 ur = tcore_user_request_new(NULL, tcore_plugin_ref_plugin_name(tcore_object_ref_plugin(co_network)));
255 tcore_user_request_set_data(ur, sizeof(struct treq_network_set_mode), &req);
256 tcore_user_request_set_command(ur, TREQ_NETWORK_SET_MODE);
257 //tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
258 //tcore_object_dispatch_request(co_network, ur);
260 //ps_handle_hook(tcore_plugin_ref_server(tcore_object_ref_plugin(modem->co_modem)), ur, modem);
261 if(TCORE_RETURN_SUCCESS != tcore_server_dispatch_request(tcore_plugin_ref_server(tcore_object_ref_plugin(modem->co_modem)), ur)) {
262 err("Failed to dispatch ");
263 tcore_user_request_unref(ur);
266 g_slist_free(co_list);
270 /* Function will be used in case any dispatch request failed in ps plugin */
271 static void __ps_send_ur_dispatch_failure_response(UserRequest *ur, enum tcore_response_command command)
273 dbg("User request dispatch failed so need to send response for command [%d]", command);
275 case TRESP_NETWORK_SEARCH:
277 struct tresp_network_search search_rsp;
278 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
280 search_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
281 search_rsp.list_count = 0;
282 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH,
283 sizeof(struct tresp_network_search), &search_rsp);
286 case TRESP_NETWORK_SET_PLMN_SELECTION_MODE:
288 struct tresp_network_set_plmn_selection_mode set_plmn_selection_mode_rsp;
289 memset(&set_plmn_selection_mode_rsp, 0, sizeof(struct tresp_network_set_plmn_selection_mode));
291 set_plmn_selection_mode_rsp.result = TCORE_RETURN_FAILURE;
292 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE,
293 sizeof(struct tresp_network_set_plmn_selection_mode), &set_plmn_selection_mode_rsp);
296 case TRESP_NETWORK_SET_MODE:
298 struct tresp_network_set_mode set_rsp;
299 memset(&set_rsp, 0, sizeof(struct tresp_network_set_mode));
301 set_rsp.result = TCORE_RETURN_FAILURE;
302 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_MODE,
303 sizeof(struct tresp_network_search), &set_rsp);
306 case TRESP_NETWORK_GET_MODE:
308 struct tresp_network_get_mode get_rsp;
309 memset(&get_rsp, 0, sizeof(struct tresp_network_get_mode));
311 get_rsp.result = TCORE_RETURN_FAILURE;
312 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_MODE,
313 sizeof(struct tresp_network_get_mode), &get_rsp);
316 case TRESP_MODEM_POWER_OFF:
318 struct tresp_modem_power_off set_power_off_rsp;
319 memset(&set_power_off_rsp, 0, sizeof(struct tresp_modem_power_off));
321 set_power_off_rsp.result = TCORE_RETURN_FAILURE;
322 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_OFF,
323 sizeof(struct tresp_modem_power_off), &set_power_off_rsp);
326 case TRESP_MODEM_POWER_LOW:
328 struct tresp_modem_power_low set_power_low_rsp;
329 memset(&set_power_low_rsp, 0, sizeof(struct tresp_modem_power_low));
331 set_power_low_rsp.result = TCORE_RETURN_FAILURE;
332 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_LOW,
333 sizeof(struct tresp_modem_power_low), &set_power_low_rsp);
336 case TRESP_MODEM_SET_FLIGHTMODE:
338 struct tresp_modem_set_flightmode set_flight_mode_rsp;
339 memset(&set_flight_mode_rsp, 0, sizeof(struct tresp_modem_set_flightmode));
341 set_flight_mode_rsp.result = TCORE_RETURN_FAILURE;
342 tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE,
343 sizeof(struct tresp_modem_set_flightmode), &set_flight_mode_rsp);
347 err("Command type not expected [%d]", command);
349 /* Unref User request */
350 tcore_user_request_unref( ur);
353 void __ps_hook_response_cb(UserRequest *ur, enum tcore_response_command command,
354 unsigned int data_len, const void *data, void *user_data)
356 ps_modem_t *modem = user_data;
357 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
360 id = ((command & ~TCORE_RESPONSE) & TCORE_REQUEST);
362 ps_dbg_ex_co(co_modem, "Entered");
363 count = ps_util_get_count_waiting_job(modem->work_queue, id);
366 ur = ps_util_pop_waiting_job(modem->work_queue, id);
368 GSList *co_list = NULL;
369 CoreObject *co_network = NULL;
370 TReturn ret = TCORE_RETURN_SUCCESS;
372 co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
373 CORE_OBJECT_TYPE_NETWORK);
375 if (G_UNLIKELY(co_list == NULL)) {
376 ps_err_ex_co(co_modem, "Network CoreObject is not present");
380 co_network = (CoreObject *) co_list->data;
381 g_slist_free(co_list);
383 ps_dbg_ex_co(co_modem, "Sending Pending Request of type = id", id);
384 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
385 if((command == TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH)
386 || (command == TRESP_NETWORK_SEARCH)
387 || (command == TRESP_NETWORK_SET_PLMN_SELECTION_MODE)
388 ||(command == TRESP_NETWORK_SET_MODE)
389 || (command ==TRESP_NETWORK_GET_MODE))
390 ret = tcore_object_dispatch_request(co_network , ur);
391 else if ((command == TRESP_MODEM_SET_FLIGHTMODE)
392 || (command == TRESP_MODEM_POWER_LOW)
393 || (command == TRESP_MODEM_POWER_OFF))
394 ret = tcore_object_dispatch_request(modem->co_modem , ur);
395 if(TCORE_RETURN_SUCCESS != ret) {
396 /* send responce wrt to command */
397 err("Failed to dispatch request, need to sent response to dbus")
398 __ps_send_ur_dispatch_failure_response(ur, command);
405 case TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH:
406 case TRESP_NETWORK_SEARCH:
407 ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SEARCH response received");
409 modem->hook_flag &= PS_RESET_NETWORK_SEARCH_FLAG;
412 case TRESP_NETWORK_SET_PLMN_SELECTION_MODE:
413 ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SET_PLMN_SELECTION_MODE response received ");
415 modem->hook_flag &= PS_NETWORK_RESET_SELECTION_FLAG;
418 case TRESP_NETWORK_SET_MODE:
420 ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SET_MODE response received ");
423 modem->hook_flag &= PS_NETWORK_RESET_SELECT_MODE_FLAG ;
427 case TRESP_NETWORK_GET_MODE:{
429 const struct tresp_network_get_mode *resp_get_mode = data;
430 dbg("TRESP_NETWORK_GET_MODE response received mode (mode:[%d])", resp_get_mode->mode);
433 modem->hook_flag &= PS_NETWORK_RESET_GET_MODE_FLAG;
436 rv = __ps_set_network_mode(resp_get_mode->mode, modem);
438 dbg("network set mode request!");
442 case TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
443 ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION response received ");
445 modem->hook_flag &= PS_NETWORK_RESET_SET_DEFAULT_DATA_SUBS;
448 case TRESP_MODEM_SET_FLIGHTMODE:
449 ps_dbg_ex_co(co_modem, "TRESP_MODEM_SET_FLIGHTMODE response received ");
451 modem->hook_flag &= PS_NETWORK_RESET_SET_FLIGHT_MODE_FLAG;
454 case TRESP_MODEM_POWER_LOW:
455 ps_dbg_ex_co(co_modem, "TRESP_MODEM_POWER_LOW response received ");
457 modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_LOW_FLAG;
460 case TRESP_MODEM_POWER_OFF:
461 ps_dbg_ex_co(co_modem, "TRESP_MODEM_POWER_OFF response received ");
463 modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_OFF_FLAG;
466 case TRESP_SIM_SET_POWERSTATE:
467 ps_dbg_ex_co(co_modem, "TRESP_SIM_SET_POWERSTATE response received ");
469 modem->hook_flag &= PS_SIM_SET_POWER_STATE_FLAG;
473 ps_dbg_ex_co(co_modem, "Unexpected response ");
476 ps_dbg_ex_co(co_modem, " FLAG %x", modem->hook_flag);
478 if(modem->hook_flag == PS_NO_PENDING_REQUEST
479 && command != TRESP_MODEM_POWER_LOW
480 && command != TRESP_MODEM_POWER_OFF
481 && modem->mode_pref_changed == FALSE) {
482 _ps_modem_set_data_allowed(modem, modem->data_allowed);
486 void __ps_modem_get_mode_pref_change(ps_modem_t* modem, UserRequest *ur)
488 enum telephony_network_service_type svc_type;
489 enum tcore_request_command cmd;
490 GSList *co_list = NULL;
492 cmd = tcore_user_request_get_command(ur);
493 if(cmd != TREQ_NETWORK_SET_MODE) {
494 err("Not a TREQ_NETWORK_SET_MODE");
495 modem->mode_pref_changed = FALSE;
498 modem->mode_pref_changed = TRUE;
500 co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem), CORE_OBJECT_TYPE_NETWORK);
501 if (G_LIKELY(co_list != NULL)) {
502 CoreObject *co_network = NULL;
503 const struct treq_network_set_mode *req;
505 co_network = (CoreObject *) co_list->data;
506 req = tcore_user_request_ref_data(ur, NULL);
507 tcore_network_get_service_type(co_network, &svc_type);
508 dbg("mode_pref[0x%x], svc_type[%d]", req->mode, svc_type);
510 case NETWORK_SERVICE_TYPE_2G:
511 case NETWORK_SERVICE_TYPE_2_5G:
512 case NETWORK_SERVICE_TYPE_2_5G_EDGE: {
513 if(req->mode == NETWORK_MODE_GSM)
514 modem->mode_pref_changed = FALSE;
517 case NETWORK_SERVICE_TYPE_3G:
518 case NETWORK_SERVICE_TYPE_HSDPA: {
519 if(req->mode & NETWORK_MODE_WCDMA)
520 modem->mode_pref_changed = FALSE;
522 case NETWORK_SERVICE_TYPE_LTE: {
523 if(req->mode & NETWORK_MODE_LTE)
524 modem->mode_pref_changed = FALSE;
530 dbg("mode_pref_changed : %d", modem->mode_pref_changed);
533 void __ps_modem_cp_reset_send_pending_request_response(gpointer data)
535 gpointer *queue_data = NULL;
536 ps_modem_t *modem = data;
537 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
539 ps_dbg_ex_co(co_modem, "Entered");
540 queue_data = g_queue_pop_head(modem->work_queue);
542 struct work_queue_data *wqd = (struct work_queue_data *)queue_data ;
544 enum tcore_request_command cmd = tcore_user_request_get_command(wqd->ur);
546 if(cmd == TREQ_NETWORK_SEARCH){
547 struct tresp_network_search search_rsp;
548 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
550 search_rsp.result = TCORE_RETURN_FAILURE;
551 search_rsp.list_count = 0;
552 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SEARCH,
553 sizeof(struct tresp_network_search), &search_rsp);
555 else if(cmd == TREQ_NETWORK_SET_PLMN_SELECTION_MODE){
556 struct tresp_network_set_plmn_selection_mode set_plmn_mode_rsp;
557 memset(&set_plmn_mode_rsp, 0, sizeof(struct tresp_network_set_plmn_selection_mode));
559 set_plmn_mode_rsp.result = TCORE_RETURN_FAILURE;
560 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE,
561 sizeof(struct tresp_network_set_plmn_selection_mode), &set_plmn_mode_rsp);
563 else if(cmd == TREQ_NETWORK_SET_MODE){
564 struct tresp_network_set_mode setmode_rsp;
565 memset(&setmode_rsp, 0, sizeof(struct tresp_network_set_mode));
567 setmode_rsp.result = TCORE_RETURN_FAILURE;
568 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_MODE,
569 sizeof(struct tresp_network_set_mode), &setmode_rsp);
571 else if(cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH){
572 struct tresp_network_set_cancel_manual_search search_cancel_rsp;
573 memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
575 search_cancel_rsp.result = TCORE_RETURN_FAILURE;
576 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
577 sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
579 else if(cmd == TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION){
580 struct tresp_network_set_default_data_subscription default_data_rsp;
581 memset(&default_data_rsp, 0, sizeof(struct tresp_network_set_default_data_subscription));
583 default_data_rsp.result = TCORE_RETURN_FAILURE;
584 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION,
585 sizeof(struct tresp_network_set_default_data_subscription), &default_data_rsp);
587 else if (cmd == TREQ_MODEM_SET_FLIGHTMODE) {
588 struct tresp_modem_set_flightmode set_flight_mode;
589 memset(&set_flight_mode, 0, sizeof(struct tresp_modem_set_flightmode));
591 set_flight_mode.result = TCORE_RETURN_FAILURE;
592 tcore_user_request_send_response(wqd->ur, TRESP_MODEM_SET_FLIGHTMODE,
593 sizeof(struct tresp_modem_set_flightmode), &set_flight_mode);
596 else if (cmd == TREQ_MODEM_POWER_OFF) {
597 struct tresp_modem_power_off set_power_off;
598 memset(&set_power_off, 0, sizeof(struct tresp_modem_power_off));
600 set_power_off.result = TCORE_RETURN_FAILURE;
601 tcore_user_request_send_response(wqd->ur, TRESP_MODEM_POWER_OFF,
602 sizeof(struct tresp_modem_power_off), &set_power_off);
605 else if (cmd == TREQ_MODEM_POWER_LOW) {
606 struct tresp_modem_power_low set_power_low;
607 memset(&set_power_low, 0, sizeof(struct tresp_modem_power_low));
609 set_power_low.result = TCORE_RETURN_FAILURE;
610 tcore_user_request_send_response(wqd->ur, TRESP_MODEM_POWER_LOW,
611 sizeof(struct tresp_modem_power_low), &set_power_low);
614 else if (cmd == TREQ_SIM_SET_POWERSTATE) {
615 struct tresp_sim_set_powerstate set_power;
616 memset(&set_power, 0, sizeof(struct tresp_sim_set_powerstate));
618 set_power.result = TCORE_RETURN_FAILURE;
619 tcore_user_request_send_response(wqd->ur, TRESP_SIM_SET_POWERSTATE,
620 sizeof(struct tresp_sim_set_powerstate), &set_power);
623 err("Unexpected command ");
625 tcore_user_request_unref(wqd->ur);
630 queue_data = g_queue_pop_head(modem->work_queue);
634 static void __ps_modem_cp_reset_handler(gpointer object)
636 ps_modem_t * modem = object;
639 /* check for any pending request in modem queue and respond with error */
640 __ps_modem_cp_reset_send_pending_request_response(modem);
642 /* reset modem flag */
643 modem->hook_flag &=PS_NO_PENDING_REQUEST;
647 void __ps_modem_set_hook_flag(ps_modem_t *modem ,enum tcore_request_command cmd)
649 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
652 case TREQ_NETWORK_SEARCH:
653 ps_dbg_ex_co(co_modem, "TREQ_NETWORK_SEARCH");
654 modem->hook_flag |= PS_NETWORK_SEARCH_PENDING;
655 ps_dbg_ex_co(co_modem, "TREQ_NETWORK_SEARCH setting flag %x", modem->hook_flag);
657 case TREQ_NETWORK_SET_PLMN_SELECTION_MODE:
658 modem->hook_flag |= PS_NETWORK_SELECTION_PENDING;
659 ps_dbg_ex_co(co_modem, "TREQ_NETWORK_SET_PLMN_SELECTION_MODE setting flag %x", modem->hook_flag);
661 case TREQ_NETWORK_SET_MODE:
662 modem->hook_flag |= PS_NETWORK_SELECT_MODE;
663 ps_dbg_ex_co(co_modem, "TREQ_NETWORK_SET_MODE setting flag %x", modem->hook_flag);
665 case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
666 modem->hook_flag |= PS_NETWORK_SET_DEFAULT_DATA_SUBS;
667 ps_dbg_ex_co(co_modem, "TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION setting flag %x", modem->hook_flag);
669 case TREQ_MODEM_SET_FLIGHTMODE:
670 modem->hook_flag |= PS_NETWORK_SET_FLIGHT_MODE;
671 ps_dbg_ex_co(co_modem, "TREQ_MODEM_SET_FLIGHTMODE setting flag %x", modem->hook_flag);
673 case TREQ_MODEM_POWER_OFF:
674 modem->hook_flag |= PS_NETWORK_SET_POWER_OFF;
675 ps_dbg_ex_co(co_modem, "TREQ_MODEM_POWER_OFF setting flag %x", modem->hook_flag);
677 case TREQ_MODEM_POWER_LOW:
678 modem->hook_flag |= PS_NETWORK_SET_POWER_LOW;
679 ps_dbg_ex_co(co_modem, "TREQ_MODEM_POWER_LOW setting flag %x", modem->hook_flag);
681 case TREQ_SIM_SET_POWERSTATE:
682 modem->hook_flag |= PS_SIM_SET_POWER_STATE;
683 ps_dbg_ex_co(co_modem, "TREQ_SIM_SET_POWERSTATE setting flag %x", modem->hook_flag);
686 ps_dbg_ex_co(co_modem, "Not handled request");
691 enum tcore_hook_return ps_handle_hook(Server *s, UserRequest *ur, void *user_data)
693 gboolean ret = FALSE;
694 TReturn rv = TCORE_RETURN_FAILURE;
696 CoreObject *co_ps = NULL;
697 GSList *co_ps_list = NULL;
698 TcorePlugin *target_plg = NULL;
701 ps_modem_t *modem = user_data;
702 CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
704 char *modem_name = NULL;
705 enum tcore_request_command cmd = tcore_user_request_get_command(ur);
707 ps_dbg_ex_co(co_modem, "Entered");
709 modem_name = tcore_user_request_get_modem_name (ur);
711 return TCORE_HOOK_RETURN_CONTINUE;
713 target_plg = tcore_object_ref_plugin(modem->co_modem);
714 if( g_strcmp0(tcore_server_get_cp_name_by_plugin(target_plg), modem_name) != 0) {
715 ps_dbg_ex_co(co_modem, "request modem (%s) not matched current modem(%s)",
717 tcore_server_get_cp_name_by_plugin(target_plg));
719 if( cmd == TREQ_NETWORK_SEARCH ) {
720 co_ps_list = tcore_plugin_get_core_objects_bytype (target_plg, CORE_OBJECT_TYPE_PS);
722 ps_dbg_ex_co(co_modem, "No ps core object present ");
724 return TCORE_HOOK_RETURN_CONTINUE;
726 co_ps = co_ps_list->data;
727 g_slist_free (co_ps_list);
730 ps_dbg_ex_co(co_modem, "No ps core object present ");
732 return TCORE_HOOK_RETURN_CONTINUE;
735 if(FALSE == tcore_ps_any_context_activating_activated(co_ps, &value)){
736 ps_dbg_ex_co(co_modem, "No activating/activated context present");
737 /* Block PS always-on while network operations. */
738 __ps_modem_set_hook_flag(modem, cmd);
739 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
741 return TCORE_HOOK_RETURN_CONTINUE;
744 ps_dbg_ex_co(co_modem, "Value returned [%d]", value);
745 if(( CONTEXT_STATE_ACTIVATING == value) || ( CONTEXT_STATE_ACTIVATED == value)) {
746 ps_dbg_ex_co(co_modem, "Activated/Activating context present need to deactivate them");
747 rv = tcore_ps_deactivate_contexts(co_ps);
748 if(rv != TCORE_RETURN_SUCCESS){
749 ps_dbg_ex_co(co_modem, "fail to deactivation");
751 return TCORE_HOOK_RETURN_CONTINUE;
753 __ps_modem_set_hook_flag(modem, cmd);
754 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
756 }else if(cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH){
757 __ps_modem_set_hook_flag(modem, cmd);
758 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
761 return TCORE_HOOK_RETURN_CONTINUE;
767 co_ps_list = tcore_plugin_get_core_objects_bytype (target_plg, CORE_OBJECT_TYPE_PS);
769 return TCORE_HOOK_RETURN_CONTINUE;
771 co_ps = co_ps_list->data;
772 g_slist_free (co_ps_list);
775 return TCORE_HOOK_RETURN_CONTINUE;
777 if(cmd == TREQ_MODEM_POWER_ON) {
778 if(modem->powered == PS_MODEM_STATE_ONLINE) {
779 struct tresp_modem_power_on set_power_on;
780 memset(&set_power_on, 0, sizeof(struct tresp_modem_power_on));
781 dbg("FLAG: 0x%x", modem->hook_flag);
783 if(modem->hook_flag & PS_NETWORK_SET_POWER_LOW) {
784 dbg("LOW power request is pending, send abort response");
785 set_power_on.result = TCORE_RETURN_OPERATION_ABORTED;
786 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_ON,
787 sizeof(struct tresp_modem_power_on), &set_power_on);
789 dbg("No pending LOW power request, send success response.");
790 set_power_on.result = TCORE_RETURN_EALREADY;
791 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_ON,
792 sizeof(struct tresp_modem_power_on), &set_power_on);
794 tcore_user_request_unref(ur);
795 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
797 return TCORE_HOOK_RETURN_CONTINUE;
799 if(FALSE == tcore_ps_any_context_activating_activated(co_ps, &value)){
800 ps_dbg_ex_co(co_modem, "No activating/activated context present");
801 /* Block PS always-on while network operations. */
802 #ifdef POWER_SAVING_FEATURE_WEARABLE
803 if ((cmd != TREQ_MODEM_POWER_LOW)
804 || (FALSE == __ps_is_any_call_in_progress(tcore_object_ref_plugin(modem->co_modem), ON_REQUEST, TNOTI_UNKNOWN))){
805 __ps_modem_set_hook_flag(modem, cmd);
806 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
807 return TCORE_HOOK_RETURN_CONTINUE;
810 __ps_modem_get_mode_pref_change(modem, ur);
811 __ps_modem_set_hook_flag(modem, cmd);
812 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
813 return TCORE_HOOK_RETURN_CONTINUE;
818 ps_dbg_ex_co(co_modem, "Value returned [%d]", value);
819 if( CONTEXT_STATE_ACTIVATED == value ) {
820 ps_dbg_ex_co(co_modem, "Activated/Activating context present need to deactivate them");
821 rv = tcore_ps_deactivate_contexts(co_ps);
822 if(rv != TCORE_RETURN_SUCCESS){
823 ps_dbg_ex_co(co_modem, "fail to deactivation");
824 return TCORE_HOOK_RETURN_CONTINUE;
826 } else if ( CONTEXT_STATE_ACTIVATING == value) {
827 #ifdef POWER_SAVING_FEATURE_WEARABLE
828 if ((cmd != TREQ_MODEM_POWER_LOW)
829 || (FALSE == __ps_is_any_call_in_progress(tcore_object_ref_plugin(modem->co_modem), ON_REQUEST, TNOTI_UNKNOWN))){
830 return TCORE_HOOK_RETURN_CONTINUE;
833 if((cmd == TREQ_MODEM_SET_FLIGHTMODE) ||(cmd == TREQ_MODEM_POWER_OFF) ) {
834 ps_dbg_ex_co(co_modem, "No need to stop these request for pdp in activating state ");
835 return TCORE_HOOK_RETURN_CONTINUE;
838 ps_dbg_ex_co(co_modem, "For rest command will wait for activation successful ");
841 if(!modem->work_queue){
842 ps_err_ex_co(co_modem, "no queue present unable to handle request");
843 return TCORE_HOOK_RETURN_CONTINUE;
846 job_cnt = ps_util_get_count_waiting_job(modem->work_queue, cmd);
848 ps_err_ex_co(co_modem, "duplicated job for cmd(%d)", cmd);
850 if(cmd == TREQ_NETWORK_SEARCH){
851 struct tresp_network_search search_rsp;
852 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
854 search_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
855 search_rsp.list_count = 0;
856 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH,
857 sizeof(struct tresp_network_search), &search_rsp);
859 else if(cmd == TREQ_NETWORK_SET_PLMN_SELECTION_MODE){
860 struct tresp_network_set_plmn_selection_mode set_plmn_mode_rsp;
861 memset(&set_plmn_mode_rsp, 0, sizeof(struct tresp_network_set_plmn_selection_mode));
863 set_plmn_mode_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
864 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE,
865 sizeof(struct tresp_network_set_plmn_selection_mode), &set_plmn_mode_rsp);
867 else if(cmd == TREQ_NETWORK_SET_MODE){
868 struct tresp_network_set_mode setmode_rsp;
869 memset(&setmode_rsp, 0, sizeof(struct tresp_network_set_mode));
871 setmode_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
872 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_MODE,
873 sizeof(struct tresp_network_set_mode), &setmode_rsp);
875 else if(cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH){
876 struct tresp_network_set_cancel_manual_search search_cancel_rsp;
877 memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
879 search_cancel_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
880 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
881 sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
883 else if(cmd == TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION){
884 struct tresp_network_set_default_data_subscription default_data_rsp;
885 memset(&default_data_rsp, 0, sizeof(struct tresp_network_set_default_data_subscription));
887 default_data_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
888 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION,
889 sizeof(struct tresp_network_set_default_data_subscription), &default_data_rsp);
891 else if (cmd == TREQ_MODEM_SET_FLIGHTMODE) {
892 struct tresp_modem_set_flightmode set_flight_mode;
893 memset(&set_flight_mode, 0, sizeof(struct tresp_modem_set_flightmode));
895 set_flight_mode.result = TCORE_RETURN_OPERATION_ABORTED;
896 tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE,
897 sizeof(struct tresp_modem_set_flightmode), &set_flight_mode);
900 else if (cmd == TREQ_MODEM_POWER_OFF) {
901 struct tresp_modem_power_off set_power_off;
902 memset(&set_power_off, 0, sizeof(struct tresp_modem_power_off));
904 set_power_off.result = TCORE_RETURN_OPERATION_ABORTED;
905 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_OFF,
906 sizeof(struct tresp_modem_power_off), &set_power_off);
909 else if (cmd == TREQ_MODEM_POWER_LOW) {
910 struct tresp_modem_power_low set_power_low;
911 memset(&set_power_low, 0, sizeof(struct tresp_modem_power_low));
913 set_power_low.result = TCORE_RETURN_OPERATION_ABORTED;
914 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_LOW,
915 sizeof(struct tresp_modem_power_low), &set_power_low);
918 else if (cmd == TREQ_SIM_SET_POWERSTATE) {
919 struct tresp_sim_set_powerstate set_power;
920 memset(&set_power, 0, sizeof(struct tresp_sim_set_powerstate));
922 set_power.result = TCORE_RETURN_OPERATION_ABORTED;
923 tcore_user_request_send_response(ur, TRESP_SIM_SET_POWERSTATE,
924 sizeof(struct tresp_sim_set_powerstate), &set_power);
927 tcore_user_request_unref(ur);
928 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
931 ps_dbg_ex_co(co_modem, "Deactivation request is sent, wait for call disconnect notification ");
933 if(TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH == cmd){
934 UserRequest *ur_pending = NULL;
935 ur_pending = ps_util_pop_waiting_job(modem->work_queue, TREQ_NETWORK_SEARCH);
938 ps_dbg_ex_co(co_modem, "no pendig search request");
939 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
940 return TCORE_HOOK_RETURN_CONTINUE;
943 struct tresp_network_search search_rsp;
944 struct tresp_network_set_cancel_manual_search search_cancel_rsp;
946 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
947 memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
949 search_rsp.list_count = 0;
950 ps_dbg_ex_co(co_modem, "send search response to upper layer");
951 tcore_user_request_send_response(ur_pending, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &search_rsp);
952 tcore_user_request_unref(ur_pending);
954 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
955 search_cancel_rsp.result = TCORE_RETURN_SUCCESS;
956 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
957 sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
959 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
963 ret = ps_util_add_waiting_job(modem->work_queue, cmd , ur);
965 ps_dbg_ex_co(co_modem, "fail to add the request to queue");
966 return TCORE_HOOK_RETURN_CONTINUE;
969 __ps_modem_get_mode_pref_change(modem, ur);
970 __ps_modem_set_hook_flag(modem, cmd);
971 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
974 void __ps_send_pending_user_request(gpointer data)
976 ps_modem_t *modem = data;
977 GSList *co_list = NULL;
978 CoreObject *co_network = NULL;
979 CoreObject *co_sim = NULL;
980 gpointer *queue_data = NULL;
982 co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
983 CORE_OBJECT_TYPE_NETWORK);
985 if (G_UNLIKELY(co_list == NULL)) {
989 co_network = (CoreObject *) co_list->data;
990 g_slist_free(co_list);
992 co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
993 CORE_OBJECT_TYPE_SIM);
995 if (G_UNLIKELY(co_list == NULL)) {
999 co_sim = (CoreObject *) co_list->data;
1000 g_slist_free(co_list);
1002 ps_dbg_ex_co(co_network, "Extracting the user request from the work queue");
1004 queue_data = g_queue_pop_head(modem->work_queue);
1005 while( queue_data) {
1006 struct work_queue_data *wqd = (struct work_queue_data *)queue_data ;
1007 ps_dbg_ex_co(co_network, " sending Pending request [%x]", wqd ->id);
1009 ps_dbg_ex_co(co_network, "Setting responce hook for request ");
1010 tcore_user_request_set_response_hook(wqd->ur, __ps_hook_response_cb, modem);
1013 case TREQ_NETWORK_SEARCH :
1014 case TREQ_NETWORK_SET_MODE :
1015 case TREQ_NETWORK_SET_PLMN_SELECTION_MODE :
1016 case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION :
1017 tcore_object_dispatch_request(co_network, wqd->ur);
1019 case TREQ_MODEM_SET_FLIGHTMODE:
1020 case TREQ_MODEM_POWER_OFF:
1021 tcore_object_dispatch_request(modem->co_modem, wqd->ur);
1023 case TREQ_MODEM_POWER_LOW:
1024 #ifdef POWER_SAVING_FEATURE_WEARABLE
1025 __ps_check_handle_modem_off_request(modem, ON_REQUEST, TNOTI_UNKNOWN);
1027 if (modem->hook_flag & PS_NETWORK_SET_POWER_LOW) {
1028 tcore_object_dispatch_request(modem->co_modem, wqd->ur);
1033 case TREQ_SIM_SET_POWERSTATE:
1034 tcore_object_dispatch_request(co_sim, wqd->ur);
1037 ps_err_ex_co(co_network, "No expected request ");
1041 /* Freeing Allocated memory*/
1043 queue_data = g_queue_pop_head(modem->work_queue);
1045 ps_dbg_ex_co(co_network, "All pending request sent ");
1048 static enum tcore_hook_return __on_hook_call_status(Server *s, CoreObject *source,
1049 enum tcore_notification_command command, unsigned int data_len, void *data,
1052 gpointer modem = NULL;
1053 gpointer service = user_data;
1054 CoreObject *co_network;
1055 gpointer co_ps = NULL;
1058 gboolean b_data_allowed = FALSE;
1059 gboolean b_roaming_checker = TRUE;
1060 gboolean b_mms_checker = FALSE;
1061 gboolean b_ims_checker = FALSE;
1063 struct tnoti_ps_call_status *cstatus = NULL;
1065 dbg("call status event");
1066 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1068 co_network = _ps_service_ref_co_network(service);
1069 cstatus = (struct tnoti_ps_call_status *) data;
1070 co_ps = (CoreObject *)_ps_service_ref_co_ps(service);
1071 if (co_ps != source) {
1072 ps_warn_ex_co(co_network, "Received notification for different Subscription - neglecting the notification!!!");
1073 return TCORE_HOOK_RETURN_CONTINUE;
1076 modem = _ps_service_ref_modem(service);
1078 ps_err_ex_co(co_network, "modem does not exist");
1079 return TCORE_HOOK_RETURN_CONTINUE;
1082 b_data_allowed = _ps_modem_get_data_allowed(modem);
1084 co_list = tcore_ps_ref_context_by_id(co_ps, cstatus->context_id);
1085 for (; co_list; co_list = co_list->next) {
1086 CoreObject *co_context = NULL;
1087 enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
1089 co_context = co_list->data;
1090 role = tcore_context_get_role(co_context);
1092 if( role == CONTEXT_ROLE_MMS || role == CONTEXT_ROLE_PREPAID_MMS){
1093 b_mms_checker = TRUE;
1096 if( role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY){
1097 b_ims_checker = TRUE;
1102 #if !defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
1103 ps_dbg_ex_co(co_network, "csc runtime feature disabled");
1104 b_mms_checker = FALSE;
1107 if( (_ps_modem_get_roaming(modem)) && !(_ps_modem_get_data_roaming_allowed(modem)) ){
1108 ps_dbg_ex_co(co_network, "roaming network is not allowed");
1109 b_roaming_checker = FALSE;
1112 ps_dbg_ex_co(co_network, "data_allowed(%d) call status event cid(%d) state(%d) reason(%d)",
1113 b_data_allowed, cstatus->context_id, cstatus->state, cstatus->result);
1115 if( !b_roaming_checker || (!b_data_allowed && !b_mms_checker && !b_ims_checker) ){
1116 ps_dbg_ex_co(co_network, "mismatched: roaming checker(%d) data_allowed(%d) mms_checker(%d) b_ims_checker(%d)",
1117 b_roaming_checker, b_data_allowed, b_mms_checker, b_ims_checker);
1119 if(cstatus->state == PS_CALL_STATE_RESULT_OK) {
1120 _ps_service_set_connected(service, cstatus, FALSE);
1121 tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
1122 return TCORE_HOOK_RETURN_CONTINUE;
1124 else if(cstatus->state == PS_CALL_STATE_RESULT_CONNECT) {
1125 _ps_service_set_connected(service, cstatus, TRUE);
1126 _ps_service_disconnect_contexts(service);
1127 return TCORE_HOOK_RETURN_CONTINUE;
1131 ps_dbg_ex_co(co_network, "service(%p) status(%d)", service, cstatus->state);
1132 if(cstatus->state == PS_CALL_STATE_RESULT_OK) { //DEFINE
1133 _ps_service_set_ps_defined(service, TRUE, cstatus->context_id);
1135 else if(cstatus->state == PS_CALL_STATE_RESULT_CONNECT) { //CONNECTED
1138 if (tcore_ps_get_cid_active(co_ps, cstatus->context_id) == FALSE) {
1139 ps_dbg_ex_co(co_network, "DDS scenario");
1141 /* De-activate context */
1142 rv = tcore_ps_deactivate_contexts(co_ps);
1143 if(rv != TCORE_RETURN_SUCCESS){
1144 ps_dbg_ex_co(co_network, "fail to deactivation");
1145 return TCORE_HOOK_RETURN_CONTINUE;
1149 _ps_service_set_connected(service, cstatus, TRUE);
1150 tcore_ps_set_cid_connected(co_ps, cstatus->context_id, TRUE);
1152 if (g_queue_get_length((GQueue *)_ps_modem_ref_work_queue(modem)) || (_ps_modem_get_reset_profile(modem) == TRUE)) {
1153 ps_dbg_ex_co(co_network, "Special request present in queue ");
1155 rv = tcore_ps_deactivate_contexts(co_ps);
1156 if(rv != TCORE_RETURN_SUCCESS){
1157 ps_dbg_ex_co(co_network, "fail to deactivation");
1158 return TCORE_HOOK_RETURN_CONTINUE;
1163 else if(cstatus->state == PS_CALL_STATE_RESULT_NO_CARRIER) { //DISCONNECTED-NO CARRIER
1164 gpointer def_context = NULL;
1165 unsigned char def_cid = 0;
1167 gboolean retry = TRUE;
1169 //retry = __ps_check_pdp_permanent_reject_cause(cstatus->result);
1170 /* if retry not permitted by network */
1171 //if(FALSE == retry)
1172 ps_dbg_ex_co(co_network, "DO NOT RETRY NETWORK CONNECTION AUTOMATICALLY");
1173 ps_dbg_ex_co(co_network, "permanent reject cause (%d)", cstatus->result);
1175 def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
1177 gpointer co_context = NULL;
1178 co_context = _ps_context_ref_co_context(def_context);
1179 def_cid = tcore_context_get_id(co_context);
1182 _ps_service_set_ps_defined(service, FALSE, cstatus->context_id);
1183 tcore_ps_set_cid_active(co_ps, cstatus->context_id, FALSE);
1184 tcore_ps_set_cid_connected(co_ps, cstatus->context_id, FALSE);
1185 _ps_service_set_connected(service, cstatus, FALSE);
1187 if(FALSE == tcore_ps_any_context_activating_activated(co_ps, &value)){
1188 ps_dbg_ex_co(co_network, "No open connections, publish disconnected signal");
1190 /* Handle any pending request if present */
1191 modem = _ps_service_ref_modem(service);
1192 __ps_send_pending_user_request(modem);
1194 /* Ensured that set_reset_profile is always done default thread's context */
1195 if (_ps_modem_get_reset_profile(modem) == TRUE) {
1196 /* Initiate Reset Profile */
1197 ps_dbg_ex_co(co_network, "Profiles are being reset");
1198 /* Shouldn't invoke set profile directly, as it will remove hooks registered to server while being hook callback*/
1199 if (NULL == _ps_modem_get_profile_reset_gsource(modem)) {
1200 GSource *gsource = NULL;
1201 gsource = ps_util_gsource_dispatch(g_main_context_default(), G_PRIORITY_LOW, (GSourceFunc)_ps_modem_initiate_reset_profile, modem) ;
1202 _ps_modem_set_profile_reset_gsource(modem, gsource);
1206 ps_dbg_ex_co(co_network, "any context activating or activated [%d]", value);
1207 if(FALSE == retry) {
1208 if(cstatus->context_id == def_cid){
1209 _ps_service_reset_connection_timer(def_context);
1212 } // disconnected case
1214 return TCORE_HOOK_RETURN_CONTINUE;
1217 static enum tcore_hook_return __on_hook_call_status_0(Server *s, CoreObject *source,
1218 enum tcore_notification_command command, unsigned int data_len, void *data,
1221 return __on_hook_call_status(s, source, command, data_len, data, user_data);
1224 static enum tcore_hook_return __on_hook_call_status_1(Server *s, CoreObject *source,
1225 enum tcore_notification_command command, unsigned int data_len, void *data,
1228 return __on_hook_call_status(s, source, command, data_len, data, user_data);
1232 static enum tcore_hook_return __on_hook_session_data_counter_0(Server *s, CoreObject *source,
1233 enum tcore_notification_command command, unsigned int data_len, void *data,
1236 gpointer service = user_data;
1237 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1239 ps_dbg_ex_co(_ps_service_ref_co_network(service), "session data counter event");
1241 return TCORE_HOOK_RETURN_CONTINUE;
1244 static enum tcore_hook_return __on_hook_session_data_counter_1(Server *s, CoreObject *source,
1245 enum tcore_notification_command command, unsigned int data_len, void *data,
1248 gpointer service = user_data;
1249 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1251 ps_dbg_ex_co(_ps_service_ref_co_network(service), "session data counter event");
1253 return TCORE_HOOK_RETURN_CONTINUE;
1256 static enum tcore_hook_return __on_hook_ipconfiguration(Server *s, CoreObject *source,
1257 enum tcore_notification_command command, unsigned int data_len, void *data,
1260 gpointer service = user_data;
1261 CoreObject *co_ps = NULL;
1262 CoreObject *co_network = NULL;
1263 struct tnoti_ps_pdp_ipconfiguration *devinfo = NULL;
1264 char ipv4[16], ipv4_dns_1[16], ipv4_dns_2[16];
1266 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1268 co_network = _ps_service_ref_co_network(service);
1269 devinfo = (struct tnoti_ps_pdp_ipconfiguration *) data;
1270 co_ps = (CoreObject *)_ps_service_ref_co_ps(service);
1271 if (co_ps != source) {
1272 ps_warn_ex_co(co_network, "Received notification for different Subscription - neglecting the notification!!!");
1273 return TCORE_HOOK_RETURN_CONTINUE;
1276 ps_dbg_ex_co(co_network, "ip configuration event");
1279 * In case IPv4 address is available and DNS address
1280 * is NOT available, set -
1281 * DNS 1 - Google DNS
1284 snprintf(ipv4, 16, "%d.%d.%d.%d",
1285 devinfo->ip_address[0], devinfo->ip_address[1],
1286 devinfo->ip_address[2], devinfo->ip_address[3]);
1287 if (!g_str_equal(ipv4, "0.0.0.0")) {
1288 snprintf(ipv4_dns_1, 16, "%d.%d.%d.%d",
1289 devinfo->primary_dns[0], devinfo->primary_dns[1],
1290 devinfo->primary_dns[2], devinfo->primary_dns[3]);
1291 if (g_str_equal(ipv4_dns_1, "0.0.0.0")) {
1292 err("[IPV4]primary dns address is 0");
1295 devinfo->primary_dns[0] = 8;
1296 devinfo->primary_dns[1] = 8;
1297 devinfo->primary_dns[2] = 8;
1298 devinfo->primary_dns[3] = 8;
1301 snprintf(ipv4_dns_2, 16, "%d.%d.%d.%d",
1302 devinfo->secondary_dns[0], devinfo->secondary_dns[1],
1303 devinfo->secondary_dns[2], devinfo->secondary_dns[3]);
1304 if (g_str_equal(ipv4_dns_2, "0.0.0.0")) {
1306 err("[IPV4]secondary dns address is 0");
1307 devinfo->secondary_dns[0] = 208;
1308 devinfo->secondary_dns[1] = 67;
1309 devinfo->secondary_dns[2] = 222;
1310 devinfo->secondary_dns[3] = 222;
1315 * In case IPv6 address is available and DNS address
1316 * is NOT available, set -
1317 * DNS 1 - Google DNS
1320 if (devinfo->ipv6_address != NULL) {
1321 if (devinfo->ipv6_primary_dns == NULL) {
1322 err("[IPV6]primary dns address is 0");
1323 devinfo->ipv6_primary_dns = g_strdup("2001:4860:4860::8888");
1326 if (devinfo->ipv6_secondary_dns == NULL) {
1327 err("[IPV6]secondary dns address is 0");
1328 devinfo->ipv6_secondary_dns = g_strdup("2620:0:ccc::2");
1332 _ps_service_set_context_info(service, devinfo);
1334 return TCORE_HOOK_RETURN_CONTINUE;
1338 static enum tcore_hook_return __on_hook_ipconfiguration_0(Server *s, CoreObject *source,
1339 enum tcore_notification_command command, unsigned int data_len, void *data,
1342 return __on_hook_ipconfiguration(s, source, command, data_len, data, user_data);
1345 static enum tcore_hook_return __on_hook_ipconfiguration_1(Server *s, CoreObject *source,
1346 enum tcore_notification_command command, unsigned int data_len, void *data,
1349 return __on_hook_ipconfiguration(s, source, command, data_len, data, user_data);
1352 static enum tcore_hook_return __on_hook_powered(Server *s, CoreObject *source,
1353 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1355 gpointer modem = user_data;
1356 CoreObject * co_modem;
1357 struct tnoti_modem_power *modem_power = NULL;
1358 int power = PS_MODEM_STATE_UNKNOWN;
1360 CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE);
1362 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
1363 co_modem = _ps_modem_ref_co_modem(modem);
1364 if(source != co_modem) {
1365 ps_warn_ex_co(co_modem, "Powered event for other subscription ");
1366 return TCORE_HOOK_RETURN_CONTINUE;
1369 modem_power = (struct tnoti_modem_power *)data;
1370 g_return_val_if_fail(modem_power != NULL, TCORE_HOOK_RETURN_CONTINUE);
1371 ps_dbg_ex_co(co_modem, "powered event called: state [%d]", modem_power->state);
1373 switch(modem_power->state) {
1374 case MODEM_STATE_ONLINE:
1375 case MODEM_STATE_RESUME: {
1376 power = PS_MODEM_STATE_ONLINE;
1378 case MODEM_STATE_LOW: {
1379 power = PS_MODEM_STATE_LOW;
1381 case MODEM_STATE_ERROR:
1382 case MODEM_STATE_OFFLINE:
1383 case MODEM_STATE_RESET: {
1384 /* Reset hook flag in any present */
1385 __ps_modem_cp_reset_handler(modem);
1387 power = PS_MODEM_STATE_OFFLINE;
1390 ps_warn_ex_co(co_modem,"Unhandled modem power event." );
1394 if(power != PS_MODEM_STATE_UNKNOWN)
1395 _ps_modem_processing_power_enable(modem, power);
1397 return TCORE_HOOK_RETURN_CONTINUE;
1401 static enum tcore_hook_return __on_hook_powered_0(Server *s, CoreObject *source,
1402 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1404 return __on_hook_powered(s, source, command, data_len, data, user_data);
1407 static enum tcore_hook_return __on_hook_powered_1(Server *s, CoreObject *source,
1408 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1410 return __on_hook_powered(s, source, command, data_len, data, user_data);
1413 static enum tcore_hook_return __on_hook_flight(Server *s, CoreObject *source,
1414 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1416 gpointer modem = user_data;
1417 CoreObject * co_modem = _ps_modem_ref_co_modem(modem);
1418 struct tnoti_modem_flight_mode *modem_flight = NULL;
1420 g_return_val_if_fail(modem != NULL, TCORE_HOOK_RETURN_CONTINUE);
1421 if(source != co_modem) {
1422 ps_warn_ex_co(co_modem, "flight mode event for other subscription ");
1423 return TCORE_HOOK_RETURN_CONTINUE;
1426 ps_dbg_ex_co(co_modem, "flight mode event called");
1428 modem_flight = (struct tnoti_modem_flight_mode *)data;
1429 _ps_modem_processing_flight_mode(modem, modem_flight->enable);
1431 return TCORE_HOOK_RETURN_CONTINUE;
1434 static enum tcore_hook_return __on_hook_flight_0(Server *s, CoreObject *source,
1435 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1437 return __on_hook_flight(s, source, command, data_len, data, user_data);
1440 static enum tcore_hook_return __on_hook_flight_1(Server *s, CoreObject *source,
1441 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1443 return __on_hook_flight(s, source, command, data_len, data, user_data);
1446 static enum tcore_hook_return __on_hook_net_register(Server *s, CoreObject *source,
1447 enum tcore_notification_command command, unsigned int data_len, void *data,
1450 gpointer service = user_data;
1451 gboolean ps_attached = FALSE;
1452 struct tnoti_network_registration_status *regist_status;
1453 CoreObject *co_network;
1454 dbg("network register event called");
1456 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
1459 co_network = (CoreObject *)_ps_service_ref_co_network(service);
1460 if (co_network != source) {
1461 ps_dbg_ex_co(co_network, "Received notification for different Subscription - neglecting the notification!!!");
1462 return TCORE_HOOK_RETURN_CONTINUE;
1465 regist_status = (struct tnoti_network_registration_status *) data;
1466 if (regist_status->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
1469 _ps_modem_set_roaming(_ps_service_ref_modem(service), regist_status->roaming_status);
1470 _ps_service_processing_network_event(service, ps_attached, regist_status->roaming_status);
1472 return TCORE_HOOK_RETURN_CONTINUE;
1475 static enum tcore_hook_return __on_hook_net_register_0(Server *s, CoreObject *source,
1476 enum tcore_notification_command command, unsigned int data_len, void *data,
1479 return __on_hook_net_register(s, source, command, data_len, data, user_data);
1482 static enum tcore_hook_return __on_hook_net_register_1(Server *s, CoreObject *source,
1483 enum tcore_notification_command command, unsigned int data_len, void *data,
1486 return __on_hook_net_register(s, source, command, data_len, data, user_data);
1489 static enum tcore_hook_return __on_hook_net_change(Server *s, CoreObject *source,
1490 enum tcore_notification_command command, unsigned int data_len, void *data,
1493 gpointer service = user_data;
1494 struct tnoti_network_change *network_change;
1495 CoreObject *co_network;
1496 dbg("network change event called");
1498 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
1500 co_network = (CoreObject *)_ps_service_ref_co_network(service);
1501 if (co_network != source) {
1502 ps_dbg_ex_co(co_network, "Received notification for different Subscription - neglecting the notification!!!");
1503 return TCORE_HOOK_RETURN_CONTINUE;
1506 network_change = (struct tnoti_network_change *) data;
1507 ps_dbg_ex_co(co_network, "plmn(%s) act(%d)", network_change->plmn, network_change->act);
1508 _ps_service_set_access_technology(service, network_change->act);
1510 return TCORE_HOOK_RETURN_CONTINUE;
1513 static enum tcore_hook_return __on_hook_net_change_0(Server *s, CoreObject *source,
1514 enum tcore_notification_command command, unsigned int data_len, void *data,
1517 return __on_hook_net_change(s, source, command, data_len, data, user_data);
1520 static enum tcore_hook_return __on_hook_net_change_1(Server *s, CoreObject *source,
1521 enum tcore_notification_command command, unsigned int data_len, void *data,
1524 return __on_hook_net_change(s, source, command, data_len, data, user_data);
1527 static enum tcore_hook_return __on_hook_net_restricted_state(Server *s, CoreObject *source,
1528 enum tcore_notification_command command, unsigned int data_len, void *data,
1531 gpointer service = user_data;
1532 struct tnoti_network_restricted_state *network_restricted;
1533 CoreObject *co_network;
1534 dbg("network restricted event called");
1536 g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
1538 co_network = (CoreObject *)_ps_service_ref_co_network(service);
1539 if (co_network != source) {
1540 ps_warn_ex_co(co_network, "Received notification for different Subscription - neglecting the notification!!!");
1541 return TCORE_HOOK_RETURN_CONTINUE;
1544 network_restricted = (struct tnoti_network_restricted_state *) data;
1545 ps_dbg_ex_co(co_network, "network restricted state(%d)", network_restricted->restricted_state);
1547 _ps_service_set_restricted(service, ((network_restricted->restricted_state & NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
1549 return TCORE_HOOK_RETURN_CONTINUE;
1552 static enum tcore_hook_return __on_hook_net_restricted_state_0(Server *s, CoreObject *source,
1553 enum tcore_notification_command command, unsigned int data_len, void *data,
1556 return __on_hook_net_restricted_state(s, source,command, data_len, data, user_data);
1560 static enum tcore_hook_return __on_hook_net_restricted_state_1(Server *s, CoreObject *source,
1561 enum tcore_notification_command command, unsigned int data_len, void *data,
1564 return __on_hook_net_restricted_state(s, source,command, data_len, data, user_data);
1568 static enum tcore_hook_return __on_hook_sim_init(Server *s, CoreObject *source,
1569 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1571 struct tnoti_sim_status *sim_data;
1572 ps_modem_t *modem = user_data;
1573 CoreObject * co_modem = _ps_modem_ref_co_modem(modem);
1574 gchar *cp_name, *source_cp_name;
1575 ps_dbg_ex_co(co_modem, "sim init event called");
1577 g_return_val_if_fail(user_data != NULL, TCORE_HOOK_RETURN_CONTINUE);
1579 cp_name = _ps_modem_ref_cp_name(modem);
1580 source_cp_name = (gchar *)tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
1581 if (g_strcmp0(cp_name, source_cp_name) != 0) {
1582 ps_warn_ex_co(co_modem, "Received notification for different Subscription - neglecting the notification!!!");
1583 return TCORE_HOOK_RETURN_CONTINUE;
1587 sim_data = (struct tnoti_sim_status *)data;
1588 ps_dbg_ex_co(co_modem, "sim status is (%d)", sim_data->sim_status);
1590 switch (sim_data->sim_status) {
1591 case SIM_STATUS_INIT_COMPLETED: {
1592 struct tel_sim_imsi *sim_imsi = NULL;
1593 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1594 sim_type = tcore_sim_get_type(source);
1596 if(sim_type == SIM_TYPE_NVSIM) {
1597 dbg("initial boot from CDMA network.");
1598 _ps_modem_processing_sim_complete( (gpointer)user_data, TRUE, PS_CDMA_DUMMY_PROFILE_PLMN);
1600 sim_imsi = tcore_sim_get_imsi(source);
1601 _ps_modem_processing_sim_complete((gpointer)user_data, TRUE, (gchar *)sim_imsi->plmn);
1607 case SIM_STATUS_CARD_ERROR: /* FALLTHROUGH */
1608 case SIM_STATUS_CARD_REMOVED: /* FALLTHROUGH */
1609 case SIM_STATUS_CARD_CRASHED: /* FALLTHROUGH */
1610 case SIM_STATUS_CARD_POWEROFF: {
1611 /* Set SIM complete FALSE, operator is not required */
1612 _ps_modem_processing_sim_complete((gpointer)user_data, FALSE, NULL);
1614 /* TODO: Handle CDMA specific case */
1618 ps_dbg_ex_co(co_modem, "Unhandled SIM state: [%d]", sim_data->sim_status);
1622 return TCORE_HOOK_RETURN_CONTINUE;
1625 #ifdef POWER_SAVING_FEATURE_WEARABLE
1626 static gboolean __ps_is_any_call_in_progress(TcorePlugin *plugin, __ps_call_flow_type type, enum tcore_notification_command command)
1630 int total_call_cnt = 0;
1632 gboolean call_in_progress = FALSE;
1634 list = tcore_plugin_get_core_objects_bytype(plugin, CORE_OBJECT_TYPE_CALL);
1636 /* call_in_progress = FALSE; */
1637 err("[ error ] co_list : 0");
1638 return call_in_progress;
1641 o = (CoreObject *)list->data;
1644 total_call_cnt = tcore_call_object_total_length(o);
1645 dbg("totall call cnt (%d)", total_call_cnt);
1647 if(((type == ON_REQUEST || type == ON_NON_CALL_NOTI_HOOK) && total_call_cnt != 0)
1648 || ((type == ON_CALL_NOTI_HOOK)
1649 && ((command != TNOTI_CALL_STATUS_IDLE) || (total_call_cnt > 1)))) {
1650 dbg("call is still connected");
1651 call_in_progress = TRUE;
1653 dbg("No call is in progress");
1656 return call_in_progress;
1660 /* Check for pending TREQ_MODEM_POWER_OFF request */
1661 void __ps_check_handle_modem_off_request(gpointer data, __ps_call_flow_type type,enum tcore_notification_command command)
1663 ps_modem_t *modem = data;
1669 if (modem->hook_flag & PS_NETWORK_SET_POWER_LOW) {
1670 UserRequest *ur = NULL;
1671 ur = ps_util_pop_waiting_job(modem->work_queue, TREQ_MODEM_POWER_LOW);
1673 gboolean call_in_progress;
1674 dbg("Sending Pending SET POWER OFF");
1676 /* Checking if any voice or MMS is in progress, if so, delay Modem power off.
1677 Need to hook on both voice call status and MMS profile de-activation.
1679 call_in_progress = __ps_is_any_call_in_progress(tcore_object_ref_plugin(modem->co_modem), type, command);
1681 if (call_in_progress) {
1683 /* add to the waiting queue and continue and wait till there is no call or MMS */
1684 ret = ps_util_add_waiting_job(modem->work_queue, TREQ_MODEM_POWER_LOW , ur);
1686 err("fail to add the request to queue");
1687 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
1688 if(TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(modem->co_modem, ur)) {
1689 __ps_send_ur_dispatch_failure_response(ur, TRESP_MODEM_POWER_LOW);
1690 modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_LOW_FLAG;
1695 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
1696 if(TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(modem->co_modem, ur)) {
1697 __ps_send_ur_dispatch_failure_response(ur, TRESP_MODEM_POWER_LOW);
1698 modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_LOW_FLAG;
1703 dbg("No pending TREQ_MODEM_POWER_LOW reqeust");
1707 static enum tcore_hook_return __on_hook_voice_call_status(Server *s, CoreObject *co_call,
1708 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1710 __ps_check_handle_modem_off_request(user_data,ON_CALL_NOTI_HOOK,command);
1711 return TCORE_HOOK_RETURN_CONTINUE;
1715 static enum tcore_hook_return __on_hook_sim_init_0(Server *s, CoreObject *source,
1716 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1718 return __on_hook_sim_init(s, source, command, data_len, data, user_data);
1721 static enum tcore_hook_return __on_hook_sim_init_1(Server *s, CoreObject *source,
1722 enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
1724 return __on_hook_sim_init(s, source, command, data_len, data, user_data);
1727 void _ps_get_network_mode(gpointer data)
1729 UserRequest *ur = NULL;
1730 ps_modem_t *modem = data;
1732 GSList *co_list = NULL;
1733 CoreObject *co_network = NULL;
1735 ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "network get mode by data allowed option");
1737 co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
1738 CORE_OBJECT_TYPE_NETWORK);
1740 if (G_UNLIKELY(co_list == NULL)) {
1744 co_network = (CoreObject *) co_list->data;
1746 ur = tcore_user_request_new(NULL, NULL);
1747 tcore_user_request_set_data(ur, 0, NULL);
1748 tcore_user_request_set_command(ur, TREQ_NETWORK_GET_MODE);
1749 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
1751 __ps_modem_set_hook_flag(modem, TREQ_NETWORK_GET_MODE);
1753 if(TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_network, ur)) {
1754 err("Failed to dispatch ");
1755 __ps_send_ur_dispatch_failure_response(ur,TRESP_NETWORK_GET_MODE);
1756 modem->hook_flag &= PS_NETWORK_RESET_GET_MODE_FLAG;
1758 g_slist_free(co_list);
1763 gboolean _ps_hook_co_modem_event(gpointer modem)
1767 CoreObject *co_modem;
1768 const char *modem_name = NULL;
1769 g_return_val_if_fail(modem != NULL, FALSE);
1771 p = _ps_modem_ref_plugin(modem);
1772 s = tcore_plugin_ref_server(p);
1773 co_modem = _ps_modem_ref_co_modem(modem);
1775 modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_modem));
1776 if( TRUE == g_str_has_suffix(modem_name , "0")) {
1777 tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER, __on_hook_powered_0, modem);
1778 tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE, __on_hook_flight_0, modem);
1779 tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, __on_hook_sim_init_0, modem);
1780 #ifdef POWER_SAVING_FEATURE_WEARABLE /* TODO: Modify for DSDS support */
1781 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_IDLE, __on_hook_voice_call_status, modem);
1782 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_ACTIVE, __on_hook_voice_call_status, modem);
1783 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_HELD, __on_hook_voice_call_status, modem);
1784 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_DIALING, __on_hook_voice_call_status, modem);
1785 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_ALERT, __on_hook_voice_call_status, modem);
1786 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_INCOMING, __on_hook_voice_call_status, modem);
1787 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_WAITING, __on_hook_voice_call_status, modem);
1788 #endif /* #ifdef POWER_SAVING_FEATURE_WEARABLE */
1790 tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER, __on_hook_powered_1, modem);
1791 tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE, __on_hook_flight_1, modem);
1792 tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, __on_hook_sim_init_1, modem);
1793 #ifdef POWER_SAVING_FEATURE_WEARABLE /* TODO: Modify for DSDS support */
1794 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_IDLE, __on_hook_voice_call_status, modem);
1795 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_ACTIVE, __on_hook_voice_call_status, modem);
1796 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_HELD, __on_hook_voice_call_status, modem);
1797 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_DIALING, __on_hook_voice_call_status, modem);
1798 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_ALERT, __on_hook_voice_call_status, modem);
1799 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_INCOMING, __on_hook_voice_call_status, modem);
1800 tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_WAITING, __on_hook_voice_call_status, modem);
1801 #endif /* #ifdef POWER_SAVING_FEATURE_WEARABLE */
1806 gboolean _ps_free_co_modem_event(gpointer modem)
1810 CoreObject *co_modem;
1811 const char *modem_name = NULL;
1812 g_return_val_if_fail(modem != NULL, FALSE);
1814 p = _ps_modem_ref_plugin(modem);
1815 s = tcore_plugin_ref_server(p);
1816 co_modem = _ps_modem_ref_co_modem(modem);
1818 modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_modem));
1819 if( TRUE == g_str_has_suffix(modem_name , "0")) {
1820 tcore_server_remove_notification_hook(s, __on_hook_powered_0);
1821 tcore_server_remove_notification_hook(s, __on_hook_flight_0);
1822 tcore_server_remove_notification_hook(s, __on_hook_sim_init_0);
1824 tcore_server_remove_notification_hook(s, __on_hook_powered_1);
1825 tcore_server_remove_notification_hook(s, __on_hook_flight_1);
1826 tcore_server_remove_notification_hook(s, __on_hook_sim_init_1);
1831 enum tcore_hook_return __on_hook_modem_added(Server *s,
1832 CoreObject *source, enum tcore_notification_command command,
1833 unsigned int data_len, void *data, void *user_data)
1835 gpointer *master = user_data;
1836 TcorePlugin *plg = data;
1837 if(FALSE == _ps_master_create_modems(master, plg)){
1838 err("Failed to create modem");
1840 return TCORE_HOOK_RETURN_CONTINUE;
1843 gboolean _ps_get_co_modem_values(gpointer modem)
1846 CoreObject *co_modem = NULL;
1847 CoreObject *co_sim = NULL;
1849 GSList *co_lists = NULL;
1850 gboolean sim_init = FALSE, modem_powered = FALSE, flight_mode = FALSE;
1852 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1853 struct tel_sim_imsi *sim_imsi = NULL;
1855 g_return_val_if_fail(modem != NULL, FALSE);
1857 co_modem = _ps_modem_ref_co_modem(modem);
1861 plg = tcore_object_ref_plugin(co_modem);
1865 co_lists = tcore_plugin_get_core_objects_bytype(plg, CORE_OBJECT_TYPE_SIM);
1869 co_sim = co_lists->data;
1870 g_slist_free(co_lists);
1872 sim_status = tcore_sim_get_status(co_sim);
1873 if(sim_status == SIM_STATUS_INIT_COMPLETED)
1876 sim_imsi = tcore_sim_get_imsi(co_sim);
1877 modem_powered = tcore_modem_get_powered(co_modem);
1878 flight_mode = tcore_modem_get_flight_mode_state(co_modem);
1880 _ps_modem_processing_flight_mode(modem, flight_mode);
1881 _ps_modem_processing_power_enable(modem, modem_powered);
1883 sim_type = tcore_sim_get_type(co_sim);
1885 if(sim_type == SIM_TYPE_NVSIM)
1886 _ps_modem_processing_sim_complete(modem, sim_init, PS_CDMA_DUMMY_PROFILE_PLMN);
1888 _ps_modem_processing_sim_complete(modem, sim_init, (gchar *)sim_imsi->plmn);
1893 gboolean _ps_hook_co_network_event(gpointer service)
1897 CoreObject *co_network = NULL;
1898 const char *modem_name = NULL;
1900 g_return_val_if_fail(service != NULL, FALSE);
1902 p = _ps_service_ref_plugin(service);
1903 s = tcore_plugin_ref_server(p);
1904 co_network = _ps_service_ref_co_network(service);
1906 modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_network));
1907 if( TRUE == g_str_has_suffix(modem_name , "0")) {
1908 tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, __on_hook_net_register_0, service);
1909 tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, __on_hook_net_change_0, service);
1910 tcore_server_add_notification_hook(s, TNOTI_NETWORK_RESTRICTED_STATE, __on_hook_net_restricted_state_0, service);
1912 tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, __on_hook_net_register_1, service);
1913 tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, __on_hook_net_change_1, service);
1914 tcore_server_add_notification_hook(s, TNOTI_NETWORK_RESTRICTED_STATE, __on_hook_net_restricted_state_1, service);
1919 gboolean _ps_get_co_network_values(gpointer service)
1921 CoreObject *co_network = NULL;
1922 gboolean ps_attached = FALSE;
1923 gint ps_restricted = 0;
1925 enum telephony_network_service_domain_status ps_status;
1926 enum telephony_network_access_technology act;
1928 g_return_val_if_fail(service != NULL, FALSE);
1930 co_network = _ps_service_ref_co_network(service);
1931 ps_dbg_ex_co(co_network, "Entered ");
1933 tcore_network_get_service_status(co_network, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
1934 tcore_network_get_access_technology(co_network, &act);
1936 if (ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
1939 ps_restricted = tcore_network_get_restricted_state(co_network);
1941 _ps_service_set_restricted(service, ((ps_restricted == NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
1942 _ps_service_set_roaming(service, tcore_network_get_roaming_state(co_network));
1943 _ps_service_set_ps_attached(service, ps_attached);
1944 _ps_service_set_access_technology(service, act);
1949 gboolean _ps_hook_co_ps_event(gpointer service)
1953 CoreObject *co_ps = NULL;
1954 const char *modem_name = NULL;
1955 g_return_val_if_fail(service != NULL, FALSE);
1957 ps_dbg_ex_co(_ps_service_ref_co_network(service), "Entered ");
1958 p = _ps_service_ref_plugin(service);
1959 s = tcore_plugin_ref_server(p);
1960 co_ps = _ps_service_ref_co_ps(service);
1962 modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_ps));
1963 if( TRUE == g_str_has_suffix(modem_name , "0")) {
1964 tcore_server_add_notification_hook(s, TNOTI_PS_CALL_STATUS, __on_hook_call_status_0, service);
1965 tcore_server_add_notification_hook(s, TNOTI_PS_CURRENT_SESSION_DATA_COUNTER, __on_hook_session_data_counter_0, service);
1966 tcore_server_add_notification_hook(s, TNOTI_PS_PDP_IPCONFIGURATION, __on_hook_ipconfiguration_0, service);
1968 tcore_server_add_notification_hook(s, TNOTI_PS_CALL_STATUS, __on_hook_call_status_1, service);
1969 tcore_server_add_notification_hook(s, TNOTI_PS_CURRENT_SESSION_DATA_COUNTER, __on_hook_session_data_counter_1, service);
1970 tcore_server_add_notification_hook(s, TNOTI_PS_PDP_IPCONFIGURATION, __on_hook_ipconfiguration_1, service);
1975 gboolean _ps_free_modem_event(gpointer modem)
1979 g_return_val_if_fail(modem != NULL, FALSE);
1981 p = _ps_modem_ref_plugin(modem);
1982 s = tcore_plugin_ref_server(p);
1984 tcore_server_remove_notification_hook(s, __on_hook_powered);
1985 tcore_server_remove_notification_hook(s, __on_hook_flight);
1986 tcore_server_remove_notification_hook(s, __on_hook_sim_init);
1988 #ifdef POWER_SAVING_FEATURE_WEARABLE
1989 tcore_server_remove_notification_hook(s, __on_hook_voice_call_status);
1990 #endif /* #ifdef POWER_SAVING_FEATURE_WEARABLE */
1996 gboolean _ps_free_co_ps_event(gpointer service)
2000 CoreObject *co_ps = NULL;
2001 CoreObject * co_network;
2002 const char * modem_name = NULL;
2004 g_return_val_if_fail(service != NULL, FALSE);
2005 co_network = _ps_service_ref_co_network(service);
2007 ps_dbg_ex_co(co_network, "Entered ");
2008 p = _ps_service_ref_plugin(service);
2009 s = tcore_plugin_ref_server(p);
2010 co_ps = _ps_service_ref_co_ps(service);
2012 modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_ps));
2014 ps_dbg_ex_co(co_network, "modem name %s", modem_name);
2016 if( TRUE == g_str_has_suffix(modem_name , "0")) {
2017 tcore_server_remove_notification_hook(s, __on_hook_call_status_0);
2018 tcore_server_remove_notification_hook(s, __on_hook_session_data_counter_0);
2019 tcore_server_remove_notification_hook(s, __on_hook_ipconfiguration_0);
2021 tcore_server_remove_notification_hook(s, __on_hook_call_status_1);
2022 tcore_server_remove_notification_hook(s, __on_hook_session_data_counter_1);
2023 tcore_server_remove_notification_hook(s, __on_hook_ipconfiguration_1);
2028 gboolean _ps_free_co_network_event(gpointer service)
2032 CoreObject *co_network = NULL;
2033 const char *modem_name = NULL;
2034 g_return_val_if_fail(service != NULL, FALSE);
2036 ps_dbg_ex_co(_ps_service_ref_co_network(service), "Entered ");
2037 p = _ps_service_ref_plugin(service);
2038 s = tcore_plugin_ref_server(p);
2039 co_network = _ps_service_ref_co_network(service);
2041 modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_network));
2042 if( TRUE == g_str_has_suffix(modem_name , "0")) {
2043 tcore_server_remove_notification_hook(s, __on_hook_net_register_0);
2044 tcore_server_remove_notification_hook(s, __on_hook_net_change_0);
2045 tcore_server_remove_notification_hook(s, __on_hook_net_restricted_state_0);
2047 tcore_server_remove_notification_hook(s, __on_hook_net_register_1);
2048 tcore_server_remove_notification_hook(s, __on_hook_net_change_1);
2049 tcore_server_remove_notification_hook(s, __on_hook_net_restricted_state_1);
2054 gboolean _ps_update_cellular_state_key(gpointer object)
2057 static Storage *strg;
2058 int current_state = 0;
2059 int stored_state = 0;
2060 ps_service_t *service = object;
2061 CoreObject * co_network = _ps_service_ref_co_network(service);
2062 ps_modem_t *modem = _ps_service_ref_modem(service);
2063 ps_subs_type subs_type = _ps_modem_get_subs_type(modem);
2064 int selected_sim = -1;
2066 ps_dbg_ex_co(co_network, "Update cellular state for [SIM%d]", subs_type + 1);
2068 s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
2069 strg = tcore_server_find_storage(s, "vconf");
2071 selected_sim = tcore_storage_get_int(strg, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
2072 if ((selected_sim != -1) &&(selected_sim != (int)subs_type)) {
2073 ps_warn_ex_co(co_network, "Update for only [SIM%d] selected by Setting", selected_sim + 1);
2077 current_state = _ps_service_check_cellular_state(service);
2079 if (tcore_modem_get_flight_mode_state(modem->co_modem) == TRUE)
2080 current_state = TELEPHONY_PS_FLIGHT_MODE;
2082 stored_state = tcore_storage_get_int(strg, STORAGE_KEY_CELLULAR_STATE);
2083 ps_dbg_ex_co(co_network, "Cellular state, current: [%d], stored: [%d]", current_state, stored_state);
2084 if (current_state != stored_state)
2085 tcore_storage_set_int(strg, STORAGE_KEY_CELLULAR_STATE, current_state);