コード例 #1
0
/* Listener client attaches to a stream
 */
bool openavbEptSrvrAttachStream(int h,
                            AVBStreamID_t *streamID,
                            openavbSrpLsnrDeclSubtype_t ld)
{
	openavbRC rc = OPENAVB_SUCCESS;
	static U8 emptyMAC[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
	static AVBTSpec_t emptytSpec = {0, 0};

	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	clientStream_t *ps = findStream(streamID);
	if (ps && ps->clientHandle != h) {
		AVB_LOGF_ERROR("Error attaching listener: multiple clients for stream %d", streamID->uniqueID);
		AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
		return FALSE;
	}

	if (!ps) {
		ps = addStream(h, streamID);
		if (!ps) {
			AVB_LOGF_ERROR("Error attaching listener: unable to add client stream %d", streamID->uniqueID);
			AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
			return FALSE;
		}
		ps->role = clientListener;
	}

	if(x_cfg.noSrp) {
		// we are operating in a mode supporting preconfigured streams; SRP is not in use,
		if(ld == openavbSrp_LDSt_Interest) {
			// As a proxy for SRP, which would normally make this call after confirming
			// availability of the stream, call the callback from here
			strmRegCb((void*)ps, openavbSrp_AtTyp_TalkerAdvertise,
					  emptyMAC, // a flag to listener to read info from configuration file
					  &emptytSpec,
					  MAX_AVB_SR_CLASSES, // srClass - value doesn't matter because openavbEptSrvrNotifyLstnrOfSrpCb() throws it away
					  1, // accumLatency
					  NULL); // *failInfo
		}
	} else {
		// Normal SRP Operation so pass to SRP
		rc = openavbSrpAttachStream((void*)ps, streamID, ld);
		if (!IS_OPENAVB_SUCCESS(rc))
			delStream(ps);
	}

	openavbEndPtLogAllStaticStreams();

	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
	return IS_OPENAVB_SUCCESS(rc);
}
コード例 #2
0
ファイル: openavb_listener.c プロジェクト: AVnu/Open-AVB
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;
}
コード例 #3
0
ファイル: openavb_endpoint.c プロジェクト: AVnu/Open-AVB
bool x_listenerDetach(clientStream_t *ps)
{
	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	openavbRC rc = OPENAVB_SUCCESS;

	if(!x_cfg.noSrp) {
		// Pass to SRP
		rc = openavbSrpDetachStream(&ps->streamID);
	}

	// remove record
	delStream(ps);

	openavbEndPtLogAllStaticStreams();

	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
	return IS_OPENAVB_SUCCESS(rc);
}
コード例 #4
0
ファイル: openavb_endpoint.c プロジェクト: AVnu/Open-AVB
/*************************************************************
 * MAAP Restart - our destination MAC has been changed.
 *
 * This is a clunky way to handle it - but it works, and this code
 * won't be called often.  (MAAP sends probes before settling on an
 * address, so only a buggy or malicious peer should send us down this
 * path.)
 *
 * A better way to handle this would require SRP and the
 * talkers/listeners to look at destination addresses (in addition
 * to StreamID and talker/listener declaration) and explicitly handle
 * destination address changes.
 */
static void maapRestartCallback(void* handle, struct ether_addr *addr)
{
	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	static clientStream_t* ps;
	openavbRC rc;

	ps = findStreamMaap(handle);
	AVB_LOGF_STATUS("MAAP restart callback: handle=%p, stream=%p", handle, ps);

	if (ps) {
		memcpy(ps->destAddr, addr->ether_addr_octet, ETH_ALEN);

		// Pretend that our listeners went away
		strmAttachCb(ps, (openavbSrpLsnrDeclSubtype_t)0);

		if(!x_cfg.noSrp) {
			// Remove the old registration with SRP
			openavbSrpDeregisterStream(&ps->streamID);

			// Re-register with the new address
			rc = openavbSrpRegisterStream((void*)ps,
			                          &ps->streamID,
			                          ps->destAddr,
			                          &ps->tSpec,
			                          ps->srClass,
			                          ps->srRank,
			                          ps->latency);
		} else {
			rc = OPENAVB_SUCCESS;
		}

		if (!IS_OPENAVB_SUCCESS(rc)) {
			AVB_LOG_ERROR("MAAP restart: failed to re-register talker stream");
		}
	}
	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
}
コード例 #5
0
ファイル: openavb_endpoint.c プロジェクト: AVnu/Open-AVB
/*************************************************************
 *
 * Internal function to cleanup streams
 *
 */
