/* * 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; }