[Kstars-devel] KDE/kdeedu/kstars/kstars/indi

Jasem Mutlaq mutlaqja at ikarustech.com
Sun Sep 24 18:50:57 CEST 2006


SVN commit 588011 by mutlaqja:

Adding the INDI observer pattern which would allow inter-driver
communication when required. This feature is needed when controlling
multiple devices in observatories, where drivers may watch the state and
value changes of other properties they're interested in to perform their
operation.

The classical example of this problem is the Rain Collector and Roof Top
(Dome)
drivers. The roof top needs to know from the rain collector driver if
it's raining or not so it can make decisions on opening or closing the
roof top. Therefore, such decisions can be made without an operator
present.

CCMAIL: kstars-devel at kde.org



 M  +2 -2      CMakeLists.txt  
 M  +35 -2     indiserver.c  
 M  +91 -98    observer.c  
 M  +0 -4      observer.h  
 M  +5 -1      sbigudrv.h  


--- trunk/KDE/kdeedu/kstars/kstars/indi/CMakeLists.txt #588010:588011
@@ -170,9 +170,9 @@
 
 ########### next target ###############
 ########### INDI Server ##############
-set(indiserver_SRCS indiserver.c fq.c )
+set(indiserver_SRCS indiserver.c fq.c)
 
-kde4_add_executable(indiserver ${indiserver_SRCS}  ${liblilxml_SRCS} ${libindicom_SRCS})
+kde4_add_executable(indiserver ${indiserver_SRCS}  ${liblilxml_SRCS})
 
 target_link_libraries(indiserver  ${KDE4_KDECORE_LIBS} pthread )
 
--- trunk/KDE/kdeedu/kstars/kstars/indi/indiserver.c #588010:588011
@@ -839,6 +839,10 @@
 	    mp->count = 0;
 	}
 
+	/* Ignore subscribtion requests, don't send them to clients */
+	if (!strcmp(tagXMLEle(root), "propertyVectorSubscribtion"))
+		return NULL;
+	
 	/* queue message to each interested client */
 	for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) {
 	    int isblob;
@@ -898,6 +902,9 @@
 		manageObservers(sender, root);
 		return NULL;
 	}
+	/* We discard messages */
+       else if (!strcmp(tagXMLEle(root), "message"))
+		return NULL;
 
 	/* We have no observers, return */
 	if (nobserverinfo_active == 0)
@@ -1109,13 +1116,14 @@
 	/* build a new message */
 	mp = (Msg *) malloc (sizeof(Msg));
 	mp->ep = xmlAlert;