bool x_talkerDeregister(clientStream_t *ps)
{
	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	openavbRC rc = OPENAVB_SUCCESS;

	if(!x_cfg.noSrp) {
		// Pass to SRP
		rc = openavbSrpDeregisterStream(&ps->streamID);
	}

	// Remove QMgr entry for stream
	if (ps->fwmark != INVALID_FWMARK) {
		openavbQmgrRemoveStream(ps->fwmark);
		ps->fwmark = INVALID_FWMARK;
	}

	// Release MAAP address allocation
	if (ps->hndMaap) {
		openavbMaapRelease(ps->hndMaap);
		ps->hndMaap = NULL;
	}

	// Finish Shaping
	if (ps->hndShaper) {
		openavbShaperRelease(ps->hndShaper);
		ps->hndShaper = NULL;
	}

	// remove record
	delStream(ps);

	openavbEndPtLogAllStaticStreams();

	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
	return IS_OPENAVB_SUCCESS(rc);
}
コード例 #6
0
ファイル: openavb_talker.c プロジェクト: Chandini212/Open-AVB
static inline bool talkerDoStream(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;
	talker_data_t *pTalkerData = pTLState->pPvtTalkerData;
	bool bRet = FALSE;

	if (pTLState->bStreaming) {
		U64 nowNS;

		if (!pCfg->tx_blocking_in_intf) {

			// sleep until the next interval
			SLEEP_UNTIL_NSEC(pTalkerData->nextCycleNS);

			//AVB_DBG_INTERVAL(8000, TRUE);

			// send the frames for this interval
			int i;
			for (i = pTalkerData->wakeFrames; i > 0; i--) {
					if (IS_OPENAVB_SUCCESS(openavbAvtpTx(pTalkerData->avtpHandle, i == 1, pCfg->tx_blocking_in_intf)))
					pTalkerData->cntFrames++;
				else break;
				}
			}
		else {
			// Interface module block option
			if (IS_OPENAVB_SUCCESS(openavbAvtpTx(pTalkerData->avtpHandle, TRUE, pCfg->tx_blocking_in_intf)))
				pTalkerData->cntFrames++;
		}

		if (pTalkerData->cntWakes++ % pTalkerData->wakeRate == 0) {
			// time to service the endpoint IPC
			bRet = TRUE;
		}

		CLOCK_GETTIME64(OPENAVB_TIMER_CLOCK, &nowNS);

		if (pCfg->report_seconds > 0) {
			if (nowNS > pTalkerData->nextReportNS) {
			  
				S32 late = pTalkerData->wakesPerReport - pTalkerData->cntWakes;
				U64 bytes = openavbAvtpBytes(pTalkerData->avtpHandle);
				if (late < 0) late = 0;
				U32 txbuf = openavbAvtpTxBufferLevel(pTalkerData->avtpHandle);
				U32 mqbuf = openavbMediaQCountItems(pTLState->pMediaQ, TRUE);
			
				AVB_LOGRT_INFO(LOG_RT_BEGIN, LOG_RT_ITEM, FALSE, "TX UID:%d, ", LOG_RT_DATATYPE_U16, &pTalkerData->streamID.uniqueID);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "calls=%ld, ", LOG_RT_DATATYPE_U32, &pTalkerData->cntWakes);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "frames=%ld, ", LOG_RT_DATATYPE_U32, &pTalkerData->cntFrames);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "late=%d, ", LOG_RT_DATATYPE_U32, &late);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "bytes=%lld, ", LOG_RT_DATATYPE_U64, &bytes);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "txbuf=%d, ", LOG_RT_DATATYPE_U32, &txbuf);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, LOG_RT_END, "mqbuf=%d, ", LOG_RT_DATATYPE_U32, &mqbuf);

				openavbTalkerAddStat(pTLState, TL_STAT_TX_CALLS, pTalkerData->cntWakes);
				openavbTalkerAddStat(pTLState, TL_STAT_TX_FRAMES, pTalkerData->cntFrames);
				openavbTalkerAddStat(pTLState, TL_STAT_TX_LATE, late);
				openavbTalkerAddStat(pTLState, TL_STAT_TX_BYTES, bytes);

				pTalkerData->cntFrames = 0;
				pTalkerData->cntWakes = 0;
				pTalkerData->nextReportNS = nowNS + (pCfg->report_seconds * NANOSECONDS_PER_SECOND);  
			}
		}

		if (nowNS > pTalkerData->nextSecondNS) {
			pTalkerData->nextSecondNS += NANOSECONDS_PER_SECOND;
			bRet = TRUE;
		}

		if (!pCfg->tx_blocking_in_intf) {
			pTalkerData->nextCycleNS += pTalkerData->intervalNS;

			if ((pTalkerData->nextCycleNS + (pCfg->max_transmit_deficit_usec * 1000)) < nowNS) {
				// Hit max deficit time. Something must be wrong. Reset the cycle timer.	
				// Align clock : allows for some performance gain
				nowNS = ((nowNS + (pTalkerData->intervalNS)) / pTalkerData->intervalNS) * pTalkerData->intervalNS;
				pTalkerData->nextCycleNS = nowNS + pTalkerData->intervalNS;
			}				
		}
	}
	else {
            SLEEP(1);
	    // time to service the endpoint IPC
	    bRet = TRUE;
	}

	AVB_TRACE_EXIT(AVB_TRACE_TL);
	return bRet;
}
コード例 #7
0
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) {
			  
				U64 lost = openavbAvtpLost(pListenerData->avtpHandle);
				U64 bytes = openavbAvtpBytes(pListenerData->avtpHandle);
				U32 rxbuf = openavbAvtpRxBufferLevel(pListenerData->avtpHandle);
				U32 mqbuf = openavbMediaQCountItems(pTLState->pMediaQ, TRUE);
				U32 mqrdy = openavbMediaQCountItems(pTLState->pMediaQ, FALSE);
			
				AVB_LOGRT_INFO(LOG_RT_BEGIN, LOG_RT_ITEM, FALSE, "RX UID:%d, ", LOG_RT_DATATYPE_U16, &pListenerData->streamID.uniqueID);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "calls=%ld, ", LOG_RT_DATATYPE_U32, &pListenerData->nReportCalls);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "frames=%ld, ", LOG_RT_DATATYPE_U32, &pListenerData->nReportFrames);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "lost=%lld, ", LOG_RT_DATATYPE_U64, &lost);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "bytes=%lld, ", LOG_RT_DATATYPE_U64, &bytes);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "rxbuf=%d, ", LOG_RT_DATATYPE_U32, &rxbuf);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, FALSE, "mqbuf=%d, ", LOG_RT_DATATYPE_U32, &mqbuf);
				AVB_LOGRT_INFO(FALSE, LOG_RT_ITEM, LOG_RT_END, "mqrdy=%d", LOG_RT_DATATYPE_U32, &mqrdy);

				openavbListenerAddStat(pTLState, TL_STAT_RX_CALLS, pListenerData->nReportCalls);
				openavbListenerAddStat(pTLState, TL_STAT_RX_FRAMES, pListenerData->nReportFrames);
				openavbListenerAddStat(pTLState, TL_STAT_RX_LOST, lost);
				openavbListenerAddStat(pTLState, TL_STAT_RX_BYTES, bytes);

				pListenerData->nReportCalls = 0;
				pListenerData->nReportFrames = 0;
				pListenerData->nextReportNS += (pCfg->report_seconds * NANOSECONDS_PER_SECOND);  
			}
		}

		if (nowNS > pListenerData->nextSecondNS) {
			pListenerData->nextSecondNS += NANOSECONDS_PER_SECOND;
			bRet = TRUE;
		}
	}
	else {
            SLEEP(1);
            bRet = TRUE;
	}

	AVB_TRACE_EXIT(AVB_TRACE_TL);
	return bRet;
}
コード例 #8
0
void openavbAcmpSMController_txCommand(U8 messageType, openavb_acmp_ACMPCommandResponse_t *command, bool retry)
{
	AVB_TRACE_ENTRY(AVB_TRACE_ACMP);
	openavb_list_node_t node = NULL;

	openavbRC rc = openavbAcmpMessageSend(messageType, command, OPENAVB_ACMP_STATUS_SUCCESS);
	if (IS_OPENAVB_SUCCESS(rc)) {
		if (!retry) {
			node = openavbListNew(openavbAcmpSMControllerVars.inflight, sizeof(openavb_acmp_InflightCommand_t));
			if (node) {
				openavb_acmp_InflightCommand_t *pInFlightCommand = openavbListData(node);
				if (pInFlightCommand) {

					memcpy(&pInFlightCommand->command, command, sizeof(pInFlightCommand->command));
					pInFlightCommand->command.message_type = messageType;
					pInFlightCommand->retried = FALSE;
					pInFlightCommand->original_sequence_id = command->sequence_id;	// AVDECC_TODO - is this correct?

					CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &pInFlightCommand->timer);
					switch (messageType) {
						case OPENAVB_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_GET_TX_STATE_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_CONNECT_RX_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_DISCONNECT_RX_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_GET_RX_STATE_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_GET_TX_CONNECTION_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						default:
							AVB_LOGF_ERROR("Unsupported command %u in openavbAcmpSMController_txCommand", messageType);
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_CONNECT_RX_COMMAND * MICROSECONDS_PER_MSEC);
							break;
					}
				}
			}
		}
		else {
			// Retry case
			node = openavbAcmpSMController_findInflightNodeFromCommand(command);
			if (node) {
				openavb_acmp_InflightCommand_t *pInFlightCommand = openavbListData(node);
				if (pInFlightCommand) {
					pInFlightCommand->retried = TRUE;

					CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &pInFlightCommand->timer);
					switch (messageType) {
						case OPENAVB_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_GET_TX_STATE_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_CONNECT_RX_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_DISCONNECT_RX_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_GET_RX_STATE_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						case OPENAVB_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE:
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_GET_TX_CONNECTION_COMMAND * MICROSECONDS_PER_MSEC);
							break;
						default:
							AVB_LOGF_ERROR("Unsupported command %u in openavbAcmpSMController_txCommand", messageType);
							openavbTimeTimespecAddUsec(&pInFlightCommand->timer, OPENAVB_ACMP_COMMAND_TIMEOUT_CONNECT_RX_COMMAND * MICROSECONDS_PER_MSEC);
							break;
					}
				}
			}
		}
	}
	else {
		// Failed to send command
		openavbAcmpMessageSend(messageType, command, OPENAVB_ACMP_STATUS_COULD_NOT_SEND_MESSAGE);
		if (retry) {
			node = openavbAcmpSMController_findInflightNodeFromCommand(command);
			if (node) {
				openavbListDelete(openavbAcmpSMControllerVars.inflight, node);
			}
		}
	}

	AVB_TRACE_EXIT(AVB_TRACE_ACMP);
}
コード例 #9
0
/* Talker client registers a stream
 */
