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>
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) {
52 static gboolean on_event_sap_status(CoreObject *o, const void *event_info, void *user_data)
54 struct tnoti_sap_status_changed noti;
55 GSList *tokens = NULL;
57 const char *line = NULL;
60 dbg(" Function entry ");
62 lines = (GSList *) event_info;
63 if (1 != g_slist_length(lines)) {
64 dbg("unsolicited msg but multiple line");
67 line = (char *) (lines->data);
69 tokens = tcore_at_tok_new(line);
70 if (g_slist_length(tokens) != 1) {
71 msg("invalid message");
72 tcore_at_tok_free(tokens);
75 status = atoi(g_slist_nth_data(tokens, 0));
79 noti.status = SAP_CARD_STATUS_UNKNOWN;
82 noti.status = SAP_CARD_STATUS_RESET;
85 noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
88 noti.status = SAP_CARD_STATUS_REMOVED;
91 noti.status = SAP_CARD_STATUS_INSERTED;
94 noti.status = SAP_CARD_STATUS_RECOVERED;
97 noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
101 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_STATUS,
102 sizeof(struct tnoti_sap_status_changed), ¬i);
106 /*static void on_event_sap_disconnect(CoreObject *o, const void *event_info, void *user_data)
108 //ToDo - Indication not present
110 const ipc_sap_disconnect_noti_type *ipc = event_info;
111 struct tnoti_sap_disconnect noti;
113 dbg("NOTI RECEIVED");
115 noti.type = ipc->disconnect_type;
116 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_DISCONNECT,
117 sizeof(struct tnoti_sap_disconnect), ¬i);
120 static void on_response_connect(TcorePending *p, int data_len, const void *data, void *user_data)
122 const TcoreATResponse *resp = data;
123 UserRequest *ur = NULL;
124 struct tresp_sap_req_connect res;
125 int *max_msg_size = (int *)user_data;
127 dbg(" Function entry ");
129 memset(&res, 0x00, sizeof(struct tresp_sap_req_connect));
130 ur = tcore_pending_ref_user_request(p);
132 if(resp->success > 0)
136 res.status = SAP_CONNECTION_STATUS_OK;
137 res.max_msg_size = *max_msg_size;
141 res.status = SAP_CONNECTION_STATUS_UNABLE_TO_ESTABLISH;
142 res.max_msg_size = 0;
146 tcore_user_request_send_response(ur, TRESP_SAP_REQ_CONNECT, sizeof(struct tresp_sap_req_connect), &res);
148 dbg(" Function exit");
151 static void on_response_disconnect(TcorePending *p, int data_len, const void *data, void *user_data)
153 const TcoreATResponse *resp = data;
154 UserRequest *ur = NULL;
155 struct tresp_sap_req_disconnect res;
157 dbg(" Function entry ");
158 memset(&res, 0x00, sizeof(struct tresp_sap_req_disconnect));
159 ur = tcore_pending_ref_user_request(p);
161 if(resp->success > 0)
165 res.result = SAP_RESULT_CODE_OK;
169 //ToDo - Error mapping
173 tcore_user_request_send_response(ur, TRESP_SAP_REQ_DISCONNECT, sizeof(struct tresp_sap_req_disconnect), &res);
175 dbg(" Function exit");
178 static void on_response_req_status(TcorePending *p, int data_len, const void *data, void *user_data)
180 const TcoreATResponse *resp = data;
181 UserRequest *ur = NULL;
182 struct tresp_sap_req_status res;
184 dbg(" Function entry ");
186 ur = tcore_pending_ref_user_request(p);
188 if(resp->success > 0)
191 //ToDo - No AT command present
196 //ToDo - Error mapping
200 tcore_user_request_send_response(ur, TRESP_SAP_REQ_STATUS, sizeof(struct tresp_sap_req_status), &res);
202 dbg(" Function exit");
205 static void on_response_set_transfort_protocol(TcorePending *p, int data_len, const void *data, void *user_data)
207 const TcoreATResponse *resp = data;
208 UserRequest *ur = NULL;
209 struct tresp_sap_set_protocol res;
211 dbg(" Function entry ");
213 ur = tcore_pending_ref_user_request(p);
215 if(resp->success > 0)
218 //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;
241 dbg(" Function entry ");
243 ur = tcore_pending_ref_user_request(p);
245 if(resp->success > 0)
249 line = (const char*)resp->lines->data;
250 tokens = tcore_at_tok_new(line);
251 if (g_slist_length(tokens) < 1) {
252 msg("invalid message");
253 tcore_at_tok_free(tokens);
257 sap_status = atoi(g_slist_nth_data(tokens, 0));
261 res.result = SAP_RESULT_CODE_OK;
264 res.result = SAP_RESULT_CODE_NO_REASON;
267 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
270 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
273 res.result = SAP_RESULT_CODE_CARD_REMOVED;
276 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
279 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
282 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
285 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
291 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
295 tcore_user_request_send_response(ur, TRESP_SAP_SET_POWER, sizeof(struct tresp_sap_set_power), &res);
297 tcore_at_tok_free(tokens);
298 dbg(" Function exit");
301 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
303 const TcoreATResponse *resp = data;
304 UserRequest *ur = NULL;
305 struct tresp_sap_req_atr res;
309 char *atr_data = NULL;
311 dbg(" Function entry ");
313 ur = tcore_pending_ref_user_request(p);
315 if(resp->success > 0)
320 line = (const char*)resp->lines->data;
321 tokens = tcore_at_tok_new(line);
322 if (g_slist_length(tokens) < 1) {
323 msg("invalid message");
324 tcore_at_tok_free(tokens);
328 sap_status = atoi(g_slist_nth_data(tokens, 0));
329 atr_data = (char *) g_slist_nth_data(tokens, 1);
331 res.atr_length = strlen(atr_data);
332 if( res.atr_length > 256 ) {
333 dbg(" Memory overflow handling");
336 memcpy(res.atr, atr_data, res.atr_length);
340 res.result = SAP_RESULT_CODE_OK;
343 res.result = SAP_RESULT_CODE_NO_REASON;
346 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
349 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
352 res.result = SAP_RESULT_CODE_CARD_REMOVED;
355 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
358 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
361 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
364 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
370 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
374 tcore_user_request_send_response(ur, TRESP_SAP_REQ_ATR, sizeof(struct tresp_sap_req_atr), &res);
376 dbg(" Function exit");
379 static void on_response_transfer_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
381 const TcoreATResponse *resp = data;
382 UserRequest *ur = NULL;
383 struct tresp_sap_transfer_apdu res;
387 char *apdu_data = NULL;
389 dbg(" Function entry ");
391 ur = tcore_pending_ref_user_request(p);
393 if(resp->success > 0)
398 line = (const char*)resp->lines->data;
399 tokens = tcore_at_tok_new(line);
400 if (g_slist_length(tokens) < 1) {
401 msg("invalid message");
402 tcore_at_tok_free(tokens);
406 sap_status = atoi(g_slist_nth_data(tokens, 0));
407 apdu_data = (char *) g_slist_nth_data(tokens, 1);
409 res.resp_apdu_length = strlen(apdu_data);
410 if( res.resp_apdu_length > 256 ) {
411 dbg(" Memory overflow handling");
414 memcpy(res.resp_adpdu, apdu_data, res.resp_apdu_length);
418 res.result = SAP_RESULT_CODE_OK;
421 res.result = SAP_RESULT_CODE_NO_REASON;
424 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
427 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
430 res.result = SAP_RESULT_CODE_CARD_REMOVED;
433 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
436 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
439 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
442 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
448 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
452 tcore_user_request_send_response(ur, TRESP_SAP_TRANSFER_APDU, sizeof(struct tresp_sap_transfer_apdu), &res);
454 dbg(" Function exit");
457 static void on_response_get_cardreader_status(TcorePending *p, int data_len, const void *data, void *user_data)
459 const TcoreATResponse *resp = data;
460 UserRequest *ur = NULL;
461 struct tresp_sap_req_cardreaderstatus res;
465 char *card_reader_status = NULL;
467 dbg(" Function entry ");
469 ur = tcore_pending_ref_user_request(p);
471 if(resp->success > 0)
476 line = (const char*)resp->lines->data;
477 tokens = tcore_at_tok_new(line);
478 if (g_slist_length(tokens) < 1) {
479 msg("invalid message");
480 tcore_at_tok_free(tokens);
484 sap_status = atoi(g_slist_nth_data(tokens, 0));
485 card_reader_status = (char *) g_slist_nth_data(tokens, 1);
487 res.reader_status = *card_reader_status;
491 res.result = SAP_RESULT_CODE_OK;
494 res.result = SAP_RESULT_CODE_NO_REASON;
497 res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
500 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
503 res.result = SAP_RESULT_CODE_CARD_REMOVED;
506 res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
509 res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
512 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
515 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
521 res.result = SAP_RESULT_CODE_NOT_SUPPORT;
525 tcore_user_request_send_response(ur, TRESP_SAP_REQ_CARDREADERSTATUS, sizeof(struct tresp_sap_req_cardreaderstatus), &res);
527 dbg(" Function exit");
530 static TReturn s_connect(CoreObject *o, UserRequest *ur)
534 TcorePending *pending = NULL;
535 char *cmd_str = NULL;
536 const struct treq_sap_req_connect *req_data;
537 int *usr_data = NULL;
539 dbg(" Function entry");
541 return TCORE_RETURN_EINVAL;
542 hal = tcore_object_get_hal(o);
543 if(FALSE == tcore_hal_get_power_state(hal)){
544 dbg("cp not ready/n");
545 return TCORE_RETURN_ENOSYS;
547 req_data = tcore_user_request_ref_data(ur, NULL);
548 usr_data = (int*)malloc(sizeof(int));
549 *usr_data = req_data->max_msg_size;
550 cmd_str = g_strdup_printf("AT+XBCON=0,0,0");
552 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
554 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
556 tcore_pending_set_request_data(pending, 0, req);
557 tcore_pending_set_response_callback(pending, on_response_connect, usr_data);
558 tcore_pending_link_user_request(pending, ur);
559 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
561 tcore_hal_send_request(hal, pending);
564 dbg(" Function exit");
565 return TCORE_RETURN_SUCCESS;
568 static TReturn s_disconnect(CoreObject *o, UserRequest *ur)
572 TcorePending *pending = NULL;
573 char *cmd_str = NULL;
574 const struct treq_sap_req_disconnect *req_data;
576 dbg(" Function entry");
578 return TCORE_RETURN_EINVAL;
579 hal = tcore_object_get_hal(o);
580 if(FALSE == tcore_hal_get_power_state(hal)){
581 dbg("cp not ready/n");
582 return TCORE_RETURN_ENOSYS;
585 req_data = tcore_user_request_ref_data(ur, NULL);
587 cmd_str = g_strdup_printf("AT+ XBDISC");
589 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
591 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
593 tcore_pending_set_request_data(pending, 0, req);
594 tcore_pending_set_response_callback(pending, on_response_disconnect, NULL);
595 tcore_pending_link_user_request(pending, ur);
596 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
598 tcore_hal_send_request(hal, pending);
601 dbg(" Function exit");
602 return TCORE_RETURN_SUCCESS;
605 static TReturn s_req_status(CoreObject *o, UserRequest *ur)
609 TcorePending *pending = NULL;
610 char *cmd_str = NULL;
611 const struct treq_sap_req_status *req_data;
613 dbg(" Function entry");
615 return TCORE_RETURN_EINVAL;
616 hal = tcore_object_get_hal(o);
617 if(FALSE == tcore_hal_get_power_state(hal)){
618 dbg("cp not ready/n");
619 return TCORE_RETURN_ENOSYS;
622 req_data = tcore_user_request_ref_data(ur, NULL);
624 //cmd_str = g_strdup_printf("");//ToDo - No AT command present.
626 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
628 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
630 tcore_pending_set_request_data(pending, 0, req);
631 tcore_pending_set_response_callback(pending, on_response_req_status, NULL);
632 tcore_pending_link_user_request(pending, ur);
633 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
635 tcore_hal_send_request(hal, pending);
638 dbg(" Function exit");
639 return TCORE_RETURN_SUCCESS;
642 static TReturn s_set_transport_protocol(CoreObject *o, UserRequest *ur)
646 TcorePending *pending = NULL;
647 char *cmd_str = NULL;
648 const struct treq_sap_set_protocol *req_data;
650 dbg(" Function entry");
652 return TCORE_RETURN_EINVAL;
653 hal = tcore_object_get_hal(o);
654 if(FALSE == tcore_hal_get_power_state(hal)){
655 dbg("cp not ready/n");
656 return TCORE_RETURN_ENOSYS;
659 req_data = tcore_user_request_ref_data(ur, NULL);
661 //cmd_str = g_strdup_printf("");//ToDo - No AT command present.
663 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
665 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
667 tcore_pending_set_request_data(pending, 0, req);
668 tcore_pending_set_response_callback(pending, on_response_set_transfort_protocol, NULL);
669 tcore_pending_link_user_request(pending, ur);
670 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
672 tcore_hal_send_request(hal, pending);
675 dbg(" Function exit");
676 return TCORE_RETURN_SUCCESS;
679 static TReturn s_set_power(CoreObject *o, UserRequest *ur)
683 TcorePending *pending = NULL;
684 char *cmd_str = NULL;
685 const struct treq_sap_set_power *req_data;
688 dbg(" Function entry");
690 return TCORE_RETURN_EINVAL;
691 hal = tcore_object_get_hal(o);
692 if(FALSE == tcore_hal_get_power_state(hal)){
693 dbg("cp not ready/n");
694 return TCORE_RETURN_ENOSYS;
697 req_data = tcore_user_request_ref_data(ur, NULL);
699 if(req_data->mode == SAP_POWER_ON) {
701 } else if ( req_data->mode == SAP_POWER_OFF ) {
703 } else if ( req_data->mode == SAP_POWER_RESET ) {
709 cmd_str = g_strdup_printf("AT+ XBPWR=%d", action);
711 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
713 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
715 tcore_pending_set_request_data(pending, 0, req);
716 tcore_pending_set_response_callback(pending, on_response_set_power, NULL);
717 tcore_pending_link_user_request(pending, ur);
718 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
720 tcore_hal_send_request(hal, pending);
723 dbg(" Function exit");
724 return TCORE_RETURN_SUCCESS;
727 static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
731 TcorePending *pending = NULL;
732 char *cmd_str = NULL;
733 const struct treq_sap_req_atr *req_data;
735 dbg(" Function entry");
737 return TCORE_RETURN_EINVAL;
738 hal = tcore_object_get_hal(o);
739 if(FALSE == tcore_hal_get_power_state(hal)){
740 dbg("cp not ready/n");
741 return TCORE_RETURN_ENOSYS;
744 req_data = tcore_user_request_ref_data(ur, NULL);
746 cmd_str = g_strdup_printf("AT+ XBATR");
748 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
750 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
752 tcore_pending_set_request_data(pending, 0, req);
753 tcore_pending_set_response_callback(pending, on_response_get_atr, NULL);
754 tcore_pending_link_user_request(pending, ur);
755 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
757 tcore_hal_send_request(hal, pending);
760 dbg(" Function exit");
761 return TCORE_RETURN_SUCCESS;
764 static TReturn s_transfer_apdu(CoreObject *o, UserRequest *ur)
768 TcorePending *pending = NULL;
769 char *cmd_str = NULL;
770 const struct treq_sap_transfer_apdu *req_data;
772 dbg(" Function entry");
774 return TCORE_RETURN_EINVAL;
775 hal = tcore_object_get_hal(o);
776 if(FALSE == tcore_hal_get_power_state(hal)){
777 dbg("cp not ready/n");
778 return TCORE_RETURN_ENOSYS;
781 req_data = tcore_user_request_ref_data(ur, NULL);
783 cmd_str = g_strdup_printf("AT+ XBAPDU=\"%s\"", req_data->apdu_data); //ToDo - Need to check passing input as a string.
785 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
787 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
789 tcore_pending_set_request_data(pending, 0, req);
790 tcore_pending_set_response_callback(pending, on_response_transfer_apdu, NULL);
791 tcore_pending_link_user_request(pending, ur);
792 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
794 tcore_hal_send_request(hal, pending);
797 dbg(" Function exit");
798 return TCORE_RETURN_SUCCESS;
801 static TReturn s_get_cardreader_status(CoreObject *o, UserRequest *ur)
805 TcorePending *pending = NULL;
806 char *cmd_str = NULL;
807 const struct treq_sap_req_cardreaderstatus *req_data;
809 dbg(" Function entry");
811 return TCORE_RETURN_EINVAL;
812 hal = tcore_object_get_hal(o);
813 if(FALSE == tcore_hal_get_power_state(hal)){
814 dbg("cp not ready/n");
815 return TCORE_RETURN_ENOSYS;
818 req_data = tcore_user_request_ref_data(ur, NULL);
820 cmd_str = g_strdup_printf("AT+ XBCRDSTAT");
822 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
824 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
826 tcore_pending_set_request_data(pending, 0, req);
827 tcore_pending_set_response_callback(pending, on_response_get_cardreader_status, NULL);
828 tcore_pending_link_user_request(pending, ur);
829 tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
831 tcore_hal_send_request(hal, pending);
834 dbg(" Function exit");
835 return TCORE_RETURN_SUCCESS;
838 static struct tcore_sap_operations sap_ops =
840 .connect = s_connect,
841 .disconnect = s_disconnect,
842 .req_status = s_req_status,
843 .set_transport_protocol = s_set_transport_protocol,
844 .set_power = s_set_power,
845 .get_atr = s_get_atr,
846 .transfer_apdu = s_transfer_apdu,
847 .get_cardreader_status = s_get_cardreader_status,
851 gboolean s_sap_init(TcorePlugin *cp, CoreObject *co_sap)
855 tcore_sap_override_ops(co_sap, &sap_ops);
857 tcore_object_override_callback(co_sap,"+XBCSTAT", on_event_sap_status, NULL);
864 void s_sap_exit(TcorePlugin *cp, CoreObject *co_sap)