summaryrefslogtreecommitdiffstats
path: root/nxp/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxp/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp')
-rw-r--r--nxp/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/nxp/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp b/nxp/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp
new file mode 100644
index 0000000..86607b5
--- /dev/null
+++ b/nxp/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include "com_android_nfc.h"
+
+namespace android {
+
+/*
+ * Callbacks
+ */
+
+static void nfc_jni_receive_callback(void* pContext, uint8_t ssap, NFCSTATUS status)
+{
+ struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
+ LOG_CALLBACK("nfc_jni_receiveFrom_callback", status);
+
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ pCallbackData->pContext = (void*)ssap;
+ TRACE("RECEIVE UI_FRAME FROM SAP %d OK \n", ssap);
+ }
+
+ /* Report the callback status and wake up the caller */
+ pCallbackData->status = status;
+ sem_post(&pCallbackData->sem);
+}
+
+static void nfc_jni_send_callback(void *pContext, NFCSTATUS status)
+{
+ struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
+ LOG_CALLBACK("nfc_jni_sendTo_callback", status);
+
+ /* Report the callback status and wake up the caller */
+ pCallbackData->status = status;
+ sem_post(&pCallbackData->sem);
+}
+
+/*
+* Methods
+*/
+static jboolean com_android_nfc_NativeLlcpConnectionlessSocket_doSendTo(JNIEnv *e, jobject o, jint nsap, jbyteArray data)
+{
+ NFCSTATUS ret;
+ struct timespec ts;
+ phLibNfc_Handle hRemoteDevice;
+ phLibNfc_Handle hLlcpSocket;
+ phNfc_sData_t sSendBuffer = {NULL, 0};
+ struct nfc_jni_callback_data cb_data;
+ jboolean result = JNI_FALSE;
+
+ /* Retrieve handles */
+ hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o);
+ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o);
+
+ /* Create the local semaphore */
+ if (!nfc_cb_data_init(&cb_data, NULL))
+ {
+ goto clean_and_return;
+ }
+
+ sSendBuffer.buffer = (uint8_t*)e->GetByteArrayElements(data, NULL);
+ sSendBuffer.length = (uint32_t)e->GetArrayLength(data);
+
+ TRACE("phLibNfc_Llcp_SendTo()");
+ REENTRANCE_LOCK();
+ ret = phLibNfc_Llcp_SendTo(hRemoteDevice,
+ hLlcpSocket,
+ nsap,
+ &sSendBuffer,
+ nfc_jni_send_callback,
+ (void*)&cb_data);
+ REENTRANCE_UNLOCK();
+ if(ret != NFCSTATUS_PENDING)
+ {
+ ALOGE("phLibNfc_Llcp_SendTo() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
+ goto clean_and_return;
+ }
+ TRACE("phLibNfc_Llcp_SendTo() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
+
+ /* Wait for callback response */
+ if(sem_wait(&cb_data.sem))
+ {
+ ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ goto clean_and_return;
+ }
+
+ if(cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+ result = JNI_TRUE;
+
+clean_and_return:
+ if (sSendBuffer.buffer != NULL)
+ {
+ e->ReleaseByteArrayElements(data, (jbyte*)sSendBuffer.buffer, JNI_ABORT);
+ }
+ nfc_cb_data_deinit(&cb_data);
+ return result;
+}
+
+static jobject com_android_nfc_NativeLlcpConnectionlessSocket_doReceiveFrom(JNIEnv *e, jobject o, jint linkMiu)
+{
+ NFCSTATUS ret;
+ struct timespec ts;
+ uint8_t ssap;
+ jobject llcpPacket = NULL;
+ phLibNfc_Handle hRemoteDevice;
+ phLibNfc_Handle hLlcpSocket;
+ phNfc_sData_t sReceiveBuffer;
+ jclass clsLlcpPacket;
+ jfieldID f;
+ jbyteArray receivedData = NULL;
+ struct nfc_jni_callback_data cb_data;
+
+ /* Create the local semaphore */
+ if (!nfc_cb_data_init(&cb_data, NULL))
+ {
+ goto clean_and_return;
+ }
+
+ /* Create new LlcpPacket object */
+ if(nfc_jni_cache_object(e,"com/android/nfc/LlcpPacket",&(llcpPacket)) == -1)
+ {
+ ALOGE("Find LlcpPacket class error");
+ goto clean_and_return;
+ }
+
+ /* Get NativeConnectionless class object */
+ clsLlcpPacket = e->GetObjectClass(llcpPacket);
+ if(e->ExceptionCheck())
+ {
+ ALOGE("Get Object class error");
+ goto clean_and_return;
+ }
+
+ /* Retrieve handles */
+ hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o);
+ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o);
+ TRACE("phLibNfc_Llcp_RecvFrom(), Socket Handle = 0x%02x, Link LIU = %d", hLlcpSocket, linkMiu);
+
+ sReceiveBuffer.buffer = (uint8_t*)malloc(linkMiu);
+ sReceiveBuffer.length = linkMiu;
+
+ REENTRANCE_LOCK();
+ ret = phLibNfc_Llcp_RecvFrom(hRemoteDevice,
+ hLlcpSocket,
+ &sReceiveBuffer,
+ nfc_jni_receive_callback,
+ &cb_data);
+ REENTRANCE_UNLOCK();
+ if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
+ {
+ ALOGE("phLibNfc_Llcp_RecvFrom() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
+ goto clean_and_return;
+ }
+ TRACE("phLibNfc_Llcp_RecvFrom() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
+
+ /* Wait for callback response */
+ if(sem_wait(&cb_data.sem))
+ {
+ ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ goto clean_and_return;
+ }
+
+ if(cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+ ssap = (uint32_t)cb_data.pContext;
+ TRACE("Data Received From SSAP = %d\n, length = %d", ssap, sReceiveBuffer.length);
+
+ /* Set Llcp Packet remote SAP */
+ f = e->GetFieldID(clsLlcpPacket, "mRemoteSap", "I");
+ e->SetIntField(llcpPacket, f,(jbyte)ssap);
+
+ /* Set Llcp Packet Buffer */
+ ALOGD("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);
+
+clean_and_return:
+ nfc_cb_data_deinit(&cb_data);
+ return llcpPacket;
+}
+
+static jboolean com_android_nfc_NativeLlcpConnectionlessSocket_doClose(JNIEnv *e, jobject o)
+{
+ NFCSTATUS ret;
+ phLibNfc_Handle hLlcpSocket;
+ TRACE("Close Connectionless socket");
+
+ /* Retrieve socket handle */
+ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o);
+
+ TRACE("phLibNfc_Llcp_Close()");
+ REENTRANCE_LOCK();
+ ret = phLibNfc_Llcp_Close(hLlcpSocket);
+ REENTRANCE_UNLOCK();
+ if(ret == NFCSTATUS_SUCCESS)
+ {
+ TRACE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
+ return TRUE;
+ }
+ else
+ {
+ ALOGE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
+ return FALSE;
+ }
+}
+
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gMethods[] =
+{
+ {"doSendTo", "(I[B)Z", (void *)com_android_nfc_NativeLlcpConnectionlessSocket_doSendTo},
+
+ {"doReceiveFrom", "(I)Lcom/android/nfc/LlcpPacket;", (void *)com_android_nfc_NativeLlcpConnectionlessSocket_doReceiveFrom},
+
+ {"doClose", "()Z", (void *)com_android_nfc_NativeLlcpConnectionlessSocket_doClose},
+};
+
+
+int register_com_android_nfc_NativeLlcpConnectionlessSocket(JNIEnv *e)
+{
+ return jniRegisterNativeMethods(e,
+ "com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",
+ gMethods, NELEM(gMethods));
+}
+
+} // android namespace