示例#1
0
/* put Msg mp on queue of each driver snooping dev/name.
 * if BLOB always honor current mode.
 */
void
q2SDrivers (int isblob, const char *dev, const char *name, Msg *mp, XMLEle *root)
{
	DvrInfo *dp;

	for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) {
            Property *sp = findSDevice (dp, dev, name);

	    /* nothing for dp if not snooping for dev/name or wrong BLOB mode */
	    if (!sp)
		continue;
	    if ((isblob && sp->blob==B_NEVER) || (!isblob && sp->blob==B_ONLY))
		continue;

	    /* ok: queue message to this device */
	    mp->count++;
	    pushFQ (dp->msgq, mp);
	    if (verbose > 1) {
		fprintf (stderr, "%s: Driver %s: queuing snooped <%s device='%s' name='%s'>\n",
				    indi_tstamp(NULL), dp->name, tagXMLEle(root),
				    findXMLAttValu (root, "device"),
				    findXMLAttValu (root, "name"));
	    }
	}
}
示例#2
0
/* put Msg mp on queue of each driver responsible for dev, or all drivers
 * if dev not specified.
 */
void
q2RDrivers (const char *dev, Msg *mp, XMLEle *root)
{
	int sawremote = 0;
	DvrInfo *dp;

	/* queue message to each interested driver.
	 * N.B. don't send generic getProps to more than one remote driver,
	 *   otherwise they all fan out and we get multiple responses back.
	 */
	for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) {
	    int isremote = (dp->pid == REMOTEDVR);
            if (dp->active == 0)
                continue;
        //if (dev[0] && dp->dev[0] && strcmp (dev, dp->dev))
            if (dev[0] && isDeviceInDriver(dev, dp) == 0)
                continue;	/* driver known to not support this dev */
	    if (!dev[0] && isremote && sawremote)
		continue;	/* already sent generic to another remote */
	    if (isremote)
		sawremote = 1;

	    /* ok: queue message to this driver */
	    mp->count++;
	    pushFQ (dp->msgq, mp);
	    if (verbose > 1)
		fprintf (stderr, "%s: Driver %s: queuing responsible for <%s device='%s' name='%s'>\n",
				    indi_tstamp(NULL), dp->name, tagXMLEle(root),
				    findXMLAttValu (root, "device"),
				    findXMLAttValu (root, "name"));
	}
}
示例#3
0
/* start the given remote INDI driver connection.
 * exit if trouble.
 */
void
startRemoteDvr (DvrInfo *dp)
{
	Msg *mp;
	char dev[1024];
	char host[1024];
	char buf[1024];
	int indi_port, sockfd;

	/* extract host and port */
	indi_port = INDIPORT;
	if (sscanf (dp->name, "%[^@]@%[^:]:%d", dev, host, &indi_port) < 2) {
	    fprintf (stderr, "Bad remote device syntax: %s\n", dp->name);
	    Bye();
	}

	/* connect */
	sockfd = openINDIServer (host, indi_port);

	/* record flag pid, io channels, init lp and snoop list */
	dp->pid = REMOTEDVR;
	dp->rfd = sockfd;
	dp->wfd = sockfd;
	dp->lp = newLilXML();
	dp->msgq = newFQ(1);
    dp->sprops = (Property*) malloc (1);	/* seed for realloc */
	dp->nsprops = 0;
	dp->nsent = 0;
    dp->active = 1;
    dp->ndev = 1;
    dp->dev = (char **) malloc(sizeof(char *));

	/* N.B. storing name now is key to limiting outbound traffic to this
	 * dev.
	 */
    dp->dev[0] = (char *) malloc(MAXINDIDEVICE * sizeof(char));
    strncpy (dp->dev[0], dev, MAXINDIDEVICE-1);
    dp->dev[0][MAXINDIDEVICE-1] = '\0';

	/* Sending getProperties with device lets remote server limit its
	 * outbound (and our inbound) traffic on this socket to this device.
	 */
	mp = newMsg();
	pushFQ (dp->msgq, mp);
	sprintf (buf, "<getProperties device='%s' version='%g'/>\n",
             dp->dev[0], INDIV);
	setMsgStr (mp, buf);
	mp->count++;

	if (verbose > 0)
	    fprintf (stderr, "%s: Driver %s: socket=%d\n", indi_tstamp(NULL),
							    dp->name, sockfd);
}
示例#4
0
/* queue the xml command in root from the given device to each
 * interested client, except notme
 */
