Authentication for ACardEmulator/TCardEmulator
secure sending and with high priority
This commit is contained in:
committed by
Frank Morgner
parent
45273626eb
commit
9c758ffda0
2
ACardEmulator/app/.gitignore
vendored
2
ACardEmulator/app/.gitignore
vendored
@@ -1 +1 @@
|
|||||||
/build
|
/build
|
||||||
@@ -71,14 +71,6 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||||
@@ -87,6 +79,14 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
|
||||||
@@ -108,6 +108,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
signingConfigs {
|
||||||
|
config {
|
||||||
|
keyAlias keystoreProperties['keyAlias']
|
||||||
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
storeFile keystoreProperties['storeFile']
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
|
}
|
||||||
|
}
|
||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.1"
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.vsmartcard.acardemulator"
|
applicationId "com.vsmartcard.acardemulator"
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
@@ -15,6 +26,10 @@ android {
|
|||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.config
|
||||||
|
}
|
||||||
|
debug {
|
||||||
|
signingConfig signingConfigs.config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -49,7 +64,7 @@ android.applicationVariants.all { variant ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
compile 'com.android.support:appcompat-v7:23.0.1'
|
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||||
compile 'com.android.support:support-v4:23.0.1'
|
compile 'com.android.support:support-v4:23.0.1'
|
||||||
compile 'com.android.support:design:23.2.1'
|
compile 'com.android.support:design:23.2.1'
|
||||||
|
|||||||
@@ -23,12 +23,17 @@
|
|||||||
|
|
||||||
package com.vsmartcard.acardemulator;
|
package com.vsmartcard.acardemulator;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.SimpleDateFormat;
|
import javax.security.cert.CertificateException;
|
||||||
import java.util.Calendar;
|
import javax.security.cert.X509Certificate;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.Signature;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -40,8 +45,8 @@ import com.samsung.android.sdk.accessory.*;
|
|||||||
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
|
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
|
||||||
|
|
||||||
public class SmartcardProviderService extends SAAgent {
|
public class SmartcardProviderService extends SAAgent {
|
||||||
private static final String TAG = "HelloAccessory(P)";
|
private static final String TAG = "ACardEmulator";
|
||||||
private static final int HELLOACCESSORY_CHANNEL_ID = 104;
|
private static final int ACCESSORY_CHANNEL_ID = 104;
|
||||||
private static final Class<ServiceConnection> SASOCKET_CLASS = ServiceConnection.class;
|
private static final Class<ServiceConnection> SASOCKET_CLASS = ServiceConnection.class;
|
||||||
private final IBinder mBinder = new LocalBinder();
|
private final IBinder mBinder = new LocalBinder();
|
||||||
private ServiceConnection mConnectionHandler = null;
|
private ServiceConnection mConnectionHandler = null;
|
||||||
@@ -99,8 +104,7 @@ public class SmartcardProviderService extends SAAgent {
|
|||||||
@Override
|
@Override
|
||||||
protected void onServiceConnectionRequested(SAPeerAgent peerAgent) {
|
protected void onServiceConnectionRequested(SAPeerAgent peerAgent) {
|
||||||
if (peerAgent != null) {
|
if (peerAgent != null) {
|
||||||
//TODO: Check for keys and everything
|
authenticatePeerAgent(peerAgent);
|
||||||
acceptServiceConnectionRequest(peerAgent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,12 +120,36 @@ public class SmartcardProviderService extends SAAgent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] getApplicationCertificate(Context context) {
|
||||||
|
byte[] cert = new byte[0];
|
||||||
|
String packageName = context.getPackageName();
|
||||||
|
try {
|
||||||
|
PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||||
|
if (pkgInfo != null) {
|
||||||
|
Signature[] sigs = pkgInfo.signatures;
|
||||||
|
if (sigs != null) {
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(sigs[0].toByteArray());
|
||||||
|
X509Certificate x509cert = X509Certificate.getInstance(stream);
|
||||||
|
cert = x509cert.getPublicKey().getEncoded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException | CertificateException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
}
|
||||||
|
return cert;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onAuthenticationResponse(SAPeerAgent peerAgent, SAAuthenticationToken authToken, int error) {
|
protected void onAuthenticationResponse(SAPeerAgent peerAgent, SAAuthenticationToken authToken, int error) {
|
||||||
/*
|
if (authToken.getAuthenticationType() == SAAuthenticationToken.AUTHENTICATION_TYPE_CERTIFICATE_X509) {
|
||||||
* The authenticatePeerAgent(peerAgent) API may not be working properly depending on the firmware
|
byte[] myAppKey = getApplicationCertificate(getApplicationContext());
|
||||||
* version of accessory device. Please refer to another sample application for Security.
|
if (authToken.getKey().length == myAppKey.length) {
|
||||||
*/
|
if (Arrays.equals(authToken.getKey(), myAppKey)) {
|
||||||
|
acceptServiceConnectionRequest(peerAgent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rejectServiceConnectionRequest(peerAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,7 +203,7 @@ public class SmartcardProviderService extends SAAgent {
|
|||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
mConnectionHandler.send(HELLOACCESSORY_CHANNEL_ID, response);
|
mConnectionHandler.secureSend(ACCESSORY_CHANNEL_ID, response);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<serviceChannel
|
<serviceChannel
|
||||||
id="104"
|
id="104"
|
||||||
dataRate="low"
|
dataRate="low"
|
||||||
priority="low"
|
priority="high"
|
||||||
reliability= "enable"/>
|
reliability= "enable"/>
|
||||||
</serviceProfile>
|
</serviceProfile>
|
||||||
</application>
|
</application>
|
||||||
|
|||||||
@@ -5,4 +5,6 @@
|
|||||||
|
|
||||||
void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_len);
|
void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_len);
|
||||||
|
|
||||||
|
extern gboolean agent_connected;
|
||||||
|
|
||||||
#endif /* __tcardemulator_H__ */
|
#endif /* __tcardemulator_H__ */
|
||||||
|
|||||||
@@ -12,13 +12,6 @@
|
|||||||
#include <nfc.h>
|
#include <nfc.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
//extern unsigned char *rapdu;
|
|
||||||
//extern size_t rapdu_length;
|
|
||||||
//extern gboolean rapdu_received;
|
|
||||||
|
|
||||||
#define HELLO_ACC_ASPID "/com/vsmcartcard"
|
|
||||||
#define HELLO_ACC_CHANNELID 104
|
|
||||||
|
|
||||||
void initialize_sap();
|
void initialize_sap();
|
||||||
gboolean find_peers();
|
gboolean find_peers();
|
||||||
gboolean request_service_connection(void);
|
gboolean request_service_connection(void);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<transport type="TRANSPORT_BT" />
|
<transport type="TRANSPORT_BT" />
|
||||||
<transport type="TRANSPORT_WIFI" />
|
<transport type="TRANSPORT_WIFI" />
|
||||||
</supportedTransports>
|
</supportedTransports>
|
||||||
<serviceChannel id="104" dataRate="low" priority="low"
|
<serviceChannel id="104" dataRate="low" priority="high"
|
||||||
reliability="enable">
|
reliability="enable">
|
||||||
</serviceChannel>
|
</serviceChannel>
|
||||||
</serviceProfile>
|
</serviceProfile>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
#include <sap.h>
|
#include <sap.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#define HELLO_ACCESSORY_PROFILE_ID "/com/vsmcartcard"
|
#define ACCESSORY_PROFILE_ID "/com/vsmcartcard"
|
||||||
#define HELLO_ACCESSORY_CHANNELID 104
|
#define ACCESSORY_CHANNELID 104
|
||||||
|
|
||||||
typedef struct priv {
|
typedef struct priv {
|
||||||
sap_agent_h agent;
|
sap_agent_h agent;
|
||||||
@@ -17,17 +17,10 @@ typedef struct priv {
|
|||||||
nfc_se_h nfc_handle;
|
nfc_se_h nfc_handle;
|
||||||
} priv_s;
|
} priv_s;
|
||||||
|
|
||||||
typedef struct message_queue {
|
gboolean agent_created = FALSE;
|
||||||
void *message;
|
gboolean agent_connected = FALSE;
|
||||||
unsigned int message_len;
|
|
||||||
struct message_queue *next;
|
|
||||||
} message_queue_s;
|
|
||||||
|
|
||||||
static gboolean agent_created = FALSE;
|
|
||||||
static gboolean agent_connected = FALSE;
|
|
||||||
|
|
||||||
static priv_s 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,
|
void on_peer_agent_updated(sap_peer_agent_h peer_agent,
|
||||||
sap_peer_agent_status_e peer_status,
|
sap_peer_agent_status_e peer_status,
|
||||||
@@ -42,7 +35,7 @@ void on_peer_agent_updated(sap_peer_agent_h peer_agent,
|
|||||||
case SAP_PEER_AGENT_FOUND_RESULT_FOUND:
|
case SAP_PEER_AGENT_FOUND_RESULT_FOUND:
|
||||||
if (peer_status == SAP_PEER_AGENT_STATUS_AVAILABLE) {
|
if (peer_status == SAP_PEER_AGENT_STATUS_AVAILABLE) {
|
||||||
priv_data.peer_agent = peer_agent;
|
priv_data.peer_agent = peer_agent;
|
||||||
dlog_print(DLOG_INFO, LOG_TAG, "Find Peer Success!!");
|
dlog_print(DLOG_INFO, LOG_TAG, "requesting service connection");
|
||||||
request_service_connection();
|
request_service_connection();
|
||||||
} else {
|
} else {
|
||||||
dlog_print(DLOG_INFO, LOG_TAG, "peer agent removed");
|
dlog_print(DLOG_INFO, LOG_TAG, "peer agent removed");
|
||||||
@@ -96,77 +89,20 @@ static void on_data_recieved(sap_socket_h socket,
|
|||||||
unsigned short int channel_id,
|
unsigned short int channel_id,
|
||||||
unsigned int payload_length,
|
unsigned int payload_length,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
void *user_data)
|
void *user_data) {
|
||||||
{
|
|
||||||
dlog_print(DLOG_INFO, LOG_TAG, "received data: %p, len:%d", buffer, payload_length);
|
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;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// rapdu_received = TRUE;
|
|
||||||
|
|
||||||
send_apdu_response(priv_data.nfc_handle, buffer, payload_length);
|
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 send_data(nfc_se_h nfc_handle, void *message, unsigned int message_len) {
|
||||||
gboolean result;
|
gboolean result;
|
||||||
if (agent_connected) {
|
priv_data.nfc_handle = nfc_handle;
|
||||||
priv_data.nfc_handle = nfc_handle;
|
result = sap_socket_send_secure_data(priv_data.socket,
|
||||||
result = sap_socket_send_data(priv_data.socket,
|
ACCESSORY_CHANNELID, message_len, message);
|
||||||
HELLO_ACCESSORY_CHANNELID, message_len, message);
|
|
||||||
|
|
||||||
if (result != SAP_RESULT_SUCCESS) {
|
if (result != SAP_RESULT_SUCCESS) {
|
||||||
|
dlog_print(DLOG_INFO, LOG_TAG, "couldn't send sap message: %d", result);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = add_message(message, message_len);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -186,17 +122,16 @@ static void on_service_connection_created(sap_peer_agent_h peer_agent,
|
|||||||
sap_socket_set_data_received_cb(socket, on_data_recieved, peer_agent);
|
sap_socket_set_data_received_cb(socket, on_data_recieved, peer_agent);
|
||||||
priv_data.socket = socket;
|
priv_data.socket = socket;
|
||||||
agent_connected = TRUE;
|
agent_connected = TRUE;
|
||||||
// read messages in queue and send them
|
break;
|
||||||
message_queue_s *message_queue = read_message();
|
|
||||||
while (message_queue != NULL) {
|
case SAP_CONNECTION_IN_PROGRESS:
|
||||||
send_data(priv_data.nfc_handle, message_queue->message, message_queue->message_len);
|
dlog_print(DLOG_INFO, LOG_TAG, "connection is already in progress");
|
||||||
message_queue = read_message();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SAP_CONNECTION_ALREADY_EXIST:
|
case SAP_CONNECTION_ALREADY_EXIST:
|
||||||
dlog_print(DLOG_INFO, LOG_TAG, "connection is already exist");
|
dlog_print(DLOG_INFO, LOG_TAG, "connection already exists");
|
||||||
priv_data.socket = socket;
|
priv_data.socket = socket;
|
||||||
|
agent_connected = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
|
case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
|
||||||
@@ -225,8 +160,7 @@ static void on_service_connection_created(sap_peer_agent_h peer_agent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean _create_service_connection(gpointer user_data)
|
static gboolean _create_service_connection(gpointer user_data) {
|
||||||
{
|
|
||||||
struct priv *priv = NULL;
|
struct priv *priv = NULL;
|
||||||
sap_result_e result = SAP_RESULT_FAILURE;
|
sap_result_e result = SAP_RESULT_FAILURE;
|
||||||
|
|
||||||
@@ -245,16 +179,12 @@ static gboolean _create_service_connection(gpointer user_data)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean request_service_connection(void)
|
gboolean request_service_connection(void) {
|
||||||
{
|
|
||||||
g_idle_add(_create_service_connection, &priv_data);
|
g_idle_add(_create_service_connection, &priv_data);
|
||||||
|
|
||||||
dlog_print(DLOG_DEBUG, LOG_TAG, "request_service_connection call over");
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean _terminate_service_connection(gpointer user_data)
|
static gboolean _terminate_service_connection(gpointer user_data) {
|
||||||
{
|
|
||||||
struct priv *priv = NULL;
|
struct priv *priv = NULL;
|
||||||
sap_result_e result = SAP_RESULT_FAILURE;
|
sap_result_e result = SAP_RESULT_FAILURE;
|
||||||
|
|
||||||
@@ -281,7 +211,6 @@ static gboolean _terminate_service_connection(gpointer user_data)
|
|||||||
gboolean terminate_service_connection(void)
|
gboolean terminate_service_connection(void)
|
||||||
{
|
{
|
||||||
g_idle_add(_terminate_service_connection, &priv_data);
|
g_idle_add(_terminate_service_connection, &priv_data);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,6 +241,13 @@ gboolean find_peers()
|
|||||||
|
|
||||||
GSList* request_installed_aids() {
|
GSList* request_installed_aids() {
|
||||||
GSList* aid_list = g_slist_append(NULL, "A000000397425446590201");
|
GSList* aid_list = g_slist_append(NULL, "A000000397425446590201");
|
||||||
|
aid_list = g_slist_append(aid_list, "A0000003974254465902");
|
||||||
|
aid_list = g_slist_append(aid_list, "A00000039742544659");
|
||||||
|
aid_list = g_slist_append(aid_list, "F276A288BCFBA69D34F31001");
|
||||||
|
aid_list = g_slist_append(aid_list, "F000000001");
|
||||||
|
aid_list = g_slist_append(aid_list, "D27600012401");
|
||||||
|
aid_list = g_slist_append(aid_list, "D2760001240102000000000000010000");
|
||||||
|
aid_list = g_slist_append(aid_list, "A000000527210101");
|
||||||
return aid_list;
|
return aid_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,6 +318,7 @@ static void on_device_status_changed(sap_device_status_e status, sap_transport_t
|
|||||||
priv_data.socket = NULL;
|
priv_data.socket = NULL;
|
||||||
sap_peer_agent_destroy(priv_data.peer_agent);
|
sap_peer_agent_destroy(priv_data.peer_agent);
|
||||||
priv_data.peer_agent = NULL;
|
priv_data.peer_agent = NULL;
|
||||||
|
agent_connected = FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -408,7 +345,7 @@ gboolean agent_initialize()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = sap_agent_initialize(priv_data.agent,
|
result = sap_agent_initialize(priv_data.agent,
|
||||||
HELLO_ACCESSORY_PROFILE_ID, SAP_AGENT_ROLE_CONSUMER,
|
ACCESSORY_PROFILE_ID, SAP_AGENT_ROLE_CONSUMER,
|
||||||
on_agent_initialized, NULL);
|
on_agent_initialized, NULL);
|
||||||
dlog_print(DLOG_DEBUG, LOG_TAG, "sap_agent_initialize >>> %d", result);
|
dlog_print(DLOG_DEBUG, LOG_TAG, "sap_agent_initialize >>> %d", result);
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "tcardemulator.h"
|
#include "tcardemulator.h"
|
||||||
|
#include "sap_app.h"
|
||||||
#include <service_app.h>
|
#include <service_app.h>
|
||||||
#include <nfc.h>
|
#include <nfc.h>
|
||||||
#include <dlog.h>
|
#include <dlog.h>
|
||||||
@@ -10,45 +11,30 @@ typedef struct appdata {
|
|||||||
|
|
||||||
} appdata_s;
|
} appdata_s;
|
||||||
|
|
||||||
//unsigned char *rapdu = NULL;
|
static void hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event, unsigned char *apdu, unsigned int apdu_len, void *user_data) {
|
||||||
//size_t rapdu_length = 0;
|
|
||||||
//gboolean rapdu_received = FALSE;
|
|
||||||
|
|
||||||
static void
|
|
||||||
hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event,
|
|
||||||
unsigned char *apdu, unsigned int apdu_len, void *user_data)
|
|
||||||
{
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NFC_HCE_EVENT_DEACTIVATED:
|
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);
|
dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_DEACTIVATED event on NFC handle %d", handle);
|
||||||
//terminate_service_connection();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NFC_HCE_EVENT_ACTIVATED:
|
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);
|
dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_ACTIVATED event on NFC handle %d", handle);
|
||||||
//find_peers();
|
if (!agent_connected) {
|
||||||
|
find_peers();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NFC_HCE_EVENT_APDU_RECEIVED:
|
case NFC_HCE_EVENT_APDU_RECEIVED:
|
||||||
// rapdu_received = FALSE;
|
|
||||||
dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_APDU_RECEIVED event on NFC handle %d", handle);
|
dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_APDU_RECEIVED event on NFC handle %d", handle);
|
||||||
send_data(handle, apdu, apdu_len);
|
if (agent_connected) {
|
||||||
// size_t count_apdu = 0;
|
send_data(handle, apdu, apdu_len);
|
||||||
// while (!rapdu_received && count_apdu < 10) {
|
} else {
|
||||||
// dlog_print(DLOG_INFO, LOG_TAG, "waiting for response");
|
dlog_print(DLOG_INFO, LOG_TAG, "couldn't send message on SAP channel because agent is not connected");
|
||||||
// usleep(100);
|
}
|
||||||
// count_apdu++;
|
|
||||||
// }
|
|
||||||
// nfc_hce_send_apdu_response(handle, rapdu, rapdu_length);
|
|
||||||
// rapdu_received = FALSE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Error handling
|
dlog_print(DLOG_DEBUG, LOG_TAG, "received unknown event on NFC handle %d", handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,9 +61,7 @@ void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool service_app_create(void *data) {
|
||||||
service_app_create(void *data)
|
|
||||||
{
|
|
||||||
int ret = NFC_ERROR_NONE;
|
int ret = NFC_ERROR_NONE;
|
||||||
bool r = false;
|
bool r = false;
|
||||||
nfc_se_card_emulation_mode_type_e ce_type;
|
nfc_se_card_emulation_mode_type_e ce_type;
|
||||||
@@ -122,9 +106,7 @@ err:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void service_app_terminate(void *data) {
|
||||||
service_app_terminate(void *data)
|
|
||||||
{
|
|
||||||
int ret = NFC_ERROR_NONE;
|
int ret = NFC_ERROR_NONE;
|
||||||
|
|
||||||
nfc_manager_unset_hce_event_cb();
|
nfc_manager_unset_hce_event_cb();
|
||||||
@@ -137,43 +119,26 @@ service_app_terminate(void *data)
|
|||||||
|
|
||||||
terminate_service_connection();
|
terminate_service_connection();
|
||||||
|
|
||||||
// free(rapdu);
|
|
||||||
// rapdu = NULL;
|
|
||||||
// rapdu_length = 0;
|
|
||||||
// rapdu_received = FALSE;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void service_app_control(app_control_h app_control, void *data) {
|
||||||
service_app_control(app_control_h app_control, void *data)
|
|
||||||
{
|
|
||||||
// Todo: add your code here
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void service_app_low_memory(void *data) {
|
||||||
service_app_low_memory(void *data)
|
|
||||||
{
|
|
||||||
// Todo: add your code here
|
|
||||||
service_app_terminate(&data);
|
service_app_terminate(&data);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void service_app_low_battery(void *data) {
|
||||||
service_app_low_battery(void *data)
|
|
||||||
{
|
|
||||||
// Todo: add your code here
|
|
||||||
service_app_terminate(&data);
|
service_app_terminate(&data);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int main(int argc, char* argv[]) {
|
||||||
main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
appdata_s ad = {};
|
appdata_s ad = {};
|
||||||
|
|
||||||
service_app_event_callback_s event_callback;
|
service_app_event_callback_s event_callback;
|
||||||
@@ -184,20 +149,5 @@ main(int argc, char* argv[])
|
|||||||
event_callback.low_memory = service_app_low_memory;
|
event_callback.low_memory = service_app_low_memory;
|
||||||
event_callback.low_battery = service_app_low_battery;
|
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);
|
return svc_app_main(argc, argv, &event_callback, &ad);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user