Ejemplo n.º 1
0
static void	*handleNotices(void *parm)
{
	/*	Main loop for LTP notice reception and handling.	*/

	Sdr			sdr = getIonsdr();
	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	char			*procName = "ltpcli";
	AcqWorkArea		*redWork;
	AcqWorkArea		*greenWork;
	LtpNoticeType		type;
	LtpSessionId		sessionId;
	unsigned char		reasonCode;
	unsigned char		endOfBlock;
	unsigned int		dataOffset;
	unsigned int		dataLength;
	Object			data;		/*	ZCO reference.	*/
	unsigned int		greenBuflen = 0;
	char			*greenBuffer = NULL;

	snooze(1);	/*	Let main thread become interruptable.	*/
	if (ltp_open(BpLtpClientId) < 0)
	{
		putErrmsg("ltpcli can't open client access.",
				itoa(BpLtpClientId));
		ionKillMainThread(procName);
		return NULL;
	}

	redWork = bpGetAcqArea(rtp->vduct);
	greenWork = bpGetAcqArea(rtp->vduct);
	if (redWork == NULL || greenWork == NULL)
	{
		ltp_close(BpLtpClientId);
		putErrmsg("ltpcli can't get acquisition work areas", NULL);
		ionKillMainThread(procName);
		return NULL;
	}

	/*	Can now start receiving notices.  On failure, take
	 *	down the CLI.						*/

	while (rtp->running)
	{
		if (ltp_get_notice(BpLtpClientId, &type, &sessionId,
				&reasonCode, &endOfBlock, &dataOffset,
				&dataLength, &data) < 0)
		{
			putErrmsg("Can't get LTP notice.", NULL);
			ionKillMainThread(procName);
			rtp->running = 0;
			continue;
		}

		switch (type)
		{
		case LtpExportSessionComplete:	/*	Xmit success.	*/
			if (data == 0)		/*	Ignore it.	*/
			{
				break;		/*	Out of switch.	*/
			}

			if (bpHandleXmitSuccess(data, 0) < 0)
			{
				putErrmsg("Crashed on xmit success.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
				break;		/*	Out of switch.	*/
			}

			CHKNULL(sdr_begin_xn(sdr));
			zco_destroy(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed on data cleanup.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpExportSessionCanceled:	/*	Xmit failure.	*/
			if (data == 0)		/*	Ignore it.	*/
			{
				break;		/*	Out of switch.	*/
			}

			if (bpHandleXmitFailure(data) < 0)
			{
				putErrmsg("Crashed on xmit failure.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
				break;		/*	Out of switch.	*/
			}

			CHKNULL(sdr_begin_xn(sdr));
			zco_destroy(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed on data cleanup.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpImportSessionCanceled:
			/*	None of the red data for the import
			 *	session (if any) have been received
			 *	yet, so nothing to discard.  In case
			 *	part or all of the import session was
			 *	green data, force deletion of retained
			 *	data.					*/

			sessionId.sourceEngineId = 0;
			sessionId.sessionNbr = 0;
			if (handleGreenSegment(greenWork, &sessionId,
					0, 0, 0, 0, NULL, NULL) < 0)
			{
				putErrmsg("Can't cancel green session.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpRecvRedPart:
			if (!endOfBlock)
			{
				/*	Block is partially red and
				 *	partially green.  Too risky
				 *	to wait for green EOB before
				 *	clearing the work area, so
				 *	just discard the data.		*/

				CHKNULL(sdr_begin_xn(sdr));
				zco_destroy(sdr, data);
				if (sdr_end_xn(sdr) < 0)
				{
					putErrmsg("Crashed: partially red.",
							NULL);
					ionKillMainThread(procName);
					rtp->running = 0;
				}

				break;		/*	Out of switch.	*/
			}

			if (acquireRedBundles(redWork, data,
					sessionId.sourceEngineId) < 0)
			{
				putErrmsg("Can't acquire bundle(s).", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpRecvGreenSegment:
			if (handleGreenSegment(greenWork, &sessionId,
					endOfBlock, dataOffset, dataLength,
					data, &greenBuflen, &greenBuffer) < 0)
			{
				putErrmsg("Can't handle green segment.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			/*	Discard the ZCO in any case.		*/

			CHKNULL(sdr_begin_xn(sdr));
			zco_destroy(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed: green segment.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		default:
			break;		/*	Out of switch.		*/
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] ltpcli receiver thread has ended.");

	/*	Free resources.						*/

	if (greenBuffer)
	{
		MRELEASE(greenBuffer);
	}

	bpReleaseAcqArea(greenWork);
	bpReleaseAcqArea(redWork);
	ltp_close(BpLtpClientId);
	return NULL;
}
Ejemplo n.º 2
0
Archivo: ltpcli.c Proyecto: b/ION
static void	*handleNotices(void *parm)
{
	/*	Main loop for LTP notice reception and handling.	*/

	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	AcqWorkArea		*work;
	LtpNoticeType		type;
	LtpSessionId		sessionId;
	unsigned char		reasonCode;
	unsigned char		endOfBlock;
	unsigned long		dataOffset;
	unsigned long		dataLength;
	Object			data;		/*	ZCO reference.	*/
	Sdr			sdr;

	snooze(1);	/*	Let main thread become interruptable.	*/
	if (ltp_open(BpLtpClientId) < 0)
	{
		putErrmsg("ltpcli can't open client access.",
				itoa(BpLtpClientId));
		pthread_kill(rtp->mainThread, SIGTERM);
		return NULL;
	}

	work = bpGetAcqArea(rtp->vduct);
	if (work == NULL)
	{
		ltp_close(BpLtpClientId);
		putErrmsg("ltpcli can't get acquisition work area", NULL);
		pthread_kill(rtp->mainThread, SIGTERM);
		return NULL;
	}

	/*	Can now start receiving notices.  On failure, take
	 *	down the CLI.						*/

	while (rtp->running)
	{	
		if (ltp_get_notice(BpLtpClientId, &type, &sessionId,
				&reasonCode, &endOfBlock, &dataOffset,
				&dataLength, &data) < 0)
		{
			putErrmsg("Can't get LTP notice.", NULL);
			pthread_kill(rtp->mainThread, SIGTERM);
			rtp->running = 0;
			continue;
		}

		switch (type)
		{
		case LtpExportSessionCanceled:	/*	Xmit failure.	*/
			if (data == 0)		/*	Ignore it.	*/
			{
				break;		/*	Out of switch.	*/
			}

			if (bpHandleXmitFailure(data) < 0)
			{
				putErrmsg("Crashed on xmit failure.", NULL);
				pthread_kill(rtp->mainThread, SIGTERM);
				rtp->running = 0;
				break;		/*	Out of switch.	*/
			}

			sdr = getIonsdr();
			sdr_begin_xn(sdr);
			zco_destroy_reference(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed on data cleanup.", NULL);
				pthread_kill(rtp->mainThread, SIGTERM);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpImportSessionCanceled:
			break;		/*	Out of switch.		*/

		case LtpRecvGreenSegment:
		case LtpRecvRedPart:
			if (acquireBundles(work, data,
					sessionId.sourceEngineId) < 0)
			{
				putErrmsg("Can't acquire bundle(s).", NULL);
				pthread_kill(rtp->mainThread, SIGTERM);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		default:
			break;		/*	Out of switch.		*/
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] ltpcli receiver thread has ended.");

	/*	Free resources.						*/

	bpReleaseAcqArea(work);
	ltp_close(BpLtpClientId);
	return NULL;
}