Commit f067256d authored by Nick Pelly's avatar Nick Pelly
Browse files

NFC application.


NFC application contains the NFC service code that implements NFC API and
talks to NFC hardware.

This is the first cut at moving NFC service code out of frameworks/base into
application service. Android.mk are renamed to Android.mk.hide at this commit
because it does not work yet.
Signed-off-by: default avatarNick Pelly <npelly@google.com>
parent a886d223
No related merge requests found
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := Nfc
LOCAL_CERTIFICATE := platform
LOCAL_JNI_SHARED_LIBRARIES := libnfc_jni
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.nfc" >
<uses-permission android:name="android.permission.NFC_ADMIN" />
<uses-permission android:name="android.permission.NFC_RAW" />
<uses-permission android:name="android.permission.NFC_NOTIFY" />
<uses-permission android:name="android.permission.NFC_LLCP" />
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:persistent="true">
<service android:name=".NfcService">
</service>
</application>
</manifest>
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_SRC_FILES:= \
com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket.cpp \
com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket.cpp \
com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket.cpp \
com_trustedlogic_trustednfc_android_internal_NativeNdefTag.cpp \
com_trustedlogic_trustednfc_android_internal_NativeNfcManager.cpp \
com_trustedlogic_trustednfc_android_internal_NativeNfcTag.cpp \
com_trustedlogic_trustednfc_android_internal_NativeP2pDevice.cpp \
com_trustedlogic_trustednfc_android_NdefMessage.cpp \
com_trustedlogic_trustednfc_android_NdefRecord.cpp \
trustednfc_jni.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
external/libnfc-nxp/src \
external/libnfc-nxp/inc
LOCAL_SHARED_LIBRARIES := \
libnativehelper \
libcutils \
libutils \
libnfc
LOCAL_MODULE := libnfc_jni
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_NdefMessage.c
* Original-Author : Trusted Logic S.A. (Jeremie Corbier)
* Created : 06-10-2009
*/
#include "trustednfc_jni.h"
namespace android {
static jint com_trustedlogic_trustednfc_android_NdefMessage_parseNdefMessage(
JNIEnv *e, jobject o, jbyteArray array)
{
NFCSTATUS status;
uint32_t i;
jbyte *raw_msg;
jsize raw_msg_size;
uint32_t num_of_records = 0;
uint8_t **records = NULL;
uint8_t *is_chunked = NULL;
jint ret = -1;
phFriNfc_NdefRecord_t record;
jclass record_cls;
jobjectArray records_array;
jmethodID ctor;
jclass msg_cls;
jfieldID mrecords;
raw_msg_size = e->GetArrayLength(array);
raw_msg = e->GetByteArrayElements(array, NULL);
if(raw_msg == NULL)
return -1;
/* Get the number of records in the message so we can allocate buffers */
LOGD("phFriNfc_NdefRecord_GetRecords(NULL)");
REENTRANCE_LOCK();
status = phFriNfc_NdefRecord_GetRecords((uint8_t *)raw_msg,
(uint32_t)raw_msg_size, NULL, NULL, &num_of_records);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_SUCCESS)
{
LOGE("phFriNfc_NdefRecord_GetRecords(NULL) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto end;
}
LOGD("phFriNfc_NdefRecord_GetRecords(NULL) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
LOGD("found %d records in message", num_of_records);
is_chunked = (uint8_t*)malloc(num_of_records);
if(is_chunked == NULL)
goto end;
records = (uint8_t**)malloc(num_of_records * sizeof(uint8_t *));
if(records == NULL)
goto end;
/* Now, actually retrieve records position in message */
LOGD("phFriNfc_NdefRecord_GetRecords()");
REENTRANCE_LOCK();
status = phFriNfc_NdefRecord_GetRecords((uint8_t *)raw_msg,
(uint32_t)raw_msg_size, records, is_chunked, &num_of_records);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_SUCCESS)
{
LOGE("phFriNfc_NdefRecord_GetRecords() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto end;
}
LOGD("phFriNfc_NdefRecord_GetRecords() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Build NDEF records array */
record_cls =
e->FindClass("android/nfc/NdefRecord");
records_array = e->NewObjectArray((jsize)num_of_records, record_cls,
NULL);
if(records_array == NULL)
goto end;
ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[B)V");
LOGD("NFC_Number of records = %d\n",num_of_records);
for(i = 0; i < num_of_records; i++)
{
jbyteArray type, id, payload;
jobject new_record;
LOGD("phFriNfc_NdefRecord_Parse()");
REENTRANCE_LOCK();
status = phFriNfc_NdefRecord_Parse(&record, records[i]);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_SUCCESS)
{
LOGE("phFriNfc_NdefRecord_Parse() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto end;
}
LOGD("phFriNfc_NdefRecord_Parse() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
type = e->NewByteArray(record.TypeLength);
if(type == NULL)
{
LOGD("NFC_Set Record Type Error\n");
goto end;
}
id = e->NewByteArray(record.IdLength);
if(id == NULL)
{
LOGD("NFC_Set Record ID Error\n");
goto end;
}
payload = e->NewByteArray(record.PayloadLength);
if(payload == NULL)
{
LOGD("NFC_Set Record Payload Error\n");
goto end;
}
e->SetByteArrayRegion(type, 0, record.TypeLength,
(jbyte *)record.Type);
e->SetByteArrayRegion(id, 0, record.IdLength,
(jbyte *)record.Id);
e->SetByteArrayRegion(payload, 0, record.PayloadLength,
(jbyte *)record.PayloadData);
new_record = e->NewObject(record_cls, ctor,
(jshort)record.Tnf, type, id, payload);
e->SetObjectArrayElement(records_array, i, new_record);
/* Try not to clutter the Java stack too much */
e->DeleteLocalRef(new_record);
e->DeleteLocalRef(type);
e->DeleteLocalRef(id);
e->DeleteLocalRef(payload);
}
/* Store built array in our NDEFMessage instance */
msg_cls = e->GetObjectClass(o);
mrecords = e->GetFieldID(msg_cls, "mRecords",
"[Landroid/nfc/NdefRecord;");
e->SetObjectField(o, mrecords, (jobject)records_array);
ret = 0;
end:
if(is_chunked)
free(is_chunked);
if(records)
free(records);
e->ReleaseByteArrayElements(array, raw_msg, JNI_ABORT);
return ret;
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"parseNdefMessage", "([B)I",
(void *)com_trustedlogic_trustednfc_android_NdefMessage_parseNdefMessage},
};
int register_com_trustedlogic_trustednfc_android_NdefMessage(JNIEnv *e)
{
return jniRegisterNativeMethods(e,
"android/nfc/NdefMessage",
gMethods, NELEM(gMethods));
}
} // namespace android
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_NdefRecord.c
* Original-Author : Trusted Logic S.A. (Jeremie Corbier)
* Created : 08-10-2009
*/
#include "trustednfc_jni.h"
namespace android {
static jbyteArray com_trustedlogic_trustednfc_android_NdefRecord_generate(
JNIEnv *e, jobject o, jshort flags, jshort tnf, jbyteArray type,
jbyteArray id, jbyteArray payload)
{
NFCSTATUS status;
phFriNfc_NdefRecord_t record;
uint32_t buf_size;
uint32_t record_size;
uint8_t *buf = NULL;
jbyteArray result = NULL;
/* Prepare NDEF record structure */
record.Flags = (uint8_t)flags;
record.Tnf = (uint8_t)tnf;
record.TypeLength = (uint32_t)e->GetArrayLength(type);
record.Type = (uint8_t *)e->GetByteArrayElements(type, NULL);
record.IdLength = (uint32_t)e->GetArrayLength(id);
record.Id = (uint8_t *)e->GetByteArrayElements(id, NULL);
record.PayloadLength = (uint32_t)e->GetArrayLength(payload);
record.PayloadData = (uint8_t *)e->GetByteArrayElements(payload, NULL);
buf_size = record.PayloadLength + record.IdLength + record.TypeLength + 8;
buf = (uint8_t*)malloc(buf_size);
if(buf == NULL)
goto end;
LOGD("phFriNfc_NdefRecord_Generate()");
REENTRANCE_LOCK();
status = phFriNfc_NdefRecord_Generate(&record, buf, buf_size, &record_size);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_SUCCESS)
{
LOGE("phFriNfc_NdefRecord_Generate() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto end;
}
LOGD("phFriNfc_NdefRecord_Generate() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
result = e->NewByteArray(record_size);
if(result == NULL)
goto end;
e->SetByteArrayRegion(result, 0, record_size, (jbyte *)buf);
end:
e->ReleaseByteArrayElements(type, (jbyte *)record.Type, JNI_ABORT);
e->ReleaseByteArrayElements(id, (jbyte *)record.Id, JNI_ABORT);
e->ReleaseByteArrayElements(payload, (jbyte *)record.PayloadData, JNI_ABORT);
if(buf)
free(buf);
return result;
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"generate", "(SS[B[B[B)[B",
(void *)com_trustedlogic_trustednfc_android_NdefRecord_generate},
};
int register_com_trustedlogic_trustednfc_android_NdefRecord(JNIEnv *e)
{
return jniRegisterNativeMethods(e,
"android/nfc/NdefRecord",
gMethods, NELEM(gMethods));
}
} // namespace android
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionLessSocket.c
* Original-Author : Trusted Logic S.A. (Daniel Tomas)
* Created : 04-03-2010
*/
#include <semaphore.h>
#include "trustednfc_jni.h"
static sem_t trustednfc_jni_llcp_send_sem;
static sem_t trustednfc_jni_llcp_receive_sem;
static NFCSTATUS trustednfc_jni_cb_status = NFCSTATUS_FAILED;
static uint8_t receivedSsap;
namespace android {
/*
* Callbacks
*/
static void trustednfc_jni_receive_callback(void* pContext, uint8_t ssap, NFCSTATUS status)
{
uint8_t* receiveSsap = (uint8_t*)pContext;
LOG_CALLBACK("trustednfc_jni_receiveFrom_callback", status);
trustednfc_jni_cb_status = status;
if(status == NFCSTATUS_SUCCESS)
{
*receiveSsap = ssap;
LOGD("RECEIVE UI_FRAME FROM SAP %d OK \n",*receiveSsap);
}
sem_post(&trustednfc_jni_llcp_receive_sem);
}
static void trustednfc_jni_send_callback(void *pContext, NFCSTATUS status)
{
PHNFC_UNUSED_VARIABLE(pContext);
LOG_CALLBACK("trustednfc_jni_sendTo_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_llcp_send_sem);
}
/*
* Methods
*/
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket_doSendTo(JNIEnv *e, jobject o, jint nsap, jbyteArray data)
{
NFCSTATUS ret;
struct timespec ts;
phLibNfc_Handle hLlcpSocket;
phNfc_sData_t sSendBuffer;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
sSendBuffer.buffer = (uint8_t*)e->GetByteArrayElements(data, NULL);
sSendBuffer.length = (uint32_t)e->GetArrayLength(data);
LOGD("phLibNfc_Llcp_SendTo()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_SendTo(hLlcpSocket,
nsap,
&sSendBuffer,
trustednfc_jni_send_callback,
(void*)hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_SendTo() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return FALSE;
}
LOGD("phLibNfc_Llcp_SendTo() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_llcp_send_sem) == -1)
return FALSE;
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
}
static jobject com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket_doReceiveFrom(JNIEnv *e, jobject o, jint linkMiu)
{
NFCSTATUS ret;
struct timespec ts;
uint8_t ssap;
jobject llcpPacket = NULL;
phLibNfc_Handle hLlcpSocket;
phNfc_sData_t sReceiveBuffer;
jclass clsLlcpPacket;
jfieldID f;
jbyteArray receivedData;
/* Create new LlcpPacket object */
if(trustednfc_jni_cache_object(e,"com/trustedlogic/trustednfc/android/LlcpPacket",&(llcpPacket)) == -1)
{
LOGD("Find LlcpPacket class error");
return NULL;
}
/* Get NativeConnectionless class object */
clsLlcpPacket = e->GetObjectClass(llcpPacket);
if(e->ExceptionCheck())
{
LOGD("Get Object class error");
return NULL;
}
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
LOGD("Socket Handle = 0x%02x",hLlcpSocket);
LOGD("Link LIU = %d",linkMiu);
sReceiveBuffer.buffer = (uint8_t*)malloc(linkMiu);
sReceiveBuffer.length = linkMiu;
LOGD("phLibNfc_Llcp_RecvFrom()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_RecvFrom(hLlcpSocket,
&sReceiveBuffer,
trustednfc_jni_receive_callback,
&ssap);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_RecvFrom() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return NULL;
}
LOGD("phLibNfc_Llcp_RecvFrom() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_llcp_receive_sem) == -1)
return NULL;
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
LOGD("Data Received From SSAP = %d\n",ssap);
LOGD("Data Received Length = %d\n",sReceiveBuffer.length);
/* Set Llcp Packet remote SAP */
f = e->GetFieldID(clsLlcpPacket, "mRemoteSap", "I");
e->SetIntField(llcpPacket, f,(jbyte)ssap);
/* Set Llcp Packet Buffer */
LOGD("Set LlcpPacket Data Buffer\n");
f = e->GetFieldID(clsLlcpPacket, "mDataBuffer", "[B");
receivedData = e->NewByteArray(sReceiveBuffer.length);
e->SetByteArrayRegion(receivedData, 0, sReceiveBuffer.length,(jbyte *)sReceiveBuffer.buffer);
e->SetObjectField(llcpPacket, f, receivedData);
return llcpPacket;
}
else
{
return FALSE;
}
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket_doClose(JNIEnv *e, jobject o)
{
NFCSTATUS ret;
phLibNfc_Handle hLlcpSocket;
LOGD("Close Connectionless socket");
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
LOGD("phLibNfc_Llcp_Close()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Close(hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret == NFCSTATUS_SUCCESS)
{
LOGD("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return TRUE;
}
else
{
LOGE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return FALSE;
}
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"doSendTo", "(I[B)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket_doSendTo},
{"doReceiveFrom", "(I)Landroid/nfc/LlcpPacket;",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket_doReceiveFrom},
{"doClose", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket_doClose},
};
int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket(JNIEnv *e)
{
if(sem_init(&trustednfc_jni_llcp_send_sem, 0, 0) == -1)
return -1;
if(sem_init(&trustednfc_jni_llcp_receive_sem, 0, 0) == -1)
return -1;
return jniRegisterNativeMethods(e,
"com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket",
gMethods, NELEM(gMethods));
}
} // android namespace
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket.c
* Original-Author : Trusted Logic S.A. (Daniel Tomas)
* Created : 04-03-2010
*/
#include <semaphore.h>
#include "trustednfc_jni.h"
static sem_t trustednfc_jni_llcp_sem;
static NFCSTATUS trustednfc_jni_cb_status = NFCSTATUS_FAILED;
namespace android {
extern phLibNfc_Handle hIncommingLlcpSocket;
extern sem_t trustednfc_jni_llcp_listen_sem;
extern void trustednfc_jni_llcp_transport_socket_err_callback(void* pContext,
uint8_t nErrCode);
/*
* Callbacks
*/
static void trustednfc_jni_llcp_accept_socket_callback(void* pContext,
NFCSTATUS status)
{
PHNFC_UNUSED_VARIABLE(pContext);
LOG_CALLBACK("trustednfc_jni_llcp_accept_socket_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_llcp_sem);
}
/*
* Methods
*/
static jobject com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, int timeout, jint miu, jint rw, jint linearBufferLength)
{
NFCSTATUS ret;
struct timespec ts;
phLibNfc_Llcp_sSocketOptions_t sOptions;
phNfc_sData_t sWorkingBuffer;
jfieldID f;
jclass clsNativeLlcpSocket;
jobject clientSocket = 0;
/* Wait for connection request */
if(timeout != 0)
{
LOGD("Accept timeout set to %d s\n", timeout);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += timeout;
/* Wait for tag Notification */
if(sem_timedwait(&trustednfc_jni_llcp_listen_sem, &ts) == -1)
{
return NULL;
}
}
else
{
/* Wait for tag Notification */
if(sem_wait(&trustednfc_jni_llcp_listen_sem) == -1)
{
return NULL;
}
}
/* Set socket options with the socket options of the service */
sOptions.miu = miu;
sOptions.rw = rw;
/* Allocate Working buffer length */
sWorkingBuffer.buffer = (uint8_t*)malloc((miu*rw)+miu+linearBufferLength);
sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
/* Accept the incomming socket */
LOGD("phLibNfc_Llcp_Accept()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Accept( hIncommingLlcpSocket,
&sOptions,
&sWorkingBuffer,
trustednfc_jni_llcp_transport_socket_err_callback,
trustednfc_jni_llcp_accept_socket_callback,
(void*)hIncommingLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return NULL;
}
LOGD("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
/* Wait for tag Notification */
if(sem_wait(&trustednfc_jni_llcp_sem) == -1)
{
return NULL;
}
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
/* Create new LlcpSocket object */
if(trustednfc_jni_cache_object(e,"com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket",&(clientSocket)) == -1)
{
LOGD("LLCP Socket creation error");
return NULL;
}
/* Get NativeConnectionOriented class object */
clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
if(e->ExceptionCheck())
{
LOGD("LLCP Socket get class object error");
return NULL;
}
/* Set socket handle */
f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
e->SetIntField(clientSocket, f,(jint)hIncommingLlcpSocket);
LOGD("socket Handle = %02x\n",hIncommingLlcpSocket);
/* Set socket MIU */
f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
e->SetIntField(clientSocket, f,(jint)miu);
LOGD("socket MIU = %d\n",miu);
/* Set socket RW */
f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
e->SetIntField(clientSocket, f,(jint)rw);
LOGD("socket RW = %d\n",rw);
return clientSocket;
}
else
{
return NULL;
}
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket_doClose(JNIEnv *e, jobject o)
{
NFCSTATUS ret;
phLibNfc_Handle hLlcpSocket;
LOGD("Close Service socket");
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Close(hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret == NFCSTATUS_SUCCESS)
{
LOGD("Close Service socket OK");
return TRUE;
}
else
{
LOGD("Close Service socket KO");
return FALSE;
}
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"doAccept", "(IIII)Lcom/trustedlogic/trustednfc/android/internal/NativeLlcpSocket;",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket_doAccept},
{"doClose", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket_doClose},
};
int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket(JNIEnv *e)
{
if(sem_init(&trustednfc_jni_llcp_sem, 0, 0) == -1)
return -1;
return jniRegisterNativeMethods(e,
"com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket",
gMethods, NELEM(gMethods));
}
} // namespace android
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket.c
* Original-Author : Trusted Logic S.A. (Daniel Tomas)
* Created : 04-03-2010
*/
#include <semaphore.h>
#include "trustednfc_jni.h"
static sem_t trustednfc_jni_llcp_sem;
static NFCSTATUS trustednfc_jni_cb_status = NFCSTATUS_FAILED;
namespace android {
/*
* Callbacks
*/
static void trustednfc_jni_disconnect_callback(void* pContext,
NFCSTATUS status)
{
PHNFC_UNUSED_VARIABLE(pContext);
LOG_CALLBACK("trustednfc_jni_llcp_disconnect_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_llcp_sem);
}
static void trustednfc_jni_connect_callback(void* pContext, uint8_t nErrCode, NFCSTATUS status)
{
PHNFC_UNUSED_VARIABLE(pContext);
LOG_CALLBACK("trustednfc_jni_llcp_connect_callback", status);
trustednfc_jni_cb_status = status;
if(status == NFCSTATUS_SUCCESS)
{
LOGD("Socket connected\n");
}
else
{
LOGD("Socket not connected:");
switch(nErrCode)
{
case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_ACTIVE:
{
LOGD("> SAP NOT ACTIVE\n");
}break;
case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND:
{
LOGD("> SAP NOT FOUND\n");
}break;
case PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED:
{
LOGD("> CONNECT REJECTED\n");
}break;
case PHFRINFC_LLCP_DM_OPCODE_CONNECT_NOT_ACCEPTED:
{
LOGD("> CONNECT NOT ACCEPTED\n");
}break;
case PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE:
{
LOGD("> SOCKET NOT AVAILABLE\n");
}break;
}
}
sem_post(&trustednfc_jni_llcp_sem);
}
static void trustednfc_jni_receive_callback(void* pContext, NFCSTATUS status)
{
uint8_t i;
PHNFC_UNUSED_VARIABLE(pContext);
LOG_CALLBACK("trustednfc_jni_llcp_receive_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_llcp_sem);
}
static void trustednfc_jni_send_callback(void *pContext, NFCSTATUS status)
{
PHNFC_UNUSED_VARIABLE(pContext);
LOG_CALLBACK("trustednfc_jni_llcp_send_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_llcp_sem);
}
/*
* Methods
*/
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doConnect(JNIEnv *e, jobject o, jint nSap, jint timeout)
{
NFCSTATUS ret;
struct timespec ts;
phLibNfc_Handle hLlcpSocket;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
LOGD("phLibNfc_Llcp_Connect(%d)",nSap);
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Connect(hLlcpSocket,
nSap,
trustednfc_jni_connect_callback,
(void*)hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, trustednfc_jni_get_status_name(ret));
return FALSE;
}
LOGD("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, trustednfc_jni_get_status_name(ret));
if(timeout != 0)
{
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += timeout;
/* Wait for callback response */
if(sem_timedwait(&trustednfc_jni_llcp_sem, &ts) == -1)
return FALSE;
}
else
{
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_llcp_sem) == -1)
return FALSE;
}
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
LOGD("LLCP Connect request OK",ret);
return TRUE;
}
else
{
LOGD("LLCP Connect request KO",ret);
return FALSE;
}
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doConnectBy(JNIEnv *e, jobject o, jstring sn, jint timeout)
{
NFCSTATUS ret;
struct timespec ts;
phNfc_sData_t serviceName;
phLibNfc_Handle hLlcpSocket;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
/* Service socket */
serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
LOGD("phLibNfc_Llcp_ConnectByUri()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_ConnectByUri(hLlcpSocket,
&serviceName,
trustednfc_jni_connect_callback,
(void*)hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return FALSE;
}
LOGD("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
if(timeout != 0)
{
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += timeout;
/* Wait for callback response */
if(sem_timedwait(&trustednfc_jni_llcp_sem, &ts) == -1)
return FALSE;
}
else
{
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_llcp_sem) == -1)
return FALSE;
}
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doClose(JNIEnv *e, jobject o)
{
NFCSTATUS ret;
phLibNfc_Handle hLlcpSocket;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
LOGD("phLibNfc_Llcp_Close()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Close(hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_SUCCESS)
{
LOGE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return FALSE;
}
LOGD("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return TRUE;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doSend(JNIEnv *e, jobject o, jbyteArray data)
{
NFCSTATUS ret;
struct timespec ts;
phLibNfc_Handle hLlcpSocket;
phNfc_sData_t sSendBuffer;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
sSendBuffer.buffer = (uint8_t*)e->GetByteArrayElements(data, NULL);
sSendBuffer.length = (uint32_t)e->GetArrayLength(data);
LOGD("phLibNfc_Llcp_Send()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Send(hLlcpSocket,
&sSendBuffer,
trustednfc_jni_send_callback,
(void*)hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return FALSE;
}
LOGD("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_llcp_sem) == -1)
return FALSE;
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
}
static jint com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray buffer)
{
NFCSTATUS ret;
struct timespec ts;
phLibNfc_Handle hLlcpSocket;
phNfc_sData_t sReceiveBuffer;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
sReceiveBuffer.buffer = (uint8_t*)e->GetByteArrayElements(buffer, NULL);
sReceiveBuffer.length = (uint32_t)e->GetArrayLength(buffer);
LOGD("phLibNfc_Llcp_Recv()");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_Recv(hLlcpSocket,
&sReceiveBuffer,
trustednfc_jni_receive_callback,
(void*)hLlcpSocket);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return 0;
}
LOGD("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_llcp_sem) == -1)
return FALSE;
if(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS)
{
return sReceiveBuffer.length;
}
else
{
return 0;
}
}
static jint com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doGetRemoteSocketMIU(JNIEnv *e, jobject o)
{
NFCSTATUS ret;
phLibNfc_Handle hLlcpSocket;
phLibNfc_Llcp_sSocketOptions_t remoteSocketOption;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
LOGD("phLibNfc_Llcp_SocketGetRemoteOptions(MIU)");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_SocketGetRemoteOptions(hLlcpSocket,
&remoteSocketOption);
REENTRANCE_UNLOCK();
if(ret == NFCSTATUS_SUCCESS)
{
LOGD("phLibNfc_Llcp_SocketGetRemoteOptions(MIU) returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return remoteSocketOption.miu;
}
else
{
LOGW("phLibNfc_Llcp_SocketGetRemoteOptions(MIU) returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return 0;
}
}
static jint com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doGetRemoteSocketRW(JNIEnv *e, jobject o)
{
NFCSTATUS ret;
phLibNfc_Handle hLlcpSocket;
phLibNfc_Llcp_sSocketOptions_t remoteSocketOption;
/* Retrieve socket handle */
hLlcpSocket = trustednfc_jni_get_nfc_socket_handle(e,o);
LOGD("phLibNfc_Llcp_SocketGetRemoteOptions(RW)");
REENTRANCE_LOCK();
ret = phLibNfc_Llcp_SocketGetRemoteOptions(hLlcpSocket,
&remoteSocketOption);
REENTRANCE_UNLOCK();
if(ret == NFCSTATUS_SUCCESS)
{
LOGD("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return remoteSocketOption.rw;
}
else
{
LOGW("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return 0;
}
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"doConnect", "(II)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doConnect},
{"doConnectBy", "(Ljava/lang/String;I)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doConnectBy},
{"doClose", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doClose},
{"doSend", "([B)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doSend},
{"doReceive", "([B)I",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doReceive},
{"doGetRemoteSocketMiu", "()I",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doGetRemoteSocketMIU},
{"doGetRemoteSocketRw", "()I",
(void *)com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket_doGetRemoteSocketRW},
};
int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket(JNIEnv *e)
{
if(sem_init(&trustednfc_jni_llcp_sem, 0, 0) == -1)
return -1;
return jniRegisterNativeMethods(e,
"com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket",gMethods, NELEM(gMethods));
}
} // namespace android
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_internal_NativeNdefTag.c
* Original-Author : Trusted Logic S.A. (Jeremie Corbier)
* Created : 09-12-2009
*/
#include <semaphore.h>
#include "trustednfc_jni.h"
static sem_t trustednfc_jni_ndef_tag_sem;
static phLibNfc_Data_t trustednfc_jni_ndef_rw;
static NFCSTATUS trustednfc_jni_cb_status = NFCSTATUS_FAILED;
/* Shared with NfcTag module */
extern uint8_t trustednfc_jni_is_ndef;
extern uint8_t * trustednfc_jni_ndef_buf;
extern uint32_t trustednfc_jni_ndef_buf_len;
namespace android {
static void trustednfc_jni_tag_rw_callback(void *pContext, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_tag_rw_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_ndef_tag_sem);
}
static jbyteArray com_trustedlogic_trustednfc_android_internal_NativeNdefTag_doRead(JNIEnv *e,
jobject o)
{
phLibNfc_Handle handle = 0;
jbyteArray buf = NULL;
NFCSTATUS status;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_nfc_tag_handle(e, o);
trustednfc_jni_ndef_rw.length = trustednfc_jni_ndef_buf_len;
trustednfc_jni_ndef_rw.buffer = trustednfc_jni_ndef_buf;
LOGD("phLibNfc_Ndef_Read()");
REENTRANCE_LOCK();
status = phLibNfc_Ndef_Read( handle,
&trustednfc_jni_ndef_rw,
phLibNfc_Ndef_EBegin,
trustednfc_jni_tag_rw_callback,
(void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_ndef_tag_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
buf = e->NewByteArray(trustednfc_jni_ndef_rw.length);
e->SetByteArrayRegion(buf, 0, trustednfc_jni_ndef_rw.length,
(jbyte *)trustednfc_jni_ndef_rw.buffer);
clean_and_return:
CONCURRENCY_UNLOCK();
return buf;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeNdefTag_doWrite(JNIEnv *e,
jobject o, jbyteArray buf)
{
NFCSTATUS status;
jboolean result = JNI_FALSE;
CONCURRENCY_LOCK();
phLibNfc_Handle handle = trustednfc_jni_get_nfc_tag_handle(e, o);
trustednfc_jni_ndef_rw.length = (uint32_t)e->GetArrayLength(buf);
trustednfc_jni_ndef_rw.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL);
LOGD("phLibNfc_Ndef_Write()");
REENTRANCE_LOCK();
status = phLibNfc_Ndef_Write(handle, &trustednfc_jni_ndef_rw,trustednfc_jni_tag_rw_callback, (void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_ndef_tag_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
if (result != JNI_TRUE)
{
e->ReleaseByteArrayElements(buf, (jbyte *)trustednfc_jni_ndef_rw.buffer, JNI_ABORT);
}
CONCURRENCY_UNLOCK();
return result;
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"doRead", "()[B",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNdefTag_doRead},
{"doWrite", "([B)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNdefTag_doWrite},
};
int register_com_trustedlogic_trustednfc_android_internal_NativeNdefTag(JNIEnv *e)
{
if(sem_init(&trustednfc_jni_ndef_tag_sem, 0, 0) == -1)
return -1;
return jniRegisterNativeMethods(e,
"com/trustedlogic/trustednfc/android/internal/NativeNdefTag",
gMethods, NELEM(gMethods));
}
} // namespace android
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_internal_NativeNfcTag.c
* Original-Author : Trusted Logic S.A. (Jeremie Corbier)
* Created : 27-08-2009
*/
#include <semaphore.h>
#include "trustednfc_jni.h"
static sem_t trustednfc_jni_tag_sem;
static NFCSTATUS trustednfc_jni_cb_status = NFCSTATUS_FAILED;
static phLibNfc_Data_t trustednfc_jni_ndef_rw;
static phLibNfc_Handle handle;
uint8_t trustednfc_jni_is_ndef = -1;
uint8_t *trustednfc_jni_ndef_buf = NULL;
uint32_t trustednfc_jni_ndef_buf_len = 0;
namespace android {
extern void trustednfc_jni_restart_discovery(struct trustednfc_jni_native_data *nat);
/*
* Callbacks
*/
static void trustednfc_jni_tag_rw_callback(void *pContext, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_tag_rw_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_tag_sem);
}
static void trustednfc_jni_connect_callback(void *pContext,
phLibNfc_Handle hRemoteDev,
phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_connect_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_tag_sem);
}
static void trustednfc_jni_checkndef_callback(void *pContext,
phLibNfc_ChkNdef_Info_t info, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_checkndef_callback", status);
if(status == NFCSTATUS_OK)
{
if(trustednfc_jni_ndef_buf)
{
free(trustednfc_jni_ndef_buf);
}
trustednfc_jni_ndef_buf_len = info.MaxNdefMsgLength;
trustednfc_jni_ndef_buf = (uint8_t*)malloc(trustednfc_jni_ndef_buf_len);
trustednfc_jni_is_ndef = 1;
}
else
{
trustednfc_jni_is_ndef = 0;
}
sem_post(&trustednfc_jni_tag_sem);
}
static void trustednfc_jni_disconnect_callback(void *pContext,
phLibNfc_Handle hRemoteDev, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_disconnect_callback", status);
if(trustednfc_jni_ndef_buf)
{
free(trustednfc_jni_ndef_buf);
}
trustednfc_jni_ndef_buf = NULL;
trustednfc_jni_ndef_buf_len = 0;
trustednfc_jni_is_ndef = -1;
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_tag_sem);
}
static void trustednfc_jni_async_disconnect_callback(void *pContext,
phLibNfc_Handle hRemoteDev, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_async_disconnect_callback", status);
if(trustednfc_jni_ndef_buf)
{
free(trustednfc_jni_ndef_buf);
}
trustednfc_jni_ndef_buf = NULL;
trustednfc_jni_ndef_buf_len = 0;
trustednfc_jni_is_ndef = -1;
}
static void trustednfc_jni_presence_check_callback(void* pContext,NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_presence_check_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_tag_sem);
}
static void trustednfc_jni_async_presence_check_callback(void* pContext,NFCSTATUS status)
{
NFCSTATUS ret;
JNIEnv* env = (JNIEnv*)pContext;
LOG_CALLBACK("trustednfc_jni_async_presence_check_callback", status);
if(status != NFCSTATUS_SUCCESS)
{
/* Disconnect & Restart Polling loop */
LOGI("Tag removed from the RF Field\n");
LOGD("phLibNfc_RemoteDev_Disconnect(async)");
REENTRANCE_LOCK();
ret = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE, trustednfc_jni_async_disconnect_callback,(void*)handle);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
trustednfc_jni_restart_discovery(trustednfc_jni_get_nat_ext(env));
return;
}
LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
}
else
{
// usleep(100000);
LOGD("phLibNfc_RemoteDev_CheckPresence(async)");
/* Presence Check */
REENTRANCE_LOCK();
ret = phLibNfc_RemoteDev_CheckPresence(handle,trustednfc_jni_async_presence_check_callback, (void*)env);
REENTRANCE_UNLOCK();
if(ret != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
return;
}
LOGD("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", ret, trustednfc_jni_get_status_name(ret));
}
}
static phNfc_sData_t *trustednfc_jni_transceive_buffer;
static void trustednfc_jni_transceive_callback(void *pContext,
phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_transceive_callback", status);
trustednfc_jni_cb_status = status;
trustednfc_jni_transceive_buffer = pResBuffer;
sem_post(&trustednfc_jni_tag_sem);
}
/* Functions */
static jbyteArray com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doRead(JNIEnv *e,
jobject o)
{
NFCSTATUS status;
phLibNfc_Handle handle = 0;
jbyteArray buf = NULL;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_nfc_tag_handle(e, o);
trustednfc_jni_ndef_rw.length = trustednfc_jni_ndef_buf_len;
trustednfc_jni_ndef_rw.buffer = trustednfc_jni_ndef_buf;
LOGD("phLibNfc_Ndef_Read()");
REENTRANCE_LOCK();
status = phLibNfc_Ndef_Read(handle, &trustednfc_jni_ndef_rw,
phLibNfc_Ndef_EBegin,
trustednfc_jni_tag_rw_callback,
(void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
buf = e->NewByteArray(trustednfc_jni_ndef_rw.length);
e->SetByteArrayRegion(buf, 0, trustednfc_jni_ndef_rw.length,
(jbyte *)trustednfc_jni_ndef_rw.buffer);
clean_and_return:
CONCURRENCY_UNLOCK();
return buf;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doWrite(JNIEnv *e,
jobject o, jbyteArray buf)
{
NFCSTATUS status;
jboolean result = JNI_FALSE;
phLibNfc_Handle handle = trustednfc_jni_get_nfc_tag_handle(e, o);
CONCURRENCY_LOCK();
trustednfc_jni_ndef_rw.length = (uint32_t)e->GetArrayLength(buf);
trustednfc_jni_ndef_rw.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL);
LOGD("phLibNfc_Ndef_Write()");
LOGD("Ndef Handle :0x%x\n",handle);
LOGD("Ndef buffer length : %d", trustednfc_jni_ndef_rw.length);
REENTRANCE_LOCK();
status = phLibNfc_Ndef_Write(handle, &trustednfc_jni_ndef_rw,trustednfc_jni_tag_rw_callback, (void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
if (result != JNI_TRUE)
{
e->ReleaseByteArrayElements(buf, (jbyte *)trustednfc_jni_ndef_rw.buffer, JNI_ABORT);
}
CONCURRENCY_UNLOCK();
return result;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doConnect(JNIEnv *e,
jobject o)
{
phLibNfc_Handle handle = 0;
jclass cls;
jfieldID f;
NFCSTATUS status;
jboolean result = JNI_FALSE;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_nfc_tag_handle(e, o);
LOGD("phLibNfc_RemoteDev_Connect(RW)");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Connect(handle, trustednfc_jni_connect_callback,(void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
/* Connect Status */
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
CONCURRENCY_UNLOCK();
return result;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doDisconnect(JNIEnv *e, jobject o)
{
phLibNfc_Handle handle = 0;
jclass cls;
jfieldID f;
NFCSTATUS status;
jboolean result = JNI_FALSE;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_nfc_tag_handle(e, o);
/* Disconnect */
LOGI("Disconnecting from target (handle = 0x%x)", handle);
/* Presence Check */
do
{
// usleep(100000);
LOGD("phLibNfc_RemoteDev_CheckPresence()");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_CheckPresence(handle,trustednfc_jni_presence_check_callback,(void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* TODO: handle error */
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
}
while(trustednfc_jni_cb_status == NFCSTATUS_SUCCESS);
LOGI("Tag removed from the RF Field\n");
LOGD("phLibNfc_RemoteDev_Disconnect()");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE,
trustednfc_jni_disconnect_callback, (void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
trustednfc_jni_restart_discovery(trustednfc_jni_get_nat_ext(e));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
/* Connect Status */
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
CONCURRENCY_UNLOCK();
return result;
}
static void com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doAsyncDisconnect(JNIEnv *e, jobject o)
{
NFCSTATUS status;
handle = trustednfc_jni_get_nfc_tag_handle(e, o);
/* Disconnect */
LOGI("Disconnecting Asynchronously from target (handle = 0x%x)", handle);
LOGD("phLibNfc_RemoteDev_CheckPresence(async)");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_CheckPresence(handle,trustednfc_jni_async_presence_check_callback,(void*)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_CheckPresence(async) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto disconnect_on_failure;
}
LOGD("phLibNfc_RemoteDev_CheckPresence(async) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
return;
disconnect_on_failure:
LOGD("phLibNfc_RemoteDev_Disconnect(async)");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE, trustednfc_jni_async_disconnect_callback,(void*)handle);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
trustednfc_jni_restart_discovery(trustednfc_jni_get_nat_ext(e));
return;
}
LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
}
static jbyteArray com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doTransceive(JNIEnv *e,
jobject o, jbyteArray data)
{
uint8_t offset = 0;
uint8_t *buf;
uint32_t buflen;
phLibNfc_sTransceiveInfo_t transceive_info;
jbyteArray result = NULL;
int res;
jstring type = trustednfc_jni_get_nfc_tag_type(e, o);
const char* str = e->GetStringUTFChars(type, 0);
phLibNfc_Handle handle = trustednfc_jni_get_nfc_tag_handle(e, o);
NFCSTATUS status;
CONCURRENCY_LOCK();
LOGD("Tag %s\n", str);
buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
buflen = (uint32_t)e->GetArrayLength(data);
/* Prepare transceive info structure */
if((res = strcmp(str, "Mifare1K") == 0) || (res = strcmp(str, "Mifare4K") == 0) || (res = strcmp(str, "MifareUL") == 0))
{
offset = 2;
transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
transceive_info.addr = (uint8_t)buf[1];
}
else if((res = strcmp(str, "Felica") == 0))
{
transceive_info.cmd.FelCmd = phNfc_eFelica_Raw;
transceive_info.addr = 0;
}
else if((res = strcmp(str, "Iso14443") == 0))
{
transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
transceive_info.addr = 0;
}
else if((res = strcmp(str, "Jewel") == 0))
{
transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw;
transceive_info.addr = 0;
}
/* Free memory */
e->ReleaseStringUTFChars(type, str);
transceive_info.sSendData.buffer = buf + offset;
transceive_info.sSendData.length = buflen - offset;
transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
transceive_info.sRecvData.length = 1024;
if(transceive_info.sRecvData.buffer == NULL)
{
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Transceive()");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
trustednfc_jni_transceive_callback, (void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
/* Copy results back to Java */
result = e->NewByteArray(trustednfc_jni_transceive_buffer->length);
if(result != NULL)
{
e->SetByteArrayRegion(result, 0,
trustednfc_jni_transceive_buffer->length,
(jbyte *)trustednfc_jni_transceive_buffer->buffer);
}
clean_and_return:
if(transceive_info.sRecvData.buffer != NULL)
{
free(transceive_info.sRecvData.buffer);
}
e->ReleaseByteArrayElements(data,
(jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
CONCURRENCY_UNLOCK();
return result;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeNfcTag_checkNDEF(JNIEnv *e, jobject o)
{
phLibNfc_Handle handle = 0;
NFCSTATUS status;
jboolean result = JNI_FALSE;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_nfc_tag_handle(e, o);
LOGD("phLibNfc_Ndef_CheckNdef()");
REENTRANCE_LOCK();
status = phLibNfc_Ndef_CheckNdef(handle, trustednfc_jni_checkndef_callback,(void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_tag_sem);
if (trustednfc_jni_is_ndef == 0)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
CONCURRENCY_UNLOCK();
return result;
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"doConnect", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doConnect},
{"doDisconnect", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doDisconnect},
{"doAsyncDisconnect", "()V",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doAsyncDisconnect},
{"doTransceive", "([B)[B",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doTransceive},
{"checkNDEF", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_checkNDEF},
{"doRead", "()[B",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doRead},
{"doWrite", "([B)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeNfcTag_doWrite},
};
int register_com_trustedlogic_trustednfc_android_internal_NativeNfcTag(JNIEnv *e)
{
if(sem_init(&trustednfc_jni_tag_sem, 0, 0) == -1)
return -1;
return jniRegisterNativeMethods(e,
"com/trustedlogic/trustednfc/android/internal/NativeNfcTag",
gMethods, NELEM(gMethods));
}
} // namespace android
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : com_trustedlogic_trustednfc_android_internal_NativeP2pDevice.c
* Original-Author : Trusted Logic S.A. (Daniel Tomas)
* Created : 04-03-2010
*/
#include <semaphore.h>
#include "trustednfc_jni.h"
static sem_t trustednfc_jni_peer_sem;
static NFCSTATUS trustednfc_jni_cb_status = NFCSTATUS_FAILED;
uint8_t trustednfc_jni_p2p_presence_check = 0;
namespace android {
static phNfc_sData_t sGeneralBytes;
/*
* Callbacks
*/
static void trustednfc_jni_presence_check_callback(void* pContext, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_presence_check_callback", status);
if(status != NFCSTATUS_SUCCESS)
{
trustednfc_jni_p2p_presence_check = 1;
}
sem_post(&trustednfc_jni_peer_sem);
}
static void trustednfc_jni_connect_callback(void *pContext,
phLibNfc_Handle hRemoteDev,
phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_connect_callback", status);
if(status == NFCSTATUS_SUCCESS)
{
sGeneralBytes.length = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;
sGeneralBytes.buffer = (uint8_t*)malloc(psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length);
sGeneralBytes.buffer = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo;
}
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_peer_sem);
}
static void trustednfc_jni_disconnect_callback(void *pContext,
phLibNfc_Handle hRemoteDev, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_disconnect_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_peer_sem);
}
static void trustednfc_jni_receive_callback(void *pContext,
phNfc_sData_t *data, NFCSTATUS status)
{
phNfc_sData_t **ptr = (phNfc_sData_t **)pContext;
LOG_CALLBACK("trustednfc_jni_receive_callback", status);
trustednfc_jni_cb_status = status;
if(status == NFCSTATUS_SUCCESS)
*ptr = data;
else
*ptr = NULL;
sem_post(&trustednfc_jni_peer_sem);
}
static void trustednfc_jni_send_callback(void *pContext, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_send_callback", status);
trustednfc_jni_cb_status = status;
sem_post(&trustednfc_jni_peer_sem);
}
/*
* Functions
*/
static phNfc_sData_t *trustednfc_jni_transceive_buffer;
static void trustednfc_jni_transceive_callback(void *pContext,
phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
{
LOG_CALLBACK("trustednfc_jni_transceive_callback", status);
trustednfc_jni_cb_status = status;
trustednfc_jni_transceive_buffer = pResBuffer;
sem_post(&trustednfc_jni_peer_sem);
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doConnect(JNIEnv *e, jobject o)
{
phLibNfc_Handle handle = 0;
NFCSTATUS status;
jboolean result = JNI_FALSE;
jclass target_cls = NULL;
jobject tag;
jmethodID ctor;
jfieldID f;
jbyteArray generalBytes = NULL;
int i;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_p2p_device_handle(e, o);
LOGD("phLibNfc_RemoteDev_Connect(P2P)");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Connect(handle, trustednfc_jni_connect_callback, (void*)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Connect(P2P) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Connect(P2P) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_peer_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
/* Set General Bytes */
target_cls = e->GetObjectClass(o);
f = e->GetFieldID(target_cls, "mGeneralBytes", "[B");
LOGD("General Bytes Length = %d", sGeneralBytes.length);
LOGD("General Bytes =");
for(i=0;i<sGeneralBytes.length;i++)
{
LOGD("0x%02x ", sGeneralBytes.buffer[i]);
}
generalBytes = e->NewByteArray(sGeneralBytes.length);
e->SetByteArrayRegion(generalBytes, 0,
sGeneralBytes.length,
(jbyte *)sGeneralBytes.buffer);
e->SetObjectField(o, f, generalBytes);
result = JNI_TRUE;
clean_and_return:
CONCURRENCY_UNLOCK();
return result;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doDisconnect(JNIEnv *e,
jobject o)
{
phLibNfc_Handle handle = 0;
jboolean result = JNI_FALSE;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_p2p_device_handle(e, o);
/* Disconnect */
LOGD("Disconnecting from target (handle = 0x%x)", handle);
/* Presence Check */
while(trustednfc_jni_p2p_presence_check == 0)
{
REENTRANCE_LOCK();
phLibNfc_RemoteDev_CheckPresence(handle,trustednfc_jni_presence_check_callback,(void *)e);
REENTRANCE_UNLOCK();
/* Wait for callback response */
sem_wait(&trustednfc_jni_peer_sem);
}
trustednfc_jni_p2p_presence_check = 0;
LOGD("Target removed from the RF Field\n");
REENTRANCE_LOCK();
phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE,
trustednfc_jni_disconnect_callback, (void *)e);
REENTRANCE_UNLOCK();
/* Wait for callback response */
sem_wait(&trustednfc_jni_peer_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
CONCURRENCY_UNLOCK();
return result;
}
static jbyteArray com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doTransceive(JNIEnv *e,
jobject o, jbyteArray data)
{
NFCSTATUS status;
uint8_t offset = 2;
uint8_t *buf;
uint32_t buflen;
phLibNfc_sTransceiveInfo_t transceive_info;
jbyteArray result = NULL;
phLibNfc_Handle handle = trustednfc_jni_get_p2p_device_handle(e, o);
CONCURRENCY_LOCK();
/* Transceive*/
LOGD("Transceive data to target (handle = 0x%x)", handle);
buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
buflen = (uint32_t)e->GetArrayLength(data);
LOGD("Buffer Length = %d\n", buflen);
transceive_info.sSendData.buffer = buf; //+ offset;
transceive_info.sSendData.length = buflen; //- offset;
transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
transceive_info.sRecvData.length = 1024;
if(transceive_info.sRecvData.buffer == NULL)
{
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Transceive(P2P)");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, trustednfc_jni_transceive_callback, (void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Transceive(P2P) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Transceive(P2P) returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_peer_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
/* Copy results back to Java */
result = e->NewByteArray(trustednfc_jni_transceive_buffer->length);
if(result != NULL)
e->SetByteArrayRegion(result, 0,
trustednfc_jni_transceive_buffer->length,
(jbyte *)trustednfc_jni_transceive_buffer->buffer);
clean_and_return:
LOGD("P2P Transceive status = 0x%08x",trustednfc_jni_cb_status);
if(transceive_info.sRecvData.buffer != NULL)
free(transceive_info.sRecvData.buffer);
e->ReleaseByteArrayElements(data,
(jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
CONCURRENCY_UNLOCK();
return result;
}
static jbyteArray com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doReceive(
JNIEnv *e, jobject o)
{
NFCSTATUS status;
struct timespec ts;
phLibNfc_Handle handle;
jbyteArray buf = NULL;
static phNfc_sData_t *data;
CONCURRENCY_LOCK();
handle = trustednfc_jni_get_p2p_device_handle(e, o);
/* Receive */
LOGD("phLibNfc_RemoteDev_Receive()");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Receive(handle, trustednfc_jni_receive_callback,(void *)&data);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Receive() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Receive() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
if(sem_wait(&trustednfc_jni_peer_sem) == -1)
{
goto clean_and_return;
}
if(data == NULL)
{
goto clean_and_return;
}
buf = e->NewByteArray(data->length);
e->SetByteArrayRegion(buf, 0, data->length, (jbyte *)data->buffer);
clean_and_return:
CONCURRENCY_UNLOCK();
return buf;
}
static jboolean com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doSend(
JNIEnv *e, jobject o, jbyteArray buf)
{
NFCSTATUS status;
phNfc_sData_t data;
jboolean result = JNI_FALSE;
phLibNfc_Handle handle = trustednfc_jni_get_p2p_device_handle(e, o);
CONCURRENCY_LOCK();
/* Send */
LOGD("Send data to the Initiator (handle = 0x%x)", handle);
data.length = (uint32_t)e->GetArrayLength(buf);
data.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL);
LOGD("phLibNfc_RemoteDev_Send()");
REENTRANCE_LOCK();
status = phLibNfc_RemoteDev_Send(handle, &data, trustednfc_jni_send_callback,(void *)e);
REENTRANCE_UNLOCK();
if(status != NFCSTATUS_PENDING)
{
LOGE("phLibNfc_RemoteDev_Send() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
goto clean_and_return;
}
LOGD("phLibNfc_RemoteDev_Send() returned 0x%04x[%s]", status, trustednfc_jni_get_status_name(status));
/* Wait for callback response */
sem_wait(&trustednfc_jni_peer_sem);
if(trustednfc_jni_cb_status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
result = JNI_TRUE;
clean_and_return:
if (result != JNI_TRUE)
{
e->ReleaseByteArrayElements(buf, (jbyte *)data.buffer, JNI_ABORT);
}
CONCURRENCY_UNLOCK();
return result;
}
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
{"doConnect", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doConnect},
{"doDisconnect", "()Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doDisconnect},
{"doTransceive", "([B)[B",
(void *)com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doTransceive},
{"doReceive", "()[B",
(void *)com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doReceive},
{"doSend", "([B)Z",
(void *)com_trustedlogic_trustednfc_android_internal_NativeP2pDevice_doSend},
};
int register_com_trustedlogic_trustednfc_android_internal_NativeP2pDevice(JNIEnv *e)
{
if(sem_init(&trustednfc_jni_peer_sem, 0, 0) == -1)
return -1;
return jniRegisterNativeMethods(e,
"com/trustedlogic/trustednfc/android/internal/NativeP2pDevice",
gMethods, NELEM(gMethods));
}
} // namepspace android
This diff is collapsed.
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* File : trustednfc_jni.h
* Original-Author : Trusted Logic S.A. (Jeremie Corbier)
* Created : 26-08-2009
*/
#ifndef __TRUSTEDNFC_JNI_H__
#define __TRUSTEDNFC_JNI_H__
#define LOG_TAG "Trusted_NFC_JNI"
#include <JNIHelp.h>
#include <jni.h>
#include <pthread.h>
extern "C" {
#include <phNfcStatus.h>
#include <phNfcTypes.h>
#include <phNfcIoctlCode.h>
#include <phLibNfc.h>
#include <phDal4Nfc_messageQueueLib.h>
}
#include <cutils/properties.h> // for property_get
/* Discovery modes -- keep in sync with NFCManager.DISCOVERY_MODE_* */
#define DISCOVERY_MODE_TAG_READER 0
#define DISCOVERY_MODE_NFCIP1 1
#define DISCOVERY_MODE_CARD_EMULATION 2
#define DISCOVERY_MODE_TABLE_SIZE 3
#define DISCOVERY_MODE_DISABLED 0
#define DISCOVERY_MODE_ENABLED 1
#define MODE_P2P_TARGET 0
#define MODE_P2P_INITIATOR 1
/* Properties values */
#define PROPERTY_LLCP_LTO 0
#define PROPERTY_LLCP_MIU 1
#define PROPERTY_LLCP_WKS 2
#define PROPERTY_LLCP_OPT 3
#define PROPERTY_NFC_DISCOVERY_A 4
#define PROPERTY_NFC_DISCOVERY_B 5
#define PROPERTY_NFC_DISCOVERY_F 6
#define PROPERTY_NFC_DISCOVERY_15693 7
#define PROPERTY_NFC_DISCOVERY_NCFIP 8
/* Error codes */
#define ERROR_BUFFER_TOO_SMALL -12
#define ERROR_INSUFFICIENT_RESOURCES -9
/* Name strings for target types */
#define TARGET_TYPE_ISO14443 "Iso14443"
#define TARGET_TYPE_MIFARE_UL "MifareUL"
#define TARGET_TYPE_MIFARE_1K "Mifare1K"
#define TARGET_TYPE_MIFARE_4K "Mifare4K"
#define TARGET_TYPE_MIFARE_DESFIRE "MifareDESFIRE"
#define TARGET_TYPE_MIFARE_UNKNOWN "Unknown Mifare"
#define TARGET_TYPE_FELICA "Felica"
#define TARGET_TYPE_JEWEL "Jewel"
#define TARGET_TYPE_UNKNOWN "Unknown Type"
/* Utility macros for logging */
#define GET_LEVEL(status) ((status)==NFCSTATUS_SUCCESS)?ANDROID_LOG_DEBUG:ANDROID_LOG_WARN
#define LOG_CALLBACK(funcName, status) LOG_PRI(GET_LEVEL(status), LOG_TAG, "Callback: %s() - status=0x%04x[%s]", funcName, status, trustednfc_jni_get_status_name(status));
struct trustednfc_jni_native_data
{
/* Thread handle */
pthread_t thread;
int running;
/* Our VM */
JavaVM *vm;
int env_version;
/* Reference to the NFCManager instance */
jobject manager;
/* Cached objects */
jobject cached_NfcTag;
jobject cached_P2pDevice;
/* Target discovery configuration */
int discovery_modes_state[DISCOVERY_MODE_TABLE_SIZE];
phLibNfc_sADD_Cfg_t discovery_cfg;
phLibNfc_Registry_Info_t registry_info;
/* Secure Element selected */
int seId;
/* LLCP params */
int lto;
int miu;
int wks;
int opt;
/* Tag detected */
jobject tag;
/* Lib Status */
NFCSTATUS status;
};
typedef struct trustednfc_jni_native_monitor
{
/* Mutex protecting native library against reentrance */
pthread_mutex_t reentrance_mutex;
/* Mutex protecting native library against concurrency */
pthread_mutex_t concurrency_mutex;
} trustednfc_jni_native_monitor_t;
/* TODO: treat errors and add traces */
#define REENTRANCE_LOCK() pthread_mutex_lock(&trustednfc_jni_get_monitor()->reentrance_mutex)
#define REENTRANCE_UNLOCK() pthread_mutex_unlock(&trustednfc_jni_get_monitor()->reentrance_mutex)
#define CONCURRENCY_LOCK() pthread_mutex_lock(&trustednfc_jni_get_monitor()->concurrency_mutex)
#define CONCURRENCY_UNLOCK() pthread_mutex_unlock(&trustednfc_jni_get_monitor()->concurrency_mutex)
namespace android {
const char* trustednfc_jni_get_status_name(NFCSTATUS status);
int trustednfc_jni_cache_object(JNIEnv *e, const char *clsname,
jobject *cached_obj);
struct trustednfc_jni_native_data* trustednfc_jni_get_nat(JNIEnv *e, jobject o);
struct trustednfc_jni_native_data* trustednfc_jni_get_nat_ext(JNIEnv *e);
trustednfc_jni_native_monitor_t* trustednfc_jni_init_monitor(void);
trustednfc_jni_native_monitor_t* trustednfc_jni_get_monitor(void);
/* P2P */
phLibNfc_Handle trustednfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o);
jshort trustednfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o);
/* TAG */
phLibNfc_Handle trustednfc_jni_get_nfc_tag_handle(JNIEnv *e, jobject o);
jstring trustednfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o);
/* LLCP */
phLibNfc_Handle trustednfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o);
int register_com_trustedlogic_trustednfc_android_internal_NativeNfcManager(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_internal_NativeNfcTag(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_internal_NativeNdefTag(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_NdefMessage(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_NdefRecord(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_internal_NativeP2pDevice(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket(JNIEnv *e);
int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket(JNIEnv *e);
} // namespace android
#endif
res/drawable-hdpi/bt_incomming_file_notification.png

1.47 KB

res/drawable-hdpi/bt_share.png

6.21 KB

res/drawable-hdpi/ic_launcher_folder_bluetooth.png

5.22 KB

res/drawable-hdpi/icon.png

6.21 KB

res/drawable-mdpi/bt_incomming_file_notification.png

964 Bytes

res/drawable-mdpi/bt_share.png

3.57 KB

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment