/* Update the client property BLOB handling policy */ void crackBLOBHandling(const char *dev, const char *name, const char *enableBLOB, ClInfo *cp) { int i=0; /* If we have EnableBLOB with property name, we add it to Client device list */ if (name[0]) addClDevice (cp, dev, name, 1); else /* Otherwise, we set the whole client blob handling to what's passed (enableBLOB) */ crackBLOB(enableBLOB, &cp->blob); /* If whole client blob handling policy was updated, we need to pass that also to all children and if the request was for a specific property, then we apply the policy to it */ for (i = 0; i < cp->nprops; i++) { Property *pp = &cp->props[i]; if (!name[0]) crackBLOB(enableBLOB, &pp->blob); else if (!strcmp (pp->dev, dev) && (!strcmp(pp->name, name))) { crackBLOB(enableBLOB, &pp->blob); return; } } }
/* 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); } }
/* 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); }