Code Sync up from tizen_2.4
[platform/core/telephony/tel-plugin-packetservice.git] / src / tcore-interface.c
1 /*
2  * PacketService Control Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: DongHoo Park <donghoo.park@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include "ps.h"
23
24 #include <server.h>
25 #include <plugin.h>
26 #include <storage.h>
27 #include <co_ps.h>
28 #include <co_context.h>
29 #include <co_modem.h>
30 #include <co_sim.h>
31 #include <type/network.h>
32 #include <co_network.h>
33 #ifdef POWER_SAVING_FEATURE_WEARABLE
34 #include <co_call.h>
35 #endif
36 #include <user_request.h>
37
38 #define TIMEOUT_MAX                     1280
39
40 enum ps_call_state {
41         PS_CALL_STATE_RESULT_OK = 0x00,
42         PS_CALL_STATE_RESULT_CONNECT = 0x01,
43         PS_CALL_STATE_RESULT_NO_CARRIER = 0x03
44 };
45
46 struct work_queue_data {
47         unsigned int id;
48         UserRequest *ur;
49 };
50
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);
53
54
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);
59 #endif
60
61
62 static gboolean ps_util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur)
63 {
64         struct work_queue_data *wqd;
65
66         if (!queue)
67                 return FALSE;
68
69         wqd = calloc(sizeof(struct work_queue_data), 1);
70         if (!wqd)
71                 return FALSE;
72
73         wqd->id = id;
74         wqd->ur = ur;
75         g_queue_push_tail(queue, wqd);
76
77         dbg("id = %d, ur = 0x%x", wqd->id, wqd->ur);
78         return TRUE;
79 }
80
81 static guint ps_util_get_count_waiting_job(GQueue *queue, unsigned int id)
82 {
83         guint i = 0;
84         guint count = 0;
85         struct work_queue_data *wqd = NULL;
86
87         if (!queue)
88                 return count;
89
90         dbg("job count: %d", g_queue_get_length(queue));
91
92         do {
93                 wqd = g_queue_peek_nth(queue, i);
94                 if (!wqd)
95                         break;
96
97                 if (wqd->id == id) {
98                         count++;
99                 }
100
101                 i++;
102         } while (wqd != NULL);
103
104         dbg("count: %d, id = %d", count, id);
105
106         return count;
107 }
108
109 static UserRequest *ps_util_pop_waiting_job(GQueue *queue, unsigned int id)
110 {
111         int i = 0;
112         UserRequest *ur;
113         struct work_queue_data *wqd;
114
115         if (!queue)
116                 return NULL;
117
118         dbg("before waiting job count: %d", g_queue_get_length(queue));
119
120         do {
121                 wqd = g_queue_peek_nth(queue, i);
122                 if (!wqd)
123                         return NULL;
124
125                 if (wqd->id == id) {
126                         wqd = g_queue_pop_nth(queue, i);
127                         break;
128                 }
129
130                 i++;
131         } while (wqd != NULL);
132
133         dbg("after  waiting job count: %d", g_queue_get_length(queue));
134
135         if (!wqd)
136                 return NULL;
137
138         ur = wqd->ur;
139         free(wqd);
140
141         return ur;
142 }
143 #if 0
144 static gboolean __ps_check_pdp_permanent_reject_cause(int cause)
145 {
146         gboolean ret = TRUE;
147
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)) {
153                 switch(cause) {
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");
162                                 ret = FALSE;
163                         } break;
164                         default: {
165                         } break;
166                 }
167         }
168         if(ps_feature_get_bool(PS_FEATURE_OPERATOR_KT)) {
169                 switch(cause) {
170                         case PS_PDP_PERMANENT_REJECT_NSAPI_ALREADY_USED:
171                         case PS_PDP_PERMANENT_REJECT_PROTOCOL_ERROR:{
172                                 dbg("Permanent reject cause");
173                                 ret = FALSE;
174                         } break;
175                         default:
176                           break;
177                 }
178         }
179         if(ps_feature_get_bool(PS_FEATURE_OPERATOR_SKT)) {
180                 switch(cause) {
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");
197                                 ret = FALSE;
198                         } break;
199                         default:
200                           break;
201                 }
202         }
203         return ret;
204 }
205 #endif
206 static gboolean __ps_set_network_mode(int mode, void *data)
207 {
208         int c_mode = 0;
209         gboolean roaming = FALSE;
210         struct treq_network_set_mode req;
211
212         UserRequest *ur = NULL;
213         ps_modem_t *modem = data;
214
215         GSList *co_list = NULL;
216         CoreObject *co_network = NULL;
217
218         co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
219                         CORE_OBJECT_TYPE_NETWORK);
220
221         if (G_UNLIKELY(co_list == NULL)) {
222                 return FALSE;
223         }
224
225         memset(&req,0,sizeof(struct treq_network_set_mode));
226
227         co_network = (CoreObject *) co_list->data;
228         c_mode = mode;
229         dbg("current network mode (%d)", c_mode);
230
231         if(modem->data_allowed) {
232                 c_mode |= NETWORK_MODE_LTE;
233         }
234         else{
235                 c_mode &= ~NETWORK_MODE_LTE;
236         }
237         dbg("network mode(%d) - data allowed(%d)", c_mode, modem->data_allowed);
238
239         roaming = tcore_network_get_roaming_state(co_network);
240         if(modem->data_allowed && roaming) {
241                 c_mode &= ~NETWORK_MODE_LTE;
242         }
243         dbg("network mode(%d) - roaming(%d)", c_mode, roaming);
244
245         dbg("candidate mode(%d), current mode(%d)", c_mode, mode);
246         if(c_mode == mode) {
247                 dbg("mode is the same as before, do not send");
248                 g_slist_free(co_list);
249                 return FALSE;
250         }
251
252         req.mode = c_mode;
253
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);
259
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);
264         }
265
266         g_slist_free(co_list);
267         return TRUE;
268 }
269
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)
272 {
273         dbg("User request dispatch failed so need to send response for command [%d]", command);
274         switch (command) {
275         case TRESP_NETWORK_SEARCH:
276                 {
277                         struct tresp_network_search search_rsp;
278                         memset(&search_rsp, 0, sizeof(struct tresp_network_search));
279
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);
284                 }
285                 break;
286         case TRESP_NETWORK_SET_PLMN_SELECTION_MODE:
287                 {
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));
290
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);
294                 }
295                 break;
296         case TRESP_NETWORK_SET_MODE:
297                 {
298                         struct tresp_network_set_mode set_rsp;
299                         memset(&set_rsp, 0, sizeof(struct tresp_network_set_mode));
300
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);
304                 }
305                 break;
306         case TRESP_NETWORK_GET_MODE:
307                 {
308                         struct tresp_network_get_mode get_rsp;
309                         memset(&get_rsp, 0, sizeof(struct tresp_network_get_mode));
310
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);
314                 }
315                 break;
316         case TRESP_MODEM_POWER_OFF:
317                 {
318                         struct tresp_modem_power_off set_power_off_rsp;
319                         memset(&set_power_off_rsp, 0, sizeof(struct tresp_modem_power_off));
320
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);
324                 }
325                 break;
326         case TRESP_MODEM_POWER_LOW:
327                 {
328                         struct tresp_modem_power_low set_power_low_rsp;
329                         memset(&set_power_low_rsp, 0, sizeof(struct tresp_modem_power_low));
330
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);
334                 }
335                 break;
336         case TRESP_MODEM_SET_FLIGHTMODE:
337                 {
338                         struct tresp_modem_set_flightmode set_flight_mode_rsp;
339                         memset(&set_flight_mode_rsp, 0, sizeof(struct tresp_modem_set_flightmode));
340
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);
344                 }
345                 break;
346         default :
347                         err("Command type not expected [%d]", command);
348         }
349         /* Unref User request */
350         tcore_user_request_unref( ur);
351 }
352
353 void __ps_hook_response_cb(UserRequest *ur, enum tcore_response_command command,
354         unsigned int data_len, const void *data, void *user_data)
355 {
356         ps_modem_t *modem = user_data;
357         CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
358         guint count;
359         guint id;
360         id = ((command & ~TCORE_RESPONSE) & TCORE_REQUEST);
361
362         ps_dbg_ex_co(co_modem, "Entered");
363         count = ps_util_get_count_waiting_job(modem->work_queue, id);
364
365         if (count != 0) {
366                 ur = ps_util_pop_waiting_job(modem->work_queue, id);
367                 if(ur){
368                         GSList *co_list = NULL;
369                         CoreObject *co_network = NULL;
370                         TReturn ret = TCORE_RETURN_SUCCESS;
371
372                         co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
373                                 CORE_OBJECT_TYPE_NETWORK);
374
375                         if (G_UNLIKELY(co_list == NULL)) {
376                                 ps_err_ex_co(co_modem, "Network CoreObject is not present");
377                                 return;
378                         }
379
380                         co_network = (CoreObject *) co_list->data;
381                         g_slist_free(co_list);
382
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);
399                         }
400                         return;
401                 }
402         }
403
404         switch(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");
408                         if (count == 0) {
409                                 modem->hook_flag &= PS_RESET_NETWORK_SEARCH_FLAG;
410                         }
411                         break;
412                 case TRESP_NETWORK_SET_PLMN_SELECTION_MODE:
413                         ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SET_PLMN_SELECTION_MODE response received ");
414                         if (count == 0) {
415                                 modem->hook_flag &= PS_NETWORK_RESET_SELECTION_FLAG;
416                         }
417                         break;
418                 case TRESP_NETWORK_SET_MODE:
419                 {
420                         ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SET_MODE response received ");
421
422                         if (count == 0) {
423                                 modem->hook_flag &= PS_NETWORK_RESET_SELECT_MODE_FLAG ;
424                         }
425
426                 }break;
427                 case TRESP_NETWORK_GET_MODE:{
428                         gboolean rv = FALSE;
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);
431
432                         if (count == 0) {
433                                 modem->hook_flag &= PS_NETWORK_RESET_GET_MODE_FLAG;
434                         }
435
436                         rv = __ps_set_network_mode(resp_get_mode->mode, modem);
437                         if(rv) {
438                                 dbg("network set mode request!");
439                                 return;
440                         }
441                 }break;
442                 case TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
443                 ps_dbg_ex_co(co_modem, "TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION response received ");
444                 if (count == 0) {
445                         modem->hook_flag &= PS_NETWORK_RESET_SET_DEFAULT_DATA_SUBS;
446                 }
447                 break;
448                 case TRESP_MODEM_SET_FLIGHTMODE:
449                 ps_dbg_ex_co(co_modem, "TRESP_MODEM_SET_FLIGHTMODE response received ");
450                 if (count == 0) {
451                                 modem->hook_flag &= PS_NETWORK_RESET_SET_FLIGHT_MODE_FLAG;
452                 }
453                 break;
454                 case TRESP_MODEM_POWER_LOW:
455                 ps_dbg_ex_co(co_modem, "TRESP_MODEM_POWER_LOW response received ");
456                 if (count == 0) {
457                                 modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_LOW_FLAG;
458                 }
459                 break;
460                 case TRESP_MODEM_POWER_OFF:
461                 ps_dbg_ex_co(co_modem, "TRESP_MODEM_POWER_OFF response received ");
462                 if (count == 0) {
463                                 modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_OFF_FLAG;
464                 }
465                 break;
466                 case TRESP_SIM_SET_POWERSTATE:
467                 ps_dbg_ex_co(co_modem, "TRESP_SIM_SET_POWERSTATE response received ");
468                 if (count == 0) {
469                                 modem->hook_flag &= PS_SIM_SET_POWER_STATE_FLAG;
470                 }
471                 break;
472                 default :{
473                         ps_dbg_ex_co(co_modem, "Unexpected response ");
474                 } break;
475         }
476         ps_dbg_ex_co(co_modem, " FLAG %x", modem->hook_flag);
477
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);
483         }
484 }
485
486 void __ps_modem_get_mode_pref_change(ps_modem_t* modem, UserRequest *ur)
487 {
488         enum telephony_network_service_type svc_type;
489         enum tcore_request_command cmd;
490         GSList *co_list = NULL;
491
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;
496                 return;
497         }
498         modem->mode_pref_changed = TRUE;
499
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;
504
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);
509                 switch(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;
515                         } break;
516
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;
521                         } break;
522                         case NETWORK_SERVICE_TYPE_LTE: {
523                                 if(req->mode & NETWORK_MODE_LTE)
524                                         modem->mode_pref_changed = FALSE;
525                         } break;
526                         default:
527                           break;
528                 }
529         }
530         dbg("mode_pref_changed : %d", modem->mode_pref_changed);
531 }
532
533 void __ps_modem_cp_reset_send_pending_request_response(gpointer data)
534 {
535         gpointer *queue_data = NULL;
536         ps_modem_t *modem = data;
537         CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
538
539         ps_dbg_ex_co(co_modem, "Entered");
540         queue_data = g_queue_pop_head(modem->work_queue);
541         while( queue_data) {
542                 struct work_queue_data *wqd = (struct work_queue_data *)queue_data ;
543                 if(wqd->ur) {
544                         enum tcore_request_command cmd = tcore_user_request_get_command(wqd->ur);
545
546                         if(cmd == TREQ_NETWORK_SEARCH){
547                                 struct tresp_network_search search_rsp;
548                                 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
549
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);
554                         }
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));
558
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);
562                         }
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));
566
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);
570                         }
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));
574
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);
578                         }
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));
582
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);
586                         }
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));
590
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);
594
595                         }
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));
599
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);
603
604                         }
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));
608
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);
612
613                         }
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));
617
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);
621
622                         } else {
623                                 err("Unexpected command ");
624                         }
625                         tcore_user_request_unref(wqd->ur);
626
627                         /* Memory Free */
628                         free(wqd);
629                 }
630                 queue_data = g_queue_pop_head(modem->work_queue);
631         }
632 }
633
634 static void __ps_modem_cp_reset_handler(gpointer object)
635 {
636         ps_modem_t * modem = object;
637
638         dbg("Entred");
639         /* check for any pending request in modem queue and respond with error */
640         __ps_modem_cp_reset_send_pending_request_response(modem);
641
642         /* reset modem flag */
643         modem->hook_flag  &=PS_NO_PENDING_REQUEST;
644 }
645
646
647 void __ps_modem_set_hook_flag(ps_modem_t *modem ,enum tcore_request_command cmd)
648 {
649         CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
650
651         switch(cmd) {
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);
656                 break;
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);
660                 break;
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);
664                 break;
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);
668                 break;
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);
672                 break;
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);
676                 break;
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);
680                 break;
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);
684                 break;
685                 default:
686                         ps_dbg_ex_co(co_modem, "Not handled request");
687                 break;
688         }
689 }
690
691 enum tcore_hook_return ps_handle_hook(Server *s, UserRequest *ur, void *user_data)
692 {
693         gboolean ret = FALSE;
694         TReturn rv = TCORE_RETURN_FAILURE;
695
696         CoreObject *co_ps = NULL;
697         GSList *co_ps_list = NULL;
698         TcorePlugin *target_plg = NULL;
699         int value = 0;
700         guint job_cnt = 0;
701         ps_modem_t *modem = user_data;
702         CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
703
704         char *modem_name = NULL;
705         enum tcore_request_command cmd = tcore_user_request_get_command(ur);
706
707         ps_dbg_ex_co(co_modem, "Entered");
708
709         modem_name = tcore_user_request_get_modem_name (ur);
710         if (!modem_name)
711                 return TCORE_HOOK_RETURN_CONTINUE;
712
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)",
716                                 modem_name,
717                                 tcore_server_get_cp_name_by_plugin(target_plg));
718
719                 if( cmd == TREQ_NETWORK_SEARCH ) {
720                         co_ps_list = tcore_plugin_get_core_objects_bytype (target_plg, CORE_OBJECT_TYPE_PS);
721                         if (!co_ps_list) {
722                                 ps_dbg_ex_co(co_modem, "No ps core object present ");
723                                 free(modem_name);
724                                 return TCORE_HOOK_RETURN_CONTINUE;
725                         }
726                         co_ps = co_ps_list->data;
727                         g_slist_free (co_ps_list);
728
729                         if (!co_ps) {
730                                 ps_dbg_ex_co(co_modem, "No ps core object present ");
731                                 free(modem_name);
732                                 return TCORE_HOOK_RETURN_CONTINUE;
733                         }
734
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);
740                                 free(modem_name);
741                                 return TCORE_HOOK_RETURN_CONTINUE;
742                         }
743
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");
750                                         free(modem_name);
751                                         return TCORE_HOOK_RETURN_CONTINUE;
752                                 }
753                                 __ps_modem_set_hook_flag(modem, cmd);
754                                 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
755                         }
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);
759                 }
760                 free(modem_name);
761                 return TCORE_HOOK_RETURN_CONTINUE;
762         }
763
764         if(modem_name)
765                 free(modem_name);
766
767         co_ps_list = tcore_plugin_get_core_objects_bytype (target_plg, CORE_OBJECT_TYPE_PS);
768         if (!co_ps_list)
769                 return TCORE_HOOK_RETURN_CONTINUE;
770
771         co_ps = co_ps_list->data;
772         g_slist_free (co_ps_list);
773
774         if (!co_ps)
775                 return TCORE_HOOK_RETURN_CONTINUE;
776
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);
782
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);
788                         } else {
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);
793                         }
794                         tcore_user_request_unref(ur);
795                         return TCORE_HOOK_RETURN_STOP_PROPAGATION;
796                 }
797                 return TCORE_HOOK_RETURN_CONTINUE;
798         }
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;
808                 }
809 #else
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;
814
815 #endif
816         }
817
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;
825                 }
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;
831                 }
832 #else
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;
836                 }
837 #endif
838                 ps_dbg_ex_co(co_modem, "For rest command will wait for activation successful ");
839         }
840
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;
844         }
845
846         job_cnt = ps_util_get_count_waiting_job(modem->work_queue, cmd);
847         if(job_cnt){
848                 ps_err_ex_co(co_modem, "duplicated job for cmd(%d)", cmd);
849
850                 if(cmd == TREQ_NETWORK_SEARCH){
851                         struct tresp_network_search search_rsp;
852                         memset(&search_rsp, 0, sizeof(struct tresp_network_search));
853
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);
858                 }
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));
862
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);
866                 }
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));
870
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);
874                 }
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));
878
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);
882                 }
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));
886
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);
890                 }
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));
894
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);
898
899                 }
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));
903
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);
907
908                 }
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));
912
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);
916
917                 }
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));
921
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);
925
926                 }
927                 tcore_user_request_unref(ur);
928                 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
929         }
930
931         ps_dbg_ex_co(co_modem, "Deactivation request is sent, wait for call disconnect notification ");
932
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);
936
937                 if(!ur_pending){
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;
941                 }
942                 else{
943                         struct tresp_network_search search_rsp;
944                         struct tresp_network_set_cancel_manual_search search_cancel_rsp;
945
946                         memset(&search_rsp, 0, sizeof(struct tresp_network_search));
947                         memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
948
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);
953
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);
958
959                         return TCORE_HOOK_RETURN_STOP_PROPAGATION;
960                 }
961         }
962
963         ret = ps_util_add_waiting_job(modem->work_queue, cmd , ur);
964         if(!ret){
965                 ps_dbg_ex_co(co_modem, "fail to add the request to queue");
966                 return TCORE_HOOK_RETURN_CONTINUE;
967         }
968
969         __ps_modem_get_mode_pref_change(modem, ur);
970         __ps_modem_set_hook_flag(modem, cmd);
971         return TCORE_HOOK_RETURN_STOP_PROPAGATION;
972 }
973
974 void __ps_send_pending_user_request(gpointer data)
975 {
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;
981
982         co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
983                         CORE_OBJECT_TYPE_NETWORK);
984
985         if (G_UNLIKELY(co_list == NULL)) {
986                 return ;
987         }
988
989         co_network = (CoreObject *) co_list->data;
990         g_slist_free(co_list);
991
992         co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
993                         CORE_OBJECT_TYPE_SIM);
994
995         if (G_UNLIKELY(co_list == NULL)) {
996                 return ;
997         }
998
999         co_sim = (CoreObject *) co_list->data;
1000         g_slist_free(co_list);
1001
1002         ps_dbg_ex_co(co_network, "Extracting the user request from the work queue");
1003
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);
1008                 if(wqd->ur) {
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);
1011
1012                         switch (wqd ->id) {
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);
1018                                         break;
1019                                 case TREQ_MODEM_SET_FLIGHTMODE:
1020                                 case TREQ_MODEM_POWER_OFF:
1021                                         tcore_object_dispatch_request(modem->co_modem, wqd->ur);
1022                                         break;
1023                                 case TREQ_MODEM_POWER_LOW:
1024                                 #ifdef POWER_SAVING_FEATURE_WEARABLE
1025                                                 __ps_check_handle_modem_off_request(modem, ON_REQUEST, TNOTI_UNKNOWN);
1026                                 #else
1027                                         if (modem->hook_flag & PS_NETWORK_SET_POWER_LOW) {
1028                                                 tcore_object_dispatch_request(modem->co_modem, wqd->ur);
1029                                         }
1030                                 #endif
1031
1032                                         break;
1033                                 case TREQ_SIM_SET_POWERSTATE:
1034                                         tcore_object_dispatch_request(co_sim, wqd->ur);
1035                                         break;
1036                                 default :
1037                                 ps_err_ex_co(co_network, "No expected request ");
1038                         }
1039                 }
1040
1041                 /* Freeing Allocated memory*/
1042                 free(wqd);
1043                 queue_data = g_queue_pop_head(modem->work_queue);
1044         }
1045         ps_dbg_ex_co(co_network, "All pending request sent ");
1046 }
1047
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,
1050                 void *user_data)
1051 {
1052         gpointer modem = NULL;
1053         gpointer service = user_data;
1054         CoreObject *co_network;
1055         gpointer co_ps = NULL;
1056         GSList *co_list;
1057
1058         gboolean b_data_allowed = FALSE;
1059         gboolean b_roaming_checker = TRUE;
1060         gboolean b_mms_checker = FALSE;
1061         gboolean b_ims_checker = FALSE;
1062
1063         struct tnoti_ps_call_status *cstatus = NULL;
1064
1065         dbg("call status event");
1066         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1067
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;
1074         }
1075
1076         modem = _ps_service_ref_modem(service);
1077         if(!modem){
1078                 ps_err_ex_co(co_network, "modem does not exist");
1079                 return TCORE_HOOK_RETURN_CONTINUE;
1080         }
1081
1082         b_data_allowed = _ps_modem_get_data_allowed(modem);
1083
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;
1088
1089                 co_context = co_list->data;
1090                 role = tcore_context_get_role(co_context);
1091
1092                 if( role == CONTEXT_ROLE_MMS || role == CONTEXT_ROLE_PREPAID_MMS){
1093                         b_mms_checker = TRUE;
1094                         break;
1095                 }
1096                 if( role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY){
1097                         b_ims_checker = TRUE;
1098                         break;
1099                 }
1100         }
1101
1102 #if !defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
1103                 ps_dbg_ex_co(co_network, "csc runtime feature disabled");
1104                 b_mms_checker = FALSE;
1105 #endif
1106
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;
1110         }
1111
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);
1114
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);
1118
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;
1123                 }
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;
1128                 }
1129         }
1130
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);
1134         }
1135         else if(cstatus->state == PS_CALL_STATE_RESULT_CONNECT) {       //CONNECTED
1136                 TReturn rv;
1137
1138                 if (tcore_ps_get_cid_active(co_ps, cstatus->context_id) == FALSE) {
1139                         ps_dbg_ex_co(co_network, "DDS scenario");
1140
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;
1146                         }
1147                 }
1148                 else {
1149                         _ps_service_set_connected(service, cstatus, TRUE);
1150                         tcore_ps_set_cid_connected(co_ps, cstatus->context_id, TRUE);
1151
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 ");
1154
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;
1159                                 }
1160                         }
1161                 }
1162         }
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;
1166                 int value = 0;
1167                 gboolean retry = TRUE;
1168
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);
1174
1175                         def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
1176                         if(def_context){
1177                                 gpointer co_context = NULL;
1178                                 co_context = _ps_context_ref_co_context(def_context);
1179                                 def_cid = tcore_context_get_id(co_context);
1180                         }
1181
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);
1186
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");
1189
1190                         /* Handle any pending request if present */
1191                         modem = _ps_service_ref_modem(service);
1192                         __ps_send_pending_user_request(modem);
1193
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);
1203                                 }
1204                         }
1205                 }
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);
1210                         }
1211                 }
1212         } // disconnected case
1213
1214         return TCORE_HOOK_RETURN_CONTINUE;
1215 }
1216
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,
1219                 void *user_data)
1220 {
1221         return __on_hook_call_status(s, source, command, data_len, data, user_data);
1222 }
1223
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,
1226                 void *user_data)
1227 {
1228         return __on_hook_call_status(s, source, command, data_len, data, user_data);
1229 }
1230
1231
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,
1234                 void *user_data)
1235 {
1236         gpointer service = user_data;
1237         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1238
1239         ps_dbg_ex_co(_ps_service_ref_co_network(service), "session data counter event");
1240
1241         return TCORE_HOOK_RETURN_CONTINUE;
1242 }
1243
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,
1246                 void *user_data)
1247 {
1248         gpointer service = user_data;
1249         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1250
1251         ps_dbg_ex_co(_ps_service_ref_co_network(service), "session data counter event");
1252
1253         return TCORE_HOOK_RETURN_CONTINUE;
1254 }
1255
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,
1258                 void *user_data)
1259 {
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];
1265
1266         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION);
1267
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;
1274         }
1275
1276         ps_dbg_ex_co(co_network, "ip configuration event");
1277
1278         /*
1279          * In case IPv4 address is available and DNS address
1280          * is NOT available, set -
1281          * DNS 1 - Google DNS
1282          * DNS 2 - Open DNS
1283          */
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");
1293
1294                         //google dns 1st
1295                         devinfo->primary_dns[0] = 8;
1296                         devinfo->primary_dns[1] = 8;
1297                         devinfo->primary_dns[2] = 8;
1298                         devinfo->primary_dns[3] = 8;
1299                 }
1300
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")) {
1305                         //open dns 2nd
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;
1311                 }
1312         }
1313
1314         /*
1315          * In case IPv6 address is available and DNS address
1316          * is NOT available, set -
1317          * DNS 1 - Google DNS
1318          * DNS 2 - Open DNS
1319          */
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");
1324
1325                 }
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");
1329                 }
1330         }
1331
1332         _ps_service_set_context_info(service, devinfo);
1333
1334         return TCORE_HOOK_RETURN_CONTINUE;
1335 }
1336
1337
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,
1340                 void *user_data)
1341 {
1342         return __on_hook_ipconfiguration(s, source, command, data_len, data, user_data);
1343 }
1344
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,
1347                 void *user_data)
1348 {
1349         return __on_hook_ipconfiguration(s, source, command, data_len, data, user_data);
1350 }
1351
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)
1354 {
1355         gpointer modem = user_data;
1356         CoreObject * co_modem;
1357         struct tnoti_modem_power *modem_power = NULL;
1358         int  power = PS_MODEM_STATE_UNKNOWN;
1359
1360         CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE);
1361
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;
1367         }
1368
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);
1372
1373         switch(modem_power->state) {
1374                 case MODEM_STATE_ONLINE:
1375                 case MODEM_STATE_RESUME: {
1376                         power = PS_MODEM_STATE_ONLINE;
1377                 } break;
1378                 case MODEM_STATE_LOW: {
1379                         power = PS_MODEM_STATE_LOW;
1380                 } break;
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);
1386
1387                         power = PS_MODEM_STATE_OFFLINE;
1388                 } break;
1389                 default: {
1390                         ps_warn_ex_co(co_modem,"Unhandled modem power event." );
1391                 } break;
1392         }
1393
1394         if(power != PS_MODEM_STATE_UNKNOWN)
1395                 _ps_modem_processing_power_enable(modem, power);
1396
1397         return TCORE_HOOK_RETURN_CONTINUE;
1398 }
1399
1400
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)
1403 {
1404         return __on_hook_powered(s, source,     command, data_len, data, user_data);
1405 }
1406
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)
1409 {
1410         return __on_hook_powered(s, source,     command, data_len, data, user_data);
1411 }
1412
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)
1415 {
1416         gpointer modem = user_data;
1417         CoreObject * co_modem = _ps_modem_ref_co_modem(modem);
1418         struct tnoti_modem_flight_mode *modem_flight = NULL;
1419
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;
1424         }
1425
1426         ps_dbg_ex_co(co_modem, "flight mode event called");
1427
1428         modem_flight = (struct tnoti_modem_flight_mode *)data;
1429         _ps_modem_processing_flight_mode(modem, modem_flight->enable);
1430
1431         return TCORE_HOOK_RETURN_CONTINUE;
1432 }
1433
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)
1436 {
1437         return __on_hook_flight(s, source, command, data_len, data, user_data);
1438 }
1439
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)
1442 {
1443         return __on_hook_flight(s, source, command, data_len, data, user_data);
1444 }
1445
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,
1448                 void *user_data)
1449 {
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");
1455
1456         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
1457
1458
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;
1463         }
1464
1465         regist_status = (struct tnoti_network_registration_status *) data;
1466         if (regist_status->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
1467                 ps_attached = TRUE;
1468
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);
1471
1472         return TCORE_HOOK_RETURN_CONTINUE;
1473 }
1474
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,
1477                 void *user_data)
1478 {
1479         return __on_hook_net_register(s, source, command, data_len, data, user_data);
1480 }
1481
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,
1484                 void *user_data)
1485 {
1486         return __on_hook_net_register(s, source, command, data_len, data, user_data);
1487 }
1488
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,
1491                 void *user_data)
1492 {
1493         gpointer service = user_data;
1494         struct tnoti_network_change *network_change;
1495         CoreObject *co_network;
1496         dbg("network change event called");
1497
1498         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
1499
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;
1504         }
1505
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);
1509
1510         return TCORE_HOOK_RETURN_CONTINUE;
1511 }
1512
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,
1515                 void *user_data)
1516 {
1517         return __on_hook_net_change(s, source, command, data_len, data, user_data);
1518 }
1519
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,
1522                 void *user_data)
1523 {
1524         return __on_hook_net_change(s, source, command, data_len, data, user_data);
1525 }
1526
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,
1529                 void *user_data)
1530 {
1531         gpointer service = user_data;
1532         struct tnoti_network_restricted_state *network_restricted;
1533         CoreObject *co_network;
1534         dbg("network restricted event called");
1535
1536         g_return_val_if_fail(service != NULL, TCORE_HOOK_RETURN_CONTINUE);
1537
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;
1542         }
1543
1544         network_restricted = (struct tnoti_network_restricted_state *) data;
1545         ps_dbg_ex_co(co_network, "network restricted state(%d)", network_restricted->restricted_state);
1546
1547         _ps_service_set_restricted(service, ((network_restricted->restricted_state & NETWORK_RESTRICTED_STATE_PS_ALL) ? TRUE : FALSE));
1548
1549         return TCORE_HOOK_RETURN_CONTINUE;
1550 }
1551
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,
1554                 void *user_data)
1555 {
1556         return __on_hook_net_restricted_state(s, source,command, data_len, data, user_data);
1557 }
1558
1559
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,
1562                 void *user_data)
1563 {
1564         return __on_hook_net_restricted_state(s, source,command, data_len, data, user_data);
1565 }
1566
1567
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)
1570 {
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");
1576
1577         g_return_val_if_fail(user_data != NULL, TCORE_HOOK_RETURN_CONTINUE);
1578
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;
1584         }
1585
1586
1587         sim_data = (struct tnoti_sim_status *)data;
1588         ps_dbg_ex_co(co_modem, "sim status is (%d)", sim_data->sim_status);
1589
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);
1595
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);
1599                         } else {
1600                                 sim_imsi = tcore_sim_get_imsi(source);
1601                                 _ps_modem_processing_sim_complete((gpointer)user_data, TRUE, (gchar *)sim_imsi->plmn);
1602
1603                                 g_free(sim_imsi);
1604                         }
1605                 } break;
1606
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);
1613
1614                         /* TODO: Handle CDMA specific case */
1615                 } break;
1616
1617                 default: {
1618                         ps_dbg_ex_co(co_modem,  "Unhandled SIM state: [%d]", sim_data->sim_status);
1619                 } break;
1620         }
1621
1622         return TCORE_HOOK_RETURN_CONTINUE;
1623 }
1624
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)
1627 {
1628         GSList *list = 0;
1629         CoreObject *o = 0;
1630         int total_call_cnt = 0;
1631
1632         gboolean call_in_progress = FALSE;
1633
1634         list = tcore_plugin_get_core_objects_bytype(plugin, CORE_OBJECT_TYPE_CALL);
1635         if ( !list ) {
1636                 /* call_in_progress = FALSE; */
1637                 err("[ error ] co_list : 0");
1638                 return call_in_progress;
1639         }
1640
1641         o = (CoreObject *)list->data;
1642         g_slist_free(list);
1643
1644         total_call_cnt = tcore_call_object_total_length(o);
1645         dbg("totall call cnt (%d)", total_call_cnt);
1646
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;
1652         }else {
1653                 dbg("No call is in progress");
1654         }
1655
1656         return call_in_progress;
1657 }
1658
1659
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)
1662 {
1663         ps_modem_t *modem = data;
1664
1665         if (!modem) {
1666                 return;
1667         }
1668
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);
1672                 if (ur) {
1673                         gboolean call_in_progress;
1674                         dbg("Sending Pending SET POWER OFF");
1675
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.
1678                         */
1679                         call_in_progress = __ps_is_any_call_in_progress(tcore_object_ref_plugin(modem->co_modem), type, command);
1680
1681                         if (call_in_progress) {
1682                                 gboolean ret;
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);
1685                                 if(!ret) {
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;
1691
1692                                         }
1693                                 }
1694                         } else  {
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;
1699                                 }
1700                         }
1701                 }
1702         }else {
1703                 dbg("No pending TREQ_MODEM_POWER_LOW reqeust");
1704         }
1705 }
1706
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)
1709 {
1710         __ps_check_handle_modem_off_request(user_data,ON_CALL_NOTI_HOOK,command);
1711         return TCORE_HOOK_RETURN_CONTINUE;
1712 }
1713 #endif
1714
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)
1717 {
1718         return  __on_hook_sim_init(s, source, command,  data_len, data, user_data);
1719 }
1720
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)
1723 {
1724         return  __on_hook_sim_init(s, source, command,  data_len, data, user_data);
1725 }
1726
1727 void _ps_get_network_mode(gpointer data)
1728 {
1729         UserRequest *ur = NULL;
1730         ps_modem_t *modem =  data;
1731
1732         GSList *co_list = NULL;
1733         CoreObject *co_network = NULL;
1734
1735         ps_dbg_ex_co(_ps_modem_ref_co_modem(modem), "network get mode by data allowed option");
1736
1737         co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(modem->co_modem),
1738                         CORE_OBJECT_TYPE_NETWORK);
1739
1740         if (G_UNLIKELY(co_list == NULL)) {
1741                 return ;
1742         }
1743
1744         co_network = (CoreObject *) co_list->data;
1745
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);
1750
1751         __ps_modem_set_hook_flag(modem, TREQ_NETWORK_GET_MODE);
1752
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;
1757         }
1758         g_slist_free(co_list);
1759
1760         return;
1761 }
1762
1763 gboolean _ps_hook_co_modem_event(gpointer modem)
1764 {
1765         Server *s = NULL;
1766         TcorePlugin *p;
1767         CoreObject *co_modem;
1768         const char *modem_name = NULL;
1769         g_return_val_if_fail(modem != NULL, FALSE);
1770
1771         p = _ps_modem_ref_plugin(modem);
1772         s = tcore_plugin_ref_server(p);
1773         co_modem = _ps_modem_ref_co_modem(modem);
1774
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 */
1789         } else {
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 */
1802         }
1803         return TRUE;
1804 }
1805
1806 gboolean _ps_free_co_modem_event(gpointer modem)
1807 {
1808         Server *s = NULL;
1809         TcorePlugin *p;
1810         CoreObject *co_modem;
1811         const char *modem_name = NULL;
1812         g_return_val_if_fail(modem != NULL, FALSE);
1813
1814         p = _ps_modem_ref_plugin(modem);
1815         s = tcore_plugin_ref_server(p);
1816         co_modem = _ps_modem_ref_co_modem(modem);
1817
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);
1823         } else {
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);
1827         }
1828         return TRUE;
1829 }
1830
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)
1834 {
1835         gpointer *master = user_data;
1836         TcorePlugin *plg = data;
1837         if(FALSE == _ps_master_create_modems(master, plg)){
1838                 err("Failed to create modem");
1839         }
1840         return TCORE_HOOK_RETURN_CONTINUE;
1841 }
1842
1843 gboolean _ps_get_co_modem_values(gpointer modem)
1844 {
1845         TcorePlugin *plg;
1846         CoreObject *co_modem = NULL;
1847         CoreObject *co_sim = NULL;
1848
1849         GSList *co_lists = NULL;
1850         gboolean sim_init = FALSE, modem_powered = FALSE, flight_mode = FALSE;
1851         int sim_status = 0;
1852         enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1853         struct tel_sim_imsi *sim_imsi = NULL;
1854
1855         g_return_val_if_fail(modem != NULL, FALSE);
1856
1857         co_modem = _ps_modem_ref_co_modem(modem);
1858         if (!co_modem)
1859                 return FALSE;
1860
1861         plg = tcore_object_ref_plugin(co_modem);
1862         if (!plg)
1863                 return FALSE;
1864
1865         co_lists = tcore_plugin_get_core_objects_bytype(plg, CORE_OBJECT_TYPE_SIM);
1866         if (!co_lists)
1867                 return FALSE;
1868
1869         co_sim = co_lists->data;
1870         g_slist_free(co_lists);
1871
1872         sim_status = tcore_sim_get_status(co_sim);
1873         if(sim_status == SIM_STATUS_INIT_COMPLETED)
1874                 sim_init = TRUE;
1875
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);
1879
1880         _ps_modem_processing_flight_mode(modem, flight_mode);
1881         _ps_modem_processing_power_enable(modem, modem_powered);
1882
1883         sim_type = tcore_sim_get_type(co_sim);
1884
1885         if(sim_type == SIM_TYPE_NVSIM)
1886                 _ps_modem_processing_sim_complete(modem, sim_init, PS_CDMA_DUMMY_PROFILE_PLMN);
1887         else
1888                 _ps_modem_processing_sim_complete(modem, sim_init, (gchar *)sim_imsi->plmn);
1889         g_free(sim_imsi);
1890         return TRUE;
1891 }
1892
1893 gboolean _ps_hook_co_network_event(gpointer service)
1894 {
1895         Server *s = NULL;
1896         TcorePlugin *p;
1897         CoreObject *co_network = NULL;
1898         const char *modem_name = NULL;
1899
1900         g_return_val_if_fail(service != NULL, FALSE);
1901
1902         p = _ps_service_ref_plugin(service);
1903         s = tcore_plugin_ref_server(p);
1904         co_network = _ps_service_ref_co_network(service);
1905
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);
1911         } else {
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);
1915         }
1916         return TRUE;
1917 }
1918
1919 gboolean _ps_get_co_network_values(gpointer service)
1920 {
1921         CoreObject *co_network = NULL;
1922         gboolean ps_attached = FALSE;
1923         gint ps_restricted = 0;
1924
1925         enum telephony_network_service_domain_status ps_status;
1926         enum telephony_network_access_technology act;
1927
1928         g_return_val_if_fail(service != NULL, FALSE);
1929
1930         co_network = _ps_service_ref_co_network(service);
1931         ps_dbg_ex_co(co_network, "Entered ");
1932
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);
1935
1936         if (ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
1937                 ps_attached = TRUE;
1938
1939         ps_restricted = tcore_network_get_restricted_state(co_network);
1940
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);
1945
1946         return TRUE;
1947 }
1948
1949 gboolean _ps_hook_co_ps_event(gpointer service)
1950 {
1951         Server *s = NULL;
1952         TcorePlugin *p;
1953         CoreObject *co_ps = NULL;
1954         const char *modem_name = NULL;
1955         g_return_val_if_fail(service != NULL, FALSE);
1956
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);
1961
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);
1967         } else {
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);
1971         }
1972         return TRUE;
1973 }
1974
1975 gboolean _ps_free_modem_event(gpointer modem)
1976 {
1977         Server *s = NULL;
1978         TcorePlugin *p;
1979         g_return_val_if_fail(modem != NULL, FALSE);
1980
1981         p = _ps_modem_ref_plugin(modem);
1982         s = tcore_plugin_ref_server(p);
1983
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);
1987
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 */
1991
1992         return TRUE;
1993
1994 }
1995
1996 gboolean _ps_free_co_ps_event(gpointer service)
1997 {
1998         Server *s = NULL;
1999         TcorePlugin *p;
2000         CoreObject *co_ps = NULL;
2001         CoreObject * co_network;
2002         const char * modem_name = NULL;
2003
2004         g_return_val_if_fail(service != NULL, FALSE);
2005         co_network = _ps_service_ref_co_network(service);
2006
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);
2011
2012         modem_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co_ps));
2013         if(modem_name){
2014                 ps_dbg_ex_co(co_network, "modem name %s", modem_name);
2015         }
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);
2020          } else {
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);
2024          }
2025          return TRUE;
2026 }
2027
2028 gboolean _ps_free_co_network_event(gpointer service)
2029 {
2030         Server *s = NULL;
2031         TcorePlugin *p;
2032         CoreObject *co_network = NULL;
2033         const char *modem_name = NULL;
2034         g_return_val_if_fail(service != NULL, FALSE);
2035
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);
2040
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);
2046         } else {
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);
2050         }
2051         return TRUE;
2052 }
2053
2054 gboolean _ps_update_cellular_state_key(gpointer object)
2055 {
2056         Server *s = NULL;
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;
2065
2066         ps_dbg_ex_co(co_network, "Update cellular state for [SIM%d]", subs_type + 1);
2067
2068         s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
2069         strg = tcore_server_find_storage(s, "vconf");
2070
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);
2074                 return FALSE;
2075         }
2076
2077         current_state = _ps_service_check_cellular_state(service);
2078
2079         if (tcore_modem_get_flight_mode_state(modem->co_modem) == TRUE)
2080                 current_state = TELEPHONY_PS_FLIGHT_MODE;
2081
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);
2086
2087         return TRUE;
2088 }
2089