static jboolean com_NativeLlcpServiceSocket_doClose(JNIEnv *e, jobject o) { NFCSTATUS ret; phLibNfc_Handle hLlcpSocket; nfc_jni_native_monitor_t * pMonitor = nfc_jni_get_monitor(); TRACE("Close Service socket"); /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); pthread_mutex_lock(&pMonitor->incoming_socket_mutex); /* TODO: implement accept abort */ pthread_cond_broadcast(&pMonitor->incoming_socket_cond); pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Close(hLlcpSocket); REENTRANCE_UNLOCK(); if(ret == NFCSTATUS_SUCCESS) { TRACE("Close Service socket OK"); return TRUE; } else { LOGD("Close Service socket KO"); return FALSE; } }
static jint com_android_nfc_NativeLlcpSocket_doGetRemoteSocketRW(JNIEnv *e, jobject o) { NFCSTATUS ret; phLibNfc_Handle hLlcpSocket; phLibNfc_Llcp_sSocketOptions_t remoteSocketOption; /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(RW)"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_SocketGetRemoteOptions(hLlcpSocket, &remoteSocketOption); REENTRANCE_UNLOCK(); if(ret == NFCSTATUS_SUCCESS) { TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return remoteSocketOption.rw; } else { LOGW("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return 0; } }
static jboolean com_android_nfc_NativeLlcpSocket_doConnectBy(JNIEnv *e, jobject o, jstring sn) { NFCSTATUS ret; struct timespec ts; phNfc_sData_t serviceName = {0}; phLibNfc_Handle hRemoteDevice; phLibNfc_Handle hLlcpSocket; 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; } /* Service socket */ serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); serviceName.length = (uint32_t)e->GetStringUTFLength(sn); TRACE("phLibNfc_Llcp_ConnectByUri()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_ConnectByUri(hRemoteDevice, hLlcpSocket, &serviceName, nfc_jni_connect_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { ALOGE("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); goto clean_and_return; } TRACE("phLibNfc_Llcp_ConnectByUri() 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 (serviceName.buffer != NULL) { e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); } nfc_cb_data_deinit(&cb_data); return result; }
static jboolean com_android_nfc_NativeLlcpSocket_doSend(JNIEnv *e, jobject o, 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_Send()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Send(hRemoteDevice, hLlcpSocket, &sSendBuffer, nfc_jni_send_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { ALOGE("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); goto clean_and_return; } TRACE("phLibNfc_Llcp_Send() 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 jboolean com_android_nfc_NativeP2pDevice_doConnect(JNIEnv *e, jobject o) { uint32_t handle = nfc_jni_get_nfc_socket_handle(e, o); bool_t canUse = W_FALSE; jclass target_cls = NULL; jfieldID f; if(IS_SERVER_SOCKET(handle)) { canUse = isServerSoketValid(handle); } else if(IS_CLIENT_SOCKET(handle)) { canUse = isClientSoketValid(handle); } if(canUse==W_FALSE) { return JNI_FALSE; } target_cls = e->GetObjectClass(o); f = e->GetFieldID(target_cls, "mGeneralBytes", "[B"); jbyteArray generalBytes = NULL; generalBytes = e->NewByteArray(GENERAL_BYTES_LENGTH); e->SetByteArrayRegion(generalBytes, 0, GENERAL_BYTES_LENGTH, (jbyte *)GENERAL_BYTES); e->SetObjectField(o, f, generalBytes); return JNI_TRUE; }
static jint com_android_nfc_NativeLlcpSocket_doGetRemoteSocketMIU(JNIEnv *e, jobject o) { NFCSTATUS ret; phLibNfc_Handle hRemoteDevice; phLibNfc_Handle hLlcpSocket; phLibNfc_Llcp_sSocketOptions_t remoteSocketOption; /* Retrieve handles */ hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(MIU)"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_SocketGetRemoteOptions(hRemoteDevice, hLlcpSocket, &remoteSocketOption); REENTRANCE_UNLOCK(); if(ret == NFCSTATUS_SUCCESS) { TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(MIU) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return remoteSocketOption.miu; } else { ALOGW("phLibNfc_Llcp_SocketGetRemoteOptions(MIU) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return 0; } }
/******************************************************************************* ** ** Function: nativeLlcpSocket_doGetRemoteSocketMIU ** ** Description: Get peer's maximum information unit. ** e: JVM environment. ** o: Java object. ** ** Returns: Peer's maximum information unit. ** *******************************************************************************/ static jint nativeLlcpSocket_doGetRemoteSocketMIU (JNIEnv* e, jobject o) { ALOGD ("%s: enter", __FUNCTION__); PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); jint miu = PeerToPeer::getInstance().getRemoteMaxInfoUnit(jniHandle); ALOGD ("%s: exit", __FUNCTION__); return miu; }
/******************************************************************************* ** ** Function: nativeLlcpSocket_doClose ** ** Description: Close socket. ** e: JVM environment. ** o: Java object. ** ** Returns: True if ok. ** *******************************************************************************/ static jboolean nativeLlcpSocket_doClose(JNIEnv *e, jobject o) { ALOGD ("%s: enter", __FUNCTION__); PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); bool stat = PeerToPeer::getInstance().disconnectConnOriented (jniHandle); ALOGD ("%s: exit", __FUNCTION__); return stat ? JNI_TRUE : JNI_FALSE; }
/******************************************************************************* ** ** Function: nativeLlcpSocket_doGetRemoteSocketRW ** ** Description: Get peer's receive window size. ** e: JVM environment. ** o: Java object. ** ** Returns: Peer's receive window size. ** *******************************************************************************/ static jint nativeLlcpSocket_doGetRemoteSocketRW (JNIEnv* e, jobject o) { ALOGD ("%s: enter", __FUNCTION__); PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); jint rw = PeerToPeer::getInstance().getRemoteRecvWindow (jniHandle); ALOGD ("%s: exit", __FUNCTION__); return rw; }
/* * Methods */ static jboolean com_android_nfc_NativeLlcpSocket_doConnect(JNIEnv *e, jobject o, jint nSap) { NFCSTATUS ret; struct timespec ts; phLibNfc_Handle hRemoteDevice; phLibNfc_Handle hLlcpSocket; 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; } TRACE("phLibNfc_Llcp_Connect(%d)",nSap); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Connect(hRemoteDevice, hLlcpSocket, nSap, nfc_jni_connect_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { ALOGE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, nfc_jni_get_status_name(ret)); goto clean_and_return; } TRACE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, 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) { ALOGW("LLCP Connect request failed"); goto clean_and_return; } result = JNI_TRUE; clean_and_return: nfc_cb_data_deinit(&cb_data); return result; }
/******************************************************************************* ** ** Function: nativeLlcpSocket_doSend ** ** Description: Send data to peer. ** e: JVM environment. ** o: Java object. ** data: Buffer of data. ** ** Returns: True if sent ok. ** *******************************************************************************/ static jboolean nativeLlcpSocket_doSend (JNIEnv* e, jobject o, jbyteArray data) { ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter", __FUNCTION__); ScopedByteArrayRO bytes(e, data); PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); UINT8* raw_ptr = const_cast<UINT8*>(reinterpret_cast<const UINT8*>(&bytes[0])); // TODO: API bug: send should take const*! bool stat = PeerToPeer::getInstance().send(jniHandle, raw_ptr, bytes.size()); ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit", __FUNCTION__); return stat ? JNI_TRUE : JNI_FALSE; }
/******************************************************************************* ** ** Function: nativeLlcpSocket_doConnectBy ** ** Description: Establish a connection to the peer. ** e: JVM environment. ** o: Java object. ** sn: Service name. ** ** Returns: True if ok. ** *******************************************************************************/ static jboolean nativeLlcpSocket_doConnectBy (JNIEnv* e, jobject o, jstring sn) { ALOGD ("%s: enter", __FUNCTION__); PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); ScopedUtfChars serviceName(e, sn); if (serviceName.c_str() == NULL) { return JNI_FALSE; } bool stat = PeerToPeer::getInstance().connectConnOriented(jniHandle, serviceName.c_str()); ALOGD ("%s: exit", __FUNCTION__); return stat ? JNI_TRUE : JNI_FALSE; }
static jboolean com_android_nfc_NativeP2pDevice_doDisconnect(JNIEnv *e, jobject o) { uint32_t handle = nfc_jni_get_nfc_socket_handle(e, o); bool_t canUse = W_FALSE; jclass target_cls = NULL; jfieldID f; if(IS_SERVER_SOCKET(handle)) { return serverSocketDisconnect(handle); } else if(IS_CLIENT_SOCKET(handle)) { return socketDisconnect(handle); } return JNI_FALSE; }
static jbyteArray com_android_nfc_NativeP2pDevice_doTransceive(JNIEnv *e, jobject o, jbyteArray data) { uint32_t handle = nfc_jni_get_nfc_socket_handle(e, o); bool_t canUse = W_FALSE; jclass target_cls = NULL; jfieldID f; if(IS_SERVER_SOCKET(handle)) { return serverSocketTransceive(e, handle, data); } else if(IS_CLIENT_SOCKET(handle)) { return socketTransceive(e, handle, data); } return NULL; }
static jint com_android_nfc_NativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray buffer) { NFCSTATUS ret; struct timespec ts; phLibNfc_Handle hLlcpSocket; phNfc_sData_t sReceiveBuffer; /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); sReceiveBuffer.buffer = (uint8_t*)e->GetByteArrayElements(buffer, NULL); sReceiveBuffer.length = (uint32_t)e->GetArrayLength(buffer); TRACE("phLibNfc_Llcp_Recv()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Recv(hLlcpSocket, &sReceiveBuffer, nfc_jni_receive_callback, (void*)hLlcpSocket); REENTRANCE_UNLOCK(); if((ret != NFCSTATUS_SUCCESS) && (ret != NFCSTATUS_PENDING)) { /* Return status should be either SUCCESS or PENDING */ LOGE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return 0; } TRACE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Wait for callback response (happen if status is either SUCCESS or PENDING) */ if(sem_wait(nfc_jni_llcp_sem) == -1) { return 0; } if(nfc_jni_cb_status == NFCSTATUS_SUCCESS) { return sReceiveBuffer.length; } else { return 0; } }
static jboolean com_android_nfc_NativeLlcpSocket_doClose(JNIEnv *e, jobject o) { NFCSTATUS ret; phLibNfc_Handle hLlcpSocket; /* 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) { LOGE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return FALSE; } TRACE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return TRUE; }
static jboolean com_android_nfc_NativeLlcpSocket_doSend(JNIEnv *e, jobject o, jbyteArray data) { NFCSTATUS ret; struct timespec ts; phLibNfc_Handle hLlcpSocket; phNfc_sData_t sSendBuffer; /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); sSendBuffer.buffer = (uint8_t*)e->GetByteArrayElements(data, NULL); sSendBuffer.length = (uint32_t)e->GetArrayLength(data); TRACE("phLibNfc_Llcp_Send()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Send(hLlcpSocket, &sSendBuffer, nfc_jni_send_callback, (void*)hLlcpSocket); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { LOGE("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return FALSE; } TRACE("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Wait for callback response */ if(sem_wait(nfc_jni_llcp_sem) == -1) return FALSE; if(nfc_jni_cb_status == NFCSTATUS_SUCCESS) { return TRUE; } else { return FALSE; } }
static jboolean com_android_nfc_NativeLlcpSocket_doConnectBy(JNIEnv *e, jobject o, jstring sn) { NFCSTATUS ret; struct timespec ts; phNfc_sData_t serviceName; phLibNfc_Handle hLlcpSocket; /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); /* Service socket */ serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); serviceName.length = (uint32_t)e->GetStringUTFLength(sn); TRACE("phLibNfc_Llcp_ConnectByUri()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_ConnectByUri(hLlcpSocket, &serviceName, nfc_jni_connect_callback, (void*)hLlcpSocket); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { LOGE("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return FALSE; } TRACE("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Wait for callback response */ if(sem_wait(nfc_jni_llcp_sem) == -1) return FALSE; if(nfc_jni_cb_status == NFCSTATUS_SUCCESS) { return TRUE; } else { return FALSE; } }
/******************************************************************************* ** ** Function: nativeLlcpSocket_doReceive ** ** Description: Receive data from peer. ** e: JVM environment. ** o: Java object. ** origBuffer: Buffer to put received data. ** ** Returns: Number of bytes received. ** *******************************************************************************/ static jint nativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray origBuffer) { ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter", __FUNCTION__); ScopedByteArrayRW bytes(e, origBuffer); PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); uint16_t actualLen = 0; bool stat = PeerToPeer::getInstance().receive(jniHandle, reinterpret_cast<UINT8*>(&bytes[0]), bytes.size(), actualLen); jint retval = 0; if (stat && (actualLen>0)) { retval = actualLen; } else retval = -1; ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit; actual len=%d", __FUNCTION__, retval); return retval; }
/* * Methods */ static jboolean com_android_nfc_NativeLlcpSocket_doConnect(JNIEnv *e, jobject o, jint nSap) { NFCSTATUS ret; struct timespec ts; phLibNfc_Handle hLlcpSocket; /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); TRACE("phLibNfc_Llcp_Connect(%d)",nSap); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Connect(hLlcpSocket, nSap, nfc_jni_connect_callback, (void*)hLlcpSocket); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { LOGE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, nfc_jni_get_status_name(ret)); return FALSE; } TRACE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, nfc_jni_get_status_name(ret)); /* Wait for callback response */ if(sem_wait(nfc_jni_llcp_sem) == -1) return FALSE; if(nfc_jni_cb_status == NFCSTATUS_SUCCESS) { TRACE("LLCP Connect request OK"); return TRUE; } else { LOGD("LLCP Connect request KO"); return FALSE; } }
static jint com_android_nfc_NativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray buffer) { NFCSTATUS ret; struct timespec ts; phLibNfc_Handle hRemoteDevice; phLibNfc_Handle hLlcpSocket; phNfc_sData_t sReceiveBuffer = {NULL, 0}; struct nfc_jni_callback_data cb_data; jint result = -1; /* 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; } sReceiveBuffer.buffer = (uint8_t*)e->GetByteArrayElements(buffer, NULL); sReceiveBuffer.length = (uint32_t)e->GetArrayLength(buffer); TRACE("phLibNfc_Llcp_Recv()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Recv(hRemoteDevice, hLlcpSocket, &sReceiveBuffer, nfc_jni_receive_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(ret == NFCSTATUS_PENDING) { /* 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) { result = sReceiveBuffer.length; } } else if (ret == NFCSTATUS_SUCCESS) { result = sReceiveBuffer.length; } else { /* Return status should be either SUCCESS or PENDING */ ALOGE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); goto clean_and_return; } TRACE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); clean_and_return: if (sReceiveBuffer.buffer != NULL) { e->ReleaseByteArrayElements(buffer, (jbyte*)sReceiveBuffer.buffer, 0); } nfc_cb_data_deinit(&cb_data); return result; }
/* * Methods */ static jobject com_NativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, jint miu, jint rw, jint linearBufferLength) { NFCSTATUS ret = NFCSTATUS_SUCCESS; struct timespec ts; phLibNfc_Llcp_sSocketOptions_t sOptions; phNfc_sData_t sWorkingBuffer; jfieldID f; jclass clsNativeLlcpSocket; jobject clientSocket = NULL; struct nfc_jni_callback_data cb_data; phLibNfc_Handle hIncomingSocket, hServerSocket; nfc_jni_native_monitor_t * pMonitor = nfc_jni_get_monitor(); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } /* Get server socket */ hServerSocket = nfc_jni_get_nfc_socket_handle(e,o); /* 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; while(cb_data.status != NFCSTATUS_SUCCESS) { /* Wait for tag Notification */ pthread_mutex_lock(&pMonitor->incoming_socket_mutex); while ((hIncomingSocket = getIncomingSocket(pMonitor, hServerSocket)) == NULL) { pthread_cond_wait(&pMonitor->incoming_socket_cond, &pMonitor->incoming_socket_mutex); } pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); /* Accept the incomming socket */ TRACE("phLibNfc_Llcp_Accept()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Accept( hIncomingSocket, &sOptions, &sWorkingBuffer, nfc_jni_llcp_transport_socket_err_callback, nfc_jni_llcp_accept_socket_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { // NOTE: This may happen if link went down since incoming socket detected, then // just drop it and start a new accept loop. LOGD("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); continue; } TRACE("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { LOGE("Failed to wait for semaphore (errno=0x%08x)", errno); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { /* NOTE: Do not generate an error if the accept failed to avoid error in server application */ LOGD("Failed to accept incoming socket 0x%04x[%s]", cb_data.status, nfc_jni_get_status_name(cb_data.status)); } } /* Create new LlcpSocket object */ if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpSocket",&(clientSocket)) == -1) { LOGD("LLCP Socket creation error"); goto clean_and_return; } /* Get NativeConnectionOriented class object */ clsNativeLlcpSocket = e->GetObjectClass(clientSocket); if(e->ExceptionCheck()) { LOGD("LLCP Socket get class object error"); goto clean_and_return; } /* Set socket handle */ f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); e->SetIntField(clientSocket, f,(jint)hIncomingSocket); /* Set socket MIU */ f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); e->SetIntField(clientSocket, f,(jint)miu); /* Set socket RW */ f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); e->SetIntField(clientSocket, f,(jint)rw); TRACE("socket handle 0x%02x: MIU = %d, RW = %d\n",hIncomingSocket, miu, rw); clean_and_return: nfc_cb_data_deinit(&cb_data); return clientSocket; }
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; }