// This is currently only for used for Endpoint tl_handle_t TLHandleListGet(int endpointHandle) { AVB_TRACE_ENTRY(AVB_TRACE_TL); if (!endpointHandle || !gTLHandleList) { AVB_TRACE_EXIT(AVB_TRACE_TL); return NULL; } TL_LOCK(); int i1; for (i1 = 0; i1 < gMaxTL; i1++) { if (gTLHandleList[i1]) { tl_state_t *pTLState = (tl_state_t *)gTLHandleList[i1]; if (pTLState->endpointHandle == endpointHandle) { TL_UNLOCK(); AVB_TRACE_EXIT(AVB_TRACE_TL); return pTLState; } } } TL_UNLOCK(); AVB_TRACE_EXIT(AVB_TRACE_TL); return NULL; }
bool openavbTLAVDECCRunTalker(tl_handle_t handle, U16 configIdx, U16 descriptorType, U16 descriptorIdx, void *pVoidTalkerStreamInfo) { AVB_TRACE_ENTRY(AVB_TRACE_TL); if (!handle) { AVB_LOG_ERROR("Invalid handle."); AVB_TRACE_EXIT(AVB_TRACE_TL); return FALSE; } tl_state_t *pTLState = (tl_state_t *)handle; if (pTLState->cfg.intf_cb.intf_avdecc_init_cb) { pTLState->cfg.intf_cb.intf_avdecc_init_cb(pTLState->pMediaQ, configIdx, descriptorType, descriptorIdx); } if (pTLState->cfg.map_cb.map_avdecc_init_cb) { pTLState->cfg.map_cb.map_avdecc_init_cb(pTLState->pMediaQ, configIdx, descriptorType, descriptorIdx); } if (!openavbTLIsRunning(handle)) { openavbTLRun(handle); } AVB_TRACE_EXIT(AVB_TRACE_TL); return TRUE; }
/* Talker Listener thread function that talks primarily with the endpoint */ void* openavbTLThreadFn(void *pv) { AVB_TRACE_ENTRY(AVB_TRACE_TL); tl_state_t *pTLState = (tl_state_t *)pv; while (pTLState->bRunning) { AVB_TRACE_LINE(AVB_TRACE_TL_DETAIL); int endpointHandle = openavbEptClntOpenSrvrConnection(pTLState); if (endpointHandle == AVB_ENDPOINT_HANDLE_INVALID) { // error connecting to endpoint, already logged } else { pTLState->endpointHandle = endpointHandle; // Validate the AVB version for TL and Endpoint are the same before continuing pTLState->AVBVerState = OPENAVB_TL_AVB_VER_UNKNOWN; pTLState->bConnected = openavbEptClntRequestVersionFromServer(pTLState->endpointHandle); while (pTLState->bRunning && pTLState->bConnected && pTLState->AVBVerState == OPENAVB_TL_AVB_VER_UNKNOWN) { // Check for endpoint version message. Timeout in 50 msec. if (!openavbEptClntService(pTLState->endpointHandle, 50)) { AVB_LOG_WARNING("Lost connection to endpoint, will retry"); pTLState->bConnected = FALSE; pTLState->endpointHandle = 0; } } if (pTLState->AVBVerState == OPENAVB_TL_AVB_VER_INVALID) { AVB_LOG_ERROR("AVB core version is different than Endpoint AVB core version. Streams will not be started. Will reconnect to the endpoint and check again."); } if (pTLState->bConnected && pTLState->AVBVerState == OPENAVB_TL_AVB_VER_VALID) { if (pTLState->cfg.role == AVB_ROLE_TALKER) { openavbTLRunTalker(pTLState); } else { openavbTLRunListener(pTLState); } } // Close the endpoint connection. unless connection already gone in which case the socket could already be reused. if (pTLState->bConnected) { openavbEptClntCloseSrvrConnection(endpointHandle); pTLState->bConnected = FALSE; pTLState->endpointHandle = 0; } } if (pTLState->bRunning) { SLEEP(1); } } THREAD_JOINABLE(pTLState->TLThread); AVB_TRACE_EXIT(AVB_TRACE_TL); return NULL; }
void openavbRawsockClose(void *pvRawsock) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); ((base_rawsock_t*)pvRawsock)->cb.close(pvRawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); }
static void socketClose(int h) { AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT); if (h != AVB_ENDPOINT_HANDLE_INVALID) { close(h); } AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT); }
void openavbSetRxSignalMode(void *pvRawsock, bool rxSignalMode) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); ((base_rawsock_t*)pvRawsock)->cb.setRxSignalMode(pvRawsock, rxSignalMode); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); }
/* Client version request */ bool openavbEptSrvrHndlVerRqstFromClient(int h) { AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT); openavbEptSrvrSendServerVersionToClient(h, AVB_CORE_VER_FULL); AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT); return TRUE; }
bool openavbTLAVDECCStopTalker(tl_handle_t handle, U16 configIdx, void *pVoidTalkerStreamInfo) { AVB_TRACE_ENTRY(AVB_TRACE_TL); openavbTLStop(handle); AVB_TRACE_EXIT(AVB_TRACE_TL); return TRUE; }
int openavbRawsockRxBufLevel(void *pvRawsock) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); int ret = ((base_rawsock_t*)pvRawsock)->cb.rxBufLevel(pvRawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
bool openavbRawsockGetAddr(void *pvRawsock, U8 addr[ETH_ALEN]) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); bool ret = ((base_rawsock_t*)pvRawsock)->cb.getAddr(pvRawsock, addr); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return ret; }
bool openavbRawsockRxAVTPSubtype(void *pvRawsock, U8 subtype) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); bool ret = ((base_rawsock_t*)pvRawsock)->cb.rxAVTPSubtype(pvRawsock, subtype); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return ret; }
int openavbRawsockGetSocket(void *pvRawsock) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); int ret = ((base_rawsock_t*)pvRawsock)->cb.getSocket(pvRawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return ret; }
bool openavbRawsockRelRxFrame(void *pvRawsock, U8 *pBuffer) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); bool ret = ((base_rawsock_t*)pvRawsock)->cb.relRxFrame(pvRawsock, pBuffer); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
static inline bool listenerDoStream(tl_state_t *pTLState) { AVB_TRACE_ENTRY(AVB_TRACE_TL); if (!pTLState) { AVB_LOG_ERROR("Invalid TLState"); AVB_TRACE_EXIT(AVB_TRACE_TL); return FALSE; } openavb_tl_cfg_t *pCfg = &pTLState->cfg; listener_data_t *pListenerData = pTLState->pPvtListenerData; bool bRet = FALSE; if (pTLState->bStreaming) { U64 nowNS; pListenerData->nReportCalls++; // Try to receive a frame if (IS_OPENAVB_SUCCESS(openavbAvtpRx(pListenerData->avtpHandle))) { pListenerData->nReportFrames++; } CLOCK_GETTIME64(OPENAVB_TIMER_CLOCK, &nowNS); if (pCfg->report_seconds > 0) { if (nowNS > pListenerData->nextReportNS) { listenerShowStats(pListenerData, pTLState); openavbListenerAddStat(pTLState, TL_STAT_RX_CALLS, pListenerData->nReportCalls); openavbListenerAddStat(pTLState, TL_STAT_RX_FRAMES, pListenerData->nReportFrames); pListenerData->nReportCalls = 0; pListenerData->nReportFrames = 0; pListenerData->nextReportNS += (pCfg->report_seconds * NANOSECONDS_PER_SECOND); } } else if (pCfg->report_frames > 0 && pListenerData->nReportFrames != pListenerData->lastReportFrames) { if (pListenerData->nReportFrames % pCfg->report_frames == 1) { listenerShowStats(pListenerData, pTLState); pListenerData->lastReportFrames = pListenerData->nReportFrames; } } if (nowNS > pListenerData->nextSecondNS) { pListenerData->nextSecondNS += NANOSECONDS_PER_SECOND; bRet = TRUE; } } else { SLEEP_MSEC(1); bRet = TRUE; } AVB_TRACE_EXIT(AVB_TRACE_TL); return bRet; }
U8 *openavbRawsockGetRxFrame(void *pvRawsock, U32 timeout, unsigned int *offset, unsigned int *len) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); U8 *ret = ((base_rawsock_t*)pvRawsock)->cb.getRxFrame(pvRawsock, timeout, offset, len); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
int openavbRawsockRxParseHdr(void *pvRawsock, U8 *pBuffer, hdr_info_t *pInfo) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); int ret = ((base_rawsock_t*)pvRawsock)->cb.rxParseHdr(pvRawsock, pBuffer, pInfo); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
bool openavbRawsockTxFrameReady(void *pvRawsock, U8 *pBuffer, unsigned int len) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); bool ret = ((base_rawsock_t*)pvRawsock)->cb.txFrameReady(pvRawsock, pBuffer, len); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
/* Client version request */ bool openavbAvdeccMsgSrvrHndlVerRqstFromClient(int avdeccMsgHandle) { AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG); openavbAvdeccMsgSrvrSendServerVersionToClient(avdeccMsgHandle, AVB_CORE_VER_FULL); AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG); return TRUE; }
bool openavbRawsockTxSetHdr(void *pvRawsock, hdr_info_t *pHdr) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); bool ret = ((base_rawsock_t*)pvRawsock)->cb.txSetHdr(pvRawsock, pHdr); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return ret; }
bool openavbRawsockTxSetMark(void *pvRawsock, int mark) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); bool ret = ((base_rawsock_t*)pvRawsock)->cb.txSetMark(pvRawsock, mark); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return ret; }
U8 *openavbRawsockGetTxFrame(void *pvRawsock, bool blocking, unsigned int *len) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); U8 *ret = ((base_rawsock_t*)pvRawsock)->cb.getTxFrame(pvRawsock, blocking, len); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
unsigned long openavbRawsockGetTXOutOfBuffersCyclic(void *pvRawsock) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL); unsigned long ret = ((base_rawsock_t*)pvRawsock)->cb.getTXOutOfBuffersCyclic(pvRawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL); return ret; }
bool openavbRawsockRxMulticast(void *pvRawsock, bool add_membership, const U8 addr[ETH_ALEN]) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); bool ret = ((base_rawsock_t*)pvRawsock)->cb.rxMulticast(pvRawsock, add_membership, addr); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return ret; }
// Open a rawsock for TX or RX void *pcapRawsockOpen(pcap_rawsock_t* rawsock, const char *ifname, bool rx_mode, bool tx_mode, U16 ethertype, U32 frame_size, U32 num_frames) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); AVB_LOGF_DEBUG("Open, rx=%d, tx=%d, ethertype=%x size=%d, num=%d", rx_mode, tx_mode, ethertype, frame_size, num_frames); baseRawsockOpen(&rawsock->base, ifname, rx_mode, tx_mode, ethertype, frame_size, num_frames); if (tx_mode) { AVB_LOG_DEBUG("pcap rawsock transmit mode will bypass FQTSS"); } rawsock->handle = 0; // Get info about the network device if (!simpleAvbCheckInterface(ifname, &(rawsock->base.ifInfo))) { AVB_LOGF_ERROR("Creating rawsock; bad interface name: %s", ifname); free(rawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return NULL; } // Deal with frame size. if (rawsock->base.frameSize == 0) { // use interface MTU as max frames size, if none specified rawsock->base.frameSize = rawsock->base.ifInfo.mtu + ETH_HLEN + VLAN_HLEN; } else if (rawsock->base.frameSize > rawsock->base.ifInfo.mtu + ETH_HLEN + VLAN_HLEN) { AVB_LOG_ERROR("Creating rawsock; requested frame size exceeds MTU"); free(rawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return NULL; } char errbuf[PCAP_ERRBUF_SIZE]; rawsock->handle = open_pcap_dev(ifname, rawsock->base.frameSize, errbuf); if (!rawsock->handle) { AVB_LOGF_ERROR("Cannot open device %s: %s", ifname, errbuf); free(rawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return NULL; } // fill virtual functions table rawsock_cb_t *cb = &rawsock->base.cb; cb->close = pcapRawsockClose; cb->getTxFrame = pcapRawsockGetTxFrame; cb->txFrameReady = pcapRawsockTxFrameReady; cb->send = pcapRawsockSend; cb->getRxFrame = pcapRawsockGetRxFrame; cb->rxMulticast = pcapRawsockRxMulticast; cb->rxParseHdr = pcapRawsockRxParseHdr; AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); return rawsock; }
void openavbRawsockClose(void *pvRawsock) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); base_rawsock_t *rawsock = (base_rawsock_t*)pvRawsock; if (VALID_RAWSOCK(rawsock) && rawsock->cb.close) rawsock->cb.close(pvRawsock); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); }
void openavbSetRxSignalMode(void *pvRawsock, bool rxSignalMode) { AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK); base_rawsock_t *rawsock = (base_rawsock_t*)pvRawsock; if (VALID_RAWSOCK(rawsock) && rawsock->cb.setRxSignalMode) rawsock->cb.setRxSignalMode(pvRawsock, rxSignalMode); AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK); }
void openavbAcmpSMController_removeInflight(openavb_acmp_ACMPCommandResponse_t *commandResponse) { AVB_TRACE_ENTRY(AVB_TRACE_ACMP); openavb_list_node_t node = openavbAcmpSMController_findInflightNodeFromCommand(commandResponse); if (node) { openavbListDelete(openavbAcmpSMControllerVars.inflight, node); } AVB_TRACE_EXIT(AVB_TRACE_ACMP); }
void openavbAcmpSMControllerSet_doTerminate(bool value) { AVB_TRACE_ENTRY(AVB_TRACE_ACMP); openavbAcmpSMControllerVars.doTerminate = value; SEM_ERR_T(err); SEM_POST(openavbAcmpSMControllerSemaphore, err); SEM_LOG_ERR(err); AVB_TRACE_EXIT(AVB_TRACE_ACMP); }
static bool openavbEptSrvrSendToClient(int h, openavbEndpointMessage_t *msg) { AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT); if (h < 0 || h >= POLL_FD_COUNT) { AVB_LOG_ERROR("Sending message; invalid handle"); AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT); return FALSE; } if (!msg) { AVB_LOG_ERROR("Sending message; invalid argument passed"); AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT); return FALSE; } int csock = fds[h].fd; if (csock == SOCK_INVALID) { AVB_LOG_ERROR("Socket closed unexpectedly"); return FALSE; } ssize_t nWrite = write(csock, msg, OPENAVB_ENDPOINT_MSG_LEN); AVB_LOGF_VERBOSE("Sent message, len=%zu, nWrite=%zu", OPENAVB_ENDPOINT_MSG_LEN, nWrite); if (nWrite < OPENAVB_ENDPOINT_MSG_LEN) { if (nWrite < 0) { AVB_LOGF_ERROR("Failed to write socket: %s", strerror(errno)); } else if (nWrite == 0) { AVB_LOG_ERROR("Socket closed unexpectedly"); } else { AVB_LOG_ERROR("Socket write too short"); } socketClose(h); AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT); return FALSE; } AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT); return TRUE; }
// General shutdown callback regardless if a talker or listener. Called once during openavbTLClose() void openavbIntfLoggerGenEndCB(media_q_t *pMediaQ) { AVB_TRACE_ENTRY(AVB_TRACE_INTF); if (pMediaQ) { pvt_data_t *pPvtData = pMediaQ->pPvtIntfInfo; if (!pPvtData) { AVB_LOG_ERROR("Private interface module data not allocated."); return; } } AVB_TRACE_EXIT(AVB_TRACE_INTF); }