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