⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voip_stream_server.c

📁 telcobridges voip develop
💻 C
📖 第 1 页 / 共 4 页
字号:
	 |  Error handling section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	ERROR_HANDLING
	{
		/* Print the error to the user */
		TbxCliToolsLogPrint(
			pCliContext->hCliTools,
			TRACE_LEVEL_ERROR,
			NULL,
			"VoipStreamServerStart: %s (Result 0x%08X, %s, line %d)\n",
			TBX_ERROR_DESCRIPTION,
			TBX_ERROR_RESULT,
			__FILE__,
			TBX_ERROR_LINE);
	}

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Cleanup section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CLEANUP
	{
		TBX_SEM_GIV( pStreamServerContext->StreamServerSem );
	}

	RETURN;
}

/*-------------------------------------------------------------------------------------------------------------------------------
 |
 |  VoipStreamServerClose	:	This function closes the stream server library.
 |
 |  Note					:	~
 |
 |  Return					:	TBX_RESULT_OK if the function succeeded
 |								Other error code if the function could not complete properly.
 |
 *------------------------------------------------------------------------------------------------------------------------------*/
TBX_RESULT
VoipStreamServerClose()
{
	PVOIP_CLI_CONTEXT			pCliContext;
	PVOIP_STREAM_SERVER_CONTEXT	pStreamServerContext;
	TBX_THREAD					hThread;

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Code section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CODE
	{
		/* Initialize local variables */
		pCliContext = &g_pContext->CliContext;
		pStreamServerContext = &g_pContext->StreamServerContext;

		if( pStreamServerContext->hStreamServerLib != (TBX_STREAM_SERVER_LIB_HANDLE)TBX_HANDLE_INVALID )
		{
			TBX_SEM_GET( pStreamServerContext->StreamServerSem, TBX_SEM_WAIT_FOREVER );

			/* Close the receive thread */
			hThread = pStreamServerContext->hRecvThread;

			pStreamServerContext->hRecvThread = TBX_THREAD_INVALID;
			if( hThread != TBX_THREAD_INVALID )
			{
				/* Unblock the thread from its "read" function */
				StreamServerLibCancelReceive( pStreamServerContext->hStreamServerLib );

				while( !pStreamServerContext->fRecvThreadDone )
				{
					TBX_SEM_GIV( pStreamServerContext->StreamServerSem );
					TBX_SLEEP_MS( 10 );
					TBX_SEM_GET( pStreamServerContext->StreamServerSem, TBX_SEM_WAIT_FOREVER );
				}
				TBX_THREAD_DESTROY( &hThread );
			}

			StreamServerLibClose( pStreamServerContext->hStreamServerLib );
			pStreamServerContext->hStreamServerLib = (TBX_STREAM_SERVER_LIB_HANDLE)TBX_HANDLE_INVALID;

			/* Destroy the pool of prompt contexts */
			if( pStreamServerContext->hPoolOfPrompts != TBX_HANDLE_INVALID )
			{
				TBXPoolOfBuffersDestroy( pStreamServerContext->hPoolOfPrompts );
				pStreamServerContext->hPoolOfPrompts = TBX_HANDLE_INVALID;
			}

			TBX_SEM_GIV( pStreamServerContext->StreamServerSem );
			TBX_SEM_DESTROY( &pStreamServerContext->StreamServerSem );
		}

		/* Mark the stream server as not enable */
		pStreamServerContext->fEnable = TBX_FALSE;

		/* End of the code (skip to cleanup) */
		TBX_EXIT_SUCCESS (TBX_RESULT_OK);
	}

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Error handling section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	ERROR_HANDLING
	{
		/* Print the error to the user */
		TbxCliToolsLogPrint(
			pCliContext->hCliTools,
			TRACE_LEVEL_ERROR,
			NULL,
			"VoipStreamServerClose: %s (Result 0x%08X, %s, line %d)\n",
			TBX_ERROR_DESCRIPTION,
			TBX_ERROR_RESULT,
			__FILE__,
			TBX_ERROR_LINE);
	}

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Cleanup section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CLEANUP
	{
	}

	RETURN;
}

/*-------------------------------------------------------------------------------------------------------------------------------
 |
 |  VoipStreamServerReceiveThread	:	Thread that receives the responses from the stream server
 |
 |  Note							:	~
 |
 |  Return							:	TBX_RESULT_OK if the function succeeded
 |										Other error code if the function could not complete properly.
 |
 *------------------------------------------------------------------------------------------------------------------------------*/
