/* Initialize the callback data */ NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t *pCallbackData, void *pContext) { /* Create semaphore */ if (sem_init(&pCallbackData->sem, 0, 0) == -1) { NXPLOG_NCIHAL_E("Semaphore creation failed (errno=0x%08x)", errno); return NFCSTATUS_FAILED; } /* Set default status value */ pCallbackData->status = NFCSTATUS_FAILED; /* Copy the context */ pCallbackData->pContext = pContext; /* Add to active semaphore list */ if (listAdd(&phNxpNciHal_get_monitor()->sem_list, pCallbackData) != 1) { NXPLOG_NCIHAL_E("Failed to add the semaphore to the list"); } return NFCSTATUS_SUCCESS; }
/******************************************************************************* ** ** Function phNxpNciHal_select_RF_Discovery ** ** Description Sends RF_DISCOVER_SELECT_CMD ** Parameters RfID , RfProtocolType ** Returns NFCSTATUS_PENDING if success ** *******************************************************************************/ NFCSTATUS phNxpNciHal_select_RF_Discovery(unsigned int RfID,unsigned int RfProtocolType) { NFCSTATUS status = NFCSTATUS_SUCCESS; phNxpNciHal_Sem_t cb_data; pthread_t pthread; discover_type = DISCOVER_SELECT; cmd_select_rf_discovery[3]=RfID; cmd_select_rf_discovery[4]=RfProtocolType; if(pthread_create(&pthread, NULL, tmp_thread, (void*) &discover_type) != 0) { NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop"); } return status; }
/******************************************************************************* ** ** Function listDestroy ** ** Description List destruction ** ** Returns 1, if list destroyed, 0 if failed ** *******************************************************************************/ int listDestroy(struct listHead* pList) { int bListNotEmpty = 1; while (bListNotEmpty) { bListNotEmpty = listGetAndRemoveNext(pList, NULL); } if (pthread_mutex_destroy(&pList->mutex) == -1) { NXPLOG_NCIHAL_E("Mutex destruction failed (errno=0x%08x)", errno); return 0; } return 1; }
/******************************************************************************* ** ** Function hal_write_cb ** ** Description Callback function for hal write. ** ** Returns None ** *******************************************************************************/ static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo) { phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; if (pInfo->wStatus == NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus); } else { NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus); } p_cb_data->status = pInfo->wStatus; SEM_POST(p_cb_data); return; }
/******************************************************************************* ** ** Function listAdd ** ** Description Add a node to the list ** ** Returns 1, if added, 0 if otherwise ** *******************************************************************************/ int listAdd(struct listHead* pList, void* pData) { struct listNode* pNode; struct listNode* pLastNode; int result; /* Create node */ pNode = (struct listNode*) malloc(sizeof(struct listNode)); if (pNode == NULL) { result = 0; NXPLOG_NCIHAL_E("Failed to malloc"); goto clean_and_return; } pNode->pData = pData; pNode->pNext = NULL; pthread_mutex_lock(&pList->mutex); /* Add the node to the list */ if (pList->pFirst == NULL) { /* Set the node as the head */ pList->pFirst = pNode; } else { /* Seek to the end of the list */ pLastNode = pList->pFirst; while (pLastNode->pNext != NULL) { pLastNode = pLastNode->pNext; } /* Add the node to the current list */ pLastNode->pNext = pNode; } result = 1; clean_and_return: pthread_mutex_unlock(&pList->mutex); return result; }
/******************************************************************************* ** ** Function phNxpNciHal_test_rx_thread ** ** Description Thread to fetch and process messages from message queue. ** ** Returns NULL ** *******************************************************************************/ static void *phNxpNciHal_test_rx_thread(void *arg) { phLibNfc_Message_t msg; NXPLOG_NCIHAL_D("Self test thread started"); thread_running = 1; while (thread_running == 1) { /* Fetch next message from the NFC stack message queue */ if (phDal4Nfc_msgrcv(gDrvCfg.nClientId, &msg, 0, 0) == -1) { NXPLOG_NCIHAL_E("Received bad message"); continue; } if(thread_running == 0) { break; } switch (msg.eMsgType) { case PH_LIBNFC_DEFERREDCALL_MSG: { phLibNfc_DeferredCall_t *deferCall = (phLibNfc_DeferredCall_t *) (msg.pMsgData); REENTRANCE_LOCK(); deferCall->pCallback(deferCall->pParameter); REENTRANCE_UNLOCK(); break; } } } NXPLOG_NCIHAL_D("Self test thread stopped"); return NULL; }
/******************************************************************************* ** ** Function phNxpNciHal_AntennaSelfTest ** ** Description Test function to validate the Antenna's discrete ** components connection. ** ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. ** *******************************************************************************/ NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t * phAntenna_St_Resp ) { NFCSTATUS status = NFCSTATUS_FAILED; NFCSTATUS antenna_st_status = NFCSTATUS_FAILED; int len = 0; int cnt = 0; NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - start\n"); memcpy(&phAntenna_resp, phAntenna_St_Resp, sizeof(phAntenna_St_Resp_t)); len = (sizeof(antenna_self_test_data)/sizeof(antenna_self_test_data[0])); for(cnt = 0; cnt < len; cnt++) { status = phNxpNciHal_performTest(&(antenna_self_test_data[cnt])); if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED) { NXPLOG_NCIHAL_E("phNxpNciHal_AntennaSelfTest: commnad execution - FAILED\n"); break; } } if(status == NFCSTATUS_SUCCESS) { if((gtxldo_status == NFCSTATUS_SUCCESS) && (gagc_value_status == NFCSTATUS_SUCCESS) && (gagc_nfcld_status == NFCSTATUS_SUCCESS) && (gagc_differential_status == NFCSTATUS_SUCCESS)) { antenna_st_status = NFCSTATUS_SUCCESS; NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - SUCESS\n"); } else { NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n"); } } else { NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n"); } NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - end\n"); return antenna_st_status; }
/******************************************************************************* ** ** Function phNxpNciHal_readLocked ** ** Description Reads response and notification from NFCC and waits for ** read completion, for a definitive timeout value. ** ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED, ** NFCSTATUS_RESPONSE_TIMEOUT in case of timeout. ** *******************************************************************************/ static NFCSTATUS phNxpNciHal_readLocked(nci_test_data_t *pData ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phNxpNciHal_Sem_t cb_data; uint16_t read_len = 16; /* RX Buffer */ uint32_t rx_data[NCI_MAX_DATA_LEN]; /* Create the local semaphore */ if (phNxpNciHal_init_cb_data(&cb_data, pData) != NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_D("phTmlNfc_Read Create cb data failed"); status = NFCSTATUS_FAILED; goto clean_and_return; } /* call read pending */ status = phTmlNfc_Read( (uint8_t *) rx_data, (uint16_t) read_len, (pphTmlNfc_TransactCompletionCb_t) &hal_read_cb, &cb_data); if (status != NFCSTATUS_PENDING) { NXPLOG_NCIHAL_E("TML Read status error status = %x", status); status = NFCSTATUS_FAILED; goto clean_and_return; } status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_WRITE_RSP_TIMEOUT, &hal_write_rsp_timeout_cb, &cb_data); if (NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("Response timer started"); } else { NXPLOG_NCIHAL_E("Response timer not started"); status = NFCSTATUS_FAILED; goto clean_and_return; } /* Wait for callback response */ if (SEM_WAIT(cb_data)) { NXPLOG_NCIHAL_E("phTmlNfc_Read semaphore error"); status = NFCSTATUS_FAILED; goto clean_and_return; } if(cb_data.status == NFCSTATUS_RESPONSE_TIMEOUT) { NXPLOG_NCIHAL_E("Response timeout!!!"); status = NFCSTATUS_RESPONSE_TIMEOUT; goto clean_and_return; } if (cb_data.status != NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_E("phTmlNfc_Read failed "); status = NFCSTATUS_FAILED; goto clean_and_return; } clean_and_return: phNxpNciHal_cleanup_cb_data(&cb_data); return status; }
/******************************************************************************* ** ** Function hal_read_cb ** ** Description Callback function for hal read. ** ** Returns None ** *******************************************************************************/ static void hal_read_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo) { phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; if(hal_write_timer_fired == 1) { NXPLOG_NCIHAL_D("hal_read_cb - response timeout occurred"); hal_write_timer_fired = 0; p_cb_data->status = NFCSTATUS_RESPONSE_TIMEOUT; } else { NFCSTATUS status = phOsalNfc_Timer_Stop(timeoutTimerId); if (NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("Response timer stopped"); } else { NXPLOG_NCIHAL_E("Response timer stop ERROR!!!"); p_cb_data->status = NFCSTATUS_FAILED; } if (pInfo->wStatus == NFCSTATUS_SUCCESS) { NXPLOG_NCIHAL_D("hal_read_cb successful status = 0x%x", pInfo->wStatus); p_cb_data->status = NFCSTATUS_SUCCESS; } else { NXPLOG_NCIHAL_E("hal_read_cb error status = 0x%x", pInfo->wStatus); p_cb_data->status = NFCSTATUS_FAILED; } p_cb_data->status = pInfo->wStatus; nci_test_data_t *test_data = (nci_test_data_t*) p_cb_data->pContext; if(test_data->exp_rsp.len == 0) { /* Compare the actual notification with expected notification.*/ if( test_data->ntf_validator(&(test_data->exp_ntf),pInfo) == 1 ) { p_cb_data->status = NFCSTATUS_SUCCESS; } else { p_cb_data->status = NFCSTATUS_FAILED; } } /* Compare the actual response with expected response.*/ else if( test_data->rsp_validator(&(test_data->exp_rsp),pInfo) == 1) { p_cb_data->status = NFCSTATUS_SUCCESS; } else { p_cb_data->status = NFCSTATUS_FAILED; } test_data->exp_rsp.len = 0; } SEM_POST(p_cb_data); return; }
/******************************************************************************* ** ** Function hal_write_rsp_timeout_cb ** ** Description Callback function for hal write response timer. ** ** Returns None ** *******************************************************************************/ static void hal_write_rsp_timeout_cb(uint32_t timerId, void *pContext) { NXPLOG_NCIHAL_E("hal_write_rsp_timeout_cb - write timeout!!!"); hal_write_timer_fired = 1; hal_read_cb(pContext,NULL); }
/******************************************************************************* ** ** Function st_validator_testAntenna_Txldo ** ** Description Validator function to validate Antenna TxLDO current measurement. ** ** Returns One if successful otherwise Zero. ** *******************************************************************************/ static uint8_t st_validator_testAntenna_Txldo(nci_data_t *exp, phTmlNfc_TransactInfo_t *act) { uint8_t result = 0; uint8_t mesuredrange =0; long measured_val = 0; int tolerance = 0; if(NULL == exp || NULL == act) { return result; } NXPLOG_NCIHAL_D("st_validator_testAntenna_Txldo = 0x%x", act->pBuff[3]); if (0x05 == act->pBuff[2]) { if (NFCSTATUS_SUCCESS == act->pBuff[3]) { result = 1; NXPLOG_NCIHAL_D("Antenna: TxLDO current measured raw value in mA : 0x%x", act->pBuff[4]); if(0x00 == act->pBuff[5]) { NXPLOG_NCIHAL_D("Measured range : 0x00 = 50 - 100 mA"); measured_val = ((0.40 * act->pBuff[4]) + 50); NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", measured_val); } else { NXPLOG_NCIHAL_D("Measured range : 0x01 = 20 - 70 mA"); measured_val = ((0.40 * act->pBuff[4]) + 20); NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", measured_val); } tolerance = (phAntenna_resp.wTxdoMeasuredRangeMax * phAntenna_resp.wTxdoMeasuredTolerance)/100; if ((measured_val <= phAntenna_resp.wTxdoMeasuredRangeMax + tolerance)) { tolerance = (phAntenna_resp.wTxdoMeasuredRangeMin * phAntenna_resp.wTxdoMeasuredTolerance)/100; if((measured_val >= phAntenna_resp.wTxdoMeasuredRangeMin - tolerance)) { gtxldo_status = NFCSTATUS_SUCCESS; NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement PASS"); } else { gtxldo_status = NFCSTATUS_FAILED; NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL"); } } else { gtxldo_status = NFCSTATUS_FAILED; NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL"); } } else { gtxldo_status = NFCSTATUS_FAILED; NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement failed: Invalid status"); } } else { gtxldo_status = NFCSTATUS_FAILED; NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement failed: Invalid payload length"); } return result; }
/******************************************************************************* ** ** 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 phTmlNfc_TmlWriterThread ** ** Description Writes the requested data onto the lower layer driver ** ** Parameters pParam - context provided by upper layer ** ** Returns None ** *******************************************************************************/ static void phTmlNfc_TmlWriterThread(void *pParam) { NFCSTATUS wStatus = NFCSTATUS_SUCCESS; int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; /* Transaction info buffer to be passed to Callback Thread */ static phTmlNfc_TransactInfo_t tTransactionInfo; /* Structure containing Tml callback function and parameters to be invoked by the callback thread */ static phLibNfc_DeferredCall_t tDeferredInfo; /* Initialize Message structure to post message onto Callback Thread */ static phLibNfc_Message_t tMsg; /* In case of I2C Write Retry */ static uint16_t retry_cnt; UNUSED(pParam); NXPLOG_TML_D("PN54X - Tml Writer Thread Started................\n"); /* Writer thread loop shall be running till shutdown is invoked */ while (gpphTmlNfc_Context->bThreadDone) { NXPLOG_TML_D("PN54X - Tml Writer Thread Running................\n"); sem_wait(&gpphTmlNfc_Context->txSemaphore); /* If Tml write is requested */ if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable) { NXPLOG_TML_D("PN54X - Write requested.....\n"); /* Set the variable to success initially */ wStatus = NFCSTATUS_SUCCESS; if (NFCSTATUS_INVALID_DEVICE != (uintptr_t)gpphTmlNfc_Context->pDevHandle) { retry: gpphTmlNfc_Context->tWriteInfo.bEnable = 0; /* Variable to fetch the actual number of bytes written */ dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE; /* Write the data in the buffer onto the file */ NXPLOG_TML_D("PN54X - Invoking I2C Write.....\n"); dwNoBytesWrRd = phTmlNfc_i2c_write(gpphTmlNfc_Context->pDevHandle, gpphTmlNfc_Context->tWriteInfo.pBuffer, gpphTmlNfc_Context->tWriteInfo.wLength ); /* Try I2C Write Five Times, if it fails : Raju */ if (-1 == dwNoBytesWrRd) { if (getDownloadFlag() == TRUE) { if (retry_cnt++ < MAX_WRITE_RETRY_COUNT) { NXPLOG_NCIHAL_E( "PN54X - Error in I2C Write - Retry 0x%x", retry_cnt); goto retry; } } NXPLOG_TML_E("PN54X - Error in I2C Write.....\n"); wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED); } else { phNxpNciHal_print_packet("SEND", gpphTmlNfc_Context->tWriteInfo.pBuffer, gpphTmlNfc_Context->tWriteInfo.wLength); } retry_cnt = 0; if (NFCSTATUS_SUCCESS == wStatus) { NXPLOG_TML_D("PN54X - I2C Write successful.....\n"); dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE; } /* Fill the Transaction info structure to be passed to Callback Function */ tTransactionInfo.wStatus = wStatus; tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer; /* Actual number of bytes written is filled in the structure */ tTransactionInfo.wLength = (uint16_t) dwNoBytesWrRd; /* Prepare the message to be posted on the User thread */ tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb; tDeferredInfo.pParameter = &tTransactionInfo; /* Write operation completed successfully. Post a Message onto Callback Thread*/ tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; tMsg.pMsgData = &tDeferredInfo; tMsg.Size = sizeof(tDeferredInfo); /* Check whether Retransmission needs to be started, * If yes, Post message only if * case 1. Message is not posted && * case 11. Write status is success || * case 12. Last retry of write is also failure */ if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) && (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) { if (FALSE == gpphTmlNfc_Context->bWriteCbInvoked) { if ((NFCSTATUS_SUCCESS == wStatus) || (bCurrentRetryCount == 0)) { NXPLOG_TML_D("PN54X - Posting Write message.....\n"); phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg); gpphTmlNfc_Context->bWriteCbInvoked = TRUE; } } } else { NXPLOG_TML_D("PN54X - Posting Fresh Write message.....\n"); phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg); } } else { NXPLOG_TML_D("PN54X - NFCSTATUS_INVALID_DEVICE != gpphTmlNfc_Context->pDevHandle"); } /* If Data packet is sent, then NO retransmission */ if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) && (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) { NXPLOG_TML_D("PN54X - Starting timer for Retransmission case"); wStatus = phTmlNfc_InitiateTimer(); if (NFCSTATUS_SUCCESS != wStatus) { /* Reset Variables used for Retransmission */ NXPLOG_TML_D("PN54X - Retransmission timer initiate failed"); gpphTmlNfc_Context->tWriteInfo.bEnable = 0; bCurrentRetryCount = 0; } } } else { NXPLOG_TML_D("PN54X - Write request NOT enabled"); usleep(10000); } }/* End of While loop */ return; }
/******************************************************************************* ** ** 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 phNxpNciHal_NfcDep_rsp_ext ** ** Description Implements algorithm for NFC-DEP protocol priority over ** ISO-DEP protocol. ** Following the algorithm: ** IF ISO-DEP detected first time,set the ISO-DEP detected flag ** and resume polling loop with 60ms timeout value. ** a) if than NFC-DEP detected than send the response to ** libnfc-nci stack and stop the timer. ** b) if NFC-DEP not detected with in 60ms, than restart the ** polling loop to give early chance to ISO-DEP with a ** cleanup timer. ** c) if ISO-DEP detected second time send the response to ** libnfc-nci stack and stop the cleanup timer. ** d) if ISO-DEP not detected with in cleanup timeout, than ** clear the ISO-DEP detection flag. ** ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED ** *******************************************************************************/ NFCSTATUS phNxpNciHal_NfcDep_rsp_ext(uint8_t *p_ntf, uint16_t *p_len) { NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER; NXPLOG_NCIHAL_D(">> p_ntf[0]=%02x , p_ntf[1]=%02x",p_ntf[0],p_ntf[1]); if(p_ntf[0] == 0x41 && p_ntf[1] == 0x04) { //Tag selected, Disable P2P Prio logic. bIgnoreIsoDep = 1; NXPLOG_NCIHAL_D(">> Tag selected, Disable P2P Prio logic."); } else if( ((p_ntf[0] == 0x61 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x41 && p_ntf[1] == 0x06) ) && bIgnoreIsoDep == 1 ) { //Tag deselected, enable P2P Prio logic. bIgnoreIsoDep = 0x00; NXPLOG_NCIHAL_D(">> Tag deselected, enable P2P Prio logic."); } if (bIgnoreIsoDep == 0x00 && p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && *p_len > 5) { if (p_ntf[5] == 0x04 && p_ntf[6] < 0x80) { NXPLOG_NCIHAL_D(">> ISO DEP detected."); if (iso_dep_detected == 0x00) { NXPLOG_NCIHAL_D( ">> ISO DEP detected first time. Resume polling loop"); iso_dep_detected = 0x01; status = phNxpNciHal_resume_polling_loop(); custom_poll_timer = phOsalNfc_Timer_Create(); NXPLOG_NCIHAL_D("custom poll timer started - %d", custom_poll_timer); status = phOsalNfc_Timer_Start(custom_poll_timer, CUSTOM_POLL_TIMEOUT, &custom_poll_timer_handler, NULL); if (NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("custom poll timer started"); } else { NXPLOG_NCIHAL_E("custom poll timer not started!!!"); status = NFCSTATUS_FAILED; } status = NFCSTATUS_FAILED; } else { NXPLOG_NCIHAL_D(">> ISO DEP detected second time."); /* Store notification */ phNxpNciHal_NfcDep_store_ntf(p_ntf, *p_len); /* Stop Cleanup_timer */ phOsalNfc_Timer_Stop(cleanup_timer); phOsalNfc_Timer_Delete(cleanup_timer); cleanup_timer=0; EnableP2P_PrioLogic = FALSE; iso_dep_detected = 0; status = NFCSTATUS_SUCCESS; } } else if (p_ntf[5] == 0x05) { NXPLOG_NCIHAL_D(">> NFC-DEP Detected - stopping the custom poll timer"); phOsalNfc_Timer_Stop(custom_poll_timer); phOsalNfc_Timer_Delete(custom_poll_timer); EnableP2P_PrioLogic = FALSE; iso_dep_detected = 0; status = NFCSTATUS_SUCCESS; } else { NXPLOG_NCIHAL_D(">> detected other technology- stopping the custom poll timer"); phOsalNfc_Timer_Stop(custom_poll_timer); phOsalNfc_Timer_Delete(custom_poll_timer); EnableP2P_PrioLogic = FALSE; iso_dep_detected = 0; status = NFCSTATUS_INVALID_PARAMETER; } } else if( bIgnoreIsoDep == 0x00 && ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x61 && p_ntf[1] == 0x06)) ) { NXPLOG_NCIHAL_D(">> RF disabled"); if (poll_timer_fired == 0x01) { poll_timer_fired = 0x00; NXPLOG_NCIHAL_D(">>restarting polling loop."); /* start polling loop */ phNxpNciHal_start_polling_loop(); EnableP2P_PrioLogic = FALSE; NXPLOG_NCIHAL_D (">> NFC DEP NOT detected - custom poll timer expired - RF disabled"); cleanup_timer = phOsalNfc_Timer_Create(); /* Start cleanup_timer */ NFCSTATUS status = phOsalNfc_Timer_Start(cleanup_timer, CLEAN_UP_TIMEOUT, &cleanup_timer_handler, NULL); if (NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("cleanup timer started"); } else { NXPLOG_NCIHAL_E("cleanup timer not started!!!"); status = NFCSTATUS_FAILED; } status = NFCSTATUS_FAILED; } else { status = NFCSTATUS_SUCCESS; } } if (bIgnoreIsoDep == 0x00 && iso_dep_detected == 1) { if ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x61 && p_ntf[1] == 0x06)) { NXPLOG_NCIHAL_D(">>iso_dep_detected Disconnect related notification"); status = NFCSTATUS_FAILED; } else { NXPLOG_NCIHAL_W("Never come here"); } } return status; }
void phNxpNciHal_emergency_recovery(void) { NXPLOG_NCIHAL_E("%s: abort()", __FUNCTION__); // abort(); }
/******************************************************************************* ** ** Function listRemove ** ** Description Remove node from the list ** ** Returns 1, if removed, 0 if otherwise ** *******************************************************************************/ int listRemove(struct listHead* pList, void* pData) { struct listNode* pNode; struct listNode* pRemovedNode; int result; pthread_mutex_lock(&pList->mutex); if (pList->pFirst == NULL) { /* Empty list */ NXPLOG_NCIHAL_E("Failed to deallocate (list empty)"); result = 0; goto clean_and_return; } pNode = pList->pFirst; if (pList->pFirst->pData == pData) { /* Get the removed node */ pRemovedNode = pNode; /* Remove the first node */ pList->pFirst = pList->pFirst->pNext; } else { while (pNode->pNext != NULL) { if (pNode->pNext->pData == pData) { /* Node found ! */ break; } pNode = pNode->pNext; } if (pNode->pNext == NULL) { /* Node not found */ result = 0; NXPLOG_NCIHAL_E("Failed to deallocate (not found %8p)", pData); goto clean_and_return; } /* Get the removed node */ pRemovedNode = pNode->pNext; /* Remove the node from the list */ pNode->pNext = pNode->pNext->pNext; } /* Deallocate the node */ free(pRemovedNode); result = 1; clean_and_return: pthread_mutex_unlock(&pList->mutex); return result; }