3 Copyright (C) 2003-2006 Elwood C. Downey
5 Updated by Jasem Mutlaq (2003-2010)
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT
ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
46 #include <sys/types.h>
52 static void usage(
void);
53 static void deferMessage(
XMLEle * root);
54 static void handlePingReply(
XMLEle * root);
56 static LilXML *clixml = NULL;
58 #define PROCEED_IMMEDIATE 1
59 #define PROCEED_DEFERRED 0
68 static void clientMsgCB(
int fd,
void *arg)
79 nr = read(
fd, buf,
sizeof(buf));
86 fprintf(stderr,
"%s: %s\n",
me, strerror(
errno));
91 fprintf(stderr,
"%s: EOF\n",
me);
96 for (bp = buf; nr-- > 0; bp++)
101 if (strcmp(
tagXMLEle(root),
"pingReply") == 0)
103 handlePingReply(root);
110 fprintf(stderr,
"%s XML error: %s\n",
me, msg);
125 static void flushDeferredMessages(
void * arg)
132 while((p = firstDeferredMessage))
134 firstDeferredMessage = p->
next;
135 if (firstDeferredMessage)
137 firstDeferredMessage->
prev = NULL;
141 lastDeferredMessage = NULL;
145 fprintf(stderr,
"%s dispatch error: %s\n",
me, msg);
154 if (firstDeferredMessage == NULL)
161 newDeferredMessage->
next = NULL;
162 newDeferredMessage->
prev = lastDeferredMessage;
163 if (lastDeferredMessage == NULL)
165 firstDeferredMessage = newDeferredMessage;
169 lastDeferredMessage->
next = newDeferredMessage;
171 lastDeferredMessage = newDeferredMessage;
174 #define MAX_PING_UID_LEN 64
183 static pthread_t eventLoopThread;
184 static PingReply * firstReceivedPing = NULL;
185 static PingReply * lastReceivedPing = NULL;
186 static pthread_mutex_t pingReplyMutex = PTHREAD_MUTEX_INITIALIZER;
187 static pthread_cond_t pingReplyCond = PTHREAD_COND_INITIALIZER;
189 static void handlePingReply(
XMLEle * root)
204 pthread_mutex_lock(&pingReplyMutex);
207 pr->
prev = lastReceivedPing;
208 if (lastReceivedPing) {
209 lastReceivedPing->
next = pr;
211 firstReceivedPing = pr;
213 lastReceivedPing = pr;
214 pthread_cond_broadcast(&pingReplyCond);
215 pthread_mutex_unlock(&pingReplyMutex);
219 static int consumePingReply(
const char *
uid) {
222 if (!strcmp(cur->
uid,
uid)) {
227 firstReceivedPing = cur->
next;
232 lastReceivedPing = cur->
prev;
244 static void waitPingReplyFromEventLoopThread(
const char *
uid) {
245 pthread_mutex_lock(&pingReplyMutex);
246 while(!consumePingReply(
uid)) {
247 pthread_cond_wait(&pingReplyCond, &pingReplyMutex);
249 pthread_mutex_unlock(&pingReplyMutex);
252 static void waitPingReplyFromOtherThread(
const char *
uid) {
257 pthread_mutex_lock(&pingReplyMutex);
258 while(!consumePingReply(
uid))
261 pthread_mutex_unlock(&pingReplyMutex);
266 int ns = select(
fd + 1, &rfd, NULL, NULL, NULL);
273 clientMsgCB(0, NULL);
275 pthread_mutex_lock(&pingReplyMutex);
277 pthread_mutex_unlock(&pingReplyMutex);
284 pthread_t currentThread = pthread_self();
285 if (!pthread_equal(currentThread, eventLoopThread)) {
286 waitPingReplyFromOtherThread(
uid);
288 waitPingReplyFromEventLoopThread(
uid);
297 if ( (ret = setgid(getgid())) != 0)
298 IDLog(
"setgid: %s", strerror(ret));
300 if ( (ret = setuid(getuid())) != 0)
301 IDLog(
"getuid: %s", strerror(ret));
303 if (geteuid() != getuid())
307 eventLoopThread = pthread_self();
311 for (
me = av[0]; av[0][0]; av[0]++)
316 while (--ac && (*++av)[0] ==
'-')
339 fprintf(stderr,
"%s: inf loop ended\n",
me);
344 static void usage(
void)
346 fprintf(stderr,
"Usage: %s [options]\n", me);
347 fprintf(stderr,
"Purpose: INDI Device driver framework.\n");
348 fprintf(stderr,
"Options:\n");
349 fprintf(stderr,
" -v : more verbose to stderr\n");
void eventLoop()
Main calls this when ready to hand over control.
void addImmediateWork(TCF *fp, void *ud)
int addCallback(int fd, CBF *fp, void *ud)
Public interface to INDI's eventloop mechanism.
void IDLog(const char *fmt,...)
Interface to the reference INDI C API device implementation on the Device Driver side.
int dispatch(XMLEle *root, char msg[])
struct PingReply PingReply
void waitPingReply(const char *uid)
struct DeferredMessage DeferredMessage
#define PROCEED_IMMEDIATE
int main(int ac, char *av[])
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
LilXML * newLilXML()
Create a new lilxml parser.
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
XMLEle * readXMLEle(LilXML *lp, int newc, char ynot[])
Process an XML one char at a time.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
char * valuXMLAtt(XMLAtt *ap)
Return the value of an XML attribute.
A little DOM-style library to handle parsing and processing an XML file.
Namespace to encapsulate INDI client, drivers, and mediator classes.
struct DeferredMessage * next
struct DeferredMessage * prev
char uid[MAX_PING_UID_LEN+1]