static void
send2Clients (ClInfo *notme, XMLEle *root, char *dev)
{
	ClInfo *cp;
	Msg *mp;

	/* build a new message */
	mp = (Msg *) mymalloc (sizeof(Msg));
	mp->ep = root;
	mp->count = 0;

	/* lock access to client info */
	pthread_mutex_lock (&client_m);

	/* queue message to each interested client */
	for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) {
	    int isblob;

	    /* cp ok? notme? valid dev? blob? */
	    if (!cp->active || cp == notme)
		continue;
	    if (findClDevice (cp, dev) < 0)
		continue;
	    isblob = !strcmp (tagXMLEle(root), "setBLOBVector");
	    if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY))
		continue;

	    /* ok: queue message to given client */
	    mp->count++;
	    pushFQ (cp->msgq, mp);
	}

	/* wake up client write threads, the last of which will free the Msg */
	if (mp->count > 0)
	    pthread_cond_broadcast(&client_c);
	else {
	    if (verbose > 2)
		fprintf (stderr, "no clients want %s\n", xmlLog(root));
	    freeMsg (mp);	/* no interested clients, free Msg now */
	}

	/* finished with client info */
	pthread_mutex_unlock (&client_m);
}
示例#5
0
/* start the given local INDI driver process.
 * exit if trouble.
 */
void
startLocalDvr (DvrInfo *dp)
{
	Msg *mp;
    char buf[32];
	int rp[2], wp[2], ep[2];
	int pid;

#ifdef OSX_EMBEDED_MODE
  fprintf(stderr, "STARTING \"%s\"\n", dp->name); fflush(stderr);
#endif

	/* build three pipes: r, w and error*/
	if (pipe (rp) < 0) {
	    fprintf (stderr, "%s: read pipe: %s\n", indi_tstamp(NULL),
							    strerror(errno));
	    Bye();
	}
	if (pipe (wp) < 0) {
	    fprintf (stderr, "%s: write pipe: %s\n", indi_tstamp(NULL),
							    strerror(errno));
	    Bye();
	}
	if (pipe (ep) < 0) {
	    fprintf (stderr, "%s: stderr pipe: %s\n", indi_tstamp(NULL),
							    strerror(errno));
	    Bye();
	}

	/* fork&exec new process */
	pid = fork();
	if (pid < 0) {
	    fprintf (stderr, "%s: fork: %s\n", indi_tstamp(NULL), strerror(errno));
	    Bye();
	}
	if (pid == 0) {
	    /* child: exec name */
	    int fd;

	    /* rig up pipes */
	    dup2 (wp[0], 0);	/* driver stdin reads from wp[0] */
	    dup2 (rp[1], 1);	/* driver stdout writes to rp[1] */
	    dup2 (ep[1], 2);	/* driver stderr writes to e[]1] */
	    for (fd = 3; fd < 100; fd++)
		(void) close (fd);

	    if (*dp->envDev)
	      setenv("INDIDEV", dp->envDev, 1);
        /* Only reset environment variable in case of FIFO */
        else if (fifo.fd > 0)
	      unsetenv("INDIDEV");
	    if (*dp->envConfig)
	      setenv("INDICONFIG", dp->envConfig, 1);
        else if (fifo.fd > 0)
	      unsetenv("INDICONFIG");
	    if (*dp->envSkel)
	      setenv("INDISKEL", dp->envSkel, 1);
        else if (fifo.fd > 0)
	      unsetenv("INDISKEL");
	    char executable[MAXSBUF];
        if (*dp->envPrefix)
        {
	      setenv("INDIPREFIX", dp->envPrefix, 1);
#ifdef OSX_EMBEDED_MODE
	      snprintf(executable, MAXSBUF, "%s/Contents/MacOS/%s", dp->envPrefix, dp->name);
#else
        snprintf(executable, MAXSBUF, "%s/bin/%s", dp->envPrefix, dp->name);
#endif
        
        fprintf(stderr, "%s\n", executable);
        
          execlp (executable, dp->name, NULL);
        }
        else
        {
          if (fifo.fd > 0)
            unsetenv("INDIPREFIX");
          execlp (dp->name, dp->name, NULL);
	    }

#ifdef OSX_EMBEDED_MODE
  fprintf(stderr, "FAILED \"%s\"\n", dp->name); fflush(stderr);
#endif
	    fprintf (stderr, "%s: Driver %s: execlp: %s\n", indi_tstamp(NULL),
						dp->name, strerror(errno));
	    _exit (1);	/* parent will notice EOF shortly */
	}

	/* don't need child's side of pipes */
	close (wp[0]);
	close (rp[1]);
	close (ep[1]);

	/* record pid, io channels, init lp and snoop list */
	dp->pid = pid;
	dp->rfd = rp[0];
	dp->wfd = wp[1];
	dp->efd = ep[0];
	dp->lp = newLilXML();
    dp->msgq = newFQ(1);
    dp->sprops = (Property*) malloc (1);	/* seed for realloc */
	dp->nsprops = 0;
	dp->nsent = 0;
    dp->active = 1;
    dp->ndev = 0;
    dp->dev = (char **) malloc(sizeof(char *));

	/* first message primes driver to report its properties -- dev known
	 * if restarting
	 */
    mp = newMsg();
	pushFQ (dp->msgq, mp);
    sprintf (buf, "<getProperties version='%g'/>\n", INDIV);
	setMsgStr (mp, buf);
    mp->count++;

	if (verbose > 0)
	    fprintf (stderr, "%s: Driver %s: pid=%d rfd=%d wfd=%d efd=%d\n",
		    indi_tstamp(NULL), dp->name, dp->pid, dp->rfd, dp->wfd, dp->efd);
}
示例#6
0
/* put Msg mp on queue of each client interested in dev/name, except notme.
 * if BLOB always honor current mode.
 * return -1 if had to shut down any clients, else 0.
 */
