~ubuntu-branches/debian/experimental/ion/experimental

« back to all changes in this revision

Viewing changes to ltp/aos/aoslsi.c

  • Committer: Package Import Robot
  • Author(s): Leo Iannacone
  • Date: 2012-02-01 09:46:31 UTC
  • Revision ID: package-import@ubuntu.com-20120201094631-qpfwehc1b7ftkjgx
Tags: upstream-2.5.3~dfsg1
ImportĀ upstreamĀ versionĀ 2.5.3~dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  aoslsi.c - LTP over AOS Link Service Adapter, input
 
3
 
 
4
*/
 
5
 
 
6
/* 7/6/2010, copied from udplsi, as per issue 101-LTP-over-AOS-via-UDP
 
7
   Greg Menke, Raytheon, under contract METS-MR-679-0909 with NASA GSFC */
 
8
 
 
9
 
 
10
#include "aoslsa.h"
 
11
 
 
12
static void     interruptThread()
 
13
{
 
14
        isignal(SIGTERM, interruptThread);
 
15
        ionKillMainThread("aoslsi");
 
16
}
 
17
 
 
18
/*      *       *       Receiver thread functions       *       *       */
 
19
 
 
20
typedef struct
 
21
{
 
22
        int             linkSocket;
 
23
        int             running;
 
24
} ReceiverThreadParms;
 
25
 
 
26
static void     *handleDatagrams(void *parm)
 
27
{
 
28
        /*      Main loop for AOS datagram reception and handling.      */
 
29
 
 
30
        ReceiverThreadParms     *rtp = (ReceiverThreadParms *) parm;
 
31
        char                    *procName = "aoslsi";
 
32
        char                    *buffer;
 
33
        int                     segmentLength;
 
34
        struct sockaddr_in      fromAddr;
 
35
        unsigned int            fromSize;
 
36
 
 
37
        snooze(1);      /*      Let main thread become interruptible.   */
 
38
        buffer = MTAKE(AOSLSA_BUFSZ);
 
39
        if (buffer == NULL)
 
40
        {
 
41
                putErrmsg("aoslsi can't get AOS buffer.", NULL);
 
42
                ionKillMainThread(procName);
 
43
                return NULL;
 
44
        }
 
45
 
 
46
        /*      Can now start receiving bundles.  On failure, take
 
47
         *      down the LSI.                                           */
 
48
 
 
49
        while (rtp->running)
 
50
        {       
 
51
                fromSize = sizeof fromAddr;
 
52
                segmentLength = irecvfrom(rtp->linkSocket, buffer, AOSLSA_BUFSZ,
 
53
                                0, (struct sockaddr *) &fromAddr, &fromSize);
 
54
                switch (segmentLength)
 
55
                {
 
56
                case -1:
 
57
                        putSysErrmsg("Can't acquire segment", NULL);
 
58
                        ionKillMainThread(procName);
 
59
 
 
60
                        /*      Intentional fall-through to next case.  */
 
61
 
 
62
                case 1:                         /*      Normal stop.    */
 
63
                        rtp->running = 0;
 
64
                        continue;
 
65
                }
 
66
 
 
67
                if (ltpHandleInboundSegment(buffer, segmentLength) < 0)
 
68
                {
 
69
                        putErrmsg("Can't handle inbound segment.", NULL);
 
70
                        ionKillMainThread(procName);
 
71
                        rtp->running = 0;
 
72
                        continue;
 
73
                }
 
74
 
 
75
                /*      Make sure other tasks have a chance to run.     */
 
76
 
 
77
                sm_TaskYield();
 
78
        }
 
79
 
 
80
        writeErrmsgMemos();
 
81
        writeMemo("[i] aoslsi receiver thread has ended.");
 
82
 
 
83
        /*      Free resources.                                         */
 
84
 
 
85
        MRELEASE(buffer);
 
86
        return NULL;
 
87
}
 
88
 
 
89
/*      *       *       Main thread functions   *       *       *       */
 
90
 
 
91
#if defined (VXWORKS) || defined (RTEMS)
 
92
int     aoslsi(int a1, int a2, int a3, int a4, int a5,
 
93
                int a6, int a7, int a8, int a9, int a10)
 
94
{
 
95
        char    *endpointSpec = (char *) a1;
 
96
#else
 
97
int     main(int argc, char *argv[])
 
98
{
 
99
        char    *endpointSpec = (argc > 1 ? argv[1] : NULL);
 
100
#endif
 
101
        LtpVdb                  *vdb;
 
102
        unsigned short          portNbr = 0;
 
103
        unsigned int            ipAddress = 0;
 
104
        struct sockaddr         socketName;
 
105
        struct sockaddr_in      *inetName;
 
106
        ReceiverThreadParms     rtp;
 
107
        unsigned int            nameLength;
 
108
        pthread_t               receiverThread;
 
109
        int                     fd;
 
110
        char                    quit = '\0';
 
111
 
 
112
        /*      Note that ltpadmin must be run before the first
 
113
         *      invocation of ltplsi, to initialize the LTP database
 
114
         *      (as necessary) and dynamic database.                    */ 
 
115
 
 
116
        if (ltpInit(0, 0) < 0)
 
117
        {
 
118
                putErrmsg("aoslsi can't initialize LTP.", NULL);
 
119
                return 1;
 
120
        }
 
121
 
 
122
        vdb = getLtpVdb();
 
123
        if (vdb->lsiPid != ERROR && vdb->lsiPid != sm_TaskIdSelf())
 
124
        {
 
125
                putErrmsg("LSI task is already started.", itoa(vdb->lsiPid));
 
126
                return 1;
 
127
        }
 
128
 
 
129
        /*      All command-line arguments are now validated.           */
 
130
 
 
131
        if (endpointSpec)
 
132
        {
 
133
                if(parseSocketSpec(endpointSpec, &portNbr, &ipAddress) != 0)
 
134
                {
 
135
                        putErrmsg("Can't get IP/port for endpointSpec.", endpointSpec);
 
136
                        return -1;
 
137
                }
 
138
        }
 
139
        if (portNbr == 0)
 
140
        {
 
141
                portNbr = LtpAosDefaultPortNbr;
 
142
        }
 
143
        portNbr = htons(portNbr);
 
144
        ipAddress = htonl(ipAddress);
 
145
 
 
146
        memset((char *) &socketName, 0, sizeof socketName);
 
147
        inetName = (struct sockaddr_in *) &socketName;
 
148
        inetName->sin_family = AF_INET;
 
149
        inetName->sin_port = portNbr;
 
150
        memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &ipAddress, 4);
 
151
        rtp.linkSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 
152
        if (rtp.linkSocket < 0)
 
153
        {
 
154
                putSysErrmsg("LSI can't open AOS socket", NULL);
 
155
                return -1;
 
156
        }
 
157
 
 
158
        nameLength = sizeof(struct sockaddr);
 
159
        if (reUseAddress(rtp.linkSocket)
 
160
        || bind(rtp.linkSocket, &socketName, nameLength) < 0
 
161
        || getsockname(rtp.linkSocket, &socketName, &nameLength) < 0)
 
162
        {
 
163
                closesocket(rtp.linkSocket);
 
164
                putSysErrmsg("Can't initialize socket", NULL);
 
165
                return 1;
 
166
        }
 
167
 
 
168
        /*      Set up signal handling; SIGTERM is shutdown signal.     */
 
169
 
 
170
        ionNoteMainThread("aoslsi");
 
171
        isignal(SIGTERM, interruptThread);
 
172
 
 
173
        /*      Start the receiver thread.                              */
 
174
 
 
175
        rtp.running = 1;
 
176
        if (pthread_create(&receiverThread, NULL, handleDatagrams, &rtp))
 
177
        {
 
178
                closesocket(rtp.linkSocket);
 
179
                putSysErrmsg("aoslsi can't create receiver thread", NULL);
 
180
                return 1;
 
181
        }
 
182
 
 
183
        /*      Now sleep until interrupted by SIGTERM, at which point
 
184
         *      it's time to stop the link service.                     */
 
185
 
 
186
        {
 
187
                char    txt[500];
 
188
 
 
189
                isprintf(txt, sizeof(txt),
 
190
                        "[i] aoslsi is running, spec=[%s:%d].", 
 
191
                        inet_ntoa(inetName->sin_addr), ntohs(portNbr));
 
192
                writeMemo(txt);
 
193
        }
 
194
 
 
195
        ionPauseMainThread(-1);
 
196
 
 
197
        /*      Time to shut down.                                      */
 
198
 
 
199
        rtp.running = 0;
 
200
 
 
201
        /*      Wake up the receiver thread by sending it a 1-byte
 
202
         *      datagram.                                               */
 
203
 
 
204
        fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 
205
        if (fd >= 0)
 
206
        {
 
207
                isendto(fd, &quit, 1, 0, &socketName, sizeof(struct sockaddr));
 
208
                closesocket(fd);
 
209
        }
 
210
 
 
211
        pthread_join(receiverThread, NULL);
 
212
        closesocket(rtp.linkSocket);
 
213
        writeErrmsgMemos();
 
214
        writeMemo("[i] aoslsi duct has ended.");
 
215
        ionDetach();
 
216
        return 0;
 
217
}