static TBX_RESULT VoipStreamServerReceiveThread()
{
	TBX_RESULT							result;
	PVOIP_CLI_CONTEXT					pCliContext;
	STREAMSERVER_MSG					Message;
	STREAMSERVER_MSG					OutMessage;
	TBX_STREAM_SERVER_HANDLE			hStreamServer;
	PVOIP_STREAM_SERVER_CONTEXT			pStreamServerContext;
	PVOIP_STREAM_SERVER_PROMPT_CONTEXT	pStreamServerPromptContext;

	/* Initialize local variables */
	pCliContext = &g_pContext->CliContext;
	pStreamServerContext = &g_pContext->StreamServerContext;

	TBX_SEM_GET( pStreamServerContext->StreamServerSem, TBX_SEM_WAIT_FOREVER );

	pStreamServerContext->fRecvThreadRunning = TBX_TRUE;
	TbxCliToolsLogPrint( pCliContext->hCliTools, TRACE_LEVEL_ALWAYS, NULL, "Stream server receive thread started...\n" );

	/* Force server availability update to immediately get the availability of the stream server */
	StreamServerForceAvailabilityUpdate( pStreamServerContext->hStreamServerLib );

	while( g_fContinue == TBX_TRUE )
	{
		/* Wait for a message from a stream server... */
		TBX_SEM_GIV( pStreamServerContext->StreamServerSem );
		result = StreamServerLibRead
		(
			pStreamServerContext->hStreamServerLib,
			&Message,
			0xFFFFFFFF,
			&hStreamServer,
			NULL
		);
		TBX_SEM_GET( pStreamServerContext->StreamServerSem, TBX_SEM_WAIT_FOREVER );

		if( g_fContinue == TBX_FALSE )
		{
			break;
		}

		/* Was the receive successful and the message from our stream server? */
		if( TBX_RESULT_SUCCESS( result ) && (hStreamServer == pStreamServerContext->hStreamServer) )
		{
			TbxCliToolsLogPrint(
				pCliContext->hCliTools,
				TRACE_LEVEL_1,
				NULL,
				"Stream server: Received message type %d from stream server, context 0x%08X\n",
				(int)Message.Header.MessageType,
				(int)Message.Header.un32UserContext );

			/* Validate this is an expected stream server response */
			switch( Message.Header.MessageType )
			{
				case STREAMSERVER_MSG_ID_EVT_SERVER_AVAILABILITY:
				{
					TBX_BOOL	fServerAvailable;

					fServerAvailable = Message.EvtServerAvailbility.fIpAddress0Available || Message.EvtServerAvailbility.fIpAddress1Available;

					if( pStreamServerContext->fServerAvailable != fServerAvailable )
					{
						TbxCliToolsLogPrint(
							pCliContext->hCliTools,
							TRACE_LEVEL_1,
							NULL,
							"Stream server: State is now %s\n",
							fServerAvailable ? "available" : "unavailable" );

						if( fServerAvailable )
						{
							/* Server was unavailable, now available. We must re-synchronize */
							TbxCliToolsLogPrint(
								pCliContext->hCliTools,
								TRACE_LEVEL_1,
								NULL,
								"Stream server: resynchronization starting...\n" );

							/* Build the "list playing prompts" message... */
							memset( &OutMessage.ReqListPlayingPrompts, 0, sizeof(OutMessage.ReqListPlayingPrompts) );
							OutMessage.Header.MessageType						= STREAMSERVER_MSG_ID_REQ_LIST_PLAYING_PROMPTS;
							OutMessage.Header.un32UserContext					= 0;	/* Don't care */
							OutMessage.ReqListPlayingPrompts.fCurrentAppOnly	= TBX_TRUE;

							result = StreamServerLibCommandSend
							(
								pStreamServerContext->hStreamServerLib,
								&OutMessage,
								pStreamServerContext->hStreamServer
							);
							if( TBX_RESULT_SUCCESS(result) )
							{
								/* Server is available. Resynch starting. */
								pStreamServerContext->fServerAvailable = TBX_TRUE;
								pStreamServerContext->fResyncRunning = TBX_TRUE;
							}
							else
							{
								TbxCliToolsLogPrint(
									pCliContext->hCliTools,
									TRACE_LEVEL_1,
									NULL,
									"Stream server: resynchronization FAILED (failed to send ListPrompts message).\n" );
							}
						}
						else
						{
							/* Mark every prompts has not synched yet... */
							pStreamServerPromptContext = TBXPoolOfBuffersFirst( pStreamServerContext->hPoolOfPrompts );
							while( pStreamServerPromptContext )
							{
								pStreamServerPromptContext->fSynched = TBX_FALSE;

								pStreamServerPromptContext = TBXPoolOfBuffersNext( pStreamServerContext->hPoolOfPrompts, pStreamServerPromptContext );
							}

							/* Server is no more available. We will stop accepting calls */
							pStreamServerContext->fServerAvailable	= TBX_FALSE;
							pStreamServerContext->fResyncRunning	= TBX_FALSE;
						}
					}
				} break;

				case STREAMSERVER_MSG_ID_RSP_LIST_PLAYING_PROMPTS:
				{
					/* This is a response from "list playing prompts" */
					if( pStreamServerContext->fResyncRunning )
					{
						if( Message.RspListPlayingPrompts.un32NbPrompts == 0 )
						{
							/* End of listing */
							TbxCliToolsLogPrint(
								pCliContext->hCliTools,
								TRACE_LEVEL_1,
								NULL,
								"Stream server: resynchronization finished.\n" );

							/* Any non-synched resource means it is not playing anymore on the server */
							pStreamServerPromptContext = TBXPoolOfBuffersFirst( pStreamServerContext->hPoolOfPrompts );
							while( pStreamServerPromptContext )
							{
								if( pStreamServerPromptContext->fSynched )
								{
									/*  This context has already been "synched" */
								}
								else
								{
									pStreamServerPromptContext->fSynched = TBX_TRUE;
									if( pStreamServerPromptContext->fStarting || pStreamServerPromptContext->fPlaying )
									{
										TbxCliToolsLogPrint(
											pCliContext->hCliTools,
											TRACE_LEVEL_1,
											NULL,
											"Stream server: restarting playback after resync for prompt 0x%08X because server stopped play while it was unavailable.\n",
											pStreamServerPromptContext->un32PromptId );

										/* The state machine expects the channel to still be playing, restart playback */
										VoipStreamServerStartPlayInternal( pStreamServerPromptContext );
									}
									else if( pStreamServerPromptContext->fStopping )
									{
										/* The state machine expects the "DONE" response. Simulate that */
										TbxCliToolsLogPrint(
											pCliContext->hCliTools,
											TRACE_LEVEL_1,
											NULL,
											"Stream server: Simulating RSP_DONE for prompt 0x%08X because server stopped play while it was unavailable.\n",
											pStreamServerPromptContext->un32PromptId );

										pStreamServerPromptContext->fStarting	= TBX_FALSE;
										pStreamServerPromptContext->fPlaying	= TBX_FALSE;
										pStreamServerPromptContext->fStopping	= TBX_FALSE;
									}
								}

								pStreamServerPromptContext = TBXPoolOfBuffersNext( pStreamServerContext->hPoolOfPrompts, pStreamServerPromptContext );
							}

							/* Resynchronization done */
							pStreamServerContext->fResyncRunning = TBX_FALSE;
						}
						else
						{
							/* Retrieve the prompt context */
							pStreamServerPromptContext = TBXPoolOfBuffersFind(
								pStreamServerContext->hPoolOfPrompts,
								Message.RspListPlayingPrompts.un32UserContext);
							if( pStreamServerPromptContext )
							{
								if( pStreamServerPromptContext->fSynched )
								{
									/* No need to resync */
								}
								else
								{
									pStreamServerPromptContext->fSynched = TBX_TRUE;

									/* Validate that our state matches the stream server's */
									if( pStreamServerPromptContext->fStarting )
									{
										/* Current app is waiting for the "started" event, that we probably missed
										   because the stream server was disconnected. Simulate that we received it */

										TbxCliToolsLogPrint(
											pCliContext->hCliTools,
											TRACE_LEVEL_1,
											NULL,
											"Stream server: Simulating RSP_STARTED for prompt 0x%08X because server started play while it was unavailable.\n",
											pStreamServerPromptContext->un32PromptId );

										pStreamServerPromptContext->fStarting	= TBX_FALSE;
										pStreamServerPromptContext->fPlaying	= TBX_TRUE;
										pStreamServerPromptContext->fStopping	= TBX_FALSE;
									}
									else if( pStreamServerPromptContext->fPlaying )
									{
										/* Current app expects the call to be playing, which is in fact the case!
										   Keep it like this! */
									}
									else
									{
										/* Current app expects the call to be stopping or be already stopped.
										   Stop this playback on the server */
										TbxCliToolsLogPrint(
											pCliContext->hCliTools,
											TRACE_LEVEL_1,
											NULL,
											"Stream server: Stopping play ctx 0x%08X on stream server because current app stopped it while server was unavailable.\n",
											Message.RspListPlayingPrompts.un32UserContext );

										memset( &OutMessage.ReqStop, 0, sizeof(OutMessage.ReqStop) );
										OutMessage.Header.MessageType		= STREAMSERVER_MSG_ID_REQ_STOP;
										OutMessage.Header.un32UserContext	= Message.RspListPlayingPrompts.un32UserContext;
										StreamServerLibCommandSend
										(
											pStreamServerContext->hStreamServerLib,
											&OutMessage,
											pStreamServerContext->hStreamServer
										);
									}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -