diff options
Diffstat (limited to 'nxp/jni/com_android_nfc_NativeNfcManager.cpp')
-rwxr-xr-x[-rw-r--r--] | nxp/jni/com_android_nfc_NativeNfcManager.cpp | 1022 |
1 files changed, 896 insertions, 126 deletions
diff --git a/nxp/jni/com_android_nfc_NativeNfcManager.cpp b/nxp/jni/com_android_nfc_NativeNfcManager.cpp index d82291b..af0e4fb 100644..100755 --- a/nxp/jni/com_android_nfc_NativeNfcManager.cpp +++ b/nxp/jni/com_android_nfc_NativeNfcManager.cpp @@ -30,6 +30,34 @@ #define ERROR_BUFFER_TOO_SMALL -12 #define ERROR_INSUFFICIENT_RESOURCES -9 +/**************************************************************** +* define CONFIG_CE_DEFAULT in order to always enable PCD A +* discovery while the discovery loop is on. +* The only case where this is an issue is when a remote device +* is another android NFC device and has an activity triggered +* on an intent of ISO14443 technology discovery. +* +* if this is the case then the P2P NDEF PUSH service will never +* get notified there is another NDEF client because the client +* will actually get discovered as a ISO14443 tag. +* +* if CONFIG_CE_DEFAULT is NOT defined, then the issue with +* this case is mostly solved because the PCD A/B modes can +* only be activated when the foreground activity calls for them in +* enableForegroundDispatch +* and they are de-activated whenever the device turns off +* discovery loop +* +* HOST CARD EMULATION PATCH 1.01 +* Author: doug yeager (doug@simplytapp.com) +******************************************************************/ +#define HOST_EMULATION +//#define CONFIG_CE_DEFAULT +#define TURN_CE_ON 1 +#define TURN_CE_OFF 0 +#define UNBLOCK_CE_CALLBACK 2 +#define INIT_CE 3 + extern uint32_t libnfc_llc_error_count; static phLibNfc_sConfig_t gDrvCfg; @@ -39,6 +67,11 @@ static phNfc_sData_t gOutputParam; uint8_t device_connected_flag; static bool driverConfigured = FALSE; +static bool ceAOn = FALSE; +static bool ceBOn = FALSE; +static bool turnCeAOn = FALSE; +static bool turnCeBOn = FALSE; +static bool discoveryOn = FALSE; static phLibNfc_Handle hLlcpHandle; static NFCSTATUS lastErrorStatus = NFCSTATUS_FAILED; @@ -70,8 +103,13 @@ static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status); static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status); static void nfc_jni_se_set_mode_callback(void *context, phLibNfc_Handle handle, NFCSTATUS status); +static void nfc_jni_CE_callback(void *context, + phLibNfc_eCE_EvtType_t evt_type, uint32_t handle, NFCSTATUS status); static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status); +static void nfc_jni_CEcfg_callback(void *pContext, NFCSTATUS status); static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume); +static void set_CE_A_mode(uint8_t mode, struct nfc_jni_native_data *nat); +static void set_CE_B_mode(uint8_t mode, struct nfc_jni_native_data *nat); static void nfc_jni_Discovery_notification_callback(void *pContext, phLibNfc_RemoteDevList_t *psRemoteDevList, uint8_t uNofRemoteDev, NFCSTATUS status); @@ -86,7 +124,7 @@ static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock); static void client_kill_deferred_call(void* arg) { struct nfc_jni_native_data *nat = (struct nfc_jni_native_data *)arg; - + nat->running = FALSE; } @@ -94,15 +132,15 @@ static void kill_client(nfc_jni_native_data *nat) { phDal4Nfc_Message_Wrapper_t wrapper; phLibNfc_DeferredCall_t *pMsg; - + usleep(50000); ALOGD("Terminating client thread..."); - + pMsg = (phLibNfc_DeferredCall_t*)malloc(sizeof(phLibNfc_DeferredCall_t)); pMsg->pCallback = client_kill_deferred_call; pMsg->pParameter = (void*)nat; - + wrapper.msg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; wrapper.msg.pMsgData = pMsg; wrapper.msg.Size = sizeof(phLibNfc_DeferredCall_t); @@ -359,7 +397,7 @@ static int nfc_jni_initialize(struct nfc_jni_native_data *nat) { goto force_download; } TRACE("phLibNfc_Mgt_Initialize returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - + /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { @@ -553,18 +591,28 @@ force_download: nat->discovery_cfg.Duration = 300000; /* in ms */ nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; +#if defined (HOST_EMULATION) /* Register for the card emulation mode */ REENTRANCE_LOCK(); - ret = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); + ret = phLibNfc_CE_NtfRegister(nfc_jni_CE_callback,(void *)nat); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_SUCCESS) { - ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",ret); - goto clean_and_return; + ALOGD("pphLibNfc_CE_RemoteDev_NtfRegister returned 0x%02x",ret); } - TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", ret); - - + TRACE("phLibNfc_CE_NtfRegister returned 0x%x\n", ret); +#else + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); +#endif /* ====== END ======= */ ALOGI("NFC Initialized"); @@ -724,7 +772,7 @@ static void *nfc_jni_client_thread(void *arg) } } TRACE("NFC client stopped"); - + nat->vm->DetachCurrentThread(); return NULL; @@ -738,7 +786,7 @@ static phLibNfc_sNfcIPCfg_t nfc_jni_nfcip1_cfg = { 3, { 0x46, 0x66, 0x6D } -}; +}; /* * Callbacks @@ -762,7 +810,7 @@ static void nfc_jni_llcp_linkStatus_callback(void *pContext, TRACE("Callback: nfc_jni_llcp_linkStatus_callback()"); nat->vm->GetEnv( (void **)&e, nat->env_version); - + /* Update link status */ g_eLinkStatus = eLinkStatus; @@ -805,7 +853,7 @@ static void nfc_jni_llcp_linkStatus_callback(void *pContext, { ALOGE("Exception occured"); kill_client(nat); - } + } } } @@ -830,6 +878,16 @@ static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status) sem_post(&pCallbackData->sem); } +static void nfc_jni_CEcfg_callback(void *pContext, NFCSTATUS status) +{ + struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; + LOG_CALLBACK("nfc_jni_CEcfg_callback", status); + + /* Report the callback status and wake up the caller */ + pCallbackData->status = status; + sem_post(&pCallbackData->sem); +} + static void nfc_jni_llcp_transport_listen_socket_callback(void *pContext, phLibNfc_Handle hIncomingSocket) { @@ -887,6 +945,113 @@ static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status) sem_post(&pContextData->sem); } +static void nfc_jni_Discover_14443_4_PCD_callback(void *pContext, phLibNfc_Handle handle, phNfc_sData_t *data, NFCSTATUS status) +{ + JNIEnv *e; + NFCSTATUS ret; + jclass tag_cls = NULL; + jobject tag; + jmethodID ctor; + jfieldID f; + struct nfc_jni_native_data *nat; + uint16_t j; + phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t *) handle; + phLibNfc_RemoteDevList_t psRemoteDevList[1]; + uint8_t *buffer; + + nat = (struct nfc_jni_native_data *)pContext; + + nat->vm->GetEnv( (void **)&e, nat->env_version); + + if(status == NFCSTATUS_DESELECTED) + { + if(!device_connected_flag) + { + //free handle memory + phOsalNfc_FreeMemory(psRemoteDevInfo); + } + LOG_CALLBACK("nfc_jni_Discover_14443_4_PCD_callback: Target deselected", status); + } + else + { + LOG_CALLBACK("nfc_jni_discover_14443_4_PCD_callback", status); + + storedHandle = handle; + /* Reset device connected flag */ + device_connected_flag = 1; + + //store the incoming data + if(psRemoteDevInfo!=NULL) + { + buffer = (uint8_t*)malloc(data->length); + memcpy(buffer, data->buffer, data->length); + psRemoteDevInfo->RemoteDevInfo.Iso14443_4_PCD_Info.buffer = buffer; + psRemoteDevInfo->RemoteDevInfo.Iso14443_4_PCD_Info.length = data->length; + } + + + tag_cls = e->GetObjectClass(nat->cached_NfcTag); + if(e->ExceptionCheck()) + { + kill_client(nat); + return; + } + + /* New tag instance */ + ctor = e->GetMethodID(tag_cls, "<init>", "()V"); + tag = e->NewObject(tag_cls, ctor); + + /* Generate technology list */ + jintArray techList; + jintArray handleList; + jintArray typeList; + psRemoteDevList[0].psRemoteDevInfo = psRemoteDevInfo; + psRemoteDevList[0].hTargetDev = handle; + nfc_jni_get_technology_tree(e, psRemoteDevList, + 1, + &techList, &handleList, &typeList); + + /* Push the technology list into the java object */ + f = e->GetFieldID(tag_cls, "mTechList", "[I"); + e->SetObjectField(tag, f, techList); + + f = e->GetFieldID(tag_cls, "mTechHandles", "[I"); + e->SetObjectField(tag, f, handleList); + + f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I"); + e->SetObjectField(tag, f, typeList); + + f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I"); + e->SetIntField(tag, f,(jint)-1); + + f = e->GetFieldID(tag_cls, "mConnectedHandle", "I"); + e->SetIntField(tag, f,(jint)-1); + + if(techList!=NULL) + e->DeleteLocalRef(techList); + if(handleList!=NULL) + e->DeleteLocalRef(handleList); + if(typeList!=NULL) + e->DeleteLocalRef(typeList); + + if (nat->tag != NULL) { + e->DeleteGlobalRef(nat->tag); + } + nat->tag = e->NewGlobalRef(tag); + + /* Notify the service */ + TRACE("Notify Nfc Service"); + /* Notify manager that new a tag was found */ + e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag); + if(e->ExceptionCheck()) + { + ALOGE("Exception occured"); + kill_client(nat); + } + e->DeleteLocalRef(tag); + } +} + static uint8_t find_preferred_target(phLibNfc_RemoteDevList_t *psRemoteDevList, uint8_t uNoOfRemoteDev) { @@ -923,20 +1088,20 @@ static void nfc_jni_Discovery_notification_callback(void *pContext, int target_index = 0; // Target that will be reported (if multiple can be >0) nat = (struct nfc_jni_native_data *)pContext; - + nat->vm->GetEnv( (void **)&e, nat->env_version); - + if(status == NFCSTATUS_DESELECTED) { - LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status); - + LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status); + /* Notify manager that a target was deselected */ e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected); if(e->ExceptionCheck()) { ALOGE("Exception occured"); kill_client(nat); - } + } } else { @@ -956,34 +1121,34 @@ static void nfc_jni_Discovery_notification_callback(void *pContext, tag_cls = e->GetObjectClass(nat->cached_P2pDevice); if(e->ExceptionCheck()) { - ALOGE("Get Object Class Error"); + ALOGE("Get Object Class Error"); kill_client(nat); return; - } - + } + /* New target instance */ ctor = e->GetMethodID(tag_cls, "<init>", "()V"); tag = e->NewObject(tag_cls, ctor); - + /* Set P2P Target mode */ - f = e->GetFieldID(tag_cls, "mMode", "I"); - + f = e->GetFieldID(tag_cls, "mMode", "I"); + if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) { ALOGD("Discovered P2P Initiator"); e->SetIntField(tag, f, (jint)MODE_P2P_INITIATOR); } else - { + { ALOGD("Discovered P2P Target"); e->SetIntField(tag, f, (jint)MODE_P2P_TARGET); } - + if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) { /* Set General Bytes */ f = e->GetFieldID(tag_cls, "mGeneralBytes", "[B"); - + TRACE("General Bytes length ="); for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++) { @@ -991,11 +1156,11 @@ static void nfc_jni_Discovery_notification_callback(void *pContext, } generalBytes = e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length); - - e->SetByteArrayRegion(generalBytes, 0, + + e->SetByteArrayRegion(generalBytes, 0, remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length, (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo); - + e->SetObjectField(tag, f, generalBytes); } @@ -1066,21 +1231,21 @@ static void nfc_jni_Discovery_notification_callback(void *pContext, } nat->tag = e->NewGlobalRef(tag); - /* Notify the service */ + /* Notify the service */ TRACE("Notify Nfc Service"); if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) { /* Store the hanlde of the P2P device */ hLlcpHandle = remDevHandle; - + /* Notify manager that new a P2P device was found */ e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag); if(e->ExceptionCheck()) { ALOGE("Exception occured"); kill_client(nat); - } + } } else { @@ -1090,10 +1255,10 @@ static void nfc_jni_Discovery_notification_callback(void *pContext, { ALOGE("Exception occured"); kill_client(nat); - } + } } e->DeleteLocalRef(tag); - } + } } static void nfc_jni_init_callback(void *pContext, NFCSTATUS status) @@ -1294,6 +1459,111 @@ static void nfc_jni_transaction_callback(void *context, } } +/* Card Emulation callback */ +static void nfc_jni_CE_callback(void *context, + phLibNfc_eCE_EvtType_t evt_type, uint32_t handle, + NFCSTATUS status) +{ + JNIEnv *e; + jobject tmp_array = NULL; + jobject mifare_block = NULL; + struct nfc_jni_native_data *nat; + phNfc_sData_t *aid; + phNfc_sData_t *mifare_command; + int i=0; + + LOG_CALLBACK("nfc_jni_CE_callback", status); + nat = (struct nfc_jni_native_data *)context; + + nat->vm->GetEnv( (void **)&e, nat->env_version); + + if(status == NFCSTATUS_SUCCESS) + { + switch(evt_type) + { + case phLibNfc_eCE_B_EvtActivated: + { + if(!device_connected_flag) + { + TRACE("> CE EVT B ACTIVATED"); + /* Receive */ + TRACE("phLibNfc_RemoteDev_CE_B_Receive()"); + REENTRANCE_LOCK(); + status = phLibNfc_RemoteDev_CE_B_Receive(nfc_jni_Discover_14443_4_PCD_callback,(void *)context); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_PENDING) + { + ALOGE("phLibNfc_RemoteDev_CE_B_Receive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); + goto error; + } + } + }break; + case phLibNfc_eCE_A_EvtActivated: + { + if(!device_connected_flag) + { + TRACE("> CE EVT A ACTIVATED"); + /* Receive */ + TRACE("phLibNfc_RemoteDev_CE_A_Receive()"); + REENTRANCE_LOCK(); + status = phLibNfc_RemoteDev_CE_A_Receive(nfc_jni_Discover_14443_4_PCD_callback,(void *)context); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_PENDING) + { + ALOGE("phLibNfc_RemoteDev_CE_A_Receive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); + goto error; + } + } + }break; + case phLibNfc_eCE_B_EvtDeActivated: + case phLibNfc_eCE_A_EvtDeActivated: + { + LOG_CALLBACK("nfc_jni_Discover_14443_4_PCD_callback: Target deselected", status); + if(!device_connected_flag || storedHandle!=handle) + { + //free handle memory + phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t *) handle; + phOsalNfc_FreeMemory(psRemoteDevInfo); + } + TRACE("> CE EVT A DEACTIVATED"); + }break; + case phLibNfc_eCE_EvtFieldOn: + { + TRACE("> CE EVT_FIELD_ON"); + }break; + + case phLibNfc_eCE_EvtFieldOff: + { + TRACE("> CE EVT_FIELD_OFF"); + }break; + + default: + { + TRACE("Unknown CE event"); + }break; + } + } + else + { + ALOGE("CE transaction notification error"); + goto error; + } + + /* Function finished, now clean and return */ + goto clean_and_return; + + error: + /* In case of error, just discard the notification */ + ALOGE("Failed to send CE transaction notification"); + e->ExceptionClear(); + + clean_and_return: + if(tmp_array != NULL) + { + e->DeleteLocalRef(tmp_array); + } +} + static void nfc_jni_se_set_mode_callback(void *pContext, phLibNfc_Handle handle, NFCSTATUS status) { @@ -1330,6 +1600,9 @@ static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool /* Reset device connected flag */ device_connected_flag = 0; + set_CE_A_mode(UNBLOCK_CE_CALLBACK, nat); + set_CE_B_mode(UNBLOCK_CE_CALLBACK, nat); + /* Start Polling loop */ TRACE("****** Start NFC Discovery ******"); REENTRANCE_LOCK(); @@ -1348,6 +1621,9 @@ static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool if(ret != NFCSTATUS_PENDING) { + set_CE_A_mode(TURN_CE_OFF, nat); + set_CE_B_mode(TURN_CE_OFF, nat); + discoveryOn = FALSE; emergency_recovery(nat); goto clean_and_return; } @@ -1356,9 +1632,22 @@ static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool if(sem_wait(&cb_data.sem)) { ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + set_CE_A_mode(TURN_CE_OFF, nat); + set_CE_B_mode(TURN_CE_OFF, nat); + discoveryOn = FALSE; goto clean_and_return; } + discoveryOn = TRUE; +#ifndef CONFIG_CE_DEFAULT + if(turnCeAOn) + set_CE_A_mode(TURN_CE_ON, nat); + if(turnCeBOn) + set_CE_B_mode(TURN_CE_ON, nat); +#else + set_CE_A_mode(TURN_CE_ON, nat); +#endif + clean_and_return: nfc_cb_data_deinit(&cb_data); } @@ -1369,6 +1658,9 @@ static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) NFCSTATUS ret; struct nfc_jni_callback_data cb_data; + set_CE_A_mode(TURN_CE_OFF, nat); + set_CE_B_mode(TURN_CE_OFF, nat); + /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { @@ -1379,7 +1671,7 @@ static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode; discovery_cfg.NfcIP_Target_Mode = 0; discovery_cfg.NfcIP_Tgt_Disable = TRUE; - + /* Start Polling loop */ TRACE("****** Stop NFC Discovery ******"); REENTRANCE_LOCK(); @@ -1407,10 +1699,464 @@ static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) goto clean_and_return; } + discoveryOn = FALSE; + clean_and_return: nfc_cb_data_deinit(&cb_data); } +static void set_CE_A_mode(uint8_t mode, struct nfc_jni_native_data *nat) +{ +#if defined (HOST_EMULATION) + uint8_t unblocked = FALSE; + NFCSTATUS status; + struct nfc_jni_callback_data cb_data; + + if(mode==INIT_CE) + { + ceAOn=FALSE; + /* Create the local semaphore */ + if (!nfc_cb_data_init(&cb_data, NULL)) + { + goto clean_and_return; + } + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_A_14443_4_ConfigParams(TRUE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status == NFCSTATUS_PENDING) + { + sem_wait(&cb_data.sem); + } + TRACE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_A_14443_4_ConfigParams(FALSE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status == NFCSTATUS_PENDING) + { + sem_wait(&cb_data.sem); + } + ceAOn=FALSE; + + if(ceAOn==TRUE || ceBOn==TRUE) + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfUnregister(); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + else + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + + return; + } + + if(mode==TURN_CE_ON || mode==TURN_CE_OFF) + turnCeAOn = FALSE; //reset flag + + if(ceAOn==TRUE && mode==TURN_CE_ON) + return; //already on + if(ceAOn==FALSE && mode==TURN_CE_OFF) + return; //already off + if(ceAOn==FALSE && mode==UNBLOCK_CE_CALLBACK) + return; //can't block when it is already off + + if(discoveryOn==FALSE && mode==TURN_CE_ON) + { + turnCeAOn = TRUE; //turn on when discovery turns on + return; + } + + if(mode==TURN_CE_OFF || mode==UNBLOCK_CE_CALLBACK) + if(phLibNfc_Mgt_Unblock_Cb_CE_A_14443_4( )==NFCSTATUS_SUCCESS) + unblocked=TRUE; + + + /* Create the local semaphore */ + if (!nfc_cb_data_init(&cb_data, NULL)) + { + goto clean_and_return; + } + + if(mode==TURN_CE_OFF || (mode==UNBLOCK_CE_CALLBACK && unblocked==TRUE)) + { + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_A_14443_4_ConfigParams(FALSE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_PENDING) + { + ALOGE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + goto clean_and_return; + } + TRACE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + + /* Wait for callback response */ + if(sem_wait(&cb_data.sem)) + { + ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + goto clean_and_return; + } + + ceAOn=FALSE; + } + + if(mode==TURN_CE_ON || (mode==UNBLOCK_CE_CALLBACK && unblocked==TRUE && discoveryOn==TRUE)) + { + TRACE("phLibNfc_SE_SetMode()"); + /* Set SE mode - Default */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault, + nfc_jni_se_set_mode_callback, (void *)&cb_data); + REENTRANCE_UNLOCK(); + + TRACE("phLibNfc_SE_SetMode returned 0x%02x", status); + if (status != NFCSTATUS_PENDING) { + ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); + goto clean_and_return; + } + TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); + + /* Wait for callback response */ + if (sem_wait(&cb_data.sem)) { + ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + goto clean_and_return; + } + + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_A_14443_4_ConfigParams(TRUE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_PENDING) + { + ALOGE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + goto clean_and_return; + } + TRACE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + /* Wait for callback response */ + if(sem_wait(&cb_data.sem)) + { + ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + goto clean_and_return; + } + + ceAOn=TRUE; + } + +clean_and_return: + + if(ceAOn==TRUE || ceBOn==TRUE) + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfUnregister(); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + else + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + +#endif //HOST_EMULATION +} + +static void set_CE_B_mode(uint8_t mode, struct nfc_jni_native_data *nat) +{ +#if defined (HOST_EMULATION) + uint8_t unblocked = FALSE; + NFCSTATUS status; + struct nfc_jni_callback_data cb_data; + + if(mode==INIT_CE) + { + ceBOn=FALSE; + /* Create the local semaphore */ + if (!nfc_cb_data_init(&cb_data, NULL)) + { + goto clean_and_return; + } + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams(TRUE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status == NFCSTATUS_PENDING) + { + sem_wait(&cb_data.sem); + } + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams(FALSE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status == NFCSTATUS_PENDING) + { + sem_wait(&cb_data.sem); + } + ceBOn=FALSE; + + if(ceAOn==TRUE || ceBOn==TRUE) + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfUnregister(); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + else + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + + return; + } + + if(mode==TURN_CE_ON || mode==TURN_CE_OFF) + turnCeBOn = FALSE; //reset flag + + if(ceBOn==TRUE && mode==TURN_CE_ON) + return; //already on + if(ceBOn==FALSE && mode==TURN_CE_OFF) + return; //already off + if(ceBOn==FALSE && mode==UNBLOCK_CE_CALLBACK) + return; //can't block when it is already off + + if(discoveryOn==FALSE && mode==TURN_CE_ON) + { + turnCeBOn = TRUE; //turn on when discovery turns on + return; + } + + if(mode==TURN_CE_OFF || mode==UNBLOCK_CE_CALLBACK) + if(phLibNfc_Mgt_Unblock_Cb_CE_B_14443_4( )==NFCSTATUS_SUCCESS) + unblocked=TRUE; + + + /* Create the local semaphore */ + if (!nfc_cb_data_init(&cb_data, NULL)) + { + goto clean_and_return; + } + + if(mode==TURN_CE_OFF || (mode==UNBLOCK_CE_CALLBACK && unblocked==TRUE)) + { + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams(FALSE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_PENDING) + { + ALOGE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + goto clean_and_return; + } + TRACE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + + /* Wait for callback response */ + if(sem_wait(&cb_data.sem)) + { + ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + goto clean_and_return; + } + + ceBOn=FALSE; + } + + if(mode==TURN_CE_ON || (mode==UNBLOCK_CE_CALLBACK && unblocked==TRUE && discoveryOn==TRUE)) + { + TRACE("phLibNfc_SE_SetMode()"); + /* Set SE mode - Default */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault, + nfc_jni_se_set_mode_callback, (void *)&cb_data); + REENTRANCE_UNLOCK(); + + TRACE("phLibNfc_SE_SetMode returned 0x%02x", status); + if (status != NFCSTATUS_PENDING) { + ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); + goto clean_and_return; + } + TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); + + /* Wait for callback response */ + if (sem_wait(&cb_data.sem)) { + ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + goto clean_and_return; + } + + REENTRANCE_LOCK(); + status = phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams(TRUE, + nfc_jni_CEcfg_callback, + (void *)&cb_data); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_PENDING) + { + ALOGE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + goto clean_and_return; + } + TRACE("phLibNfc_Mgt_SetCE_14443_4_ConfigParams returned 0x%04x[%s]", status, + nfc_jni_get_status_name(status)); + + /* Wait for callback response */ + if(sem_wait(&cb_data.sem)) + { + ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); + goto clean_and_return; + } + + ceBOn=TRUE; + } + +clean_and_return: + + if(ceAOn==TRUE || ceBOn==TRUE) + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfUnregister(); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + else + { + /* Register for the SE card emulation mode */ + REENTRANCE_LOCK(); + status = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); + REENTRANCE_UNLOCK(); + if(status != NFCSTATUS_SUCCESS) + { + ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",status); + goto clean_and_return; + } + TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", status); + } + +#endif //HOST EMULATION +} + +static void com_android_nfc_NfcManager_disableCE_A(JNIEnv *e, jobject o) +{ +#ifndef CONFIG_CE_DEFAULT + struct nfc_jni_native_data *nat; + + CONCURRENCY_LOCK(); + + /* Retrieve native structure address */ + nat = nfc_jni_get_nat(e, o); + + set_CE_A_mode(TURN_CE_OFF, nat); + CONCURRENCY_UNLOCK(); +#endif + return; +} + +static void com_android_nfc_NfcManager_enableCE_A(JNIEnv *e, jobject o) +{ +#ifndef CONFIG_CE_DEFAULT + struct nfc_jni_native_data *nat; + + CONCURRENCY_LOCK(); + + /* Retrieve native structure address */ + nat = nfc_jni_get_nat(e, o); + + set_CE_A_mode(TURN_CE_ON, nat); + CONCURRENCY_UNLOCK(); +#endif + return; +} + +static void com_android_nfc_NfcManager_disableCE_B(JNIEnv *e, jobject o) +{ + struct nfc_jni_native_data *nat; + + CONCURRENCY_LOCK(); + + /* Retrieve native structure address */ + nat = nfc_jni_get_nat(e, o); + + set_CE_B_mode(TURN_CE_OFF, nat); + CONCURRENCY_UNLOCK(); + return; +} + +static void com_android_nfc_NfcManager_enableCE_B(JNIEnv *e, jobject o) +{ + struct nfc_jni_native_data *nat; + + CONCURRENCY_LOCK(); + + /* Retrieve native structure address */ + nat = nfc_jni_get_nat(e, o); + + set_CE_B_mode(TURN_CE_ON, nat); + CONCURRENCY_UNLOCK(); + return; +} static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o) { @@ -1420,13 +2166,13 @@ static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o) /* Retrieve native structure address */ nat = nfc_jni_get_nat(e, o); - + nfc_jni_stop_discovery_locked(nat); CONCURRENCY_UNLOCK(); } - + static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) { NFCSTATUS ret; struct nfc_jni_native_data *nat; @@ -1624,31 +2370,31 @@ static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject jobject obj; jfieldID f; - TRACE("****** Init Native Structure ******"); + TRACE("****** Init Native Structure ******"); /* Initialize native structure */ nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); if(nat == NULL) { ALOGD("malloc of nfc_jni_native_data failed"); - return FALSE; + return FALSE; } memset(nat, 0, sizeof(*nat)); e->GetJavaVM(&(nat->vm)); nat->env_version = e->GetVersion(); nat->manager = e->NewGlobalRef(o); - + cls = e->GetObjectClass(o); f = e->GetFieldID(cls, "mNative", "I"); e->SetIntField(o, f, (jint)nat); - + /* Initialize native cached references */ cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls, "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V"); cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls, "notifyTransactionListeners", "([B)V"); - + cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls, "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); @@ -1682,7 +2428,7 @@ static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1) { ALOGD("Native Structure initialization failed"); - return FALSE; + return FALSE; } TRACE("****** Init Native Structure OK ******"); return TRUE; @@ -1698,7 +2444,7 @@ static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) char value[PROPERTY_VALUE_MAX]; #endif jboolean result; - + CONCURRENCY_LOCK(); #ifdef TNFC_EMULATOR_ONLY @@ -1744,6 +2490,12 @@ static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) /* Perform the initialization */ init_result = nfc_jni_initialize(nat); + if(init_result==TRUE) + { + set_CE_A_mode(INIT_CE, nat); + set_CE_B_mode(INIT_CE, nat); + } + clean_and_return: CONCURRENCY_UNLOCK(); @@ -1835,7 +2587,7 @@ static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jo uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE; TRACE("****** Get Secure Element List ******"); - + TRACE("phLibNfc_SE_GetSecureElementList()"); REENTRANCE_LOCK(); ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count); @@ -1876,6 +2628,9 @@ static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject /* Retrieve native structure address */ nat = nfc_jni_get_nat(e, o); + set_CE_A_mode(TURN_CE_OFF, nat); + set_CE_B_mode(TURN_CE_OFF, nat); + /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; @@ -1916,6 +2671,9 @@ static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobjec /* Retrieve native structure address */ nat = nfc_jni_get_nat(e, o); + set_CE_A_mode(UNBLOCK_CE_CALLBACK, nat); + set_CE_B_mode(UNBLOCK_CE_CALLBACK, nat); + /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; @@ -1929,7 +2687,7 @@ static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobjec ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault, nfc_jni_se_set_mode_callback, (void *)&cb_data); REENTRANCE_UNLOCK(); - + TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret); if (ret != NFCSTATUS_PENDING) { ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); @@ -2031,7 +2789,7 @@ static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o) else { ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return JNI_FALSE; + return JNI_FALSE; } } @@ -2049,10 +2807,10 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEn phLibNfc_Llcp_sLinkParameters_t sParams; jclass clsNativeConnectionlessSocket; jfieldID f; - + /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - + nat = nfc_jni_get_nat(e, o); + /* Allocate Working buffer length */ phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams); sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP @@ -2068,7 +2826,7 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEn nfc_jni_llcp_transport_socket_err_callback, (void*)nat); REENTRANCE_UNLOCK(); - + if(ret != NFCSTATUS_SUCCESS) { lastErrorStatus = ret; @@ -2085,7 +2843,7 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEn serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); serviceName.length = (uint32_t)e->GetStringUTFLength(sn); } - + /* Bind socket */ TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); REENTRANCE_LOCK(); @@ -2097,41 +2855,41 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEn ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Close socket created */ REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); + ret = phLibNfc_Llcp_Close(hLlcpSocket); REENTRANCE_UNLOCK(); goto error; } TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - + + /* Create new NativeLlcpConnectionlessSocket object */ if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1) { goto error; - } - + } + /* Get NativeConnectionless class object */ clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket); if(e->ExceptionCheck()) { goto error; } - + /* Set socket handle */ f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I"); e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket); - TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); - + TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); + /* Set the miu link of the connectionless socket */ f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I"); e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT); - TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); - + TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); + /* Set socket SAP */ f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I"); e->SetIntField(connectionlessSocket, f,(jint)nSap); - TRACE("Connectionless socket SAP = %d\n",nSap); - + TRACE("Connectionless socket SAP = %d\n",nSap); + return connectionlessSocket; error: if (serviceName.buffer != NULL) { @@ -2155,20 +2913,20 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, j struct nfc_jni_native_data *nat; jobject serviceSocket = NULL; jclass clsNativeLlcpServiceSocket; - jfieldID f; - + jfieldID f; + /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - + nat = nfc_jni_get_nat(e, o); + /* Set Connection Oriented socket options */ sOptions.miu = miu; - sOptions.rw = rw; - + sOptions.rw = rw; + /* Allocate Working buffer length */ sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); - + /* Create socket */ TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle); REENTRANCE_LOCK(); @@ -2179,7 +2937,7 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, j nfc_jni_llcp_transport_socket_err_callback, (void*)nat); REENTRANCE_UNLOCK(); - + if(ret != NFCSTATUS_SUCCESS) { ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); @@ -2207,7 +2965,7 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, j lastErrorStatus = ret; ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Close socket created */ - ret = phLibNfc_Llcp_Close(hLlcpSocket); + ret = phLibNfc_Llcp_Close(hLlcpSocket); goto error; } TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); @@ -2218,53 +2976,53 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, j nfc_jni_llcp_transport_listen_socket_callback, (void*)hLlcpSocket); REENTRANCE_UNLOCK(); - + if(ret != NFCSTATUS_SUCCESS) { ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); lastErrorStatus = ret; /* Close created socket */ REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); + ret = phLibNfc_Llcp_Close(hLlcpSocket); REENTRANCE_UNLOCK(); goto error; - } + } TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - + /* Create new NativeLlcpServiceSocket object */ if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1) { ALOGE("Llcp Socket object creation error"); goto error; - } - + } + /* Get NativeLlcpServiceSocket class object */ clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket); if(e->ExceptionCheck()) { ALOGE("Llcp Socket get object class error"); goto error; - } - + } + /* Set socket handle */ f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I"); e->SetIntField(serviceSocket, f,(jint)hLlcpSocket); - TRACE("Service socket Handle = %02x\n",hLlcpSocket); - + TRACE("Service socket Handle = %02x\n",hLlcpSocket); + /* Set socket linear buffer length */ f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); e->SetIntField(serviceSocket, f,(jint)linearBufferLength); - TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); - + TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); + /* Set socket MIU */ f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I"); e->SetIntField(serviceSocket, f,(jint)miu); - TRACE("Service socket MIU = %d\n",miu); - + TRACE("Service socket MIU = %d\n",miu); + /* Set socket RW */ f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I"); e->SetIntField(serviceSocket, f,(jint)rw); - TRACE("Service socket RW = %d\n",rw); + TRACE("Service socket RW = %d\n",rw); return serviceSocket; error: @@ -2284,14 +3042,14 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject struct nfc_jni_native_data *nat; jclass clsNativeLlcpSocket; jfieldID f; - + /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - + nat = nfc_jni_get_nat(e, o); + /* Set Connection Oriented socket options */ sOptions.miu = miu; sOptions.rw = rw; - + /* Allocate Working buffer length */ sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); @@ -2314,22 +3072,22 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject return NULL; } TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - + /* Create new NativeLlcpSocket object */ if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1) { - ALOGE("Llcp socket object creation error"); - return NULL; - } - + ALOGE("Llcp socket object creation error"); + return NULL; + } + /* Get NativeConnectionless class object */ clsNativeLlcpSocket = e->GetObjectClass(clientSocket); if(e->ExceptionCheck()) { - ALOGE("Get class object error"); - return NULL; + ALOGE("Get class object error"); + return NULL; } - + /* Test if an SAP number is present */ if(nSap != 0) { @@ -2344,41 +3102,41 @@ static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Close socket created */ REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); + ret = phLibNfc_Llcp_Close(hLlcpSocket); REENTRANCE_UNLOCK(); return NULL; } TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - + /* Set socket SAP */ f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I"); e->SetIntField(clientSocket, f,(jint)nSap); - TRACE("socket SAP = %d\n",nSap); - } - + TRACE("socket SAP = %d\n",nSap); + } + /* Set socket handle */ f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); e->SetIntField(clientSocket, f,(jint)hLlcpSocket); - TRACE("socket Handle = %02x\n",hLlcpSocket); - + TRACE("socket Handle = %02x\n",hLlcpSocket); + /* Set socket MIU */ f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); e->SetIntField(clientSocket, f,(jint)miu); - TRACE("socket MIU = %d\n",miu); - + TRACE("socket MIU = %d\n",miu); + /* Set socket RW */ f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); e->SetIntField(clientSocket, f,(jint)rw); - TRACE("socket RW = %d\n",rw); - - + TRACE("socket RW = %d\n",rw); + + return clientSocket; } static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o) { TRACE("Last Error Status = 0x%02x",lastErrorStatus); - + if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL) { return ERROR_BUFFER_TOO_SMALL; @@ -2544,25 +3302,25 @@ static JNINativeMethod gMethods[] = {"doInitialize", "()Z", (void *)com_android_nfc_NfcManager_initialize}, - + {"doDeinitialize", "()Z", (void *)com_android_nfc_NfcManager_deinitialize}, - + {"enableDiscovery", "()V", (void *)com_android_nfc_NfcManager_enableDiscovery}, {"doGetSecureElementList", "()[I", (void *)com_android_nfc_NfcManager_doGetSecureElementList}, - + {"doSelectSecureElement", "()V", (void *)com_android_nfc_NfcManager_doSelectSecureElement}, - + {"doDeselectSecureElement", "()V", (void *)com_android_nfc_NfcManager_doDeselectSecureElement}, - + {"doCheckLlcp", "()Z", (void *)com_android_nfc_NfcManager_doCheckLlcp}, - + {"doActivateLlcp", "()Z", (void *)com_android_nfc_NfcManager_doActivateLlcp}, @@ -2574,10 +3332,22 @@ static JNINativeMethod gMethods[] = {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;", (void *)com_android_nfc_NfcManager_doCreateLlcpSocket}, - + {"doGetLastError", "()I", (void *)com_android_nfc_NfcManager_doGetLastError}, + {"disableCE_A", "()V", + (void *)com_android_nfc_NfcManager_disableCE_A}, + + {"enableCE_A", "()V", + (void *)com_android_nfc_NfcManager_enableCE_A}, + + {"enableCE_B", "()V", + (void *)com_android_nfc_NfcManager_enableCE_B}, + + {"disableCE_B", "()V", + (void *)com_android_nfc_NfcManager_disableCE_B}, + {"disableDiscovery", "()V", (void *)com_android_nfc_NfcManager_disableDiscovery}, @@ -2601,9 +3371,9 @@ static JNINativeMethod gMethods[] = {"doDump", "()Ljava/lang/String;", (void *)com_android_nfc_NfcManager_doDump}, -}; - - +}; + + int register_com_android_nfc_NativeNfcManager(JNIEnv *e) { nfc_jni_native_monitor_t *nfc_jni_native_monitor; |