Correct some typo and add missing feature define
[platform/core/telephony/tel-plugin-packetservice.git] / src / ps_hook.c
1 /*
2  * tel-plugin-packetservice
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_common.h"
23 #include "ps_hook.h"
24 #include "ps_context.h"
25 #include "ps_modem.h"
26 #include "ps_service.h"
27
28 #include <server.h>
29 #include <plugin.h>
30 #include <co_ps.h>
31 #include <co_context.h>
32 #include <co_modem.h>
33 #include <co_sim.h>
34 #include <type/network.h>
35 #include <co_network.h>
36 #include <co_call.h>
37 #include <user_request.h>
38
39 #include "ps_log.h"
40
41 #ifdef TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL
42 typedef enum {
43         ON_REQUEST,
44         ON_NON_CALL_NOTI_HOOK,
45         ON_CALL_NOTI_HOOK,
46 } __ps_call_flow_type;
47
48 static gboolean __ps_set_network_mode(int mode, void *data)
49 {
50         int c_mode = 0;
51         gboolean roaming = FALSE;
52         struct treq_network_set_mode req;
53
54         UserRequest *ur = NULL;
55         ps_modem_t *modem = data;
56
57         CoreObject *co_network = NULL;
58
59         memset(&req, 0, sizeof(struct treq_network_set_mode));
60
61         co_network = tcore_plugin_ref_core_object(tcore_object_ref_plugin(modem->co_modem),
62                                                   CORE_OBJECT_TYPE_NETWORK);
63         c_mode = mode;
64
65         if (modem->data_allowed)
66                 c_mode |= NETWORK_MODE_LTE;
67         else
68                 c_mode &= ~NETWORK_MODE_LTE;
69
70         roaming = tcore_network_get_roaming_state(co_network);
71         if (modem->data_allowed && roaming)
72                 c_mode &= ~NETWORK_MODE_LTE;
73
74         ps_dbg_ex_modem(modem, "candidate mode(%d), current mode(%d), roaming(%d), data allowed(%d)", c_mode, mode, roaming, modem->data_allowed);
75         if (c_mode == mode)
76                 return FALSE;
77
78         req.mode = c_mode;
79
80         ur = tcore_user_request_new(NULL, tcore_plugin_ref_plugin_name(tcore_object_ref_plugin(co_network)));
81         tcore_user_request_set_data(ur, sizeof(struct treq_network_set_mode), &req);
82         tcore_user_request_set_command(ur, TREQ_NETWORK_SET_MODE);
83
84         if (TCORE_RETURN_SUCCESS != tcore_server_dispatch_request(tcore_plugin_ref_server(tcore_object_ref_plugin(modem->co_modem)), ur)) {
85                 ps_err_ex_modem(modem, "Failed to dispatch");
86                 tcore_user_request_unref(ur);
87         }
88
89         return TRUE;
90 }
91
92 /* Function will be used in case any dispatch request failed in ps plugin */
93 static void __ps_send_ur_dispatch_failure_response(UserRequest *ur, enum tcore_response_command command)
94 {
95         err("User request dispatch failed so need to send response for command [%d]", command);
96         switch (command) {
97         case TRESP_NETWORK_SEARCH: {
98                 struct tresp_network_search search_rsp;
99                 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
100
101                 search_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
102                 search_rsp.list_count = 0;
103                 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH,
104                                                  sizeof(struct tresp_network_search), &search_rsp);
105         }
106         break;
107
108         case TRESP_NETWORK_SET_PLMN_SELECTION_MODE: {
109                 struct tresp_network_set_plmn_selection_mode set_plmn_selection_mode_rsp;
110                 memset(&set_plmn_selection_mode_rsp, 0, sizeof(struct tresp_network_set_plmn_selection_mode));
111
112                 set_plmn_selection_mode_rsp.result = TCORE_RETURN_FAILURE;
113                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE,
114                                                  sizeof(struct tresp_network_set_plmn_selection_mode), &set_plmn_selection_mode_rsp);
115         }
116         break;
117
118         case TRESP_NETWORK_SET_MODE: {
119                 struct tresp_network_set_mode set_rsp;
120                 memset(&set_rsp, 0, sizeof(struct tresp_network_set_mode));
121
122                 set_rsp.result = TCORE_RETURN_FAILURE;
123                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_MODE,
124                                                  sizeof(struct tresp_network_set_mode), &set_rsp);
125         }
126         break;
127
128         case TRESP_NETWORK_GET_MODE: {
129                 struct tresp_network_get_mode get_rsp;
130                 memset(&get_rsp, 0, sizeof(struct tresp_network_get_mode));
131
132                 get_rsp.result = TCORE_RETURN_FAILURE;
133                 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_MODE,
134                                                  sizeof(struct tresp_network_get_mode), &get_rsp);
135         }
136         break;
137
138         case TRESP_MODEM_POWER_OFF: {
139                 struct tresp_modem_power_off set_power_off_rsp;
140                 memset(&set_power_off_rsp, 0, sizeof(struct tresp_modem_power_off));
141
142                 set_power_off_rsp.result = TCORE_RETURN_FAILURE;
143                 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_OFF,
144                                                  sizeof(struct tresp_modem_power_off), &set_power_off_rsp);
145         }
146         break;
147
148         case TRESP_MODEM_POWER_LOW: {
149                 struct tresp_modem_power_low set_power_low_rsp;
150                 memset(&set_power_low_rsp, 0, sizeof(struct tresp_modem_power_low));
151
152                 set_power_low_rsp.result = TCORE_RETURN_FAILURE;
153                 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_LOW,
154                                                  sizeof(struct tresp_modem_power_low), &set_power_low_rsp);
155         }
156         break;
157
158         case TRESP_MODEM_SET_FLIGHTMODE: {
159                 struct tresp_modem_set_flightmode set_flight_mode_rsp;
160                 memset(&set_flight_mode_rsp, 0, sizeof(struct tresp_modem_set_flightmode));
161
162                 set_flight_mode_rsp.result = TCORE_RETURN_FAILURE;
163                 tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE,
164                                                  sizeof(struct tresp_modem_set_flightmode), &set_flight_mode_rsp);
165         }
166         break;
167
168         default:
169                 err("Command type not expected [%d]", command);
170         }
171         /* Unref User request */
172         tcore_user_request_unref(ur);
173 }
174
175 static void __ps_hook_response_cb(UserRequest *ur, enum tcore_response_command command,
176                                   unsigned int data_len, const void *data, void *user_data)
177 {
178         ps_modem_t *modem = user_data;
179         CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
180         guint count;
181         guint id;
182         id = ((command & ~TCORE_RESPONSE) & TCORE_REQUEST);
183
184         ps_dbg_ex_modem(modem, "Entered");
185         count = ps_util_get_waiting_job_count(modem->work_queue, id);
186
187         if (count != 0) {
188                 ur = ps_util_pop_waiting_job(modem->work_queue, id);
189                 if (ur) {
190                         CoreObject *co_network = NULL;
191                         TReturn ret = TCORE_RETURN_SUCCESS;
192
193                         co_network = tcore_plugin_ref_core_object(tcore_object_ref_plugin(co_modem),
194                                                                   CORE_OBJECT_TYPE_NETWORK);
195
196                         ps_info_ex_modem(modem, "Sending Pending Request of type = id", id);
197                         tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
198                         if ((command == TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH)
199                             || (command == TRESP_NETWORK_SEARCH)
200                             || (command == TRESP_NETWORK_SET_PLMN_SELECTION_MODE)
201                             || (command == TRESP_NETWORK_SET_MODE)
202                             || (command == TRESP_NETWORK_GET_MODE))
203                                 ret = tcore_object_dispatch_request(co_network, ur);
204                         else if ((command == TRESP_MODEM_SET_FLIGHTMODE)
205                                  || (command == TRESP_MODEM_POWER_LOW)
206                                  || (command == TRESP_MODEM_POWER_OFF))
207                                 ret = tcore_object_dispatch_request(co_modem, ur);
208                         if (TCORE_RETURN_SUCCESS != ret) {
209                                 /* send responce wrt to command */
210                                 __ps_send_ur_dispatch_failure_response(ur, command);
211                         }
212                         return;
213                 }
214         }
215
216         switch (command) {
217         case TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH:
218         case TRESP_NETWORK_SEARCH:
219                 ps_dbg_ex_modem(modem, "TRESP_NETWORK_SEARCH  response received");
220                 if (count == 0)
221                         modem->hook_flag &= PS_RESET_NETWORK_SEARCH_FLAG;
222                 break;
223
224         case TRESP_NETWORK_SET_PLMN_SELECTION_MODE:
225                 ps_dbg_ex_modem(modem, "TRESP_NETWORK_SET_PLMN_SELECTION_MODE response received ");
226                 if (count == 0)
227                         modem->hook_flag &= PS_NETWORK_RESET_SELECTION_FLAG;
228                 break;
229
230         case TRESP_NETWORK_SET_MODE: {
231                 ps_dbg_ex_modem(modem, "TRESP_NETWORK_SET_MODE response received ");
232
233                 if (count == 0) {
234                         modem->hook_flag &= PS_NETWORK_RESET_SELECT_MODE_FLAG;
235                         modem->mode_pref_changed = FALSE;
236                 }
237                 ps_dbg_ex_modem(modem, "mode_pref_changed : %d", modem->mode_pref_changed);
238         }
239         break;
240
241         case TRESP_NETWORK_GET_MODE: {
242                 gboolean rv = FALSE;
243                 const struct tresp_network_get_mode *resp_get_mode = data;
244                 ps_dbg_ex_modem(modem, "TRESP_NETWORK_GET_MODE response received mode (mode:[%d])", resp_get_mode->mode);
245
246                 if (count == 0)
247                         modem->hook_flag &= PS_NETWORK_RESET_GET_MODE_FLAG;
248
249                 rv = __ps_set_network_mode(resp_get_mode->mode, modem);
250                 if (rv) {
251                         ps_dbg_ex_modem(modem, "network set mode request!");
252                         return;
253                 }
254         }
255         break;
256
257         case TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
258                 ps_dbg_ex_modem(modem, "TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION response received ");
259                 if (count == 0)
260                         modem->hook_flag &= PS_NETWORK_RESET_SET_DEFAULT_DATA_SUBS;
261                 break;
262
263         case TRESP_MODEM_SET_FLIGHTMODE: {
264                 GHashTableIter iter;
265                 gpointer key, service;
266                 ps_context_t *def_context = NULL, *ims_context = NULL;
267
268                 ps_dbg_ex_modem(modem, "TRESP_MODEM_SET_FLIGHTMODE response received ");
269                 if (count == 0)
270                         modem->hook_flag &= PS_NETWORK_RESET_SET_FLIGHT_MODE_FLAG;
271
272                 g_hash_table_iter_init(&iter, modem->services);
273                 while (g_hash_table_iter_next(&iter, &key, &service) == TRUE) {
274                         def_context = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
275                         if (def_context)
276                                 _ps_context_set_alwayson_enable(def_context, TRUE);
277
278                         ims_context = _ps_service_return_default_context(service, CONTEXT_ROLE_IMS);
279                         if (ims_context)
280                                 _ps_context_set_alwayson_enable(ims_context, TRUE);
281
282                 }
283         }
284         break;
285
286         case TRESP_MODEM_POWER_LOW:
287                 ps_dbg_ex_modem(modem, "TRESP_MODEM_POWER_LOW response received ");
288                 if (count == 0)
289                         modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_LOW_FLAG;
290                 break;
291
292         case TRESP_MODEM_POWER_OFF:
293                 ps_dbg_ex_modem(modem, "TRESP_MODEM_POWER_OFF response received ");
294                 if (count == 0)
295                         modem->hook_flag &= PS_NETWORK_RESET_SET_POWER_OFF_FLAG;
296                 break;
297
298         case TRESP_SIM_SET_POWERSTATE:
299                 ps_dbg_ex_modem(modem, "TRESP_SIM_SET_POWERSTATE response received ");
300                 if (count == 0)
301                         modem->hook_flag &= PS_SIM_SET_POWER_STATE_FLAG;
302                 break;
303
304         default: {
305                 ps_warn_ex_modem(modem, "Unexpected response ");
306         }
307         break;
308         }
309
310         ps_info_ex_modem(modem, "After unset - FLAG %x", modem->hook_flag);
311         if (modem->hook_flag == PS_NO_PENDING_REQUEST
312             && command != TRESP_MODEM_POWER_LOW
313             && command != TRESP_MODEM_POWER_OFF
314             && modem->mode_pref_changed == FALSE) {
315                 _ps_modem_connect_default_context(modem);
316         }
317 }
318
319 static void __ps_modem_get_mode_pref_change(ps_modem_t *modem, UserRequest *ur)
320 {
321         enum telephony_network_service_type svc_type;
322         enum tcore_request_command cmd;
323         CoreObject *co_network = NULL;
324         const struct treq_network_set_mode *req;
325
326         cmd = tcore_user_request_get_command(ur);
327         if (cmd != TREQ_NETWORK_SET_MODE) {
328                 ps_warn_ex_modem(modem, "Not a TREQ_NETWORK_SET_MODE");
329                 modem->mode_pref_changed = FALSE;
330                 return;
331         }
332         modem->mode_pref_changed = TRUE;
333
334         co_network = tcore_plugin_ref_core_object(tcore_object_ref_plugin(modem->co_modem),
335                                                   CORE_OBJECT_TYPE_NETWORK);
336         req = tcore_user_request_ref_data(ur, NULL);
337
338         tcore_network_get_service_type(co_network, &svc_type);
339         ps_dbg_ex_modem(modem, "mode_pref[0x%x], svc_type[%d]", req->mode, svc_type);
340         switch (svc_type) {
341         case NETWORK_SERVICE_TYPE_2G:
342         case NETWORK_SERVICE_TYPE_2_5G:
343         case NETWORK_SERVICE_TYPE_2_5G_EDGE: {
344                 if (req->mode == NETWORK_MODE_GSM)
345                         modem->mode_pref_changed = FALSE;
346         }
347         break;
348
349         case NETWORK_SERVICE_TYPE_3G:
350         case NETWORK_SERVICE_TYPE_HSDPA: {
351                 if (req->mode & NETWORK_MODE_WCDMA)
352                         modem->mode_pref_changed = FALSE;
353         }
354         break;
355
356         case NETWORK_SERVICE_TYPE_LTE: {
357                 if (req->mode & NETWORK_MODE_LTE)
358                         modem->mode_pref_changed = FALSE;
359         }
360         break;
361
362         default:
363                 break;
364         }
365
366         ps_dbg_ex_modem(modem, "mode_pref_changed : %d", modem->mode_pref_changed);
367 }
368
369 static int __ps_deactivation_timeout_handler(alarm_id_t alarm_id, void *data)
370 {
371         ps_modem_t *modem = data;
372
373         if (alarm_id > 0) {
374                 ps_dbg_ex_modem(modem, "remove connection retry timer (%d)", alarm_id);
375                 alarmmgr_remove_alarm(alarm_id);
376         }
377
378         ps_dbg_ex_modem(modem, "Deactivation timeout, proceed pending cmd");
379         /* Handle any pending request if present */
380         _ps_hook_send_pending_user_request(modem);
381         return 1;
382 }
383
384 static void __ps_set_deactivation_timeout(ps_modem_t *modem, int timeout)
385 {
386         int ret;
387         int result = 0;
388
389         /* Acquire lock */
390         ret = device_power_request_lock(POWER_LOCK_CPU, 0);
391         if (ret < 0)
392                 ps_dbg_ex_modem(modem, "ret : (0x%x)", ret);
393
394         result = alarmmgr_add_alarm_withcb(ALARM_TYPE_VOLATILE, (time_t)(timeout),
395                                            0, __ps_deactivation_timeout_handler, modem, &(modem->deact_timer_src));
396
397         /* Release lock */
398         ret = device_power_release_lock(POWER_LOCK_CPU);
399         if (ret < 0)
400                 ps_dbg_ex_modem(modem, "ret : (0x%x)", ret);
401
402         if (result != ALARMMGR_RESULT_SUCCESS) {
403                 ps_dbg_ex_modem(modem, "Failed to add alarm(%d)", result);
404                 return;
405         }
406
407         ps_dbg_ex_modem(modem, "deactivation timeout - timer src(%d), timeout(%d)", modem->deact_timer_src, timeout);
408 }
409
410 static void __ps_modem_set_hook_flag(ps_modem_t *modem, enum tcore_request_command cmd)
411 {
412         switch (cmd) {
413         case TREQ_NETWORK_SEARCH:
414                 ps_dbg_ex_modem(modem, "TREQ_NETWORK_SEARCH");
415                 modem->hook_flag |= PS_NETWORK_SEARCH_PENDING;
416                 ps_dbg_ex_modem(modem, "TREQ_NETWORK_SEARCH setting flag %x", modem->hook_flag);
417                 break;
418
419         case TREQ_NETWORK_SET_PLMN_SELECTION_MODE:
420                 modem->hook_flag |= PS_NETWORK_SELECTION_PENDING;
421                 ps_dbg_ex_modem(modem, "TREQ_NETWORK_SET_PLMN_SELECTION_MODE setting flag %x", modem->hook_flag);
422                 break;
423
424         case TREQ_NETWORK_SET_MODE:
425                 modem->hook_flag |= PS_NETWORK_SELECT_MODE;
426                 ps_dbg_ex_modem(modem, "TREQ_NETWORK_SET_MODE setting flag %x", modem->hook_flag);
427                 break;
428
429         case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
430                 modem->hook_flag |= PS_NETWORK_SET_DEFAULT_DATA_SUBS;
431                 ps_dbg_ex_modem(modem, "TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION setting flag %x", modem->hook_flag);
432                 break;
433
434         case TREQ_MODEM_SET_FLIGHTMODE:
435                 modem->hook_flag |= PS_NETWORK_SET_FLIGHT_MODE;
436                 ps_dbg_ex_modem(modem, "TREQ_MODEM_SET_FLIGHTMODE setting flag %x", modem->hook_flag);
437                 break;
438
439         case TREQ_MODEM_POWER_OFF:
440                 modem->hook_flag |= PS_NETWORK_SET_POWER_OFF;
441                 ps_dbg_ex_modem(modem, "TREQ_MODEM_POWER_OFF setting flag %x", modem->hook_flag);
442                 break;
443
444         case TREQ_MODEM_POWER_LOW:
445                 modem->hook_flag |= PS_NETWORK_SET_POWER_LOW;
446                 ps_dbg_ex_modem(modem, "TREQ_MODEM_POWER_LOW setting flag %x", modem->hook_flag);
447                 break;
448
449         case TREQ_SIM_SET_POWERSTATE:
450                 modem->hook_flag |= PS_SIM_SET_POWER_STATE;
451                 ps_dbg_ex_modem(modem, "TREQ_SIM_SET_POWERSTATE setting flag %x", modem->hook_flag);
452                 break;
453
454         default:
455                 ps_dbg_ex_modem(modem, "Not handled request");
456                 break;
457         }
458         ps_info_ex_modem(modem, "After set - FLAG %x", modem->hook_flag);
459 }
460
461 static enum tcore_hook_return __ps_handle_modem_power_on(ps_modem_t *modem, UserRequest *ur)
462 {
463         if (modem->powered == PS_MODEM_STATE_ONLINE) {
464                 struct tresp_modem_power_on set_power_on;
465                 memset(&set_power_on, 0, sizeof(struct tresp_modem_power_on));
466                 ps_dbg_ex_modem(modem, "FLAG: 0x%x", modem->hook_flag);
467
468                 if (modem->hook_flag & PS_NETWORK_SET_POWER_LOW) {
469                         ps_dbg_ex_modem(modem, "LOW power request is pending, send abort response");
470                         set_power_on.result = TCORE_RETURN_OPERATION_ABORTED;
471                         tcore_user_request_send_response(ur, TRESP_MODEM_POWER_ON,
472                                                          sizeof(struct tresp_modem_power_on), &set_power_on);
473                 } else {
474                         ps_dbg_ex_modem(modem, "No pending LOW power request, send success response.");
475                         set_power_on.result = TCORE_RETURN_EALREADY;
476                         tcore_user_request_send_response(ur, TRESP_MODEM_POWER_ON,
477                                                          sizeof(struct tresp_modem_power_on), &set_power_on);
478                 }
479                 tcore_user_request_unref(ur);
480                 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
481         }
482         return TCORE_HOOK_RETURN_CONTINUE;
483 }
484
485 static void __ps_handle_waiting_job(UserRequest *ur, enum tcore_request_command cmd)
486 {
487         if (cmd == TREQ_NETWORK_SEARCH) {
488                 struct tresp_network_search search_rsp;
489                 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
490
491                 search_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
492                 search_rsp.list_count = 0;
493                 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH,
494                                                  sizeof(struct tresp_network_search), &search_rsp);
495         } else if (cmd == TREQ_NETWORK_SET_PLMN_SELECTION_MODE) {
496                 struct tresp_network_set_plmn_selection_mode set_plmn_mode_rsp;
497                 memset(&set_plmn_mode_rsp, 0, sizeof(struct tresp_network_set_plmn_selection_mode));
498
499                 set_plmn_mode_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
500                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE,
501                                                  sizeof(struct tresp_network_set_plmn_selection_mode), &set_plmn_mode_rsp);
502         } else if (cmd == TREQ_NETWORK_SET_MODE) {
503                 struct tresp_network_set_mode setmode_rsp;
504                 memset(&setmode_rsp, 0, sizeof(struct tresp_network_set_mode));
505
506                 setmode_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
507                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_MODE,
508                                                  sizeof(struct tresp_network_set_mode), &setmode_rsp);
509         } else if (cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) {
510                 struct tresp_network_set_cancel_manual_search search_cancel_rsp;
511                 memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
512
513                 search_cancel_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
514                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
515                                                  sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
516         } else if (cmd == TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION) {
517                 struct tresp_network_set_default_data_subscription default_data_rsp;
518                 memset(&default_data_rsp, 0, sizeof(struct tresp_network_set_default_data_subscription));
519
520                 default_data_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
521                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION,
522                                                  sizeof(struct tresp_network_set_default_data_subscription), &default_data_rsp);
523         } else if (cmd == TREQ_MODEM_SET_FLIGHTMODE) {
524                 struct tresp_modem_set_flightmode set_flight_mode;
525                 memset(&set_flight_mode, 0, sizeof(struct tresp_modem_set_flightmode));
526
527                 set_flight_mode.result = TCORE_RETURN_OPERATION_ABORTED;
528                 tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE,
529                                                  sizeof(struct tresp_modem_set_flightmode), &set_flight_mode);
530         } else if (cmd == TREQ_MODEM_POWER_OFF) {
531                 struct tresp_modem_power_off set_power_off;
532                 memset(&set_power_off, 0, sizeof(struct tresp_modem_power_off));
533
534                 set_power_off.result = TCORE_RETURN_OPERATION_ABORTED;
535                 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_OFF,
536                                                  sizeof(struct tresp_modem_power_off), &set_power_off);
537         } else if (cmd == TREQ_MODEM_POWER_LOW) {
538                 struct tresp_modem_power_low set_power_low;
539                 memset(&set_power_low, 0, sizeof(struct tresp_modem_power_low));
540
541                 set_power_low.result = TCORE_RETURN_OPERATION_ABORTED;
542                 tcore_user_request_send_response(ur, TRESP_MODEM_POWER_LOW,
543                                                  sizeof(struct tresp_modem_power_low), &set_power_low);
544         } else if (cmd == TREQ_SIM_SET_POWERSTATE) {
545                 struct tresp_sim_set_powerstate set_power;
546                 memset(&set_power, 0, sizeof(struct tresp_sim_set_powerstate));
547
548                 set_power.result = TCORE_RETURN_OPERATION_ABORTED;
549                 tcore_user_request_send_response(ur, TRESP_SIM_SET_POWERSTATE,
550                                                  sizeof(struct tresp_sim_set_powerstate), &set_power);
551         }
552         tcore_user_request_unref(ur);
553 }
554
555 static  enum tcore_hook_return __ps_handle_network_search_modem_changed(ps_modem_t *modem, CoreObject *co_ps,
556                         UserRequest *ur, enum tcore_request_command cmd)
557 {
558         gboolean ret = FALSE;
559         TReturn rv = TCORE_RETURN_FAILURE;
560
561         GHashTableIter iter;
562         gpointer key, service;
563         guint job_cnt = 0;
564         int value = 0;
565
566         if (!modem || !co_ps || !ur)
567                 return TCORE_HOOK_RETURN_CONTINUE;
568
569         if (FALSE == tcore_ps_any_context_activating_activated(co_ps, &value)) {
570                 ps_dbg_ex_modem(modem, "No activating/activated context present");
571                 /* Block PS always-on while network operations. */
572                 __ps_modem_set_hook_flag(modem, cmd);
573                 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
574                 return TCORE_HOOK_RETURN_CONTINUE;
575         }
576
577         ps_info_ex_modem(modem, "Value returned [%d]", value);
578         if (CONTEXT_STATE_ACTIVATED == value) {
579                 ps_dbg_ex_modem(modem, "Internet/mms/tethering  Activated/Activating context present need to deactivate them");
580                 if (cmd == TREQ_NETWORK_SEARCH) {
581                         g_hash_table_iter_init(&iter, modem->services);
582                         while (g_hash_table_iter_next(&iter, &key, &service) == TRUE)
583                                 _ps_service_disconnect_internet_mms_tethering_contexts(service);
584                 } else {
585                         rv = tcore_ps_deactivate_contexts(co_ps);
586                         if (rv != TCORE_RETURN_SUCCESS) {
587                                 ps_dbg_ex_modem(modem, "fail to deactivation");
588                                 return TCORE_HOOK_RETURN_CONTINUE;
589                         }
590                 }
591         } else if (CONTEXT_STATE_ACTIVATING == value) {
592                 if (cmd == TREQ_MODEM_SET_FLIGHTMODE) {
593                         ps_info_ex_modem(modem, "No need to stop these request for pdp in activating state ");
594                         return TCORE_HOOK_RETURN_CONTINUE;
595                 }
596                 ps_dbg_ex_modem(modem, "For rest command will wait for activation successful ");
597         }
598         if (!modem->work_queue) {
599                 ps_err_ex_modem(modem, "no queue present unable to handle request");
600                 return TCORE_HOOK_RETURN_CONTINUE;
601         }
602
603         job_cnt = ps_util_get_waiting_job_count(modem->work_queue, cmd);
604         if (job_cnt) {
605                 ps_err_ex_modem(modem, "duplicated job for cmd(%d)", cmd);
606
607                 if (cmd == TREQ_NETWORK_SEARCH) {
608                         struct tresp_network_search search_rsp;
609                         memset(&search_rsp, 0, sizeof(struct tresp_network_search));
610
611                         search_rsp.result = TCORE_RETURN_OPERATION_ABORTED;
612                         search_rsp.list_count = 0;
613                         tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH,
614                                                          sizeof(struct tresp_network_search), &search_rsp);
615                 } else if (cmd == TREQ_MODEM_SET_FLIGHTMODE) {
616                         struct tresp_modem_set_flightmode set_flight_mode;
617                         memset(&set_flight_mode, 0, sizeof(struct tresp_modem_set_flightmode));
618
619                         set_flight_mode.result = TCORE_RETURN_OPERATION_ABORTED;
620                         tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE,
621                                                          sizeof(struct tresp_modem_set_flightmode), &set_flight_mode);
622                 }
623
624                 tcore_user_request_unref(ur);
625                 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
626         }
627         ret = ps_util_add_waiting_job(modem->work_queue, cmd, ur);
628         if (!ret) {
629                 ps_err_ex_modem(modem, "fail to add the request to queue");
630                 return TCORE_HOOK_RETURN_CONTINUE;
631         }
632
633         __ps_modem_get_mode_pref_change(modem, ur);
634         __ps_modem_set_hook_flag(modem, cmd);
635         return TCORE_HOOK_RETURN_STOP_PROPAGATION;
636
637 }
638
639 static  enum tcore_hook_return __ps_handle_cancel_manual_search_modem_changed(ps_modem_t *modem, UserRequest *ur)
640 {
641         UserRequest *ur_pending = NULL;
642         ur_pending = ps_util_pop_waiting_job(modem->work_queue, TREQ_NETWORK_SEARCH);
643
644         if (!ur_pending) {
645                 ps_dbg_ex_modem(modem, "no pendig search request");
646                 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
647                 return TCORE_HOOK_RETURN_CONTINUE;
648         } else {
649                 struct tresp_network_search search_rsp;
650                 struct tresp_network_set_cancel_manual_search search_cancel_rsp;
651
652                 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
653                 memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
654
655                 search_rsp.list_count = 0;
656                 ps_dbg_ex_modem(modem, "send search response to upper layer");
657                 tcore_user_request_send_response(ur_pending, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &search_rsp);
658                 tcore_user_request_unref(ur_pending);
659
660                 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
661                 search_cancel_rsp.result = TCORE_RETURN_SUCCESS;
662                 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
663                                                  sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
664
665                 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
666         }
667         return TCORE_HOOK_RETURN_CONTINUE;
668 }
669
670 static void __ps_handle_cancel_manual_search(ps_modem_t *modem, UserRequest *ur, UserRequest *ur_pending)
671 {
672         struct tresp_network_search search_rsp;
673         struct tresp_network_set_cancel_manual_search search_cancel_rsp;
674
675         memset(&search_rsp, 0, sizeof(struct tresp_network_search));
676         memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
677
678         search_rsp.list_count = 0;
679         ps_dbg_ex_modem(modem, "send search response to upper layer");
680         tcore_user_request_send_response(ur_pending, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &search_rsp);
681         tcore_user_request_unref(ur_pending);
682
683         tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
684         search_cancel_rsp.result = TCORE_RETURN_SUCCESS;
685         tcore_user_request_send_response(ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
686                                          sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
687 }
688
689 static enum tcore_hook_return ps_handle_hook(Server *s, UserRequest *ur, void *user_data)
690 {
691         gboolean ret = FALSE;
692         TReturn rv = TCORE_RETURN_FAILURE;
693
694         CoreObject *co_ps = NULL;
695         TcorePlugin *target_plg = NULL;
696         int value = 0;
697         guint job_cnt = 0;
698         ps_modem_t *modem = user_data;
699         CoreObject *co_modem = _ps_modem_ref_co_modem(modem);
700         GHashTableIter iter;
701         gpointer key, service;
702
703         char *modem_name = NULL;
704         enum tcore_request_command cmd = tcore_user_request_get_command(ur);
705
706         ps_dbg_ex_modem(modem, "Entered");
707
708         modem_name = tcore_user_request_get_modem_name(ur);
709         if (!modem_name)
710                 return TCORE_HOOK_RETURN_CONTINUE;
711
712         target_plg = tcore_object_ref_plugin(co_modem);
713         if (g_strcmp0(tcore_server_get_cp_name_by_plugin(target_plg), modem_name) != 0) {
714                 ps_info_ex_modem(modem, "request modem (%s) not matched current modem(%s)",
715                                  modem_name,
716                                  tcore_server_get_cp_name_by_plugin(target_plg));
717                 free(modem_name);
718
719                 if (cmd == TREQ_NETWORK_SEARCH || cmd == TREQ_MODEM_SET_FLIGHTMODE) {
720                         co_ps = tcore_plugin_ref_core_object(target_plg, CORE_OBJECT_TYPE_PS);
721                         if (!co_ps) {
722                                 ps_err_ex_modem(modem, "No ps core object present ");
723                                 return TCORE_HOOK_RETURN_CONTINUE;
724                         }
725                         return __ps_handle_network_search_modem_changed(modem, co_ps, ur, cmd);
726                 } else if (cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) {
727                         return __ps_handle_cancel_manual_search_modem_changed(modem, ur);
728                 }
729                 return TCORE_HOOK_RETURN_CONTINUE;
730         }
731
732         if (modem_name)
733                 free(modem_name);
734
735         co_ps = tcore_plugin_ref_core_object(target_plg, CORE_OBJECT_TYPE_PS);
736         if (!co_ps)
737                 return TCORE_HOOK_RETURN_CONTINUE;
738
739         if (cmd == TREQ_MODEM_POWER_ON) {
740                 return __ps_handle_modem_power_on(modem, ur);
741         }
742         if (FALSE == tcore_ps_any_context_activating_activated(co_ps, &value)) {
743                 ps_dbg_ex_modem(modem, "No activating/activated context present");
744                 /* Block PS always-on while network operations. */
745                 __ps_modem_get_mode_pref_change(modem, ur);
746                 __ps_modem_set_hook_flag(modem, cmd);
747                 tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
748                 return TCORE_HOOK_RETURN_CONTINUE;
749         }
750
751         ps_info_ex_modem(modem, "Value returned [%d]", value);
752         if (CONTEXT_STATE_ACTIVATED == value) {
753                 ps_dbg_ex_modem(modem, "Internet/mms/tethering Activated/Activating context present need to deactivate them");
754                 if (cmd == TREQ_NETWORK_SEARCH || cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) {
755                         g_hash_table_iter_init(&iter, modem->services);
756                         while (g_hash_table_iter_next(&iter, &key, &service) == TRUE)
757                                 _ps_service_disconnect_internet_mms_tethering_contexts(service);
758                 } else {
759                         rv = tcore_ps_deactivate_contexts(co_ps);
760                         if (cmd == TREQ_MODEM_SET_FLIGHTMODE || cmd == TREQ_MODEM_POWER_OFF)
761                                 __ps_set_deactivation_timeout(modem, 10);
762                         if (rv != TCORE_RETURN_SUCCESS) {
763                                 ps_dbg_ex_modem(modem, "fail to deactivation");
764                                 return TCORE_HOOK_RETURN_CONTINUE;
765                         }
766                 }
767         } else if (CONTEXT_STATE_ACTIVATING == value) {
768                 if ((cmd == TREQ_MODEM_SET_FLIGHTMODE) || (cmd == TREQ_MODEM_POWER_OFF)) {
769                         ps_info_ex_modem(modem, "No need to stop these request for pdp in activating state ");
770                         return TCORE_HOOK_RETURN_CONTINUE;
771                 }
772                 ps_dbg_ex_modem(modem, "For rest command will wait for activation successful ");
773         }
774
775         if (!modem->work_queue) {
776                 ps_err_ex_modem(modem, "no queue present unable to handle request");
777                 return TCORE_HOOK_RETURN_CONTINUE;
778         }
779
780         job_cnt = ps_util_get_waiting_job_count(modem->work_queue, cmd);
781         if (job_cnt) {
782                 ps_err_ex_modem(modem, "duplicated job for cmd(%d)", cmd);
783
784                 __ps_handle_waiting_job(ur, cmd);
785                 return TCORE_HOOK_RETURN_STOP_PROPAGATION;
786         }
787
788         ps_dbg_ex_modem(modem, "Deactivation request is sent, wait for call disconnect notification ");
789
790         if (TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH == cmd) {
791                 UserRequest *ur_pending = NULL;
792                 ur_pending = ps_util_pop_waiting_job(modem->work_queue, TREQ_NETWORK_SEARCH);
793
794                 if (!ur_pending) {
795                         ps_dbg_ex_modem(modem, "no pendig search request");
796                         tcore_user_request_set_response_hook(ur, __ps_hook_response_cb, modem);
797                         return TCORE_HOOK_RETURN_CONTINUE;
798                 } else {
799                         __ps_handle_cancel_manual_search(modem, ur, ur_pending);
800                         return TCORE_HOOK_RETURN_STOP_PROPAGATION;
801                 }
802         }
803
804         ret = ps_util_add_waiting_job(modem->work_queue, cmd, ur);
805         if (!ret) {
806                 ps_err_ex_modem(modem, "fail to add the request to queue");
807                 return TCORE_HOOK_RETURN_CONTINUE;
808         }
809
810         __ps_modem_get_mode_pref_change(modem, ur);
811         __ps_modem_set_hook_flag(modem, cmd);
812         return TCORE_HOOK_RETURN_STOP_PROPAGATION;
813 }
814
815 guchar _ps_hook_get_hook_flag(ps_modem_t *modem)
816 {
817         g_return_val_if_fail(modem != NULL, FALSE);
818         return modem->hook_flag;
819 }
820
821 GQueue *_ps_hook_ref_work_queue(ps_modem_t *modem)
822 {
823         g_return_val_if_fail(modem != NULL, NULL);
824         return modem->work_queue;
825 }
826
827 void _ps_hook_cp_reset_send_pending_request_response(ps_modem_t *modem)
828 {
829         gpointer queue_data = NULL;
830
831         ps_info_ex_modem(modem, "Entered");
832         queue_data = g_queue_pop_head(modem->work_queue);
833         while (queue_data) {
834                 struct work_queue_data *wqd = queue_data;
835                 if (wqd->ur) {
836                         enum tcore_request_command cmd = tcore_user_request_get_command(wqd->ur);
837
838                         if (cmd == TREQ_NETWORK_SEARCH) {
839                                 struct tresp_network_search search_rsp;
840                                 memset(&search_rsp, 0, sizeof(struct tresp_network_search));
841
842                                 search_rsp.result = TCORE_RETURN_FAILURE;
843                                 search_rsp.list_count = 0;
844                                 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SEARCH,
845                                                                  sizeof(struct tresp_network_search), &search_rsp);
846                         } else if (cmd == TREQ_NETWORK_SET_PLMN_SELECTION_MODE) {
847                                 struct tresp_network_set_plmn_selection_mode set_plmn_mode_rsp;
848                                 memset(&set_plmn_mode_rsp, 0, sizeof(struct tresp_network_set_plmn_selection_mode));
849
850                                 set_plmn_mode_rsp.result = TCORE_RETURN_FAILURE;
851                                 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE,
852                                                                  sizeof(struct tresp_network_set_plmn_selection_mode), &set_plmn_mode_rsp);
853                         } else if (cmd == TREQ_NETWORK_SET_MODE) {
854                                 struct tresp_network_set_mode setmode_rsp;
855                                 memset(&setmode_rsp, 0, sizeof(struct tresp_network_set_mode));
856
857                                 setmode_rsp.result = TCORE_RETURN_FAILURE;
858                                 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_MODE,
859                                                                  sizeof(struct tresp_network_set_mode), &setmode_rsp);
860                         } else if (cmd == TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH) {
861                                 struct tresp_network_set_cancel_manual_search search_cancel_rsp;
862                                 memset(&search_cancel_rsp, 0, sizeof(struct tresp_network_set_cancel_manual_search));
863
864                                 search_cancel_rsp.result = TCORE_RETURN_FAILURE;
865                                 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
866                                                                  sizeof(struct tresp_network_set_cancel_manual_search), &search_cancel_rsp);
867                         } else if (cmd == TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION) {
868                                 struct tresp_network_set_default_data_subscription default_data_rsp;
869                                 memset(&default_data_rsp, 0, sizeof(struct tresp_network_set_default_data_subscription));
870
871                                 default_data_rsp.result = TCORE_RETURN_FAILURE;
872                                 tcore_user_request_send_response(wqd->ur, TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION,
873                                                                  sizeof(struct tresp_network_set_default_data_subscription), &default_data_rsp);
874                         } else if (cmd == TREQ_MODEM_SET_FLIGHTMODE) {
875                                 struct tresp_modem_set_flightmode set_flight_mode;
876                                 memset(&set_flight_mode, 0, sizeof(struct tresp_modem_set_flightmode));
877
878                                 set_flight_mode.result = TCORE_RETURN_FAILURE;
879                                 tcore_user_request_send_response(wqd->ur, TRESP_MODEM_SET_FLIGHTMODE,
880                                                                  sizeof(struct tresp_modem_set_flightmode), &set_flight_mode);
881                         } else if (cmd == TREQ_MODEM_POWER_OFF) {
882                                 struct tresp_modem_power_off set_power_off;
883                                 memset(&set_power_off, 0, sizeof(struct tresp_modem_power_off));
884
885                                 set_power_off.result = TCORE_RETURN_FAILURE;
886                                 tcore_user_request_send_response(wqd->ur, TRESP_MODEM_POWER_OFF,
887                                                                  sizeof(struct tresp_modem_power_off), &set_power_off);
888
889                         } else if (cmd == TREQ_MODEM_POWER_LOW) {
890                                 struct tresp_modem_power_low set_power_low;
891                                 memset(&set_power_low, 0, sizeof(struct tresp_modem_power_low));
892
893                                 set_power_low.result = TCORE_RETURN_FAILURE;
894                                 tcore_user_request_send_response(wqd->ur, TRESP_MODEM_POWER_LOW,
895                                                                  sizeof(struct tresp_modem_power_low), &set_power_low);
896
897                         } else if (cmd == TREQ_SIM_SET_POWERSTATE) {
898                                 struct tresp_sim_set_powerstate set_power;
899                                 memset(&set_power, 0, sizeof(struct tresp_sim_set_powerstate));
900
901                                 set_power.result = TCORE_RETURN_FAILURE;
902                                 tcore_user_request_send_response(wqd->ur, TRESP_SIM_SET_POWERSTATE,
903                                                                  sizeof(struct tresp_sim_set_powerstate), &set_power);
904
905                         } else {
906                                 ps_err_ex_modem(modem, "Unexpected command ");
907                         }
908                         tcore_user_request_unref(wqd->ur);
909
910                         /* Memory Free */
911                         free(wqd);
912                 }
913                 queue_data = g_queue_pop_head(modem->work_queue);
914         }
915 }
916
917 void _ps_hook_send_pending_user_request(ps_modem_t *modem)
918 {
919         TcorePlugin *plugin = NULL;
920         CoreObject *co_network = NULL;
921         CoreObject *co_modem = NULL;
922         CoreObject *co_sim = NULL;
923         gpointer queue_data = NULL;
924
925         co_modem = _ps_modem_ref_co_modem(modem);
926         plugin = tcore_object_ref_plugin(co_modem);
927         co_network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
928         co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
929
930         ps_dbg_ex_modem(modem, "Extracting the user request from the work queue");
931
932         queue_data = g_queue_pop_head(modem->work_queue);
933         while (queue_data) {
934                 struct work_queue_data *wqd = queue_data;
935                 ps_info_ex_modem(modem, " sending Pending request [%x]", wqd->id);
936                 if (wqd->ur) {
937                         ps_dbg_ex_modem(modem, "Setting responce hook for request ");
938                         tcore_user_request_set_response_hook(wqd->ur, __ps_hook_response_cb, modem);
939
940                         switch (wqd->id) {
941                         case TREQ_NETWORK_SEARCH:
942                         case TREQ_NETWORK_SET_MODE:
943                         case TREQ_NETWORK_SET_PLMN_SELECTION_MODE:
944                         case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION: {
945                                 char *modem_name;
946                                 TcorePlugin *modem_plugin, *ur_modem_plugin;
947
948                                 modem_name = tcore_user_request_get_modem_name(wqd->ur);
949                                 if (!modem_name)
950                                         return;
951
952                                 modem_plugin = tcore_object_ref_plugin(co_modem);
953                                 ur_modem_plugin = tcore_server_find_plugin(tcore_plugin_ref_server(modem_plugin), modem_name);
954                                 if (modem_plugin != ur_modem_plugin) {
955                                         ps_info_ex_modem(modem, "request modem (%s) not matched current modem(%s)",
956                                                          modem_name, tcore_server_get_cp_name_by_plugin(modem_plugin));
957                                         /* Network search request enqueued for other sim, so dispatch it */
958                                         if (wqd->id == TREQ_NETWORK_SEARCH) {
959                                                 CoreObject *co_other_network;
960
961                                                 co_other_network = tcore_plugin_ref_core_object(ur_modem_plugin, CORE_OBJECT_TYPE_NETWORK);
962                                                 if (co_other_network == NULL) {
963                                                         ps_warn_ex_modem(modem, "No network core object in other modem plugin");
964                                                 } else {
965                                                         if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_other_network, wqd->ur))
966                                                                 ps_err_ex_modem(modem, "Failed to dispatch ");
967                                                 }
968                                                 free(modem_name);
969                                                 break;
970                                         } else {
971                                                 return;
972                                         }
973                                 }
974                                 free(modem_name);
975                                 if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_network, wqd->ur))
976                                         ps_err_ex_modem(modem, "Failed to dispatch ");
977                         }
978                         break;
979
980                         case TREQ_MODEM_SET_FLIGHTMODE:
981                         case TREQ_MODEM_POWER_OFF: {
982                                 char *modem_name;
983                                 TcorePlugin *modem_plugin, *ur_modem_plugin;
984
985                                 modem_name = tcore_user_request_get_modem_name(wqd->ur);
986                                 if (!modem_name)
987                                         return;
988
989                                 modem_plugin = tcore_object_ref_plugin(co_modem);
990                                 ur_modem_plugin = tcore_server_find_plugin(tcore_plugin_ref_server(modem_plugin), modem_name);
991                                 if (modem_plugin != ur_modem_plugin) {
992                                         ps_info_ex_modem(modem, "request modem (%s) not matched current modem(%s)",
993                                                          modem_name, tcore_server_get_cp_name_by_plugin(modem_plugin));
994                                         /* Flight mode request enqueued for other sim, so dispatch it */
995                                         if (wqd->id == TREQ_MODEM_SET_FLIGHTMODE) {
996                                                 CoreObject *co_other_modem;
997
998                                                 co_other_modem = tcore_plugin_ref_core_object(ur_modem_plugin, CORE_OBJECT_TYPE_MODEM);
999                                                 if (co_other_modem == NULL) {
1000                                                         ps_warn_ex_modem(modem, "No modem core object in other modem plugin");
1001                                                 } else {
1002                                                         if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_other_modem, wqd->ur))
1003                                                                 ps_err_ex_modem(modem, "Failed to dispatch ");
1004                                                 }
1005                                                 free(modem_name);
1006                                                 break;
1007                                         } else {
1008                                                 free(modem_name);
1009                                                 return;
1010                                         }
1011                                 }
1012                                 free(modem_name);
1013
1014                                 if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_modem, wqd->ur))
1015                                         ps_err_ex_modem(modem, "Failed to dispatch ");
1016                         }
1017                         break;
1018
1019                         case TREQ_MODEM_POWER_LOW:
1020                                 if (modem->hook_flag & PS_NETWORK_SET_POWER_LOW)
1021                                         if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_modem, wqd->ur))
1022                                                 err("Failed to dispatch ");
1023                                 break;
1024
1025                         case TREQ_SIM_SET_POWERSTATE:
1026                                 if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_sim, wqd->ur))
1027                                         ps_err_ex_modem(modem, "Failed to dispatch ");
1028                                 break;
1029
1030                         default:
1031                                 ps_err_ex_modem(modem, "No expected request ");
1032                         }
1033                 }
1034
1035                 /* Freeing Allocated memory*/
1036                 free(wqd);
1037                 queue_data = g_queue_pop_head(modem->work_queue);
1038         }
1039
1040         ps_dbg_ex_modem(modem, "All pending request sent ");
1041 }
1042
1043 gboolean _ps_hook_add_modem_hooks(ps_modem_t *modem)
1044 {
1045         Server *s = NULL;
1046         g_return_val_if_fail(modem != NULL, FALSE);
1047         s = tcore_plugin_ref_server(_ps_modem_ref_plugin(modem));
1048
1049         /* Adding hooks for special Network Requests */
1050         tcore_server_add_request_hook(s, TREQ_NETWORK_SEARCH, ps_handle_hook, modem);
1051         tcore_server_add_request_hook(s, TREQ_NETWORK_SET_PLMN_SELECTION_MODE, ps_handle_hook, modem);
1052         tcore_server_add_request_hook(s, TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH, ps_handle_hook, modem);
1053         tcore_server_add_request_hook(s, TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION, ps_handle_hook, modem);
1054         tcore_server_add_request_hook(s, TREQ_SIM_SET_POWERSTATE, ps_handle_hook, modem);
1055         tcore_server_add_request_hook(s, TREQ_MODEM_SET_FLIGHTMODE, ps_handle_hook, modem);
1056         tcore_server_add_request_hook(s, TREQ_MODEM_POWER_OFF, ps_handle_hook, modem);
1057         tcore_server_add_request_hook(s, TREQ_MODEM_POWER_LOW, ps_handle_hook, modem);
1058         tcore_server_add_request_hook(s, TREQ_MODEM_POWER_ON, ps_handle_hook, modem);
1059
1060         return TRUE;
1061 }
1062
1063 gboolean _ps_hook_free_modem_hooks(ps_modem_t *modem)
1064 {
1065         return TRUE;
1066 }
1067
1068 #endif /* TIZEN_SUPPORT_REQUEST_HOOK_PDP_CONTROL */