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; }
void testNfc(int readNdefMessages) { printf("Starting test_nfc.\n"); const hw_module_t *hwModule = 0; nfc_pn544_device_t *nfcDevice = 0; printf("Finding NFC hardware module.\n"); hw_get_module(NFC_HARDWARE_MODULE_ID, &hwModule); assert(hwModule != NULL); printf("Opening NFC device.\n"); assert(nfc_pn544_open(hwModule, &nfcDevice) == 0); assert(nfcDevice != 0); assert(nfcDevice->num_eeprom_settings != 0); assert(nfcDevice->eeprom_settings); printf("Configuring NFC driver.\n"); phLibNfc_sConfig_t driverConfig; driverConfig.nClientId = phDal4Nfc_msgget(0, 0600); assert(driverConfig.nClientId); void *hwRef; NFCSTATUS status = phLibNfc_Mgt_ConfigureDriver(&driverConfig, &hwRef); assert(hwRef); assert(status == NFCSTATUS_SUCCESS); pthread_t messageThread = createMessageThread(&driverConfig.nClientId); printf("Initializing NFC stack.\n"); NFCSTATUS callbackStatus = 0xFFFF; status = phLibNfc_Mgt_Initialize(hwRef, initializeCallback, &callbackStatus); assert(status == NFCSTATUS_PENDING); pthread_mutex_lock(&mut); while (callbackStatus == 0xFFFF) pthread_cond_wait(&cond, &mut); pthread_mutex_unlock(&mut); assert(callbackStatus == NFCSTATUS_SUCCESS); printf("Getting NFC stack capabilities.\n"); phLibNfc_StackCapabilities_t capabilities; status = phLibNfc_Mgt_GetstackCapabilities(&capabilities, &callbackStatus); assert(status == NFCSTATUS_SUCCESS); printf("NFC capabilities:\n" "\tHAL version: %u\n" "\tFW version: %u\n" "\tHW version: %u\n" "\tModel: %u\n" "\tHCI version: %u\n" "\tVendor: %s\n" "\tFull version: %u %u\n" "\tFW Update: %u\n", capabilities.psDevCapabilities.hal_version, capabilities.psDevCapabilities.fw_version, capabilities.psDevCapabilities.hw_version, capabilities.psDevCapabilities.model_id, capabilities.psDevCapabilities.hci_version, capabilities.psDevCapabilities.vendor_name, capabilities.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1], capabilities.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2], capabilities.psDevCapabilities.firmware_update_info); if (readNdefMessages) { /* Start tag discovery */ phLibNfc_Registry_Info_t registryInfo; registryInfo.MifareUL = 1; registryInfo.MifareStd = 1; registryInfo.ISO14443_4A = 1; registryInfo.ISO14443_4B = 1; registryInfo.Jewel = 1; registryInfo.Felica = 1; registryInfo.NFC = 1; registryInfo.ISO15693 = 1; int context; status = phLibNfc_RemoteDev_NtfRegister(®istryInfo, discoveryNotificationCallback, &context); assert(status == NFCSTATUS_SUCCESS); phLibNfc_sADD_Cfg_t discoveryConfig; discoveryConfig.NfcIP_Mode = phNfc_eP2P_ALL; #if (ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR >= 1) || (ANDROID_VERSION_MAJOR >= 5) discoveryConfig.NfcIP_Target_Mode = 0x0E; #endif discoveryConfig.Duration = 300000; discoveryConfig.NfcIP_Tgt_Disable = 0; discoveryConfig.PollDevInfo.PollCfgInfo.EnableIso14443A = 1; discoveryConfig.PollDevInfo.PollCfgInfo.EnableIso14443B = 1; discoveryConfig.PollDevInfo.PollCfgInfo.EnableFelica212 = 1; discoveryConfig.PollDevInfo.PollCfgInfo.EnableFelica424 = 1; discoveryConfig.PollDevInfo.PollCfgInfo.EnableIso15693 = 1; discoveryConfig.PollDevInfo.PollCfgInfo.EnableNfcActive = 1; discoveryConfig.PollDevInfo.PollCfgInfo.DisableCardEmulation = 1; targetStatus = 0xFFFF; status = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG, discoveryConfig, discoveryCallback, &context); for (;;) { pthread_mutex_lock(&mut); while (targetStatus == 0xFFFF) pthread_cond_wait(&cond, &mut); pthread_mutex_unlock(&mut); fprintf(stderr, "Discovered %d targets\n", numberOfDiscoveredTargets); if (numberOfDiscoveredTargets > 0) { targetStatus = 0xFFFF; status = phLibNfc_RemoteDev_Connect(discoveredTargets[0].hTargetDev, remoteDevConnectCallback, &context); if (status == NFCSTATUS_PENDING) { pthread_mutex_lock(&mut); while (targetStatus == 0xFFFF) pthread_cond_wait(&cond, &mut); pthread_mutex_unlock(&mut); if (targetStatus == NFCSTATUS_SUCCESS) { targetStatus = 0xFFFF; status = phLibNfc_Ndef_CheckNdef(discoveredTargets[0].hTargetDev, remoteDevNdefReadCheckCallback, &context); pthread_mutex_lock(&mut); while (targetStatus == 0xFFFF) pthread_cond_wait(&cond, &mut); pthread_mutex_unlock(&mut); if (targetStatus == NFCSTATUS_SUCCESS && (ndefInfo.NdefCardState == PHLIBNFC_NDEF_CARD_READ_WRITE || ndefInfo.NdefCardState == PHLIBNFC_NDEF_CARD_READ_ONLY)) { phLibNfc_Data_t ndefBuffer; ndefBuffer.length = ndefInfo.MaxNdefMsgLength; ndefBuffer.buffer = malloc(ndefBuffer.length); targetStatus = 0xFFFF; status = phLibNfc_Ndef_Read(discoveredTargets[0].hTargetDev, &ndefBuffer, phLibNfc_Ndef_EBegin, remoteDevNdefReadCallback, &context); pthread_mutex_lock(&mut); while (targetStatus == 0xFFFF) pthread_cond_wait(&cond, &mut); pthread_mutex_unlock(&mut); if (targetStatus == NFCSTATUS_SUCCESS) { int i; fprintf(stderr, "NDEF: "); for (i = 0; i < ndefBuffer.length; ++i) fprintf(stderr, "%02x", ndefBuffer.buffer[i]); fprintf(stderr, "\n"); } free(ndefBuffer.buffer); } } } } if (status == NFCSTATUS_FAILED) { fprintf(stderr, "Failed to connect to remote device\n"); break; } targetStatus = 0xFFFF; status = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_RESUME, discoveryConfig, discoveryCallback, &context); assert(status == NFCSTATUS_SUCCESS || status == NFCSTATUS_PENDING); } } printf("Deinitializing NFC stack.\n"); callbackStatus = 0xFFFF; status = phLibNfc_Mgt_DeInitialize(hwRef, initializeCallback, &callbackStatus); assert(status == NFCSTATUS_PENDING); pthread_mutex_lock(&mut); while (callbackStatus == 0xFFFF) pthread_cond_wait(&cond, &mut); pthread_mutex_unlock(&mut); assert(callbackStatus == NFCSTATUS_SUCCESS); terminateMessageThread(driverConfig.nClientId); pthread_join(messageThread, NULL); printf("Unconfiguring NFC driver.\n"); status = phLibNfc_Mgt_UnConfigureDriver(hwRef); assert(status == NFCSTATUS_SUCCESS); int result = phDal4Nfc_msgctl(driverConfig.nClientId, 0, 0); assert(result == 0); printf("Closing NFC device.\n"); nfc_pn544_close(nfcDevice); }
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; }