Ejemplo n.º 1
0
INDI::BaseDevice * INDI::BaseClientQt::findDev (XMLEle * root, int create, char * errmsg)
{
    XMLAtt * ap;
    INDI::BaseDevice * dp;
    char * dn;

    /* get device name */
    ap = findXMLAtt (root, "device");
    if (!ap)
    {
        snprintf(errmsg, MAXRBUF, "No device attribute found in element %s", tagXMLEle(root));
        return (NULL);
    }

    dn = valuXMLAtt(ap);

    if (*dn == '\0')
    {
        snprintf(errmsg, MAXRBUF, "Device name is empty! %s", tagXMLEle(root));
        return (NULL);
    }

    dp = findDev(dn, errmsg);

    if (dp)
        return dp;

    /* not found, create if ok */
    if (create)
        return (addDevice (root, errmsg));

    snprintf(errmsg, MAXRBUF, "INDI: <%s> no such device %s", tagXMLEle(root), dn);
    return NULL;
}
Ejemplo n.º 2
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"));
	    }
	}
}
Ejemplo n.º 3
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"));
	}
}
Ejemplo n.º 4
0
/* read more from the given client, send to each appropriate driver when see
 * xml closure. also send all newXXX() to all other interested clients.
 * shut down client if any trouble.
 */
static void
clientMsg (ClInfo *cp)
{
	char buf[BUFSZ];
	int i, nr;

	/* read client */
	nr = read (cp->s, buf, sizeof(buf));
	if (nr < 0) {
	    fprintf (stderr, "Client %d: %s\n", cp->s, strerror(errno));
	    shutdownClient (cp);
	    return;
	}
	if (nr == 0) {
	    if (verbose)
		fprintf (stderr, "Client %d: read EOF\n", cp->s);
	    shutdownClient (cp);
	    return;
	} 
	if (verbose > 2)
	    fprintf (stderr, "Client %d: read %d:\n%.*s", cp->s, nr, nr, buf);

	/* process XML, sending when find closure */
	for (i = 0; i < nr; i++) {
	    char err[1024];
	    XMLEle *root = readXMLEle (cp->lp, buf[i], err);
	    if (root) {
		char *roottag = tagXMLEle(root);

		if (verbose > 1)
		    fprintf (stderr, "Client %d: read %s\n", cp->s,
		    						xmlLog(root));

		/* record BLOB message locally, others go to matching drivers */
		if (!strcmp (roottag, "enableBLOB")) {
		    cp->blob = crackBLOB (pcdataXMLEle(root));
		    delXMLEle (root);
		} else {
		    char *dev = findXMLAttValu (root, "device");

		    /* snag interested devices */
		    if (!strcmp (roottag, "getProperties"))
			addClDevice (cp, dev);

		    /* send message to driver(s) responsible for dev */
		    send2Drivers (root, dev);

		    /* echo new* commands back to other clients, else done */
		    if (!strncmp (roottag, "new", 3))
			send2Clients (cp, root, dev); /* does delXMLEle */
		    else
			delXMLEle (root);
		}
	    } else if (err[0])
		fprintf (stderr, "Client %d: %s\n", cp->s, err);
	}
}
Ejemplo n.º 5
0
/* return pointer to static string containing tag, device and name attributes
 * of the given xml
 */
static char *
xmlLog (XMLEle *root)
{
	static char buf[256];

	sprintf (buf, "%.*s %.*s %.*s",
			    sizeof(buf)/3-2, tagXMLEle(root),
			    sizeof(buf)/3-2, findXMLAttValu(root,"device"),
			    sizeof(buf)/3-2, findXMLAttValu(root,"name"));
	return (buf);
}
Ejemplo n.º 6
0
/* pull out device and name attributes from root.
 * return 0 if ok else -1 with reason in msg[].
 */
int
crackDN (XMLEle *root, char **dev, char **name, char msg[])
{
        XMLAtt *ap;

        ap = findXMLAtt (root, "device");
        if (!ap) {
            sprintf (msg, "%s requires 'device' attribute", tagXMLEle(root));
            return (-1);
        }
        *dev = valuXMLAtt(ap);

        ap = findXMLAtt (root, "name");
        if (!ap) {
            sprintf (msg, "%s requires 'name' attribute", tagXMLEle(root));
            return (-1);
        }
        *name = valuXMLAtt(ap);

        return (0);
}
Ejemplo n.º 7
0
/* print key attributes and values of the given xml to stderr.
 */
