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 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 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; } }
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 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_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; }
/******************************************************************************* ** ** Function phNxpNciHal_cleanup_monitor ** ** Description Clean up semaphore monitor ** ** Returns None ** *******************************************************************************/ void phNxpNciHal_cleanup_monitor(void) { if (nxpncihal_monitor != NULL) { pthread_mutex_destroy(&nxpncihal_monitor->concurrency_mutex); REENTRANCE_UNLOCK(); pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex); phNxpNciHal_releaseall_cb_data(); listDestroy(&nxpncihal_monitor->sem_list); } free(nxpncihal_monitor); nxpncihal_monitor = NULL; return; }
static jbyteArray com_android_nfc_NativeNdefTag_doRead(JNIEnv *e, jobject o) { phLibNfc_Handle handle = 0; jbyteArray buf = NULL; NFCSTATUS status; CONCURRENCY_LOCK(); handle = nfc_jni_get_nfc_tag_handle(e, o); nfc_jni_ndef_rw.length = nfc_jni_ndef_buf_len; nfc_jni_ndef_rw.buffer = nfc_jni_ndef_buf; TRACE("phLibNfc_Ndef_Read()"); REENTRANCE_LOCK(); status = phLibNfc_Ndef_Read( handle, &nfc_jni_ndef_rw, phLibNfc_Ndef_EBegin, nfc_jni_tag_rw_callback, (void *)e); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* Wait for callback response */ sem_wait(nfc_jni_ndef_tag_sem); if(nfc_jni_cb_status != NFCSTATUS_SUCCESS) { goto clean_and_return; } buf = e->NewByteArray(nfc_jni_ndef_rw.length); e->SetByteArrayRegion(buf, 0, nfc_jni_ndef_rw.length, (jbyte *)nfc_jni_ndef_rw.buffer); clean_and_return: CONCURRENCY_UNLOCK(); return buf; }
static jboolean com_android_nfc_NativeNdefTag_doWrite(JNIEnv *e, jobject o, jbyteArray buf) { NFCSTATUS status; jboolean result = JNI_FALSE; CONCURRENCY_LOCK(); phLibNfc_Handle handle = nfc_jni_get_nfc_tag_handle(e, o); nfc_jni_ndef_rw.length = (uint32_t)e->GetArrayLength(buf); nfc_jni_ndef_rw.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL); TRACE("phLibNfc_Ndef_Write()"); REENTRANCE_LOCK(); status = phLibNfc_Ndef_Write(handle, &nfc_jni_ndef_rw,nfc_jni_tag_rw_callback, (void *)e); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { LOGE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* Wait for callback response */ sem_wait(nfc_jni_ndef_tag_sem); if(nfc_jni_cb_status != NFCSTATUS_SUCCESS) { goto clean_and_return; } result = JNI_TRUE; clean_and_return: if (result != JNI_TRUE) { e->ReleaseByteArrayElements(buf, (jbyte *)nfc_jni_ndef_rw.buffer, JNI_ABORT); } CONCURRENCY_UNLOCK(); return result; }
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; } }
/******************************************************************************* ** ** Function phNxpNciHal_test_rx_thread ** ** Description Thread to fetch and process messages from message queue. ** ** Returns NULL ** *******************************************************************************/ static void *phNxpNciHal_test_rx_thread(void *arg) { phLibNfc_Message_t msg; NXPLOG_NCIHAL_D("Self test thread started"); thread_running = 1; while (thread_running == 1) { /* Fetch next message from the NFC stack message queue */ if (phDal4Nfc_msgrcv(gDrvCfg.nClientId, &msg, 0, 0) == -1) { NXPLOG_NCIHAL_E("Received bad message"); continue; } if(thread_running == 0) { break; } switch (msg.eMsgType) { case PH_LIBNFC_DEFERREDCALL_MSG: { phLibNfc_DeferredCall_t *deferCall = (phLibNfc_DeferredCall_t *) (msg.pMsgData); REENTRANCE_LOCK(); deferCall->pCallback(deferCall->pParameter); REENTRANCE_UNLOCK(); break; } } } NXPLOG_NCIHAL_D("Self test thread stopped"); return NULL; }
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; } }
/* * 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 jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle) { jclass cls; jfieldID f; NFCSTATUS status; jboolean result = JNI_FALSE; phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; uint32_t SmartMX_Handle; struct nfc_jni_callback_data cb_data; phNfc_sData_t InParam; phNfc_sData_t OutParam; uint8_t Output_Buff[10]; uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; uint8_t GpioSetValue[4]; uint8_t gpioValue; /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } TRACE("Close Secure element function "); CONCURRENCY_LOCK(); /* Disconnect */ TRACE("Disconnecting from SMX (handle = 0x%x)", handle); REENTRANCE_LOCK(); status = phLibNfc_RemoteDev_Disconnect(handle, NFC_SMARTMX_RELEASE, com_android_nfc_jni_disconnect_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(status != NFCSTATUS_PENDING) { ALOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { goto clean_and_return; } /* Disconnect Status */ if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("\n> Disconnect SE ERROR \n" ); goto clean_and_return; } CONCURRENCY_UNLOCK(); /* Get GPIO information */ CONCURRENCY_LOCK(); InParam.buffer = GpioGetValue; InParam.length = 3; OutParam.buffer = Output_Buff; TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); REENTRANCE_LOCK(); status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(status!=NFCSTATUS_PENDING) { ALOGE("IOCTL status error"); goto clean_and_return; } /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("IOCTL semaphore error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("READ MEM ERROR"); goto clean_and_return; } gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; TRACE("GpioValue = Ox%02x",gpioValue); /* Set GPIO information */ GpioSetValue[0] = 0x00; GpioSetValue[1] = 0xF8; GpioSetValue[2] = 0x2B; GpioSetValue[3] = (gpioValue & 0xBF); TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); for(i=0;i<4;i++) { TRACE("0x%02x",GpioSetValue[i]); } InParam.buffer = GpioSetValue; InParam.length = 4; OutParam.buffer = Output_Buff; TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); REENTRANCE_LOCK(); status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(status!=NFCSTATUS_PENDING) { ALOGE("IOCTL status error"); goto clean_and_return; } /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("IOCTL semaphore error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("READ MEM ERROR"); goto clean_and_return; } result = JNI_TRUE; clean_and_return: nfc_cb_data_deinit(&cb_data); CONCURRENCY_UNLOCK(); 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; }
/* * 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 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 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; }
static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o) { NFCSTATUS ret; int semResult; phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; phLibNfc_sADD_Cfg_t discovery_cfg; phLibNfc_Registry_Info_t registry_info; phNfc_sData_t InParam; phNfc_sData_t OutParam; uint8_t ExternalRFDetected[3] = {0x00, 0xFC, 0x01}; uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; uint8_t GpioSetValue[4]; uint8_t gpioValue; uint8_t Output_Buff[10]; uint8_t reg_value; uint8_t mask_value; struct nfc_jni_callback_data cb_data; struct nfc_jni_callback_data cb_data_SE_Notification; /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data_SE_Notification, NULL)) { goto clean_and_return; } /* Registery */ registry_info.MifareUL = TRUE; registry_info.MifareStd = TRUE; registry_info.ISO14443_4A = TRUE; registry_info.ISO14443_4B = TRUE; registry_info.Jewel = TRUE; registry_info.Felica = TRUE; registry_info.NFC = FALSE; CONCURRENCY_LOCK(); TRACE("Open Secure Element"); /* Check if NFC device is already connected to a tag or P2P peer */ if (device_connected_flag == 1) { ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag"); goto clean_and_return; } /* Test if External RF field is detected */ InParam.buffer = ExternalRFDetected; InParam.length = 3; OutParam.buffer = Output_Buff; TRACE("phLibNfc_Mgt_IoCtl()"); REENTRANCE_LOCK(); ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(ret!=NFCSTATUS_PENDING) { ALOGE("IOCTL status error"); goto clean_and_return; } /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("IOCTL semaphore error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("READ MEM ERROR"); goto clean_and_return; } /* Check the value */ reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0]; mask_value = reg_value & 0x40; if(mask_value == 0x40) { // There is an external RF field present, fail the open request ALOGD("Unable to open SE connection, external RF Field detected"); goto clean_and_return; } /* Get Secure Element List */ TRACE("phLibNfc_SE_GetSecureElementList()"); ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE); if (ret == NFCSTATUS_SUCCESS) { TRACE("\n> Number of Secure Element(s) : %d\n", No_SE); /* Display Secure Element information */ for (i = 0; i<No_SE; i++) { if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) { TRACE("> SMX detected"); TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement); /* save SMARTMX index */ SmartMX_detected = 1; SmartMX_index = i; } } if(SmartMX_detected) { REENTRANCE_LOCK(); TRACE("phLibNfc_RemoteDev_NtfRegister()"); ret = phLibNfc_RemoteDev_NtfRegister(®istry_info, com_android_nfc_jni_open_secure_element_notification_callback, (void *)&cb_data_SE_Notification); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_SUCCESS) { ALOGE("Register Notification error"); goto clean_and_return; } /* Set wired mode */ REENTRANCE_LOCK(); TRACE("phLibNfc_SE_SetMode: Wired mode"); ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement, phLibNfc_SE_ActModeWired, com_android_nfc_jni_smartMX_setModeCb, (void *)&cb_data); REENTRANCE_UNLOCK(); if (ret != NFCSTATUS_PENDING ) { ALOGE("\n> SE Set SmartMX mode ERROR \n" ); goto clean_and_return; } /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("Secure Element opening error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("SE set mode failed"); goto clean_and_return; } TRACE("Waiting for notification"); /* Wait for callback response */ if(sem_wait(&cb_data_SE_Notification.sem)) { ALOGE("Secure Element opening error"); goto clean_and_return; } if(cb_data_SE_Notification.status != NFCSTATUS_SUCCESS && cb_data_SE_Notification.status != NFCSTATUS_MULTIPLE_PROTOCOLS) { ALOGE("SE detection failed"); goto clean_and_return; } CONCURRENCY_UNLOCK(); /* Connect Tag */ CONCURRENCY_LOCK(); TRACE("phLibNfc_RemoteDev_Connect(SMX)"); REENTRANCE_LOCK(); ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { ALOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); goto clean_and_return; } TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("CONNECT semaphore error"); goto clean_and_return; } /* Connect Status */ if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("Secure Element connect error"); goto clean_and_return; } CONCURRENCY_UNLOCK(); /* Get GPIO information */ CONCURRENCY_LOCK(); InParam.buffer = GpioGetValue; InParam.length = 3; OutParam.buffer = Output_Buff; TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); REENTRANCE_LOCK(); ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(ret!=NFCSTATUS_PENDING) { ALOGE("IOCTL status error"); } /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("IOCTL semaphore error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("READ MEM ERROR"); goto clean_and_return; } gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; TRACE("GpioValue = Ox%02x",gpioValue); /* Set GPIO information */ GpioSetValue[0] = 0x00; GpioSetValue[1] = 0xF8; GpioSetValue[2] = 0x2B; GpioSetValue[3] = (gpioValue | 0x40); TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); for(i=0;i<4;i++) { TRACE("0x%02x",GpioSetValue[i]); } InParam.buffer = GpioSetValue; InParam.length = 4; OutParam.buffer = Output_Buff; TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); REENTRANCE_LOCK(); ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); if(ret!=NFCSTATUS_PENDING) { ALOGE("IOCTL status error"); goto clean_and_return; } /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { ALOGE("IOCTL semaphore error"); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { ALOGE("READ MEM ERROR"); goto clean_and_return; } CONCURRENCY_UNLOCK(); nfc_cb_data_deinit(&cb_data); nfc_cb_data_deinit(&cb_data_SE_Notification); /* Return the Handle of the SecureElement */ return secureElementHandle; } else { ALOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected"); goto clean_and_return; } } else { ALOGE("phLibNfc_SE_GetSecureElementList(): Error"); goto clean_and_return; } clean_and_return: nfc_cb_data_deinit(&cb_data); nfc_cb_data_deinit(&cb_data_SE_Notification); CONCURRENCY_UNLOCK(); return 0; }
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; }