static jboolean com_NativeLlcpServiceSocket_doClose(JNIEnv *e, jobject o) { NFCSTATUS ret; phLibNfc_Handle hLlcpSocket; nfc_jni_native_monitor_t * pMonitor = nfc_jni_get_monitor(); TRACE("Close Service socket"); /* Retrieve socket handle */ hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); pthread_mutex_lock(&pMonitor->incoming_socket_mutex); /* TODO: implement accept abort */ pthread_cond_broadcast(&pMonitor->incoming_socket_cond); pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Close(hLlcpSocket); REENTRANCE_UNLOCK(); if(ret == NFCSTATUS_SUCCESS) { TRACE("Close Service socket OK"); return TRUE; } else { LOGD("Close Service socket KO"); return FALSE; } }
void nfc_cb_data_releaseAll() { nfc_jni_callback_data* pCallbackData; while (listGetAndRemoveNext(&nfc_jni_get_monitor()->sem_list, (void**)&pCallbackData)) { pCallbackData->status = NFCSTATUS_FAILED; sem_post(&pCallbackData->sem); } }
void nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData) { /* Destroy semaphore */ if (sem_destroy(&pCallbackData->sem)) { ALOGE("Failed to destroy semaphore (errno=0x%08x)", errno); } /* Remove from active semaphore list */ if (!listRemove(&nfc_jni_get_monitor()->sem_list, pCallbackData)) { ALOGE("Failed to remove semaphore from the list"); } }
bool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext) { /* Create semaphore */ if(sem_init(&pCallbackData->sem, 0, 0) == -1) { ALOGE("Semaphore creation failed (errno=0x%08x)", errno); return false; } /* Set default status value */ pCallbackData->status = NFCSTATUS_FAILED; /* Copy the context */ pCallbackData->pContext = pContext; /* Add to active semaphore list */ if (!listAdd(&nfc_jni_get_monitor()->sem_list, pCallbackData)) { ALOGE("Failed to add the semaphore to the list"); } return true; }
/* * Methods */ static jobject com_NativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, jint miu, jint rw, jint linearBufferLength) { NFCSTATUS ret = NFCSTATUS_SUCCESS; struct timespec ts; phLibNfc_Llcp_sSocketOptions_t sOptions; phNfc_sData_t sWorkingBuffer; jfieldID f; jclass clsNativeLlcpSocket; jobject clientSocket = NULL; struct nfc_jni_callback_data cb_data; phLibNfc_Handle hIncomingSocket, hServerSocket; nfc_jni_native_monitor_t * pMonitor = nfc_jni_get_monitor(); /* Create the local semaphore */ if (!nfc_cb_data_init(&cb_data, NULL)) { goto clean_and_return; } /* Get server socket */ hServerSocket = nfc_jni_get_nfc_socket_handle(e,o); /* Set socket options with the socket options of the service */ sOptions.miu = miu; sOptions.rw = rw; /* Allocate Working buffer length */ sWorkingBuffer.buffer = (uint8_t*)malloc((miu*rw)+miu+linearBufferLength); sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; while(cb_data.status != NFCSTATUS_SUCCESS) { /* Wait for tag Notification */ pthread_mutex_lock(&pMonitor->incoming_socket_mutex); while ((hIncomingSocket = getIncomingSocket(pMonitor, hServerSocket)) == NULL) { pthread_cond_wait(&pMonitor->incoming_socket_cond, &pMonitor->incoming_socket_mutex); } pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); /* Accept the incomming socket */ TRACE("phLibNfc_Llcp_Accept()"); REENTRANCE_LOCK(); ret = phLibNfc_Llcp_Accept( hIncomingSocket, &sOptions, &sWorkingBuffer, nfc_jni_llcp_transport_socket_err_callback, nfc_jni_llcp_accept_socket_callback, (void*)&cb_data); REENTRANCE_UNLOCK(); if(ret != NFCSTATUS_PENDING) { // NOTE: This may happen if link went down since incoming socket detected, then // just drop it and start a new accept loop. LOGD("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); continue; } TRACE("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); /* Wait for callback response */ if(sem_wait(&cb_data.sem)) { LOGE("Failed to wait for semaphore (errno=0x%08x)", errno); goto clean_and_return; } if(cb_data.status != NFCSTATUS_SUCCESS) { /* NOTE: Do not generate an error if the accept failed to avoid error in server application */ LOGD("Failed to accept incoming socket 0x%04x[%s]", cb_data.status, nfc_jni_get_status_name(cb_data.status)); } } /* Create new LlcpSocket object */ if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpSocket",&(clientSocket)) == -1) { LOGD("LLCP Socket creation error"); goto clean_and_return; } /* Get NativeConnectionOriented class object */ clsNativeLlcpSocket = e->GetObjectClass(clientSocket); if(e->ExceptionCheck()) { LOGD("LLCP Socket get class object error"); goto clean_and_return; } /* Set socket handle */ f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); e->SetIntField(clientSocket, f,(jint)hIncomingSocket); /* Set socket MIU */ f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); e->SetIntField(clientSocket, f,(jint)miu); /* Set socket RW */ f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); e->SetIntField(clientSocket, f,(jint)rw); TRACE("socket handle 0x%02x: MIU = %d, RW = %d\n",hIncomingSocket, miu, rw); clean_and_return: nfc_cb_data_deinit(&cb_data); return clientSocket; }