-	mp->count = 1;
+	mp->count = 0;
 	
 	/* Check if any observers are listening to this driver */
 	for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++)
 	{
-		if (ob->dp == dp)
+		if (!strcmp(ob->dev,dp->dev))
 		{
+			mp->count++;
 			pushFQ (ob->dp->msgq, mp);
 			if (verbose > 2)
 				fprintf (stderr,"Driver %s: message %d queued with count %d\n",
@@ -1321,3 +1329,28 @@
 	fprintf (stderr, "\n");
 }
 
+int crackObserverState(char *stateStr)
+{
+	if (!strcmp(stateStr, "Value"))
+		return (IDT_VALUE);
+	else if (!strcmp(stateStr, "State"))
+		return (IDT_STATE);
+	else if (!strcmp(stateStr, "All"))
+		return (IDT_ALL);
+	
+	else return -1;
+}
+
+int crackPropertyState(char *pstateStr)
+{
+	if (!strcmp(pstateStr, "Idle"))
+		return IPS_IDLE;
+	else if (!strcmp(pstateStr, "Ok"))
+		return IPS_OK;
+	else if (!strcmp(pstateStr, "Busy"))
+		return IPS_BUSY;
+	else if (!strcmp(pstateStr, "Alert"))
+		return IPS_ALERT;
+	else return -1;
+}
+
--- trunk/KDE/kdeedu/kstars/kstars/indi/observer.c #588010:588011
@@ -34,18 +34,6 @@
     int in_use;
     char dev[MAXINDIDEVICE];
     char name[MAXINDINAME];
-    IDType type;
-    CBSP *fp;
-} SP;
-
-static SP *sp_sub;			/* malloced list of work procedures */
-static int nsp_sub;			/* n entries in wproc[] */
-
-typedef struct 
-{
-    int in_use;
-    char dev[MAXINDIDEVICE];
-    char name[MAXINDINAME];
     IPType property_type;
     IDType notification_type;
     fpt fp;
@@ -54,58 +42,6 @@
 static OBP *oblist;			/* malloced list of work procedures */
 static int noblist;			/* n entries in wproc[] */
 
-void IOSubscribeSwitch(const char *dev, const char *name, IDType type, CBSP *fp)
-{
-        SP *sp;
-
-	/* reuse first unused slot or grow */
-	for (sp = sp_sub; sp < &sp_sub[nsp_sub]; sp++)
-	    if (!sp->in_use)
-		break;
-	if (sp == &sp_sub[nsp_sub])
-       {
-	    sp_sub = sp_sub ? (SP *) realloc (sp_sub, (nsp_sub+1)*sizeof(SP))
-	    		  : (SP *) malloc (sizeof(SP));
-	    sp = &sp_sub[nsp_sub++];
-	}
-
-	/* init new entry */
-	sp->in_use = 1;
-	sp->fp = fp;
-        sp->type = type;
-	strncpy(sp->dev, dev, MAXINDIDEVICE);
-	strncpy(sp->name, name, MAXINDINAME);
-	
-
-	printf ("<propertyVectorSubscribtion\n");
-	printf ("  device='%s'\n", dev);
-	printf ("  name='%s'\n", name);
-	printf ("  action='subscribe'\n");
-	printf ("  notification='%s'\n", idtypeStr(type));
-	printf ("</propertyVectorSubscribtion>\n");
-	fflush (stdout);
-
-}
-
-void IOUnsubscribeSwitch(const char *dev, const char *name)
-{
-   SP *sp;
-	
-    for (sp = sp_sub; sp < &sp_sub[nsp_sub]; sp++)
-   {
-       if (!strcmp(sp->dev, dev) && !strcmp(sp->name, name))
-	{
-		sp->in_use = 0;
-		printf ("<propertyVectorSubscribtion\n");
-		printf ("  device='%s'\n", dev);
-		printf ("  name='%s'\n", name);
-		printf ("  action='unsubscribe'\n");
-		printf ("</propertyVectorSubscribtion>\n");
-		fflush (stdout);
-	}
-   }
-}
-
 void IOSubscribeProperty(const char *dev, const char *name, IPType property_type, IDType notification_type, fpt fp)
 {
 
@@ -129,7 +65,6 @@
         obp->notification_type	= notification_type;
 	strncpy(obp->dev, dev, MAXINDIDEVICE);
 	strncpy(obp->name, name, MAXINDINAME);
-	
 
 	printf ("<propertyVectorSubscribtion\n");
 	printf ("  device='%s'\n", dev);
@@ -145,7 +80,7 @@
     OBP *obp;
 	
     for (obp = oblist; obp < &oblist[noblist]; obp++)
-   {
+    {
        if (!strcmp(obp->dev, dev) && !strcmp(obp->name, name))
 	{
 		obp->in_use = 0;
@@ -155,7 +90,7 @@
 		printf ("  action='unsubscribe' />\n");
 		fflush (stdout);
 	}
-   }
+    }
 
 }
 
@@ -188,7 +123,8 @@
         IDState state;
 	char prop_dev[MAXINDIDEVICE];
 	char prop_name[MAXINDINAME];
-	   
+	XMLEle *epx;
+	int n;
 
 	/* Driver sent which message? */
 	if (strstr(tagXMLEle(root), "def"))
@@ -197,6 +133,9 @@
 		state = IDS_UPDATED;
 	else if (strstr(tagXMLEle(root), "del"))
 		state = IDS_DELETED;
+	/* So far the only alert is when the driver dies, so the xml tag should suffice for now */
+	else if (!strcmp(tagXMLEle(root), "subscribtionAlert"))
+		state = IDS_DIED;
 	else
 	{
 		/* Silently ignore */
@@ -212,9 +151,9 @@
 	else
 		strncpy(prop_dev, valuXMLAtt(ap), MAXINDIDEVICE);
 	
-	/* Del prop might not have name, so don't panic */
+	/* Del/Die prop might not have name, so don't panic */
 	ap = findXMLAtt(root, "name");
-	if (!ap && state != IDS_DELETED)
+	if (!ap && (state == IDS_DEFINED || state == IDS_UPDATED))
 	{
 		fprintf(stderr, "<%s> missing 'name' attribute.\n", tagXMLEle(root));
 		exit(1);
@@ -223,31 +162,36 @@
 		strncpy(prop_name, valuXMLAtt(ap), MAXINDINAME);
 
 
-    for (obp = oblist; obp < &oblist[noblist]; obp++)
-   {
-	/* We got a match */
-	if (!strcmp(obp->dev, prop_dev) && ((state == IDS_DELETED) || (!strcmp(obp->name, prop_name))))
+	if (state == IDS_DELETED || state == IDS_DIED)
 	{
-	XMLEle *epx;
-	int n;
-
-	if (state == IDS_DELETED)
-	{
-		switch (obp->property_type)
+		for (obp = oblist; obp < &oblist[noblist]; obp++)
 		{
-			case IPT_SWITCH:
-			case IPT_TEXT:
-			case IPT_NUMBER:
-			case IPT_LIGHT:
-				obp->fp(obp->dev, obp->name, IDS_DELETED, NULL, NULL, 0);
-				break;
-			case IPT_BLOB:
-				obp->fp(obp->dev, obp->name, IDS_DELETED, NULL, NULL, NULL, NULL, 0);
-				break;
+			/* We got a match */
+			if (!strcmp(obp->dev, prop_dev))
+			{
+				switch (obp->property_type)
+				{
+					case IPT_SWITCH:
+					case IPT_TEXT:
+					case IPT_NUMBER:
+					case IPT_LIGHT:
+						obp->fp(obp->dev, obp->name, state, NULL, NULL, 0);
+						break;
+					case IPT_BLOB:
+						obp->fp(obp->dev, obp->name, state, NULL, NULL, NULL, NULL, 0);
+						break;
+				}
+			}
 		}
-		continue;
+		
+		return (0);
 	}
-
+	
+	for (obp = oblist; obp < &oblist[noblist]; obp++)
+	{
+	
+	if (!strcmp(obp->dev, prop_dev) && !strcmp(obp->name, prop_name))
+	{
 	/* check tag in surmised decreasing order of likelyhood */
 	if (!strcmp (tagXMLEle(root), "setNumberVector") || !strcmp (tagXMLEle(root), "defNumberVector"))
 	{
@@ -263,7 +207,7 @@
 
 	    /* pull out each name/value pair */
 	    for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) {
-		if (strcmp (tagXMLEle(epx), "oneNumber") == 0) {
+		  if (strstr(tagXMLEle(epx), "Number")) {
 		    XMLAtt *na = findXMLAtt (epx, "name");
 		    if (na) {
 			if (n >= maxn) {
@@ -283,7 +227,9 @@
 	    
 	    /* invoke driver if something to do, but not an error if not */
 	    if (n > 0)
+	    {
 		obp->fp(obp->dev, obp->name, state, doubles, names, n);
+	    }
 	    else
 		IDLog("%s: NumberVector with no valid members", obp->name);
 
@@ -303,7 +249,7 @@
 
 	    /* pull out each name/state pair */
 	    for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) {
-		if (strcmp (tagXMLEle(epx), "oneSwitch") == 0) {
+		    if (strstr(tagXMLEle(epx), "Switch")) {
 		    XMLAtt *na = findXMLAtt (epx, "name");
 		    if (na) {
 			if (n >= maxn) {
@@ -321,7 +267,10 @@
 			    names[n] = valuXMLAtt(na);
 			    n++;
 			} else 
+			{
 			    IDLog ("%s: must be On or Off: %s\n",  obp->name,    pcdataXMLEle(epx));
+			    exit(1);
+			}
 		    }
 		}
 	    }
@@ -348,7 +297,7 @@
 
 	    /* pull out each name/text pair */
 	    for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) {
-		if (strcmp (tagXMLEle(epx), "oneText") == 0) {
+		if (strstr(tagXMLEle(epx), "Text")) {
 		    XMLAtt *na = findXMLAtt (epx, "name");
 		    if (na) {
 			if (n >= maxn) {
@@ -389,7 +338,7 @@
 
 	    /* pull out each name/BLOB pair */
 	    for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) {
-		if (strcmp (tagXMLEle(epx), "oneBLOB") == 0) {
+		if (strstr(tagXMLEle(epx), "BLOB")) {
 		    XMLAtt *na = findXMLAtt (epx, "name");
 		    XMLAtt *fa = findXMLAtt (epx, "format");
 		    XMLAtt *sa = findXMLAtt (epx, "size");
@@ -419,15 +368,59 @@
 
 	    return (0);
 	}
-	else return (-1);
+	
+	if (!strcmp (tagXMLEle(root), "setLightVector") || !strcmp (tagXMLEle(root), "defLightVector")) {
+		static IPState *states;
+		static char **names;
+		static int maxn;
 
-	/* FIXME TODO need to fetch LIGHT!!! */
+		/* seed for reallocs */
+		if (!states) {
+			states = (IPState *) malloc (sizeof(void*));
+			names = (char **) malloc (sizeof(void*));
+		}
 
+		/* pull out each name/state pair */
+		for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) {
+			if (strstr(tagXMLEle(epx), "Light")) {
+				XMLAtt *na = findXMLAtt (epx, "name");
+				if (na) {
+					if (n >= maxn) {
+						int newsz = (maxn=n+1)*sizeof(IPState);
+						states = (IPState *) realloc(states, newsz);
+						newsz = maxn*sizeof(char *);
+						names = (char **) realloc (names, newsz);
+					}
+					if (crackPropertyState(pcdataXMLEle(epx)) != -1) {
+						states[n] = crackPropertyState(pcdataXMLEle(epx));
+						names[n] = valuXMLAtt(na);
+						n++;
+					} 
+					} else 
+					{
+						IDLog ("%s: invalid state: %s\n",  obp->name, pcdataXMLEle(epx));
+						exit(1);
+					}
+				}
+			}
+
+		/* invoke driver if something to do, but not an error if not */
+		if (n > 0)
+			obp->fp(obp->dev, obp->name, state, states, names, n);
+		else
+			IDLog("%s: LightVector with no valid members", obp->name);
+
+		return (0);
+	}
+	
+	return (-1);
+
+
 	} /* End if */
 
    } /* End For */
 
-  return (0);
+  return (-1);
 	
 }
 
--- trunk/KDE/kdeedu/kstars/kstars/indi/observer.h #588010:588011
@@ -56,14 +56,10 @@
 extern "C" {
 #endif
 
-void IOSubscribeSwitch(const char *dev, const char *name, IDType data_type, CBSP *fp);
-void IOUnsubscribeSwitch(const char *dev, const char *name);
-
 void IOSubscribeProperty(const char *dev, const char *name, IPType property_type, IDType notification_type, fpt fp);
 void IOUnsubscribeProperty(const char *dev, const char *name);
 
 int processObservers(XMLEle *root);
-
 const char * idtypeStr(IDType type);
 int crackObserverState(char *stateStr);
 int crackPropertyState(char *pstateStr);
--- trunk/KDE/kdeedu/kstars/kstars/indi/sbigudrv.h #588010:588011
@@ -25,9 +25,13 @@
 #define _PARDRV_
 
 /* needed for KDE_EXPORT macros */
+/* DO NOT EDIT OR REMOVE THIS */
+#ifndef HAVE_CONFIG_H
 #include <kdemacros.h>
+#else
+#define KDE_EXPORT
+#endif
 
-
 /*
 
 	SBIG Specific Code


More information about the Kstars-devel mailing list