bool openavbEptSrvrRegisterStream(int h,
                              AVBStreamID_t *streamID,
                              U8 destAddr[],
                              AVBTSpec_t *tSpec,
                              U8 srClass,
                              U8 srRank,
                              U32 latency)
{
	openavbRC rc = OPENAVB_SUCCESS;

	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	clientStream_t *ps = findStream(streamID);
	
	if (ps && ps->clientHandle != h) {
		AVB_LOGF_ERROR("Error registering talker; multiple clients for stream %d", streamID->uniqueID);
		AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
		return FALSE;
	}

	ps = addStream(h, streamID);
	if (!ps) {
		AVB_LOGF_ERROR("Error registering talker; unable to add client stream %d", streamID->uniqueID);
		AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
		return FALSE;
	}
	ps->role = clientTalker;
	ps->tSpec = *tSpec;
	ps->srClass = (SRClassIdx_t)srClass;
	ps->srRank  = srRank;
	ps->latency = latency;
	ps->fwmark = INVALID_FWMARK;

	if (memcmp(ps->destAddr, destAddr, ETH_ALEN) == 0) {
		// no client-supplied address, use MAAP
		struct ether_addr addr;
		ps->hndMaap = openavbMaapAllocate(1, &addr);
		if (ps->hndMaap) {
			memcpy(ps->destAddr, addr.ether_addr_octet, ETH_ALEN);
			strmAttachCb((void*)ps, openavbSrp_LDSt_Stream_Info);		// Inform talker about MAAP
		}
		else {
			AVB_LOG_ERROR("Error registering talker: MAAP failed to allocate MAC address");
			AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
			delStream(ps);
			return FALSE;
		}
	}
	else {
		// client-supplied destination MAC address
		memcpy(ps->destAddr, destAddr, ETH_ALEN);
		ps->hndMaap = NULL;
	}

	// Do SRP talker register
	AVB_LOGF_DEBUG("REGISTER: ps=%p, streamID=%d, tspec=%d,%d, srClass=%d, srRank=%d, latency=%d, da="ETH_FORMAT"",
				   ps, streamID->uniqueID,
				   tSpec->maxFrameSize, tSpec->maxIntervalFrames,
				   ps->srClass, ps->srRank, ps->latency,
				   ETH_OCTETS(ps->destAddr));


	if(x_cfg.noSrp) {
		// we are operating in a mode supporting preconfigured streams; SRP is not in use,
		// so, as a proxy for SRP, which would normally make this call after establishing
		// the stream, call the callback from here
		strmAttachCb((void*)ps, openavbSrp_LDSt_Ready);
	} else {
		// normal SRP operation
		rc = openavbSrpRegisterStream((void*)ps, &ps->streamID,
		                          ps->destAddr, &ps->tSpec,
		                          ps->srClass, ps->srRank,
		                          ps->latency);
		if (!IS_OPENAVB_SUCCESS(rc)) {
			if (ps->hndMaap)
				openavbMaapRelease(ps->hndMaap);
			delStream(ps);
		}
	}

	openavbEndPtLogAllStaticStreams();
	
	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
	return IS_OPENAVB_SUCCESS(rc);
}
コード例 #10
0
ファイル: openavb_endpoint.c プロジェクト: AVnu/Open-AVB
int avbEndpointLoop(void)
{
	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	int retVal = -1;
	openavbRC rc = OPENAVB_SUCCESS;
	do {

		if (!x_cfg.bypassAsCapableCheck && (startPTP() < 0)) {
			// make sure ptp, a separate process, starts and is using the same interface as endpoint
			AVB_LOG_ERROR("PTP failed to start - Exiting");
			break;
		} else if(x_cfg.bypassAsCapableCheck) {
			AVB_LOG_WARNING(" ");
			AVB_LOG_WARNING("Configuration 'gptp_asCapable_not_required = 1' is set.");
			AVB_LOG_WARNING("This configuration bypasses the requirement for gPTP");
			AVB_LOG_WARNING("and openavb_gptp is not started automatically.");
			AVB_LOG_WARNING("An appropriate ptp MUST be started separately.");
			AVB_LOG_WARNING("Any network which does not use ptp to synchronize time");
			AVB_LOG_WARNING("on each and every network device is NOT an AVB network.");
			AVB_LOG_WARNING("Such a network WILL NOT FUNCTION PROPERLY.");
			AVB_LOG_WARNING(" ");
		}

		x_streamList = NULL;

		if (!openavbQmgrInitialize(x_cfg.fqtss_mode, x_cfg.ifindex, x_cfg.ifname, x_cfg.mtu, x_cfg.link_kbit, x_cfg.nsr_kbit)) {
			AVB_LOG_ERROR("Failed to initialize QMgr");
			break;
		}

		if (!openavbMaapInitialize(x_cfg.ifname, x_cfg.maapPort, &(x_cfg.maap_preferred), maapRestartCallback)) {
			AVB_LOG_ERROR("Failed to initialize MAAP");
			openavbQmgrFinalize();
			break;
		}

		if (!openavbShaperInitialize(x_cfg.ifname, x_cfg.shaperPort)) {
			AVB_LOG_ERROR("Failed to initialize Shaper");
			openavbMaapFinalize();
			openavbQmgrFinalize();
			break;
		}

		if(!x_cfg.noSrp) {
			// Initialize SRP
			rc = openavbSrpInitialize(strmAttachCb, strmRegCb, x_cfg.ifname, x_cfg.link_kbit, x_cfg.bypassAsCapableCheck);
		} else {
			rc = OPENAVB_SUCCESS;
			AVB_LOG_WARNING(" ");
			AVB_LOG_WARNING("Configuration 'preconfigured = 1' is set.");
			AVB_LOG_WARNING("SRP is disabled. Streams MUST be configured manually");
			AVB_LOG_WARNING("on each and every device in the network, without exception.");
			AVB_LOG_WARNING("AN AVB NETWORK WILL NOT FUNCTION AS EXPECTED UNLESS ALL");
			AVB_LOG_WARNING("STREAMS ARE PROPERLY CONFIGURED ON ALL NETWORK DEVICES.");
			AVB_LOG_WARNING(" ");
		}

		if (!IS_OPENAVB_SUCCESS(rc)) {
			AVB_LOG_ERROR("Failed to initialize SRP");
			openavbShaperFinalize();
			openavbMaapFinalize();
			openavbQmgrFinalize();
			break;
		}

		if (openavbEndpointServerOpen()) {

			retVal = 0;

			while (endpointRunning) {
				openavbEptSrvrService();
			}

			openavbEndpointServerClose();
		}

		if(!x_cfg.noSrp) {
			// Shutdown SRP
			openavbSrpShutdown();
		}

		openavbShaperFinalize();
		openavbMaapFinalize();
		openavbQmgrFinalize();

	} while (0);

	if (!x_cfg.bypassAsCapableCheck && (stopPTP() < 0)) {
		AVB_LOG_WARNING("Failed to execute PTP stop command: killall -s SIGINT openavb_gptp");
	}

	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
	return retVal;
}
コード例 #11
0
ファイル: openavb_endpoint.c プロジェクト: AVnu/Open-AVB
/* SRP tells us about a listener peer (Listener Ready or Failed)
 */