void
traceMsg (XMLEle *root)
{
	static const char *prtags[] = {
	    "defNumber", "oneNumber",
	    "defText",   "oneText",
	    "defSwitch", "oneSwitch",
	    "defLight",  "oneLight",
	};
	XMLEle *e;
	const char *msg, *perm, *pcd;
	unsigned int i;

	/* print tag header */
	fprintf (stderr, "%s %s %s %s", tagXMLEle(root),
						findXMLAttValu(root,"device"),
						findXMLAttValu(root,"name"),
						findXMLAttValu(root,"state"));
	pcd = pcdataXMLEle (root);
	if (pcd[0])
	    fprintf (stderr, " %s", pcd);
	perm = findXMLAttValu(root,"perm");
	if (perm[0])
	    fprintf (stderr, " %s", perm);
	msg = findXMLAttValu(root,"message");
	if (msg[0])
	    fprintf (stderr, " '%s'", msg);

	/* print each array value */
	for (e = nextXMLEle(root,1); e; e = nextXMLEle(root,0))
	    for (i = 0; i < sizeof(prtags)/sizeof(prtags[0]); i++)
		if (strcmp (prtags[i], tagXMLEle(e)) == 0)
		    fprintf (stderr, "\n %10s='%s'", findXMLAttValu(e,"name"),
							    pcdataXMLEle (e));

	fprintf (stderr, "\n");
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
/* read more from the given driver, send to each interested client when see
 * xml closure. if driver dies, try restarting.
 * return 0 if ok else -1 if had to shut down anything.
 */
int
readFromDriver (DvrInfo *dp)
{
	char buf[MAXRBUF];
	int shutany = 0;
	ssize_t i, nr;

	/* read driver */
	nr = read (dp->rfd, buf, sizeof(buf));
	if (nr <= 0) {
	    if (nr < 0)
		fprintf (stderr, "%s: Driver %s: stdin %s\n", indi_tstamp(NULL),
						    dp->name, strerror(errno));
	    else
		fprintf (stderr, "%s: Driver %s: stdin EOF\n",
							indi_tstamp(NULL), dp->name);
            shutdownDvr (dp, 1);
	    return (-1);
	}

	/* process XML, sending when find closure */
    for (i = 0; i < nr; i++)
    {
	    char err[1024];
	    XMLEle *root = readXMLEle (dp->lp, buf[i], err);
        if (root)
        {
		char *roottag = tagXMLEle(root);
		const char *dev = findXMLAttValu (root, "device");
		const char *name = findXMLAttValu (root, "name");
		int isblob = !strcmp (tagXMLEle(root), "setBLOBVector");
		Msg *mp;

        if (verbose > 2)
        {
		    fprintf(stderr, "%s: Driver %s: read ", indi_tstamp(0),dp->name);
		    traceMsg (root);
		} else if (verbose > 1) {
		    fprintf (stderr, "%s: Driver %s: read <%s device='%s' name='%s'>\n",
				    indi_tstamp(NULL), dp->name, tagXMLEle(root),
				    findXMLAttValu (root, "device"),
				    findXMLAttValu (root, "name"));
		}

		/* that's all if driver is just registering a snoop */
        if (!strcmp (roottag, "getProperties"))
        {
		    addSDevice (dp, dev, name);
		    delXMLEle (root);
		    continue;
		}

		/* that's all if driver is just registering a BLOB mode */
        if (!strcmp (roottag, "enableBLOB"))
        {
                    Property *sp = findSDevice (dp, dev, name);
		    if (sp)
			crackBLOB (pcdataXMLEle (root), &sp->blob);
		    delXMLEle (root);
		    continue;
		}

        /* Found a new device? Let's add it to driver info */
        if (dev[0] && isDeviceInDriver(dev, dp) == 0)
        {
            dp->dev = (char **) realloc(dp->dev, (dp->ndev+1) * sizeof(char *));
            dp->dev[dp->ndev] = (char *) malloc(MAXINDIDEVICE * sizeof(char));

            strncpy (dp->dev[dp->ndev], dev, MAXINDIDEVICE-1);
            dp->dev[dp->ndev][MAXINDIDEVICE-1] = '\0';

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

            dp->ndev++;
        }

		/* log messages if any and wanted */
		if (ldir)
		    logDMsg (root, dev);

		/* build a new message -- set content iff anyone cares */
		mp = newMsg();

		/* send to interested clients */
         if (q2Clients (NULL, isblob, dev, name, mp, root) < 0)
            shutany++;

		/* send to snooping drivers */
        q2SDrivers (isblob, dev, name, mp, root);

		/* set message content if anyone cares else forget it */
		if (mp->count > 0)
		    setMsgXMLEle (mp, root);
		else
		    freeMsg (mp);
		delXMLEle (root);

	    } else if (err[0]) {
		char *ts = indi_tstamp(NULL);
		fprintf (stderr, "%s: Driver %s: XML error: %s\n", ts,
								dp->name, err);
		fprintf (stderr, "%s: Driver %s: XML read: %.*s\n", ts,
							    dp->name, (int)nr, buf);
                shutdownDvr (dp, 1);
		return (-1);
	    }
	}

	return (shutany ? -1 : 0);
}
Ejemplo n.º 10
0
/* read more from the given client, send to each appropriate driver when see
 * xml closure. also send all newXXX() to all other interested clients.
 * return -1 if had to shut down anything, else 0.
 */
int
readFromClient (ClInfo *cp)
{
	char buf[MAXRBUF];
	int shutany = 0;
	ssize_t i, nr;

	/* read client */
	nr = read (cp->s, buf, sizeof(buf));
	if (nr <= 0) {
	    if (nr < 0)
		fprintf (stderr, "%s: Client %d: read: %s\n", indi_tstamp(NULL),
							cp->s, strerror(errno));
	    else if (verbose > 0)
		fprintf (stderr, "%s: Client %d: read EOF\n", indi_tstamp(NULL),
									cp->s);
	    shutdownClient (cp);
	    return (-1);
	}

	/* process XML, sending when find closure */
	for (i = 0; i < nr; i++) {
	    char err[1024];
	    XMLEle *root = readXMLEle (cp->lp, buf[i], err);
	    if (root) {
		char *roottag = tagXMLEle(root);
		const char *dev = findXMLAttValu (root, "device");
		const char *name = findXMLAttValu (root, "name");
		int isblob = !strcmp (tagXMLEle(root), "setBLOBVector");
		Msg *mp;

		if (verbose > 2) {
		    fprintf (stderr, "%s: Client %d: read ",indi_tstamp(NULL),cp->s);
		    traceMsg (root);
		} else if (verbose > 1) {
		    fprintf (stderr, "%s: Client %d: read <%s device='%s' name='%s'>\n",
				    indi_tstamp(NULL), cp->s, tagXMLEle(root),
				    findXMLAttValu (root, "device"),
				    findXMLAttValu (root, "name"));
		}

		/* snag interested properties.
		 * N.B. don't open to alldevs if seen specific dev already, else
		 *   remote client connections start returning too much.
		 */
		if (dev[0])
                    addClDevice (cp, dev, name, isblob);
		else if (!strcmp (roottag, "getProperties") && !cp->nprops)
		    cp->allprops = 1;

		/* snag enableBLOB -- send to remote drivers too */
		if (!strcmp (roottag, "enableBLOB"))
                   // crackBLOB (pcdataXMLEle(root), &cp->blob);
                     crackBLOBHandling (dev, name, pcdataXMLEle(root), cp);

		/* build a new message -- set content iff anyone cares */
		mp = newMsg();

		/* send message to driver(s) responsible for dev */
		q2RDrivers (dev, mp, root);

		/* echo new* commands back to other clients */
		if (!strncmp (roottag, "new", 3)) {
                    if (q2Clients (cp, isblob, dev, name, mp, root) < 0)
			shutany++;
		}

		/* set message content if anyone cares else forget it */
		if (mp->count > 0)
		    setMsgXMLEle (mp, root);
		else
		    freeMsg (mp);
		delXMLEle (root);

	    } else if (err[0]) {
		char *ts = indi_tstamp(NULL);
		fprintf (stderr, "%s: Client %d: XML error: %s\n", ts,
								cp->s, err);
		fprintf (stderr, "%s: Client %d: XML read: %.*s\n", ts,
							    cp->s, (int)nr, buf);
		shutdownClient (cp);
		return (-1);
	    }
	}

	return (shutany ? -1 : 0);
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
/* pull apart the name and value from the given message, and set operand value.
 * ignore any other messages.
 * return 0 if found a recognized operand else -1
 */
static int
setOp (XMLEle *root)
{
	char *t = tagXMLEle (root);
        const char *d = findXMLAttValu (root, "device");
        const char *n = findXMLAttValu (root, "name");
	int nset = 0;
	double v;
	char prop[1024];
	XMLEle *ep;

	/* check values */
	if (!strcmp (t,"defNumberVector") || !strcmp (t,"setNumberVector")) {
	    for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {
		char *et = tagXMLEle(ep);
		if (!strcmp (et,"defNumber") || !strcmp (et,"oneNumber")) {
		    sprintf (prop, "%s.%s.%s", d, n, findXMLAttValu(ep,"name"));
		    v = atof(pcdataXMLEle(ep));
		    if (setOperand (prop, v) == 0) {
			nset++;
			if (oflag)
			    fprintf (stderr, "%s=%g\n", prop, v);
		    }
		}
	    }
	} else if(!strcmp(t,"defSwitchVector") || !strcmp(t,"setSwitchVector")){
	    for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {
		char *et = tagXMLEle(ep);
		if (!strcmp (et,"defSwitch") || !strcmp (et,"oneSwitch")) {
		    sprintf (prop, "%s.%s.%s", d, n, findXMLAttValu(ep,"name"));
		    v = (double)!strcmp(pcdataXMLEle(ep),"On");
		    if (setOperand (prop, v) == 0) {
			nset++;
			if (oflag)
			    fprintf (stderr, "%s=%g\n", prop, v);
		    }
		}
	    }
	} else if(!strcmp(t,"defLightVector") || !strcmp(t,"setLightVector")){
	    for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) {
		char *et = tagXMLEle(ep);
		if (!strcmp (et,"defLight") || !strcmp (et,"oneLight")) {
		    sprintf (prop, "%s.%s.%s", d, n, findXMLAttValu(ep,"name"));
		    v = (double)pstatestr(pcdataXMLEle(ep));
		    if (setOperand (prop, v) == 0) {
			nset++;
			if (oflag)
			    fprintf (stderr, "%s=%g\n", prop, v);
		    }
		}
	    }
	}

	/* check special elements */
        t = (char *) findXMLAttValu (root, "state");
	if (t[0]) {
	    sprintf (prop, "%s.%s._STATE", d, n);
	    v = (double)pstatestr(t);
	    if (setOperand (prop, v) == 0) {
		nset++;
		if (oflag)
		    fprintf (stderr, "%s=%g\n", prop, v);
	    }
	}
        t = (char *) findXMLAttValu (root, "timestamp");
	if (t[0]) {
	    sprintf (prop, "%s.%s._TS", d, n);
	    v = (double)timestamp(t);
	    if (setOperand (prop, v) == 0) {
		nset++;
		if (oflag)
		    fprintf (stderr, "%s=%g\n", prop, v);
	    }
	}

	/* return whether any were set */
	return (nset > 0 ? 0 : -1);
}
Ejemplo n.º 13
0
int INDI::BaseClientQt::dispatchCommand(XMLEle * root, char * errmsg)
{
    if  (!strcmp (tagXMLEle(root), "message"))
        return messageCmd(root, errmsg);
    else if  (!strcmp (tagXMLEle(root), "delProperty"))
        return delPropertyCmd(root, errmsg);
    // Just ignore any getProperties we might get
    else if  (!strcmp (tagXMLEle(root), "getProperties"))
        return INDI_PROPERTY_DUPLICATED;

    /* Get the device, if not available, create it */
    INDI::BaseDevice * dp = findDev (root, 1, errmsg);
    if (dp == NULL)
    {
        strcpy(errmsg,"No device available and none was created");
        return INDI_DEVICE_NOT_FOUND;
    }

    // FIXME REMOVE THIS

    // Ignore echoed newXXX and getProperties
    if (strstr(tagXMLEle(root), "new") ||strstr(tagXMLEle(root), "getProperties"))
        return 0;

    if ((!strcmp (tagXMLEle(root), "defTextVector"))  ||
            (!strcmp (tagXMLEle(root), "defNumberVector")) ||
            (!strcmp (tagXMLEle(root), "defSwitchVector")) ||
            (!strcmp (tagXMLEle(root), "defLightVector"))  ||
            (!strcmp (tagXMLEle(root), "defBLOBVector")))
        return dp->buildProp(root, errmsg);
    else if (!strcmp (tagXMLEle(root), "setTextVector") ||
             !strcmp (tagXMLEle(root), "setNumberVector") ||
             !strcmp (tagXMLEle(root), "setSwitchVector") ||
             !strcmp (tagXMLEle(root), "setLightVector") ||
             !strcmp (tagXMLEle(root), "setBLOBVector"))
        return dp->setValue(root, errmsg);

    return INDI_DISPATCH_ERROR;
}