fix SPN display issue
[platform/core/telephony/tel-plugin-imc.git] / src / imc_sat.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <glib.h>
24
25 #include <tcore.h>
26 #include <server.h>
27 #include <plugin.h>
28 #include <core_object.h>
29 #include <hal.h>
30 #include <queue.h>
31 #include <storage.h>
32 #include <at.h>
33
34 #include <co_sat.h>
35
36 #include "imc_sat.h"
37 #include "imc_common.h"
38
39 #define PROACTV_CMD_LEN 256
40
41 static void on_response_enable_sat(TcorePending *p,
42         guint data_len, const void *data, void *user_data)
43 {
44         const TcoreAtResponse *at_resp = data;
45
46         if (at_resp && at_resp->success) {
47                 dbg("Enable SAT (Proactive command) - [OK]");
48         }
49         else {
50                 err("Enable SAT (Proactive command) - [NOK]");
51         }
52 }
53
54 /* Hook functions */
55 static TcoreHookReturn on_hook_imc_sim_status(TcorePlugin *plugin,
56         TcoreNotification command, guint data_len, void *data, void *user_data)
57 {
58         const TelSimCardStatus *sim_status = (TelSimCardStatus *)data;
59         CoreObject *co = (CoreObject *)user_data;
60
61         tcore_check_return_value(sim_status != NULL, TCORE_HOOK_RETURN_CONTINUE);
62
63         /*
64          * If SIM is initialized -
65          *      * Enable SAT
66          */
67         dbg("SIM Status: [%d]", *sim_status);
68         if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
69                 dbg("SIM Initialized!!! Enable SAT");
70
71                 /* Enable SAT - Send AT+CFUN=6 */
72                 tcore_at_prepare_and_send_request(co,
73                         "AT+CFUN=6", NULL,
74                         TCORE_AT_COMMAND_TYPE_NO_RESULT,
75                         TCORE_PENDING_PRIORITY_DEFAULT,
76                         NULL,
77                         on_response_enable_sat, NULL,
78                         on_send_imc_request, NULL,
79                         0, NULL, NULL);
80         }
81
82         return TCORE_HOOK_RETURN_CONTINUE;
83 }
84
85 static gboolean on_response_imc_sat_terminal_response_confirm
86         (CoreObject *co, const void *event_info, void *user_data)
87 {
88         dbg("Entry");
89         return TRUE;
90 }
91
92 static gboolean on_notification_imc_sat_proactive_command
93         (CoreObject *co, const void *event_info, void *user_data)
94 {
95         TelSatDecodedProactiveData decoded_data;
96         TelSatNotiProactiveData proactive_noti;
97         gint proactive_cmd_len = 0;
98         GSList *lines = NULL;
99         GSList *tokens = NULL;
100         gchar *line = NULL;
101         gchar *hex_data = NULL;
102         gchar *tmp = NULL;
103         gchar *record_data = NULL;
104         guint record_data_len;
105         gint decode_err;
106         gboolean decode_ret = FALSE;
107
108         dbg("Entry");
109
110         tcore_check_return_value_assert(co != NULL, FALSE);
111         memset(&proactive_noti, 0x00, sizeof(TelSatNotiProactiveData));
112         memset(&decoded_data, 0x00, sizeof(TelSatDecodedProactiveData));
113
114         lines = (GSList *) event_info;
115         line = (gchar *) lines->data;
116         tokens = tcore_at_tok_new(line);
117         if (g_slist_length(tokens) != 1) {
118                 err("Invalid message");
119                 tcore_at_tok_free(tokens);
120                 return TRUE;
121         }
122
123         hex_data = (gchar *)g_slist_nth_data(tokens, 0);
124         dbg("SAT data: [%s] SAT data length: [%d]", hex_data, strlen(hex_data));
125
126         tmp = (gchar *)tcore_at_tok_extract((gchar *)hex_data);
127         tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
128         dbg("record_data: %x", record_data);
129         tcore_free(tmp);
130
131         tcore_util_hex_dump("    ", strlen(hex_data) / 2, record_data);
132         proactive_cmd_len = strlen(record_data);
133         dbg("proactive_cmd_len = %d", proactive_cmd_len);
134
135         decode_ret = tcore_sat_decode_proactive_command((guchar *) record_data,
136                 record_data_len, &decoded_data, &decode_err);
137         if (!decode_ret) {
138                 err("Proactive Command decoding failed");
139                 tcore_at_tok_free(tokens);
140                 return TRUE;
141         }
142
143         tcore_free(record_data);
144
145         proactive_noti.cmd_number = decoded_data.cmd_num;
146         proactive_noti.cmd_type = decoded_data.cmd_type;
147         proactive_noti.decode_err_code = decode_err;
148
149         switch (decoded_data.cmd_type) {
150         case TEL_SAT_PROATV_CMD_DISPLAY_TEXT:
151                 dbg("decoded command is display text!!");
152                 memcpy(&proactive_noti.proactive_ind_data.display_text,
153                         &decoded_data.data.display_text,
154                         sizeof(TelSatDisplayTextTlv));
155                 break;
156
157         case TEL_SAT_PROATV_CMD_GET_INKEY:
158                 dbg("decoded command is get inkey!!");
159                 memcpy(&proactive_noti.proactive_ind_data.get_inkey,
160                         &decoded_data.data.get_inkey,
161                         sizeof(TelSatGetInkeyTlv));
162                 break;
163
164         case TEL_SAT_PROATV_CMD_GET_INPUT:
165                 dbg("decoded command is get input!!");
166                 memcpy(&proactive_noti.proactive_ind_data.get_input,
167                         &decoded_data.data.get_input,
168                         sizeof(TelSatGetInputTlv));
169                 break;
170
171         case TEL_SAT_PROATV_CMD_MORE_TIME:
172                 dbg("decoded command is more time!!");
173                 memcpy(&proactive_noti.proactive_ind_data.more_time,
174                         &decoded_data.data.more_time,
175                         sizeof(TelSatMoreTimeTlv));
176                 break;
177
178         case TEL_SAT_PROATV_CMD_PLAY_TONE:
179                 dbg("decoded command is play tone!!");
180                 memcpy(&proactive_noti.proactive_ind_data.play_tone,
181                         &decoded_data.data.play_tone,
182                         sizeof(TelSatPlayToneTlv));
183                 break;
184
185         case TEL_SAT_PROATV_CMD_SETUP_MENU:
186                 dbg("decoded command is SETUP MENU!!");
187                 memcpy(&proactive_noti.proactive_ind_data.setup_menu,
188                         &decoded_data.data.setup_menu, sizeof(TelSatSetupMenuTlv));
189                 break;
190
191         case TEL_SAT_PROATV_CMD_SELECT_ITEM:
192                 dbg("decoded command is select item!!");
193                 memcpy(&proactive_noti.proactive_ind_data.select_item,
194                         &decoded_data.data.select_item,
195                         sizeof(TelSatSelectItemTlv));
196                 break;
197
198         case TEL_SAT_PROATV_CMD_SEND_SMS:
199                 dbg("decoded command is send sms!!");
200                 memcpy(&proactive_noti.proactive_ind_data.send_sms,
201                         &decoded_data.data.send_sms,
202                         sizeof(TelSatSendSmsTlv));
203                 break;
204
205         case TEL_SAT_PROATV_CMD_SEND_SS:
206                 dbg("decoded command is send ss!!");
207                 memcpy(&proactive_noti.proactive_ind_data.send_ss,
208                         &decoded_data.data.send_ss,
209                         sizeof(TelSatSendSsTlv));
210                 break;
211
212         case TEL_SAT_PROATV_CMD_SEND_USSD:
213                 dbg("decoded command is send ussd!!");
214                 memcpy(&proactive_noti.proactive_ind_data.send_ussd,
215                         &decoded_data.data.send_ussd,
216                         sizeof(TelSatSendUssdTlv));
217                 break;
218
219         case TEL_SAT_PROATV_CMD_SETUP_CALL:
220                 dbg("decoded command is setup call!!");
221                 memcpy(&proactive_noti.proactive_ind_data.setup_call,
222                         &decoded_data.data.setup_call,
223                         sizeof(TelSatSetupCallTlv));
224                 break;
225
226         case TEL_SAT_PROATV_CMD_REFRESH:
227                 dbg("decoded command is refresh");
228                 memcpy(&proactive_noti.proactive_ind_data.refresh,
229                         &decoded_data.data.refresh, sizeof(TelSatRefreshTlv));
230                 break;
231
232         case TEL_SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
233                 dbg("decoded command is provide local info");
234                 memcpy(&proactive_noti.proactive_ind_data.provide_local_info,
235                         &decoded_data.data.provide_local_info,
236                         sizeof(TelSatProvideLocalInfoTlv));
237                 break;
238
239         case TEL_SAT_PROATV_CMD_SETUP_EVENT_LIST:
240                 dbg("decoded command is setup event list!!");
241                 memcpy(&proactive_noti.proactive_ind_data.setup_event_list,
242                         &decoded_data.data.setup_event_list,
243                         sizeof(TelSatSetupEventListTlv));
244                 // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
245                 break;
246
247         case TEL_SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
248                 dbg("decoded command is setup idle mode text");
249                 memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text,
250                         &decoded_data.data.setup_idle_mode_text,
251                         sizeof(TelSatSetupIdleModeTextTlv));
252                 break;
253
254         case TEL_SAT_PROATV_CMD_SEND_DTMF:
255                 dbg("decoded command is send dtmf");
256                 memcpy(&proactive_noti.proactive_ind_data.send_dtmf,
257                         &decoded_data.data.send_dtmf,
258                         sizeof(TelSatSendDtmfTlv));
259                 break;
260
261         case TEL_SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
262                 dbg("decoded command is language notification");
263                 memcpy(&proactive_noti.proactive_ind_data.language_notification,
264                         &decoded_data.data.language_notification,
265                         sizeof(TelSatLanguageNotificationTlv));
266                 break;
267
268         case TEL_SAT_PROATV_CMD_LAUNCH_BROWSER:
269                 dbg("decoded command is launch browser");
270                 memcpy(&proactive_noti.proactive_ind_data.launch_browser,
271                         &decoded_data.data.launch_browser,
272                         sizeof(TelSatLaunchBrowserTlv));
273                 break;
274
275         case TEL_SAT_PROATV_CMD_OPEN_CHANNEL:
276                 dbg("decoded command is open channel!!");
277                 memcpy(&proactive_noti.proactive_ind_data.open_channel,
278                         &decoded_data.data.open_channel,
279                         sizeof(TelSatOpenChannelTlv));
280                 break;
281
282         case TEL_SAT_PROATV_CMD_CLOSE_CHANNEL:
283                 dbg("decoded command is close channel!!");
284                 memcpy(&proactive_noti.proactive_ind_data.close_channel,
285                         &decoded_data.data.close_channel,
286                         sizeof(TelSatCloseChannelTlv));
287                 break;
288
289         case TEL_SAT_PROATV_CMD_RECEIVE_DATA:
290                 dbg("decoded command is receive data!!");
291                 memcpy(&proactive_noti.proactive_ind_data.receive_data,
292                         &decoded_data.data.receive_data,
293                         sizeof(TelSatReceiveChannelTlv));
294                 break;
295
296         case TEL_SAT_PROATV_CMD_SEND_DATA:
297                 dbg("decoded command is send data!!");
298                 memcpy(&proactive_noti.proactive_ind_data.send_data,
299                         &decoded_data.data.send_data,
300                         sizeof(TelSatSendChannelTlv));
301                 break;
302
303         case TEL_SAT_PROATV_CMD_GET_CHANNEL_STATUS:
304                 dbg("decoded command is get channel status!!");
305                 memcpy(&proactive_noti.proactive_ind_data.get_channel_status,
306                         &decoded_data.data.get_channel_status,
307                         sizeof(TelSatGetChannelStatusTlv));
308                 break;
309
310         default:
311                 dbg("invalid command:[%d]", decoded_data.cmd_type);
312                 break;
313         }
314
315         if (decoded_data.cmd_type == TEL_SAT_PROATV_CMD_REFRESH) {
316                 /*Not supported*/
317                 dbg("Not suported Proactive command");
318                 tcore_at_tok_free(tokens);
319                 return TRUE;
320         }
321
322         /* Send notification */
323         tcore_object_send_notification(co,
324                 TCORE_NOTIFICATION_SAT_PROACTIVE_CMD,
325                 sizeof(TelSatNotiProactiveData), &proactive_noti);
326
327         tcore_at_tok_free(tokens);
328
329         dbg("Exit");
330         return TRUE;
331 }
332
333 /* SAT Responses */
334 static void on_response_imc_sat_send_envelop_cmd(TcorePending *p,
335         guint data_len, const void *data, void *user_data)
336 {
337         const TcoreAtResponse *at_resp = data;
338         CoreObject *co = tcore_pending_ref_core_object(p);
339         ImcRespCbData *resp_cb_data = user_data;
340         TelSatEnvelopeResp envelop_resp;
341         TelSatResult result = TEL_SAT_RESULT_FAILURE;
342         GSList *tokens = NULL;
343         const gchar *line = NULL;
344         const gchar *env_res = NULL;
345         gint sw2 = -1;
346
347         dbg("Entry");
348
349         tcore_check_return_assert(co != NULL);
350         tcore_check_return_assert(resp_cb_data != NULL);
351         tcore_check_return_assert(resp_cb_data->cb != NULL);
352
353         if (at_resp && at_resp->success) {
354                 result = TEL_SAT_RESULT_SUCCESS;
355                 dbg("RESPONSE OK");
356                 if (at_resp->lines) {
357                         line = (const gchar *) at_resp->lines->data;
358                         tokens = tcore_at_tok_new(line);
359                         if (g_slist_length(tokens) < 1) {
360                                 err("invalid message");
361                                 tcore_at_tok_free(tokens);
362                                 return;
363                         }
364                 }
365                 env_res = g_slist_nth_data(tokens, 0);
366                 envelop_resp = TEL_SAT_ENVELOPE_SUCCESS;
367                 dbg("RESPONSE tokens present");
368                 if (NULL != g_slist_nth_data(tokens, 1)) {
369                         sw2 = atoi(g_slist_nth_data(tokens, 1));
370                         dbg("status word SW2:[%d]", sw2);
371                         if (sw2 == 0) {
372                                 dbg("Response is processed completely and sending session end notification");
373                                 /* Send Session End notification */
374                                 tcore_object_send_notification(co,
375                                 TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
376                         }
377                 }
378         } else {
379                 dbg("RESPONSE NOK");
380                 envelop_resp = TEL_SAT_ENVELOPE_FAILED;
381         }
382
383         /* Invoke callback */
384         if (resp_cb_data->cb)
385                 resp_cb_data->cb(co, (gint)result, &envelop_resp, resp_cb_data->cb_data);
386
387         imc_destroy_resp_cb_data(resp_cb_data);
388         tcore_at_tok_free(tokens);
389         dbg("Exit");
390 }
391
392 static void on_response_imc_sat_send_terminal_response(TcorePending *p,
393         guint data_len, const void *data, void *user_data)
394 {
395         const TcoreAtResponse *at_resp = data;
396         CoreObject *co = tcore_pending_ref_core_object(p);
397         ImcRespCbData *resp_cb_data = user_data;
398         TelSatResult result = TEL_SAT_RESULT_FAILURE;
399
400         dbg("Entry");
401
402         tcore_check_return_assert(co != NULL);
403         tcore_check_return_assert(resp_cb_data != NULL);
404         tcore_check_return_assert(resp_cb_data->cb != NULL);
405
406         if (at_resp && at_resp->success) {
407                 result = TEL_SAT_RESULT_SUCCESS;
408                 dbg("RESPONSE OK");
409                 dbg(" at_resp->success = %d", at_resp->success);
410                 /* Send Session End notification */
411                 tcore_object_send_notification(co, TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
412         }
413
414         /* Invoke callback */
415         if (resp_cb_data->cb)
416                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
417
418         imc_destroy_resp_cb_data(resp_cb_data);
419         dbg("Exit");
420 }
421
422 static void on_response_imc_sat_send_user_confirmation(TcorePending *p,
423         guint data_len, const void *data, void *user_data)
424 {
425         const TcoreAtResponse *at_resp = data;
426         CoreObject *co = tcore_pending_ref_core_object(p);
427         ImcRespCbData *resp_cb_data = user_data;
428         TelSatResult result = TEL_SAT_RESULT_FAILURE;
429
430         dbg("Entry");
431
432         tcore_check_return_assert(co != NULL);
433         tcore_check_return_assert(resp_cb_data != NULL);
434         tcore_check_return_assert(resp_cb_data->cb != NULL);
435
436         if (at_resp && at_resp->success) {
437                 dbg("RESPONSE OK");
438                 result = TEL_SAT_RESULT_SUCCESS;
439         }
440
441         /* Invoke callback */
442         if (resp_cb_data->cb)
443                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
444
445         imc_destroy_resp_cb_data(resp_cb_data);
446         dbg("Exit");
447 }
448
449 /* SAT Requests */
450 /*
451  * Operation - Send Envelop Command
452  *
453  * Request -
454  * AT-Command: AT+SATE
455  *
456  * Response - SW
457  * Success: (Single line)
458  * <sw1>,<sw2>
459  * OK
460  * Failure:
461  * +CME ERROR: <error>
462  */
463 static TelReturn imc_sat_send_envelope(CoreObject *co,
464         const TelSatRequestEnvelopCmdData *envelop_data,
465         TcoreObjectResponseCallback cb, void *cb_data)
466 {
467         gchar *at_cmd;
468         gint envelope_cmd_len = 0;
469         gchar envelope_cmd[PROACTV_CMD_LEN];
470         gint count = 0;
471         gchar hex_string[PROACTV_CMD_LEN * 2];
472         gchar *buffer = NULL;
473         gboolean encode_ret = FALSE;
474
475         ImcRespCbData *resp_cb_data;
476         TelReturn ret;
477
478         dbg("Entry");
479         memset(&hex_string, 0x00, sizeof(hex_string));
480         buffer = hex_string;
481
482         encode_ret = tcore_sat_encode_envelop_cmd(envelop_data,
483                 (gchar *)envelope_cmd, (gint *)&envelope_cmd_len);
484         if (!encode_ret) {
485                 err("Envelope Command encoding failed");
486                 return TEL_RETURN_FAILURE;
487         }
488
489         dbg("envelope_cmd_len after encoding :[%d]", envelope_cmd_len);
490         if (envelope_cmd_len == 0) {
491                 err("Envelope command length after encoding is NULL");
492                 return TEL_RETURN_INVALID_PARAMETER;
493         }
494
495         for (count = 0; count < envelope_cmd_len; count++) {
496                 dbg("envelope_cmd: %02x", (guchar)envelope_cmd[count]);
497                 sprintf(buffer, "%02x", (guchar)envelope_cmd[count]);
498                 buffer += 2;
499         }
500         dbg("hex_string: %s", hex_string);
501
502         /* AT-Command */
503         at_cmd = g_strdup_printf("AT+SATE=\"%s\"", hex_string);
504
505         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
506                 (void *)&envelop_data->sub_cmd, sizeof(TelSatEnvelopSubCmd));
507
508         /* Send Request to modem */
509         ret = tcore_at_prepare_and_send_request(co,
510                 at_cmd, NULL,
511                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
512                 TCORE_PENDING_PRIORITY_DEFAULT,
513                 NULL,
514                 on_response_imc_sat_send_envelop_cmd, resp_cb_data,
515                 on_send_imc_request, NULL,
516                 0, NULL, NULL);
517         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Envelop Command");
518
519         /* Free resources */
520         tcore_free(at_cmd);
521         dbg("Exit");
522         return ret;
523 }
524
525 /*
526  * Operation - Send Terminal Response
527  *
528  * Request -
529  * AT-Command: AT+SATR
530  *
531  * Response - OK
532  * Success: (NO Result)
533  * OK
534  * Failure:
535  * +CME ERROR: <error>
536  */
537 static TelReturn imc_sat_send_terminal_response(CoreObject *co,
538         const TelSatRequestTerminalResponseData *terminal_rsp_data,
539         TcoreObjectResponseCallback cb, void *cb_data)
540 {
541         gchar *at_cmd;
542         gint terminal_resp_len = 0;
543         gchar terminal_resp[PROACTV_CMD_LEN];
544         gint i = 0;
545         gchar *hex_string = NULL;
546         gboolean encode_ret = FALSE;
547
548         ImcRespCbData *resp_cb_data;
549         TelReturn ret;
550
551         dbg("Entry");
552
553         encode_ret = tcore_sat_encode_terminal_response(terminal_rsp_data,
554                 (gchar *)terminal_resp, (gint *)&terminal_resp_len);
555         if (!encode_ret) {
556                 err("Envelope Command encoding failed");
557                 return TEL_RETURN_FAILURE;
558         }
559
560         dbg("terminal_resp after encoding: %s", terminal_resp);
561         dbg("terminal_resp length after encoding:[%d]", strlen(terminal_resp));
562         if (terminal_resp_len == 0) {
563                 err("Terminal Response length after encoding is NULL");
564                 return TEL_RETURN_INVALID_PARAMETER;
565         }
566         hex_string = calloc((terminal_resp_len * 2) + 1, 1);
567
568         for (i = 0; i < terminal_resp_len * 2; i += 2) {
569                 gchar value = 0;
570                 value = (terminal_resp[i / 2] & 0xf0) >> 4;
571                 if (value < 0xA)
572                         hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + '0';
573                 else
574                         hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
575
576                 value = terminal_resp[i / 2] & 0x0f;
577                 if (value < 0xA)
578                         hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + '0';
579                 else
580                         hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + 'A' - 10;
581         }
582         dbg("hex_string: %s", hex_string);
583
584         /* AT-Command */
585         at_cmd = g_strdup_printf("AT+SATR=\"%s\"", hex_string);
586
587         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
588
589         /* Send Request to modem */
590         ret = tcore_at_prepare_and_send_request(co,
591                 at_cmd, NULL,
592                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
593                 TCORE_PENDING_PRIORITY_DEFAULT,
594                 NULL,
595                 on_response_imc_sat_send_terminal_response, resp_cb_data,
596                 on_send_imc_request, NULL,
597                 0, NULL, NULL);
598         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Terminal Response");
599
600         /* Free resources */
601         tcore_free(at_cmd);
602         dbg("Exit");
603         return ret;
604 }
605
606 /*
607  * Operation - Send User Confirmation
608  *
609  * Request -
610  * AT-Command: AT+SATD
611  *
612  * Response - OK
613  * Success: (NO Result)
614  * OK
615  * Failure:
616  * +CME ERROR: <error>
617  */
618 static TelReturn imc_sat_send_user_confirmation(CoreObject *co,
619         const TelSatRequestUserConfirmationData *user_conf_data,
620         TcoreObjectResponseCallback cb, void *cb_data)
621 {
622         gchar *at_cmd;
623         guint usr_conf;
624         ImcRespCbData *resp_cb_data;
625         TelReturn ret;
626
627         dbg("Entry");
628
629         usr_conf = (guint)user_conf_data->user_conf;
630         dbg("User confirmation:[%d]", usr_conf);
631
632         /* AT-Command */
633         at_cmd = g_strdup_printf("AT+SATD=%d", usr_conf);
634
635         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
636
637         /* Send Request to modem */
638         ret = tcore_at_prepare_and_send_request(co,
639                 at_cmd, NULL,
640                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
641                 TCORE_PENDING_PRIORITY_DEFAULT,
642                 NULL,
643                 on_response_imc_sat_send_user_confirmation, resp_cb_data,
644                 on_send_imc_request, NULL,
645                 0, NULL, NULL);
646         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send User Confirmation");
647
648         /* Free resources */
649         tcore_free(at_cmd);
650         dbg("Exit");
651         return ret;
652
653 }
654
655 /* SAT Operations */
656 static TcoreSatOps imc_sat_ops = {
657         .send_envelope = imc_sat_send_envelope,
658         .send_terminal_response = imc_sat_send_terminal_response,
659         .send_user_confirmation = imc_sat_send_user_confirmation
660 };
661
662 /* SAT Init */
663 gboolean imc_sat_init(TcorePlugin *p, CoreObject *co)
664 {
665         dbg("Entry");
666
667         /* Set operations */
668         tcore_sat_set_ops(co, &imc_sat_ops);
669
670         /* Add Callbacks */
671         /*
672          * At present keeping the same notification processing for
673          * both SATI and SATN command. But in future notification processing
674          * will be seperated for both command depending on SAT re-architecure.
675          */
676         tcore_object_add_callback(co, "+SATI",
677                 on_notification_imc_sat_proactive_command, NULL);
678         tcore_object_add_callback(co, "+SATN",
679                 on_notification_imc_sat_proactive_command, NULL);
680         tcore_object_add_callback(co, "+SATF",
681                 on_response_imc_sat_terminal_response_confirm, NULL);
682
683         /* Hooks */
684         tcore_plugin_add_notification_hook(p,
685                 TCORE_NOTIFICATION_SIM_STATUS, on_hook_imc_sim_status, co);
686
687         dbg("Exit");
688         return TRUE;
689 }
690
691 /* SAT Exit */
692 void imc_sat_exit(TcorePlugin *p, CoreObject *co)
693 {
694         dbg("Exit");
695 }