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 jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e, jobject o,jint handle, jbyteArray data) { uint8_t offset = 0; uint8_t *buf; uint32_t buflen; phLibNfc_sTransceiveInfo_t transceive_info; jbyteArray result = NULL; int res; int tech = SecureElementTech; NFCSTATUS status; struct nfc_jni_callback_data cb_data; /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } TRACE("Exchange APDU function "); CONCURRENCY_LOCK(); TRACE("Secure Element tech: %d\n", tech); buf = (uint8_t *)e->GetByteArrayElements(data, NULL); buflen = (uint32_t)e->GetArrayLength(data); /* Prepare transceive info structure */ if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL) { offset = 2; transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; transceive_info.addr = (uint8_t)buf[1]; } else if(tech == TARGET_TYPE_ISO14443_4) { transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw; transceive_info.addr = 0; } 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(SMX)"); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, com_android_nfc_jni_transceive_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { ALOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("TRANSCEIVE semaphore error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("TRANSCEIVE error"); goto clean_and_return; } /* Copy results back to Java */ result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length); if(result != NULL) { e->SetByteArrayRegion(result, 0, com_android_nfc_jni_transceive_buffer->length, (jbyte *)com_android_nfc_jni_transceive_buffer->buffer); } clean_and_return: nfc_cb_data_deinit(&cb_data); if(transceive_info.sRecvData.buffer != NULL) { free(transceive_info.sRecvData.buffer); } e->ReleaseByteArrayElements(data, (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT); CONCURRENCY_UNLOCK(); return result; }