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;
}
Ejemplo n.º 2
0
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(&registryInfo, 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(&registry_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;
}