summaryrefslogtreecommitdiffstats
path: root/nci/jni/NativeLlcpConnectionlessSocket.cpp
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2012-11-18 22:49:42 -0800
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-11-21 21:08:23 +0000
commit6a645b3241be2ba27b2b38f0cd68ad7e6fafafa5 (patch)
tree4db310cf6ff3ab0dbb5407ffa13235b1d834be3a /nci/jni/NativeLlcpConnectionlessSocket.cpp
parent3d402b5b2bd83007c5bffa4d40977e3314da4a91 (diff)
parenteba57c26732d3313befb574af85770452d841b87 (diff)
downloadpackages_apps_nfc-6a645b3241be2ba27b2b38f0cd68ad7e6fafafa5.zip
packages_apps_nfc-6a645b3241be2ba27b2b38f0cd68ad7e6fafafa5.tar.gz
packages_apps_nfc-6a645b3241be2ba27b2b38f0cd68ad7e6fafafa5.tar.bz2
Merge branch 'jb-mr1-release' of https://android.googlesource.com/platform/packages/apps/Nfc into HEAD
Conflicts: nxp/jni/com_android_nfc_NativeNfcManager.cpp Change-Id: Ic84af6ad1cda79984f40e9fc464d2cbaa994b89a
Diffstat (limited to 'nci/jni/NativeLlcpConnectionlessSocket.cpp')
-rw-r--r--nci/jni/NativeLlcpConnectionlessSocket.cpp311
1 files changed, 311 insertions, 0 deletions
diff --git a/nci/jni/NativeLlcpConnectionlessSocket.cpp b/nci/jni/NativeLlcpConnectionlessSocket.cpp
new file mode 100644
index 0000000..ecc57e3
--- /dev/null
+++ b/nci/jni/NativeLlcpConnectionlessSocket.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2012 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 "OverrideLog.h"
+#include "NfcJniUtil.h"
+#include "JavaClassConstants.h"
+extern "C"
+{
+ #include "nfa_api.h"
+ #include "nfa_p2p_api.h"
+}
+
+
+namespace android
+{
+
+
+/*****************************************************************************
+**
+** private variables and functions
+**
+*****************************************************************************/
+static sem_t sConnlessRecvSem;
+static jboolean sConnlessRecvWaitingForData = JNI_FALSE;
+static uint8_t* sConnlessRecvBuf = NULL;
+static uint32_t sConnlessRecvLen = 0;
+static uint32_t sConnlessRecvRemoteSap = 0;
+
+
+/*******************************************************************************
+**
+** Function: nativeLlcpConnectionlessSocket_doSendTo
+**
+** Description: Send data to peer.
+** e: JVM environment.
+** o: Java object.
+** nsap: service access point.
+** data: buffer for data.
+**
+** Returns: True if ok.
+**
+*******************************************************************************/
+static jboolean nativeLlcpConnectionlessSocket_doSendTo (JNIEnv *e, jobject o, jint nsap, jbyteArray data)
+{
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ jint handle = 0;
+ uint8_t* buf = NULL;
+ uint32_t len = 0;
+ jclass c = NULL;
+ jfieldID f = NULL;
+
+ ALOGD ("%s: nsap = %d", __FUNCTION__, nsap);
+
+ c = e->GetObjectClass (o);
+ f = e->GetFieldID (c, "mHandle", "I");
+ handle = e->GetIntField (o, f);
+
+ buf = (uint8_t*) e->GetByteArrayElements (data, NULL);
+ len = (uint32_t) e->GetArrayLength (data);
+
+ ALOGD ("NFA_P2pSendUI: len = %d", len);
+ status = NFA_P2pSendUI ((tNFA_HANDLE) handle, nsap, len, buf);
+
+ ALOGD ("%s: NFA_P2pSendUI done, status = %d", __FUNCTION__, status);
+ if (status != NFA_STATUS_OK)
+ {
+ ALOGE ("%s: NFA_P2pSendUI failed, status = %d", __FUNCTION__, status);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+
+/*******************************************************************************
+**
+** Function: nativeLlcpConnectionlessSocket_receiveData
+**
+** Description: Receive data from the stack.
+** data: buffer contains data.
+** len: length of data.
+** remoteSap: remote service access point.
+**
+** Returns: None
+**
+*******************************************************************************/
+void nativeLlcpConnectionlessSocket_receiveData (uint8_t* data, uint32_t len, uint32_t remoteSap)
+{
+ ALOGD ("%s: waiting for data = %d, len = %d", __FUNCTION__, sConnlessRecvWaitingForData, len);
+
+ // Sanity...
+ if (sConnlessRecvLen < len)
+ {
+ len = sConnlessRecvLen;
+ }
+
+ if (sConnlessRecvWaitingForData)
+ {
+ sConnlessRecvWaitingForData = JNI_FALSE;
+ sConnlessRecvLen = len;
+ memcpy (sConnlessRecvBuf, data, len);
+ sConnlessRecvRemoteSap = remoteSap;
+
+ sem_post (&sConnlessRecvSem);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: connectionlessCleanup
+**
+** Description: Free resources.
+**
+** Returns: None
+**
+*******************************************************************************/
+static jobject connectionlessCleanup ()
+{
+ sConnlessRecvWaitingForData = JNI_FALSE;
+ sConnlessRecvLen = 0;
+ if (sConnlessRecvBuf != NULL)
+ {
+ free (sConnlessRecvBuf);
+ sConnlessRecvBuf = NULL;
+ }
+ return NULL;
+}
+
+
+/*******************************************************************************
+**
+** Function: nativeLlcpConnectionlessSocket_abortWait
+**
+** Description: Abort current operation and unblock threads.
+**
+** Returns: None
+**
+*******************************************************************************/
+void nativeLlcpConnectionlessSocket_abortWait ()
+{
+ sem_post (&sConnlessRecvSem);
+}
+
+
+/*******************************************************************************
+**
+** Function: nativeLlcpConnectionlessSocket_doReceiveFrom
+**
+** Description: Receive data from a peer.
+** e: JVM environment.
+** o: Java object.
+** linkMiu: max info unit
+**
+** Returns: LlcpPacket Java object.
+**
+*******************************************************************************/
+static jobject nativeLlcpConnectionlessSocket_doReceiveFrom (JNIEnv *e, jobject o, jint linkMiu)
+{
+ jbyteArray receivedData = NULL;
+ jobject llcpPacket = NULL;
+ jclass clsLlcpPacket = NULL;
+ jfieldID f = NULL;
+
+ ALOGD ("%s: linkMiu = %d", __FUNCTION__, linkMiu);
+
+ if (sConnlessRecvWaitingForData != JNI_FALSE)
+ {
+ ALOGD ("%s: Already waiting for incoming data", __FUNCTION__);
+ return NULL;
+ }
+
+ sConnlessRecvBuf = (uint8_t*) malloc (linkMiu);
+ if (sConnlessRecvBuf == NULL)
+ {
+ ALOGD ("%s: Failed to allocate %d bytes memory buffer", __FUNCTION__, linkMiu);
+ return NULL;
+ }
+ sConnlessRecvLen = linkMiu;
+
+ // Create the write semaphore
+ if (sem_init (&sConnlessRecvSem, 0, 0) == -1)
+ {
+ ALOGE ("%s: semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno);
+ return connectionlessCleanup ();
+ }
+
+ sConnlessRecvWaitingForData = JNI_TRUE;
+
+ // Wait for sConnlessRecvSem completion status
+ if (sem_wait (&sConnlessRecvSem))
+ {
+ ALOGE ("%s: Failed to wait for write semaphore (errno=0x%08x)", __FUNCTION__, errno);
+ goto TheEnd;
+ }
+
+ // Create new LlcpPacket object
+ if (nfc_jni_cache_object (e, "com/android/nfc/LlcpPacket", &(llcpPacket)) == -1)
+ {
+ ALOGE ("%s: Find LlcpPacket class error", __FUNCTION__);
+ return connectionlessCleanup ();
+ }
+
+ // Get NativeConnectionless class object
+ clsLlcpPacket = e->GetObjectClass (llcpPacket);
+ if (e->ExceptionCheck ())
+ {
+ e->ExceptionClear();
+ ALOGE ("%s: Get Object class error", __FUNCTION__);
+ return connectionlessCleanup ();
+ }
+
+ // Set Llcp Packet remote SAP
+ f = e->GetFieldID (clsLlcpPacket, "mRemoteSap", "I");
+ e->SetIntField (llcpPacket, f, (jbyte) sConnlessRecvRemoteSap);
+
+ // Set Llcp Packet Buffer
+ ALOGD ("%s: Received Llcp packet buffer size = %d\n", __FUNCTION__, sConnlessRecvLen);
+ f = e->GetFieldID (clsLlcpPacket, "mDataBuffer", "[B");
+ receivedData = e->NewByteArray (sConnlessRecvLen);
+ e->SetByteArrayRegion (receivedData, 0, sConnlessRecvLen, (jbyte*) sConnlessRecvBuf);
+ e->SetObjectField (llcpPacket, f, receivedData);
+
+TheEnd:
+ connectionlessCleanup ();
+ if (sem_destroy (&sConnlessRecvSem))
+ {
+ ALOGE ("%s: Failed to destroy sConnlessRecvSem semaphore (errno=0x%08x)", __FUNCTION__, errno);
+ }
+ return llcpPacket;
+}
+
+
+/*******************************************************************************
+**
+** Function: nativeLlcpConnectionlessSocket_doClose
+**
+** Description: Close socket.
+** e: JVM environment.
+** o: Java object.
+**
+** Returns: True if ok.
+**
+*******************************************************************************/
+static jboolean nativeLlcpConnectionlessSocket_doClose (JNIEnv *e, jobject o)
+{
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ jint handle = 0;
+ jclass c = NULL;
+ jfieldID f = NULL;
+
+ ALOGD ("%s", __FUNCTION__);
+
+ c = e->GetObjectClass (o);
+ f = e->GetFieldID (c, "mHandle", "I");
+ handle = e->GetIntField (o, f);
+
+ status = NFA_P2pDisconnect ((tNFA_HANDLE) handle, FALSE);
+ if (status != NFA_STATUS_OK)
+ {
+ ALOGE ("%s: disconnect failed, status = %d", __FUNCTION__, status);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+
+/*****************************************************************************
+**
+** Description: JNI functions
+**
+*****************************************************************************/
+static JNINativeMethod gMethods[] =
+{
+ {"doSendTo", "(I[B)Z", (void*) nativeLlcpConnectionlessSocket_doSendTo},
+ {"doReceiveFrom", "(I)Lcom/android/nfc/LlcpPacket;", (void*) nativeLlcpConnectionlessSocket_doReceiveFrom},
+ {"doClose", "()Z", (void*) nativeLlcpConnectionlessSocket_doClose},
+};
+
+
+/*******************************************************************************
+**
+** Function: register_com_android_nfc_NativeLlcpConnectionlessSocket
+**
+** Description: Regisgter JNI functions with Java Virtual Machine.
+** e: Environment of JVM.
+**
+** Returns: Status of registration.
+**
+*******************************************************************************/
+int register_com_android_nfc_NativeLlcpConnectionlessSocket (JNIEnv *e)
+{
+ return jniRegisterNativeMethods (e, gNativeLlcpConnectionlessSocketClassName, gMethods, NELEM(gMethods));
+}
+
+
+} // android namespace