diff options
author | Steve Kondik <shade@chemlab.org> | 2012-11-18 22:49:42 -0800 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2012-11-21 21:08:23 +0000 |
commit | 6a645b3241be2ba27b2b38f0cd68ad7e6fafafa5 (patch) | |
tree | 4db310cf6ff3ab0dbb5407ffa13235b1d834be3a /nci/jni/NativeLlcpConnectionlessSocket.cpp | |
parent | 3d402b5b2bd83007c5bffa4d40977e3314da4a91 (diff) | |
parent | eba57c26732d3313befb574af85770452d841b87 (diff) | |
download | packages_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.cpp | 311 |
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 |