static jint com_android_nfc_NativeLlcpSocket_doGetRemoteSocketRW(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(RW)"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_SocketGetRemoteOptions(hRemoteDevice, 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 { ALOGW("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); return 0; } }
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_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_NativeP2pDevice_doSend( JNIEnv *e, jobject o, jbyteArray buf) { NFCSTATUS status; phNfc_sData_t data; jboolean result = JNI_FALSE; struct nfc_jni_callback_data cb_data; phLibNfc_Handle handle = nfc_jni_get_p2p_device_handle(e, o); CONCURRENCY_LOCK(); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } /* Send */ TRACE("Send data to the Initiator (handle = 0x%x)", handle); data.length = (uint32_t)e->GetArrayLength(buf); data.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL); TRACE("phLibNfc_RemoteDev_Send()"); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Send(handle, &data, nfc_jni_send_callback,(void *)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_RemoteDev_Send() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Send() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* 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) { goto clean_and_return; } result = JNI_TRUE; clean_and_return: if (result != JNI_TRUE) { e->ReleaseByteArrayElements(buf, (jbyte *)data.buffer, JNI_ABORT); } nfc_cb_data_deinit(&cb_data); CONCURRENCY_UNLOCK(); return result; }
/* * 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; }
static jbyteArray com_android_nfc_NativeP2pDevice_doReceive( JNIEnv *e, jobject o) { NFCSTATUS status; struct timespec ts; phLibNfc_Handle handle; jbyteArray buf = NULL; static phNfc_sData_t *data; struct nfc_jni_callback_data cb_data; CONCURRENCY_LOCK(); handle = nfc_jni_get_p2p_device_handle(e, o); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, (void*)data)) { goto clean_and_return; } /* Receive */ TRACE("phLibNfc_RemoteDev_Receive()"); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Receive(handle, nfc_jni_receive_callback,(void *)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_RemoteDev_Receive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Receive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* 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(data == NULL) { goto clean_and_return; } buf = e->NewByteArray(data->length); e->SetByteArrayRegion(buf, 0, data->length, (jbyte *)data->buffer); clean_and_return: nfc_cb_data_deinit(&cb_data); CONCURRENCY_UNLOCK(); return buf; }
static jbyteArray com_android_nfc_NativeP2pDevice_doTransceive(JNIEnv *e, jobject o, jbyteArray data) { NFCSTATUS status; uint8_t offset = 2; uint8_t *buf; uint32_t buflen; phLibNfc_sTransceiveInfo_t transceive_info; jbyteArray result = NULL; phLibNfc_Handle handle = nfc_jni_get_p2p_device_handle(e, o); phNfc_sData_t * receive_buffer = NULL; struct nfc_jni_callback_data cb_data; CONCURRENCY_LOCK(); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, (void*)receive_buffer)) { goto clean_and_return; } /* Transceive*/ TRACE("Transceive data to target (handle = 0x%x)", handle); buf = (uint8_t *)e->GetByteArrayElements(data, NULL); buflen = (uint32_t)e->GetArrayLength(data); TRACE("Buffer Length = %d\n", buflen); transceive_info.sSendData.buffer = buf; //+ offset; transceive_info.sSendData.length = buflen; //- offset; transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); transceive_info.sRecvData.length = 1024; if(transceive_info.sRecvData.buffer == NULL) { goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Transceive(P2P)"); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, nfc_jni_transceive_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_RemoteDev_Transceive(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Transceive(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* 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) { goto clean_and_return; } /* Copy results back to Java */ result = e->NewByteArray(receive_buffer->length); if(result != NULL) e->SetByteArrayRegion(result, 0, receive_buffer->length, (jbyte *)receive_buffer->buffer); clean_and_return: if(transceive_info.sRecvData.buffer != NULL) { free(transceive_info.sRecvData.buffer); } e->ReleaseByteArrayElements(data, (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT); nfc_cb_data_deinit(&cb_data); CONCURRENCY_UNLOCK(); return result; }
static jboolean com_android_nfc_NativeP2pDevice_doDisconnect(JNIEnv *e, jobject o) { phLibNfc_Handle handle = 0; jboolean result = JNI_FALSE; NFCSTATUS status; struct nfc_jni_callback_data cb_data; CONCURRENCY_LOCK(); handle = nfc_jni_get_p2p_device_handle(e, o); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } /* Disconnect */ TRACE("Disconnecting from target (handle = 0x%x)", handle); /* NativeNfcTag waits for tag to leave the field here with presence check. * We do not in P2P path because presence check is not safe while transceive may be * in progress. */ TRACE("phLibNfc_RemoteDev_Disconnect()"); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE,nfc_jni_disconnect_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); if(status == NFCSTATUS_TARGET_NOT_CONNECTED) { LOGE("phLibNfc_RemoteDev_Disconnect() failed: Target not connected"); } else { LOGE("phLibNfc_RemoteDev_Disconnect() failed"); nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); } goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { LOGE("Failed to wait for semaphore (errno=0x%08x)", errno); goto clean_and_return; } /* Disconnect Status */ if(cb_data.status != NFCSTATUS_SUCCESS) { goto clean_and_return; } result = JNI_TRUE; clean_and_return: /* Reset device connected flag */ device_connected_flag = 0; nfc_cb_data_deinit(&cb_data); CONCURRENCY_UNLOCK(); return result; }
static jboolean com_android_nfc_NativeP2pDevice_doConnect(JNIEnv *e, jobject o) { phLibNfc_Handle handle = 0; NFCSTATUS status; jboolean result = JNI_FALSE; struct nfc_jni_callback_data cb_data; jclass target_cls = NULL; jobject tag; jmethodID ctor; jfieldID f; jbyteArray generalBytes = NULL; phNfc_sData_t sGeneralBytes; unsigned int i; CONCURRENCY_LOCK(); handle = nfc_jni_get_p2p_device_handle(e, o); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, (void*)&sGeneralBytes)) { goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Connect(P2P)"); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Connect(handle, nfc_jni_connect_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_RemoteDev_Connect(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Connect(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* 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) { goto clean_and_return; } /* Set General Bytes */ target_cls = e->GetObjectClass(o); f = e->GetFieldID(target_cls, "mGeneralBytes", "[B"); TRACE("General Bytes Length = %d", sGeneralBytes.length); TRACE("General Bytes ="); for(i=0;i<sGeneralBytes.length;i++) { TRACE("0x%02x ", sGeneralBytes.buffer[i]); } generalBytes = e->NewByteArray(sGeneralBytes.length); e->SetByteArrayRegion(generalBytes, 0, sGeneralBytes.length, (jbyte *)sGeneralBytes.buffer); e->SetObjectField(o, f, generalBytes); result = JNI_TRUE; clean_and_return: if (result != JNI_TRUE) { /* Restart the polling loop if the connection failed */ nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); } nfc_cb_data_deinit(&cb_data); CONCURRENCY_UNLOCK(); return result; }
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; }
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; }