Example #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;
}
Example #2
0
int	ltpcounter(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
	int		clientId = a1;
	int		maxBytes = a2;
#else
int	main(int argc, char **argv)
{
	int		clientId = (argc > 1 ? strtol(argv[1], NULL, 0) : 0);
	int		maxBytes = (argc > 2 ? strtol(argv[2], NULL, 0) : 0);
#endif
	IonAlarm	alarm = { 5, 0, showProgress, NULL };
	pthread_t	alarmThread;
	int		state = 1;
	LtpNoticeType	type;
	LtpSessionId	sessionId;
	unsigned char	reasonCode;
	unsigned char	endOfBlock;
	unsigned int	dataOffset;
	unsigned int	dataLength;
	Object		data;
	char		buffer[255];

	if (clientId < 1)
	{
		PUTS("Usage: ltpcounter <client ID> [<max nbr of bytes>]");
		PUTS("  Max nbr of bytes defaults to 2 billion.");
		return 0;
	}

	oK(_clientId(&clientId));
	if (maxBytes < 1)
	{
		maxBytes = 2000000000;
	}

	if (ltp_attach() < 0)
	{
		putErrmsg("ltpcounter can't initialize LTP.", NULL);
		return 1;
	}

	if (ltp_open(_clientId(NULL)) < 0)
	{
		putErrmsg("ltpcounter can't open client access.",
				itoa(_clientId(NULL)));
		return 1;
	}

	ionSetAlarm(&alarm, &alarmThread);
	isignal(SIGINT, handleQuit);
	oK((_running(&state)));
	while (_running(NULL))
	{
		if (ltp_get_notice(_clientId(NULL), &type, &sessionId,
				&reasonCode, &endOfBlock, &dataOffset,
				&dataLength, &data) < 0)
		{
			putErrmsg("Can't get LTP notice.", NULL);
			state = 0;
			oK((_running(&state)));
			continue;
		}

		switch (type)
		{
		case LtpExportSessionCanceled:
			isprintf(buffer, sizeof buffer, "Transmission \
canceled: source engine " UVAST_FIELDSPEC ", session %u, reason code %d.",
					sessionId.sourceEngineId,
					sessionId.sessionNbr, reasonCode);
			writeMemo(buffer);
			if (data)
			{
				ltp_release_data(data);
			}

			break;

		case LtpImportSessionCanceled:
			oK(_sessionsCanceled(1));
			isprintf(buffer, sizeof buffer, "Reception canceled: \
source engine " UVAST_FIELDSPEC ", session %u, reason code %d.",
					sessionId.sourceEngineId,
					sessionId.sessionNbr, reasonCode);
			writeMemo(buffer);
			break;

		case LtpRecvGreenSegment:
			isprintf(buffer, sizeof buffer, "Green segment \
received, discarded: source engine " UVAST_FIELDSPEC ", session %u, \
offset %u, length %u, eob=%d.", sessionId.sourceEngineId, sessionId.sessionNbr,
					dataOffset, dataLength, endOfBlock);
			writeMemo(buffer);
			ltp_release_data(data);
			break;

		case LtpRecvRedPart:
			oK(_blocksReceived(1));
			oK(_bytesReceived(dataLength));
			ltp_release_data(data);
			break;

		default:
			break;
		}

		if (_bytesReceived(0) >= maxBytes)
		{
			state = 0;
			oK((_running(&state)));
		}
	}

	ionCancelAlarm(alarmThread);
	writeErrmsgMemos();
	printCount();
	PUTS("Stopping ltpcounter.");
	ltp_close(_clientId(NULL));
	ltp_detach();
	return 0;
}
Example #3
0
File: ltpcli.c Project: 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;
}