From f2a68c95c16ae7ba08fe4dc9679f8d043f0dc4b2 Mon Sep 17 00:00:00 2001 From: Jan-Christopher Pien <101@janchristopherpien.de> Date: Fri, 7 Oct 2016 16:39:02 +0200 Subject: [PATCH] Refactor connecting to SAP service and sending messages in queue Sending and receiving works correctly, however establishing an SAP connection takes too long --- ACardEmulator/ACardEmulator.iml | 2 +- ACardEmulator/app/app.iml | 19 ++- .../acardemulator/MainActivity.java | 3 + .../SmartcardProviderService.java | 16 +- .../app/src/main/res/layout/activity_main.xml | 2 +- .../src/main/res/xml/accessoryservices.xml | 6 +- ACardEmulator/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +- TCardEmulator/.cproject | 26 ++-- TCardEmulator/inc/sap_app.h | 8 + TCardEmulator/inc/tcardemulator.h | 11 +- TCardEmulator/res/accessoryservices.xml | 4 +- TCardEmulator/src/sap.c | 138 +++++++++++++----- TCardEmulator/src/tcardemulator.c | 91 +++++++----- TCardEmulator/tizen-manifest.xml | 2 +- 15 files changed, 217 insertions(+), 117 deletions(-) create mode 100644 TCardEmulator/inc/sap_app.h diff --git a/ACardEmulator/ACardEmulator.iml b/ACardEmulator/ACardEmulator.iml index 507b069..7771d4c 100644 --- a/ACardEmulator/ACardEmulator.iml +++ b/ACardEmulator/ACardEmulator.iml @@ -13,7 +13,7 @@ - + \ No newline at end of file diff --git a/ACardEmulator/app/app.iml b/ACardEmulator/app/app.iml index abc25a2..70b0fb8 100644 --- a/ACardEmulator/app/app.iml +++ b/ACardEmulator/app/app.iml @@ -32,12 +32,14 @@ + + @@ -88,7 +90,6 @@ - @@ -103,6 +104,7 @@ + @@ -118,18 +120,19 @@ - - + + - - + - - - + + + + + \ No newline at end of file diff --git a/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/MainActivity.java b/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/MainActivity.java index 28f9789..d88f470 100644 --- a/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/MainActivity.java +++ b/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/MainActivity.java @@ -120,6 +120,9 @@ public class MainActivity extends AppCompatActivity { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(EmulatorSingleton.TAG); bManager.registerReceiver(bReceiver, intentFilter); + + Intent serviceIntent = new Intent(this.getApplicationContext(), SmartcardProviderService.class); + startService(serviceIntent); } @Override diff --git a/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/SmartcardProviderService.java b/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/SmartcardProviderService.java index 2f8d948..17ea8f6 100644 --- a/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/SmartcardProviderService.java +++ b/ACardEmulator/app/src/main/java/com/vsmartcard/acardemulator/SmartcardProviderService.java @@ -60,7 +60,7 @@ public class SmartcardProviderService extends SAAgent { EmulatorSingleton.createEmulator(this); } catch (SsdkUnsupportedException e) { // try to handle SsdkUnsupportedException - if (processUnsupportedException(e) == true) { + if (processUnsupportedException(e)) { EmulatorSingleton.createEmulator(this); return; } @@ -73,6 +73,7 @@ public class SmartcardProviderService extends SAAgent { */ stopSelf(); } + findPeerAgents(); } @Override @@ -82,13 +83,23 @@ public class SmartcardProviderService extends SAAgent { @Override protected void onFindPeerAgentsResponse(SAPeerAgent[] peerAgents, int result) { + switch (result) { + case PEER_AGENT_FOUND: + break; + case FINDPEER_SERVICE_NOT_FOUND: + break; + case FINDPEER_DEVICE_NOT_CONNECTED: + break; + default: + break; + } Log.d(TAG, "onFindPeerAgentResponse : result =" + result); } @Override protected void onServiceConnectionRequested(SAPeerAgent peerAgent) { if (peerAgent != null) { - Toast.makeText(getBaseContext(), "connection accepted", Toast.LENGTH_SHORT).show(); + //TODO: Check for keys and everything acceptServiceConnectionRequest(peerAgent); } } @@ -98,6 +109,7 @@ public class SmartcardProviderService extends SAAgent { if (result == SAAgent.CONNECTION_SUCCESS) { if (socket != null) { mConnectionHandler = (ServiceConnection) socket; + Toast.makeText(getBaseContext(), "connection established", Toast.LENGTH_SHORT).show(); } } else if (result == SAAgent.CONNECTION_ALREADY_EXIST) { Log.e(TAG, "onServiceConnectionResponse, CONNECTION_ALREADY_EXIST"); diff --git a/ACardEmulator/app/src/main/res/layout/activity_main.xml b/ACardEmulator/app/src/main/res/layout/activity_main.xml index 8b0042d..cc41a10 100644 --- a/ACardEmulator/app/src/main/res/layout/activity_main.xml +++ b/ACardEmulator/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" - tools:context="com.vsmartcard.smartcardemulator.MainActivity"> + tools:context="com.vsmartcard.acardemulator.MainActivity"> - + + @@ -12,17 +13,16 @@ - - + - + - + - + - + @@ -223,6 +222,7 @@ + @@ -230,17 +230,16 @@ - - + - + - + - + - + diff --git a/TCardEmulator/inc/sap_app.h b/TCardEmulator/inc/sap_app.h new file mode 100644 index 0000000..2475765 --- /dev/null +++ b/TCardEmulator/inc/sap_app.h @@ -0,0 +1,8 @@ +#ifndef __sap_H__ +#define __sap_H__ + +#include + +void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_len); + +#endif /* __tcardemulator_H__ */ diff --git a/TCardEmulator/inc/tcardemulator.h b/TCardEmulator/inc/tcardemulator.h index 7784530..521baf9 100644 --- a/TCardEmulator/inc/tcardemulator.h +++ b/TCardEmulator/inc/tcardemulator.h @@ -9,18 +9,19 @@ #include #include +#include -extern unsigned char *rapdu; -extern size_t rapdu_length; -extern gboolean rapdu_received; +//extern unsigned char *rapdu; +//extern size_t rapdu_length; +//extern gboolean rapdu_received; -#define HELLO_ACC_ASPID "/sample/hello" +#define HELLO_ACC_ASPID "/com/vsmcartcard" #define HELLO_ACC_CHANNELID 104 void initialize_sap(); gboolean find_peers(); gboolean request_service_connection(void); gboolean terminate_service_connection(void); -gboolean send_data(void *message, unsigned int message_len); +gboolean send_data(nfc_se_h nfc_handle, void *message, unsigned int message_len); #endif /* __tcardemulator_H__ */ diff --git a/TCardEmulator/res/accessoryservices.xml b/TCardEmulator/res/accessoryservices.xml index e73a26d..57095a1 100644 --- a/TCardEmulator/res/accessoryservices.xml +++ b/TCardEmulator/res/accessoryservices.xml @@ -1,7 +1,7 @@ - - + diff --git a/TCardEmulator/src/sap.c b/TCardEmulator/src/sap.c index f7ef2fb..1a06c94 100644 --- a/TCardEmulator/src/sap.c +++ b/TCardEmulator/src/sap.c @@ -1,20 +1,32 @@ #include "tcardemulator.h" -#include +#include "sap_app.h" #include +#include #include +#include +#include -#define HELLO_ACCESSORY_PROFILE_ID "/sample/hello" +#define HELLO_ACCESSORY_PROFILE_ID "/com/vsmcartcard" #define HELLO_ACCESSORY_CHANNELID 104 -struct priv { +typedef struct priv { sap_agent_h agent; sap_socket_h socket; sap_peer_agent_h peer_agent; -}; + nfc_se_h nfc_handle; +} priv_s; + +typedef struct message_queue { + void *message; + unsigned int message_len; + struct message_queue *next; +} message_queue_s; static gboolean agent_created = FALSE; +static gboolean agent_connected = FALSE; -static struct priv priv_data = { 0 }; +static priv_s priv_data = { 0 }; +static message_queue_s *m_queue = NULL; void on_peer_agent_updated(sap_peer_agent_h peer_agent, sap_peer_agent_status_e peer_status, @@ -54,7 +66,7 @@ void on_peer_agent_updated(sap_peer_agent_h peer_agent, static void on_service_connection_terminated(sap_peer_agent_h peer_agent, sap_socket_h socket, - sap_service_connection_result_e result, + sap_service_connection_terminated_reason_e result, void *user_data) { switch (result) { @@ -75,6 +87,7 @@ static void on_service_connection_terminated(sap_peer_agent_h peer_agent, sap_socket_destroy(priv_data.socket); priv_data.socket = NULL; + agent_connected = FALSE; } @@ -85,28 +98,77 @@ static void on_data_recieved(sap_socket_h socket, void *user_data) { dlog_print(DLOG_INFO, LOG_TAG, "received data: %p, len:%d", buffer, payload_length); - unsigned char *p = realloc(rapdu, payload_length); - if (p) { - rapdu = p; - rapdu_length = payload_length; - } else { - dlog_print(DLOG_ERROR, LOG_TAG, "not enough for storing data"); - if (rapdu && rapdu_length >= 2) { - dlog_print(DLOG_ERROR, LOG_TAG, - "not enough memory, returning 0x6D00 as R-APDU"); - rapdu[0] = 0x6D; - rapdu[1] = 0x00; - rapdu_length = 2; - } else { - dlog_print(DLOG_ERROR, LOG_TAG, - "not enough memory, setting R-APDU to nothing"); - rapdu_length = 0; - } - } + //unsigned char *p = realloc(rapdu, payload_length); +// if (p) { +// rapdu = p; +// rapdu_length = payload_length; +// } else { +// dlog_print(DLOG_ERROR, LOG_TAG, "not enough for storing data"); +// if (rapdu && rapdu_length >= 2) { +// dlog_print(DLOG_ERROR, LOG_TAG, +// "not enough memory, returning 0x6D00 as R-APDU"); +// rapdu[0] = 0x6D; +// rapdu[1] = 0x00; +// rapdu_length = 2; +// } else { +// dlog_print(DLOG_ERROR, LOG_TAG, +// "not enough memory, setting R-APDU to nothing"); +// rapdu_length = 0; +// } +// } - rapdu_received = TRUE; +// rapdu_received = TRUE; + + send_apdu_response(priv_data.nfc_handle, buffer, payload_length); } +message_queue_s *read_message() { + if (m_queue != NULL) { + message_queue_s *message = m_queue; + m_queue = message->next; + return message; + } + return NULL; +} + + +gboolean add_message(void *message, unsigned int message_len) { + message_queue_s *message_pointer = m_queue; + message_queue_s *prev = message_pointer; + while (message_pointer != NULL) { + prev = message_pointer; + message_pointer = message_pointer->next; + } + message_pointer = malloc(sizeof (message_queue_s)); + if (message_pointer != NULL) { + if (m_queue == NULL) { + m_queue = message_pointer; + } else { + prev->next = message_pointer; + } + message_pointer->message = message; + message_pointer->message_len = message_len; + message_pointer->next = NULL; + return TRUE; + } + return FALSE; +} + +gboolean send_data(nfc_se_h nfc_handle, void *message, unsigned int message_len) { + gboolean result; + if (agent_connected) { + priv_data.nfc_handle = nfc_handle; + result = sap_socket_send_data(priv_data.socket, + HELLO_ACCESSORY_CHANNELID, message_len, message); + + if (result != SAP_RESULT_SUCCESS) { + + } + } else { + result = add_message(message, message_len); + } + return result; +} static void on_service_connection_created(sap_peer_agent_h peer_agent, sap_socket_h socket, @@ -122,6 +184,13 @@ static void on_service_connection_created(sap_peer_agent_h peer_agent, sap_socket_set_data_received_cb(socket, on_data_recieved, peer_agent); priv_data.socket = socket; + agent_connected = TRUE; + // read messages in queue and send them + message_queue_s *message_queue = read_message(); + while (message_queue != NULL) { + send_data(priv_data.nfc_handle, message_queue->message, message_queue->message_len); + message_queue = read_message(); + } break; case SAP_CONNECTION_ALREADY_EXIST: @@ -197,9 +266,12 @@ static gboolean _terminate_service_connection(gpointer user_data) } if (result == SAP_RESULT_SUCCESS) { - dlog_print(DLOG_DEBUG, LOG_TAG, "req service conn call succeeded"); + dlog_print(DLOG_DEBUG, LOG_TAG, "terminate service conn call succeeded"); + + priv->socket = NULL; + agent_connected = FALSE; } else { - dlog_print(DLOG_ERROR, LOG_TAG, "req service conn call is failed (%d)", result); + dlog_print(DLOG_ERROR, LOG_TAG, "terminate service conn call is failed (%d)", result); } return FALSE; @@ -237,18 +309,6 @@ gboolean find_peers() return TRUE; } -gboolean send_data(void *message, unsigned int message_len) -{ - int result; - if (priv_data.socket) { - result = sap_socket_send_data(priv_data.socket, - HELLO_ACCESSORY_CHANNELID, message_len, message); - } else { - return FALSE; - } - return TRUE; -} - static void on_agent_initialized(sap_agent_h agent, sap_agent_initialized_result_e result, void *user_data) diff --git a/TCardEmulator/src/tcardemulator.c b/TCardEmulator/src/tcardemulator.c index cf7dc47..80ba95d 100644 --- a/TCardEmulator/src/tcardemulator.c +++ b/TCardEmulator/src/tcardemulator.c @@ -5,9 +5,13 @@ #include #include -unsigned char *rapdu = NULL; -size_t rapdu_length = 0; -gboolean rapdu_received = FALSE; +typedef struct appdata { + +} appdata_s; + +//unsigned char *rapdu = NULL; +//size_t rapdu_length = 0; +//gboolean rapdu_received = FALSE; static void hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event, @@ -17,26 +21,29 @@ hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event, case NFC_HCE_EVENT_DEACTIVATED: // Do something when NFC_HCE_EVENT_DEACTIVATED event arrives // When the event arrives, apdu and apdu len is NULL and 0 + dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_DEACTIVATED event on NFC handle %d", handle); terminate_service_connection(); break; case NFC_HCE_EVENT_ACTIVATED: // Do something when NFC_HCE_EVENT_ACTIVATED event arrives // When the event arrives, apdu and apdu len is NULL and 0 + dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_ACTIVATED event on NFC handle %d", handle); find_peers(); break; case NFC_HCE_EVENT_APDU_RECEIVED: - rapdu_received = FALSE; - send_data(apdu, apdu_len); - size_t count = 0; - while (!rapdu_received && count < 10) { - dlog_print(DLOG_INFO, LOG_TAG, "waiting for response"); - usleep(100); - count++; - } - nfc_hce_send_apdu_response(handle, rapdu, rapdu_length); - rapdu_received = FALSE; +// rapdu_received = FALSE; + dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_APDU_RECEIVED event on NFC handle %d", handle); + send_data(handle, apdu, apdu_len); +// size_t count_apdu = 0; +// while (!rapdu_received && count_apdu < 10) { +// dlog_print(DLOG_INFO, LOG_TAG, "waiting for response"); +// usleep(100); +// count_apdu++; +// } +// nfc_hce_send_apdu_response(handle, rapdu, rapdu_length); +// rapdu_received = FALSE; break; default: @@ -45,6 +52,11 @@ hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event, } } +void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_len) { + dlog_print(DLOG_DEBUG, LOG_TAG, "sending data to nfc handle: %d", handle); + nfc_hce_send_apdu_response(handle, resp, resp_len); +} + bool service_app_create(void *data) { @@ -76,6 +88,8 @@ service_app_create(void *data) if (ret != NFC_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "nfc_manager_set_hce_event_cb failed : %d", ret); goto err; + } else { + dlog_print(DLOG_DEBUG, LOG_TAG, "nfc_manager_set_hce_event_cb succeeded"); } initialize_sap(); @@ -101,10 +115,10 @@ service_app_terminate(void *data) terminate_service_connection(); - free(rapdu); - rapdu = NULL; - rapdu_length = 0; - rapdu_received = FALSE; +// free(rapdu); +// rapdu = NULL; +// rapdu_length = 0; +// rapdu_received = FALSE; return; } @@ -118,19 +132,19 @@ service_app_control(app_control_h app_control, void *data) } void -service_app_low_memory_callback(void *data) +service_app_low_memory(void *data) { // Todo: add your code here - service_app_exit(); + service_app_terminate(&data); return; } void -service_app_low_battery_callback(void *data) +service_app_low_battery(void *data) { // Todo: add your code here - service_app_exit(); + service_app_terminate(&data); return; } @@ -138,29 +152,30 @@ service_app_low_battery_callback(void *data) int main(int argc, char* argv[]) { - char ad[50] = {0,}; + appdata_s ad = {}; service_app_event_callback_s event_callback; event_callback.create = service_app_create; event_callback.terminate = service_app_terminate; event_callback.app_control = service_app_control; - event_callback.low_memory = service_app_low_memory_callback; - event_callback.low_battery = service_app_low_battery_callback; + event_callback.low_memory = service_app_low_memory; + event_callback.low_battery = service_app_low_battery; -#if 1 - initialize_sap(); - find_peers(); - rapdu_received = FALSE; - unsigned char apdu[] = {0x00, 0xa4, 0x00, 0x00}; - send_data(apdu, sizeof apdu); - size_t count = 0; - while (!rapdu_received && count < 10) { - dlog_print(DLOG_INFO, LOG_TAG, "waiting for response"); - usleep(100); - count++; - } -#endif - return svc_app_main(argc, argv, &event_callback, ad); +//#if 1 +// initialize_sap(); +// find_peers(); +// rapdu_received = FALSE; +// unsigned char apdu[] = {0x00, 0xa4, 0x00, 0x00}; +// send_data(apdu, sizeof apdu); +// size_t count = 0; +// while (!rapdu_received && count < 10) { +// dlog_print(DLOG_INFO, LOG_TAG, "waiting for response"); +// usleep(100); +// count++; +// } +//#endif + + return svc_app_main(argc, argv, &event_callback, &ad); } diff --git a/TCardEmulator/tizen-manifest.xml b/TCardEmulator/tizen-manifest.xml index f099c89..89e7f8d 100644 --- a/TCardEmulator/tizen-manifest.xml +++ b/TCardEmulator/tizen-manifest.xml @@ -8,8 +8,8 @@ - http://developer.samsung.com/tizen/privilege/accessoryprotocol http://tizen.org/privilege/nfc.cardemulation + http://developer.samsung.com/tizen/privilege/accessoryprotocol true