4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Ankit Jogi <ankit.jogi@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include <core_object.h>
32 #include <user_request.h>
36 #include "imc_common.h"
40 static void on_confirmation_sap_message_send(TcorePending *p, gboolean result, void *user_data)
42 dbg("on_confirmation_sap_message_send - msg out from queue.\n");
44 if (result == FALSE) /* Fail */
50 static gboolean on_event_sap_status(CoreObject *o, const void *event_info, void *user_data)
52 struct tnoti_sap_status_changed noti;
53 GSList *tokens = NULL;
55 const char *line = NULL;
58 dbg(" Function entry ");
60 lines = (GSList *) event_info;
61 if (1 != g_slist_length(lines)) {
62 dbg("unsolicited msg but multiple line");
65 line = (char *)(lines->data);
67 tokens = tcore_at_tok_new(line);
68 if (g_slist_length(tokens) != 1) {
69 msg("invalid message");
70 tcore_at_tok_free(tokens);
73 status = atoi(g_slist_nth_data(tokens, 0));
77 noti.status = SAP_CARD_STATUS_UNKNOWN;
81 noti.status = SAP_CARD_STATUS_RESET;
85 noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
89 noti.status = SAP_CARD_STATUS_REMOVED;
93 noti.status = SAP_CARD_STATUS_INSERTED;
97 noti.status = SAP_CARD_STATUS_RECOVERED;
101 noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
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), ¬i);
111 static void on_event_sap_disconnect(CoreObject *o, const void *event_info, void *user_data)
113 /* ToDo - Indication not present */
115 const ipc_sap_disconnect_noti_type *ipc = event_info;
116 struct tnoti_sap_disconnect noti;
118 dbg("NOTI RECEIVED");
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), ¬i);
126 static void on_response_connect(TcorePending *p, int data_len, const void *data, void *user_data)
128 const TcoreATResponse *resp = data;
129 UserRequest *ur = NULL;
130 struct tresp_sap_req_connect res;
131 int *max_msg_size = (int *)user_data;
133 dbg(" Function entry ");
135 memset(&res, 0x00, sizeof(struct tresp_sap_req_connect));
136 ur = tcore_pending_ref_user_request(p);
138 if (resp->success > 0) {
141 res.status = SAP_CONNECTION_STATUS_OK;
142 res.max_msg_size = *max_msg_size;
146 res.status = SAP_CONNECTION_STATUS_UNABLE_TO_ESTABLISH;
147 res.max_msg_size = 0;
151 tcore_user_request_send_response(ur, TRESP_SAP_REQ_CONNECT, sizeof(struct tresp_sap_req_connect), &res);
153 dbg(" Function exit");
156 static void on_response_disconnect(TcorePending *p, int data_len, const void *data, void *user_data)
158 const TcoreATResponse *resp = data;
159 UserRequest *ur = NULL;
160 struct tresp_sap_req_disconnect res;
162 dbg(" Function entry ");
163 memset(&res, 0x00, sizeof(struct tresp_sap_req_disconnect));
164 ur = tcore_pending_ref_user_request(p);
166 if (resp->success > 0) {
169 res.result = SAP_RESULT_CODE_OK;
173 /* ToDo - Error mapping */
177 tcore_user_request_send_response(ur, TRESP_SAP_REQ_DISCONNECT, sizeof(struct tresp_sap_req_disconnect), &res);
179 dbg(" Function exit");
182 static void on_response_req_status(TcorePending *p, int data_len, const void *data, void *user_data)
184 const TcoreATResponse *resp = data;
185 UserRequest *ur = NULL;
186 struct tresp_sap_req_status res;
188 dbg(" Function entry ");
190 ur = tcore_pending_ref_user_request(p);
192 if (resp->success > 0) {
194 /* ToDo - No AT command present */
198 /* ToDo - Error mapping */
202 tcore_user_request_send_response(ur, TRESP_SAP_REQ_STATUS, sizeof(struct tresp_sap_req_status), &res);
204 dbg(" Function exit");
207 static void on_response_set_transfort_protocol(TcorePending *p, int data_len, const void *data, void *user_data)
209 const TcoreATResponse *resp = data;
210 UserRequest *ur = NULL;
211 struct tresp_sap_set_protocol res;
213 dbg(" Function entry ");
215 ur = tcore_pending_ref_user_request(p);
217 if (resp->success > 0) {
219 /* ToDo - No AT command present */
223 /* ToDo - Error mapping */
227 tcore_user_request_send_response(ur, TRESP_SAP_SET_PROTOCOL, sizeof(struct tresp_sap_set_protocol), &res);
229 dbg(" Function exit");
232 static void on_response_set_power(TcorePending *p, int data_len, const void *data, void *user_data)
234 const TcoreATResponse *resp = data;
235 UserRequest *ur = NULL;
236 struct tresp_sap_set_power res;
237 GSList *tokens = NULL;
241 dbg(" Function entry ");
243 ur = tcore_pending_ref_user_request(p);
245 if (resp->success > 0) {
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);
256 sap_status = atoi(g_slist_nth_data(tokens, 0));
258 switch (sap_status) {
260 res.result = SAP_RESULT_CODE_OK;
263 res.result = SAP_RESULT_CODE_NO_REASON;
266 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
269 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
272 res.result = SAP_RESULT_CODE_CARD_REMOVED;
275 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
278 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
281 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
284 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
290 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
294 tcore_user_request_send_response(ur, TRESP_SAP_SET_POWER, sizeof(struct tresp_sap_set_power), &res);
296 tcore_at_tok_free(tokens);
297 dbg(" Function exit");
300 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
302 const TcoreATResponse *resp = data;
303 UserRequest *ur = NULL;
304 struct tresp_sap_req_atr res;
305 GSList *tokens = NULL;
308 char *atr_data = NULL;
310 dbg(" Function entry ");
312 ur = tcore_pending_ref_user_request(p);
314 if (resp->success > 0) {
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);
326 sap_status = atoi(g_slist_nth_data(tokens, 0));
327 atr_data = (char *) g_slist_nth_data(tokens, 1);
329 res.atr_length = strlen(atr_data);
330 if (res.atr_length > 256) {
331 dbg(" Memory overflow handling");
334 memcpy(res.atr, atr_data, res.atr_length);
336 switch (sap_status) {
338 res.result = SAP_RESULT_CODE_OK;
342 res.result = SAP_RESULT_CODE_NO_REASON;
346 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
350 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
354 res.result = SAP_RESULT_CODE_CARD_REMOVED;
358 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
362 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
366 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
370 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
376 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
380 tcore_user_request_send_response(ur, TRESP_SAP_REQ_ATR, sizeof(struct tresp_sap_req_atr), &res);
382 dbg(" Function exit");
385 static void on_response_transfer_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
387 const TcoreATResponse *resp = data;
388 UserRequest *ur = NULL;
389 struct tresp_sap_transfer_apdu res;
390 GSList *tokens = NULL;
393 char *apdu_data = NULL;
395 dbg(" Function entry ");
397 ur = tcore_pending_ref_user_request(p);
399 if (resp->success > 0) {
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);
411 sap_status = atoi(g_slist_nth_data(tokens, 0));
412 apdu_data = (char *) g_slist_nth_data(tokens, 1);
414 res.resp_apdu_length = strlen(apdu_data);
415 if (res.resp_apdu_length > 256) {
416 dbg(" Memory overflow handling");
419 memcpy(res.resp_adpdu, apdu_data, res.resp_apdu_length);
421 switch (sap_status) {
423 res.result = SAP_RESULT_CODE_OK;
427 res.result = SAP_RESULT_CODE_NO_REASON;
431 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
435 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
439 res.result = SAP_RESULT_CODE_CARD_REMOVED;
443 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
447 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
451 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
455 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
461 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
465 tcore_user_request_send_response(ur, TRESP_SAP_TRANSFER_APDU, sizeof(struct tresp_sap_transfer_apdu), &res);
467 dbg(" Function exit");
470 static void on_response_get_cardreader_status(TcorePending *p, int data_len, const void *data, void *user_data)
472 const TcoreATResponse *resp = data;
473 UserRequest *ur = NULL;
474 struct tresp_sap_req_cardreaderstatus res;
475 GSList *tokens = NULL;
478 char *card_reader_status = NULL;
480 dbg(" Function entry ");
482 ur = tcore_pending_ref_user_request(p);
484 if (resp->success > 0) {
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);
496 sap_status = atoi(g_slist_nth_data(tokens, 0));
497 card_reader_status = (char *)g_slist_nth_data(tokens, 1);
499 res.reader_status = *card_reader_status;
501 switch (sap_status) {
503 res.result = SAP_RESULT_CODE_OK;
507 res.result = SAP_RESULT_CODE_NO_REASON;
511 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
515 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
519 res.result = SAP_RESULT_CODE_CARD_REMOVED;
523 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
527 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
531 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
535 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
541 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
545 tcore_user_request_send_response(ur, TRESP_SAP_REQ_CARDREADERSTATUS, sizeof(struct tresp_sap_req_cardreaderstatus), &res);
547 dbg(" Function exit");
550 static TReturn imc_connect(CoreObject *o, UserRequest *ur)
554 TcorePending *pending = NULL;
555 char *cmd_str = NULL;
556 const struct treq_sap_req_connect *req_data;
557 int *usr_data = NULL;
559 dbg(" Function entry");
561 return TCORE_RETURN_EINVAL;
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;
569 req_data = tcore_user_request_ref_data(ur, NULL);
570 usr_data = (int *)malloc(sizeof(int));
572 return TCORE_RETURN_ENOMEM;
574 *usr_data = req_data->max_msg_size;
575 cmd_str = g_strdup_printf("AT+XBCON=0, 0, 0");
577 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
581 return TCORE_RETURN_FAILURE;
584 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
591 tcore_hal_send_request(hal, pending);
594 dbg(" Function exit");
595 return TCORE_RETURN_SUCCESS;
598 static TReturn imc_disconnect(CoreObject *o, UserRequest *ur)
602 TcorePending *pending = NULL;
603 char *cmd_str = NULL;
605 dbg(" Function entry");
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;
614 cmd_str = g_strdup_printf("AT+ XBDISC");
616 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
619 return TCORE_RETURN_FAILURE;
622 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
629 tcore_hal_send_request(hal, pending);
632 dbg(" Function exit");
633 return TCORE_RETURN_SUCCESS;
636 static TReturn imc_req_status(CoreObject *o, UserRequest *ur)
640 TcorePending *pending = NULL;
641 char *cmd_str = NULL;
643 dbg(" Function entry");
645 return TCORE_RETURN_EINVAL;
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;
653 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
655 return TCORE_RETURN_FAILURE;
657 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
664 tcore_hal_send_request(hal, pending);
667 dbg(" Function exit");
668 return TCORE_RETURN_SUCCESS;
671 static TReturn imc_set_transport_protocol(CoreObject *o, UserRequest *ur)
675 TcorePending *pending = NULL;
676 char *cmd_str = NULL;
678 dbg(" Function entry");
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;
687 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
689 return TCORE_RETURN_FAILURE;
691 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
698 tcore_hal_send_request(hal, pending);
701 dbg(" Function exit");
702 return TCORE_RETURN_SUCCESS;
705 static TReturn imc_set_power(CoreObject *o, UserRequest *ur)
709 TcorePending *pending = NULL;
710 char *cmd_str = NULL;
711 const struct treq_sap_set_power *req_data;
714 dbg(" Function entry");
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;
723 req_data = tcore_user_request_ref_data(ur, NULL);
725 if (req_data->mode == SAP_POWER_ON)
727 else if (req_data->mode == SAP_POWER_OFF)
729 else if (req_data->mode == SAP_POWER_RESET)
734 cmd_str = g_strdup_printf("AT+ XBPWR=%d", action);
736 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
739 return TCORE_RETURN_FAILURE;
742 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
749 tcore_hal_send_request(hal, pending);
752 dbg(" Function exit");
753 return TCORE_RETURN_SUCCESS;
756 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
760 TcorePending *pending = NULL;
761 char *cmd_str = NULL;
763 dbg(" Function entry");
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;
772 cmd_str = g_strdup_printf("AT+ XBATR");
774 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
777 return TCORE_RETURN_FAILURE;
780 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
787 tcore_hal_send_request(hal, pending);
790 dbg(" Function exit");
791 return TCORE_RETURN_SUCCESS;
794 static TReturn imc_transfer_apdu(CoreObject *o, UserRequest *ur)
798 TcorePending *pending = NULL;
799 char *cmd_str = NULL;
800 const struct treq_sap_transfer_apdu *req_data;
802 dbg(" Function entry");
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;
811 req_data = tcore_user_request_ref_data(ur, NULL);
813 cmd_str = g_strdup_printf("AT+ XBAPDU=\"%s\"", req_data->apdu_data); /* ToDo - Need to check passing input as a string. */
815 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
818 return TCORE_RETURN_FAILURE;
821 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
828 tcore_hal_send_request(hal, pending);
831 dbg(" Function exit");
832 return TCORE_RETURN_SUCCESS;
835 static TReturn imc_get_cardreader_status(CoreObject *o, UserRequest *ur)
839 TcorePending *pending = NULL;
840 char *cmd_str = NULL;
842 dbg(" Function entry");
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;
851 cmd_str = g_strdup_printf("AT+ XBCRDSTAT");
853 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
856 return TCORE_RETURN_FAILURE;
859 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
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);
866 tcore_hal_send_request(hal, pending);
869 dbg(" Function exit");
870 return TCORE_RETURN_SUCCESS;
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,
885 gboolean imc_sap_init(TcorePlugin *cp, CoreObject *co_sap)
890 tcore_sap_set_ops(co_sap, &sap_ops, TCORE_OPS_TYPE_CP);
892 tcore_object_add_callback(co_sap, "+XBCSTAT", on_event_sap_status, NULL);
899 void imc_sap_exit(TcorePlugin *cp, CoreObject *co_sap)