openavbRC strmAttachCb(void* pv,
							 openavbSrpLsnrDeclSubtype_t lsnrDecl)
{
	AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);

	openavbRC rc = OPENAVB_FAILURE;
	clientStream_t *ps = (clientStream_t*)pv;

	AVB_LOGF_INFO("SRP talker callback uid=%d: lsnrDecl=%x", ps->streamID.uniqueID, lsnrDecl);

	if (lsnrDecl == openavbSrp_LDSt_Ready
		|| lsnrDecl == openavbSrp_LDSt_Ready_Failed)
	{
		// Somebody is listening - get ready to stream

		if (ps->fwmark != INVALID_FWMARK) {
			AVB_LOG_DEBUG("attach callback: already setup queues");
			rc = OPENAVB_SUCCESS;
		}
		else {
			AVB_LOG_DEBUG("Attach callback: setting up queues for streaming");

			rc = openavbSrpGetClassParams(ps->srClass, &ps->priority, &ps->vlanID, &ps->classRate);
			if (IS_OPENAVB_SUCCESS(rc)) {
				ps->fwmark = openavbQmgrAddStream(ps->srClass, ps->classRate, ps->tSpec.maxIntervalFrames, ps->tSpec.maxFrameSize);
				if (ps->fwmark == INVALID_FWMARK) {
					AVB_LOG_ERROR("Error in attach callback: unable to setup stream queues");
					rc = OPENAVB_FAILURE;
				}
				else {
					rc = OPENAVB_SUCCESS;
				}
			}
			else {
				AVB_LOG_ERROR("Error in attach callback: unable to get class params");
				rc = OPENAVB_FAILURE;
			}
		}
	}
	else {
		// Nobody listening
		if (ps->fwmark != INVALID_FWMARK) {
			AVB_LOG_DEBUG("Attach callback: tearing down queues");
			openavbQmgrRemoveStream(ps->fwmark);
			ps->fwmark = INVALID_FWMARK;
		}
		rc = OPENAVB_SUCCESS;
	}

	if (IS_OPENAVB_SUCCESS(rc)) {

		openavbEptSrvrNotifyTlkrOfSrpCb(ps->clientHandle,
		                             &ps->streamID,
		                             x_cfg.ifname,
		                             ps->destAddr,
		                             lsnrDecl,
		                             ps->srClass,
		                             ps->classRate,
		                             ps->vlanID,
		                             ps->priority,
		                             ps->fwmark);
		rc = OPENAVB_SUCCESS;
	}

	AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
	return rc;
}