void phNxpNciHal_TestMode_close () { NFCSTATUS status = NFCSTATUS_SUCCESS; CONCURRENCY_LOCK(); if (NULL != gpphTmlNfc_Context->pDevHandle) { /* Abort any pending read and write */ status = phTmlNfc_ReadAbort(); status = phTmlNfc_WriteAbort(); phOsalNfc_Timer_Cleanup(); status = phTmlNfc_Shutdown(); NXPLOG_NCIHAL_D("phNxpNciHal_close return status = %d", status); thread_running = 0; phDal4Nfc_msgrelease(gDrvCfg.nClientId); status = phOsalNfc_Timer_Delete(timeoutTimerId); } CONCURRENCY_UNLOCK(); phNxpNciHal_cleanup_monitor(); /* Return success always */ return; }
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; }
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_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; }
/******************************************************************************* ** ** Function phNxpNciHal_performTest ** ** Description Performs a single cycle of command,response and ** notification. ** ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED, ** *******************************************************************************/ NFCSTATUS phNxpNciHal_performTest(nci_test_data_t *pData ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if(NULL == pData) { return NFCSTATUS_FAILED; } CONCURRENCY_LOCK(); status = phNxpNciHal_writeLocked(pData); if(status == NFCSTATUS_RESPONSE_TIMEOUT) { goto clean_and_return; } if(status != NFCSTATUS_SUCCESS) { goto clean_and_return; } status = phNxpNciHal_readLocked(pData); if(status != NFCSTATUS_SUCCESS) { goto clean_and_return; } if(0 != pData->exp_ntf.len) { status = phNxpNciHal_readLocked(pData); if(status != NFCSTATUS_SUCCESS) { goto clean_and_return; } } clean_and_return: CONCURRENCY_UNLOCK(); return status; }
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 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 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; }
/******************************************************************************* ** ** Function phNxpNciHal_TestMode_open ** ** Description It opens the physical connection with NFCC (pn547) and ** creates required client thread for operation. ** ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. ** *******************************************************************************/ NFCSTATUS phNxpNciHal_TestMode_open (void) { /* Thread */ pthread_t test_rx_thread; phOsalNfc_Config_t tOsalConfig; phTmlNfc_Config_t tTmlConfig; NFCSTATUS status = NFCSTATUS_SUCCESS; uint16_t read_len = 255; /* initialize trace level */ phNxpLog_InitializeLogLevel(); if (phNxpNciHal_init_monitor() == NULL) { NXPLOG_NCIHAL_E("Init monitor failed"); return NFCSTATUS_FAILED; } CONCURRENCY_LOCK(); memset(&tOsalConfig, 0x00, sizeof(tOsalConfig)); memset(&tTmlConfig, 0x00, sizeof(tTmlConfig)); gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600); gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN547 */ tTmlConfig.pDevName = (int8_t *) "/dev/pn544"; tOsalConfig.dwCallbackThreadId = (uint32_t) gDrvCfg.nClientId; tOsalConfig.pLogFile = NULL; tTmlConfig.dwGetMsgThreadId = (uint32_t) gDrvCfg.nClientId; nxpncihal_ctrl.gDrvCfg.nClientId = (uint32_t) gDrvCfg.nClientId; /* Initialize TML layer */ status = phTmlNfc_Init(&tTmlConfig); if (status != NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_E("phTmlNfc_Init Failed"); goto clean_and_return; } if (pthread_create(&test_rx_thread, NULL, phNxpNciHal_test_rx_thread, NULL) != 0) { NXPLOG_NCIHAL_E("pthread_create failed"); phTmlNfc_Shutdown(); goto clean_and_return; } timeoutTimerId = phOsalNfc_Timer_Create(); if(timeoutTimerId == 0xFFFF) { NXPLOG_NCIHAL_E("phOsalNfc_Timer_Create failed"); } else { NXPLOG_NCIHAL_D("phOsalNfc_Timer_Create SUCCESS"); } CONCURRENCY_UNLOCK(); return NFCSTATUS_SUCCESS; clean_and_return: CONCURRENCY_UNLOCK(); phNxpNciHal_cleanup_monitor(); return NFCSTATUS_FAILED; }
/******************************************************************************* ** ** Function tmp_thread ** ** Description Thread to execute custom poll commands . ** ** Returns None ** *******************************************************************************/ void *tmp_thread(void *tmp) { NFCSTATUS status = NFCSTATUS_SUCCESS; uint16_t data_len; NXPLOG_NCIHAL_E("tmp_thread: enter type=0x0%x", *((int*)tmp)); usleep(10*1000); switch( *((int*)tmp) ) { case START_POLLING: { CONCURRENCY_LOCK(); data_len = phNxpNciHal_write_unlocked(cmd_poll_len, cmd_poll); CONCURRENCY_UNLOCK(); if(data_len != cmd_poll_len) { NXPLOG_NCIHAL_E("phNxpNciHal_start_polling_loop: data len mismatch"); status = NFCSTATUS_FAILED; } } break; case RESUME_POLLING: { CONCURRENCY_LOCK(); data_len = phNxpNciHal_write_unlocked(sizeof(cmd_resume_rf_discovery), cmd_resume_rf_discovery); CONCURRENCY_UNLOCK(); if(data_len != sizeof(cmd_resume_rf_discovery)) { NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch"); status = NFCSTATUS_FAILED; } } break; case STOP_POLLING: { CONCURRENCY_LOCK(); data_len = phNxpNciHal_write_unlocked(sizeof(cmd_stop_rf_discovery), cmd_stop_rf_discovery); CONCURRENCY_UNLOCK(); if(data_len != sizeof(cmd_stop_rf_discovery)) { NXPLOG_NCIHAL_E("phNxpNciHal_stop_polling_loop: data len mismatch"); status = NFCSTATUS_FAILED; } } break; case DISCOVER_SELECT: { CONCURRENCY_LOCK(); data_len = phNxpNciHal_write_unlocked(sizeof(cmd_select_rf_discovery), cmd_select_rf_discovery); CONCURRENCY_UNLOCK(); if(data_len != sizeof(cmd_resume_rf_discovery)) { NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch"); status = NFCSTATUS_FAILED; } } break; default: NXPLOG_NCIHAL_E("No Matching case"); status = NFCSTATUS_FAILED; break; } NXPLOG_NCIHAL_E("tmp_thread: exit"); return NULL; }
/****************************************************************************** * Function phNxpEseP61_7816_Transceive * * Description This function prepares C-APDU and sends to p61 and recives * response from the p61. also it parses all required fields of * the response PDU. * * Returns On Success ESESTATUS_SUCCESS else proper error code * ******************************************************************************/ ESESTATUS phNxpEseP61_7816_Transceive(pphNxpEseP61_7816_cpdu_t pCmd, pphNxpEseP61_7816_rpdu_t pRsp) { ESESTATUS status = ESESTATUS_FAILED; NXPLOG_SPIHAL_D(" %s Enter \n", __FUNCTION__); uint32_t cmd_len = 0; uint8_t *pCmd_data = NULL; if (phNxpSpiHal_init_cb_data(&cb_data, NULL) != ESESTATUS_SUCCESS) { NXPLOG_SPIHAL_D("%s Create cb data failed", __FUNCTION__); CONCURRENCY_UNLOCK(); return status; } if (NULL == pCmd || NULL == pRsp) { NXPLOG_SPIHAL_E(" %s Invalid prameter \n", __FUNCTION__); status = ESESTATUS_INVALID_PARAMETER; } else if(pCmd->cpdu_type > 1) { NXPLOG_SPIHAL_E(" %s Invalid cpdu type \n", __FUNCTION__); status = ESESTATUS_INVALID_CPDU_TYPE; } else if(0 < pCmd->le_type && NULL == pRsp->pdata) { /* if response is requested, but no valid res buffer * provided by application */ NXPLOG_SPIHAL_E(" %s Invalid response buffer \n", __FUNCTION__); status = ESESTATUS_INVALID_BUFFER; } else { status = phNxpEseP61_7816_FrameCmd(pCmd, &pCmd_data, &cmd_len); if (ESESTATUS_SUCCESS == status) { status = phNxpEseP61_Transceive(cmd_len, pCmd_data); if (ESESTATUS_SUCCESS != status) { NXPLOG_SPIHAL_E(" %s phNxpEseP61_Transceive Failed \n", __FUNCTION__); } else { /* Wait for callback response */ if (SEM_WAIT(cb_data)) { NXPLOG_SPIHAL_E("phNxpEseP61_Transceive semaphore error"); status = ESESTATUS_FAILED; } else { if ((sTransceiveDataLen > 0) && (sTransceiveData != NULL)) { pRsp->sw2 = *(sTransceiveData + (sTransceiveDataLen -1)); sTransceiveDataLen--; pRsp->sw1 = *(sTransceiveData + (sTransceiveDataLen -1)); sTransceiveDataLen--; pRsp->len = sTransceiveDataLen; ALOGD("pRsp->len %d", pRsp->len); if (sTransceiveDataLen > 0 && NULL != pRsp->pdata) { memcpy(pRsp->pdata, sTransceiveData, sTransceiveDataLen); status = ESESTATUS_SUCCESS; } else if(sTransceiveDataLen == 0) { status = ESESTATUS_SUCCESS; } else { /* if application response buffer is null and data is present */ NXPLOG_SPIHAL_E("Invalid Res buffer"); status = ESESTATUS_FAILED; } NXPLOG_SPIHAL_D("Freeing memroy sTransceiveData"); free(sTransceiveData); sTransceiveData = NULL; sTransceiveDataLen = 0; } else { NXPLOG_SPIHAL_E("sTransceiveDataLen error = %d", sTransceiveDataLen); status = ESESTATUS_FAILED; } } } if (pCmd_data != NULL) { NXPLOG_SPIHAL_D("Freeing memroy pCmd_data"); free(pCmd_data); } } } phNxpSpiHal_cleanup_cb_data(&cb_data); NXPLOG_SPIHAL_D(" %s Exit status 0x%x \n", __FUNCTION__, status); return status; }