//------------------------------------------------------------------------------ static void* workerThread(void* pArgument_p) { tEdrvInstance* pInstance = (tEdrvInstance*)pArgument_p; int pcapRet; int oldCancelType; DEBUG_LVL_EDRV_TRACE("%s(): ThreadId:%ld\n", __func__, syscall(SYS_gettid)); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldCancelType); // Set up and activate the pcap live capture handle pInstance->pPcapThread = startPcap(); if (pInstance->pPcapThread == NULL) { return NULL; } if (pcap_setdirection(pInstance->pPcapThread, PCAP_D_INOUT) < 0) { DEBUG_LVL_ERROR_TRACE("%s() couldn't set PCAP direction!\n", __func__); } // signal that thread is successfully started sem_post(&pInstance->syncSem); pcapRet = pcap_loop(pInstance->pPcapThread, -1, packetHandler, (u_char*)pInstance); switch (pcapRet) { case 0: DEBUG_LVL_ERROR_TRACE("%s(): pcap_loop ended because 'cnt' is exhausted.\n", __func__); break; case -1: DEBUG_LVL_ERROR_TRACE("%s(): pcap_loop ended because of an error!\n", __func__); break; case -2: DEBUG_LVL_ERROR_TRACE("%s(): pcap_loop ended normally.\n", __func__); break; default: DEBUG_LVL_ERROR_TRACE("%s(): pcap_loop ended (unknown return value).\n", __func__); break; } return NULL; }
//------------------------------------------------------------------------------ tOplkError edrv_sendTxBuffer(tEdrvTxBuffer* pBuffer_p) { int pcapRet; // Check parameter validity ASSERT(pBuffer_p != NULL); FTRACE_MARKER("%s", __func__); if (pBuffer_p->txBufferNumber.pArg != NULL) return kErrorInvalidOperation; if (getLinkStatus(edrvInstance_l.initParam.pDevName) == FALSE) { /* there's no link! We pretend that packet is sent and immediately call * tx handler! Otherwise the stack would hang! */ if (pBuffer_p->pfnTxHandler != NULL) { pBuffer_p->pfnTxHandler(pBuffer_p); } } else { pthread_mutex_lock(&edrvInstance_l.mutex); if (edrvInstance_l.pTransmittedTxBufferLastEntry == NULL) { edrvInstance_l.pTransmittedTxBufferLastEntry = edrvInstance_l.pTransmittedTxBufferFirstEntry = pBuffer_p; } else { edrvInstance_l.pTransmittedTxBufferLastEntry->txBufferNumber.pArg = pBuffer_p; edrvInstance_l.pTransmittedTxBufferLastEntry = pBuffer_p; } pthread_mutex_unlock(&edrvInstance_l.mutex); pcapRet = pcap_sendpacket(edrvInstance_l.pPcap, pBuffer_p->pBuffer, (int)pBuffer_p->txFrameSize); if (pcapRet != 0) { DEBUG_LVL_EDRV_TRACE("%s() pcap_sendpacket returned %d (%s)\n", __func__, pcapRet, pcap_geterr(edrvInstance_l.pPcap)); return kErrorInvalidOperation; } } return kErrorOk; }
//------------------------------------------------------------------------------ tOplkError edrv_sendTxBuffer(tEdrvTxBuffer* pBuffer_p) { int pcapRet; // Check parameter validity ASSERT(pBuffer_p != NULL); //TRACE("%s: TxB=%p (%02X), last TxB=%p\n", __func__, pBuffer_p, (UINT)pBuffer_p->pBuffer[5], edrvInstance_l.pTransmittedTxBufferLastEntry); if (pBuffer_p->txBufferNumber.pArg != NULL) return kErrorInvalidOperation; EnterCriticalSection(&edrvInstance_l.criticalSection); if (edrvInstance_l.pTransmittedTxBufferLastEntry == NULL) { edrvInstance_l.pTransmittedTxBufferLastEntry = edrvInstance_l.pTransmittedTxBufferFirstEntry = pBuffer_p; } else { edrvInstance_l.pTransmittedTxBufferLastEntry->txBufferNumber.pArg = pBuffer_p; edrvInstance_l.pTransmittedTxBufferLastEntry = pBuffer_p; } LeaveCriticalSection(&edrvInstance_l.criticalSection); pcapRet = pcap_sendpacket(edrvInstance_l.pPcap, pBuffer_p->pBuffer, (int)pBuffer_p->txFrameSize); if (pcapRet != 0) { DEBUG_LVL_EDRV_TRACE("%s() pcap_sendpacket returned %d (%s)\n", __func__, pcapRet, pcap_geterr(edrvInstance_l.pPcap)); return kErrorInvalidOperation; } return kErrorOk; }