File: ltpclo.c

package info (click to toggle)
ion 3.2.1%2Bdfsg-1.1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 23,768 kB
  • ctags: 11,049
  • sloc: ansic: 141,798; sh: 22,848; makefile: 7,818; python: 1,638; sql: 311; perl: 197; awk: 178; xml: 50; java: 19
file content (188 lines) | stat: -rw-r--r-- 3,914 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
	ltpclo.c:	BP LTP-based convergence-layer output
			daemon, designed to serve as an output duct.

	Author: Scott Burleigh, JPL

	Copyright (c) 2007, California Institute of Technology.
	ALL RIGHTS RESERVED.  U.S. Government Sponsorship
	acknowledged.
	
									*/
#include "ltpcla.h"
#include "zco.h"

static sm_SemId		ltpcloSemaphore(sm_SemId *semid)
{
	long		temp;
	void		*value;
	sm_SemId	semaphore;
	
	if (semid)			/*	Add task variable.	*/
	{
		temp = *semid;
		value = (void *) temp;
		value = sm_TaskVar(&value);
	}
	else				/*	Retrieve task variable.	*/
	{
		value = sm_TaskVar(NULL);
	}

	temp = (long) value;
	semaphore = temp;
	return semaphore;
}

static void	shutDownClo()	/*	Commands CLO termination.	*/
{
	isignal(SIGTERM, shutDownClo);
	sm_SemEnd(ltpcloSemaphore(NULL));
}

/*	*	*	Main thread functions	*	*	*	*/

#if defined (VXWORKS) || defined (RTEMS) || defined (bionic)
int	ltpclo(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
	char		*ductName = (char *) a1;
#else
int	main(int argc, char *argv[])
{
	char		*ductName = (argc > 1 ? argv[1] : NULL);
#endif
	Sdr		sdr;
	VOutduct	*vduct;
	PsmAddress	vductElt;
	int		allGreen = 0;		/*	Boolean		*/
	vast		destEngineNbr;
	Outduct		outduct;
	Outflow		outflows[3];
	int		i;
	int		running = 1;
	Object		bundleZco;
	BpExtendedCOS	extendedCOS;
	char		destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int	redPartLength;
	LtpSessionId	sessionId;

	if (ductName == NULL)
	{
		PUTS("Usage: ltpclo [-]<destination engine number>");
		return 0;
	}

	if (bpAttach() < 0)
	{
		putErrmsg("ltpclo can't attach to BP.", NULL);
		return -1;
	}

	sdr = getIonsdr();
	findOutduct("ltp", ductName, &vduct, &vductElt);
	if (vductElt == 0)
	{
		putErrmsg("No such ltp duct.", ductName);
		return -1;
	}

	if (vduct->cloPid != ERROR && vduct->cloPid != sm_TaskIdSelf())
	{
		putErrmsg("CLO task is already started for this duct.",
				itoa(vduct->cloPid));
		return -1;
	}

	/*	All command-line arguments are now validated.		*/

	CHKERR(sdr_begin_xn(sdr));
	sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, vduct->outductElt),
			sizeof(Outduct));
	sdr_exit_xn(sdr);
	destEngineNbr = strtovast(ductName);
	if (destEngineNbr < 0)
	{
		allGreen = 1;
		destEngineNbr = 0 - destEngineNbr;
	}

	memset((char *) outflows, 0, sizeof outflows);
	outflows[0].outboundBundles = outduct.bulkQueue;
	outflows[1].outboundBundles = outduct.stdQueue;
	outflows[2].outboundBundles = outduct.urgentQueue;
	for (i = 0; i < 3; i++)
	{
		outflows[i].svcFactor = 1 << i;
	}

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

	/*	Set up signal handling.  SIGTERM is shutdown signal.	*/

	oK(ltpcloSemaphore(&(vduct->semaphore)));
	isignal(SIGTERM, shutDownClo);

	/*	Can now begin transmitting to remote duct.		*/

	writeMemo("[i] ltpclo is running.");
	while (running && !(sm_SemEnded(ltpcloSemaphore(NULL))))
	{
		if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS,
				destDuctName, 0, -1) < 0)
		{
			running = 0;	/*	Terminate CLO.		*/
			continue;
		}

		if (bundleZco == 0)	/*	Interrupted.		*/
		{
			continue;
		}

		if (allGreen)
		{
			redPartLength = 0;
		}
		else
		{
			if (extendedCOS.flags & BP_BEST_EFFORT)
			{
				redPartLength = 0;
			}
			else
			{
				redPartLength = LTP_ALL_RED;
			}
		}

		switch (ltp_send(destEngineNbr, BpLtpClientId, bundleZco,
				redPartLength, &sessionId))
		{
		case 0:
			putErrmsg("Unable to send this bundle via LTP.", NULL);
			break;

		case -1:
			putErrmsg("LtpSend failed.", NULL);
			running = 0;	/*	Terminate CLO.		*/
		}

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

		sm_TaskYield();

		/*	Note: bundleZco is destroyed later, when LTP's
		 *	ExportSession is closed following transmission
		 *	of bundle ZCOs as aggregated into a block.	*/
	}

	writeErrmsgMemos();
	writeMemo("[i] ltpclo duct has ended.");
	ionDetach();
	return 0;
}