int
q2Clients (ClInfo *notme, int isblob, const char *dev, const char *name, Msg *mp, XMLEle *root)
{
	int shutany = 0;
	ClInfo *cp;
    int ql,i=0;

	/* queue message to each interested client */
	for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) {
	    /* cp in use? notme? want this dev/name? blob? */
	    if (!cp->active || cp == notme)
		continue;
            if (findClDevice (cp, dev, name) < 0)
		continue;

            //if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY))
            if (!isblob && cp->blob==B_ONLY)
                continue;

            if (isblob)
            {
                if (cp->nprops > 0)
                {
                Property *pp = NULL;
                int blob_found=0;
                for (i = 0; i < cp->nprops; i++)
                {
                    pp = &cp->props[i];
                    if (!strcmp (pp->dev, dev) && (!strcmp(pp->name, name)))
                    {
                        blob_found = 1;
                        break;
                    }
                }

                if ( (blob_found && pp->blob == B_NEVER) || (blob_found==0 && cp->blob == B_NEVER) )
                    continue;
               }
               else if (cp->blob == B_NEVER)
                   continue;
           }

	    /* shut down this client if its q is already too large */
	    ql = msgQSize(cp->msgq);
	    if (ql > maxqsiz) {
		if (verbose)
		    fprintf (stderr, "%s: Client %d: %d bytes behind, shutting down\n",
						    indi_tstamp(NULL), cp->s, ql);
		shutdownClient (cp);
		shutany++;
		continue;
	    }

	    /* ok: queue message to this client */
	    mp->count++;
	    pushFQ (cp->msgq, mp);
	    if (verbose > 1)
		fprintf (stderr, "%s: Client %d: queuing <%s device='%s' name='%s'>\n",
				    indi_tstamp(NULL), cp->s, tagXMLEle(root),
				    findXMLAttValu (root, "device"),
				    findXMLAttValu (root, "name"));
	}

	return (shutany ? -1 : 0);
}