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 @@
-
-
+
-
+
@@ -98,7 +98,7 @@
-
+
@@ -175,14 +175,13 @@
-
+
-
+
@@ -223,6 +222,7 @@
+
@@ -230,17 +230,16 @@
-
-
+
-
+
@@ -313,7 +312,7 @@
-
+
@@ -387,14 +386,13 @@
-
+
-
+
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