Fix SVACE issue
[platform/core/telephony/tel-plugin-imc.git] / src / imc_sap.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact: Ankit Jogi <ankit.jogi@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 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <tcore.h>
26 #include <hal.h>
27 #include <core_object.h>
28 #include <plugin.h>
29 #include <queue.h>
30 #include <co_sap.h>
31 #include <co_sim.h>
32 #include <user_request.h>
33 #include <server.h>
34 #include <at.h>
35
36 #include "imc_common.h"
37 #include "imc_sap.h"
38
39
40 static void on_confirmation_sap_message_send(TcorePending *p, gboolean result, void *user_data)
41 {
42         dbg("on_confirmation_sap_message_send - msg out from queue.\n");
43
44         if (result == FALSE) /* Fail */
45                 dbg("SEND FAIL");
46         else
47                 dbg("SEND OK");
48 }
49
50 static gboolean on_event_sap_status(CoreObject *o, const void *event_info, void *user_data)
51 {
52         struct tnoti_sap_status_changed noti;
53         GSList *tokens = NULL;
54         GSList *lines = NULL;
55         const char *line = NULL;
56         int status = 0;
57
58         dbg(" Function entry ");
59
60         lines = (GSList *) event_info;
61         if (1 != g_slist_length(lines)) {
62                 dbg("unsolicited msg but multiple line");
63                 return FALSE;
64         }
65         line = (char *)(lines->data);
66
67         tokens = tcore_at_tok_new(line);
68         if (g_slist_length(tokens) != 1) {
69                 msg("invalid message");
70                 tcore_at_tok_free(tokens);
71                 return FALSE;
72         }
73         status = atoi(g_slist_nth_data(tokens, 0));
74
75         switch (status) {
76         case 0:
77                 noti.status = SAP_CARD_STATUS_UNKNOWN;
78         break;
79
80         case 1:
81                 noti.status = SAP_CARD_STATUS_RESET;
82         break;
83
84         case 2:
85                 noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
86         break;
87
88         case 3:
89                 noti.status = SAP_CARD_STATUS_REMOVED;
90         break;
91
92         case 4:
93                 noti.status = SAP_CARD_STATUS_INSERTED;
94         break;
95
96         case 5:
97                 noti.status = SAP_CARD_STATUS_RECOVERED;
98         break;
99
100         default:
101                 noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
102         break;
103         }
104
105         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_STATUS,
106                         sizeof(struct tnoti_sap_status_changed), &noti);
107         return TRUE;
108 }
109
110 #if 0
111 static void on_event_sap_disconnect(CoreObject *o, const void *event_info, void *user_data)
112 {
113         /* ToDo - Indication not present */
114
115         const ipc_sap_disconnect_noti_type *ipc = event_info;
116         struct tnoti_sap_disconnect noti;
117
118         dbg("NOTI RECEIVED");
119
120         noti.type = ipc->disconnect_type;
121         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_DISCONNECT,
122                                 sizeof(struct tnoti_sap_disconnect), &noti);
123 }
124 #endif
125
126 static void on_response_connect(TcorePending *p, int data_len, const void *data, void *user_data)
127 {
128         const TcoreATResponse *resp = data;
129         UserRequest *ur = NULL;
130         struct tresp_sap_req_connect res;
131         int *max_msg_size = (int *)user_data;
132
133         dbg(" Function entry ");
134
135         memset(&res, 0x00, sizeof(struct tresp_sap_req_connect));
136         ur = tcore_pending_ref_user_request(p);
137
138         if (resp->success > 0) {
139                 dbg("RESPONSE OK");
140
141                 res.status = SAP_CONNECTION_STATUS_OK;
142                 res.max_msg_size = *max_msg_size;
143
144         } else {
145                 dbg("RESPONSE NOK");
146                 res.status = SAP_CONNECTION_STATUS_UNABLE_TO_ESTABLISH;
147                 res.max_msg_size = 0;
148         }
149
150         if (ur)
151                 tcore_user_request_send_response(ur, TRESP_SAP_REQ_CONNECT, sizeof(struct tresp_sap_req_connect), &res);
152
153         dbg(" Function exit");
154 }
155
156 static void on_response_disconnect(TcorePending *p, int data_len, const void *data, void *user_data)
157 {
158         const TcoreATResponse *resp = data;
159         UserRequest *ur = NULL;
160         struct tresp_sap_req_disconnect res;
161
162         dbg(" Function entry ");
163         memset(&res, 0x00, sizeof(struct tresp_sap_req_disconnect));
164         ur = tcore_pending_ref_user_request(p);
165
166         if (resp->success > 0) {
167                 dbg("RESPONSE OK");
168
169                 res.result = SAP_RESULT_CODE_OK;
170
171         } else {
172                 dbg("RESPONSE NOK");
173                 /* ToDo - Error mapping */
174         }
175
176         if (ur)
177                 tcore_user_request_send_response(ur, TRESP_SAP_REQ_DISCONNECT, sizeof(struct tresp_sap_req_disconnect), &res);
178
179         dbg(" Function exit");
180 }
181
182 static void on_response_req_status(TcorePending *p, int data_len, const void *data, void *user_data)
183 {
184         const TcoreATResponse *resp = data;
185         UserRequest *ur = NULL;
186         struct tresp_sap_req_status res;
187
188         dbg(" Function entry ");
189
190         ur = tcore_pending_ref_user_request(p);
191
192         if (resp->success > 0) {
193                 dbg("RESPONSE OK");
194                 /* ToDo - No AT command present */
195
196         } else {
197                 dbg("RESPONSE NOK");
198                 /* ToDo - Error mapping */
199         }
200
201         if (ur)
202                 tcore_user_request_send_response(ur, TRESP_SAP_REQ_STATUS, sizeof(struct tresp_sap_req_status), &res);
203
204         dbg(" Function exit");
205 }
206
207 static void on_response_set_transfort_protocol(TcorePending *p, int data_len, const void *data, void *user_data)
208 {
209         const TcoreATResponse *resp = data;
210         UserRequest *ur = NULL;
211         struct tresp_sap_set_protocol res;
212
213         dbg(" Function entry ");
214
215         ur = tcore_pending_ref_user_request(p);
216
217         if (resp->success > 0) {
218                 dbg("RESPONSE OK");
219                 /* ToDo - No AT command present */
220
221         } else {
222                 dbg("RESPONSE NOK");
223                 /* ToDo - Error mapping */
224         }
225
226         if (ur)
227                 tcore_user_request_send_response(ur, TRESP_SAP_SET_PROTOCOL, sizeof(struct tresp_sap_set_protocol), &res);
228
229         dbg(" Function exit");
230 }
231
232 static void on_response_set_power(TcorePending *p, int data_len, const void *data, void *user_data)
233 {
234         const TcoreATResponse *resp = data;
235         UserRequest *ur = NULL;
236         struct tresp_sap_set_power res;
237         GSList *tokens = NULL;
238         const char *line;
239         int sap_status = -1;
240
241         dbg(" Function entry ");
242
243         ur = tcore_pending_ref_user_request(p);
244
245         if (resp->success > 0) {
246                 dbg("RESPONSE OK");
247                 if (resp->lines) {
248                         line = (const char *)resp->lines->data;
249                         tokens = tcore_at_tok_new(line);
250                         if (g_slist_length(tokens) < 1) {
251                                 msg("invalid message");
252                                 tcore_at_tok_free(tokens);
253                                 return;
254                         }
255                 }
256                 sap_status = atoi(g_slist_nth_data(tokens, 0));
257
258                 switch (sap_status) {
259                 case 0:
260                         res.result = SAP_RESULT_CODE_OK;
261                         break;
262                 case 1:
263                         res.result = SAP_RESULT_CODE_NO_REASON;
264                         break;
265                 case 2:
266                         res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
267                         break;
268                 case 3:
269                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
270                         break;
271                 case 4:
272                         res.result = SAP_RESULT_CODE_CARD_REMOVED;
273                         break;
274                 case 5:
275                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
276                         break;
277                 case 6:
278                         res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
279                         break;
280                 case 7:
281                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
282                         break;
283                 default:
284                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
285                         break;
286                 }
287
288         } else {
289                 dbg("RESPONSE NOK");
290                 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
291         }
292
293         if (ur)
294                 tcore_user_request_send_response(ur, TRESP_SAP_SET_POWER, sizeof(struct tresp_sap_set_power), &res);
295
296         tcore_at_tok_free(tokens);
297         dbg(" Function exit");
298 }
299
300 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
301 {
302         const TcoreATResponse *resp = data;
303         UserRequest *ur = NULL;
304         struct tresp_sap_req_atr res;
305         GSList *tokens = NULL;
306         const char *line;
307         int sap_status = -1;
308         char *atr_data = NULL;
309
310         dbg(" Function entry ");
311
312         ur = tcore_pending_ref_user_request(p);
313
314         if (resp->success > 0) {
315                 dbg("RESPONSE OK");
316
317                 if (resp->lines) {
318                         line = (const char *)resp->lines->data;
319                         tokens = tcore_at_tok_new(line);
320                         if (g_slist_length(tokens) < 1) {
321                                 msg("invalid message");
322                                 tcore_at_tok_free(tokens);
323                                 return;
324                         }
325                 }
326                 sap_status = atoi(g_slist_nth_data(tokens, 0));
327                 atr_data = (char *) g_slist_nth_data(tokens, 1);
328
329                 res.atr_length = strlen(atr_data);
330                 if (res.atr_length > 256) {
331                         dbg(" Memory overflow handling");
332                         return;
333                 }
334                 memcpy(res.atr, atr_data, res.atr_length);
335
336                 switch (sap_status) {
337                 case 0:
338                         res.result = SAP_RESULT_CODE_OK;
339                 break;
340
341                 case 1:
342                         res.result = SAP_RESULT_CODE_NO_REASON;
343                 break;
344
345                 case 2:
346                         res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
347                 break;
348
349                 case 3:
350                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
351                 break;
352
353                 case 4:
354                         res.result = SAP_RESULT_CODE_CARD_REMOVED;
355                 break;
356
357                 case 5:
358                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
359                 break;
360
361                 case 6:
362                         res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
363                 break;
364
365                 case 7:
366                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
367                 break;
368
369                 default:
370                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
371                 break;
372                 }
373
374         } else {
375                 dbg("RESPONSE NOK");
376                 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
377         }
378
379         if (ur)
380                 tcore_user_request_send_response(ur, TRESP_SAP_REQ_ATR, sizeof(struct tresp_sap_req_atr), &res);
381
382         dbg(" Function exit");
383 }
384
385 static void on_response_transfer_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
386 {
387         const TcoreATResponse *resp = data;
388         UserRequest *ur = NULL;
389         struct tresp_sap_transfer_apdu res;
390         GSList *tokens = NULL;
391         const char *line;
392         int sap_status = -1;
393         char *apdu_data = NULL;
394
395         dbg(" Function entry ");
396
397         ur = tcore_pending_ref_user_request(p);
398
399         if (resp->success > 0) {
400                 dbg("RESPONSE OK");
401
402                 if (resp->lines) {
403                         line = (const char *)resp->lines->data;
404                         tokens = tcore_at_tok_new(line);
405                         if (g_slist_length(tokens) < 1) {
406                                 msg("invalid message");
407                                 tcore_at_tok_free(tokens);
408                                 return;
409                         }
410                 }
411                 sap_status = atoi(g_slist_nth_data(tokens, 0));
412                 apdu_data = (char *) g_slist_nth_data(tokens, 1);
413
414                 res.resp_apdu_length = strlen(apdu_data);
415                 if (res.resp_apdu_length > 256) {
416                         dbg(" Memory overflow handling");
417                         return;
418                 }
419                 memcpy(res.resp_adpdu, apdu_data, res.resp_apdu_length);
420
421                 switch (sap_status) {
422                 case 0:
423                         res.result = SAP_RESULT_CODE_OK;
424                 break;
425
426                 case 1:
427                         res.result = SAP_RESULT_CODE_NO_REASON;
428                 break;
429
430                 case 2:
431                         res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
432                 break;
433
434                 case 3:
435                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
436                 break;
437
438                 case 4:
439                         res.result = SAP_RESULT_CODE_CARD_REMOVED;
440                 break;
441
442                 case 5:
443                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
444                 break;
445
446                 case 6:
447                         res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
448                 break;
449
450                 case 7:
451                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
452                 break;
453
454                 default:
455                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
456                 break;
457                 }
458
459         } else {
460                 dbg("RESPONSE NOK");
461                 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
462         }
463
464         if (ur)
465                 tcore_user_request_send_response(ur, TRESP_SAP_TRANSFER_APDU, sizeof(struct tresp_sap_transfer_apdu), &res);
466
467         dbg(" Function exit");
468 }
469
470 static void on_response_get_cardreader_status(TcorePending *p, int data_len, const void *data, void *user_data)
471 {
472         const TcoreATResponse *resp = data;
473         UserRequest *ur = NULL;
474         struct tresp_sap_req_cardreaderstatus res;
475         GSList *tokens = NULL;
476         const char *line;
477         int sap_status = -1;
478         char *card_reader_status = NULL;
479
480         dbg(" Function entry ");
481
482         ur = tcore_pending_ref_user_request(p);
483
484         if (resp->success > 0) {
485                 dbg("RESPONSE OK");
486
487                 if (resp->lines) {
488                         line = (const char *)resp->lines->data;
489                         tokens = tcore_at_tok_new(line);
490                         if (g_slist_length(tokens) < 1) {
491                                 msg("invalid message");
492                                 tcore_at_tok_free(tokens);
493                                 return;
494                         }
495                 }
496                 sap_status = atoi(g_slist_nth_data(tokens, 0));
497                 card_reader_status = (char *)g_slist_nth_data(tokens, 1);
498
499                 res.reader_status = *card_reader_status;
500
501                 switch (sap_status) {
502                 case 0:
503                         res.result = SAP_RESULT_CODE_OK;
504                 break;
505
506                 case 1:
507                         res.result = SAP_RESULT_CODE_NO_REASON;
508                 break;
509
510                 case 2:
511                         res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
512                 break;
513
514                 case 3:
515                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
516                 break;
517
518                 case 4:
519                         res.result = SAP_RESULT_CODE_CARD_REMOVED;
520                 break;
521
522                 case 5:
523                         res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
524                 break;
525
526                 case 6:
527                         res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
528                 break;
529
530                 case 7:
531                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
532                 break;
533
534                 default:
535                         res.result = SAP_RESULT_CODE_NOT_SUPPORT;
536                 break;
537                 }
538
539         } else {
540                 dbg("RESPONSE NOK");
541                 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
542         }
543
544         if (ur)
545                 tcore_user_request_send_response(ur, TRESP_SAP_REQ_CARDREADERSTATUS, sizeof(struct tresp_sap_req_cardreaderstatus), &res);
546
547         dbg(" Function exit");
548 }
549
550 static TReturn imc_connect(CoreObject *o, UserRequest *ur)
551 {
552         TcoreHal *hal;
553         TcoreATRequest *req;
554         TcorePending *pending = NULL;
555         char *cmd_str = NULL;
556         const struct treq_sap_req_connect *req_data;
557         int *usr_data = NULL;
558
559         dbg(" Function entry");
560         if (!o || !ur)
561                 return TCORE_RETURN_EINVAL;
562
563         hal = tcore_object_get_hal(o);
564         if (FALSE == tcore_hal_get_power_state(hal)) {
565                 dbg("cp not ready/n");
566                 return TCORE_RETURN_ENOSYS;
567         }
568
569         req_data = tcore_user_request_ref_data(ur, NULL);
570         usr_data = (int *)malloc(sizeof(int));
571         if (!usr_data)
572                 return TCORE_RETURN_ENOMEM;
573
574         *usr_data = req_data->max_msg_size;
575         cmd_str = g_strdup_printf("AT+XBCON=0, 0, 0");
576
577         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
578         if (req == NULL) {
579                 g_free(cmd_str);
580                 g_free(usr_data);
581                 return TCORE_RETURN_FAILURE;
582         }
583
584         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
585
586         tcore_pending_set_request_data(pending, 0, req);
587         tcore_pending_set_response_callback(pending, on_response_connect, usr_data);
588         tcore_pending_link_user_request(pending, ur);
589         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
590
591         tcore_hal_send_request(hal, pending);
592
593         g_free(cmd_str);
594         dbg(" Function exit");
595         return TCORE_RETURN_SUCCESS;
596 }
597
598 static TReturn imc_disconnect(CoreObject *o, UserRequest *ur)
599 {
600         TcoreHal *hal;
601         TcoreATRequest *req;
602         TcorePending *pending = NULL;
603         char *cmd_str = NULL;
604
605         dbg(" Function entry");
606         if (!o || !ur)
607                 return TCORE_RETURN_EINVAL;
608         hal = tcore_object_get_hal(o);
609         if (FALSE == tcore_hal_get_power_state(hal)) {
610                 dbg("cp not ready/n");
611                 return TCORE_RETURN_ENOSYS;
612         }
613
614         cmd_str = g_strdup_printf("AT+ XBDISC");
615
616         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
617         if (req == NULL) {
618                 g_free(cmd_str);
619                 return TCORE_RETURN_FAILURE;
620         }
621
622         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
623
624         tcore_pending_set_request_data(pending, 0, req);
625         tcore_pending_set_response_callback(pending, on_response_disconnect, NULL);
626         tcore_pending_link_user_request(pending, ur);
627         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
628
629         tcore_hal_send_request(hal, pending);
630
631         g_free(cmd_str);
632         dbg(" Function exit");
633         return TCORE_RETURN_SUCCESS;
634 }
635
636 static TReturn imc_req_status(CoreObject *o, UserRequest *ur)
637 {
638         TcoreHal *hal;
639         TcoreATRequest *req;
640         TcorePending *pending = NULL;
641         char *cmd_str = NULL;
642
643         dbg(" Function entry");
644         if (!o || !ur)
645                 return TCORE_RETURN_EINVAL;
646
647         hal = tcore_object_get_hal(o);
648         if (FALSE == tcore_hal_get_power_state(hal)) {
649                 dbg("cp not ready/n");
650                 return TCORE_RETURN_ENOSYS;
651         }
652
653         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
654         if (req == NULL)
655                 return TCORE_RETURN_FAILURE;
656
657         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
658
659         tcore_pending_set_request_data(pending, 0, req);
660         tcore_pending_set_response_callback(pending, on_response_req_status, NULL);
661         tcore_pending_link_user_request(pending, ur);
662         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
663
664         tcore_hal_send_request(hal, pending);
665
666         free(cmd_str);
667         dbg(" Function exit");
668         return TCORE_RETURN_SUCCESS;
669 }
670
671 static TReturn imc_set_transport_protocol(CoreObject *o, UserRequest *ur)
672 {
673         TcoreHal *hal;
674         TcoreATRequest *req;
675         TcorePending *pending = NULL;
676         char *cmd_str = NULL;
677
678         dbg(" Function entry");
679         if (!o || !ur)
680                 return TCORE_RETURN_EINVAL;
681         hal = tcore_object_get_hal(o);
682         if (FALSE == tcore_hal_get_power_state(hal)) {
683                 dbg("cp not ready/n");
684                 return TCORE_RETURN_ENOSYS;
685         }
686
687         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
688         if (req == NULL)
689                 return TCORE_RETURN_FAILURE;
690
691         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
692
693         tcore_pending_set_request_data(pending, 0, req);
694         tcore_pending_set_response_callback(pending, on_response_set_transfort_protocol, NULL);
695         tcore_pending_link_user_request(pending, ur);
696         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
697
698         tcore_hal_send_request(hal, pending);
699
700         free(cmd_str);
701         dbg(" Function exit");
702         return TCORE_RETURN_SUCCESS;
703 }
704
705 static TReturn imc_set_power(CoreObject *o, UserRequest *ur)
706 {
707         TcoreHal *hal;
708         TcoreATRequest *req;
709         TcorePending *pending = NULL;
710         char *cmd_str = NULL;
711         const struct treq_sap_set_power *req_data;
712         int action = -1;
713
714         dbg(" Function entry");
715         if (!o || !ur)
716                 return TCORE_RETURN_EINVAL;
717         hal = tcore_object_get_hal(o);
718         if (FALSE == tcore_hal_get_power_state(hal)) {
719                 dbg("cp not ready/n");
720                 return TCORE_RETURN_ENOSYS;
721         }
722
723         req_data = tcore_user_request_ref_data(ur, NULL);
724
725         if (req_data->mode == SAP_POWER_ON)
726                 action = 0;
727         else if (req_data->mode == SAP_POWER_OFF)
728                 action = 1;
729         else if (req_data->mode == SAP_POWER_RESET)
730                 action = 2;
731         else
732                 action = -1;;
733
734         cmd_str = g_strdup_printf("AT+ XBPWR=%d", action);
735
736         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
737         if (req == NULL) {
738                 g_free(cmd_str);
739                 return TCORE_RETURN_FAILURE;
740         }
741
742         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
743
744         tcore_pending_set_request_data(pending, 0, req);
745         tcore_pending_set_response_callback(pending, on_response_set_power, NULL);
746         tcore_pending_link_user_request(pending, ur);
747         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
748
749         tcore_hal_send_request(hal, pending);
750
751         g_free(cmd_str);
752         dbg(" Function exit");
753         return TCORE_RETURN_SUCCESS;
754 }
755
756 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
757 {
758         TcoreHal *hal;
759         TcoreATRequest *req;
760         TcorePending *pending = NULL;
761         char *cmd_str = NULL;
762
763         dbg(" Function entry");
764         if (!o || !ur)
765                 return TCORE_RETURN_EINVAL;
766         hal = tcore_object_get_hal(o);
767         if (FALSE == tcore_hal_get_power_state(hal)) {
768                 dbg("cp not ready/n");
769                 return TCORE_RETURN_ENOSYS;
770         }
771
772         cmd_str = g_strdup_printf("AT+ XBATR");
773
774         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
775         if (req == NULL) {
776                 g_free(cmd_str);
777                 return TCORE_RETURN_FAILURE;
778         }
779
780         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
781
782         tcore_pending_set_request_data(pending, 0, req);
783         tcore_pending_set_response_callback(pending, on_response_get_atr, NULL);
784         tcore_pending_link_user_request(pending, ur);
785         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
786
787         tcore_hal_send_request(hal, pending);
788
789         g_free(cmd_str);
790         dbg(" Function exit");
791         return TCORE_RETURN_SUCCESS;
792 }
793
794 static TReturn imc_transfer_apdu(CoreObject *o, UserRequest *ur)
795 {
796         TcoreHal *hal;
797         TcoreATRequest *req;
798         TcorePending *pending = NULL;
799         char *cmd_str = NULL;
800         const struct treq_sap_transfer_apdu *req_data;
801
802         dbg(" Function entry");
803         if (!o || !ur)
804                 return TCORE_RETURN_EINVAL;
805         hal = tcore_object_get_hal(o);
806         if (FALSE == tcore_hal_get_power_state(hal)) {
807                 dbg("cp not ready/n");
808                 return TCORE_RETURN_ENOSYS;
809         }
810
811         req_data = tcore_user_request_ref_data(ur, NULL);
812
813         cmd_str = g_strdup_printf("AT+ XBAPDU=\"%s\"", req_data->apdu_data); /* ToDo - Need to check passing input as a string. */
814
815         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
816         if (req == NULL) {
817                 g_free(cmd_str);
818                 return TCORE_RETURN_FAILURE;
819         }
820
821         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
822
823         tcore_pending_set_request_data(pending, 0, req);
824         tcore_pending_set_response_callback(pending, on_response_transfer_apdu, NULL);
825         tcore_pending_link_user_request(pending, ur);
826         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
827
828         tcore_hal_send_request(hal, pending);
829
830         g_free(cmd_str);
831         dbg(" Function exit");
832         return TCORE_RETURN_SUCCESS;
833 }
834
835 static TReturn imc_get_cardreader_status(CoreObject *o, UserRequest *ur)
836 {
837         TcoreHal *hal;
838         TcoreATRequest *req;
839         TcorePending *pending = NULL;
840         char *cmd_str = NULL;
841
842         dbg(" Function entry");
843         if (!o || !ur)
844                 return TCORE_RETURN_EINVAL;
845         hal = tcore_object_get_hal(o);
846         if (FALSE == tcore_hal_get_power_state(hal)) {
847                 dbg("cp not ready/n");
848                 return TCORE_RETURN_ENOSYS;
849         }
850
851         cmd_str = g_strdup_printf("AT+ XBCRDSTAT");
852
853         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
854         if (req == NULL) {
855                 g_free(cmd_str);
856                 return TCORE_RETURN_FAILURE;
857         }
858
859         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
860
861         tcore_pending_set_request_data(pending, 0, req);
862         tcore_pending_set_response_callback(pending, on_response_get_cardreader_status, NULL);
863         tcore_pending_link_user_request(pending, ur);
864         tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
865
866         tcore_hal_send_request(hal, pending);
867
868         g_free(cmd_str);
869         dbg(" Function exit");
870         return TCORE_RETURN_SUCCESS;
871 }
872
873 static struct tcore_sap_operations sap_ops = {
874         .connect = imc_connect,
875         .disconnect = imc_disconnect,
876         .req_status = imc_req_status,
877         .set_transport_protocol = imc_set_transport_protocol,
878         .set_power = imc_set_power,
879         .get_atr = imc_get_atr,
880         .transfer_apdu = imc_transfer_apdu,
881         .get_cardreader_status = imc_get_cardreader_status,
882 };
883
884
885 gboolean imc_sap_init(TcorePlugin *cp, CoreObject *co_sap)
886 {
887         dbg("Entry");
888
889         /* Set operations */
890         tcore_sap_set_ops(co_sap, &sap_ops, TCORE_OPS_TYPE_CP);
891
892         tcore_object_add_callback(co_sap, "+XBCSTAT", on_event_sap_status, NULL);
893
894         dbg("Exit");
895
896         return TRUE;
897 }
898
899 void imc_sap_exit(TcorePlugin *cp, CoreObject *co_sap)
900 {
901         dbg("Exit");
902 }