Refactor connecting to SAP service and sending messages in queue
Sending and receiving works correctly, however establishing an SAP connection takes too long
This commit is contained in:
committed by
Frank Morgner
parent
023550ac11
commit
f2a68c95c1
@@ -1,20 +1,32 @@
|
||||
#include "tcardemulator.h"
|
||||
#include <sap.h>
|
||||
#include "sap_app.h"
|
||||
#include <dlog.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <nfc.h>
|
||||
#include <sap.h>
|
||||
|
||||
#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)
|
||||
|
||||
Reference in New Issue
Block a user