// General initizlization of the talker and listener library. Must be called prior to using any other TL APIs. EXTERN_DLL_EXPORT bool openavbTLInitialize(U32 maxTL) { AVB_TRACE_ENTRY(AVB_TRACE_TL); LOG_EAVB_CORE_VERSION(); // CORE_TODO : This can be used to AVB stack init functionality once such a thing exists in the reference implementation AVB_TIME_INIT(); gMaxTL = maxTL; { MUTEX_ATTR_HANDLE(mta); MUTEX_ATTR_INIT(mta); MUTEX_ATTR_SET_TYPE(mta, MUTEX_ATTR_TYPE_DEFAULT); MUTEX_ATTR_SET_NAME(mta, "gTLStateMutex"); MUTEX_CREATE_ERR(); MUTEX_CREATE(gTLStateMutex, mta); MUTEX_LOG_ERR("Error creating mutex"); } gTLHandleList = calloc(1, sizeof(tl_handle_t) * gMaxTL); if (gTLHandleList) { AVB_TRACE_EXIT(AVB_TRACE_TL); return TRUE; } else { AVB_TRACE_EXIT(AVB_TRACE_TL); return FALSE; } }
bool openavbAcmpSMControllerStart() { AVB_TRACE_ENTRY(AVB_TRACE_ACMP); openavbAcmpSMControllerVars.inflight = openavbListNewList(); if (!openavbAcmpSMControllerVars.inflight) { AVB_LOG_ERROR("Unable to create inflight list. ACMP protocol not started."); AVB_TRACE_EXIT(AVB_TRACE_ACMP); return FALSE; } MUTEX_ATTR_HANDLE(mta); MUTEX_ATTR_INIT(mta); MUTEX_ATTR_SET_TYPE(mta, MUTEX_ATTR_TYPE_DEFAULT); MUTEX_ATTR_SET_NAME(mta, "openavbAcmpSMControllerMutex"); MUTEX_CREATE_ERR(); MUTEX_CREATE(openavbAcmpSMControllerMutex, mta); MUTEX_LOG_ERR("Could not create/initialize 'openavbAcmpSMControllerMutex' mutex"); SEM_ERR_T(err); SEM_INIT(openavbAcmpSMControllerSemaphore, 1, err); SEM_LOG_ERR(err); // Start the State Machine bool errResult; bRunning = TRUE; THREAD_CREATE(openavbAcmpSmControllerThread, openavbAcmpSmControllerThread, NULL, openavbAcmpSMControllerThreadFn, NULL); THREAD_CHECK_ERROR(openavbAcmpSmControllerThread, "Thread / task creation failed", errResult); if (errResult) { bRunning = FALSE; AVB_TRACE_EXIT(AVB_TRACE_ACMP); return FALSE; } AVB_TRACE_EXIT(AVB_TRACE_ACMP); return TRUE; }
// Called from openavbTLThreadFn() which is started from openavbTLRun() void openavbTLRunListener(tl_state_t *pTLState) { AVB_TRACE_ENTRY(AVB_TRACE_TL); if (!pTLState) { AVB_LOG_ERROR("Invalid TLState"); AVB_TRACE_EXIT(AVB_TRACE_TL); return; } openavb_tl_cfg_t *pCfg = &pTLState->cfg; pTLState->pPvtListenerData = calloc(1, sizeof(listener_data_t)); if (!pTLState->pPvtListenerData) { AVB_LOG_WARNING("Failed to allocate listener data."); return; } AVBStreamID_t streamID; memset(&streamID, 0, sizeof(streamID)); memcpy(streamID.addr, pCfg->stream_addr.mac, ETH_ALEN); streamID.uniqueID = pCfg->stream_uid; AVB_LOGF_INFO("Attach "STREAMID_FORMAT, STREAMID_ARGS(&streamID)); // Create Stats Mutex { MUTEX_ATTR_HANDLE(mta); MUTEX_ATTR_INIT(mta); MUTEX_ATTR_SET_TYPE(mta, MUTEX_ATTR_TYPE_DEFAULT); MUTEX_ATTR_SET_NAME(mta, "TLStatsMutex"); MUTEX_CREATE_ERR(); MUTEX_CREATE(pTLState->statsMutex, mta); MUTEX_LOG_ERR("Could not create/initialize 'TLStatsMutex' mutex"); } // Tell endpoint to listen for our stream. // If there is a talker, we'll get callback (above.) pTLState->bConnected = openavbTLRunListenerInit(pTLState->endpointHandle, &streamID); if (pTLState->bConnected) { bool bServiceIPC; // Notify AVDECC Msg of the state change. openavbAvdeccMsgClntNotifyCurrentState(pTLState); // Do until we are stopped or lose connection to endpoint while (pTLState->bRunning && pTLState->bConnected) { // Listen for an RX frame (or just sleep if not streaming) bServiceIPC = listenerDoStream(pTLState); if (bServiceIPC) { // Look for messages from endpoint. Don't block (timeout=0) if (!openavbEptClntService(pTLState->endpointHandle, 0)) { AVB_LOGF_WARNING("Lost connection to endpoint "STREAMID_FORMAT, STREAMID_ARGS(&streamID)); pTLState->bConnected = FALSE; pTLState->endpointHandle = 0; } } } // Stop streaming listenerStopStream(pTLState); { MUTEX_CREATE_ERR(); MUTEX_DESTROY(pTLState->statsMutex); // Destroy Stats Mutex MUTEX_LOG_ERR("Error destroying mutex"); } // withdraw our listener attach if (pTLState->bConnected) openavbEptClntStopStream(pTLState->endpointHandle, &streamID); // Notify AVDECC Msg of the state change. openavbAvdeccMsgClntNotifyCurrentState(pTLState); } else { AVB_LOGF_WARNING("Failed to connect to endpoint "STREAMID_FORMAT, STREAMID_ARGS(&streamID)); } if (pTLState->pPvtListenerData) { free(pTLState->pPvtListenerData); pTLState->pPvtListenerData = NULL; } AVB_TRACE_EXIT(AVB_TRACE_TL); }
// Called from openavbTLThreadFn() which is started from openavbTLRun() void openavbTLRunTalker(tl_state_t *pTLState) { AVB_TRACE_ENTRY(AVB_TRACE_TL); if (!pTLState) { AVB_LOG_ERROR("Invalid TLState"); AVB_TRACE_EXIT(AVB_TRACE_TL); return; } pTLState->pPvtTalkerData = calloc(1, sizeof(talker_data_t)); if (!pTLState->pPvtTalkerData) { AVB_LOG_WARNING("Failed to allocate talker data."); return; } // Create Stats Mutex { MUTEX_ATTR_HANDLE(mta); MUTEX_ATTR_INIT(mta); MUTEX_ATTR_SET_TYPE(mta, MUTEX_ATTR_TYPE_DEFAULT); MUTEX_ATTR_SET_NAME(mta, "TLStatsMutex"); MUTEX_CREATE_ERR(); MUTEX_CREATE(pTLState->statsMutex, mta); MUTEX_LOG_ERR("Could not create/initialize 'TLStatsMutex' mutex"); } /* If using endpoint register talker, else register with tpsec */ pTLState->bConnected = openavbTLRunTalkerInit(pTLState); if (pTLState->bConnected) { bool bServiceIPC; // Do until we are stopped or loose connection to endpoint while (pTLState->bRunning && pTLState->bConnected) { // Talk (or just sleep if not streaming.) bServiceIPC = talkerDoStream(pTLState); // TalkerDoStream() returns TRUE once per second, // so that we can service our IPC at that low rate. if (bServiceIPC) { // Look for messages from endpoint. Don't block (timeout=0) if (!openavbEptClntService(pTLState->endpointHandle, 0)) { AVB_LOGF_WARNING("Lost connection to endpoint, will retry "STREAMID_FORMAT, STREAMID_ARGS(&(((talker_data_t *)pTLState->pPvtTalkerData)->streamID))); pTLState->bConnected = FALSE; pTLState->endpointHandle = 0; } } } // Stop streaming talkerStopStream(pTLState); { MUTEX_CREATE_ERR(); MUTEX_DESTROY(pTLState->statsMutex); // Destroy Stats Mutex MUTEX_LOG_ERR("Error destroying mutex"); } // withdraw our talker registration if (pTLState->bConnected) openavbEptClntStopStream(pTLState->endpointHandle, &(((talker_data_t *)pTLState->pPvtTalkerData)->streamID)); openavbTLRunTalkerFinish(pTLState); } else { AVB_LOGF_WARNING("Failed to connect to endpoint"STREAMID_FORMAT, STREAMID_ARGS(&(((talker_data_t *)pTLState->pPvtTalkerData)->streamID))); } if (pTLState->pPvtTalkerData) { free(pTLState->pPvtTalkerData); pTLState->pPvtTalkerData = NULL; } AVB_TRACE_EXIT(AVB_TRACE_TL); }