Index: /BAORadio/libindi/libindi/BAOControl/Makefile
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/Makefile	(revision 641)
+++ /BAORadio/libindi/libindi/BAOControl/Makefile	(revision 642)
@@ -1,3 +1,3 @@
-# Makefile for the socket programming example
+# Makefile 
 #
 
@@ -7,6 +7,5 @@
 CXXFLAGS = -g 
 
-BAOcontrol_objects =  main.o baocontrol.o ClientSocket.o Socket.o filetools.o exception.o
-
+BAOcontrol_objects =  main.o baocontrol.o
 
 all : BAOcontrol
@@ -14,12 +13,14 @@
 
 BAOcontrol: $(BAOcontrol_objects)
-	g++ $(CXXFLAGS) -c -o ../BAOControl/astro.o ../drivers/telescope/astro.cpp
-	g++ $(CXXFLAGS) -o BAOcontrol $(BAOcontrol_objects) astro.o -lpthread -lX11
+	g++ $(CXXFLAGS) -c -o ../BAOControl/astro.o ../communs/astro.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOControl/exception.o ../communs/exception.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOControl/filetools.o ../communs/filetools.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOControl/Socket.o ../communs/Socket.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOControl/ClientSocket.o ../communs/ClientSocket.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOControl/logs.o ../communs/logs.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOControl/alignement.o ../communs/alignement.cpp
+	g++ $(CXXFLAGS) -o BAOcontrol $(BAOcontrol_objects) astro.o exception.o filetools.o Socket.o ClientSocket.o logs.o alignement.o -lpthread -lX11
 
-Socket:  Socket.cpp
-ClientSocket: ClientSocket.cpp
 baocontrol: baocontrol.cpp
-filetools: filetools.cpp
-exception: exception.c
 main: main.cpp
 
Index: /BAORadio/libindi/libindi/BAOControl/baocontrol.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/baocontrol.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/BAOControl/baocontrol.cpp	(revision 642)
@@ -4,16 +4,16 @@
 /* Franck RICHARD             */
 /* franckrichard033@gmail.com */
-/* DÃ©cembre 2011              */
+/* FÃ©vrier 2012               */
 /******************************/
 
 
 #include "baocontrol.h"
-#include <termios.h>
-#include <unistd.h>
+
 
 
 
 /**************************************************************************************
-**Constructeur
+** Constructeur de la classe BAOcontrol
+**
 ***************************************************************************************/
 
@@ -23,74 +23,100 @@
 
     // Le choix de la couleur des caractÃšres est adaptÃ© pour une fenÃªtre de terminal
-    // ayant un fond blanc. pour un fond noir, mettre couleurs=2 dans le fichier params
+    // ayant un fond blanc. pour un fond noir, mettre couleurs = 2 dans le fichier params
 
     ChoixCouleurs=1;
 
-
-    Affiche("\n\n\n\n\n \
+    //Affichage de la version du porgramme
+
+    AfficherLog("\n\n\n\n\n \
  ******************************************\n \
  *             BAORadio Control           *\n \
  * Laboratoire de l'AccÃ©lÃ©rateur LinÃ©aire *\n \
  *                                        *\n \
- *             v0.4  02/12/2011           *\n \
+ *             v0.5  23/02/2012           *\n \
  *        franckrichard033@gmail.com      *\n \
  ******************************************\n\n\n", true);
 
-    //Initialisation des variables globales et des pointeurs
-
-
-    delaitransit  = 0;
-    delaitracking = 0;
-    lognum        = 0;
-    numAntennes   = 0;
-    numobjets     = 0;
-    runnum        = 1;
-
-    Pression      = 1013.0;
-    Temperature   = 10.0;
-
-    NoExit        = true;
-    Transit       = false;
-    run           = false;
-    exitrun       = false;
-
-    fd            = NULL;
-    client_socket = NULL;
+
+    // Initialisation des variables globales et des pointeurs
+    // pour la signification des variables, voir baocontrol.h
+
+
+    delaitransit           = 0;
+    delaitracking          = 0;
+    lognum                 = 0;
+    numAntennes            = 0;
+    numobjets              = 0;
+    numEtoiles             = 0;
+    runnum                 = 1;
+
+    MethodeAlignement      = SIMPLE;
+
+
+    Pression               = 1013.0;
+    Temperature            = 10.0;
+
+    NoExit                 = true;
+    Transit                = false;
+    run                    = false;
+    exitrun                = false;
+    ModificationAlignement = false;
+
+    fd                     = NULL;
+    client_socket          = NULL;
 
     // chaines de caractÃšres et tableaux
 
-    LatitudeChar  = "";
-    LongitudeChar = "";
-    Serveur       = "";
-    Port          = "";
-
-    Antennes 	  = new DefAntenne[MAXANTENNES];
-    objets        = new DefObjets[MAXOBJETS];
-
-    //on initalise aussi les tableaux
+    LatitudeChar           = "";
+    LongitudeChar          = "";
+    Serveur                = "";
+    Port                   = "";
+
+    Antennes 	           = new DefAntenne[ MAXANTENNES ];
+    objets                 = new DefObjets [ MAXOBJETS ];
+    Etoiles                = new DefEtoiles[ MAXETOILES] ;
+
+
+    //on initalise aussi les structures
 
     for (int i=0; i<MAXANTENNES; i++)
     {
-        Antennes[i].ok=0;
-        Antennes[i].ip=0;
-	Antennes[i].delta_az=0;
-	Antennes[i].delta_ha=0;
+        Antennes[i].ok = 0;
+        Antennes[i].ip = 0;
+
+        Antennes[i].AlignementAntenne = new Alignement();
     }
 
     for (int i=0; i<MAXOBJETS; i++)
     {
-        objets[i].JJ=0;
-        objets[i].exec=false;
-    }
-
-    // Chargement du fichier contenant les paramÃštres
-
-    if (!ChargementParametres("params"))
-    {
-        Erreur("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n \
-        Merci de vÃ©rifier.\n\n");
+        objets[i].JJ   = 0.0;
+        objets[i].exec = false;
+    }
+
+    for (int i=0; i<MAXETOILES; i++)
+    {
+        Etoiles[i].nom          = "";
+        Etoiles[i].ad           = 0.0;
+        Etoiles[i].de           = 0.0;
+        Etoiles[i].az           = 0.0;
+        Etoiles[i].ha           = 0.0;
+        Etoiles[i].mag          = 0.0;
+        Etoiles[i].selectionnee = false;
+    }
+
+
+    // Chargement du fichier contenant les paramÃštres de l'application BAOcontrol
+    // La variable permet de rÃ©cupÃ©rer le nom de l'utilisateur ayant ouvert la session sous linux
+    // c'est dans le rÃ©pertoire /home/USER/ que BAOcontrol cherche le fichier de paramÃštre baocontrol_params
+
+    if (!ChargementParametres("/home/" + (string)getenv("USER") + "/baocontrol_params"))
+    {
+        ErreurLog("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n");
+        ErreurLog("Il devrait se trouver dans le rÃ©pertoire /home/" + (string)getenv("USER") +"\n");
+        ErreurLog("Merci de vÃ©rifier...\n\n");
         exit(1);
     }
 
+
     // Conversion de la latitude et de la longitude en radians
 
@@ -103,4 +129,5 @@
     double Longitude = Pi2 - ( a1 + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180;
 
+
     // Transfert de la latitude, longitude, pression, tempÃ©rature Ã  la classe Astro
 
@@ -108,4 +135,16 @@
 
     DefinirPressionTemp(Pression, Temperature);
+
+
+    //Chargement du catalogue d'Ã©toiles que l'on utilise pour l'alignement des antennes
+
+    if ( !ChargementCatalogueEtoiles("/home/" + (string)getenv("USER") + "/bao_catalogue.dat") )
+    {
+        ErreurLog("Le catalogue d'Ã©toiles 'bao_catalogue' est introuvable.\n");
+        ErreurLog("Il devrait se trouver dans le rÃ©pertoire /home/" + (string)getenv("USER") +"\n");
+        ErreurLog("Merci de vÃ©rifier...\n\n");
+        exit(1);
+    }
+
 
     // Ouverture du socket avec indi_BAO
@@ -121,17 +160,27 @@
 
 /**************************************************************************************
-** Destructeur
+** Destructeur de la classe BAOcontrol
+**
 ***************************************************************************************/
 
 BAOcontrol::~BAOcontrol()
 {
-    // destruction des tableaux
-    
+    AfficherLog("\nNettoyage de la mÃ©moire...\n\n", true);
+
+    // destruction des pointeurs et des tableaux
+
+    for (int i=0; i<MAXANTENNES; i++)
+    {
+        delete Antennes[i].AlignementAntenne;
+    }
+
     delete [] Antennes;
     delete [] objets;
-
-    // destruction de la fenÃªtre graphique,des caractÃšres
-
-    if (d!=NULL)
+    delete [] Etoiles;
+
+
+    // destruction de la fenÃªtre graphique et des caractÃšres
+
+    if ( d!=NULL )
     {
         XFreeGC(d, noir);
@@ -150,56 +199,8 @@
 
 
+
 /**************************************************************************************
-** Affiche le message Ã  l'Ã©cran (si AfficheEcran==true) et le sauvegarde dans le fichier
-** BAOControl.log
-***************************************************************************************/
-
-void BAOcontrol::Affiche(string Message, bool AfficheEcran)
-{
-    FILE *pFile = NULL;
-
-    if ( (pFile = fopen ("BAOcontrol.log", "a")) != NULL)
-    {
-        if (AfficheEcran) cout << Message;
-
-        fprintf (pFile, Message.c_str());
-
-        fclose (pFile);
-    }
-}
-
-void BAOcontrol::Affiche(stringstream *Message, bool AfficheEcran)
-{
-    Affiche(Message->str(), AfficheEcran);
-
-    // on efface le buffer
-
-    Message->str("");
-}
-
-
-/**************************************************************************************
-** Affiche les messages d'erreur en rouge
-***************************************************************************************/
-
-void BAOcontrol::Erreur(string chaine)
-{
-    ChoixCouleurs==1 ? cout << red1  : cout << red2;
-    Affiche(chaine, true);
-    ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
-}
-
-void BAOcontrol::Erreur(stringstream *Message)
-{
-    Erreur(Message->str());
-
-    // on efface le buffer
-
-    Message->str("");
-}
-
-
-/**************************************************************************************
-** Initialise la fenÃªtre graphique
+** Initialise la fenÃªtre graphique de BAOcontrol
+**
 ***************************************************************************************/
 
@@ -212,7 +213,8 @@
     if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
     {
-        Erreur("Impossible de contacter le serveur\n\n");
+        ErreurLog("Impossible de contacter le serveur graphique...\n\n");
         exit(1);
     }
+
 
     // crÃ©e une fenÃªtre
@@ -223,32 +225,37 @@
                             WhitePixel(d, DefaultScreen(d)));
 
+
     // CrÃ©ation du double buffer
 
     db = XCreatePixmap(d, w, larg_fenetre, haut_fenetre, DefaultDepth(d, DefaultScreen(d)));
 
+
     // Chargement de la police de caractÃšres
 
     if ((fd = XLoadQueryFont(d, "fixed")) == NULL)
     {
-        Erreur("Impossible de charger la police fixed\n\n");
+        ErreurLog("Impossible de charger la police fixed...\n\n");
         exit(1);
     }
 
+
     // CrÃ©ation des couleurs
 
     gcv.font = fd->fid;
+
     gcv.foreground = BlackPixel(d, DefaultScreen(d));
     noir = XCreateGC(d, w, GCFont | GCForeground, &gcv);
 
-    gcv.foreground = 200*255;
+    gcv.foreground = 200 * 255;
     vert = XCreateGC(d, w, GCFont | GCForeground, &gcv);
 
-    gcv.foreground = 255*256*256;
+    gcv.foreground = 255 * 256 * 256;
     rouge = XCreateGC(d, w, GCFont | GCForeground, &gcv);
 
-    gcv.foreground = 200*256*256+200*256+200;
+    gcv.foreground = 200 * 256 * 256 + 200 * 256 + 200;
     gris = XCreateGC(d, w, GCFont | GCForeground, &gcv);
 
-    // Affichage de fenÃªtre
+
+    // Affichage de la fenÃªtre
 
     XMapWindow(d, w);
@@ -267,11 +274,13 @@
     chaine = new char [100];
 
+
     // On efface la fenÃªtre
 
-    XSetForeground(d, noir, WhitePixel(d, DefaultScreen(d)));
-    XFillRectangle(d, db, noir, 0, 0, larg_fenetre, haut_fenetre);
-    XSetForeground(d, noir, BlackPixel(d, DefaultScreen(d)));
-
-    // On rÃ©cupÃšre la date et l'heure contenue dans la classe astro (et le jour julien)
+    XSetForeground( d, noir, WhitePixel(d, DefaultScreen(d)));
+    XFillRectangle( d, db, noir, 0, 0, larg_fenetre, haut_fenetre);
+    XSetForeground( d, noir, BlackPixel(d, DefaultScreen(d)));
+
+
+    // On rÃ©cupÃšre la date et l'heure contenue dans la classe astro (ainsi que le jour julien)
 
     double h  = GetHeure();
@@ -282,4 +291,5 @@
     double j  = GetJour();
     double JJ = GetJJ();
+
 
     // on Ã©vite les affichages de l'heure du genre 12:56:60 ou 24:00:00
@@ -298,4 +308,5 @@
     }
 
+
     //affichage de la date et de l'heure
 
@@ -305,5 +316,6 @@
     XDrawString(d, db, noir, 10, 10, chaine, strlen(chaine));
 
-    //En cas d'exÃ©cution d'un fichier de mouvements, on affiche la prochaine Ã©tape
+
+    // En cas d'exÃ©cution d'un fichier de mouvements, on affiche la durÃ©e avant la prochaine Ã©tape
 
     if (run)
@@ -315,5 +327,6 @@
     }
 
-    // affichage des cercles d'Ã©tat
+
+    // affichage des cercles d'Ã©tat des antennes
     // vert = l'antenne fonctionne
     // rouge = problÃšme dÃ©tectÃ© sur l'antenne
@@ -338,4 +351,5 @@
 
             XFillArc(d, db ,color, 10+i*30, 20+j*30, 15, 15, 0, 360*64);
+
             XDrawArc(d, db ,noir,  10+i*30, 20+j*30, 15, 15, 0, 360*64);
         }
@@ -343,32 +357,25 @@
 
 
-    // Affichage des messages d'indi_BAO
-    // gÃšre aussi le dÃ©filement
-
-    if (lognum>10)
-    {
-        for (int i=lognum-1; i>lognum-11; i--)
+    // Affichage des messages venant du serveur indi_BAO et rÃ©cupÃ©rÃ©s par la fonction LireReponse()
+    // Les messages d'erreurs sont affichÃ©s en rouge
+
+    for (int i=0; i<lognum; i++)
+    {
+        if (i>lognum-11)
         {
             if ((logs[i].find("Err")!=string::npos)
                     || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
             else color=vert;
-            XDrawString(d, db, color, 10, 9*12+(i-lognum+10)*12, logs[i].c_str(), strlen(logs[i].c_str()));
-        }
-    }
-    else
-    {
-        for (int i=0; i<lognum; i++)
-        {
-            if ((logs[i].find("Err")!=string::npos)
-                    || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
-            else color=vert;
-            XDrawString(d, db, color, 10, 9*12+i*12, logs[i].c_str(), strlen(logs[i].c_str()));
-        }
-    }
-
-    // On affiche la copie de l'Ã©cran une fois que tout est dessinÃ©
-    // on Ã©vite ainsi les scientillements de la fenÃªtre
+            XDrawString(d, db, color, 10, (lognum>10)?9*12+(i-lognum+10)*12:9*12+i*12,
+                        logs[i].c_str(), strlen(logs[i].c_str()));
+        }
+    }
+
+
+    // On n'affiche la fenÃªtre graphique que lorsque tous les Ã©lÃ©ments ont Ã©tÃ© dessinÃ©s Ã  l'intÃ©rieur
+    // On Ã©vite ainsi le scientillement de la fenÃªtre...
 
     XCopyArea(d, db, w, noir, 0, 0, larg_fenetre, haut_fenetre, 0, 0);
+
 
     // On force le rafraichissement de l'Ã©cran
@@ -380,6 +387,8 @@
 
 
+
 /**************************************************************************************
 ** Gestion des Ã©vÃ©nements affectant la fenÃªtre graphique
+**
 ***************************************************************************************/
 
@@ -403,6 +412,8 @@
 
 
+
 /**************************************************************************************
-** RÃ©cupÃšre les messages envoyÃ©s par indi_BAO
+** RÃ©cupÃšre les messages envoyÃ©s par le serveur indi_BAO
+**
 ***************************************************************************************/
 
@@ -410,25 +421,33 @@
 {
     string reponse, memreponse, decomp;
-    bool test=false;
+
+    bool test = false;
+
+    // on rÃ©cupÃšre les messages provenant d'indi_BAO
 
     *client_socket >> reponse;
-    
-   // printf("%s\n", reponse.c_str());
 
     do
     {
-        if (reponse.find("message")!=string::npos)
+        // s'il contient le mot message (et vient donc d'indi_BAO)
+
+        if (reponse.find("message") != string::npos)
         {
             // On ne garde que la partie intÃ©ressante
-            // La partie "message="...
+            // La partie qui suit "message="...
+
             reponse = reponse.substr(reponse.find("message") + 9);
 
+            //(on en garde une trace)
+
             memreponse = reponse;
 
-            // ...jusqu'au "
-            reponse=reponse.substr(0, reponse.find("\""));
+            // ...on extrait le message jusqu'au caractÃšre "
+
+            reponse = reponse.substr(0, reponse.find("\""));
 
             // On rÃ©cupÃšre l'adresse ip de l'antenne qui nous parle
-            // et on met Ã  jour le tableau des Ã©tats des antennes
+            // et on met Ã  jour le tableau des Ã©tats de l'antenne correspondante
+            // Dans les messages d'indi_BAO, l'adresse ip prÃ©cÃšde les mots "Antennes connectÃ©es"
 
             if (reponse.find(". (Antennes connectees")!=string::npos)
@@ -437,21 +456,24 @@
                 decomp = decomp.substr(decomp.rfind(".")+1);
 
-                // si cette antenne est dÃ©jÃ  connectÃ©e, on change son Ã©tat
-		
-                if (atoi(decomp.c_str())!=0) for (int i=0; i<numAntennes; i++)
-                {
-                    if (atoi(decomp.c_str()) == Antennes[i].ip)
+                // si cette antenne est dÃ©jÃ  connectÃ©e, on change son Ã©tat si nÃ©cessaire
+
+                if ( atoi(decomp.c_str()) != 0 ) for (int i=0; i<numAntennes; i++)
                     {
-                        Antennes[i].ok=1;
-                        test=true;
-                        break;
+                        // on a trouvÃ© l'antenne correspondante
+
+                        if (atoi(decomp.c_str()) == Antennes[i].ip)
+                        {
+                            Antennes[i].ok = 1;
+                            test = true;
+                            break;
+                        }
                     }
-                }
-
-                // ou si c'est une nouvelle antenne, on l'ajoute au tableau
+
+                // ou si c'est une nouvelle antenne, on l'ajoute au tableau Antennes
 
                 if (!test)
                 {
                     Antennes[numAntennes].ip = atoi(decomp.c_str());
+
                     Antennes[numAntennes++].ok = 1;
                 }
@@ -459,7 +481,9 @@
 
             // erreur sur une antenne -> on change son Ã©tat dans la fenÃªtre
-
-            if  ((reponse.find("ALERTE antenne ")!=string::npos) ||
-                    (reponse.find("Erreur sur l antenne ")!=string::npos))
+            // on trouve les erreurs dans les messages d'indi_BAO forumulÃ©e
+            // de la faÃ§on suivnate: "ALERTE antenne" ou bien "Erreur sur l antenne"
+
+            if  ((reponse.find("ALERTE antenne ") != string::npos) ||
+                    (reponse.find("Erreur sur l antenne ") != string::npos))
             {
                 decomp = reponse.substr(0, reponse.find(" :"));
@@ -468,4 +492,6 @@
                 for (int i=0; i<numAntennes; i++)
                 {
+                    // On identifie l'antenne dans le tableau Antennes et on change son Ã©tat
+
                     if (atoi(decomp.c_str()) == Antennes[i].ip)
                     {
@@ -475,5 +501,5 @@
             }
 
-            // On sauvegarde le message dans le tableau logs
+            // On sauvegarde le message dans le fichier logs mais on ne l'affiche pas
 
             stringstream os;
@@ -481,18 +507,18 @@
             os << lognum << " : " << reponse;
 
-            Affiche(os.str() + "\n", false);
-
-            if (lognum<MAXLOG-1) logs[lognum++] = os.str();
+            AfficherLog(os.str() + "\n", false);
+
+            if ( lognum < MAXLOG - 1 ) logs[ lognum++ ] = os.str();
 
             reponse = memreponse;
-        } 
-        else reponse="";
-	  
-
-    } while ( reponse !="" );
-
-     // on actualise la fenÃªtre
-
-        Dessiner();
+        }
+        else reponse = "";
+
+
+    } while ( reponse != "" );
+
+    // on actualise la fenÃªtre
+
+    Dessiner();
 
     // on envoie un message pour actualiser la fenÃªtre graphique
@@ -505,4 +531,6 @@
 /**************************************************************************************
 ** Est-ce que la rÃ©ponse du pilote indi_BAO est conforme Ã  ce que l'on attendait ?
+** Retourne true si c'est bonne
+**
 ***************************************************************************************/
 
@@ -529,5 +557,5 @@
             duree++;
         }
-        while (reponse.length() == 0 && duree<10 ); // on attend un message pendant 10 ms max
+        while (reponse.length() == 0 && duree < 20 ); // on attend un message pendant 10 ms max
 
         // on ajoute tous les messages reÃ§us dans memmreponse
@@ -555,5 +583,5 @@
             memreponse = memreponse.substr(0, memreponse.find("\""));
 
-            Erreur("RÃ©ponse du pilote indi_BAO :" + memreponse + "\n\n");
+            ErreurLog("RÃ©ponse du pilote indi_BAO :" + memreponse + "\n\n");
         }
 
@@ -565,14 +593,15 @@
 
 
+
 /**************************************************************************************
 ** Calcul du jour julien et du temps sidÃ©ral local
+**
 ***************************************************************************************/
 
-void BAOcontrol::Update()
+void BAOcontrol::UpdateTime()
 {
+    time_t t;
     struct tm date;
-    time_t t;
     struct timeval tv;
-    struct timezone tz;
 
     // On rÃ©cupÃšre la date et l'heure depuis l'horloge du systÃšme
@@ -580,5 +609,5 @@
     time(&t);
     date=*gmtime(&t);
-    gettimeofday(&tv, &tz);
+    gettimeofday(&tv, NULL);
 
     double Annee = (double)date.tm_year + 1900.0;
@@ -590,16 +619,9 @@
     double UTCP  = 0.0;//(double)date.tm_isdst;
 
-    /*Annee=2011;
-    Mois=6;
-    Jour=17;
-    Heu=15;
-    Min=53.0;
-    Sec=00.0;*/
-
     // On actualise la date et l'heure dans la classe Astro
 
     DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
 
-    // On lance les calculs
+    // On lance les calculs (Temps sidÃ©ral local etc...)
 
     CalculTSL();
@@ -607,9 +629,11 @@
 
 
+
 /**************************************************************************************
 ** gestion du thread permettant
-** -l'exÃ©cution d'une liste de mouvements programmÃ©s
-** -l'actualisation de la fenÃªtre graphique
-** -la rÃ©cupÃ©ration des messages du pilote indi_BAO
+** - l'exÃ©cution d'une liste de mouvements programmÃ©s
+** - l'actualisation de la fenÃªtre graphique
+** - la rÃ©cupÃ©ration des messages du pilote indi_BAO
+**
 ***************************************************************************************/
 
@@ -617,11 +641,12 @@
 {
     stringstream os;
-
-    // Tant ue l'utilisateur n'a pas taper la commande 'exit'
+    struct timeval tv;
+
+    // Tant que l'utilisateur n'a pas tapÃ© la commande 'exit'
     while (NoExit)
     {
-        //On actualise le jour julien et le temps sidÃ©ral local
-
-        Update();
+        // On actualise le jour julien et le temps sidÃ©ral local
+
+        UpdateTime();
 
         // On rÃ©cupÃšre le jour julien
@@ -632,26 +657,27 @@
         // Faut-il executer un fichier de mouvements ?
 
-        if (run && numobjets>1 && runnum<numobjets)
-        {
-            // On lance le mouvement numÃ©ro runnum si la date correspond au dÃ©but
+        if (run && numobjets > 1 && runnum < numobjets)
+        {
+            // On lance le mouvement numÃ©ro runnum si la date et l'heure correspondent au dÃ©but
             // de son exÃ©cution et que ce mouvement n'a pas Ã©tÃ© encore rÃ©alisÃ©
 
-            if (JJ >= objets[runnum].JJ && !objets[runnum].exec)
+            if ( JJ >= objets[runnum].JJ && !objets[runnum].exec )
             {
-                // petit message pour l'utilisateur
-
-                if ( runnum == 1 ) Affiche("DÃ©but de l'exÃ©cution du fichier de mouvements\n\n", true);
+                // petit message pour l'utilisateur au dÃ©but de l'execution du tout premier mouvement
+
+                if ( runnum == 1 ) AfficherLog("DÃ©but de l'exÃ©cution du fichier de mouvements\n\n", true);
 
                 os << "Suivi de l'objet nÂ°" << runnum << endl;
-                Affiche(&os, true);
-
-                // on indique que le mouvement est en cours d'exÃ©cution
-                //ou qu'il a Ã©tÃ© dÃ©jÃ  exÃ©cutÃ©
-
-                objets[runnum].exec=true;
-
-                //on envoie l'ordre goto correspondant
-
-                Goto(objets[runnum].ad, objets[runnum].de, Transit, J2000);
+
+                AfficherLog(&os, true);
+
+                // on note que le mouvement est en cours d'exÃ©cution
+                // ou qu'il a Ã©tÃ© dÃ©jÃ  exÃ©cutÃ©
+
+                objets[runnum].exec = true;
+
+                // on pointe l'objet correspondant
+
+                Goto( objets[runnum].ad, objets[runnum].de, Transit, J2000 );
             }
 
@@ -669,5 +695,5 @@
                 if ( runnum + 1 >= numobjets )
                 {
-                    Affiche("Fin de l'execution du fichier de mouvements\n\n", true);
+                    AfficherLog("Fin de l'execution du fichier de mouvements\n\n", true);
 
                     // on rÃ©affiche le prompt
@@ -685,5 +711,5 @@
                     // On sort du programme dans le cas BAOControl -r fileName
 
-                    NoExit=!exitrun;
+                    NoExit = !exitrun;
                 }
                 else
@@ -702,4 +728,20 @@
         Dessiner();
 
+        // sauvegarde les paramÃštres de correction des antennes
+
+        if (ModificationAlignement)
+        {
+            gettimeofday(&tv, NULL);
+
+            // on ne sauvegarde les paramÃštres des alignements que si l'horloge du systÃšme vient juste
+            // de changer de seconde. Cela evite les conflits avec le pilote indi_BAO qui cherche
+            // quant Ã  lui Ã  charger ce mÃªme fichier en fin de seconde...
+
+            if (tv.tv_usec/1.0E6>0.0 && tv.tv_usec/1.0E6<0.1)
+            {
+                for (int i=0; i<numAntennes; i++) if (Antennes[i].ok == 1) Antennes[i].AlignementAntenne->EnregistrementParametresAlignement(Antennes[i].ip, "/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
+            }
+        }
+
         // pause de 100 ms
 
@@ -708,5 +750,4 @@
 
     // l'utilisateur a tapÃ© exit... On sort du thread...
-
 
     pthread_exit (0);
@@ -730,7 +771,8 @@
 **          chaine2  = "25:10:10"
 **
-** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULLL)
+** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULL)
 ** retourne chaine1  = "messier 1"
 **          chaine2  = NULL
+**
 ***************************************************************************************/
 
@@ -762,4 +804,5 @@
 
             // puis on prend le deuxiÃšme bloc -> c'est la chaine2
+
             pos = chaine.find(" ");
 
@@ -781,5 +824,5 @@
             *chaine1 = chaine;
         }
-    }
+    } else return false;
 
     return true;
@@ -790,4 +833,5 @@
 /**************************************************************************************
 ** Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO
+**
 ***************************************************************************************/
 
@@ -795,6 +839,5 @@
 {
     // la communication avec le pilote indi_BAO
-    // se fait par l'envoie de fichiers xml
-    // d'oÃ¹ le cÃŽtÃ© complexe des commandes
+    // se fait par l'envoi de fichiers xml
 
     try
@@ -811,5 +854,5 @@
         if (!VerifReponse("name=\"GEOGRAPHIC_COORD\" state=\"Ok\""))
         {
-            Erreur("ERREUR fct EnvoyerCoordGeographiques : pas de rÃ©ponse du pilote indi_BAO.\n\n");
+            ErreurLog("ERREUR fct EnvoyerCoordGeographiques : pas de rÃ©ponse du pilote indi_BAO.\n\n");
 
             return false;
@@ -821,9 +864,10 @@
     catch ( SocketException& e )
     {
-        Erreur("Exception was caught:" + e.description() + "\n");
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
         return false;
     }
 
-    Affiche("Les coordonnÃ©es gÃ©ographiques ont bien Ã©tÃ© envoyÃ©es au pilote indi_BAO\n\n", true);
+    AfficherLog("Les coordonnÃ©es gÃ©ographiques ont bien Ã©tÃ© envoyÃ©es au pilote indi_BAO\n\n", true);
 
     return true;
@@ -831,7 +875,157 @@
 
 
+/**************************************************************************************
+** Transmet la pression et la tempÃ©rature au pilote indi_BAO
+**
+***************************************************************************************/
+
+bool BAOcontrol::EnvoyerPressionTemperature()
+{
+    stringstream os;
+
+    try
+    {
+        *client_socket << "<newNumberVector device=\"BAO\" name=\"PRESSION_DATA\">";
+        *client_socket << "<oneNumber name=\"Pression\">";
+        os << Pression;
+        *client_socket << os.str();
+        os.str("");
+        *client_socket << "</oneNumber>";
+        *client_socket << "<oneNumber name=\"Temperature\">";
+        os << Temperature;
+        *client_socket << os.str();
+        os.str("");
+        *client_socket << "</oneNumber>";
+        *client_socket << "</newNumberVector>";
+
+        if (!VerifReponse("name=\"PRESSION_DATA\" state=\"Ok\""))
+        {
+            ErreurLog("ERREUR fct EnvoyerPressionTemperature : pas de rÃ©ponse du pilote indi_BAO.\n\n");
+
+            return false;
+        }
+    }
+
+    // un problÃšme ?
+
+    catch ( SocketException& e )
+    {
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
+        return false;
+    }
+
+    AfficherLog("La pression et la tempÃ©rature ont bien Ã©tÃ© envoyÃ©es au pilote indi_BAO\n\n", true);
+
+    return true;
+}
+
+/**************************************************************************************
+** Envoie les paramÃštres delaitransit et delaitracking au pilote indi_BAO
+** Ces paramÃštres dÃ©finissent la durÃ©e (en sec) entre deux actualisations
+** dans les modes tracking et transit
+**
+***************************************************************************************/
+
+bool BAOcontrol::EnvoyerDelaisModesTransitEtTracking()
+{
+    stringstream os;
+
+    try
+    {
+        os << delaitransit;
+        *client_socket << "<newNumberVector device=\"BAO\" name=\"DELAY1\">";
+        *client_socket << "<oneNumber name=\"DELAY\">";
+        *client_socket << os.str();
+        *client_socket << "</oneNumber>";
+        *client_socket << "</newNumberVector>";
+        os.str("");
+
+        if (!VerifReponse("name=\"DELAY1\" state=\"Ok\""))
+        {
+            ErreurLog("ERREUR fct EnvoyerDelaisModesTransitEtTracking : pas de rÃ©ponse du pilote indi_BAO.\n\n");
+
+            return false;
+        }
+
+        os << delaitracking;
+        *client_socket << "<newNumberVector device=\"BAO\" name=\"DELAY2\">";
+        *client_socket << "<oneNumber name=\"DELAY\">";
+        *client_socket << os.str();
+        *client_socket << "</oneNumber>";
+        *client_socket << "</newNumberVector>";
+        os.str("");
+
+        if (!VerifReponse("name=\"DELAY2\" state=\"Ok\""))
+        {
+            ErreurLog("ERREUR fct EnvoyerDelaisModesTransitEtTracking : pas de rÃ©ponse du pilote indi_BAO.\n\n");
+
+            return false;
+        }
+    }
+
+    // un problÃšme ?
+
+    catch ( SocketException& e )
+    {
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
+        return false;
+    }
+
+    return true;
+}
+
+
+
+/**************************************************************************************
+** Envoie les paramÃštres delaitransit et delaitracking au pilote indi_BAO
+** Ces paramÃštres dÃ©finissent la durÃ©e (en sec) entre deux actualisations
+** dans les modes tracking et transit
+**
+***************************************************************************************/
+
+bool BAOcontrol::EnvoyerMethodeAlignement()
+{
+    stringstream os;
+
+    try
+    {
+        *client_socket << "<newSwitchVector device=\"BAO\" name=\"ALIGNMENT_SET\">";
+        *client_socket << "<oneSwitch name=\"SIMPLE\">";
+        (MethodeAlignement == SIMPLE) ? *client_socket << "On" : *client_socket << "Off";
+        *client_socket << "</oneSwitch>";
+        *client_socket << "<oneSwitch name=\"AFFINE\">";
+        (MethodeAlignement == AFFINE) ? *client_socket << "On" : *client_socket << "Off";
+        *client_socket << "</oneSwitch>";
+        *client_socket << "<oneSwitch name=\"TAKI\">";
+        (MethodeAlignement == TAKI) ? *client_socket << "On" : *client_socket << "Off";
+        *client_socket << "</oneSwitch>";
+        *client_socket << "</newSwitchVector>";
+
+        if (!VerifReponse("name=\"ALIGNMENT_SET\" state=\"Ok\""))
+        {
+            ErreurLog("ERREUR fct EnvoyerMethodeAlignement : pas de rÃ©ponse du pilote indi_BAO.\n\n");
+
+            return false;
+        }
+    }
+
+    // un problÃšme ?
+
+    catch ( SocketException& e )
+    {
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
+        return false;
+    }
+
+    return true;
+}
+
 
 /**************************************************************************************
 ** Place les antennes en position de repos
+**
 ***************************************************************************************/
 
@@ -848,5 +1042,5 @@
         if (!VerifReponse("PARK OK"))
         {
-            Erreur("La commande PARK a Ã©chouÃ©.\n\n");;
+            ErreurLog("La commande PARK a Ã©chouÃ©.\n\n");;
 
             return false;
@@ -855,9 +1049,10 @@
     catch ( SocketException& e)
     {
-        Erreur("Exception was caught:" + e.description() + "\n");
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
         return false;
     }
 
-    Affiche("Le pilote indi_BAO a bien reÃ§u la commande PARK.\n\n", true);
+    AfficherLog("Le pilote indi_BAO a bien reÃ§u la commande PARK.\n\n", true);
 
     return true;
@@ -868,4 +1063,5 @@
 /**************************************************************************************
 ** Annule le mouvement en cours
+**
 ***************************************************************************************/
 
@@ -882,5 +1078,5 @@
         if (!VerifReponse("ABORT OK"))
         {
-            Erreur("L'annulation a Ã©chouÃ©.\n\n");
+            ErreurLog("L'annulation a Ã©chouÃ©.\n\n");
 
             return false;
@@ -889,9 +1085,10 @@
     catch ( SocketException& e)
     {
-        Erreur("Exception was caught:" + e.description() + "\n");
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
         return false;
     }
 
-    Affiche("Le pilote indi_BAO a bien reÃ§u la commande ABORT.\n\n", true);
+    AfficherLog("Le pilote indi_BAO a bien reÃ§u la commande ABORT.\n\n", true);
 
     return true;
@@ -903,34 +1100,31 @@
 ** Diriger l'antenne vers les coordonnÃ©es ar et dec et suivre l'objet
 ** en activant le mode transit ou tracking.
+**
 ** si J2000 == true, cela signifie que les coordonnÃ©es ar et dec sont donnÃ©es dans le
 ** le systÃšme de coordonnÃ©es J2000 (Ã©cliptique et Ã©quinoxe du 1 janvier 2000 Ã  0 h TU)
-** Des calculs supplÃ©mentaires (prÃ©cession, nutation, abÃ©rration) sont alors nÃ©cessaires
+** Des calculs supplÃ©mentaires (prÃ©cession, nutation, aberration) sont alors rÃ©alisÃ©s
+** pour ramener les coordonnÃ©es ad et dec Ã  l'Ã©cliptique et l'Ã©quinoxe de la date de
+** l'observation.
+**
 ***************************************************************************************/
 
 bool BAOcontrol::Goto(string ar, string dec, bool Transit, bool J2000)
 {
+    double arf, decf;
+    double azi, hau;
     float  ar1, ar2, ar3;
     float  dec1, dec2, dec3;
-    double arf, decf;
-    double azi, hau;
-
-
-     /*
-     //Pour les tests
-     ar="05:39:14.8";
-     dec="23:19:24.1";
-     printf("JJ=%10.10f\n", GetJJ());
-     J2000=true;
-     */
+
 
     // Conversion de l'AD et de la dÃ©clinaison en radians
 
     Decomposition(ar, 2, &ar1, &ar2, &ar3);
+
     Decomposition(dec, 0, &dec1, &dec2, &dec3);
-    
+
     arf  = ( ar1  + ar2 / 60.0  + ar3 / 3600.0 ) * 15.0 * Pidiv180;
     decf = ( fabs(dec1) + dec2 / 60.0 + dec3 / 3600.0 ) * Pidiv180;
 
-    if (dec[0]=='-') decf = -decf;
+    if (dec[0] == '-') decf = -decf;
 
     // calculs pupplÃ©mentaires pour se ramener
@@ -952,19 +1146,8 @@
     // on en informe l'utilisateur
 
-    Affiche("CoordonnÃ©es apparentes de l'objet :\n", true);
-
-    Affiche("AD=" + ar  + "   Dec=" + dec +"\n", true);
-
-   
-    /*
-    //Tests
-    Azimut(arf, decf, &azi, &hau);
-
-    hau=RefractionAtmospherique(hau);
-
-    Affiche("CoordonnÃ©es rectangulaires liÃ©es au lieu d'observation :\n", true);
-
-    printf("Azimut = %s   Hauteur = %s\n", DHMS(azi*N180divPi,false).c_str(), DHMS(hau*N180divPi, false).c_str());
-    */
+    AfficherLog("CoordonnÃ©es apparentes de l'objet :\n", true);
+
+    AfficherLog("AD=" + ar  + "   Dec=" + dec +"\n", true);
+
 
     // On transmet les coordonnÃ©es au pilote BAO
@@ -986,5 +1169,5 @@
         if (!VerifReponse("name=\"ON_COORD_SET\""))
         {
-            Erreur("Le changement de mode TRANSIT/TRACKING a Ã©chouÃ©.\n\n");
+            ErreurLog("Le changement de mode TRANSIT/TRACKING a Ã©chouÃ©.\n\n");
 
             return false;
@@ -1002,5 +1185,5 @@
         if (!VerifReponse("name=\"EQUATORIAL_EOD_COORD_REQUEST\""))
         {
-            Erreur("Le transfert des coordonnÃ©es de l'objet a Ã©chouÃ©.\n\n");
+            ErreurLog("Le transfert des coordonnÃ©es de l'objet a Ã©chouÃ©.\n\n");
 
             return false;
@@ -1009,10 +1192,12 @@
     catch ( SocketException& e)
     {
-        Erreur("Exception was caught:" + e.description() + "\n");
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
         return false;
     }
 
-    Affiche("Les nouvelles coordonnÃ©es AD=" + ar + " Dec=" + dec, true);
-    Affiche(" ont Ã©tÃ© envoyÃ©es au pilote indi_BAO.\n\n", true);
+    AfficherLog("Les nouvelles coordonnÃ©es AD=" + ar + " Dec=" + dec, true);
+    AfficherLog(" ont Ã©tÃ© envoyÃ©es au pilote indi_BAO.\n\n", true);
+
     return true;
 }
@@ -1041,5 +1226,5 @@
             if (!VerifReponse("BAORadio is online"))
             {
-                Erreur("La connexion a Ã©chouÃ©.\n\n");
+                ErreurLog("La connexion a Ã©chouÃ©.\n\n");
 
                 return false;
@@ -1050,5 +1235,5 @@
             if (!VerifReponse("BAORadio is offline"))
             {
-                Erreur("La dÃ©connexion a Ã©chouÃ©.\n\n");
+                ErreurLog("La dÃ©connexion a Ã©chouÃ©.\n\n");
 
                 return false;
@@ -1059,5 +1244,6 @@
     catch ( SocketException& e )
     {
-        Erreur("Exception was caught:" + e.description() + "\n");
+        ErreurLog("Exception was caught:" + e.description() + "\n");
+
         return false;
     }
@@ -1065,11 +1251,19 @@
     if (connect)
     {
-        Affiche("La connexion a Ã©tÃ© Ã©tablie avec le pilote indi_BAO.\n\n", true);
+        AfficherLog("La connexion a Ã©tÃ© Ã©tablie avec le pilote indi_BAO.\n\n", true);
+
+        usleep(500000);
 
         EnvoyerCoordGeographiques();
+
+        EnvoyerPressionTemperature();
+
+        EnvoyerDelaisModesTransitEtTracking();
+
+        EnvoyerMethodeAlignement();
     }
     else
     {
-        Affiche("BAOcontrol s'est bien dÃ©connectÃ© du pilote indi_BAO.\n\n", true);
+        AfficherLog("BAOcontrol s'est bien dÃ©connectÃ© du pilote indi_BAO.\n\n", true);
     }
 
@@ -1080,4 +1274,6 @@
 /**************************************************************************************
 ** Gestion du clavier en mode raw pour la procÃ©dure d'alignement
+** Cela permet de ne pas avoir Ã  taper sur la touche 'entrÃ©e' aprÃšs avoir appuyÃ© sur
+** une flÃšche de direction
 ***************************************************************************************/
 
@@ -1086,14 +1282,14 @@
     static struct termios cooked;
     static int raw_actif = 0;
-    
+
     if (raw_actif == activer)
         return;
-    
+
     if (activer)
     {
         struct termios raw;
-        
+
         tcgetattr(STDIN_FILENO, &cooked);
-        
+
         raw = cooked;
         cfmakeraw(&raw);
@@ -1102,5 +1298,5 @@
     else
         tcsetattr(STDIN_FILENO, TCSANOW, &cooked);
-    
+
     raw_actif = activer;
 }
@@ -1109,95 +1305,316 @@
 /**************************************************************************************
 ** Alignement de l'antenne situÃ©e Ã  l'adresse ip
+**
+** Le principe consiste Ã  utiliser des Ã©toiles comme point de repÃšre pour la calibration
+** des antennes : on compare la position calculÃ©e de chaque objet avec la position
+** effectivement mesurÃ©e lors de la procÃ©dure d'alignement. On en tire alors une matrice
+** de rotation qui doit corriger les dÃ©fauts d'alignement de l'antenne (le 0 pas codeur
+** pas  parfaitement dirigÃ© vers le sud et un axe de rotation az pas forcÃ©ment
+** perpendiculaire au sol...)
 ***************************************************************************************/
 
-bool BAOcontrol::Alignement(string ip)
+bool BAOcontrol::AlignementAntenneIP( string ip )
 {
-   bool test=false;
-   
-   int i;
-   
-   if (ip.rfind(".") != string::npos) ip=ip.substr(ip.rfind(".")+1);
-   
-   for (i=0; i<numAntennes; i++)
-   {
-      if (atoi(ip.c_str()) == Antennes[i].ip) { test=true; break; }
-   }
-  
-   if ((test) && (atoi(ip.c_str())!=0))
-   {
-         Affiche("DÃ©but de l'alignement de l'antenne.\n \
-         Appuyez sur les touches Z,Q,D,X pour centrer l'objet dans le viseur.\n \
-         (ESC pour arrÃªter et valider).\n\n", true);
-	 
-	 int c = 0;
-	 
-	 while (c!=27)
-	 {
-	   mode_raw(1);
-	   
-	   c = getchar();
-	   
-	   mode_raw(0);
-	   
-           switch(c)
-	   {
-	     case 122 : Antennes[i].delta_ha++; Affiche("delta_ha + 1\n", true); break;
-	     case 100 : Antennes[i].delta_az++; Affiche("delta_az + 1\n", true); break;
-	     case 113 : Antennes[i].delta_az--; Affiche("delta_az - 1\n", true); break;
-	     case 120 : Antennes[i].delta_ha--; Affiche("delta_ha - 1\n", true); break;
-	   }  
-	   
-	   // Enregistrement des paramÃštres d'alignement des antennes
-    
-           EnregistrementParametresAlignement("/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
-	 }          
-   }  
-   else
-   {
-         Erreur("L'antenne situÃ©e Ã  l'adresse ip indiquÃ©e n'existe pas\n\n");
-	 
-	 return false;
-   }
-    
-   return true;
-}
-
-
-/**************************************************************************************
-** Sauvegarde des paramÃštres d'alignement des antennes
-***************************************************************************************/
-
-bool BAOcontrol::EnregistrementParametresAlignement(string fileName)
-{
-    string section;
-    string key;
-    string value;
-    char ip[100];
+    static int Vitesse = 10;
+
+    bool test = false;
 
     stringstream os;
 
-    //Affiche("Enregistrement de l'alignement des antennes dans le fichier " + fileName + "\n", true);
-
-    //Enregistrement des corrections des l'antennes
-
-    for (int i=0; i< numAntennes; i++)
-    {
-        sprintf(ip, "%i", Antennes[i].ip);
-        os << "Alignement antenne ip x.x.x." << (string)ip;
-        section = os.str();
-        os.str("");
-        key     = "delta_az";
-        os << Antennes[i].delta_az;
-        value = os.str();
-        os.str("");
-
-        writeINI((char*)section.c_str(), (char*)key.c_str(), (char*)value.c_str(), (char*)fileName.c_str());
-
-        key     = "delta_ha";
-        os << Antennes[i].delta_ha;
-        value = os.str();
-        os.str("");
-
-        writeINI((char*)section.c_str(), (char*)key.c_str(), (char*)value.c_str(), (char*)fileName.c_str());
+    int i, num;
+
+    char c;
+
+
+    ModificationAlignement=false;
+
+    // On sÃ©lectionne la bonne antenne Ã  partir de son adresse ip (on ne prend en compte que le dernier nombre de l'adresse IP.
+
+    if ( ip.rfind(".") != string::npos ) ip = ip.substr(ip.rfind(".") + 1);
+
+    for (num=0; num<numAntennes; num++)
+    {
+        if (atoi(ip.c_str()) == Antennes[num].ip) {
+
+            test=true;
+
+            break;
+        }
+    }
+
+    // on a identifiÃ© l'antenne
+
+    if ( test && atoi(ip.c_str()) != 0 )
+    {
+        // L'alignement de l'antenne 'num' est en cours. Il ne faut pas calculer la
+        // matrice de correction tant que ce n'est pas fini..
+
+        AfficherLog("DÃ©but de l'alignement de l'antenne.\n\n", true);
+
+        // On charge les paramÃštres d'alignement existants s'ils existent
+
+        Antennes[num].AlignementAntenne->ChargementParametresAlignement(ip, "/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg", atol(ip.c_str()), num);
+
+        // l'antenne num est en cours d'alignement
+
+        Antennes[num].AlignementAntenne->AlignementEnCours = true;
+
+        // Si on n'a pas encore effectuÃ© la premiÃšre phase de l'alignement (viser la polaire) dans les mÃ©thode d'alignement AFFINE et TAKI
+
+        if ( Antennes[num].AlignementAntenne->delta_az_polar == 0 && MethodeAlignement!=SIMPLE)
+        {
+            cout << "Le radiotÃ©lescope va pointer l'Ã©toile polaire.\n";
+	    cout << "Agissez sur les touches Q et D pour centrer l'Ã©toile dans le viseur...\n";
+	    cout << "Appuyez sur A pour envoyer un ABORT Ã  l'antenne.\n";
+            cout << "Puis, appuyez sur ESC pour valider...\n\n";
+
+
+            // On pointe l'Ã©toile polaire
+
+            Goto("02:31:49.6", "89:15:50.9", Transit, true);
+
+            do
+            {
+                mode_raw(1);
+
+                c = getchar();
+
+                mode_raw(0);
+
+                usleep(10000);
+
+                // Gestion des touches flÃ©chÃ©es du clavier. On modifie l'orientation de l'instrument
+                // sur les axes AD et Dec...
+
+                switch (c)
+                {
+                case 'd' :
+                    Antennes[num].AlignementAntenne->delta_az_polar++;
+                    ModificationAlignement=true;                       // On avertit le reste du programme du changement d'un paramÃštre
+                    AfficherLog("delta_az + 1\n", true);               // sur l'une des antennes -> d'oÃ¹ la nÃ©cessitÃ© de sauvegarder
+                    break;                                             // les nouveaux paramÃštres
+                case 'q' :
+                    Antennes[num].AlignementAntenne->delta_az_polar--;
+                    ModificationAlignement=true;
+                    AfficherLog("delta_az - 1\n", true);
+		    
+                    break;
+                case 'a' :
+                    Abort();
+                    sleep(2);
+
+                    break;
+
+               
+                }
+
+            } while (c!=27);
+        }
+
+
+        AfficherLog("\n\n\nListe des Ã©toiles brillantes situÃ©es Ã  plus de 30Â° au-dessus de l'horizon :\n\n", true);
+
+        UpdateTime();
+
+        // recherche les Ã©toiles situÃ©es Ã  une hauteur supÃ©rieure Ã  30 Â°
+        // (et donc accessibles Ã  l'antenne)
+
+        for (i=1; i<numEtoiles; i++)
+        {
+            Azimut(Etoiles[i].ad, Etoiles[i].de, &Etoiles[i].az, &Etoiles[i].ha);
+
+            // calcule de la rÃ©fraction atmosphÃ©rique
+
+            Etoiles[i].ha = RefractionAtmospherique(Etoiles[i].ha);
+
+            // SÃ©lectionner et afficher les Ã©toiles > 30Â°
+
+            if ( Etoiles[i].selectionnee = ((Etoiles[i].ha > (HAUTMIN + 5.0) * Pidiv180) && (Etoiles[i].mag < MAGNITUDEMAXETOILESCALIBRATION)) )
+            {
+                os.width(20);
+                os << Etoiles[i].nom;
+                os << "\t(" << Etoiles[i].cons << ")\taz=" << Etoiles[i].az * N180divPi << "Â°\tha=";
+                os << Etoiles[i].ha * N180divPi << "Â°\tmagnitude=" << Etoiles[i].mag << "\n";
+
+                AfficherLog(&os, true);
+            }
+
+            if (Etoiles[i].selectionnee)
+            {
+                for (int j=1; j<=Antennes[num].AlignementAntenne->nbrcorrections; j++)
+                {
+                    // LÃ , un point important: on ne prend pas en compte l'AD des objets dans le reste des calculs
+                    // Mais l'angle horaire de ces objets avec le mÃ©ridien en retranchant le temps sidÃ©ral local
+                    // Ã  l'ascension droite des objets. Voir les dÃ©tails dans la documentation....
+
+                    double distances = DistanceAngulaireEntre2Points(
+                                           VerifAngle(Antennes[num].AlignementAntenne->ad[j] - Antennes[num].AlignementAntenne->tsl[j]),
+                                           Antennes[num].AlignementAntenne->de[j],
+                                           VerifAngle(Etoiles[i].ad - GetTSL()),
+                                           Etoiles[i].de);
+
+                    // Ici, on ne selectionne que des Ã©toiles qui ne soont pas trop proches de positions ayant dÃ©jÃ  servies Ã  la calibration
+                    // de l'antenne et qui multiplierait les mesures sans amÃ©lioration de la prÃ©cision
+
+                    if ( distances < MIN_DISTANCE_ALIGNEMENT ) Etoiles[i].selectionnee = false;
+                }
+
+            }
+        }
+
+        // Pour chaque Ã©toile que l'on a trouvÃ©, on demande Ã  l'utilisateur s'il dÃ©sire l'utiliser
+        // pour calibrer l'antenne
+
+        for (i=1; i<numEtoiles; i++)
+        {
+            if ( Etoiles[i].selectionnee )
+            {
+                AfficherLog("\nVoulez-vous pointer l'Ã©toile " + Etoiles[i].nom + " pour aligner l'antenne ? (o/n)\n", true);
+                AfficherLog("(Tapez sur la touche f pour achever l'alignement de l'antenne et enregistrer les paramÃštres.)\n", true);
+
+                // activer le mode raw Ã©vite d'avoir Ã  taper sur la touche entrÃ©e entre chaque pression
+                // sur le clavier
+
+                mode_raw(1);
+
+                c = getchar();
+
+                mode_raw(0);
+
+                switch (c)
+                {
+                case 'o':
+                {
+
+                    // On pointe l'objet
+
+                    Goto(DHMS(Etoiles[i].ad * N180divPi, true), DHMS(Etoiles[i].de * N180divPi, false), Transit, true);
+
+                    AfficherLog("Goto en cours... Veuillez attendre la fin du mouvement\n\n", true);
+
+
+                    // on incrÃ©mente le compteur qui est l'indice de sauvegarde des donnÃ©es de calibration
+                    // dans le tableau AlignementAntenne
+
+                    Antennes[num].AlignementAntenne->nbrcorrections++;
+
+                    // On sauvegarde les coordonnÃ©es de l'objet qui servira Ã  la calibration de l'antenne num
+
+                    Antennes[num].AlignementAntenne->ad[Antennes[num].AlignementAntenne->nbrcorrections]  = Etoiles[i].ad;
+                    Antennes[num].AlignementAntenne->de[Antennes[num].AlignementAntenne->nbrcorrections]  = Etoiles[i].de;
+
+                    do
+                    {
+
+                        cout << "Appuyez sur les touches Z,Q,D,X pour centrer l'objet dans le viseur.\n";
+                        cout << "Appuyez sur S pour changer de vitesse et sur A pour envoyer un ABORT Ã  l'antenne.\n";
+                        cout << "Appuyez sur G pour reprendre le suivi de l'objet aprÃšs un ABORT ou un message d'erreur.\n";
+                        cout << "(A la fin de l'opÃ©ration, appuyez sur ESC pour arrÃªter et valider).\n\n";
+
+                        mode_raw(1);
+
+                        c = getchar();
+
+                        mode_raw(0);
+
+                        // pause de 10ms
+
+                        usleep(10000);
+
+                        // Gestion des touches du clavier. On modifie l'orientation de l'instrument
+                        // sur les axes AD et Dec...
+                        // On sauvegarde Ã©galement le temps sidÃ©ral local. Ceci nous permettra de calculer
+                        // l'angle horaire de l'objet pointÃ©
+
+                        UpdateTime();
+
+                        switch (c)
+                        {
+                        case 'z' :
+                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
+                            Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] += Vitesse;
+                            ModificationAlignement = true;
+                            AfficherLog("Dec = " + DHMS((Antennes[num].AlignementAntenne->de[Antennes[num].AlignementAntenne->nbrcorrections]
+                                                         + Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaDe )
+                                                        * N180divPi, false) + "\n\n", true);
+                            break;
+
+                        case 'd' :
+                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
+                            Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] += Vitesse;
+                            ModificationAlignement = true;
+                            AfficherLog("AD = " + DHMS((VerifAngle( Antennes[num].AlignementAntenne->ad[Antennes[num].AlignementAntenne->nbrcorrections]
+                                                                    + Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaAD ) )
+                                                       * N180divPi, true) + "\n\n", true);
+                            break;
+
+                        case 'q' :
+
+                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
+                            Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] -= Vitesse;
+                            ModificationAlignement = true;
+                            AfficherLog("AD = " + DHMS((VerifAngle( Antennes[num].AlignementAntenne->ad[Antennes[num].AlignementAntenne->nbrcorrections]
+                                                                    + Antennes[num].AlignementAntenne->delta_ad[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaAD ) )
+                                                       * N180divPi, true) + "\n\n", true);
+                            break;
+
+                        case 'x' :
+                            Antennes[num].AlignementAntenne->tsl[Antennes[num].AlignementAntenne->nbrcorrections] = GetTSL();
+                            Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] -= Vitesse;
+                            ModificationAlignement = true;
+                            AfficherLog("Dec = " + DHMS((Antennes[num].AlignementAntenne->de[Antennes[num].AlignementAntenne->nbrcorrections]
+                                                         + Antennes[num].AlignementAntenne->delta_de[Antennes[num].AlignementAntenne->nbrcorrections] * PasDeltaDe )
+                                                        * N180divPi, false) + "\n\n", true);
+                            break;
+
+                        case 'a' :
+                            Abort();
+                            sleep(2);
+
+                            break;
+
+                        case 's' :
+                            (Vitesse == 1 ) ? Vitesse = 10 : Vitesse = 1;
+                            os << "Vitesse=" << Vitesse << "x\n\n";
+                            AfficherLog(&os,  true);
+
+                            break;
+
+                        case 'g' :
+                            AfficherLog("Reprise du GOTO.\n\n", true);
+                            Goto(DHMS(Etoiles[i].ad * N180divPi, true), DHMS(Etoiles[i].de * N180divPi, false), Transit, true);
+                            sleep(2);
+
+                            break;
+                        }
+
+                        //touche ESC -> on sort
+                    } while (c!=27);
+                }
+                break;
+
+                case 'f':
+                {
+                    // on sort de la boucle en cas d'appuie sur la touche f
+                    i = numEtoiles;
+                }
+                break;
+                }
+            }
+        }
+
+        AfficherLog("\nFin de la procÃ©dure d'alignement.\n\n", true);
+
+        // On indique au reste du programme que la calibration sur l'antenne num est terminÃ©e
+
+        Antennes[num].AlignementAntenne->AlignementEnCours = false;
+
+        ModificationAlignement=true;
+    }
+    else
+    {
+        ErreurLog("L'antenne situÃ©e Ã  l'adresse ip indiquÃ©e n'existe pas\n\n");
+
+        return false;
     }
 
@@ -1208,216 +1625,6 @@
 
 /**************************************************************************************
-** Lecture des mouvements planifiÃ©s contenus dans le fichier fileName
-***************************************************************************************/
-
-bool BAOcontrol::LectureFichierMouvements(string fileName)
-{
-    string section;
-    string key;
-    char * value   = NULL;
-
-    stringstream os;
-    float a1, a2, a3, h;
-
-    numobjets=1;
-
-    Affiche("Lecture du fichier " + fileName +"\n\n", true);
-
-    //Lecture de la rubrique ParamÃštres
-
-    section = "parametres";
-    key     = "mode";
-
-    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-    {
-        Transit = ( strstr(value, "transit") != NULL);
-        delete [] value;
-
-        if (Transit) Affiche("Mode transit activÃ©.\n", true);
-        else Affiche("Mode tracking activÃ©.\n", true);
-    }
-    else
-    {
-        Erreur("Le parametre mode est incorrect.\n");
-        return false;
-    }
-
-    key = "J2000";
-
-    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-    {
-        J2000 = ( strstr(value, "on") != NULL);
-        delete [] value;
-
-        if (J2000) Affiche("Mode J2000 activÃ©.\n\n", true);
-        else Affiche("Mode J2000 dÃ©sactivÃ©.\n\n", true);
-    }
-    else
-    {
-        Erreur("Le parametre J2000 est incorrect.\n");
-        return false;
-    }
-
-    // Lecture de la liste des observations
-
-    section = "objet 1";
-    key     = "date";
-
-
-    while ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-            && (numobjets<MAXOBJETS))
-    {
-        os << "object nÂ°" << numobjets << endl;
-        Affiche(&os, true);
-        delete [] value;
-        value = NULL;
-
-
-        // Lecture de la date et de l'heure de l'observation
-
-        key = "date";
-
-        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-                && (Decomposition(value, 3, &a1, &a2, &a3)))
-        {
-            Affiche("Date du dÃ©but de l'observation : le " + (string)value, true);
-            delete [] value;
-            value = NULL;
-
-            objets[numobjets].JJ = CalculJJ(a3, a2, a1, 0.0);
-        }
-        else
-        {
-            os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
-            Erreur(&os);
-            return false;
-        }
-
-        key = "heure";
-
-        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-                && (Decomposition(value, 2, &a1, &a2, &a3)))
-        {
-            Affiche(" Ã  " + (string)value, true) ;
-            delete [] value;
-            value = NULL;
-
-
-            objets[numobjets].JJ += ( a1 + a2 / 60.0 + a3 / 3600.0 ) / 24.0;
-
-            os << " TU  -> JJ=" << fixed << objets[numobjets].JJ << scientific << endl;
-
-            Affiche(&os, true);
-
-            for (int i=1; i<numobjets; i++)
-            {
-                if (objets[i].JJ==objets[numobjets].JJ)
-                {
-                    os << "Attention, les observations des objets " << i << " et ";
-                    os << numobjets << " sont dÃ©finies Ã  la mÃªme date !" << endl;
-                    Erreur(&os);
-                }
-
-                if (objets[i].JJ+objets[i].Duree/3600/24.0>objets[numobjets].JJ)
-                {
-                    os << "Attention, les observations des objets " << i << " et " ;
-                    os << numobjets << " se chevauchent !" << endl;
-                    Erreur(&os);
-                }
-            }
-        }
-        else
-        {
-            os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
-            Erreur(&os);
-            return false;
-        }
-
-
-        // Lecture de la durÃ©e de l'observation
-
-        key = "duree";
-
-        objets[numobjets].Duree=0.0;
-
-        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-        {
-            Affiche("DurÃ©e de l'observation : " + (string)value + " secondes\n", true);
-            objets[numobjets].Duree=atof(value);
-            delete [] value;
-            value = NULL;
-        }
-        else
-        {
-            os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !\n";
-            Erreur(&os);
-            return false;
-        }
-
-        // Lecture de l'ascension droite de l'objet
-
-        key = "ad";
-
-        objets[numobjets].ad = "";
-
-        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-                && (Decomposition(value, 2, NULL, NULL, NULL)))
-        {
-            Affiche("Ascension droite de l'objet : " + (string)value + "\n", true);
-            objets[numobjets].ad = value;
-            delete [] value;
-            value = NULL;
-        }
-        else
-        {
-            os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !";
-            os << endl;
-            Erreur(&os);
-            return false;
-        }
-
-        // Lecture de la dÃ©clinaison de l'objet
-
-        key = "de";
-
-        objets[numobjets].de = "";
-
-        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
-                && (Decomposition(value, 0, NULL, NULL, NULL)))
-        {
-            Affiche("DÃ©clinaison de l'objet : " + (string)value + "\n\n", true);
-            objets[numobjets].de = value;
-            delete [] value;
-            value = NULL;
-        }
-        else
-        {
-            os << "La dÃ©clinaison de la rubrique [objet " << numobjets << "] est incorrecte !";
-            os << endl;
-            Erreur(&os);
-            return false;
-        }
-
-        objets[numobjets].exec = false;
-
-        // On passe Ã  l'objet suivant
-
-        numobjets++;
-
-        os << "objet "<< numobjets;
-
-        section = os.str();
-        os.str("");
-    }
-
-    if (value) delete [] value;
-
-    return true;
-}
-
-
-
-/**************************************************************************************
-** Execute le fichier de mouvements
+** Lance l'executution d'un fichier de mouvements
+**
 ***************************************************************************************/
 
@@ -1428,5 +1635,5 @@
     bool exec = LectureFichierMouvements(fichier);
 
-    Update();
+    UpdateTime();
 
     if ( exec && numobjets>1 )
@@ -1436,18 +1643,20 @@
         if (objets[numobjets-1].JJ + objets[numobjets-1].Duree / 3600.0 / 24.0 < GetJJ())
         {
-            Erreur("Le fichier contient des dates qui sont toutes pÃ©rimÃ©es. ExÃ©cution annulÃ©e.\n\n");
-            NoExit=!exitrun;
+            ErreurLog("Le fichier contient des dates qui sont toutes pÃ©rimÃ©es. ExÃ©cution annulÃ©e.\n\n");
+            NoExit = !exitrun;
+
             return false;
         }
         else
         {
-            Affiche("Execution du fichier " + fichier + " en attente...\n\n", true);
-            run=true;
+            AfficherLog("Execution du fichier " + fichier + " en attente...\n\n", true);
+            run = true;
         }
     }
     else
     {
-        Erreur("\nLe fichier " + fichier + " contient des erreurs ou n'existe pas...\n\n\n");
+        ErreurLog("\nLe fichier " + fichier + " contient des erreurs ou n'existe pas...\n\n\n");
         NoExit=!exitrun;
+
         return false;
     }
@@ -1461,11 +1670,12 @@
 ** DÃ©composition et vÃ©rification des dates, heures, AD et dÃ©clinaisons
 **
-** type = 0 -> DÃ©clinaison/latitude
+** type = 0 -> chaine contient une dÃ©clinaison ou une latitude
 ** type = 1 -> longitude
 ** type = 2 -> AD ou heure
 ** type = 3 -> date
 **
-** Exemple de Decomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12
+** Exemple de DÃ©composition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12
 ** si la chaine a un format incorrect, la fct retourne false
+**
 ***************************************************************************************/
 
@@ -1473,16 +1683,19 @@
 {
     string car, s;
+
     float a, b, c;
 
     // pour les heures et les coordonnÃ©es, on attend ":" comme caractÃšre sÃ©parateur, sinon
-    // on attend d'avoir des "/" pour une date
-
-    (type==3) ? car="/" : car=":";
+    // on attend d'avoir des caractÃšres "/" entre chaque Ã©lÃ©ments pour une date
+
+    (type == 3) ? car="/" : car=":";
 
     // Y a-t-il 2 caractÃšres ':' ou '/' dans la chaine ?
     // C'est indispensable dans tous les cas
 
-    int test=0;
+    int test = 0;
+
     for (int i=0; i<chaine.length(); i++) if (chaine[i] == car[0]) test++;
+
     if (test<2) return false;
 
@@ -1493,5 +1706,5 @@
     a = atoi(s.c_str());
 
-    s = chaine.substr(chaine.find(car)+1, chaine.rfind(car) - chaine.find(car) - 1);
+    s = chaine.substr(chaine.find(car) + 1, chaine.rfind(car) - chaine.find(car) - 1);
 
     b = atoi(s.c_str());
@@ -1499,5 +1712,7 @@
     s = chaine.substr(chaine.rfind(car)+1);
 
-    c = Arrondi(atof(s.c_str())*100.0)/100.0;
+    // 12.125454414 sec  -> 12.125 sec
+
+    c = Arrondi(atof(s.c_str()) * 100.0) / 100.0;
 
     //vÃ©rification de la cohÃ©rence des infos contenues dans la chaine
@@ -1506,25 +1721,25 @@
     {
         // pour une dÃ©clinaison
-        if ((type==0) && (a>90.0  || a<-90.0)) return false;
+        if (( type == 0 ) && ( a>90.0  || a<-90.0 )) return false;
         // pour une AD
-        if ((type==1) && (a>360.0 || a<0.0  )) return false;
+        if (( type == 1 ) && ( a>360.0 || a<0.0   )) return false;
         // pour une heure
-        if ((type==2) && (a>23.0  || a<0.0  )) return false;
+        if (( type == 2 ) && ( a>23.0  || a<0.0   )) return false;
         // pour les minutes
-        if (b<0.0 || b>59.0 ) return false;
+        if ( b < 0.0 || b> 59.0 ) return false;
         //pour les secondes
-        if (c<0.0 || c>=60.0) return false;
+        if ( c < 0.0 || c>=60.0 ) return false;
     }
     else
     {
         //pour les jours
-        if (a<0.0 || a>31.0) return false;
+        if ( a < 0.0 || a > 31.0 ) return false;
         //pour les mois
-        if (b<0.0 || b>12.0) return false;
-    }
-
-    if (a1!=NULL) *a1 = a;
-    if (a2!=NULL) *a2 = b;
-    if (a3!=NULL) *a3 = c;
+        if ( b < 0.0 || b > 12.0 ) return false;
+    }
+
+    if ( a1 != NULL ) *a1 = a;
+    if ( a2 != NULL ) *a2 = b;
+    if ( a3 != NULL ) *a3 = c;
 
     return true;
@@ -1537,4 +1752,5 @@
 ** identification des commandes entrÃ©es par l'utilisateur
 ** puis exÃ©cution des commandes
+**
 ***************************************************************************************/
 
@@ -1544,6 +1760,7 @@
     stringstream os;
 
-    // Permet de savoir si la derniÃšre saisie de l'utilisateur
+    // Permet de savoir si la derniÃšre commande saisie par l'utilisateur
     // est une commande valide
+
     bool CommandeOK = false;
 
@@ -1553,5 +1770,4 @@
     if ( chaine.find("goto") != string::npos )
     {
-        CommandeOK = true;
 
         // L'utilisateur a fait suivre la commande goto de l'indication J2000
@@ -1559,14 +1775,18 @@
         if (J2000 = (chaine.find("j2000") != string::npos))
         {
-            Affiche("Prise en compte de la prÃ©cession, de la nutation et de l'aberration...\n", true);
-
-            // On je garde que la premiÃšre partie de la chaine avant J2000
+            AfficherLog("Prise en compte de la prÃ©cession, de la nutation et de l'aberration...\n", true);
+
+            // On ne garde que la premiÃšre partie de la chaine (avant le mot "J2000")
 
             chaine = chaine.substr(0, chaine.find("J2000"));
         }
 
-        if (DecompositionCommande(chaine, "goto", &ar, &de) && Decomposition(ar, 2, NULL, NULL, NULL) && Decomposition(de, 0, NULL, NULL, NULL))
+        if (DecompositionCommande(chaine, "goto", &ar, &de) &&
+                Decomposition(ar, 2, NULL, NULL, NULL) &&
+                Decomposition(de, 0, NULL, NULL, NULL))
         {
             // L'utilisateur a indiquÃ© deux coordonnÃ©es valides -> on exÃ©cute le goto
+
+            CommandeOK = true;
 
             Goto(ar, de, Transit, J2000);
@@ -1577,32 +1797,53 @@
             // puis on envoie les coordonnÃ©es de l'objet au pilote indi_BAO
 
+            CommandeOK = true;
+
             if ((DecompositionCommande(chaine, "goto", &objet, NULL)) && (chaine.find(":") == string::npos))
             {
-                Coordonnees reponse;
-		
-		if (objet != "sun")
-		{
-		    reponse = ServeurNED(objet);
-		    
-		    if (reponse.ar!="" && reponse.dec!="")  Goto(reponse.ar, reponse.dec, Transit, true);
-		}
-		else
-		{   
-		    printf(" lancement\n");
-		   
-		    CalculARDecSoleil(&reponse);
-		    
-		    printf("%s   %s \n", reponse.ar.c_str(), reponse.dec.c_str());
-		    
-		    Goto(reponse.ar, reponse.dec, Transit, false);
-		}                
+                CoordonneesHoraires reponse;
+
+                if (objet != "sun")
+                {
+                    bool CestUneEtoile = false;
+
+                    for (int i=0; i<numEtoiles; i++)
+                    {
+                        if (objet == Etoiles[i].nom)
+                        {
+                            AfficherLog(Etoiles[i].nom + "\n", true);
+
+                            Goto( DHMS(Etoiles[i].ad*N180divPi, true), DHMS(Etoiles[i].de*N180divPi, false), Transit, true);
+
+                            CestUneEtoile = true;
+
+                            break;
+                        }
+                    }
+
+                    if (!CestUneEtoile)
+                    {
+                        reponse = ServeurNED(objet);
+
+                        if (reponse.ar!="" && reponse.dec!="")  Goto(reponse.ar, reponse.dec, Transit, true);
+                    }
+                }
+                else
+                {
+                    printf(" lancement\n");
+
+                    CalculARDecSoleil(&reponse);
+
+                    printf("%s   %s \n", reponse.ar.c_str(), reponse.dec.c_str());
+
+                    Goto(reponse.ar, reponse.dec, Transit, false);
+                }
             }
             else
             {
-                Erreur("Erreur goto : le format de la commande est goto AD DEC\n \
-                    L AD doit Ãªtre de la forme xx:yy:zz   (ex: 12:00:03 pour 12h 0m 3s)\n \
-                    La dÃ©clinaison doit Ãªtre de la forme +/-xx:yy:zz (ex: -12:50:01 pour -12Â° 50' 01'')\n\n \
+                ErreurLog("Erreur goto : le format de la commande est goto AD DEC\n \
+                    L'AD doit Ãªtre de la forme xx:yy:zz   (ex: 12:00:03 pour 12h 0m 3s)\n \
+                    La dÃ©clinaison doit Ãªtre de la forme +/-xx:yy:zz (ex: -12:50:01.1 pour -12Â° 50' 01.1'')\n\n \
                     Il est egalement possible de faire suivre la commande d'un nom d'un objet\n \
-                    Exemple goto M 31 ou encore goto ngc145\n \
+                    Exemple goto M 31 ou encore goto ngc145.\n \
                     Ne pas prÃ©ciser dans ce cas J2000.\n\n");
             }
@@ -1622,9 +1863,9 @@
         if (chaine.find("run") != string::npos)
         {
-            run=false;
-            runnum=1;
-            numobjets=1;
-
-            Affiche("Annulation de l'exÃ©cution du fichier de mouvements.\n\n", true);
+            run       = false;
+            runnum    = 1;
+            numobjets = 1;
+
+            AfficherLog("Annulation de l'exÃ©cution du fichier de mouvements.\n\n", true);
 
             return;
@@ -1644,5 +1885,5 @@
         else
         {
-            Erreur("Erreur run : la commande run doit Ãªtre suivie par un nom de fichier.\n\n");
+            ErreurLog("Erreur run : la commande run doit Ãªtre suivie par un nom de fichier.\n\n");
         }
     }
@@ -1657,64 +1898,65 @@
     }
 
-    // Active le mode de suivi "transit"
-
-    if (chaine.find("transit") != string::npos)
+
+
+    // Place les antennes en position de repos
+
+    if (chaine.find("park") != string::npos)
     {
         CommandeOK = true;
 
-        Affiche("Mode transit activÃ©.\n\n", true);
-
-        Transit=true;
-    }
-
-    // Active le mode de suivi "tracking"
-
-    if (chaine.find("tracking") != string::npos)
+        Park();
+    }
+
+    // interroge un serveur de temps pour mettre l'horloge du PC Ã  jour
+
+    if (chaine.find("updatetime") != string::npos)
     {
         CommandeOK = true;
 
-        Affiche("Mode tracking activÃ©.\n\n", true);
-
-        Transit=false;
-    }
-
-    // Place les antennes en position de repos
-
-    if (chaine.find("park") != string::npos)
+        int rc = system("sntp -s fr.pool.ntp.org");
+
+        if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
+        {
+            ErreurLog("La commande sntp n'est pas accessible. Merci de vÃ©rifier.\n\n");
+        }
+    }
+
+    // Affiche tous les paramÃštres du programme
+
+    if (chaine.find("status") != string::npos)
     {
         CommandeOK = true;
 
-        Park();
-    }
-
-    // interroge un serveur de temps pour mettre l'horloge du PC Ã  jour
-
-    if (chaine.find("updatetime") != string::npos)
-    {
-        CommandeOK = true;
-
-        int rc = system("sntp -s fr.pool.ntp.org");
-
-        if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
-        {
-            Erreur("La commande sntp n'est pas accessible. Merci de vÃ©rifier.\n\n");
-        }
-    }
-
-    // Affiche tous les paramÃštres du programme
-
-    if (chaine.find("status") != string::npos)
-    {
-        CommandeOK = true;
-
-        os << "Latitude = " << (string)LatitudeChar << "\n";
-        os << "Longitude = " << (string)LongitudeChar << "\n\n";
-        os << "Serveur Indi = " << (string)Serveur << "\n";
+        os << "Latitude = " << LatitudeChar << "\n";
+        os << "Longitude = " << LongitudeChar << "\n\n";
+        os << "Serveur Indi = " << Serveur << "\n";
         os << "Port du serveur Indi = " << Port << "\n\n";
         os << "Pression atmosphÃ©rique  = " << Pression << " mBar\n";
         os << "TempÃ©rature = " << Temperature << " Â°C\n\n";
-        Affiche(&os, true);
-        if (Transit) Affiche("Mode Transit activÃ©.\n\n", true);
-        else Affiche ("Mode Tracking activÃ©.\n\n", true);
+
+        os << "Antennes connectÃ©es : " << numAntennes << "\n\n";
+        os << "Mode ";
+        (Transit) ? os << "transit" : os << "tracking";
+        os << " activÃ©.\n\n";
+        os << "DurÃ©e entre deux actualisations : ";
+        (Transit) ? os << delaitransit : os << delaitracking;
+        os << " sec(s)\n\n";
+        os << "MÃ©thode d'alignement : ";
+        switch (MethodeAlignement)
+        {
+        case SIMPLE :
+            os << "simple\n";
+            break;
+        case AFFINE :
+            os << "affine\n";
+            break;
+        case TAKI   :
+            os << "taki\n";
+            break;
+        }
+        os << "\n\n";
+
+        AfficherLog(&os, true);
     }
 
@@ -1725,12 +1967,30 @@
         string objet;
 
+        bool CestUneEtoile = false;
+
         CommandeOK = true;
 
         if (DecompositionCommande(chaine, "search", &objet, NULL))
         {
-            ServeurNED(objet);
-        }
-    }
-    
+            for (int i=0; i<numEtoiles; i++)
+            {
+                if (objet == Etoiles[i].nom)
+                {
+                    os << Etoiles[i].nom << "\n";
+                    os << "AD (J2000) = " << DHMS(Etoiles[i].ad*N180divPi, true) << "\n";
+                    os << "Dec (J2000) = " << DHMS(Etoiles[i].de*N180divPi, false) << "\n";
+                    AfficherLog(os.str(), true);
+
+                    CestUneEtoile = true;
+
+                    break;
+                }
+            }
+
+            if (!CestUneEtoile) ServeurNED(objet);
+        }
+    }
+
+
     // correction de l'alignement d'une antenne par rapport Ã  l'objet visÃ©
 
@@ -1743,11 +2003,201 @@
         if (DecompositionCommande(chaine, "align", &antenne, NULL))
         {
-            Alignement(antenne);
+            AlignementAntenneIP(antenne);
         }
         else
         {
-            Erreur("Erreur align : la commande align doit Ãªtre suivie par l'ip de l'antenne qui faut aligner.\n\n");
-        }
-    }
+            ErreurLog("Erreur align : la commande align doit Ãªtre suivie par l'ip de l'antenne qui faut aligner.\n\n");
+        }
+    }
+
+
+    // RÃ©initialisation de l'alignement d'une antenne
+
+    if (chaine.find("reset")!=string::npos)
+    {
+        string ip;
+
+        CommandeOK = true;
+
+        int num;
+
+        if (DecompositionCommande(chaine, "reset", &ip, NULL))
+        {
+            bool test = false;
+
+            // On sÃ©lectionne la bonne antenne (Ã  partir de son adresse ip).
+
+            if (ip.rfind(".") != string::npos) ip = ip.substr(ip.rfind(".")+1);
+
+            for (num=0; num<numAntennes; num++)
+            {
+                if (atoi(ip.c_str()) == Antennes[num].ip) {
+
+                    test = true;
+
+                    break;
+                }
+            }
+
+            // on a identifiÃ© l'antenne
+
+            if ((test) && (atoi(ip.c_str()) != 0))
+            {
+                // initialisation des paramÃštres de l'alignement de l'antenne numAntennes
+
+                Antennes[num].AlignementAntenne->InitAlignement();
+
+                ModificationAlignement = true;
+
+                AfficherLog("Les paramÃštres d'alignement de l'antenne " + ip +" ont Ã©tÃ© rÃ©initialisÃ©s.\n\n", true);
+            }
+            else
+            {
+                AfficherLog("L'antenne indiquÃ©e ne semble pas connectÃ©e.\n\n", true);
+            }
+        }
+        else
+        {
+            ErreurLog("Erreur reset : la commande reset doit Ãªtre suivie par l'ip de l'antenne qu'il faut aligner.\n\n");
+        }
+    }
+
+
+    // Commande set
+
+    if (chaine.find("set") != string::npos)
+    {
+        string commande, commande2, commande3;
+
+        // est-ce que la commande commande par set ! -> si oui, la variable commande contient alors le reste de
+        // la phrase saisie par l'utilisateur
+
+        if (DecompositionCommande(chaine, "set", &commande, NULL))
+        {
+            // A-t-on set transit xxxx ?
+
+            if (DecompositionCommande(commande, "transit", &commande2, &commande3))
+            {
+                //at-ton set transit delay xxx ?
+
+                if (commande2 == "delay")
+                {
+                    if (atoi(commande3.c_str()) > 0)
+                    {
+                        CommandeOK = true;
+
+                        delaitransit = atoi(commande3.c_str());
+
+                        EnvoyerDelaisModesTransitEtTracking();
+
+                        AfficherLog("Delai entre deux actualisations en mode transit : " + commande3 + "\n\n" , true);
+                    }
+                    else
+                    {
+                        AfficherLog("Le nombre qui suit le mot clÃ© delay doit Ãªtre entier et > 0  \n\n" , true);
+                    }
+                }
+
+                // Active le mode de suivi "transit"
+
+                if (commande2 == "on")
+                {
+                    CommandeOK = true;
+
+                    AfficherLog("Mode transit activÃ©.\n\n", true);
+
+                    Transit = true;
+                }
+            }
+
+            // a-t-on set tracking xxxx ?
+
+            if (DecompositionCommande(commande, "tracking", &commande2,  &commande3))
+            {
+                // a-ton set tracking delay xxx ?
+
+                if (commande2 == "delay")
+                {
+                    if (atoi(commande3.c_str())>0)
+                    {
+                        CommandeOK = true;
+
+                        delaitracking = atoi(commande3.c_str());
+
+                        EnvoyerDelaisModesTransitEtTracking();
+
+                        AfficherLog("Delai entre deux actualisations en mode tracking : " + commande3 + "\n\n" , true);
+                    }
+                    else
+                    {
+                        AfficherLog("Le nombre qui suit le mot clÃ© delay doit Ãªtre entier et > 0  \n\n" , true);
+                    }
+                }
+
+                // Active le mode de suivi "transit"
+
+                if (commande2 == "on")
+                {
+                    CommandeOK = true;
+
+                    AfficherLog("Mode tracking activÃ©.\n\n", true);
+
+                    Transit = false;
+                }
+            }
+
+            // A-t-on set alignment ?
+
+            if (DecompositionCommande(commande, "alignment", &commande2,  &commande3))
+            {
+
+                // A-ton set alignment method xxx ?
+
+                if (commande2 == "method")
+                {
+                    MethodeAlignement = NONE;
+
+                    if (commande3 == "simple") MethodeAlignement = SIMPLE;
+                    if (commande3 == "affine") MethodeAlignement = AFFINE;
+                    if (commande3 == "taki")   MethodeAlignement = TAKI;
+
+                    if (MethodeAlignement == NONE )
+                    {
+                        MethodeAlignement = SIMPLE;
+
+                        AfficherLog("Erreur: la syntaxe doit Ãªtre 'set alignment method x' avec x = simple/affine/taki)\n\n" , true);
+                    }
+                    else
+                    {
+                        CommandeOK = true;
+
+                        EnvoyerMethodeAlignement();
+
+                        switch (MethodeAlignement)
+                        {
+                        case  SIMPLE :
+                            AfficherLog("Activation de la mÃ©thode d'alignement simple\n\n", true);
+                            break;
+                        case  AFFINE :
+                            AfficherLog("Activation de la mÃ©thode d'alignement affine\n\n", true);
+                            break;
+                        case  TAKI :
+                            AfficherLog("Activation de la mÃ©thode d'alignement taki\n\n", true);
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    AfficherLog("Erreur: la syntaxe doit Ãªtre 'set alignment method x' avec x = simple/affine/taki)\n\n" , true);
+                }
+            }
+        }
+    }
+
+
+
+
+
 
     // Aide du programme
@@ -1759,30 +2209,34 @@
         cout << endl;
 
-        cout << "connect :           se connecte au pilote indi_BAO." << endl;
-        cout << "disconnect :        se dÃ©connecte du pilote indi_BAO." << endl;
-        cout << "goto AD Dec :       pointe l'objet situÃ© aux coordonnÃ©es apparentes AD Dec." << endl;
-        cout << "                    AD doit Ãªtre au format xx:yy:zz et dec au format +/-xx:yy:zz" << endl;
-        cout << "                    exemple goto 12:10:05 -05:10:11 permettra de pointer l'objet" << endl;
-        cout << "                    situÃ© aux coordonnÃ©es AD=12h10m5s et dec=-5Â°10'11''" << endl;
-        cout << "goto AD Dec J2000 : pointe l'objet situÃ© aux coordonnÃ©es AD Dec dans le repÃšre J2000." << endl;
-        cout << "                    Avant de pointer l'objet, le programme calcule la prÃ©cession, la nutation et l'aberration" << endl;
-        cout << "                    pour ramener les coordonnÃ©es Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe de l'observation." << endl;
-        cout << "goto nom_objet :    interroge la base NED pour trouver les coordonnÃ©es de l'objet puis le pointe." << endl;
-        cout << "                    exemples: goto m 31, goto messier 1, goto ngc 175, goto ic 434 etc..." << endl;
-        cout << "                    Dans ce mode, les coordonnÃ©es sont automatiquement rapportÃ©es" << endl;
-        cout << "                    Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe de l'observation." << endl;
-        cout << "                    Aussi, merci de ne pas faire suivre les coordonnÃ©es de l'indication J2000."<< endl;
-        cout << "                    Goto sun permet de suivre le soleil." << endl;
-        cout << "search nom_objet :  interroge le serveur NED sur internet et retourne les coordonnÃ©es de l'objet." << endl;
-	cout << "align ip :          lance la procÃ©dure d'alignement de l'antenne d'adresse ip." << endl;
-        cout << "transit :           active le mode de suivi transit." << endl;
-        cout << "tracking :          active le mode de suivi tracking." << endl;
-        cout << "status :            liste les paramÃštres du programme." << endl;
-        cout << "run filename :      exÃ©cute le fichier de mouvements filename." << endl;
-        cout << "abort run :         annule l'exÃ©cution du fichier de mouvements." << endl;
-        cout << "abort :             annule le mouvement en cours." << endl;
-        cout << "park :              place les antennes en position de repos." << endl;
-        cout << "updatetime :        synchronise l'horloge du PC avec un serveur de temps." << endl;
-        cout << "exit :              sortir de BAOControl." << endl;
+        cout << "connect :                Se connecte au pilote indi_BAO." << endl;
+        cout << "disconnect :             Se dÃ©connecte du pilote indi_BAO." << endl;
+        cout << "goto AD Dec :            Pointe l'objet situÃ© aux coordonnÃ©es apparentes AD Dec." << endl;
+        cout << "                         AD doit Ãªtre au format xx:yy:zz et dec au format +/-xx:yy:zz" << endl;
+        cout << "                         exemple goto 12:10:05 -05:10:11 permettra de pointer l'objet" << endl;
+        cout << "                         situÃ© aux coordonnÃ©es AD=12h10m5s et dec=-5Â°10'11''" << endl;
+        cout << "goto AD Dec J2000 :      Pointe l'objet situÃ© aux coordonnÃ©es AD Dec dans le repÃšre J2000." << endl;
+        cout << "                         Avant de pointer l'objet, le programme calcule la prÃ©cession, la nutation et l'aberration" << endl;
+        cout << "                         pour ramener les coordonnÃ©es Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe de l'observation." << endl;
+        cout << "goto nom_objet :         Interroge la base NED pour trouver les coordonnÃ©es de l'objet puis le pointe." << endl;
+        cout << "                         exemples: goto m 31, goto messier 1, goto ngc 175, goto ic 434 etc..." << endl;
+        cout << "                         Dans ce mode, les coordonnÃ©es sont automatiquement rapportÃ©es" << endl;
+        cout << "                         Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe de l'observation." << endl;
+        cout << "                         Aussi, merci de ne pas faire suivre les coordonnÃ©es de l'indication J2000."<< endl;
+        cout << "                         Goto sun permet de suivre le soleil." << endl;
+        cout << "search nom_objet :       Interroge le serveur NED sur internet et retourne les coordonnÃ©es de l'objet." << endl;
+        cout << "align ip :               Lance la procÃ©dure d'alignement de l'antenne d'adresse ip." << endl;
+        cout << "reset ip :               RÃ©initialise les paramÃštres d'alignement de l'antenne d'adresse ip." << endl;
+        cout << "set transit on :         Active le mode de suivi transit." << endl;
+        cout << "set transit delay x :    Fixe la durÃ©e entre deux actualisations Ã  x seconde(s) dans le mode transit" << endl;
+        cout << "set tracking on :        Active le mode de suivi tracking." << endl;
+        cout << "set tracking delay x :   Fixe la durÃ©e entre deux actualisations Ã  x seconde(s) dans le mode tracking" << endl;
+        cout << "set alignment method x : Aligne les antennes en utilisant la mÃ©thode x (simple/affine/taki)" << endl;
+        cout << "status :                 Liste les paramÃštres du programme." << endl;
+        cout << "run filename :           ExÃ©cute le fichier de mouvements filename." << endl;
+        cout << "abort run :              Annule l'exÃ©cution du fichier de mouvements." << endl;
+        cout << "abort :                  Annule le mouvement en cours." << endl;
+        cout << "park :                   Place les antennes en position de repos." << endl;
+        cout << "updatetime :             Synchronise l'horloge du PC avec un serveur de temps." << endl;
+        cout << "exit :                   Sortir de BAOControl." << endl;
 
         cout << endl;
@@ -1791,9 +2245,11 @@
     // Bye !
 
-    if (chaine.find("exit")!=string::npos)
+    if (chaine.find("exit") != string::npos)
     {
         CommandeOK = true;
 
-        Abort();
+        if ( numAntennes > 0 ) Abort();
+
+        usleep(500000);
 
         Connect(false);
@@ -1804,16 +2260,19 @@
     // La commande n'a pas Ã©tÃ© identifiÃ©e !
 
-    if (!CommandeOK) Erreur("Commande inconnue... Tapez help pour obtenir la liste des commandes disponibles.\n\n");
+    if (!CommandeOK) ErreurLog("Commande inconnue... Tapez help pour obtenir la liste des commandes disponibles.\n\n");
 }
+
 
 
 /**************************************************************************************
 ** Interroge le serveur NED sur internet et retourne les coordonnÃ©es dans le repÃšre J2000
-** Si pas de rÃ©ponse, alors message d'erreur et les coordonnÃ©es sont Ã©gales Ã  AR="" dec=""
+** Si pas de rÃ©ponse, alors message d'erreur et les coordonnÃ©es retournÃ©es sont
+** Ã©gales Ã  AD="" dec=""
+**
 ***************************************************************************************/
 
-Coordonnees BAOcontrol::ServeurNED(string objet)
+CoordonneesHoraires BAOcontrol::ServeurNED(string objet)
 {
-    Coordonnees reponse;
+    CoordonneesHoraires reponse;
     stringstream send;
 
@@ -1833,8 +2292,8 @@
     // Effacer le fichier result s'il existe dans le rÃ©pertoire du programme
 
-    if ((pFile = fopen ("result", "r")) != NULL )
+    if ((pFile = fopen ("result_recherche_bao", "r")) != NULL )
     {
         fclose (pFile);
-        rc = system( "rm result");
+        rc = system( "rm -rf result_recherche_bao");
     }
 
@@ -1842,10 +2301,10 @@
     // On sauvegarde le rÃ©sultat dans le fichier result
 
-    send << "curl >> result \"http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?objname=";
+    send << "curl >> result_recherche_bao \"http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?objname=";
     send << objet;
     send << "&extend=no&hconst=73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0";
     send << "&obj_sort=RA+or+Longitude&of=ascii_bar&zv_breaker=30000.0&list_limit=5&img_stamp=NO\"";
 
-    Affiche("Envoi de la requÃªte au serveur NED...\n", true);
+    AfficherLog("Envoi de la requÃªte au serveur NED...\n", true);
 
     // on lance la requÃªte
@@ -1857,9 +2316,9 @@
     if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
     {
-        Erreur("La commande curl n'est pas accessible. Merci de vÃ©rifier.\n\n");
+        ErreurLog("La commande curl n'est pas accessible. Merci de vÃ©rifier.\n\n");
     }
     else
     {
-        // On a obtenu quelque chose
+        // On a reÃ§u quelque chose
 
         int nbRead = 0;
@@ -1876,5 +2335,5 @@
         // On ouvre le fichier result
 
-        pFile = fopen ("result", "r");
+        pFile = fopen ("result_recherche_bao", "r");
 
         if (pFile)
@@ -1889,5 +2348,5 @@
                     // Le fichier contient une indication d'erreur -> pas de rÃ©ponse exploitable
 
-                    Affiche("\nLe serveur NED n'a pas trouvÃ© de rÃ©ponse Ã  votre demande...\n", true);
+                    AfficherLog("\nLe serveur NED n'a pas trouvÃ© de rÃ©ponse Ã  votre demande...\n", true);
                 }
                 else
@@ -1895,5 +2354,5 @@
                     // on analyse la rÃ©ponse
 
-                    Affiche("\nRÃ©ponse du serveur :\n", true);
+                    AfficherLog("\nRÃ©ponse du serveur :\n", true);
 
                     do
@@ -1905,5 +2364,4 @@
                         {
                             string chaine = (string)pBuf;
-                            string chaine2;
 
                             chaine=chaine.substr(chaine.find('|')+1);
@@ -1911,27 +2369,27 @@
                             // affiche le nom de l'objet dans le serveur NED
 
-                            Affiche(chaine.substr(0, chaine.find('|')) + "\n", true);
+                            AfficherLog(chaine.substr(0, chaine.find('|')) + "\n", true);
 
                             chaine = chaine.substr(chaine.find('|') + 1);
 
+                            string chaine2 = chaine.substr(0, chaine.find('|'));
+
+                            double ar = atof(chaine2.c_str());
+
+                            // affiche l'ascension droite
+
+                            AfficherLog("AD (J2000) = " + DHMS(ar, true) + "\n", true);
+
+                            reponse.ar = DHMS(ar, true);
+
+                            chaine=chaine.substr(chaine.find('|')+1);
+
                             chaine2 = chaine.substr(0, chaine.find('|'));
 
-                            double ar = atof(chaine2.c_str());
-
-                            // affiche l'ascension droite
-
-                            Affiche("AD (J2000) = " + DHMS(ar, true) + "\n", true);
-
-                            reponse.ar = DHMS(ar, true);
-
-                            chaine=chaine.substr(chaine.find('|')+1);
-
-                            chaine2 = chaine.substr(0, chaine.find('|'));
-
                             double dec = atof(chaine2.c_str());
 
                             // on affiche la dÃ©clinaison
 
-                            Affiche("Dec (J2000) = " + DHMS(dec, false)+"\n", true);
+                            AfficherLog("Dec (J2000) = " + DHMS(dec, false)+"\n", true);
 
                             reponse.dec = DHMS(dec, false);
@@ -1945,5 +2403,5 @@
             else
             {
-                Erreur("\nLa connexion semble impossible avec le serveur NED !\n\n");
+                ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n");
             }
 
@@ -1952,10 +2410,10 @@
         else
         {
-            Erreur("\nLa connexion semble impossible avec le serveur NED !\n\n");
+            ErreurLog("\nLa connexion semble impossible avec le serveur NED !\n\n");
         }
 
         delete [] pBuf;
 
-        Affiche("\n", true);
+        AfficherLog("\n", true);
     }
 
@@ -1973,4 +2431,5 @@
 {
     int nbchar = 0;
+
     char c;
 
@@ -2001,4 +2460,5 @@
 /**************************************************************************************
 ** chargement des paramÃštres contenus dans le fichier params
+**
 ***************************************************************************************/
 
@@ -2011,6 +2471,10 @@
 
 
-
-    Affiche("Lecture du fichier de configuration 'params' :\n\n", true);
+    // Si le fichier n'existe pas -> on sort
+
+    if (!is_readable(fileName)) return false;
+
+
+    AfficherLog("Lecture du fichier de configuration 'params' :\n\n", true);
 
 
@@ -2026,10 +2490,11 @@
     {
         LatitudeChar = (string)value;
-        delete [] value;
-        Affiche("latitude = " + LatitudeChar +"\n", true);
+        SAFEDELETE_TAB(value);
+        AfficherLog("latitude = " + LatitudeChar +"\n", true);
     }
     else
     {
-        Erreur("La latitude est incorrecte !\n");
+        ErreurLog("La latitude est incorrecte !\n");
+
         return false;
     }
@@ -2042,10 +2507,11 @@
     {
         LongitudeChar = (string)value;
-        delete [] value;
-        Affiche("longitude = " + LongitudeChar +"\n\n", true);
+        SAFEDELETE_TAB(value);
+        AfficherLog("longitude = " + LongitudeChar +"\n\n", true);
     }
     else
     {
-        Erreur("La longitude est incorrecte !\n");
+        ErreurLog("La longitude est incorrecte !\n");
+
         return false;
     }
@@ -2062,10 +2528,11 @@
     {
         Serveur = (string)value;
-        delete [] value;
-        Affiche("serveur = " + Serveur +"\n", true);
+        SAFEDELETE_TAB(value);
+        AfficherLog("serveur = " + Serveur +"\n", true);
     }
     else
     {
-        Erreur("Nom du serveur invalide !\n");
+        ErreurLog("Nom du serveur invalide !\n");
+
         return false;
     }
@@ -2077,10 +2544,11 @@
     {
         Port = (string)value;
-        delete [] value;
-        Affiche("port = " + Port +"\n\n", true);
+        SAFEDELETE_TAB(value);
+        AfficherLog("port = " + Port +"\n\n", true);
     }
     else
     {
-        Erreur("NumÃ©ro de port incorrect !\n");
+        ErreurLog("NumÃ©ro de port incorrect !\n");
+
         return false;
     }
@@ -2097,12 +2565,13 @@
     {
         Pression = atof(value);
-        delete [] value;
+        SAFEDELETE_TAB(value);
         os << "pression = " << Pression << endl;
-        Affiche(&os, true);
+        AfficherLog(&os, true);
     }
     else
     {
-        os << "La pression atmosph&rique est incorrecte !" << endl;
-        Erreur(&os);
+        os << "La pression atmosphÃ©rique est incorrecte !" << endl;
+        ErreurLog(&os);
+
         return false;
     }
@@ -2112,12 +2581,13 @@
     if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     {
-        Temperature=atof(value);
-        delete [] value;
+        Temperature = atof(value);
+        SAFEDELETE_TAB(value);
         os << "tempÃ©rature = " << Temperature << endl << endl;
-        Affiche(&os, true);
+        AfficherLog(&os, true);
     }
     else
     {
-        Erreur("La tempÃ©rature est incorrecte !\n");
+        ErreurLog("La tempÃ©rature est incorrecte !\n");
+
         return false;
     }
@@ -2134,10 +2604,11 @@
     {
         Transit = (strstr(value, "transit") != NULL);
-        Affiche("mode suivi = " + (string)value + "\n", true);
-        delete [] value;
+        AfficherLog("mode suivi = " + (string)value + "\n", true);
+        SAFEDELETE_TAB(value);
     }
     else
     {
-        Erreur("Le paramÃštre mode est incorrect !\n");
+        ErreurLog("Le paramÃštre mode est incorrect !\n");
+
         return false;
     }
@@ -2149,12 +2620,13 @@
     if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     {
-        delaitransit=atoi(value);
-        delete [] value;
+        delaitransit = atoi(value);
+        SAFEDELETE_TAB(value);
         os << "delai transit = " << delaitransit << " sec" << endl;
-        Affiche(&os, true);
+        AfficherLog(&os, true);
     }
     else
     {
-        Erreur("Le paramÃštre delai_transit est incorrect !\n");
+        ErreurLog("Le paramÃštre delai_transit est incorrect !\n");
+
         return false;
     }
@@ -2165,12 +2637,13 @@
     if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
     {
-        delaitracking=atoi(value);
-        delete [] value;
+        delaitracking = atoi(value);
+        SAFEDELETE_TAB(value);
         os << "delai tracking = " << delaitracking << " sec" << endl << endl;
-        Affiche(&os, true);
+        AfficherLog(&os, true);
     }
     else
     {
-        Erreur("Le paramÃštre delai_tracking est incorrect !\n");
+        ErreurLog("Le paramÃštre delai_tracking est incorrect !\n");
+
         return false;
     }
@@ -2187,10 +2660,10 @@
     {
         ChoixCouleurs=atoi(value);
-        delete [] value;
+        SAFEDELETE_TAB(value);
     }
     else
     {
         /*os << "Le paramÃštre couleurs est incorrect !" << endl;
-        Erreur(os.str());
+        ErreurLog(os.str());
         return false;*/
     }
@@ -2198,4 +2671,379 @@
     return true;
 }
+
+
+
+
+
+
+/**************************************************************************************
+** Lecture des mouvements planifiÃ©s contenus dans le fichier fileName
+** Ces fichiers de mouvement planifiÃ©s permettent des observations automatisÃ©es
+** d'une liste d'objets (ou zone du ciel) pour lesquels on passe de l'un Ã  l'autre
+** en fonction de l'heure
+**
+***************************************************************************************/
+
+bool BAOcontrol::LectureFichierMouvements(string fileName)
+{
+    string section;
+    string key;
+    char * value   = NULL;
+
+    stringstream os;
+    float a1, a2, a3, h;
+
+
+    // Si le fichier n'existe pas -> on sort
+
+    if (!is_readable( fileName )) return false;
+
+    AfficherLog("Lecture du fichier " + fileName +"\n\n", true);
+
+    // initialisation du compteur nombre objets
+
+    numobjets = 1;
+
+    //Lecture de la rubrique ParamÃštres
+
+    section = "parametres";
+
+    // Mode transit ou tracking ?
+
+    key     = "mode";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Transit = ( strstr(value, "transit") != NULL);
+        // il faut dÃ©truire les tableaux de caratÃšres qui sont crÃ©es
+        // dans la fonction ReadINI
+        SAFEDELETE_TAB(value);
+
+        if (Transit) AfficherLog("Mode transit activÃ©.\n", true);
+        else AfficherLog("Mode tracking activÃ©.\n", true);
+    }
+    else
+    {
+        ErreurLog("Le parametre mode est incorrect.\n");
+
+        return false;
+    }
+
+    // Les coordonnÃ©es sont-elles dans le systÃšme de coordonnÃ©es J2000 ?
+
+    key = "J2000";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        J2000 = ( strstr(value, "on") != NULL);
+
+        SAFEDELETE_TAB(value);
+
+        if (J2000) AfficherLog("Mode J2000 activÃ©.\n\n", true);
+        else AfficherLog("Mode J2000 dÃ©sactivÃ©.\n\n", true);
+    }
+    else
+    {
+        ErreurLog("Le parametre J2000 est incorrect.\n");
+
+        return false;
+    }
+
+    // Lecture de la liste des observations
+
+    section = "objet 1";
+    key     = "date";
+
+
+    while ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+            && (numobjets<MAXOBJETS))
+    {
+        os << "object nÂ°" << numobjets << endl;
+        AfficherLog(&os, true);
+
+        SAFEDELETE_TAB(value);
+
+
+        // Lecture de la date et de l'heure de l'observation
+
+        key = "date";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 3, &a1, &a2, &a3)))
+        {
+            AfficherLog("Date du dÃ©but de l'observation : le " + (string)value, true);
+            SAFEDELETE_TAB(value);
+
+            objets[numobjets].JJ = CalculJJ(a3, a2, a1, 0.0);
+        }
+        else
+        {
+            os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
+            ErreurLog(&os);
+
+            return false;
+        }
+
+        key = "heure";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 2, &a1, &a2, &a3)))
+        {
+            AfficherLog(" Ã  " + (string)value, true) ;
+            SAFEDELETE_TAB(value);
+
+
+            objets[numobjets].JJ += ( a1 + a2 / 60.0 + a3 / 3600.0 ) / 24.0;
+
+            os << " TU  -> JJ=" << fixed << objets[numobjets].JJ << scientific << endl;
+
+            AfficherLog(&os, true);
+
+            for (int i=1; i<numobjets; i++)
+            {
+                if ( objets[i].JJ == objets[numobjets].JJ )
+                {
+                    os << "Attention, les observations des objets " << i << " et ";
+                    os << numobjets << " sont dÃ©finies Ã  la mÃªme date !" << endl;
+                    ErreurLog(&os);
+                }
+
+                if ( objets[i].JJ + objets[i].Duree / 3600 / 24.0 > objets[numobjets].JJ )
+                {
+                    os << "Attention, les observations des objets " << i << " et " ;
+                    os << numobjets << " se chevauchent !" << endl;
+                    ErreurLog(&os);
+                }
+            }
+        }
+        else
+        {
+            os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
+            ErreurLog(&os);
+
+            return false;
+        }
+
+
+        // Lecture de la durÃ©e de l'observation
+
+        key = "duree";
+
+        objets[numobjets].Duree=0.0;
+
+        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+        {
+            AfficherLog("DurÃ©e de l'observation : " + (string)value + " secondes\n", true);
+            objets[numobjets].Duree=atof(value);
+            SAFEDELETE_TAB(value);
+        }
+        else
+        {
+            os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !\n";
+            ErreurLog(&os);
+
+            return false;
+        }
+
+        // Lecture de l'ascension droite de l'objet
+
+        key = "ad";
+
+        objets[numobjets].ad = "";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 2, NULL, NULL, NULL)))
+        {
+            AfficherLog("Ascension droite de l'objet : " + (string)value + "\n", true);
+            objets[numobjets].ad = value;
+            SAFEDELETE_TAB(value);
+        }
+        else
+        {
+            os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !";
+            os << endl;
+            ErreurLog(&os);
+
+            return false;
+        }
+
+        // Lecture de la dÃ©clinaison de l'objet
+
+        key = "de";
+
+        objets[numobjets].de = "";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 0, NULL, NULL, NULL)))
+        {
+            AfficherLog("DÃ©clinaison de l'objet : " + (string)value + "\n\n", true);
+            objets[numobjets].de = value;
+            SAFEDELETE_TAB(value);
+        }
+        else
+        {
+            os << "La dÃ©clinaison de la rubrique [objet " << numobjets << "] est incorrecte !";
+            os << endl;
+            ErreurLog(&os);
+
+            return false;
+        }
+
+        objets[numobjets].exec = false;
+
+        // On passe Ã  l'objet suivant
+
+        numobjets++;
+
+        os << "objet "<< numobjets;
+
+        section = os.str();
+
+        os.str("");
+    }
+
+    SAFEDELETE_TAB(value);
+
+    return true;
+}
+
+
+/**************************************************************************************
+** chargement du catalogue d'Ã©toiles nÃ©cessaire Ã  la procÃ©dure d'alignement
+**
+***************************************************************************************/
+
+bool BAOcontrol::ChargementCatalogueEtoiles(string fileName)
+{
+    string section;
+    string key;
+    char * value   = NULL;
+
+    stringstream os;
+    float a1, a2, a3, h;
+
+    // Si le fichier n'existe pas -> on sort !
+
+    if (!is_readable(fileName)) return false;
+
+    AfficherLog("Chargement du catalogue d'Ã©toiles : ", true);
+
+    UpdateTime();
+
+    numEtoiles = 1;
+
+    // Lecture des Ã©toiles
+
+    section = "star 1";
+    key     = "name";
+
+    while (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        // Nom de l'Ã©toile
+
+        Etoiles[numEtoiles].nom = value;
+        SAFEDELETE_TAB(value);
+
+        // On convertit le nom des Ã©toiles en minuscules
+
+        for (int i=0; i<strlen(Etoiles[numEtoiles].nom.c_str()); i++) Etoiles[numEtoiles].nom[i] = tolower(Etoiles[numEtoiles].nom[i]);
+
+
+        //Constellation
+
+        key = "const";
+
+        readINI(section.c_str(), key.c_str(), &value, fileName.c_str());
+
+        Etoiles[numEtoiles].cons = value;
+        SAFEDELETE_TAB(value);
+
+
+        // Lecture des coordonnÃ©es de l'Ã©toile
+
+        key = "ar";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 2, &a1, &a2, &a3)))
+        {
+            SAFEDELETE_TAB(value);
+
+            Etoiles[numEtoiles].ad = (a1 + a2/60.0 + a3/3600.0) * 15.0 * Pidiv180;
+        }
+        else
+        {
+            os << "Les coordonnÃ©es AR de l'Ã©toile " << numEtoiles << " sont incorrectes !" << endl;
+            ErreurLog(&os);
+
+            return false;
+        }
+
+        key = "de";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 0, &a1, &a2, &a3)))
+        {
+            Etoiles[numEtoiles].de = (fabs(a1) + a2/60.0 + a3/3600.0 ) * Pidiv180;
+
+            if (value[0] == '-')  Etoiles[numEtoiles].de = -Etoiles[numEtoiles].de;
+
+            SAFEDELETE_TAB(value);
+        }
+        else
+        {
+            os << "Les coordonnÃ©es DE de l'Ã©toile " << numEtoiles << " sont incorrectes !" << endl;
+            ErreurLog(&os);
+
+            return false;
+        }
+
+
+        // Lecture de la durÃ©e de l'observation
+
+        key = "mag";
+
+        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+        {
+            Etoiles[numEtoiles].mag=(double)atof(value);
+            SAFEDELETE_TAB(value);
+        }
+        else
+        {
+            os << "La magnitude de l'Ã©toile " << numEtoiles << " est incorrecte !\n";
+            ErreurLog(&os);
+
+            return false;
+        }
+
+
+        // Passage du repÃšre J2000 Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe liÃ©e Ã  la date de l'observation
+
+        Precession(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
+        NutationEtoile(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
+        AberrationAnnuelle(&Etoiles[numEtoiles].ad, &Etoiles[numEtoiles].de);
+
+
+        // On passe Ã  l'objet suivant
+
+        numEtoiles++;
+
+        key     = "name";
+
+        os << "star "<< numEtoiles;
+
+        section = os.str();
+
+        os.str("");
+    }
+
+    if (value) SAFEDELETE_TAB(value);
+
+    os << numEtoiles-1 << " Ã©toiles chargÃ©es.\n\n";
+
+    AfficherLog(os.str(), true);
+
+    return true;
+}
+
 
 
@@ -2227,4 +3075,5 @@
     if (argc == 1)  cout << "Tapez help pour obtenir la liste des commandes disponibles.\n" << endl << endl;
 
+
     // On lance la fenÃªtre graphique
 
@@ -2232,4 +3081,5 @@
 
     XSelectInput(d,w, ExposureMask );
+
 
     // On lance le thread pour gÃ©rer la fenÃªtre graphique
@@ -2237,12 +3087,11 @@
 
     if (pthread_create(&th1, NULL, (void*(*)(void*))LancementThread, this) < 0) {
-        Erreur("Impossible de crÃ©er le thread\n");
+        ErreurLog("Impossible de crÃ©er le thread\n");
         return -1;
     }
 
 
-
     // si on a utilisÃ© l'option -r en ligne de commande
-    // alors on charge et on lance l'exÃ©cution d'un fichier de mouvements
+    // alors on charge et on execute le fichier de mouvements
 
     if (argc == 3)
@@ -2263,5 +3112,5 @@
         else
         {
-            Erreur("Usage incorrect\n\n");
+            ErreurLog("Usage incorrect\n\n");
         }
     }
@@ -2273,9 +3122,12 @@
         {
             // Prompt
-            ChoixCouleurs==1 ? cout << blue1 : cout << blue2;
+            ChoixCouleurs==1 ? IDLog(blue2) : IDLog(blue1);
+
             cout << '>';
+
             // saisie
             getline(cin, chaine);
-            ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
+
+            ChoixCouleurs==1 ? IDLog(grey1) : IDLog(grey2);
 
             // on met en minuscules
@@ -2283,13 +3135,32 @@
 
             // on dÃ©code et exÃ©cute les commandes
-            DecodageEntreesUtilisateur(chaine);    
-	    
+            DecodageEntreesUtilisateur(chaine);
+
         }
         while (NoExit);
 
         pthread_join(th1 ,NULL);
-        //pthread_detach(th1);
     }
 
     return 0;
 }
+
+
+/**************************************************************************************
+** Le fichier file existe-t-il et n'est-il pas vide ?
+**
+**************************************************************************************/
+
+bool BAOcontrol::is_readable( const string & file )
+{
+    ifstream fichier( file.c_str() );
+    if (fichier.fail()) return false;
+
+    // sauvegarder la position courante
+    long pos = fichier.tellg();
+    // se placer en fin de fichier
+    fichier.seekg( 0 , ios_base::end );
+    // rÃ©cupÃ©rer la nouvelle position = la taille du fichier
+    long size = fichier.tellg();
+    return (size > 0);
+}
Index: /BAORadio/libindi/libindi/BAOControl/baocontrol.h
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/baocontrol.h	(revision 641)
+++ /BAORadio/libindi/libindi/BAOControl/baocontrol.h	(revision 642)
@@ -7,74 +7,78 @@
 
 
-#include <iostream>
-#include <string.h>
-#include <sstream>
-#include "ClientSocket.h"
-#include "SocketException.h"
+#include "math.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include <X11/Xlib.h>
-#include "filetools.h"
-#include "../drivers/telescope/astro.h"
-#include "math.h"
+
 #include <time.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include <termios.h>
 
-// couleurs utilisÃ©es dans le terminal
+#include "../communs/const.h"
+#include "../communs/logs.h"
+#include "../communs/ClientSocket.h"
+#include "../communs/SocketException.h"
+#include "../communs/astro.h"
+#include "../communs/alignement.h"
 
-#define red1 "\033[0;31m"
-#define blue1 "\033[0;34m"
-#define green1 "\033[0;32m"
-#define black1 "\033[0;30m"
-#define grey1 "\033[1;30m"
-#define red2 "\033[1;31m"
-#define blue2 "\033[1;34m"
-#define green2 "\033[1;32m"
-#define black2 "\033[1;30m"
-#define grey2 "\033[1;37m"
-
-
-// dimensions des tableaux
-
-#define MAXLOG 1000
-#define MAXOBJETS 100
-#define MAXANTENNES 50
-
-
-// dimensions de la fenÃªtre graphique
-
-#define haut_fenetre 10+22*10
-#define larg_fenetre 605
 
 using namespace std;
 
 
-struct DefAntenne
+// ParamÃštres des Ã©toiles utilisÃ©es pour l'alignement des antennes
+
+struct DefEtoiles
 {
-    unsigned char ip;			// Adresse ip d'une antenne
-
-    char ok;				// actuellement disponible ?
-    
-    long delta_az;
-    
-    long delta_ha;
-};
-
-// objets stockÃ©s dans le fichier de mouvements
-
-struct DefObjets
-{
-    double JJ;				// Date julienne oÃ¹ le tÃ©lescope doit aller pointer l'objet
-    double Duree;			// DurÃ©e de l'observation de l'objet en sec
-    string ad;				// Ascension droite J2000 de l'objet
-    string de;				// dÃ©clinaison J2000 de l'objet
-    bool exec;				// En cours d'exÃ©cution ?
+    string nom;                         // Nom de l'objet
+    string cons;                        // Nom de la constellation
+    double ad;				// Ascension droite J2000 de l'objet (en rad)
+    double de;				// dÃ©clinaison J2000 de l'objet (en rad)
+    double az;                          // Azimut (en rad)
+    double ha;                          // hauteur au-dessus de l'horizon (en rad)
+    double mag;				// magnitude
+    bool   selectionnee;                // l'objet a-t-il Ã©tÃ© sÃ©lectionnÃ© pour calibrer l'antenne 
+                                        // actuellement en mode alignement ?
 };
 
 
 
-class BAOcontrol : public Astro
+// structure dÃ©finissant les paramÃštres des antennes
+
+struct DefAntenne
+{
+    unsigned char ip;			// Adresse ip d'une antenne. Seul le dernier nombre nous intÃ©resse
+
+    char ok;				// actuellement disponible ? 
+                                        // 0 = antenne non connectÃ©e
+                                        // 1 = antenne connectÃ©e fonctionnant normalement
+                                        // 2 = antenne connectÃ©e mais prÃ©sentant un dÃ©faut
+
+    Alignement *AlignementAntenne;      // Contient les paramÃštres d'alignement de l'antenne dÃ©finie par cette structure  
+};
+
+
+
+// objets ou zone du ciel stockÃ©s dans le fichier des mouvements planifiÃ©s
+// Se reporter Ã  la notice de la commande run pour savoir comment utiliser ces fichiers de mouvement
+
+struct DefObjets
+{
+    double JJ;				// Date julienne du dÃ©but de l'observation de l'objet i dÃ©fini dans le fichier de mouvements
+    double Duree;			// DurÃ©e de l'observation de l'objet en sec
+    string ad;				// Ascension droite de l'objet dans le repÃšre J2000
+    string de;				// DÃ©clinaison de l'objet dans le repÃšre J2000
+    bool exec;				// L'objet est-il actuellement observÃ© ?
+};
+
+
+
+
+//Classe principale de l'application BAOcontrol
+
+class BAOcontrol : public Astro, public Logs
 {
 
@@ -83,42 +87,70 @@
     ~BAOcontrol();
 
+    //Gestion du thread
+    
     void *my_thread_process ();
+    
+    // intialise la clase
+    
     int init(int argc, char **argv);
 
 
+
 private:
-    void Affiche(string chaine, bool AfficheEcran);
-    void Affiche(stringstream *Message, bool AfficheEcran);
-    void Erreur(string chaine);
-    void Erreur(stringstream *Message);
+
+    // Gestion de la fenÃªtre graphique
+
     void initialiserFenetre();
     void Dessiner();
     void rouler();
+
+
+    //communications entre les antennes et le microcontrÃŽleur
+
     void LireReponse();
     bool VerifReponse(string reponseattendue);
-    void Update();
-    bool Decomposition(string chaine, char type, float *a1, float *a2, float *a3);
-    bool DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2);
+    void UpdateTime();
+
+
+    // commandes disponibles
+   
+    bool Connect(bool connect);
     bool EnvoyerCoordGeographiques();
+    bool EnvoyerPressionTemperature();
+    bool EnvoyerDelaisModesTransitEtTracking();
+    bool EnvoyerMethodeAlignement();
     bool Park();
     bool Abort();
     bool Goto(string ar, string dec, bool Transit, bool J2000);
-    bool Connect(bool connect);
+    bool AlignementAntenneIP(string ip);
+
+
+    // gestion des fichiers
+
+    int  readline (FILE * pfile, char *tab);
+    bool is_readable( const std::string & file );    
     bool LectureFichierMouvements(string fileName);
-    bool EnregistrementParametresAlignement(string fileName);
+    bool ChargementCatalogueEtoiles(string fileName);
+    bool ChargementParametres(string fileName);
+    
+
+    //Gestion serveur NED
+    
+    CoordonneesHoraires ServeurNED(string objet);
+    
+
+    // Routines principales
+
+    bool Decomposition(string chaine, char type, float *a1, float *a2, float *a3);
+    bool DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2);
     void DecodageEntreesUtilisateur(string chaine);
     bool Run(string fichier);
-    bool ChargementParametres(string fileName);
-    Coordonnees ServeurNED(string objet);
-    int  readline (FILE * pfile, char *tab);
-    bool Alignement(string ip);
 
+  
 
 
     // Variables globales
 
-    XFontStruct * fd;                           // Police de caractÃšres dans la fenÃªtre graphique
-
-    char ChoixCouleurs;                         // 1-pour un terminal Ã  fond blanc    2-pour un terminal Ã  fond noir
+    XFontStruct * fd;                           // Police de caractÃšres utilisÃ©e dans la fenÃªtre graphique
 
     string logs[MAXLOG];                        // Sauvegarde de toutes les actions et rÃ©ponses dans un tableau logs
@@ -130,4 +162,7 @@
     int numobjets;				// Nbre d'objets dans le dernier fichier de mouvements chargÃ©
     int runnum;					// NumÃ©ro de l'objet actuellement visÃ© dans le fichier de mouvement
+    int numEtoiles;				// Nbre d'Ã©toiles utilisÃ©es pour la procÃ©dure d'alignement des antennes
+    int MethodeAlignement;                      // MÃ©thode d'alignement utilisÃ©e
+    
 
     double Pression;				// Pression atmosphÃ©rique en mBar
@@ -139,11 +174,14 @@
     bool exitrun;				// doit-on sortir du programme Ã  la fin de l'execution de la commande run ?
     bool J2000;					// est-ce que les coordonnÃ©es du fichier de mouvements sont en coordonnÃ©es J2000 ?
+    bool ModificationAlignement;		// Est-ce que l'une des antennes est en cours d'alignement et est-ce qu'un paramÃštre 
+                                                // d'alignement Ã  changÃ© ?
 
     struct DefAntenne *Antennes;		// Sauvegarde de la situation actuelle de l'antenne i
     struct DefObjets  *objets;			// Liste des objets chargÃ©s depuis un fichier de mouvements
+    struct DefEtoiles *Etoiles;			// Liste des Ã©toiles servant Ã  la procÃ©dure d'alignement des antennes
 
     string LatitudeChar;			// Latitude du lieu d'observation. ChargÃ©e depuis le fichier de configuration
     string LongitudeChar;			// Longitude du lieu d'observation. ChargÃ©e depuis le fichier de configuration
-    string Serveur;				// Nom ou IP du serveur faisant tourner indi_BAO. Par defaut c'est localhost
+    string Serveur;				// Nom ou IP du serveur faisant tourner indi_BAO. Par defaut contient 'localhost'
     string Port; 				// Port utilisÃ© pour connecter le serveur indi_BAO
 
@@ -153,6 +191,6 @@
     Window w;					// fenÃªtre graphique
     Pixmap db;					// copie de la fenÃªtre pour permettre une actualisation sans scintillement
+   
     GC noir, vert, rouge, gris;			// couleurs utilisÃ©es dans la fenÃªtre graphique
-
 };
 
Index: /BAORadio/libindi/libindi/BAOControl/main.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/main.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/BAOControl/main.cpp	(revision 642)
@@ -9,5 +9,4 @@
   appli->init(argc, argv);
   
-  delete appli;
-  
+  delete appli;  
 } 
Index: /BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp	(revision 642)
@@ -5,7 +5,6 @@
 ***************************************************************************************/
 
-#include "ClientSocket.h"
-#include "ServerSocket.h"
-#include "SocketException.h"
+#include "../communs/ClientSocket.h"
+#include "../communs/SocketException.h"
 #include <iostream>
 #include <string>
@@ -128,5 +127,5 @@
 #define ERREURS 50
 
-int main ( int argc, int argv[] )
+int main ( int argc, char *argv[] )
 {
     Position Pos, Pos2;
Index: /BAORadio/libindi/libindi/BAOTest/Makefile
===================================================================
--- /BAORadio/libindi/libindi/BAOTest/Makefile	(revision 641)
+++ /BAORadio/libindi/libindi/BAOTest/Makefile	(revision 642)
@@ -2,29 +2,21 @@
 #
 
-simple_server_objects = ServerSocket.o Socket.o simple_server_main.o
-simple_client_objects = ClientSocket.o Socket.o simple_client_main.o
-BAOtest_objects = ClientSocket.o ServerSocket.o Socket.o BAOtest_main.o
+BAOtest_objects = BAOtest_main.o
 
 
-all : simple_server simple_client BAOtest
+all : BAOtest
 
-simple_server: $(simple_server_objects)
-	g++ -o simple_server $(simple_server_objects)
+BAOtest: $(BAOtest_objects)
+	g++ $(CXXFLAGS) -c -o ../BAOTest/Socket.o ../communs/Socket.cpp
+	g++ $(CXXFLAGS) -c -o ../BAOTest/ClientSocket.o ../communs/ClientSocket.cpp
+	g++ -o BAOtest $(BAOtest_objects) Socket.o ClientSocket.o
 
 
-simple_client: $(simple_client_objects)
-	g++ -o simple_client $(simple_client_objects)
-
-BAOtest: $(BAOtest_objects)
-	g++ -o BAOtest $(BAOtest_objects)
-
-
-Socket: Socket.cpp
-ServerSocket: ServerSocket.cpp
 ClientSocket: ClientSocket.cpp
-simple_server_main: simple_server_main.cpp
-simple_client_main: simple_client_main.cpp
 BAOtest_main: BAOtest_main.cpp
 
 clean:
-	rm -f *.o *.cpp~ *.h~ simple_server simple_client BAOtest
+	rm -f *.o *.cpp~ *.h~  BAOtest
+
+install:
+	cp BAOtest /usr/bin
Index: /BAORadio/libindi/libindi/CMakeLists.txt
===================================================================
--- /BAORadio/libindi/libindi/CMakeLists.txt	(revision 641)
+++ /BAORadio/libindi/libindi/CMakeLists.txt	(revision 642)
@@ -1,8 +1,9 @@
 cmake_minimum_required(VERSION 2.4.7)
+PROJECT(libindi C CXX)
 
 ##################  INDI version  ################################
 set(INDI_SOVERSION "0")
 set(CMAKE_INDI_VERSION_MAJOR 0)
-set(CMAKE_INDI_VERSION_MINOR 8)
+set(CMAKE_INDI_VERSION_MINOR 9)
 set(CMAKE_INDI_VERSION_RELEASE 0)
 set(CMAKE_INDI_VERSION_STRING "${CMAKE_INDI_VERSION_MAJOR}.${CMAKE_INDI_VERSION_MINOR}.${CMAKE_INDI_VERSION_RELEASE}")
@@ -13,6 +14,4 @@
 set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
 set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include")
-
-MESSAGE( STATUS "BIN_INSTALL_DIR: " ${BIN_INSTALL_DIR} )
 
 ##################  setup install directories  ################################
@@ -30,16 +29,7 @@
 include (CheckIncludeFiles)
 
-find_package(ZLIB REQUIRED)
-
-FIND_PACKAGE(Boost)
-IF (BOOST_FOUND)
-    INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
-ENDIF()
-
-
-macro_optional_find_package(USB)
-macro_log_feature(LIBUSB_FOUND "libusb" "User level access to USB devices" "http://www.libusb.org" FALSE "" "Provides support for USB based drivers in INDI.")
-
-macro_optional_find_package(CFITSIO)
+FIND_PACKAGE(ZLIB REQUIRED)
+FIND_PACKAGE(USB REQUIRED)
+FIND_PACKAGE(CFITSIO REQUIRED)
 
 if (NOT CFITSIO_FOUND OR CFITSIO_VERSION_MAJOR LESS 3)
@@ -48,10 +38,9 @@
 
 macro_bool_to_01(CFITSIO_FOUND HAVE_CFITSIO_H)
-macro_log_feature(CFITSIO_FOUND "libcfitsio" "A library for reading and writing data files in FITS (Flexible Image Transport System) data format" "http://indi.sf.net" FALSE "3.03" "Provides INDI with FITS I/O support.")
-
+macro_log_feature(CFITSIO_FOUND "libcfitsio" "A library for reading and writing data files in FITS (Flexible Image Transport System) data format" "http://heasarc.gsfc.nasa.gov/fitsio/fitsio.html" FALSE "3.03" "Provides INDI with FITS I/O support.")
 
 macro_optional_find_package(Nova)
 macro_bool_to_01(NOVA_FOUND HAVE_NOVA_H)
-macro_log_feature(NOVA_FOUND "libnova" "A general purpose, double precision, Celestial Mechanics, Astrometry and Astrodynamics library" "http://indi.sf.net" FALSE "0.12.1" "Provides INDI with astrodynamics library.")
+macro_log_feature(NOVA_FOUND "libnova" "A general purpose, double precision, Celestial Mechanics, Astrometry and Astrodynamics library" "http://libnova.sourceforge.net" FALSE "0.12.1" "Provides INDI with astrodynamics library.")
 
 check_include_files(linux/videodev2.h HAVE_LINUX_VIDEODEV2_H)
@@ -112,4 +101,7 @@
         ${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.cpp
         ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/indiguiderinterface.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterinterface.cpp
+
     )
 
@@ -121,7 +113,7 @@
 set(indiserver_SRCS indiserver.c fq.c)
 
-add_executable(indiserver ${indiserver_SRCS}  ${liblilxml_SRCS})
-
-target_link_libraries(indiserver  pthread )
+add_executable(indiserver ${indiserver_SRCS} ${liblilxml_SRCS})
+
+target_link_libraries(indiserver pthread)
 
 if (NOVA_FOUND)
@@ -129,5 +121,5 @@
 endif (NOVA_FOUND)
 
-install(TARGETS indiserver RUNTIME DESTINATION bin )
+install(TARGETS indiserver RUNTIME DESTINATION bin)
 
 #################################################
@@ -146,5 +138,5 @@
 endif(CFITSIO_FOUND)
 
-install(TARGETS indi LIBRARY DESTINATION lib${LIB_POSTFIX})
+install(TARGETS indi LIBRARY DESTINATION ${LIB_DESTINATION})
 set_target_properties(indi PROPERTIES VERSION ${CMAKE_INDI_VERSION_STRING} SOVERSION ${INDI_SOVERSION})
 
@@ -154,5 +146,5 @@
 ##################################################
 add_library(indimain STATIC ${indimain_SRCS})
-install(TARGETS indimain ARCHIVE DESTINATION lib${LIB_POSTFIX})
+install(TARGETS indimain ARCHIVE DESTINATION ${LIB_DESTINATION})
 
 ##################################################
@@ -161,5 +153,5 @@
 ##################################################
 add_library(indidriver STATIC ${indimain_SRCS} ${indidriver_SRCS})
-install(TARGETS indidriver ARCHIVE DESTINATION lib${LIB_POSTFIX})
+install(TARGETS indidriver ARCHIVE DESTINATION ${LIB_DESTINATION})
 
 ##################################################
@@ -168,5 +160,5 @@
 add_library(indiclient STATIC ${indiclient_SRCS})
 target_link_libraries(indiclient indi pthread)
-install(TARGETS indiclient ARCHIVE DESTINATION lib${LIB_POSTFIX})
+install(TARGETS indiclient ARCHIVE DESTINATION ${LIB_DESTINATION})
 
 #####################################
@@ -200,5 +192,6 @@
    ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200classic.cpp
    ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200apdriver.c
-   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200ap.cpp )
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200ap.cpp 
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/lx200fs2.cpp)
 
 add_executable(indi_lx200generic ${lx200generic_SRCS}  ${liblilxml_SRCS} ${libindicom_SRCS})
@@ -213,9 +206,10 @@
 
 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/make_lx200generic_symlink.cmake
-"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200classic)\n
-exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200autostar)\n
-exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200_16)\n
-exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200gps)\n
-exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_lx200ap)\n
+"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200classic)\n
+exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200autostar)\n
+exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200_16)\n
+exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200gps)\n
+exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200ap)\n
+exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_lx200generic \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_lx200fs2)\n
 ")
 set_target_properties(indi_lx200generic PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_lx200generic_symlink.cmake)
@@ -311,10 +305,12 @@
 set(BAO_SRCS
    ${indimain_SRCS}
-${CMAKE_SOURCE_DIR}/drivers/telescope/Socket.cpp
-${CMAKE_SOURCE_DIR}/drivers/telescope/ServerSocket.cpp
-${CMAKE_SOURCE_DIR}/drivers/telescope/astro.cpp
+${CMAKE_SOURCE_DIR}/communs/Socket.cpp
+${CMAKE_SOURCE_DIR}/communs/ServerSocket.cpp
+${CMAKE_SOURCE_DIR}/communs/astro.cpp
+${CMAKE_SOURCE_DIR}/communs/exception.cpp
+${CMAKE_SOURCE_DIR}/communs/filetools.cpp
+${CMAKE_SOURCE_DIR}/communs/alignement.cpp
+${CMAKE_SOURCE_DIR}/communs/logs.cpp
 ${CMAKE_SOURCE_DIR}/drivers/telescope/BAO.cpp
-${CMAKE_SOURCE_DIR}/drivers/telescope/exception.c
-${CMAKE_SOURCE_DIR}/drivers/telescope/filetools.cpp
  )
    
@@ -329,5 +325,4 @@
 
 install(TARGETS indi_BAO RUNTIME DESTINATION bin )
-
 ########### Syncscan ###############
 set(synscan_SRCS
@@ -344,4 +339,32 @@
 
 install(TARGETS indi_synscan RUNTIME DESTINATION bin )
+
+########### Magellan I #############
+set(magellan_SRCS
+   ${indimain_SRCS}
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/magellandriver.c
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/magellan1.cpp )
+
+add_executable(indi_magellan1 ${magellan_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_magellan1 ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_magellan1 RUNTIME DESTINATION bin )
+
+########### IEQ45 #############
+set(ieq45_SRCS
+   ${indimain_SRCS}
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/ieq45driver.c
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/ieq45.cpp )
+
+add_executable(indi_ieq45 ${ieq45_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_ieq45 ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_ieq45 RUNTIME DESTINATION bin )
 
 ########### Telescope Simulator ##############
@@ -361,33 +384,29 @@
 install(TARGETS indi_simulator_telescope RUNTIME DESTINATION bin )
 
+########### CCD Simulator ##############
+if (CFITSIO_FOUND)
+
+set(ccdsimulator_SRCS
+        ${indimain_SRCS}
+        ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp
+   )
+
+add_executable(indi_simulator_ccd ${ccdsimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_simulator_ccd indidriver ${CFITSIO_LIBRARIES} m z pthread)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_simulator_ccd ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_simulator_ccd RUNTIME DESTINATION bin )
+
+endif (CFITSIO_FOUND)
+
+
 #####################################
 ########## FOCUSER GROUP ############
 #####################################
 
-########### CCD Simulator ##############
-if (CFITSIO_FOUND)
-
-set(ccdsimulator_SRCS
-        ${indimain_SRCS}
-        ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp
-   )
-
-add_executable(indi_simulator_ccd ${ccdsimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
-
-target_link_libraries(indi_simulator_ccd indidriver ${CFITSIO_LIBRARIES} m z pthread)
-
-if (NOVA_FOUND)
-  target_link_libraries(indi_simulator_ccd ${NOVA_LIBRARIES})
-endif (NOVA_FOUND)
-
-install(TARGETS indi_simulator_ccd RUNTIME DESTINATION bin )
-
-endif (CFITSIO_FOUND)
-
-
-#####################################
-########## FOCUSER GROUP ############
-#####################################
-
 #################################################################################
 
@@ -396,11 +415,10 @@
 set(robofocus_SRCS
 	${indimain_SRCS}
-	${CMAKE_SOURCE_DIR}/drivers/focuser/robofocus.c
-	${CMAKE_SOURCE_DIR}/drivers/focuser/robofocusdriver.c
+        ${CMAKE_SOURCE_DIR}/drivers/focuser/robofocus.cpp
    )
 
 add_executable(indi_robo_focus ${robofocus_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
 
-target_link_libraries(indi_robo_focus m)
+target_link_libraries(indi_robo_focus indidriver m z)
 
 if (NOVA_FOUND)
@@ -428,5 +446,5 @@
 
 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake
-"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_tcfs_focus ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_tcfs3_focus)\n")
+"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_tcfs_focus \$ENV{DESTDIR}${BIN_INSTALL_DIR}/indi_tcfs3_focus)\n")
 set_target_properties(indi_tcfs_focus PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake)
 
@@ -741,6 +759,7 @@
 ${CMAKE_SOURCE_DIR}/libs/indibase/indiccd.h  ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterwheel.h
 ${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.h  ${CMAKE_SOURCE_DIR}/libs/indibase/inditelescope.h
-${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.h ${CMAKE_SOURCE_DIR}/libs/indicom.h
-${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.h
+${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.h ${CMAKE_SOURCE_DIR}/libs/indibase/indiguiderinterface.h
+${CMAKE_SOURCE_DIR}/libs/indibase/indifilterinterface.h
+${CMAKE_SOURCE_DIR}/libs/indicom.h ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.h
  DESTINATION ${INCLUDE_INSTALL_DIR}/libindi COMPONENT Devel)
 
Index: /BAORadio/libindi/libindi/ChangeLog
===================================================================
--- /BAORadio/libindi/libindi/ChangeLog	(revision 641)
+++ /BAORadio/libindi/libindi/ChangeLog	(revision 642)
@@ -1,2 +1,12 @@
+From 0.8 to 0.9
+
+      # iEQ45 GoTo German Equatorial Mount Driver.
+      # INDI::Base drivers are now used for most classes of astrnomical instruments.
+      # New improved QSI CCD & Filter driver.
+      # New improved Starlight Xpress CCD & Filter driver.
+      # New improved RoboFocus driver.
+      # libboost is no longer required to build libindi.
+      # Numerous bug fixes and minor improvements.
+
 From 0.7.2 to 0.8
 
Index: /BAORadio/libindi/libindi/Doxyfile
===================================================================
--- /BAORadio/libindi/libindi/Doxyfile	(revision 641)
+++ /BAORadio/libindi/libindi/Doxyfile	(revision 642)
@@ -6,5 +6,5 @@
 DOXYFILE_ENCODING      = UTF-8
 PROJECT_NAME           = "Instrument Neutral Distributed Interface INDI"
-PROJECT_NUMBER         = 0.7
+PROJECT_NUMBER         = 0.9
 OUTPUT_DIRECTORY       = /home/jasem/Projects/doc
 CREATE_SUBDIRS         = NO
Index: /BAORadio/libindi/libindi/INSTALL
===================================================================
--- /BAORadio/libindi/libindi/INSTALL	(revision 641)
+++ /BAORadio/libindi/libindi/INSTALL	(revision 642)
@@ -1,3 +1,3 @@
-INDI Library Setup 0.8.0
+INDI Library Setup 0.9.0
 ========================
 
@@ -19,5 +19,4 @@
 + libusb
 + libnova >= 0.12.2
-+ libfli  >= 1.7
 + cfitsio >= 3.0
 
Index: /BAORadio/libindi/libindi/Indi_Stellarium/src/Makefile
===================================================================
--- /BAORadio/libindi/libindi/Indi_Stellarium/src/Makefile	(revision 641)
+++ /BAORadio/libindi/libindi/Indi_Stellarium/src/Makefile	(revision 642)
@@ -54,5 +54,5 @@
 
 clean:
-	rm *.o *.obj
+	rm *.o TelescopeServerBAO
 
 make.dep:
Index: /BAORadio/libindi/libindi/README
===================================================================
--- /BAORadio/libindi/libindi/README	(revision 641)
+++ /BAORadio/libindi/libindi/README	(revision 642)
@@ -1,3 +1,3 @@
-libindi v0.8
+libindi v0.9
 ============
 
Index: /BAORadio/libindi/libindi/cmake_modules/FindAPOGEE.cmake
===================================================================
--- /BAORadio/libindi/libindi/cmake_modules/FindAPOGEE.cmake	(revision 641)
+++ /BAORadio/libindi/libindi/cmake_modules/FindAPOGEE.cmake	(revision 642)
@@ -52,5 +52,5 @@
   else (APOGEE_FOUND)
     if (APOGEE_FIND_REQUIRED)
-      message(FATAL_ERROR "libapogee not found. Cannot compile Apogee CCD Driver. Please install libapogee and try again. http://APOGEE.sf.net")
+      message(FATAL_ERROR "libapogee not found. Cannot compile Apogee CCD Driver. Please install libapogee and try again. http://www.indilib.org")
     endif (APOGEE_FIND_REQUIRED)
   endif (APOGEE_FOUND) 
Index: /BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake
===================================================================
--- /BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake	(revision 641)
+++ /BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake	(revision 642)
@@ -60,9 +60,15 @@
   )
 
-  if(INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
-    set(INDI_FOUND TRUE)
-  else (INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
-    set(INDI_FOUND FALSE)
-  endif(INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
+  # Find pkg-config
+  FIND_PROGRAM(PKGCONFIG_EXECUTABLE NAMES pkg-config PATHS /usr/bin/ /usr/local/bin )
+
+  # query pkg-config asking for a libindi >= 0.8.0
+     EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS --atleast-version=0.8.0 libindi RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull )
+     if(_return_VALUE STREQUAL "0")
+        set(INDI_FOUND TRUE)
+     else(_return_VALUE STREQUAL "0")
+       set(INDI_FOUND FALSE)
+       message(STATUS "Could NOT find libindi. pkg-config indicates that libindi >= 0.8.0 is not installed.")
+     endif(_return_VALUE STREQUAL "0")
 
 
@@ -72,8 +78,4 @@
       message(STATUS "INDI Include: ${INDI_INCLUDE_DIR}, INDI Data: ${INDI_DATA_DIR}")
     endif (NOT INDI_FIND_QUIETLY)
-  else (INDI_FOUND)
-    if (INDI_FIND_REQUIRED)
-      message(FATAL_ERROR "indi-dev not found. Cannot compile INDI drivers. Please install indi-dev and try again. http://www.indilib.org")
-    endif (INDI_FIND_REQUIRED)
   endif (INDI_FOUND)
 
Index: /BAORadio/libindi/libindi/drivers.xml
===================================================================
--- /BAORadio/libindi/libindi/drivers.xml	(revision 641)
+++ /BAORadio/libindi/libindi/drivers.xml	(revision 642)
@@ -1,4 +1,4 @@
 <devGroup group="Telescopes">
-        <device label="BAO" focal_length="" aperture="">
+	<device label="BAO" focal_length="" aperture="">
 		<driver name="BAO">indi_BAO</driver>
 		<version>1.0</version>
@@ -108,4 +108,12 @@
                 <version>1.0</version>
         </device>
+        <device label="Magellan I" focal_length="" aperture="">
+                <driver name="Magellan I">indi_magellan1</driver>
+                <version>1.0</version>
+        </device>
+        <device label="iEQ45" focal_length="" aperture="">
+                <driver name="IEQ45">indi_ieq45</driver>
+                <version>0.1</version>
+        </device>
         <device label="Telescope Simulator" focal_length="" aperture="">
                 <driver name="Telescope Simulator">indi_simulator_telescope</driver>
@@ -114,7 +122,7 @@
 </devGroup>
 <devGroup group="Focusers">
-	<device label="Robo Focus">
-                <driver name="Robofocus">indi_robo_focus</driver>
-		<version>0.1</version>
+	<device label="RoboFocus">
+                <driver name="RoboFocus">indi_robo_focus</driver>
+		<version>1.0</version>
 	</device>
         <device label="Optec TCF-S">
@@ -130,12 +138,8 @@
         <device label="CCD Simulator">
                 <driver name="CCD Simulator">indi_simulator_ccd</driver>
-                <version>0.1</version>
+                <version>1.0</version>
         </device>
 </devGroup>
 <devGroup group="Filter Wheels">
-  	<device label="FLI Wheel">
-		<driver name="FLI Wheel">indi_fli_wheel</driver>
-    		<version>0.9</version>
-    	</device>
 	<device label="TruTech Wheel">
 		<driver name="TruTech Wheel">indi_trutech_wheel</driver>
@@ -144,5 +148,5 @@
         <device label="Filter Simulator">
                 <driver name="Filter Simulator">indi_simulator_wheel</driver>
-                <version>0.1</version>
+                <version>1.0</version>
         </device>
 </devGroup>
Index: /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp	(revision 642)
@@ -2,20 +2,17 @@
   Copyright(c) 2010 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+ .
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+ .
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 #include "ccd_simulator.h"
@@ -84,5 +81,6 @@
 void ISSnoopDevice (XMLEle *root)
 {
-    INDI_UNUSED(root);
+    ISInit();
+    ccdsim->ISSnoopDevice(root);
 }
 
@@ -125,8 +123,12 @@
     TimeFactor=1;
 
+    SimulatorSettingsNV = new INumberVectorProperty;
+    TimeFactorSV = new ISwitchVectorProperty;
+
 }
 
 bool CCDSim::SetupParms()
 {
+    int nbuf;
     SetCCDParams(SimulatorSettingsN[0].value,SimulatorSettingsN[1].value,16,SimulatorSettingsN[2].value,SimulatorSettingsN[3].value);
     //  Kwiq
@@ -141,10 +143,7 @@
     seeing=SimulatorSettingsN[9].value;        //  we get real fat stars in this one
 
-
-    if(RawFrame != NULL) delete RawFrame;
-    RawFrameSize=XRes*YRes;                 //  this is pixel count
-    RawFrameSize=RawFrameSize*2;            //  Each pixel is 2 bytes
-    RawFrameSize+=512;                      //  leave a little extra at the end
-    RawFrame=new char[RawFrameSize];
+    nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP();
+    nbuf += 512;
+    PrimaryCCD.setFrameBufferSize(nbuf);
 
     return true;
@@ -154,11 +153,12 @@
 {
 
+    int nbuf;
     SetupParms();
 
-    if(HasGuideHead) {
+    if(HasGuideHead)
+    {
         SetGuidHeadParams(500,290,8,9.8,12.6);
-        RawGuideSize=GXRes*GYRes;                 //  this is pixel count
-        RawGuideSize+=512;                      //  leave a little extra at the end
-        RawGuiderFrame=new char[RawGuideSize];
+        nbuf = GuideCCD.getXRes() * GuideCCD.getYRes();
+        GuideCCD.setFrameBufferSize(nbuf);
     }
 
@@ -174,12 +174,5 @@
 const char * CCDSim::getDefaultName()
 {
-    //fprintf(stderr,"Arrived in getDefaultName and deviceName returns '%s'\n",deviceName());
-    //if(strlen(deviceName())==0) {
         return (char *)"CCD Simulator";
-    //} else {
-    //    char n[500];
-    //    strcpy(n,deviceName());
-    //    return n;
-    //}
 }
 
@@ -190,12 +183,6 @@
     INDI::CCD::initProperties();
 
-    IUFillNumber(&EqN[0],"RA","Ra (hh:mm:ss)","%010.6m",0,24,0,0);
-    IUFillNumber(&EqN[1],"DEC","Dec (dd:mm:ss)","%010.6m",-90,90,0,0);
-    IUFillNumberVector(&EqNV,EqN,2,"","EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
-    //IUFillNumberVector(&EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
-
-    SimulatorSettingsNV = new INumberVectorProperty;
-    IUFillNumber(&SimulatorSettingsN[0],"SIM_XRES","CCD X resolution","%4.0f",0,2048,0,1280);
-    IUFillNumber(&SimulatorSettingsN[1],"SIM_YRES","CCD Y resolution","%4.0f",0,2048,0,1024);
+    IUFillNumber(&SimulatorSettingsN[0],"SIM_PrimarCCD.getXRes()","CCD X resolution","%4.0f",0,2048,0,1280);
+    IUFillNumber(&SimulatorSettingsN[1],"SIM_PrimarCCD.getYRes()","CCD Y resolution","%4.0f",0,2048,0,1024);
     IUFillNumber(&SimulatorSettingsN[2],"SIM_XSIZE","CCD X Pixel Size","%4.2f",0,60,0,5.2);
     IUFillNumber(&SimulatorSettingsN[3],"SIM_YSIZE","CCD Y Pixel Size","%4.2f",0,60,0,5.2);
@@ -209,12 +196,6 @@
     IUFillNumber(&SimulatorSettingsN[11],"SIM_SKYGLOW","Sky Glow (magnitudes)","%4.1f",0,6000,0,19.5);
     IUFillNumber(&SimulatorSettingsN[12],"SIM_OAGOFFSET","Oag Offset (arminutes)","%4.1f",0,6000,0,0);
-    IUFillNumberVector(SimulatorSettingsNV,SimulatorSettingsN,13,deviceName(),"SIMULATOR_SETTINGS","Simulator Settings","SimSettings",IP_RW,60,IPS_IDLE);
-
-
-    TelescopeTV = new ITextVectorProperty;
-    IUFillText(&TelescopeT[0],"ACTIVE_TELESCOPE","Telescope","");
-    IUFillTextVector(TelescopeTV,TelescopeT,1,deviceName(),"ACTIVE_DEVICES","Snoop Scope","Simulator Config",IP_RW,60,IPS_IDLE);
-
-    TimeFactorSV = new ISwitchVectorProperty;
+    IUFillNumberVector(SimulatorSettingsNV,SimulatorSettingsN,13,deviceName(),"SIMULATOR_SETTINGS","Simulator Settings","Simulator Config",IP_RW,60,IPS_IDLE);
+
 
     IUFillSwitch(&TimeFactorS[0],"1X","Actual Time",ISS_ON);
@@ -224,5 +205,5 @@
 
 
-    loadConfig();
+    //loadConfig();
 
     return true;
@@ -238,5 +219,4 @@
     defineNumber(SimulatorSettingsNV);
     defineSwitch(TimeFactorSV);
-    defineText(TelescopeTV);
     //IDDefText(&ConfigFileTV, NULL);
     //IDDefSwitch(&ConfigSaveRestoreSV, NULL);
@@ -257,14 +237,4 @@
 bool CCDSim::Disconnect()
 {
-    delete RawFrame;
-    RawFrameSize=0;
-    RawFrame=NULL;
-
-
-    if(RawGuiderFrame != NULL) {
-        delete RawGuiderFrame;
-        RawGuideSize=0;
-    }
-
     return true;
 }
@@ -335,4 +305,12 @@
         float timeleft;
         timeleft=CalcTimeLeft(ExpStart,ExposureRequest);
+
+        if (timeleft < 0)
+             timeleft = 0;
+
+        PrimaryCCD.setExposure(timeleft);
+        //ImageExposureN[0].value = timeleft;
+        //IDSetNumber(ImageExposureNP, NULL);
+
         if(timeleft < 1.0)
         {
@@ -347,8 +325,18 @@
         }
     }
+
     if(InGuideExposure)
     {
         float timeleft;
         timeleft=CalcTimeLeft(GuideExpStart,GuideExposureRequest);
+
+
+        if (timeleft < 0)
+             timeleft = 0;
+
+        //ImageExposureN[0].value = timeleft;
+        //IDSetNumber(ImageExposureNP, NULL);
+        GuideCCD.setExposure(timeleft);
+
         if(timeleft < 1.0)
         {
@@ -390,7 +378,8 @@
     unsigned short int val;
 
-    ptr=(unsigned short int *)RawFrame;
-
-    if(ShowStarField) {
+    ptr=(unsigned short int *) PrimaryCCD.getFrameBuffer();
+
+    if(ShowStarField)
+    {
         char gsccmd[250];
         FILE *pp;
@@ -423,5 +412,5 @@
 
         //  Start by clearing the frame buffer
-        memset(RawFrame,0,RawFrameSize);
+        memset(PrimaryCCD.getFrameBuffer(),0,PrimaryCCD.getFrameBufferSize());
 
 
@@ -439,12 +428,12 @@
         //  no offset or rotation for and y axis means
         pb=0.0;
-        pc=XRes/2/BinX;
+        pc=PrimaryCCD.getXRes()/2/PrimaryCCD.getBinX();
         pd=0.0;
-        pf=YRes/2/BinY;
+        pf=PrimaryCCD.getYRes()/2/PrimaryCCD.getBinY();
         //  and we do a simple scale for x and y locations
         //  based on the focal length and pixel size
         //  focal length in mm, pixels in microns
-        pa=focallength/PixelSizex*1000/BinX;
-        pe=focallength/PixelSizey*1000/BinY;
+        pa=focallength/PrimaryCCD.getPixelSizeX()*1000/PrimaryCCD.getBinX();
+        pe=focallength/PrimaryCCD.getPixelSizeY()*1000/PrimaryCCD.getBinY();
 
         //IDLog("Pixels are %4.2f %4.2f  pa %6.4f  pe %6.4f\n",PixelSizex,PixelSizey,pa,pe);
@@ -478,5 +467,5 @@
         float radius;
 
-        radius=sqrt((Scalex*Scalex*XRes/2.0*XRes/2.0)+(Scaley*Scaley*YRes/2.0*YRes/2.0));
+        radius=sqrt((Scalex*Scalex*PrimaryCCD.getXRes()/2.0*PrimaryCCD.getXRes()/2.0)+(Scaley*Scaley*PrimaryCCD.getYRes()/2.0*PrimaryCCD.getYRes()/2.0));
         //  we have radius in arcseconds now
         radius=radius/60;   //  convert to arcminutes
@@ -505,5 +494,5 @@
 
         //  if this is a light frame, we need a star field drawn
-        if(FrameType==FRAME_TYPE_LIGHT)
+        if(PrimaryCCD.getFrameType()==CCDChip::LIGHT_FRAME)
         {
             //sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r 120 -m 0 9.1",rad+PEOffset,Dec);
@@ -593,5 +582,7 @@
         //  fwhm equivalent to the full field of view
 
-        if((FrameType==FRAME_TYPE_LIGHT)||(FrameType==FRAME_TYPE_FLAT))
+        CCDChip::CCD_FRAME ftype = PrimaryCCD.getFrameType();
+
+        if((ftype==CCDChip::LIGHT_FRAME)||(ftype==CCDChip::FLAT_FRAME))
         {
             float skyflux;
@@ -599,5 +590,5 @@
             //  calculate flux from our zero point and gain values
             glow=skyglow;
-            if(FrameType==FRAME_TYPE_FLAT)
+            if(ftype==CCDChip::FLAT_FRAME)
             {
                 //  Assume flats are done with a diffuser
@@ -610,11 +601,14 @@
             //  ok, flux represents one second now
             //  scale up linearly for exposure time
-            skyflux=skyflux*ExposureRequest*BinX*BinY;
+            skyflux=skyflux*ExposureRequest*PrimaryCCD.getBinX()*PrimaryCCD.getBinY();
             //IDLog("SkyFlux = %4.2f ExposureRequest %4.2f\n",skyflux,ExposureRequest);
 
             unsigned short *pt;
-            pt=(unsigned short int *)RawFrame;
-            for(int y=0; y<YRes/BinY; y++) {
-                for(int x=0; x<XRes/BinX; x++) {
+
+            int nwidth  = PrimaryCCD.getXRes()/PrimaryCCD.getBinX();
+            int nheight = PrimaryCCD.getYRes()/PrimaryCCD.getBinY();
+            pt=(unsigned short int *)PrimaryCCD.getFrameBuffer();
+            for(int y=0; y< nheight; y++) {
+                for(int x=0; x< nwidth; x++) {
                     float dc;   //  distance from center
                     float fp;   //  flux this pixel;
@@ -622,10 +616,10 @@
                     float vig;
 
-                    sx=XRes/2/BinX;
+                    sx=PrimaryCCD.getXRes()/2/PrimaryCCD.getBinX();
                     sx=sx-x;
-                    sy=YRes/2/BinY;
+                    sy=PrimaryCCD.getYRes()/2/PrimaryCCD.getBinY();
                     sy=sy-y;
 
-                    vig=XRes/BinX;
+                    vig=PrimaryCCD.getXRes()/PrimaryCCD.getBinX();
                     vig=vig*ImageScalex;
                     //  need to make this account for actual pixel size
@@ -654,6 +648,6 @@
 
         //  Now we add some bias and read noise
-        for(x=0; x<XRes; x++) {
-            for(y=0; y<YRes; y++) {
+        for(x=0; x<PrimaryCCD.getXRes(); x++) {
+            for(y=0; y<PrimaryCCD.getYRes(); y++) {
                 int noise;
 
@@ -671,5 +665,7 @@
         val=testvalue;
 
-        for(int x=0; x<XRes*YRes; x++)
+        int nbuf    = PrimaryCCD.getXRes()*PrimaryCCD.getYRes();
+
+        for(int x=0; x<nbuf; x++)
         {
             *ptr=val++;
@@ -686,10 +682,12 @@
     unsigned char val;
 
-    ptr=(unsigned char *)RawGuiderFrame;
+    ptr=(unsigned char *) GuideCCD.getFrameBuffer();
     testvalue++;
     if(testvalue > 255) testvalue=0;
     val=testvalue;
 
-    for(int x=0; x<GXRes*GYRes; x++) {
+    int nbuf = GuideCCD.getXRes()*GuideCCD.getYRes();
+    for(int x=0; x< nbuf; x++)
+    {
         *ptr=val++;
         ptr++;
@@ -708,5 +706,5 @@
     float flux;
 
-    if((x<0)||(x>XRes/BinX)||(y<0)||(y>YRes/BinY))
+    if((x<0)||(x>PrimaryCCD.getXRes()/PrimaryCCD.getBinX())||(y<0)||(y>PrimaryCCD.getYRes()/PrimaryCCD.getBinY()))
     {
         //  this star is not on the ccd frame anyways
@@ -750,5 +748,5 @@
             float fa;
             fa=exp(-2.0*0.7*(dc*dc)/seeing/seeing);
-            fp=fa*flux*BinX*BinY;
+            fp=fa*flux*PrimaryCCD.getBinX()*PrimaryCCD.getBinY();
             if(fp < 0) fp=0;
 
@@ -773,12 +771,12 @@
     int drew=0;
     if(x >= 0) {
-        if(x < XRes/BinX) {
+        if(x < PrimaryCCD.getXRes()/PrimaryCCD.getBinX()) {
             if(y >= 0) {
-                if(y < YRes/BinY) {
+                if(y < PrimaryCCD.getYRes()/PrimaryCCD.getBinY()) {
                     unsigned short *pt;
                     int newval;
                     drew++;
-                    pt=(unsigned short int *)RawFrame;
-                    pt+=(y*XRes/BinX);
+                    pt=(unsigned short int *)PrimaryCCD.getFrameBuffer();
+                    pt+=(y*PrimaryCCD.getXRes()/PrimaryCCD.getBinX());
                     pt+=x;
                     newval=pt[0];
@@ -793,5 +791,5 @@
 }
 
-int CCDSim::GuideNorth(float v)
+bool CCDSim::GuideNorth(float v)
 {
     float c;
@@ -801,7 +799,7 @@
     Dec=Dec+c;
 
-    return 0;
-}
-int CCDSim::GuideSouth(float v)
+    return true;
+}
+bool CCDSim::GuideSouth(float v)
 {
     float c;
@@ -811,8 +809,8 @@
     Dec=Dec-c;
 
-    return 0;
-}
-
-int CCDSim::GuideEast(float v)
+    return true;
+}
+
+bool CCDSim::GuideEast(float v)
 {
     float c;
@@ -823,7 +821,7 @@
     RA=RA-c;
 
-    return 0;
-}
-int CCDSim::GuideWest(float v)
+    return true;
+}
+bool CCDSim::GuideWest(float v)
 {
     float c;
@@ -834,24 +832,6 @@
     RA=RA+c;
 
-    return 0;
-}
-
-void CCDSim::ISSnoopDevice (XMLEle *root)
- {
-     //fprintf(stderr,"CCDSim handling snoop\n");
-     if(IUSnoopNumber(root,&EqNV)==0) {
-        float newra,newdec;
-        newra=EqN[0].value;
-        newdec=EqN[1].value;
-        if((newra != RA)||(newdec != Dec)) {
-            //fprintf(stderr,"RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
-            RA=newra;
-            Dec=newdec;
-
-        }
-     } else {
-        //fprintf(stderr,"Snoop Failed\n");
-     }
- }
+    return true;
+}
 
 bool CCDSim::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
@@ -859,5 +839,6 @@
     //  first check if it's for our device
     //IDLog("INDI::CCD::ISNewNumber %s\n",name);
-    if(strcmp(dev,deviceName())==0) {
+    if(strcmp(dev,deviceName())==0)
+    {
         //  This is for our device
         //  Now lets see if it's something we process here
@@ -899,31 +880,4 @@
     return INDI::CCD::ISNewNumber(dev,name,values,names,n);
 }
-bool CCDSim::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
-{
-    //  Ok, lets see if this is a property wer process
-    //IDLog("IndiTelescope got %d new text items name %s\n",n,name);
-    //  first check if it's for our device
-    if(strcmp(dev,deviceName())==0) {
-        //  This is for our device
-        //  Now lets see if it's something we process here
-        if(strcmp(name,TelescopeTV->name)==0) {
-            int rc;
-            //IDLog("calling update text\n");
-            TelescopeTV->s=IPS_OK;
-            rc=IUUpdateText(TelescopeTV,texts,names,n);
-            //IDLog("update text returns %d\n",rc);
-            //  Update client display
-            IDSetText(TelescopeTV,NULL);
-            saveConfig();
-            IUFillNumberVector(&EqNV,EqN,2,TelescopeT[0].text,"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
-            IDSnoopDevice(TelescopeT[0].text,"EQUATORIAL_EOD_COORD");
-            //  We processed this one, so, tell the world we did it
-            return true;
-        }
-
-    }
-
-    return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);
-}
 
 
Index: /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h	(revision 642)
@@ -2,20 +2,17 @@
   Copyright(c) 2010 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+ .
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+ .
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -65,6 +62,5 @@
         bool AbortGuideFrame;
 
-        float RA;
-        float Dec;
+
         float GuideRate;
 
@@ -73,18 +69,8 @@
         time_t RunStart;
 
-        //  We are going to snoop these from a telescope
-        INumberVectorProperty EqNV;
-        INumber EqN[2];
-
         //  And this lives in our simulator settings page
 
         INumberVectorProperty *SimulatorSettingsNV;
         INumber SimulatorSettingsN[13];
-
-        ITextVectorProperty *TelescopeTV; //  A text vector that stores the telescope we want to snoop
-        IText TelescopeT[1];
-
-        //ISwitch ConfigSaveRestoreS[2];
-        //ISwitchVectorProperty ConfigSaveRestoreSV;
 
         ISwitch TimeFactorS[3];
@@ -103,6 +89,4 @@
 
         void ISGetProperties (const char *dev);
-        void ISSnoopDevice (XMLEle *root);
-
 
 
@@ -123,11 +107,10 @@
         int AddToPixel(int,int,int);
 
-        int GuideNorth(float);
-        int GuideSouth(float);
-        int GuideEast(float);
-        int GuideWest(float);
+        bool GuideNorth(float);
+        bool GuideSouth(float);
+        bool GuideEast(float);
+        bool GuideWest(float);
 
         virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
-        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
         virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
 
Index: /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp	(revision 642)
@@ -1,2 +1,20 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #include "filter_simulator.h"
 
@@ -90,9 +108,9 @@
 }
 
-int FilterSim::SelectFilter(int f)
+bool FilterSim::SelectFilter(int f)
 {
     CurrentFilter=f;
     SetTimer(500);
-    return 0;
+    return true;
 }
 
Index: /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h	(revision 642)
@@ -2,20 +2,17 @@
   Copyright(c) 2010 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -37,6 +34,10 @@
         bool Connect();
         bool Disconnect();
-        int SelectFilter(int);
+        bool SelectFilter(int);
         void TimerHit();
+
+        virtual bool SetFilterNames() { return false; }
+        virtual bool GetFilterNames(const char *deviceName, const char* groupName) { return false; }
+
 
 };
Index: /BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp	(revision 642)
@@ -82,5 +82,5 @@
 	if(dev && strcmp (mydev, dev)) return;
 	ISInit();
-        tcfs->ISNewSwitch(name, states, names, num);
+        tcfs->ISNewSwitch(dev, name, states, names, num);
 }
 
@@ -89,5 +89,5 @@
 	if(dev && strcmp (mydev, dev)) return;
 	ISInit();
-        tcfs->ISNewText(name, texts, names, num);
+        tcfs->ISNewText(dev, name, texts, names, num);
 }
 
@@ -96,5 +96,5 @@
 	if(dev && strcmp (mydev, dev)) return;
 	ISInit();
-        tcfs->ISNewNumber(name, values, names, num);
+        tcfs->ISNewNumber(dev, name, values, names, num);
 }
 
@@ -239,6 +239,5 @@
     if (tty_connect(tProp->tp[0].text, 19200, 8, 0, 1, &fd) != TTY_OK)
     {
-        ConnectSP->s = IPS_ALERT;
-        IDSetSwitch (ConnectSP, "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", tProp->tp[0].text);
+        IDMessage(deviceName(), "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", tProp->tp[0].text);
 	return false;
     }
@@ -252,5 +251,5 @@
             if (!strcmp(response, "!"))
             {
-                setConnected(true, IPS_OK, "Successfully connected to TCF-S Focuser in Manual Mode.");
+                IDMessage(deviceName(), "Successfully connected to TCF-S Focuser in Manual Mode.");
 
                 IUResetSwitch(FocusModeSP);
@@ -275,5 +274,5 @@
     }
 
-    setConnected(false, IPS_ALERT, "Error connecting to TCF-S focuser...");
+    IDMessage(deviceName(), "Error connecting to TCF-S focuser...");
     return false;
 
@@ -306,5 +305,5 @@
 **
 *****************************************************************/
-bool TCFS::ISNewNumber (const char *name, double values[], char *names[], int n)
+bool TCFS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
 {
 
@@ -317,5 +316,5 @@
   {
       resetProperties();
-      IDMessage(deviceID, "TCF-S is offline. Connect before issiung any commands.");
+      IDMessage(deviceName(), "TCF-S is offline. Connect before issiung any commands.");
       return false;
   }
@@ -355,4 +354,6 @@
       return true;
   }
+
+  return DefaultDriver::ISNewNumber (dev, name, values, names, n);
     
 }
@@ -362,5 +363,5 @@
 **
 *****************************************************************/
-bool TCFS::ISNewText (const char *name, char *texts[], char *names[], int n)
+bool TCFS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
 {
     ITextVectorProperty * tProp = getText(name);
@@ -382,5 +383,5 @@
 
 
-    return false;
+    return DefaultDriver::ISNewText(dev, name, texts, names, n);
 	
 }
@@ -390,10 +391,10 @@
 **
 *****************************************************************/
-bool TCFS::ISNewSwitch (const char *name, ISState *states, char *names[], int n)
+bool TCFS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
 {
 
     ISwitch *current_active_switch = NULL, *target_active_switch = NULL;
     // First process parent!
-    if (INDI::DefaultDriver::ISNewSwitch(deviceID, name, states, names, n) == true)
+    if (INDI::DefaultDriver::ISNewSwitch(deviceName(), name, states, names, n) == true)
         return true;
 
@@ -416,5 +417,5 @@
     {
       resetProperties();
-      IDMessage(deviceID, "TCF-S is offline. Connect before issiung any commands.");
+      IDMessage(deviceName(), "TCF-S is offline. Connect before issiung any commands.");
       return false;
     }
@@ -663,5 +664,5 @@
 
 
-    return false;
+    return DefaultDriver::ISNewSwitch(dev, name, states, names, n);
 }
 
@@ -930,4 +931,4 @@
 const char * TCFS::getDefaultName()
 {
-    return "TCFS";
-}
+    return mydev;
+}
Index: /BAORadio/libindi/libindi/drivers/focuser/tcfs.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/focuser/tcfs.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/focuser/tcfs.h	(revision 642)
@@ -66,7 +66,7 @@
     // Standard INDI interface fucntions
     virtual void ISGetProperties(const char *dev);
-    virtual bool ISNewNumber (const char *name, double values[], char *names[], int n);
-    virtual bool ISNewText (const char *name, char *texts[], char *names[], int n);
-    virtual bool ISNewSwitch (const char *name, ISState *states, char *names[], int n);
+    virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+    virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+    virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
  	
 
Index: /BAORadio/libindi/libindi/drivers/telescope/BAO.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/BAO.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/BAO.cpp	(revision 642)
@@ -11,4 +11,5 @@
 
 #include "BAO.h"
+#include "../communs/alt2motor.h"
 
 
@@ -22,9 +23,7 @@
 const char *OPTIONS_GROUP  = "Options";			// Options Group
 
-/* Handy Macros */
-//#define currentRA	EquatorialCoordsRN[0].value
-//#define currentDEC	EquatorialCoordsRN[1].value
-#define targetRA	EquatorialCoordsWN[0].value
-#define targetDEC	EquatorialCoordsWN[1].value
+
+#define targetRA    EquatorialCoordsWN[0].value
+#define targetDEC   EquatorialCoordsWN[1].value
 
 
@@ -34,6 +33,8 @@
 
 
+
 /**************************************************************************************
 ** Initialisation de la classe BAO
+**
 ***************************************************************************************/
 
@@ -42,51 +43,89 @@
     init_properties();
 
-    // tÃ©lescope en Ã©tat IDLE
-    ConnectSP.s    = IPS_IDLE;
+    // Le bouton connect de la boÃ®te de dialogue d'indi8BAO
+    // est dans l'Ã©tat IDLE au dÃ©marrage
+
+    ConnectSP.s           = IPS_IDLE;
 
     // derniÃšre actualisation
-    lastRA         = 0.0;
-    lastDEC        = 0.0;
-    JJAnc          = 0.0;
-
-    currentSet     =  0;
-    lastSet        = -1;
-    SocketsNumber  =  1;
-    TrackingMode   =  1;
-
-    // dÃ©lais en sec entre deux actualisations de la
-    // position dans les modes transit et tracking
-
-    ActualisationTM1 = 15.0 * 60.0;
-    ActualisationTM2 = 5.0;
-
-    UpdateGoto      = true;
-    InitThreadOK    = false;
-    ActualisationPosition = false;
-    Abort           = false;
-    Park            = false;
-    Suivi           = false;
-    Exit            = false;
+
+    lastRA                = 0.0;
+    lastDEC               = 0.0;
+    JJAnc                 = 0.0;
+
+    // Variables d'Ã©tat
+
+    currentSet            =  0;         // Variables internes d'Indi, ne pas toucher
+    lastSet               = -1;         // Variable interne d'Indi, ne pas toucher
+
+    // Nombre d'antennes connectÃ©es
+
+    SocketsNumber         =  1;
+
+    // Le mode tracking est activÃ© par dÃ©faut
+
+    TrackingMode          =  1;
+
+    // dÃ©lais en sec entre deux actualisations
+    // dans les modes transit et tracking
+
+    ActualisationTMTransit  = 15.0 * 60.0;    // DÃ©lai entre 2 actualisations dans le mode transit
+    ActualisationTMTracking = 5.0;            //                "                 "        tracking
+
+    // cette variable vaut "true" lorsque le thread de l'aplication a Ã©tÃ© initialisÃ©
+
+    InitThreadOK   	  = false;
+
+    // UpdatedGoto = true lorsque le dernier goto a bien Ã©tÃ© rÃ©alisÃ© jusqu'au bout
+
+    UpdatedGoto     	  = true;
+
+    // RealisationGoto = true lorsque les Ã©tapes nÃ©cessaires Ã  la rÃ©alisation d'un goto
+    // sont en cours d'execution
+
+    RealisationGoto       = false;
+
+    // vaut true si l'utilisateur demande l'annulation du mouvement en cours
+
+    Abort          	  = false;
+
+    // vaut true si l'utilisateur demande de mettre les antennes en mode park
+
+    Park           	  = false;
+
+    // vaut true un objet est actuellement suivi par les antennes
+
+    Suivi         	  = false;
+
+    // vaut true si l'utilisateur demande Ã  sortir de l'application -> permet de fermer le thread
+
+    Exit           	  = false;
+    
+    Pression              = 1013.0;
+    
+    Temp                  = 10.0;
 
 
     // initialisation des sockets (Antennes)
-    
+
     for (int i=0; i<MAXHOSTNAME; i++)
     {
-        Sockets[i].Connected = false;
-        Sockets[i].IP = "";
-		
-	Sockets[i].Delta.x = 0.0;
-	Sockets[i].Delta.y = 0.0;
+        Sockets[i].Connected         = false;
+        Sockets[i].IP                = "";
+        Sockets[i].TargetPosition.x  = 0.0;
+        Sockets[i].TargetPosition.y  = 0.0;
+        Sockets[i].AlignementAntenne = new Alignement();
+
+        if (Sockets[i].AlignementAntenne) Sockets[i].AlignementAntenne->InitAlignement();
     }
 
     // initialisations supplÃ©mentaires
-    
+
     InitAntennes();
 
     // NumÃ©ro de version
-    
-    IDLog("Initilizing from BAO device...\n");
-    IDLog("Driver Version: 2011-12-02\n");
+
+    IDLog("Indi server BAORadio...\n");
+    IDLog("Driver Version: 23-02-2012\n");
 
     //connect_telescope();
@@ -94,21 +133,44 @@
 
 
+
 /**************************************************************************************
 ** Destructeur
-** Lorsque l'on lance indi_BAO depuis indiserver dans un terminal
-** Le destructeur ne semble jamais Ãªtre atteint lorsque l'on sort... A vÃ©rifier
-***************************************************************************************/
+**
+***************************************************************************************/
+
 BAO::~BAO()
 {
+    //On informe le thread que nous allons sortir
+
     Exit = true;
+
+    // On lui laisse une seconde pour qu'il se termine
+
     sleep(1);
-    pthread_join (th1, NULL);
-}
+
+    // destruction du thread
+
+    pthread_join(th1, NULL);
+
+    // destruction des objets AlignementAntennes
+
+    for (int i=0; i<MAXHOSTNAME; i++)
+    {
+        delete Sockets[i].AlignementAntenne;
+    }
+
+    // Petit message Ã  l'attention de l'utilisateur
+    // permet de savoir si le destructeur est bien atteint
+
+    IDLog("Sortie de indi_BAO\n");
+}
+
 
 
 /************************************************************************************
-* Initialisation des paramÃštres des antennes
-*
+** Initialisation des paramÃštres des antennes
+**
 ************************************************************************************/
+
 void BAO::InitAntennes()
 {
@@ -121,18 +183,21 @@
         Sockets[i].etape              = 0;
 
-        Sockets[i].ack_status = false;
-        Sockets[i].ack_pos    = false;
-        Sockets[i].ack_park   = false;
-        Sockets[i].ack_abort  = false;
-        Sockets[i].ack_goto   = false;
-
-        Sockets[i].PosValides = false;
-        Sockets[i].GotoOk     = false;
-    }
-}
+        Sockets[i].ack_status         = false;
+        Sockets[i].ack_pos            = false;
+        Sockets[i].ack_park           = false;
+        Sockets[i].ack_abort          = false;
+        Sockets[i].ack_goto           = false;
+
+        Sockets[i].PosValides         = false;
+        Sockets[i].GotoOk             = false;
+    }
+}
+
 
 
 /**************************************************************************************
 ** Initialisation des boutons et des zones d'affichage dans la boÃ®te de dialogue INDI
+** se rÃ©fÃ©rer Ã  la documentation d'INDI
+**
 ***************************************************************************************/
 
@@ -149,4 +214,10 @@
     IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
 
+    // Alignment Set
+    IUFillSwitch(&AlignmentS[0], "SIMPLE", "Simple", ISS_ON);
+    IUFillSwitch(&AlignmentS[1], "AFFINE", "Affine", ISS_OFF);
+    IUFillSwitch(&AlignmentS[2], "TAKI", "Taki", ISS_OFF);
+    IUFillSwitchVector(&AlignmentSP, AlignmentS, NARRAY(AlignmentS), mydev, "ALIGNMENT_SET", "Alignment", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
+
     // Abort
     IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
@@ -171,9 +242,14 @@
     IUFillNumberVector(&GeographicCoordsWNP, GeographicCoordsWN, NARRAY(GeographicCoordsWN), mydev, "GEOGRAPHIC_COORD" , "Geographic coords", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
 
+     // Pression tempÃ©rature - SET
+    IUFillNumber(&PressionTempWN[0], "Pression", "Pression mb", "%10.6m",  0., 1500., 0., 0.);
+    IUFillNumber(&PressionTempWN[1], "Temperature", "Temperature Â°c", "%10.6m", -50., +50., 0., 0.);
+    IUFillNumberVector(&PressionTempWNP, PressionTempWN, NARRAY(PressionTempWN), mydev, "PRESSION_DATA" , "Pression, Temperature", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
+
     // Actualisation - SET
-    IUFillNumber(&ActualisationN1[0], "DELAY", "Transit mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
+    IUFillNumber(&ActualisationN1[0], "DELAY", "Transit delay (s)", "%10.6m",  0., 3600., 0., 0.);
     IUFillNumberVector(&ActualisationNP1, ActualisationN1, NARRAY(ActualisationN1), mydev, "DELAY1" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
 
-    IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
+    IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking delay (s)", "%10.6m",  0., 3600., 0., 0.);
     IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
 }
@@ -182,4 +258,6 @@
 /**************************************************************************************
 ** Initialisation de la boÃ®te de dialogue INDI (suite)
+** Vider tous les vecteurs
+**
 ***************************************************************************************/
 
@@ -195,5 +273,7 @@
     IDDefNumber(&EquatorialCoordsWNP, NULL);
     IDDefNumber(&GeographicCoordsWNP, NULL);
+    IDDefNumber(&PressionTempWNP, NULL);
     IDDefSwitch(&OnCoordSetSP, NULL);
+    IDDefSwitch(&AlignmentSP, NULL);
     IDDefSwitch(&AbortSlewSP, NULL);
     IDDefSwitch(&ParkSP, NULL);
@@ -207,4 +287,6 @@
 /**************************************************************************************
 ** Initialisation des vecteurs INDI
+** ParamÃštres par dÃ©faut
+**
 ***************************************************************************************/
 
@@ -213,8 +295,10 @@
     ConnectSP.s			= IPS_IDLE;
     OnCoordSetSP.s		= IPS_IDLE;
+    AlignmentSP.s		= IPS_IDLE;
     AbortSlewSP.s		= IPS_IDLE;
     ParkSP.s			= IPS_IDLE;
     ObjectTP.s			= IPS_IDLE;
     EquatorialCoordsWNP.s	= IPS_IDLE;
+    PressionTempWNP.s           = IPS_IDLE;
     GeographicCoordsWNP.s	= IPS_IDLE;
     ActualisationNP1.s		= IPS_IDLE;
@@ -222,8 +306,10 @@
 
     IUResetSwitch(&OnCoordSetSP);
+    IUResetSwitch(&AlignmentSP);
     IUResetSwitch(&AbortSlewSP);
     IUResetSwitch(&ParkSP);
 
     OnCoordSetS[0].s = ISS_ON;
+    AlignmentS[0].s = ISS_ON;
     ConnectS[0].s = ISS_OFF;
     ConnectS[1].s = ISS_ON;
@@ -231,8 +317,10 @@
     IDSetSwitch(&ConnectSP, NULL);
     IDSetSwitch(&OnCoordSetSP, NULL);
+    IDSetSwitch(&AlignmentSP, NULL);
     IDSetSwitch(&AbortSlewSP, NULL);
     IDSetSwitch(&ParkSP, NULL);
     IDSetText(&ObjectTP, NULL);
     IDSetNumber(&EquatorialCoordsWNP, NULL);
+    IDSetNumber(&PressionTempWNP, NULL);
     IDSetNumber(&GeographicCoordsWNP, NULL);
     IDSetNumber(&ActualisationNP1, NULL);
@@ -241,8 +329,12 @@
 
 
+
 /**************************************************************************************
 ** En cas de changement de texte dans la boÃ®te de dialogue (par exemple : changement du
-** nom de l'objet) alors suivre l'objet... 
+** nom de l'objet) alors suivre l'objet...
 ** Cette fonction n'est pas encore utilisÃ©e
+** TODO: faut-il pouvoir modifier le nom de l'objet depuis la boÃ®te ?
+** pas sÃ»r que cela soit utile: kstars et BAOcontrol permettent de faire cela
+**
 ***************************************************************************************/
 
@@ -275,4 +367,5 @@
 
 
+
 /**************************************************************************************
 ** En cas de changement d'une valeur numÃ©rique dans la boÃ®te de dialogue Indi
@@ -285,11 +378,16 @@
 
     // Ignore if not ours
+
     if (strcmp (dev, mydev))
         return;
 
+    // Si pas de connexion -> on sort
+
     if (is_connected() == false)
     {
         IDMessage(mydev, "Error ! BAO is offline. Please connect before issuing any commands.");
+
         reset_all_properties();
+
         return;
     }
@@ -299,18 +397,43 @@
     // Geographic  Coords
     // ===================================
+
     if (!strcmp (name, GeographicCoordsWNP.name))
     {
-        int i=0, nset=0, error_code=0;
-
-        Latitude=0.0;
-        Longitude=0.0;
-
-        for (nset = i = 0; i < n; i++)
-        {
+        // l'utilisateur a modifiÃ© un les coordonnÃ©es gÃ©ographiques de la boite indi
+
+        int i = 0, nset = 0;
+
+        // En cas d'erreur, on doit pouvoir sortir avec des paramÃštres par dÃ©faut
+        //ici la latitude et la longitude vondront 0.0
+
+        Latitude  = 0.0;
+        Longitude = 0.0;
+
+        // pour ce vecteur, on sait qu'il y a n Ã©lÃ©ments possibles
+        // Exemple pour la rubrique coordonnÃ©es gÃ©ographique de la boÃ®te indi
+        // il y a deux Ã©lÃ©ments : la longtude et la latitude
+        // pour la rubrique alignement, il y aen a trois par exemple :
+        // simple, affine et taki
+
+        for (i = 0; i < n; i++)
+        {
+            // pour chacun d'entre eux, on regarde si le nom passÃ© en argument de la fonction (*name)
+            // correspond bien Ã  l'un des Ã©lÃ©ments du vecteur GeographicCoordsWNP
+
             INumber *eqp = IUFindNumber (&GeographicCoordsWNP, names[i]);
+
             if (eqp == &GeographicCoordsWN[0])
             {
+                //ici on a identifiÃ© la zone latitude de la boÃ®te de dialogue
+                // Value[i] contient la chaine de caractÃšre correspondante dans la boÃ®te
+                // C'est la valeur saisie par l'utilisateur
+
                 Latitude = values[i];
+
+                // On doit vÃ©rifier que la latitude est dans un intervalle correct
+
                 nset += Latitude >= -90.0 && Latitude <= 90.0;
+
+                // on convertit en radians
 
                 Latitude *= Pidiv180;
@@ -318,6 +441,13 @@
             else if (eqp == &GeographicCoordsWN[1])
             {
+                // ici on a identifiÃ© une modification dans la rubrique longitude
+
                 Longitude = values[i];
+
+                // dans l'intervalle ?
+
                 nset += Longitude >= 0.0 && Longitude <= 360.0;
+
+                // en radians
 
                 Longitude *= -Pidiv180;
@@ -332,15 +462,39 @@
             //IDLog("Geographic : RA %5.2f - DEC %5.2f\n", Latitude, Longitude);
 
+            //nset vaut 2, on sommes donc sÃ»rs qu'il n'y a pas de problÃšme dans les valeurs
+            // saisies par l'utilisateur
+            // voir le code plus haut pour comprendre...
+
+            // On change la couleur de la "diode" de la rubrique coordonnÃ©es gÃ©ographiques de la boÃ®te
+            // en vert
+
             GeographicCoordsWNP.s = IPS_OK;
+
+            // pas de message d'erreur dans la boÃ®te
+
             IDSetNumber(&GeographicCoordsWNP, NULL);
         }
         else
         {
+            // quelque chose cloche
+            // peut-Ãªtre l'une des veleurs saisies par l'utilisateur n'est-elle pas dans
+            // le bon intervalle ? ex : lat = 150Â°
+
+            // on change la couleur de la diode
+
             GeographicCoordsWNP.s = IPS_ALERT;
+
+            // on affiche un message d'erreur
+
             IDSetNumber(&GeographicCoordsWNP, "Latitude or Longitude missing or invalid");
 
-            Latitude=0.0;
-            Longitude=0.0;
-        }
+            // on fixe arbitrairement les valeurs Ã  0
+
+            Latitude  = 0.0;
+            Longitude = 0.0;
+        }
+
+        // c'est bon. On peut donc transmettre les nouvelles valeurs Ã  la classe astro
+        // qui utilisera ces informations pur calculer l'azimut des objets et le tsl en particulier...
 
         DefinirLongitudeLatitude(Longitude, Latitude);
@@ -355,18 +509,31 @@
     if (!strcmp (name, EquatorialCoordsWNP.name))
     {
-        int i=0, nset=0, error_code=0;
-        double newRA =0, newDEC =0;
-
-        for (nset = i = 0; i < n; i++)
+        int i = 0, nset = 0;
+
+        double newRA =0.0, newDEC =0.0;
+
+        // nous avons le mÃªme principe de fonctionnement que pour les coordonnÃ©es gÃ©ographiques
+
+        for (i = 0; i < n; i++)
         {
             INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
+
             if (eqp == &EquatorialCoordsWN[0])
             {
+                // on a compris que l'utilisateur avait changÃ© l'ascension droite de l'objet
+
+                // on affecte la nouvelle valeur Ã  newRA
+
                 newRA = values[i];
+
+                // Est-ce que cette valeur est dans le bon intervalle ?
+
                 nset += newRA >= 0 && newRA <= 24.0;
             }
             else if (eqp == &EquatorialCoordsWN[1])
             {
+                //mÃªme chose pour la dÃ©clinaison
                 newDEC = values[i];
+
                 nset += newDEC >= -90.0 && newDEC <= 90.0;
             }
@@ -375,4 +542,5 @@
 
         // si les coordonnÃ©es de l'objet sont correctes
+
         if (nset == 2)
         {
@@ -380,7 +548,11 @@
             double targetAZ, targetAlt;
 
+            // On garde une trace des nouvelles coordonnÃ©es saisies par l'utilisateur
+
             targetRA  = newRA;
             targetDEC = newDEC;
 
+            // on les affiches dans les logs
+
             fs_sexa(RAStr, newRA, 2, 3600);
             fs_sexa(DecStr, newDEC, 2, 3600);
@@ -392,8 +564,11 @@
 
             ADDEC2Motor(newRA, newDEC);
+
+            // on dÃ©clenche le goto
 
             if (process_coords() == false)
             {
                 EquatorialCoordsWNP.s = IPS_ALERT;
+
                 IDSetNumber(&EquatorialCoordsWNP, NULL);
             }
@@ -402,4 +577,5 @@
         {
             EquatorialCoordsWNP.s = IPS_ALERT;
+
             IDSetNumber(&EquatorialCoordsWNP, "Error ! RA or Dec missing or invalid");
         }
@@ -407,4 +583,64 @@
         return;
     }
+    
+    
+    // ===================================
+    // Pression, Temperature
+    // ===================================
+    if (!strcmp (name, PressionTempWNP.name))
+    {
+        int i = 0, nset = 0;
+
+        double newPression =0.0, newTemperature =0.0;
+
+        // nous avons le mÃªme principe de fonctionnement que pour les coordonnÃ©es gÃ©ographiques
+
+        for (i = 0; i < n; i++)
+        {
+            INumber *eqp = IUFindNumber (&PressionTempWNP, names[i]);
+
+            if (eqp == &PressionTempWN[0])
+            {
+                // on a compris que l'utilisateur avait changÃ© l'ascension droite de l'objet
+
+                // on affecte la nouvelle valeur Ã  newRA
+
+                newPression = values[i];
+
+                // Est-ce que cette valeur est dans le bon intervalle ?
+
+                nset += newPression >= 0.0 && newPression <= 1500.0;
+            }
+            else if (eqp == &PressionTempWN[1])
+            {
+                //mÃªme chose pour la dÃ©clinaison
+                newTemperature = values[i];
+
+                nset += newTemperature >= -50.0 && newTemperature <= 50.0;
+            }
+        }
+
+
+        // si les coordonnÃ©es de l'objet sont correctes
+
+        if (nset == 2)
+        {  
+	    PressionTempWNP.s = IPS_OK;
+
+            IDSetNumber(&PressionTempWNP, NULL);
+		    
+            Pression = newPression;
+	    Temp = newTemperature;
+        }
+        else
+        {
+            PressionTempWNP.s = IPS_ALERT;
+
+            IDSetNumber(&PressionTempWNP, "Error ! Bad values for pression or temperature");
+        }
+
+        return;
+    }
+
 
     // ===================================
@@ -413,19 +649,26 @@
     if (!strcmp (name, ActualisationNP1.name))
     {
-        int i=0, nset=0, error_code=0;
-        double newAct1 =0;
-
-        for (nset = i = 0; i < n; i++)
+        // on a ici exactement le mÃªme fonctionnement que prÃ©cÃ©dement
+        // on rÃ©gle ici les valeurs des delais entre deux actualisations
+        // de la position en mode transit et tracking
+        // retourne un message d'erreur si les durÃ©es ne sont pas exprimÃ©es
+        // dans un intervalle > 0.0 et < 3600
+
+        double newAct1 = 1.0;
+
+        for (int i = 0; i < n; i++)
         {
             INumber *eqp = IUFindNumber (&ActualisationNP1, names[i]);
+
             if (eqp == &ActualisationN1[0])
             {
                 newAct1 = values[i];
 
-                if (newAct1 >= 0.0 && newAct1 <= 3600.0)
+                if ( newAct1 >= 0.0 && newAct1 <= 3600.0 )
                 {
-                    ActualisationTM1 = newAct1;
+                    ActualisationTMTransit = newAct1;
 
                     ActualisationNP1.s = IPS_OK;
+
                     IDSetNumber(&ActualisationNP1, NULL);
                 }
@@ -433,4 +676,5 @@
                 {
                     ActualisationNP1.s = IPS_ALERT;
+
                     IDSetNumber(&ActualisationNP1, "Error ! Delay invalid");
                 }
@@ -441,19 +685,20 @@
     if (!strcmp (name, ActualisationNP2.name))
     {
-        int i=0, nset=0, error_code=0;
-        double newAct2 =0;
-
-        for (nset = i = 0; i < n; i++)
+        double newAct2 = 1.0;
+
+        for (int i = 0; i < n; i++)
         {
             INumber *eqp = IUFindNumber (&ActualisationNP2, names[i]);
+
             if (eqp == &ActualisationN2[0])
             {
                 newAct2 = values[i];
 
-                if (newAct2 >= 0.0 && newAct2 <= 3600.0)
+                if ( newAct2 >= 0.0 && newAct2 <= 3600.0 )
                 {
-                    ActualisationTM2 = newAct2;
+                    ActualisationTMTracking = newAct2;
 
                     ActualisationNP2.s = IPS_OK;
+
                     IDSetNumber(&ActualisationNP2, NULL);
                 }
@@ -469,6 +714,8 @@
 
 
+
 /**************************************************************************************
 ** L'utilisateur clique sur l'un des boutons de la boÃ®te Indi
+**
 ***************************************************************************************/
 
@@ -513,9 +760,40 @@
 
     // ===================================
+    // Alignment Set
+    // ===================================
+    if (!strcmp(name, AlignmentSP.name))
+    {
+        if (IUUpdateSwitch(&AlignmentSP, states, names, n) < 0)
+            return;
+
+        currentSet = get_switch_index(&AlignmentSP);
+        AlignmentSP.s = IPS_OK;
+        IDSetSwitch(&AlignmentSP, NULL);
+
+        for (int i=0; i<MAXALIGNEMENTANTENNE; i++)
+        {
+            switch (currentSet)
+            {
+            case 1 :
+                Sockets[i].AlignementAntenne->MethodeAlignement = SIMPLE;
+                break;
+            case 2 :
+                Sockets[i].AlignementAntenne->MethodeAlignement = AFFINE;
+                break;
+            case 3 :
+                Sockets[i].AlignementAntenne->MethodeAlignement = TAKI;
+                break;
+            }
+        }
+
+        return;
+    }
+
+    // ===================================
     // Abort slew
     // ===================================
     if (!strcmp (name, AbortSlewSP.name))
     {
-        Abort=true;
+        Abort = true;
 
         IUResetSwitch(&AbortSlewSP);
@@ -568,4 +846,5 @@
 ** l'utilisation d'un thread permet de contourner le problÃšme de la fonction accept
 ** qui est bloquante.
+**
 ***************************************************************************************/
 
@@ -590,6 +869,6 @@
             IDLog("\n");*/
         }
-        
-        sleep(1); // faire une pause pour Ã©viter de consommer trop de temps CPU -> Ã  vÃ©rifier 
+
+        sleep(1); // faire une pause pour Ã©viter de consommer trop de temps CPU -> Ã  vÃ©rifier
     }
     while (!Exit);
@@ -617,4 +896,5 @@
 ** Le retour de la commande P est POSITION/valeur_az/valeur_alt/
 ** ExtractPosition retourne donc Valeur_az et Valeur_alt
+**
 ***************************************************************************************/
 
@@ -633,11 +913,11 @@
         if (pos != string::npos)
         {
-            result->x = atol(str2.substr(0, pos).c_str());
-
-            result->y = atol(str2.substr(pos + 1).c_str());
-	    
-	    return true;
-        }        
-    } 
+            result->x = atol( str2.substr(0, pos).c_str() );
+
+            result->y = atol( str2.substr(pos + 1).c_str() );
+
+            return true;
+        }
+    }
 
     IDLog((str +" failed !\n").c_str());
@@ -649,6 +929,9 @@
 
 /************************************************************************************
-* cette procÃ©dure convertit les coordonnÃ©es Ã©quatoriales de l'objet visÃ©
-* en unitÃ©s de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK)
+** Cette procÃ©dure, aprÃšs avoir appliquÃ© la matrice de rotation aux coordonnÃ©es
+** visÃ©es par l'utilisateur, convertit les coordonnÃ©es Ã©quatoriales de l'objet visÃ©
+** en unitÃ©s de codeurs des paraboles
+** (cÃ d en nb de tours des deux axes moteurs depuis la position PARK)
+**
 ************************************************************************************/
 
@@ -657,167 +940,219 @@
     double targetAz;
     double targetAlt;
+    double newRA2  = newRA * 15.0 * Pidiv180;
+    double newDEC2 = newDEC * Pidiv180;
     char AzStr[32];
     char AltStr[32];
-
-
-    // Calcule la hauteur et l'azimut de la zone du ciel pointÃ©e (en fonction de la date et du lieu d'observation)
-
-    Azimut( newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
-    
-    // Correction de la rÃ©fraction atmosphÃ©rique
-    
-    targetAlt = RefractionAtmospherique(targetAlt);
-
-    // Petit calcul pour faire en sorte que le sud soit Ã  0Â° d'azimut
-
-    targetAz = VerifAngle( targetAz + Pi );
-
-    // On convertit les angles prÃ©cÃ©dents en degrÃ©s
-
-    targetAlt *= N180divPi;
-    targetAz  *= N180divPi;
-
-    // Affichage dans les logs
-
-    fs_sexa(AzStr, targetAz, 2, 3600);
-    fs_sexa(AltStr, targetAlt, 2, 3600);
-
-    IDLog("Horizontal coords : Az = %s     Alt = %s\n", AzStr, AltStr);
-
-
-    //Conversion des deux angles en pas codeurs
-
-    if ( targetAlt < 30.0 )
-    {
-        // L'objet est trop bas (<30Â°). On annule le suivi...
-
-        IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30Â° au-dessus de l horizon. Goto annule.");
-
-        Suivi = false;
-
-        ActualisationPosition = false;
-
-        InitAntennes();
-    }
-    else
-    {
-        // Si la hauteur est supÃ©rieure Ã  90Â°, on doit ajouter 180Â° Ã  l'azimut et corriger
-        // la hauteur en appliquant hauteur=180Â°-hauteur
-
-        if (targetAlt > 90.0)
-        {
-            targetAlt = 180.0 - targetAlt;
-            targetAz += 180.0;
-        }
-
-        // On applique la formule de Marc pour convertir la hauteur en nombre de pas codeur alt
-
-        double I0 = 81.0;
-        double I2 = 128279.4 - 129723.4 * sin( (targetAlt - 20.2345) * Pidiv180 );
-
-        double Codalt = (sqrt(I2) - I0) / 0.078947;
-
-
-        TargetPosition.y = (int) Arrondi(Codalt);
-
-        //4000 pas pour 360Â° sur l'axe az
-
-        TargetPosition.x = (int) Arrondi( targetAz * 4000.0 / 360.0);
-
-        IDLog("Nbre de pas codeurs Az = %i        Alt = %i\n", TargetPosition.x, TargetPosition.y);
-    }
-}
-
-
-/**************************************************************************************
-** Le fichier file existe-t-il et n'est-il pas vide ?
-**************************************************************************************/
-
-bool BAO::is_readable( const std::string & file ) 
-{ 
-    std::ifstream fichier( file.c_str() ); 
-    if (fichier.fail()) return false;
-    
-    // sauvegarder la position courante
-    long pos = fichier.tellg();
-    // se placer en fin de fichier
-    fichier.seekg( 0 , std::ios_base::end );
-    // rÃ©cupÃ©rer la nouvelle position = la taille du fichier
-    long size = fichier.tellg() ;
-    // restaurer la position initiale du fichier
-    fichier.seekg( pos,  std::ios_base::beg ) ;
-    return size ;
-}
-
-
-/**************************************************************************************
-** Chargement des paramÃštres d'alignement des antennes
-**************************************************************************************/
-
-bool BAO::ChargementParametresAlignement(string fileName)
-{
-    string value;
-    
-    stringstream os;
-    
-    char *delta_az = NULL;
-    
-    char *delta_ha = NULL;
-        
-    if (!is_readable(fileName)) return false;
-     
-    //IDLog("Chargement du fichier d alignement des antennes %s\n", fileName.c_str());
-     
-    //Chargement des corrections des antennes
-    
+    Coord result, vect;
+
+    // Pour toutes les antennes connectÃ©es
+
     for (int i=0; i<SocketsNumber; i++)
     {
+        // On vÃ©rifie qu'elles sont encore connectÃ©es
+
         if (Sockets[i].Connected)
         {
-            os << "Alignement antenne ip x.x.x." << Sockets[i].IP.substr(Sockets[i].IP.rfind(".")+1);
-
-            value="delta_az";
-
-            if (readINI((char*)os.str().c_str(), (char*)value.c_str(), &delta_az,  (char*)fileName.c_str()))
-
-            value="delta_ha";
-
-            if (readINI((char*)os.str().c_str(), (char*)value.c_str(), &delta_ha,  (char*)fileName.c_str()))
-
-            if (delta_az && delta_ha)
+            newRA = newRA2;
+	    newDEC = newDEC2;
+	  
+	    // Dans les modes d'alignement AFFINE et TAKI, on applique la matrice de correction
+            // sur les coordonnÃ©es horaires de l'objet visÃ©
+
+            // il faut vÃ©rifier auparavent que la matrice de rotation est disponible
+            // pour l'antenne i
+
+            if  (Sockets[i].AlignementAntenne->Matrice_ok)
             {
-	       // Si les corrections de l'antenne i ont Ã©tÃ© modifiÃ©es depuis le dÃ©marrage du programme
-	       // -> on les applique...
-               if (Sockets[i].Delta.x != atol(delta_az) || Sockets[i].Delta.y != atol(delta_ha))
-               {
-                  Sockets[i].Delta.x = atol(delta_az);
-
-                  Sockets[i].Delta.y = atol(delta_ha);
-
-                  IDLog("Correction antenne ip %s  deltaAz=%i   deltaHa=%i\n", Sockets[i].IP.c_str(), Sockets[i].Delta.x, Sockets[i].Delta.y);
-               }
+                // On est bien dans le cas de l'allignement AFFINE ou Taki
+
+                if (Sockets[i].AlignementAntenne->MethodeAlignement ==  AFFINE ||
+                        Sockets[i].AlignementAntenne->MethodeAlignement ==  TAKI)
+                {
+                    // On crÃ©e un vecteur avec pour coordonnÃ©es
+                    // x = Angle horaire de l'objet visÃ©
+                    // y = dÃ©clainaison de l'objet
+                    // z = 1.0
+                    // Voir la documentation pour plus d'explications sur le calcul affine/taki
+
+                    vect.x = VerifAngle( newRA2 - GetTSL() );
+                    vect.y = newDEC2;
+                    vect.z = 1.0;
+
+                    // Message pour l'utilisateur et les logs
+
+                    IDLog("Application de la matrice AFFINE/TAKI\nCoordonnees initiales: AD = %s  Dec = %s\n", DHMS(newRA2*N180divPi, true ).c_str(),
+                          DHMS(newDEC2*N180divPi, false ).c_str());
+
+                    // On applique la matrice de transformation
+
+                    switch (Sockets[i].AlignementAntenne->MethodeAlignement)
+                    {
+                    case AFFINE :
+                        Sockets[i].AlignementAntenne->AppliquerMatriceCorrectionAffine(&result, vect);
+                        break;
+                    case TAKI   :
+                        Sockets[i].AlignementAntenne->AppliquerMatriceCorrectionTaki( &result, vect);
+                        break;
+                    }
+
+                    // On rÃ©cupÃšre les nouvelles coordonnÃ©es. z ne nous intÃ©resse pas
+
+                    newRA  = VerifAngle(result.x+GetTSL());
+                    newDEC = result.y;
+
+                    IDLog("Coordonnees finales: AD = %s  Dec = %s\n", DHMS(newRA*N180divPi, true ).c_str(),
+                          DHMS(newDEC*N180divPi, false ).c_str());
+                }               
             }
-
-            if (delta_az) {
-                delete [] delta_az;
-                delta_az=NULL;
+            else
+            {
+                if (Sockets[i].AlignementAntenne->AlignementEnCours)
+                {
+		    // Si la matrice n'est pas prÃªte, c'est que la procÃ©dure d'alignement de l'antenne i n'est pas encore achevÃ©e.
+                    // On se contente ici d'appliquer des deltas en ascension droite et en dÃ©clinaison. Ces deltas sont envoyÃ©s de BAOcontrol
+                    // au driver indi_BAO par l'intermÃ©diaire du fichier AlignementAntennes.cfg
+                    // Consultez la documentation pour comprendre le principe de fonctionnement de l'alignement et de la communication
+                    // entre les deux programmes
+
+                    newRA  = VerifAngle(newRA2  + Sockets[i].AlignementAntenne->delta_ad[Sockets[i].AlignementAntenne->nbrcorrections] * PasDeltaAD);
+                    newDEC = newDEC2 + Sockets[i].AlignementAntenne->delta_de[Sockets[i].AlignementAntenne->nbrcorrections] * PasDeltaDe;
+
+                    IDLog("Alignement en cours.\nDelta RA=%i  delta Dec=%i\n", Sockets[i].AlignementAntenne->delta_ad[Sockets[i].AlignementAntenne->nbrcorrections], Sockets[i].AlignementAntenne->delta_de[Sockets[i].AlignementAntenne->nbrcorrections]);
+                    IDLog("Nouvelles CoordonnÃ©es AD =%s  Dec = %s\n", DHMS(newRA*N180divPi, true).c_str(), DHMS(newDEC*N180divPi, false).c_str());		  
+		}
             }
-
-            if (delta_ha) {
-                delete [] delta_ha;
-                delta_ha=NULL;
+                   IDLog("Nouvelles CoordonnÃ©es AD =%s  Dec = %s\n", DHMS(newRA*N180divPi, true).c_str(), DHMS(newDEC*N180divPi, false).c_str());		  
+
+
+            // Calcule la hauteur et l'azimut de la zone du ciel pointÃ©e (en fonction de la date et du lieu d'observation)
+
+            Azimut( newRA, newDEC, &targetAz, &targetAlt);
+
+            // Si la mÃ©thode d'alignement est la mÃ©thode SIMPLE, alors on doit cette fois-ci appliquer la matrice
+            // de correction au coordonnÃ©es horizontales et non aux coordonnÃ©es horaires comme ce que nous
+            // avons vu plus haut
+
+            if  (Sockets[i].AlignementAntenne->Matrice_ok && Sockets[i].AlignementAntenne->MethodeAlignement == SIMPLE)
+            {
+                // AprÃšs s'Ãªtre assurer que nous utilisons la mÃ©thode SIMPLE et que la matrice de rotation est ok
+
+                IDLog("Application de la matrice SIMPLE\nCoordonnees initiales: Azi = %s  Haut = %s\n", DHMS(targetAz*N180divPi, false ).c_str(),
+                      DHMS(targetAlt*N180divPi, false ).c_str());
+
+                // On constitue un vecteur vect
+                // Les coordonnÃ©es du vecteur correspondont Ã  la position
+                // d'un point sur une sphÃšre de rayon 1
+                // avec une latitude = targetAlt et une longitude=targetAz
+                // on reconnait bien les formules de passage des coordonnÃ©es
+                // sphÃ©riques aux coordonnÃ©es rectangulaires
+		
+		
+
+                vect.x = cos(targetAz) * cos(targetAlt);
+                vect.y = sin(targetAz) * cos(targetAlt);
+                vect.z = sin(targetAlt);
+
+
+                // Application de la matrice SIMPLE
+		
+		Sockets[i].AlignementAntenne->AppliquerMatriceCorrectionSimple(&result, vect);
+
+
+                // LÃ  on doit repasser des coordonnÃ©es rectangulaires
+                // aux coordonnÃ©es sphÃ©riques
+
+                if (result.x != 0.0)
+                {
+                    targetAz = atan( result.y / result.x );
+		    
+	            if (result.x < 0) targetAz+=Pi;
+                }
+                else targetAz = Pidiv2;
+
+                targetAz  = VerifAngle(targetAz);
+
+                targetAlt = asin(result.z);
+
+
+                IDLog("Coordonnees finales: Azi = %s  Haut = %s\n", DHMS(targetAz*N180divPi, false ).c_str(),
+                      DHMS(targetAlt*N180divPi, false ).c_str());
             }
 
-            os.str("");
-        }
-    }
-    
-    return true;
-}
+            // Application du delta en azimut (prÃ©alablement rÃ©glÃ© sur la polaire)
+            // Correspond Ã  la variable AlignementAntenne->delta_az_polar
+            // Ne s'applique que pour les alignements AFFINE et TAKI
+
+            if (Sockets[i].AlignementAntenne->MethodeAlignement != SIMPLE) targetAz += Sockets[i].AlignementAntenne->delta_az_polar * PasDeltaAD;
+
+            // Correction de la rÃ©fraction atmosphÃ©rique
+
+            targetAlt = RefractionAtmospherique(targetAlt);
+
+            // On ajoute Pi pour que le sud soit Ã  0Â° d'azimut
+
+            targetAz = VerifAngle( targetAz + Pi );
+
+            // On convertit les angles prÃ©cÃ©dents en degrÃ©s
+
+            targetAlt *= N180divPi;
+            targetAz  *= N180divPi;
+
+            // Affichage dans les logs
+
+            fs_sexa(AzStr, targetAz, 2, 3600);
+            fs_sexa(AltStr, targetAlt, 2, 3600);
+
+            IDLog("Coordonnees horizontales finales: Azi = %s  Haut= %s\n", AzStr, AltStr);
+
+
+            //Conversion des deux angles en pas codeurs
+
+            if ( targetAlt < HAUTMIN )
+            {
+                // L'objet est trop bas ( < 30Â°). On annule le suivi...
+
+                IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30 deg au-dessus de l horizon. Goto annule.");
+
+                Suivi = false;
+
+                RealisationGoto = false;
+
+                InitAntennes();
+
+                return;
+            }
+            else
+            {
+                // Si la hauteur est supÃ©rieure Ã  90Â°, on doit ajouter 180Â° Ã  l'azimut et corriger
+                // la hauteur en appliquant hauteur=180Â°-hauteur
+
+                if (targetAlt > 90.0)
+                {
+                    targetAlt = 180.0 - targetAlt;
+                    targetAz += 180.0;
+                }
+
+                // On applique la formule de Marc pour convertir la hauteur en nombre de pas codeur alt
+
+                Sockets[i].TargetPosition.y = (int) Arrondi( Alt2Motor( targetAlt ) );
+
+                //4000 pas pour 360Â° sur l'axe az
+
+                Sockets[i].TargetPosition.x = (int) Arrondi( targetAz * 4000.0 / 360.0);
+		
+		// Message de debug
+
+                IDLog("Nbre de pas codeurs Az = %i        Alt = %i\n", Sockets[i].TargetPosition.x, Sockets[i].TargetPosition.y);
+            }
+        }
+    }
+}
+
 
 
 /************************************************************************************
-* Retourne le nombre d'antennes connectÃ©es
-* 
+* Retourne le nombre d'antennes actuellement connectÃ©es
+*
 ************************************************************************************/
 
@@ -830,4 +1165,5 @@
     return num;
 }
+
 
 
@@ -839,9 +1175,11 @@
 void BAO::DeconnecterSocket(int num)
 {
-    IDLog("Deconnexion de l antenne : %s\n", Sockets[num].IP.c_str());
+    if (Sockets[num].Connected) IDLog("Deconnexion de l antenne : %s\n", Sockets[num].IP.c_str());
     Sockets[num].new_sock.shutdown();
     Sockets[num].Connected = false;
     Sockets[num].IP = "";
 }
+
+
 
 
@@ -877,11 +1215,11 @@
         gettimeofday(&tv, &tz);
 
-        double Annee=(double)(date.tm_year+1900);
-        double Mois=(double)(date.tm_mon+1);
-        double Jour=(double)date.tm_mday;
-        double Heu=(double)date.tm_hour;
-        double Min=(double)date.tm_min;
-        double Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
-        double UTCP=0.0;//(double)date.tm_isdst;
+        double Annee = (double)(date.tm_year + 1900);
+        double Mois  = (double)(date.tm_mon + 1);
+        double Jour  = (double)date.tm_mday;
+        double Heu   = (double)date.tm_hour;
+        double Min   = (double)date.tm_min;
+        double Sec   = (double)date.tm_sec+tv.tv_usec/1.0E6;
+        double UTCP  = 0.0;//(double)date.tm_isdst;
 
         // On transmet la date et l'heure Ã  la classe Astro
@@ -892,9 +1230,23 @@
 
         CalculTSL();
-    }
-    
-    // On chargement les paramÃštres de corrections des antennes toutes les secondes
-    
-    if ( compt%1000 == 0 ) ChargementParametresAlignement("/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg");
+	
+	
+	// On charge les paramÃštres de correction des antennes toutes les demi-secondes
+
+        if ( compt%500 == 0  && tv.tv_usec/1.0E6 > 0.5 )
+        {
+            for (int i=1; i<SocketsNumber; i++)
+            {
+                if (Sockets[i].Connected)
+                {
+                    // Si l'antenne i est connectÃ©e, on charge les paramÃštres
+                    Sockets[i].AlignementAntenne->TransmettreParametresClasseAstro(Annee, Mois, Jour, Heu, Min, Sec, Longitude, Latitude, Pression, Temp);	   
+		    
+		    Sockets[i].AlignementAntenne->ChargementParametresAlignement(Sockets[i].IP, "/home/" + (string)getenv("USER") + "/AlignementAntennes.cfg", targetRA * 15 * Pidiv180, targetDEC * Pidiv180);
+                }
+            }
+        }
+    }
+
 
 
@@ -946,62 +1298,90 @@
                         // on garde en stock la deuxiÃšme partie de la trame
                         // pour un traitement ultÃ©rieur
+
                         buffereponse = reponse.substr(pos + 1);
 
                         // Partie traitÃ©e
+
                         reponse = reponse.substr(0, pos);
-			
-			IDLog("Reponse recue de %s : %s\n", Sockets[i].IP.c_str(), reponse.c_str());
+
+                        // on l'affiche dans le log
+
+                        IDLog("Reponse recue de %s : %s\n", Sockets[i].IP.c_str(), reponse.c_str());
 
                         // On vÃ©rifie ici les acknowledges
+
                         if ((reponse.find("ACK") != string::npos) && (reponse.find("NACK") == string::npos))
                         {
                             if (reponse.find("POSITION")  != string::npos)
                             {
-                                Sockets[i].ack_pos=true;
+                                Sockets[i].ack_pos   = true;
                             }
                             else if (reponse.find("GOTO") != string::npos)
                             {
-                                Sockets[i].ack_goto=true;
+                                Sockets[i].ack_goto  = true;
                             }
                             else if (reponse.find("PARK") != string::npos)
                             {
-                                Sockets[i].ack_park=true;
+                                Sockets[i].ack_park  = true;
                             }
                             else if (reponse.find("ABORT")!= string::npos)
                             {
-                                Sockets[i].ack_abort=true;
+                                Sockets[i].ack_abort = true;
                             }
                         }
                         else
                         {
-                            //rÃ©ponse Ã  la requÃªte POSITION
+                            // RÃ©ponse Ã  la requÃªte POSITION
 
                             if (reponse.find("POSITION") != string::npos)
                             {
+                                // Il y a une erreur signalÃ©e par le microcontroleur
+
                                 if (reponse.find("NACK") != string::npos)
                                 {
-                                    //problÃšme concernant la commande P
+                                    // ProblÃšme concernant la commande P
+                                    // On affiche dans la boÃ®te indi un voyant de couleur rouge
+                                    // et on affiche un message d'erreur
+
                                     OnCoordSetSP.s = IPS_ALERT;
+
                                     IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n",
                                                 Sockets[i].IP.c_str());
+
+                                    // La position de l'antenne st donc inconnue
+
                                     Sockets[i].PosValides = false;
-                                    // Si la position de l'antenne est inconnue, on dÃ©connecte l'antenne
+
+                                    // On dÃ©connecte l'antenne
+
                                     Sockets[i].Connected  = false;
                                 }
                                 else if (Sockets[i].ack_pos)
-                                {                              
-				    if ( Sockets[i].PosValides = (ExtractPosition(reponse, &Sockets[i].Pos) == true) )
-                              	    {
-				      OnCoordSetSP.s = IPS_OK;
-                                      IDSetSwitch(&OnCoordSetSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
-                                                Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
-				    }
-				    else
-				    {
-				      OnCoordSetSP.s = IPS_ALERT;
-                                      IDSetSwitch(&OnCoordSetSP, "Antenne %s : La position n est pas valide !\n",
-                                                Sockets[i].IP.c_str());
-				    }
-				      
+                                {
+                                    // La position devrait Ãªtre valide si on arrive ici...
+
+                                    if ( Sockets[i].PosValides = (ExtractPosition(reponse, &Sockets[i].Pos) == true) )
+                                    {
+                                        // La fonction extractPositon confirme que les positions transmises
+                                        // par le microcontrÃŽleur sont valides
+
+                                        OnCoordSetSP.s = IPS_OK;
+
+                                        // message dans les logs
+
+                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
+                                                    Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
+                                    }
+                                    else
+                                    {
+                                        // Erreur repÃ©rÃ©e par la fonction ExtractPosition
+
+                                        OnCoordSetSP.s = IPS_ALERT;
+
+                                        // On en informe l'utilisateur
+
+                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : La position n est pas valide !\n",
+                                                    Sockets[i].IP.c_str());
+                                    }
                                 }
                             }
@@ -1013,10 +1393,19 @@
                                 if (reponse.find("NACK") != string::npos)
                                 {
+                                    // Une erreur  est retournÃ©e par le microcontroleur concernant la commande Park
+                                    // On affiche le voyant Park en rouge dans la boÃ®te indi...
+
                                     ParkSP.s = IPS_ALERT;
+
+                                    // ... et on affiche un message d'erreur
+
                                     IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str());
                                 }
                                 else if (Sockets[i].ack_park && reponse.find("OK")!=string::npos)
                                 {
+                                    // PARK ok !
+
                                     ParkSP.s = IPS_OK;
+
                                     IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n",  Sockets[i].IP.c_str());
                                 }
@@ -1029,13 +1418,21 @@
                                 if (reponse.find("NACK") != string::npos)
                                 {
+                                    // Une erreur  est retournÃ©e par le microcontroleur concernant la commande Abort
+                                    // On affiche le voyant Park en rouge dans la boÃ®te indi...
+
                                     AbortSlewSP.s = IPS_ALERT;
+
+                                    // ... et on affiche un message d'erreur
+
                                     IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n",  Sockets[i].IP.c_str());
                                 }
                                 else if (Sockets[i].ack_abort && reponse.find("OK")!=string::npos)
                                 {
+                                    // OK !
+
                                     AbortSlewSP.s = IPS_OK;
+
                                     IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n",  Sockets[i].IP.c_str());
                                 }
-
                             }
 
@@ -1046,6 +1443,15 @@
                                 if (reponse.find("NACK") != string::npos)
                                 {
+                                    // Une erreur  est retournÃ©e par le microcontroleur concernant la commande Goto
+                                    // On affiche le voyant Park en rouge dans la boÃ®te indi...
+
                                     OnCoordSetSP.s = IPS_ALERT;
+
+                                    // Message d'erreur
+
                                     IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n",  Sockets[i].IP.c_str());
+
+                                    // On dÃ©connecte l'antenne. Elle ne semble pas en mesure d'executer les ordres goto
+
                                     DeconnecterSocket(i);
                                 }
@@ -1061,24 +1467,32 @@
                                         Sockets[i].GotoOk = true;
 
+                                        // Voyant en vert dans la boÃ®te Indi
+
+                                        OnCoordSetSP.s = IPS_OK;
+
                                         // Message pour l'utilisateur
-					
-					OnCoordSetSP.s = IPS_OK;
+
                                         IDSetSwitch(&OnCoordSetSP, "Antenne %s : GOTO OK.\n",  Sockets[i].IP.c_str());
 
                                         // Fin du Goto pour toutes les antennes ?
-
-                                        int num=0;
+                                        // On compte les antennes connectÃ©es qui ont rÃ©alisÃ© le dernier ordre goto
+
+                                        int num = 0;
 
                                         for (int j=1; j<SocketsNumber; j++)
-					{
-					  if (Sockets[j].Connected)
+                                        {
+                                            if (Sockets[j].Connected)
                                             {
                                                 if (Sockets[j].GotoOk) num++;
                                             }
-					}
+                                        }
+
+                                        // Si le nombre d'antennes connectÃ©es est >0
+                                        // et que toutes les antennes connectÃ©es ont
+                                        // rÃ©alisÃ© le goto alors...
 
                                         if ((num == AntennesConnectees()) && (num>0))
                                         {
-					    // C'est bon ! Tout marche bien...
+                                            // C'est bon ! Tout marche bien...
                                             // On actualise l'AR et la dec dans la boÃ®te de dialogue
 
@@ -1086,7 +1500,9 @@
                                             lastDEC = targetDEC;
 
-                                            // On a fini le mouvement. On attend le prochain goto...
-
-                                            ActualisationPosition=false;
+                                            // On a fini le mouvement. Il n'y a donc plus d'Ã©tape Ã  faire
+                                            // dans le processus de rÃ©alisation d'un goto
+                                            // RealisationGoto vaut donc false
+
+                                            RealisationGoto = false;
 
                                             // RÃ©initialisation des paramÃštres des antennes en vue d'un prochain goto
@@ -1095,4 +1511,5 @@
 
                                             // On dessine les voyants de la boÃ®te de dialogue en vert
+
                                             OnCoordSetSP.s = IPS_OK;
                                             EquatorialCoordsWNP.s = IPS_OK;
@@ -1100,10 +1517,10 @@
 
                                             // Confirmation dans la boÃ®te de dialogue que toutes
-                                            // les antennes sont OK	    
-					    OnCoordSetSP.s = IPS_OK;
+                                            // les antennes sont OK
+
                                             IDSetSwitch(&OnCoordSetSP, "GOTO OK !");
-					    
-					    UpdateGoto=true;
-                                        }                                        
+
+                                            UpdatedGoto = true;
+                                        }
                                     }
                                 }
@@ -1113,10 +1530,14 @@
                         // On passe Ã  la trame suivante si memreponse n'est pas vide
 
-                        reponse=buffereponse;
-                        pos=reponse.find("\n");
+                        reponse = buffereponse;
+                        pos     = reponse.find("\n");
                     }
                 }
                 catch (SocketException& e) //AÃ¯e
                 {
+                    // Une exception concerne le socket i
+
+                    // On dÃ©connecte l'antenne pour plus de sÃ©curitÃ©
+
                     DeconnecterSocket(i);
 
@@ -1141,5 +1562,5 @@
             // pour rÃ©aliser un goto
 
-            ActualisationPosition = false;
+            RealisationGoto = false;
 
             // On envoie l'ordre ABORT Ã  toutes les antennes
@@ -1153,4 +1574,6 @@
             }
 
+            // Message Ã  destination de l'utilisateur et des logs
+
             IDSetSwitch(&OnCoordSetSP, "ABORT OK !");
 
@@ -1161,5 +1584,5 @@
             //Pour permettre de refaire un abort
 
-            Abort=false;
+            Abort = false;
         }
 
@@ -1176,5 +1599,5 @@
             // pour rÃ©aliser un goto
 
-            ActualisationPosition = false;
+            RealisationGoto = false;
 
             // On envoie l'ordre PARK Ã  toutes les antennes
@@ -1196,5 +1619,5 @@
             //Pour permettre de refaire un park
 
-            Park=false;
+            Park = false;
         }
 
@@ -1203,11 +1626,11 @@
         // Gestion du suivi
 
-        if ((Suivi) && (UpdateGoto))
+        if ((Suivi) && (UpdatedGoto))
         {
             // DÃ©lais entre deux actualisations
 
-            double delai=ActualisationTM1 / 3600.0 / 24.0;   // Actualisation toutes les 15 minutes en mode transit
-
-            if (TrackingMode==2) delai=ActualisationTM2 / 3600.0 / 24.0;   //et 5 secs en mode tracking
+            double delai = ActualisationTMTransit / 3600.0 / 24.0;   // Actualisation toutes les 15 minutes en mode transit (par dÃ©faut)
+
+            if (TrackingMode == 2) delai = ActualisationTMTracking / 3600.0 / 24.0;   //et 5 secs en mode tracking (par dÃ©faut)
 
 
@@ -1216,5 +1639,7 @@
             if (GetJJ() - JJAnc > delai)
             {
-                UpdateGoto = false;
+                // Cette variable vaudra true lorsque le goto aura Ã©tÃ© rÃ©alisÃ©
+
+                UpdatedGoto = false;
 
                 // Conversion des coordonnÃ©es en pas moteur
@@ -1226,5 +1651,7 @@
                 InitAntennes();
 
-                ActualisationPosition = true;
+                // On lance le processus d'actualisation du goto
+
+                RealisationGoto = true;
 
                 // On sauvegarde la date
@@ -1243,5 +1670,5 @@
                     if (Suivi) IDLog("ArrÃªt du suivi !");
 
-                    ActualisationPosition=false;
+                    RealisationGoto=false;
 
                     Suivi=false;
@@ -1254,24 +1681,42 @@
 
 
-        // ExÃ©cution de la procÃ©dure complÃšte de lecture de la position de l'antenne
-        // puis envoi d'une commande Goto
-
-        if (ActualisationPosition)
+        // ExÃ©cution de la procÃ©dure complÃšte d'un goto :
+        // 1Ãšre Ã©tape : envoi de la commande POSITION Ã  toutes les antennes
+        // 2Ãšme Ã©tape : VÃ©rification de l'acknowledge de la commande POSITION pour chaque antenne
+        // 3Ãšme Ã©tape : Les positions retournÃ©es par les antennes sont-elles valides ?
+        // 4Ãšme Ã©tape : Si oui, envoie de la commande goto Ã  toutes les antennes
+        // 5Ãšme Ã©tape : est-ce que toutes les antennes ont envoyÃ© l'acknowledge de la commande goto ?
+        // 6Ãšme Ã©tape : les antennes ont toutes rÃ©pondu GOTO OK !
+
+        if (RealisationGoto)
         {
             for (int i=1; i<SocketsNumber; i++)
             {
+                // On ne parle qu'aux antennes connectÃ©es
+
                 if (Sockets[i].Connected)
                 {
+                    // En fonction de l'Ã©tage de la rÃ©alisation d'un goto par l'antenne i
+
                     switch (Sockets[i].etape)
                     {
 
-                        //Envoi de la commande POS
+                        // Envoi de la commande POS
 
                     case 0 :
                     {
+                        // On doit intialiser l'acknowledge Ã  false
+
                         Sockets[i].ack_pos    = false;
+
+                        // et considÃ©rer que la position de l'antenne n'est pas valide
+
                         Sockets[i].PosValides = false;
 
+                        // avant d'envoyer l'ordre POSITION
+
                         if (!POSITION(i)) Sockets[i].sendalertes++;
+
+                        // On passe Ã  l'Ã©tage suivante
 
                         Sockets[i].etape++;
@@ -1286,32 +1731,50 @@
                         if (Sockets[i].ack_pos)
                         {
-                            // tout marche bien
+                            // tout marche bien. On a bien reÃ§u l'acknowledge de l'antenne i
+
+                            // Il n'y a donc aucune attente supplÃ©mentaire pour recevoir la rÃ©ponse
                             Sockets[i].AttenteExecution = 0;
+
+                            // Pas d'anomalie Ã  consigner
                             Sockets[i].AnomaliesExecution = 0;
+
+                            // On passe Ã  l'Ã©tape suivante
                             Sockets[i].etape++;
-                            i--; //permet de revenir sur ce mÃªme socket malgrÃ© la boucle
-                            // -> plus rapide
+
+                            //permet de rester sur le mÃªme socket malgrÃ© la boucle -> plus rapide
+                            i--;
                         }
                         else
                         {
-                            // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
+                            // On rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
 
                             // On garde une trace de l'anomalie
+
                             Sockets[i].AttenteExecution++;
 
                             if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
-                                // on recommence depuis le dÃ©but
+                                // on recommence depuis le dÃ©but.
+                                // Peut-Ãªtre que l'antenne n'a pas reÃ§u l'ordre ?
                                 Sockets[i].etape = 0;
                                 Sockets[i].AttenteExecution = 0;
+
+                                // Pas de rÃ©ponse. On consigne une erreur grave
                                 Sockets[i].AnomaliesExecution++;
                             }
 
-                            // Toujours rien -> plus sÃ©rieux : il faut dÃ©connecter l'antenne
+                            // Les erreurs graves s'accumulent. Pas de rÃ©ponse aprÃšs plusieurs minutes
+                            // Il faut dÃ©connecter l'antenne
                             if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
                             {
-			        OnCoordSetSP.s = IPS_ALERT;
+                                //Voyant en rouge dans la boÃ®te Indi
+
+                                OnCoordSetSP.s = IPS_ALERT;
+
+                                //Message Ã  l'attentnio de l'utilisateur
                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre POSITION. \
-    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+Deconnexion de l antenne.", Sockets[i].IP.c_str());
+
+                                // On dÃ©connecte l'antenne
                                 DeconnecterSocket(i);
                             }
@@ -1327,26 +1790,42 @@
                         if (Sockets[i].PosValides)
                         {
+                            // Tout vas bien
+                            // On ne consigne aucune anomalie
                             Sockets[i].AttenteExecution = 0;
                             Sockets[i].AnomaliesExecution = 0;
-                            Sockets[i].etape++; // on passe Ã  l'Ã©tape suivante
+
+                            //On passe Ã  l'Ã©tape suivante
+                            Sockets[i].etape++;
                         }
                         else
                         {
                             // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
+
                             Sockets[i].AttenteExecution++;
 
                             if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
-                                // on attend encore la rÃ©ponse posvalides                                
+                                // on attend encore la rÃ©ponse posvalides
+
                                 Sockets[i].etape = 2;
                                 Sockets[i].AttenteExecution = 0;
+
+                                // On consigne une erreur grave. L'antenne tarde Ã  rÃ©pondre
                                 Sockets[i].AnomaliesExecution++;
                             }
 
+                            // Aucune rÃ©ponse de l'antenne depuis plusieurs minutes
+                            // On la dÃ©connecte
                             if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
                             {
-			        OnCoordSetSP.s = IPS_ALERT;
+                                // Voyant en rouge
+
+                                OnCoordSetSP.s = IPS_ALERT;
+
+                                //Message d'erreur
                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : la position retournee n est pas valide. \
-    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+Deconnexion de l antenne.", Sockets[i].IP.c_str());
+
+                                //DÃ©connexion de l'antenne
                                 DeconnecterSocket(i);
                             }
@@ -1354,4 +1833,10 @@
                     }
                     break;
+
+
+
+                    // On peut remarquer qu'il n'y a pas de case 3 ici...
+                    // L'envoie de la commande goto se fait portant pendant l'Ã©tape 3 en dehors du switch
+                    // Voir le code plus loin...
 
 
@@ -1373,5 +1858,5 @@
                             if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
-                                // On prolonge l'attente                                
+                                // On prolonge l'attente pour recevoir l'acknowledge du goto
                                 Sockets[i].etape = 4;
                                 Sockets[i].AttenteExecution = 0;
@@ -1381,7 +1866,8 @@
                             if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
                             {
-			        OnCoordSetSP.s = IPS_ALERT;
-                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. \
-    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+                                OnCoordSetSP.s = IPS_ALERT;
+
+                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. Deconnexion de l antenne.", Sockets[i].IP.c_str());
+
                                 DeconnecterSocket(i);
                             }
@@ -1397,6 +1883,10 @@
                         if (Sockets[i].GotoOk)
                         {
+                            // On a bien reÃ§u Goto Ok pour l'antenne i !
+
                             Sockets[i].AttenteExecution = 0;
                             Sockets[i].AnomaliesExecution = 0;
+
+                            //On passe Ã  l'Ã©tape suivante
                             Sockets[i].etape++;
                         }
@@ -1408,6 +1898,6 @@
                             if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
-                                // On prolonge l'attente
-                                
+                                // On prolonge l'attente afin de recevoit un GOTO OK
+
                                 Sockets[i].etape = 5;
                                 Sockets[i].AttenteExecution = 0;
@@ -1415,10 +1905,14 @@
                             }
 
-			    // On dÃ©connecte l'antenne s'il n'y a pas de coonfirmation du goto au bout de 2 minutes    
+                            // On dÃ©connecte l'antenne s'il n'y a pas de coonfirmation du goto au bout de 2 minutes
                             if (Sockets[i].AnomaliesExecution > MAXANOMALIESGOTO)
                             {
-			        OnCoordSetSP.s = IPS_ALERT;
-                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. \
-    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+                                // Alerte sur une antenne
+                                OnCoordSetSP.s = IPS_ALERT;
+
+                                // Message d'erreur
+                                IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. Deconnexion de l antenne.", Sockets[i].IP.c_str());
+
+                                //DÃ©connexion de l'antenne
                                 DeconnecterSocket(i);
                             }
@@ -1433,16 +1927,25 @@
 
         ///////////////////////////////////////
-        //On attend que toutes les antennes soient prÃªtes pour lancer l'ordre Goto -> meilleure synchronisation
-
-        int num=0;
+        // Traitement de l'Ã©tape 3 de la rÃ©alisation d'un goto
+        // On place cette partie du traitement en dehors du switch et de la boucle
+        // pour pouvoir envoyer les ordres gotos Ã  toutes les antennes lorsque l'on a la confirmation
+        // qu'elles sont toutes prÃªtes Ã  executer cet ordre (Ãªtre Ã  l'Ã©tape 3 pour un socket)
+        // -> meilleure synchronisation
+
+        // On compte les antennes rendues Ã  l'Ã©tape 3 et qui attendent
+
+        int num = 0;
 
         for (int i=1; i<SocketsNumber; i++)
         {
+            // Uniquement les antennes connectÃ©es
+
             if (Sockets[i].Connected)
             {
-                if (Sockets[i].etape == 3) num++; //fin de la procÃ©dure ActualisationPosition.
-                // num antennes sont prÃªtes Ã  recevoir l'ordre GOTO
+                if (Sockets[i].etape == 3) num++; // num antennes sont prÃªtes Ã  recevoir l'ordre GOTO
             }
         }
+
+        // Toutes les antennes connectÃ©es sont prÃªtes Ã  recevoir l'ordre goto
 
         if ((num == AntennesConnectees()) && (num>0))
@@ -1452,9 +1955,11 @@
                 if (Sockets[i].Connected)
                 {
+                    // On envoie l'ordre
+
                     Sockets[i].ack_goto = false;
                     Sockets[i].AttenteExecution = 0;
                     Sockets[i].AnomaliesExecution = 0;
 
-                    if (!GOTO(i, TargetPosition.x - Sockets[i].Pos.x - Sockets[i].Delta.x, TargetPosition.y - Sockets[i].Pos.y - Sockets[i].Delta.y)) Sockets[i].sendalertes++;
+                    if (!GOTO(i, Sockets[i].TargetPosition.x - Sockets[i].Pos.x, Sockets[i].TargetPosition.y - Sockets[i].Pos.y )) Sockets[i].sendalertes++;
 
                     Sockets[i].etape++;
@@ -1464,5 +1969,7 @@
 
         ///////////////////////////////////////
-        // DÃ©tection d'anomalies sur la socket. DÃ©connexion du micro-cont ?
+        // OpÃ©ration garbage
+        // DÃ©tection d'anomalies sur le socket i.
+        // Ce n'est pas normal ici. Il faut dÃ©connecte l'antenne
 
         for (int i=1; i<SocketsNumber; i++)
@@ -1472,6 +1979,13 @@
                 if (Sockets[i].sendalertes > 0)
                 {
-		    OnCoordSetSP.s = IPS_ALERT;
+                    // Alarme dans la boÃ®te Indi
+
+                    OnCoordSetSP.s = IPS_ALERT;
+
+                    // Erreur dans les logs
+
                     IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str());
+
+                    // DÃ©connexion antenne
 
                     DeconnecterSocket(i);
@@ -1480,6 +1994,7 @@
         }
     }
-    
+
     //incrÃ©mentation du compteur
+
     compt++;
 }
@@ -1511,15 +2026,27 @@
         InitAntennes();
 
+        // On garde la trace du dÃ©but du Goto pour enchainer les actualisations
+
         JJAnc = GetJJ();
-	
-	ADDEC2Motor(targetRA, targetDEC);
+
+        // Conversion des coordonnÃ©es horaires en pas moteur
+
+        ADDEC2Motor(targetRA, targetDEC);
+
+        // Mode transit activÃ©
 
         TrackingMode = 1;
 
+        // On suit un objet
+
         Suivi = true;
 
-        UpdateGoto = false;
-
-        ActualisationPosition = true;
+        // Aucun goto n'a Ã©tÃ© encore rÃ©alisÃ©
+
+        UpdatedGoto = false;
+
+        // Mais on se lance dans la rÃ©alisation d'un goto
+
+        RealisationGoto = true;
 
         break;
@@ -1539,7 +2066,7 @@
         InitAntennes();
 
-        JJAnc=GetJJ();
-	
-	ADDEC2Motor(targetRA, targetDEC);
+        JJAnc = GetJJ();
+
+        ADDEC2Motor(targetRA, targetDEC);
 
         TrackingMode = 2;
@@ -1547,7 +2074,7 @@
         Suivi = true;
 
-        UpdateGoto = false;
-
-        ActualisationPosition = true;       
+        UpdatedGoto = false;
+
+        RealisationGoto = true;
 
         break;
@@ -1581,6 +2108,9 @@
 
         // On lance le thread !
-
-        Exit=false;
+        // Exit ne faudra true que lorsque sera venu le moment de sortir !
+
+        Exit = false;
+
+        // CrÃ©ation du thread
 
         if (pthread_create (&th1, NULL, (void*(*)(void*))LancementThread, this) < 0)
@@ -1592,11 +2122,4 @@
 
     case ISS_OFF:
-
-        // On sort du thread
-
-        Exit = true;
-        sleep(1);
-        pthread_join (th1, NULL);
-        InitThreadOK = false;
 
         // Etat des voyants
@@ -1621,4 +2144,26 @@
         SocketsNumber = 1;
 
+        // On sort du thread
+
+        // On dit au thread de sortir de la boucle
+
+        Exit = true;
+
+        // DÃ©sactiver la boucle de traitement des messages des ISPOLL
+
+        InitThreadOK = false;
+
+        // On laisse 1 s au thread pour sortir de la boucle
+
+        sleep(1);
+
+        // On dÃ©truit le thread
+
+        pthread_join (th1, NULL);
+
+        // on sort du programme
+
+        exit(EXIT_SUCCESS);
+
         break;
     }
@@ -1630,4 +2175,5 @@
 /**************************************************************************************
 **  Envoie une commande sur le socket numsocket
+**
 ***************************************************************************************/
 
@@ -1639,11 +2185,13 @@
     {
         sprintf(chaine, "%s%s\n", Commande, Params);
-	
-	Sockets[numsocket].new_sock << chaine;
-	
-	IDLog("Commande envoyee a %s: %s", Sockets[numsocket].IP.c_str(), chaine);
+
+        Sockets[numsocket].new_sock << chaine;
+
+        IDLog("Commande envoyee a %s: %s", Sockets[numsocket].IP.c_str(), chaine);
     }
     catch (SocketException& e)
     {
+        // Consignation d'une anomalie sur le socket
+
         DeconnecterSocket(numsocket);
 
@@ -1661,4 +2209,5 @@
 /**************************************************************************************
 ** Commande POSITION
+**
 ***************************************************************************************/
 
@@ -1670,4 +2219,5 @@
 /**************************************************************************************
 ** Commande PARK
+**
 ***************************************************************************************/
 
@@ -1679,4 +2229,5 @@
 /**************************************************************************************
 ** Commande ABORT
+**
 ***************************************************************************************/
 
@@ -1689,4 +2240,5 @@
 /**************************************************************************************
 ** Commande GOTO
+**
 ***************************************************************************************/
 
@@ -1700,4 +2252,6 @@
     sensAz  = 1;
 
+    // gestion des signes des deltas
+
     if ( deltaAz < 0 )
     {
@@ -1713,7 +2267,7 @@
 
     // VÃ©rification du nombre de pas Ã  faire au niveau de l'axe azimut
-    // Rappel : un tour complet autour de l'axe az fait 4000 pas codeur (#define NBREPASCODEURSAZ dans BAO.h)
-
-    // problÃšme 1 : si deltaAz > Ã  un demi-tours - soit 2000 pas alors
+    // Rappel : un tour complet autour de l'axe az fait 4000 pas codeur (voir #define NBREPASCODEURSAZ dans BAO.h)
+
+    // problÃšme 1 : si deltaAz > Ã  un demi-tours - soit 2000 pas codeur alors
     // on fait le trajet dans le sens inverse pour aller plus vite
 
@@ -1730,4 +2284,5 @@
     {
         deltaAz = NBREPASCODEURSAZ - deltaAz;
+
         sensAz = 1 - sensAz;
     }
@@ -1735,7 +2290,7 @@
     //on envoie les coordonnÃ©es au driver
 
-    if (sensAz == 1 )  sensAz='f'; else sensAz='b';
-    
-    if (sensAlt == 1 ) sensAlt='f'; else sensAlt='b';
+    (sensAz == 1 ) ? sensAz='f' : sensAz='b';
+
+    (sensAlt == 1 ) ? sensAlt='f': sensAlt='b';
 
     sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
@@ -1838,26 +2393,4 @@
 
 
-/**************************************************************************************
-**
-***************************************************************************************/
-void BAO::get_initial_data()
-{
-    //  IDSetNumber (&EquatorialCoordsRNP, NULL);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void BAO::slew_error(int slewCode)
-{
-    OnCoordSetSP.s = IPS_IDLE;
-
-    if (slewCode == 1)
-        IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
-    else if (slewCode == 2)
-        IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
-    else
-        IDSetSwitch (&OnCoordSetSP, "Slew failed.");
-}
 
 /**************************************************************************************
@@ -1929,2 +2462,3 @@
 
 
+
Index: /BAORadio/libindi/libindi/drivers/telescope/BAO.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/BAO.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/BAO.h	(revision 642)
@@ -23,26 +23,21 @@
 #include <fstream>
 
+#include <termios.h>
+#include <unistd.h>
+
 #include <config.h>
-
 #include "indicom.h"
-
-#include "Socket.h"
 #include "indidevapi.h"
 #include "indicom.h"
-#include "ServerSocket.h"
-#include "SocketException.h"
-#include "astro.h"
-#include "filetools.h"
-
-#define MAXCARACTERES 1024
-
-#define MAXATTENTE 80                // Si une commande ne recoit pas d'acknowledge. Alors refaire 80 tentatives en renvoyant la commande
-#define MAXANOMALIES 2               // Si pas de rÃ©ponse au bout de 80 tentatives -> erreur critique -> socket perdu ?
-#define MAXANOMALIESGOTO 1500
-
-#define NBREPASCODEURSAZ  4000
-   
+#include "../communs/const.h"
+#include "../communs/Socket.h"
+#include "../communs/ServerSocket.h"
+#include "../communs/SocketException.h"
+#include "../communs/astro.h"
+#include "../communs/alignement.h"
+
 
 using namespace std;
+
 
 struct Position
@@ -52,33 +47,37 @@
 };
 
+
 struct DefSocket
 {
-    ServerSocket new_sock;           // socket permettant de gÃ©rer la connexion avec une antennes
-
-    string IP;                       // IP de l'antenne
-
-    bool Connected;                  // le micro-contrÃŽleur est-il connectÃ© ?
-    bool PosValides;                 // le micro-contrÃŽleur a-t-il donnÃ© une position des moteurs valide ?
-    char status;                     // status='B' pour busy  'R' pour READY
-    int sendalertes;                 // une requÃªte 'send' a gÃ©nÃ©rÃ© une erreur sur le rÃ©seau
-    int AttenteExecution;	     // L'antenne parvient-elle Ã  executer un cycle de commandes ?
-    int AnomaliesExecution;	     // Erreur critique. L'antenne ne rÃ©pond plus !
-
-    Position Pos;                    // derniÃšre position retournÃ©e par le microcontrÃŽleur
-    Position Delta;                  // Corrections en Az et Ha
-    int etape;                       // Ã©tape dans le cycle de commandes/rÃ©ponses entre PC et microcontroleurs
-
-    bool ack_status;                 // Etat des acknowledges ?
-    bool ack_pos;                    // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre POSITION
-    bool ack_park;	             // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre PARK
-    bool ack_abort;                  // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre ABORT
-    bool ack_goto;                   // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre GOTO
-    bool GotoOk;                     // Est-ce que le dernier goto est OK ?
+    ServerSocket new_sock;                  // socket permettant de gÃ©rer la connexion avec une antennes
+
+    string IP;                              // IP de l'antenne
+
+    char status;                            // status='B' pour bus,  'R' pour READY
+
+    int sendalertes;                        // une requÃªte 'send' a gÃ©nÃ©rÃ© une erreur sur le rÃ©seau
+    int AttenteExecution;	            // L'antenne parvient-elle Ã  executer un cycle de commandes ?
+    int AnomaliesExecution;	            // Erreur critique. L'antenne ne rÃ©pond plus !
+    int etape;                              // Ã©tape dans le cycle de commandes/rÃ©ponses entre PC et microcontroleurs
+
+    bool Connected;                         // le micro-contrÃŽleur est-il connectÃ© ?
+    bool PosValides;                        // le micro-contrÃŽleur a-t-il donnÃ© une position des moteurs valide ?
+    bool ack_status;                        // Etat des acknowledges ?
+    bool ack_pos;                           // le PC a-t-il reÃ§u une confirmation du microcontroleurs aprÃšs un ordre POSITION ?
+    bool ack_park;	                    // le PC a-t-il reÃ§u une confirmation du microcontroleurs aprÃšs un ordre PARK ?
+    bool ack_abort;                         // le PC a-t-il reÃ§u une confirmation du microcontroleurs aprÃšs un ordre ABORT ?
+    bool ack_goto;                          // le PC a-t-il reÃ§u une confirmation du microcontroleurs aprÃšs un ordre GOTO ?
+    bool GotoOk;                            // Est-ce que le dernier goto est OK ?
+
+    Position TargetPosition;                // Position Ã  atteindre
+    Position Pos;                           // derniÃšre position retournÃ©e par le microcontrÃŽleur
     
-    
-};
-
-
-ServerSocket server( 8000 );         // Le PC et les antennes communiquent par le biais du port 8000 sur le rÃ©seau tcp
+    Alignement *AlignementAntenne;          // Contient les paramÃštres d'alignement de l'antenne  
+}; 
+
+
+// Le PC et les antennes communiquent par le biais du port 8000 sur le rÃ©seau Ethernet
+
+ServerSocket server( 8000 );         
 
 class BAO : public Astro
@@ -88,4 +87,8 @@
     ~BAO();
 
+    /*******************************************************/
+    /* Gestion de l'interface intÃ©grÃ©e dans KStars
+    ********************************************************/
+
     void ISGetProperties (const char *dev);
     void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
@@ -94,13 +97,17 @@
     void ISPoll ();
 
+    /*******************************************************/
+    /* Gestion des threads
+    ********************************************************/
+
     void *pThreadSocket ();
     void *pThreadExit ();
 
+    /*******************************************************/
+    /* Les commandes
+    ********************************************************/
+
     bool COMMANDE(int numsocket, char* Commande, char* Params);
     bool ExtractPosition(string str, Position *result);
-
-    void connection_lost();
-    void connection_resumed();
-
     bool STATUS(int numsocket);
     bool POSITION(int numsocket);
@@ -108,18 +115,16 @@
     bool PARK(int numsocket);
     bool GOTO(int numsocket, int deltaAz, int deltaAlt);
-    void ADDEC2Motor(double newRA, double newDEC);
+
+
+    /*******************************************************/
+    /* Connection Routines
+    ********************************************************/
+    void init_properties();
+    void connect_telescope();
+    bool is_connected(void);
     int  AntennesConnectees();
     void DeconnecterSocket(int num);
     void InitAntennes();
-    bool ChargementParametresAlignement(string fileName);
-    bool is_readable( const std::string & file );
-  
-    /*******************************************************/
-    /* Connection Routines
-    ********************************************************/
-    void init_properties();
-    void get_initial_data();
-    void connect_telescope();
-    bool is_connected(void);
+
 
     /*******************************************************/
@@ -127,5 +132,6 @@
     ********************************************************/
     bool process_coords();
-    int get_switch_index(ISwitchVectorProperty *sp);
+    int  get_switch_index(ISwitchVectorProperty *sp);
+    void ADDEC2Motor(double newRA, double newDEC);
 
     /*******************************************************/
@@ -137,9 +143,9 @@
     /* Error handling routines
     ********************************************************/
-    void slew_error(int slewCode);
     void reset_all_properties();
     void handle_error(INumberVectorProperty *nvp, int err, const char *msg);
     void correct_fault();
-
+    void connection_lost();
+    void connection_resumed();
 
 
@@ -147,8 +153,11 @@
 
     enum BAO_STATUS { BAO_TRANSIT, BAO_TRACKING, BAO_PARK };
+
+    // ParamÃštres par dÃ©faut d'un pilote indi
 
     /* Switches */
     ISwitch ConnectS[2];
     ISwitch OnCoordSetS[2];
+    ISwitch AlignmentS[3];
     ISwitch AbortSlewS[1];
     ISwitch ParkS[1];
@@ -159,25 +168,21 @@
 
     /* Numbers */
-    //INumber EquatorialCoordsRN[2];
     INumber EquatorialCoordsWN[2];
     INumber GeographicCoordsWN[2];
+    INumber PressionTempWN[2];
     INumber ActualisationN1[1];
     INumber ActualisationN2[1];
-
-    //INumber SlewAccuracyN[2];
-    //INumber TrackAccuracyN[2];
 
     /* Switch Vectors */
     ISwitchVectorProperty ConnectSP;
     ISwitchVectorProperty OnCoordSetSP;
+    ISwitchVectorProperty AlignmentSP;
     ISwitchVectorProperty AbortSlewSP;
     ISwitchVectorProperty ParkSP;
 
     /* Number Vectors */
-    //INumberVectorProperty EquatorialCoordsRNP;
     INumberVectorProperty EquatorialCoordsWNP;
     INumberVectorProperty GeographicCoordsWNP;
-    //INumberVectorProperty SlewAccuracyNP;
-    //INumberVectorProperty TrackAccuracyNP;
+    INumberVectorProperty PressionTempWNP;
     INumberVectorProperty ActualisationNP1;
     INumberVectorProperty ActualisationNP2;
@@ -191,29 +196,31 @@
 
 protected:
+
     int SocketsNumber;                   // nbre de sockets utilisÃ©s pour connecter les antennes
-    bool InitThreadOK;                   // Le thread est bien actif
-    DefSocket Sockets[MAXHOSTNAME + 1];  // Etat de chaque socket. Un socket permet la communication avec une antenne
+    bool InitThreadOK;                   // Le thread est-t-il  actif ?
+    DefSocket Sockets[MAXHOSTNAME + 1];  // DÃ©finit chaque socket. Un socket permet la communication avec une antenne
     pthread_t th1;                       // le pointeur du thread
 
     double JD;				 // Jour julien
-    double lastRA;                       // Sauvegarde de la derniÃšre position avant actualisation
-    double lastDEC;
+    double lastRA;                       // Sauvegarde de la derniÃšre position avant actualisation, ici l'AD...
+    double lastDEC;                      // ...et la dÃ©clinaison
     double JJAnc;                        // Sauvegarde du jour julien lors de la derniÃšre actualisation de la position (fct Goto)
-    double ActualisationTM1;             // DÃ©lais entre deux actualisations dans les modes transit et tracking
-    double ActualisationTM2;
+    double ActualisationTMTransit;       // DÃ©lai entre deux actualisations dans les modes transit
+    double ActualisationTMTracking;      //  "                 "                     "     tracking
     double Longitude;			 // Longitude et latitude du lieu d'observation
     double Latitude;
-    bool   ActualisationPosition;        // Permet de faire les Ã©tapes nÃ©cessaires pour rÃ©aliser un mouvement
+    double Pression;			 // Pression et tempÃ©rature sur le lieu d'observation
+    double Temp;    
+    bool   RealisationGoto;              // Permet de rÃ©aliser les diffÃ©rentes Ã©tapes nÃ©cessaires Ã  la rÃ©alisation d'un goto
+                                         // tant qu'un goto n'est pas terminÃ©, ActualisationPosition = true
     bool   Abort;			 // Annulation du mouvement en cours
     bool   Park;			 // On place les antennes dans une position de repos
-    bool   Suivi;			 // Suivi d'un objet en cours...
-    bool   UpdateGoto;			 // On peut exÃ©cuter un Goto
+    bool   Suivi;			 // Est-ce que les antennes suivent actuellement un objet ?
+    bool   UpdatedGoto;			 // On peut exÃ©cuter un Goto
     bool   Exit;                         // On ferme le driver
 
-    int    currentSet;                   // Variable interne de l'interface indi
-    int    lastSet;                      // Variable interne de l'interface indi
-    int    TrackingMode;                 //1 : Transit           2: Tracking
-
-    Position TargetPosition;             //Position Ã  atteindre en coordonnÃ©es Ã©quatoriales
+    int    currentSet;                   // mode de suivi actuel - tracking ou transit
+    int    lastSet;                      // Variable interne de l'interface indi - ne pas toucher
+    int    TrackingMode;                 // 1 : Transit           2: Tracking
 };
 
Index: /BAORadio/libindi/libindi/drivers/telescope/celestrongps.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/celestrongps.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/celestrongps.cpp	(revision 642)
@@ -525,7 +525,8 @@
 
 	 if (IUUpdateSwitch(&MovementNSSP, states, names, n) < 0)
-		return;
-
-	current_move = getOnSwitch(&SlewModeSP);
+        IDLog("fixme!!! - IUUpdateSwitch MovementNSSP\n");
+	//	return;
+
+	current_move = getOnSwitch(&MovementNSSP);
 
 	// Previosuly active switch clicked again, so let's stop.
@@ -569,7 +570,8 @@
 
 	 if (IUUpdateSwitch(&MovementWESP, states, names, n) < 0)
-		return;
-
-	current_move = getOnSwitch(&SlewModeSP);
+        IDLog("fixme!!! - IUUpdateSwitch MovementWESP\n");
+		//return;
+
+	current_move = getOnSwitch(&MovementWESP);
 
 	// Previosuly active switch clicked again, so let's stop.
Index: /BAORadio/libindi/libindi/drivers/telescope/celestronprotocol.c
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/celestronprotocol.c	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/celestronprotocol.c	(revision 642)
@@ -286,10 +286,10 @@
     {
       slewCmd[2] = 0x10; 
-      slewCmd[3] = 0x24;
+      slewCmd[3] = 0x25;
     }
   else if(direction == SOUTH)
     {
       slewCmd[2] = 0x11; 
-      slewCmd[3] = 0x24;
+      slewCmd[3] = 0x25;
     }
   else if(direction == WEST)
Index: /BAORadio/libindi/libindi/drivers/telescope/lx200driver.c
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/lx200driver.c	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/lx200driver.c	(revision 642)
@@ -88,5 +88,5 @@
 int setCommandXYZ(int fd, int x, int y, int z, const char *cmd);
 /* Common routine for Set commands */
-int setStandardProcedure(int fd, char * writeData);
+int setStandardProcedure(int fd, const char * writeData);
 /* Set Slew Mode */
 int setSlewMode(int fd, int slewMode);
@@ -220,6 +220,10 @@
   /*if ( (read_ret = portRead(temp_string, -1, LX200_TIMEOUT)) < 1)
      return read_ret;*/
-  tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
- 
+
+  error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
+  tcflush(fd, TCIFLUSH);
+  if (error_type != TTY_OK)
+    return error_type;
+
   temp_string[nbytes_read - 1] = '\0';
   
@@ -251,5 +255,8 @@
    return error_type;
   
-  tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
+  error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
+  tcflush(fd, TCIFLUSH);
+  if (error_type != TTY_OK)
+    return error_type;
  
   temp_string[nbytes_read - 1] = '\0';
@@ -685,5 +692,5 @@
 **********************************************************************/
 
-int setStandardProcedure(int fd, char * data)
+int setStandardProcedure(int fd, const char * data)
 {
  char bool_return[2];
Index: /BAORadio/libindi/libindi/drivers/telescope/lx200driver.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/lx200driver.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/lx200driver.h	(revision 642)
@@ -174,5 +174,5 @@
 int setCommandXYZ(int fd, int x, int y, int z, const char *cmd);
 /* Common routine for Set commands */
-int setStandardProcedure(int fd, char * writeData);
+int setStandardProcedure(int fd, const char * writeData);
 /* Set Slew Mode */
 int setSlewMode(int fd, int slewMode);
Index: /BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp	(revision 642)
@@ -33,4 +33,5 @@
 #include "lx200ap.h"
 #include "lx200classic.h"
+#include "lx200fs2.h"
 
 #include <config.h>
@@ -331,4 +332,5 @@
   changeLX200ClassicDeviceName(newName);
   changeLX200GPSDeviceName(newName);
+  changeLX200FS2DeviceName(newName);
 }
 
@@ -464,4 +466,25 @@
 
    MaxReticleFlashRate = 9;
+ }
+ else if (strstr(me, "indi_lx200fs2"))
+ {
+   fprintf(stderr , "initilizaing from fs2 device...\n");
+  
+   // 2. device = sub_class
+   telescope = new LX200Fs2();
+	 
+   if (envDev != NULL)
+   {
+	   // 1. change device name
+	   changeAllDeviceNames(envDev);
+	   telescope->setCurrentDeviceName(envDev);
+   }
+   else
+   {
+	  // 1. change device name
+	  changeAllDeviceNames("LX200 FS2");
+      telescope->setCurrentDeviceName("LX200 FS2");
+   }
+   
  }
  // be nice and give them a generic device
Index: /BAORadio/libindi/libindi/drivers/telescope/lx200generic.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/lx200generic.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/lx200generic.h	(revision 642)
@@ -45,9 +45,9 @@
  int checkPower(ISwitchVectorProperty *sp);
  int checkPower(ITextVectorProperty *tp);
- void handleError(ISwitchVectorProperty *svp, int err, const char *msg);
- void handleError(INumberVectorProperty *nvp, int err, const char *msg);
- void handleError(ITextVectorProperty *tvp, int err, const char *msg);
+ virtual void handleError(ISwitchVectorProperty *svp, int err, const char *msg);
+ virtual void handleError(INumberVectorProperty *nvp, int err, const char *msg);
+ virtual void handleError(ITextVectorProperty *tvp, int err, const char *msg);
  bool isTelescopeOn(void);
- void connectTelescope();
+ virtual void connectTelescope();
  void slewError(int slewCode);
  void getAlignment();
@@ -80,5 +80,4 @@
   int    currentSet;
   int    lastSet;
-  
 
 };
Index: /BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp	(revision 642)
@@ -2,21 +2,19 @@
   Copyright(c) 2010 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
+
 #include "synscanmount.h"
 #include "libs/indicom.h"
@@ -39,4 +37,5 @@
 void ISPoll(void *p);
 
+#define isDebug() true
 
 void ISInit()
@@ -110,5 +109,5 @@
 bool SynscanMount::initProperties()
 {
-    if (isDebug())
+    //if (isDebug())
         IDLog("Synscan::init_properties\n");
 
@@ -120,5 +119,5 @@
 void SynscanMount::ISGetProperties (const char *dev)
 {
-    if (isDebug())
+    //if (isDebug())
         IDLog("Enter SynscanMount::ISGetProperties %s\n",dev);
 
@@ -139,5 +138,5 @@
     int n1,n2;
 
-    //IDLog("Read Status\n");
+    //IDLog("SynScan Read Status\n");
     //tty_write(PortFD,(unsigned char *)"Ka",2, &bytesWritten);  //  test for an echo
 
@@ -147,5 +146,5 @@
     {
         //  this is not a correct echo
-        if (isDebug())
+        //if (isDebug())
             IDLog("ReadStatus Echo Fail\n");
         IDMessage(deviceName(),"Mount Not Responding");
@@ -192,5 +191,6 @@
     tty_write(PortFD,"e",1, &bytesWritten);
     numread=tty_read(PortFD,str,18,1, &bytesRead);
-    if (numread!=18)
+    if (bytesRead!=18)
+	//if(str[17] != '#')
     {
         IDLog("read status bytes didn't get a full read\n");
@@ -230,5 +230,5 @@
     TrackState=SCOPE_SLEWING;
     numread=tty_read(PortFD,str,1,60, &bytesRead);
-    if (numread!=1||str[0]!='#')
+    if (bytesRead!=1||str[0]!='#')
     {
         if (isDebug())
@@ -258,5 +258,5 @@
     tty_write(PortFD,"T0",2, &bytesWritten);
     numread=tty_read(PortFD,str,1,60, &bytesRead);
-    if (numread!=1||str[0]!='#')
+    if (bytesRead!=1||str[0]!='#')
     {
         if (isDebug())
@@ -268,5 +268,5 @@
     tty_write(PortFD,"B0000,4000",10, &bytesWritten);
     numread=tty_read(PortFD,str,1,60, &bytesRead);
-    if (numread!=1||str[0]!='#')
+    if (bytesRead!=1||str[0]!='#')
     {
         if (isDebug())
Index: /BAORadio/libindi/libindi/drivers/telescope/synscanmount.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/synscanmount.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/synscanmount.h	(revision 642)
@@ -2,20 +2,17 @@
   Copyright(c) 2010 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -39,4 +36,5 @@
         const char *getDefaultName();
 
+        //virtual bool Connect() {return true;}
         bool ReadScopeStatus();
         bool Goto(double,double);
Index: /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp	(revision 642)
@@ -13,7 +13,22 @@
 std::auto_ptr<ScopeSim> telescope_sim(0);
 
-#define	SLEWRATE	1				/* slew rate, degrees/s */
+#define	GOTO_RATE	2				/* slew rate, degrees/s */
+#define	SLEW_RATE	0.5				/* slew rate, degrees/s */
+#define FINE_SLEW_RATE  0.1                             /* slew rate, degrees/s */
+#define SID_RATE	0.004178			/* sidereal rate, degrees/s */
+
+#define GOTO_LIMIT      5                               /* Move at GOTO_RATE until distance from target is GOTO_LIMIT degrees */
+#define SLEW_LIMIT      2                               /* Move at SLEW_LIMIT until distance from target is SLEW_LIMIT degrees */
+#define FINE_SLEW_LIMIT 0.5                             /* Move at FINE_SLEW_RATE until distance from target is FINE_SLEW_LIMIT degrees */
+
 #define	POLLMS		250				/* poll period, ms */
-#define SIDRATE		0.004178			/* sidereal rate, degrees/s */
+
+#define RA_AXIS         0
+#define DEC_AXIS        1
+#define GUIDE_NORTH     0
+#define GUIDE_SOUTH     1
+#define GUIDE_WEST      0
+#define GUIDE_EAST      1
+
 
 
@@ -80,4 +95,15 @@
     currentDEC=15;
     Parked=false;
+
+    GuideNSNP = new INumberVectorProperty;
+    GuideWENP = new INumberVectorProperty;
+    EqPECNV = new INumberVectorProperty;
+    GuideRateNP = new INumberVectorProperty;
+
+    PECErrNSSP = new ISwitchVectorProperty;
+    PECErrWESP = new ISwitchVectorProperty;
+
+    /* initialize random seed: */
+      srand ( time(NULL) );
 }
 
@@ -90,4 +116,104 @@
 {
     return (char *)"Telescope Simulator";
+}
+
+bool ScopeSim::initProperties()
+{
+    /* Make sure to init parent properties first */
+    INDI::Telescope::initProperties();
+
+    /* Property for guider support. How many seconds to guide either northward or southward? */
+    IUFillNumber(&GuideNSN[GUIDE_NORTH], "TIMED_GUIDE_N", "North (sec)", "%g", 0, 10, 0.001, 0);
+    IUFillNumber(&GuideNSN[GUIDE_SOUTH], "TIMED_GUIDE_S", "South (sec)", "%g", 0, 10, 0.001, 0);
+    IUFillNumberVector(GuideNSNP, GuideNSN, 2, deviceName(), "TELESCOPE_TIMED_GUIDE_NS", "Guide North/South", MOTION_TAB, IP_RW, 0, IPS_IDLE);
+
+    /* Property for guider support. How many seconds to guide either westward or eastward? */
+    IUFillNumber(&GuideWEN[GUIDE_WEST], "TIMED_GUIDE_W", "West (sec)", "%g", 0, 10, 0.001, 0);
+    IUFillNumber(&GuideWEN[GUIDE_EAST], "TIMED_GUIDE_E", "East (sec)", "%g", 0, 10, 0.001, 0);
+    IUFillNumberVector(GuideWENP, GuideWEN, 2, deviceName(), "TELESCOPE_TIMED_GUIDE_WE", "Guide West/East", MOTION_TAB, IP_RW, 0, IPS_IDLE);
+
+    /* Simulated periodic error in RA, DEC */
+    IUFillNumber(&EqPECN[RA_AXIS],"RA_PEC","RA (hh:mm:ss)","%010.6m",0,24,0,15.);
+    IUFillNumber(&EqPECN[DEC_AXIS],"DEC_PEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,15.);
+    IUFillNumberVector(EqPECNV,EqPECN,2,deviceName(),"EQUATORIAL_PEC","Periodic Error",MOTION_TAB,IP_RO,60,IPS_IDLE);
+
+    /* Enable client to manually add periodic error northward or southward for simulation purposes */
+    IUFillSwitch(&PECErrNSS[MOTION_NORTH], "PEC_N", "North", ISS_OFF);
+    IUFillSwitch(&PECErrNSS[MOTION_SOUTH], "PEC_S", "South", ISS_OFF);
+    IUFillSwitchVector(PECErrNSSP, PECErrNSS, 2, deviceName(),"PEC_NS", "PE N/S", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
+
+    /* Enable client to manually add periodic error westward or easthward for simulation purposes */
+    IUFillSwitch(&PECErrWES[MOTION_WEST], "PEC_W", "West", ISS_OFF);
+    IUFillSwitch(&PECErrWES[MOTION_EAST], "PEC_E", "East", ISS_OFF);
+    IUFillSwitchVector(PECErrWESP, PECErrWES, 2, deviceName(),"PEC_WE", "PE W/E", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
+
+    /* How fast do we guide compared to sideral rate */
+    IUFillNumber(&GuideRateN[RA_AXIS], "GUIDE_RATE_WE", "W/E Rate", "%g", 0, 1, 0.1, 0.3);
+    IUFillNumber(&GuideRateN[DEC_AXIS], "GUIDE_RATE_NS", "N/S Rate", "%g", 0, 1, 0.1, 0.3);
+    IUFillNumberVector(GuideRateNP, GuideRateN, 2, deviceName(), "GUIDE_RATE", "Guiding Rate", MOTION_TAB, IP_RW, 0, IPS_IDLE);
+
+    /* Add debug controls so we may debug driver if necessary */
+    addDebugControl();
+
+    return true;
+}
+
+void ScopeSim::ISGetProperties (const char *dev)
+{
+    /* First we let our parent populate */
+    INDI::Telescope::ISGetProperties(dev);
+
+    if(isConnected())
+    {
+        defineNumber(GuideNSNP);
+        defineNumber(GuideWENP);
+        defineNumber(GuideRateNP);
+        defineNumber(EqPECNV);
+        defineSwitch(PECErrNSSP);
+        defineSwitch(PECErrWESP);
+    }
+
+    return;
+}
+
+bool ScopeSim::updateProperties()
+{
+    INDI::Telescope::updateProperties();
+
+    if (isConnected())
+    {
+        defineNumber(GuideNSNP);
+        defineNumber(GuideWENP);
+        defineNumber(GuideRateNP);
+        defineNumber(EqPECNV);
+        defineSwitch(PECErrNSSP);
+        defineSwitch(PECErrWESP);
+
+    }
+    else
+    {
+        deleteProperty(GuideNSNP->name);
+        deleteProperty(GuideWENP->name);
+        deleteProperty(EqPECNV->name);
+        deleteProperty(PECErrNSSP->name);
+        deleteProperty(PECErrNSSP->name);
+        deleteProperty(GuideRateNP->name);
+    }
+
+    return true;
+}
+
+bool ScopeSim::Connect()
+{
+    bool rc=false;
+
+    if(isConnected()) return true;
+
+    rc=Connect(PortT[0].text);
+
+    if(rc)
+        SetTimer(POLLMS);
+
+    return rc;
 }
 
@@ -106,6 +232,8 @@
     static struct timeval ltv;
     struct timeval tv;
-    double dt, da, dx;
-    int nlocked;
+    double dt=0, da_ra=0, da_dec=0, dx=0, dy=0, ra_guide_dt=0, dec_guide_dt=0;
+    static double last_dx=0, last_dy=0;
+    int nlocked, ns_guide_dir=-1, we_guide_dir=-1;
+    char RA_DISP[64], DEC_DISP[64], RA_GUIDE[64], DEC_GUIDE[64], RA_PEC[64], DEC_PEC[64], RA_TARGET[64], DEC_TARGET[64];
 
 
@@ -118,9 +246,53 @@
     dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6;
     ltv = tv;
-    da = SLEWRATE*dt;
+
+    if ( fabs(targetRA - currentRA)*15. >= GOTO_LIMIT )
+        da_ra = GOTO_RATE *dt;
+    else if ( fabs(targetRA - currentRA)*15. >= SLEW_LIMIT )
+        da_ra = SLEW_RATE *dt;
+    else
+        da_ra = FINE_SLEW_RATE *dt;
+
+    if ( fabs(targetDEC - currentDEC) >= GOTO_LIMIT )
+        da_dec = GOTO_RATE *dt;
+    else if ( fabs(targetDEC - currentDEC) >= SLEW_LIMIT )
+        da_dec = SLEW_RATE *dt;
+    else
+        da_dec = FINE_SLEW_RATE *dt;
+
+    switch (MovementNSSP->s)
+    {
+       case IPS_BUSY:
+        if (MovementNSS[MOTION_NORTH].s == ISS_ON)
+            currentDEC += da_dec;
+        else if (MovementNSS[MOTION_SOUTH].s == ISS_ON)
+            currentDEC -= da_dec;
+
+        NewRaDec(currentRA, currentDEC);
+        return true;
+        break;
+    }
+
+    switch (MovementWESP->s)
+    {
+        case IPS_BUSY:
+
+        if (MovementWES[MOTION_WEST].s == ISS_ON)
+            currentRA += da_ra/15.;
+        else if (MovementWES[MOTION_EAST].s == ISS_ON)
+            currentRA -= da_ra/15.;
+
+        NewRaDec(currentRA, currentDEC);
+        return true;
+        break;
+
+    }
 
     /* Process per current state. We check the state of EQUATORIAL_EOD_COORDS_REQUEST and act acoordingly */
     switch (TrackState)
     {
+    case SCOPE_IDLE:
+        EqNV->s = IPS_IDLE;
+        break;
     case SCOPE_SLEWING:
     case SCOPE_PARKING:
@@ -130,5 +302,5 @@
         dx = targetRA - currentRA;
 
-        if (fabs(dx) <= da)
+        if (fabs(dx)*15. <= da_ra)
         {
             currentRA = targetRA;
@@ -136,29 +308,36 @@
         }
         else if (dx > 0)
-            currentRA += da/15.;
+            currentRA += da_ra/15.;
         else
-            currentRA -= da/15.;
-
-
-        dx = targetDEC - currentDEC;
-        if (fabs(dx) <= da)
+            currentRA -= da_ra/15.;
+
+
+        dy = targetDEC - currentDEC;
+        if (fabs(dy) <= da_dec)
         {
             currentDEC = targetDEC;
             nlocked++;
         }
-        else if (dx > 0)
-          currentDEC += da;
+        else if (dy > 0)
+          currentDEC += da_dec;
         else
-          currentDEC -= da;
+          currentDEC -= da_dec;
+
+        EqNV->s = IPS_BUSY;
 
         if (nlocked == 2)
         {
-            //eqNP.s = IPS_OK;
-            //eqNPR.s = IPS_OK;
-            //IDSetNumber(&eqNP, NULL);
-            //IDSetNumber(&eqNPR, "Now tracking");
             if (TrackState == SCOPE_SLEWING)
             {
+
+                // Initially no PEC in both axis.
+                EqPECN[0].value = currentRA;
+                EqPECN[1].value = currentDEC;
+
+                IDSetNumber(EqPECNV, NULL);
+
                 TrackState = SCOPE_TRACKING;
+
+                EqNV->s = IPS_OK;
                 IDMessage(deviceName(), "Telescope slew is complete. Tracking...");
             }
@@ -166,9 +345,8 @@
             {
                 TrackState = SCOPE_PARKED;
+                EqNV->s = IPS_IDLE;
                 IDMessage(deviceName(), "Telescope parked successfully.");
             }
         }
-        //else
-          //  IDSetNumber(&eqNP, NULL);
 
         break;
@@ -176,6 +354,115 @@
     case SCOPE_TRACKING:
         /* tracking */
-        /* RA moves at sidereal, Dec stands still */
-         currentRA += (SIDRATE*dt/15.);
+
+        if (GuideNSN[GUIDE_NORTH].value > 0)
+        {
+            if (isDebug())
+                IDLog("  ****** Commanded to GUIDE NORTH for %g ms *****\n", GuideNSN[GUIDE_NORTH].value*1000);
+            ns_guide_dir = GUIDE_NORTH;
+        }
+        else if (GuideNSN[GUIDE_SOUTH].value > 0)
+        {
+            if (isDebug())
+                IDLog("  ****** Commanded to GUIDE SOUTH for %g ms *****\n", GuideNSN[GUIDE_SOUTH].value*1000);
+            ns_guide_dir = GUIDE_SOUTH;
+        }
+
+        // WE Guide Selection
+        if (GuideWEN[GUIDE_WEST].value > 0)
+        {
+            we_guide_dir = GUIDE_WEST;
+            if (isDebug())
+            IDLog("  ****** Commanded to GUIDE WEST for %g ms ****** \n", GuideWEN[GUIDE_WEST].value*1000);
+        }
+        else if (GuideWEN[GUIDE_EAST].value > 0)
+        {
+            we_guide_dir = GUIDE_EAST;
+            if (isDebug())
+               IDLog(" ****** Commanded to GUIDE EAST for %g ms  ****** \n", GuideWEN[GUIDE_EAST].value*1000);
+        }
+
+        if (ns_guide_dir != -1)
+        {
+
+            dec_guide_dt =  SID_RATE * GuideRateN[DEC_AXIS].value * GuideNSN[ns_guide_dir].value * (ns_guide_dir==GUIDE_NORTH ? 1 : -1);
+
+            // If time remaining is more that dt, then decrement and
+          if (GuideNSN[ns_guide_dir].value >= dt)
+              GuideNSN[ns_guide_dir].value -= dt;
+          else              
+              GuideNSN[ns_guide_dir].value = 0;
+
+          EqPECN[DEC_AXIS].value += dec_guide_dt;
+
+            if (GuideNSN[ns_guide_dir].value <= 0)
+            {
+                GuideNSN[GUIDE_NORTH].value = GuideNSN[GUIDE_SOUTH].value = 0;
+                GuideNSNP->s = IPS_OK;
+                IDSetNumber(GuideNSNP, NULL);
+            }
+            else
+                IDSetNumber(GuideNSNP, NULL);
+          }
+
+        if (we_guide_dir != -1)
+        {
+
+            ra_guide_dt = SID_RATE/15.0 * GuideRateN[RA_AXIS].value * GuideWEN[we_guide_dir].value* (we_guide_dir==GUIDE_WEST ? -1 : 1);
+
+          if (GuideWEN[we_guide_dir].value >= dt)
+                GuideWEN[we_guide_dir].value -= dt;
+          else
+                GuideWEN[we_guide_dir].value = 0;
+
+          EqPECN[RA_AXIS].value += ra_guide_dt;
+
+            if (GuideWEN[we_guide_dir].value <= 0)
+            {
+                GuideWEN[GUIDE_WEST].value = GuideWEN[GUIDE_EAST].value = 0;
+                GuideWENP->s = IPS_OK;
+                IDSetNumber(GuideWENP, NULL);
+            }
+            else
+                IDSetNumber(GuideWENP, NULL);
+          }
+
+
+        //Mention the followng:
+        // Current RA displacemet and direction
+        // Current DEC displacement and direction
+        // Amount of RA GUIDING correction and direction
+        // Amount of DEC GUIDING correction and direction
+
+        dx = EqPECN[RA_AXIS].value - targetRA;
+        dy = EqPECN[DEC_AXIS].value - targetDEC;
+        fs_sexa(RA_DISP, fabs(dx), 2, 3600 );
+        fs_sexa(DEC_DISP, fabs(dy), 2, 3600 );
+
+        fs_sexa(RA_GUIDE, fabs(ra_guide_dt), 2, 3600 );
+        fs_sexa(DEC_GUIDE, fabs(dec_guide_dt), 2, 3600 );
+
+        fs_sexa(RA_PEC, EqPECN[RA_AXIS].value, 2, 3600);
+        fs_sexa(DEC_PEC, EqPECN[DEC_AXIS].value, 2, 3600);
+
+        fs_sexa(RA_TARGET, targetRA, 2, 3600);
+        fs_sexa(DEC_TARGET, targetDEC, 2, 3600);
+
+
+        if (isDebug() && (dx!=last_dx || dy!=last_dy || ra_guide_dt || dec_guide_dt))
+        {
+            last_dx=dx;
+            last_dy=dy;
+            IDLog("#########################################\n");
+            IDLog("dt is %g\n", dt);
+            IDLog("RA Displacement (%c%s) %s -- %s of target RA %s\n", dx >= 0 ? '+' : '-', RA_DISP, RA_PEC,  (EqPECN[RA_AXIS].value - targetRA) > 0 ? "East" : "West", RA_TARGET);
+            IDLog("DEC Displacement (%c%s) %s -- %s of target RA %s\n", dy >= 0 ? '+' : '-', DEC_DISP, DEC_PEC, (EqPECN[DEC_AXIS].value - targetDEC) > 0 ? "North" : "South", DEC_TARGET);
+            IDLog("RA Guide Correction (%g) %s -- Direction %s\n", ra_guide_dt, RA_GUIDE, ra_guide_dt > 0 ? "East" : "West");
+            IDLog("DEC Guide Correction (%g) %s -- Direction %s\n", dec_guide_dt, DEC_GUIDE, dec_guide_dt > 0 ? "North" : "South");
+            IDLog("#########################################\n");
+        }
+
+        if (ns_guide_dir != -1 || we_guide_dir != -1)
+            IDSetNumber(EqPECNV, NULL);
+
          break;
 
@@ -200,4 +487,8 @@
     Parked=false;
     TrackState = SCOPE_SLEWING;
+
+    EqReqNV->s = IPS_BUSY;
+    EqNV->s    = IPS_BUSY;
+
     IDMessage(deviceName(), "Slewing to RA: %s - DEC: %s", RAStr, DecStr);
     return true;
@@ -214,28 +505,192 @@
 }
 
-bool ScopeSim::Connect()
-{
-    //  Parent class is wanting a connection
-    //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
-    bool rc=false;
-
-    if(isConnected()) return true;
-
-    //IDLog("Calling Connect\n");
-
-    rc=Connect(PortT[0].text);
-
-    if(rc)
-        SetTimer(POLLMS);
-    return rc;
-}
-
-
-
-/* update the "mount" over time */
-void mountSim (void *p)
-{
-
-}
-
-
+bool ScopeSim::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //  first check if it's for our device
+
+    if(strcmp(dev,deviceName())==0)
+    {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+         if(strcmp(name,"TELESCOPE_TIMED_GUIDE_NS")==0)
+         {
+
+             // Unless we're in track mode, we don't obey guide commands.
+             if (TrackState != SCOPE_TRACKING)
+             {
+                 GuideNSNP->s = IPS_IDLE;
+                 IDSetNumber(GuideNSNP, NULL);
+                 return true;
+             }
+
+             IUUpdateNumber(GuideNSNP, values, names, n);
+
+           return true;
+         }
+
+         if(strcmp(name,"TELESCOPE_TIMED_GUIDE_WE")==0)
+         {
+             // Unless we're in track mode, we don't obey guide commands.
+             if (TrackState != SCOPE_TRACKING)
+             {
+                 GuideWENP->s = IPS_IDLE;
+                 IDSetNumber(GuideWENP, NULL);
+                 return true;
+             }
+
+             IUUpdateNumber(GuideWENP, values, names, n);
+
+           return true;
+         }
+
+         if(strcmp(name,"GUIDE_RATE")==0)
+         {
+             IUUpdateNumber(GuideRateNP, values, names, n);
+             GuideRateNP->s = IPS_OK;
+             IDSetNumber(GuideRateNP, NULL);
+             return true;
+         }
+
+    }
+
+    //  if we didn't process it, continue up the chain, let somebody else
+    //  give it a shot
+    return INDI::Telescope::ISNewNumber(dev,name,values,names,n);
+}
+
+bool ScopeSim::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    //IDLog("Enter IsNewSwitch for %s\n",name);
+    //for(int x=0; x<n; x++) {
+    //    IDLog("Switch %s %d\n",names[x],states[x]);
+    //}
+
+    if(strcmp(dev,deviceName())==0)
+    {
+        if(strcmp(name,"PEC_NS")==0)
+        {
+            IUUpdateSwitch(PECErrNSSP,states,names,n);
+
+            PECErrNSSP->s = IPS_OK;
+
+            if (PECErrNSS[MOTION_NORTH].s == ISS_ON)
+            {
+                EqPECN[DEC_AXIS].value += SID_RATE * GuideRateN[DEC_AXIS].value;
+                if (isDebug())
+                    IDLog("$$$$$ Simulating PE in NORTH direction for value of %g $$$$$\n", SID_RATE);
+            }
+            else
+            {
+                EqPECN[DEC_AXIS].value -= SID_RATE * GuideRateN[DEC_AXIS].value;
+                if (isDebug())
+                    IDLog("$$$$$ Simulating PE in SOUTH direction for value of %g $$$$$\n", SID_RATE);
+            }
+
+            IUResetSwitch(PECErrNSSP);
+            IDSetSwitch(PECErrNSSP, NULL);
+            IDSetNumber(EqPECNV, NULL);
+
+            return true;
+
+        }
+
+        if(strcmp(name,"PEC_WE")==0)
+        {
+            IUUpdateSwitch(PECErrWESP,states,names,n);
+
+            PECErrWESP->s = IPS_OK;
+
+            if (PECErrWES[MOTION_WEST].s == ISS_ON)
+            {
+                EqPECN[RA_AXIS].value -= SID_RATE/15. * GuideRateN[RA_AXIS].value;
+                if (isDebug())
+                    IDLog("$$$$$ Simulator PE in WEST direction for value of %g $$$$$$\n", SID_RATE);
+            }
+            else
+            {
+                EqPECN[RA_AXIS].value += SID_RATE/15. * GuideRateN[RA_AXIS].value;
+                if (isDebug())
+                    IDLog("$$$$$$ Simulator PE in EAST direction for value of %g $$$$$$\n", SID_RATE);
+            }
+
+            IUResetSwitch(PECErrWESP);
+            IDSetSwitch(PECErrWESP, NULL);
+            IDSetNumber(EqPECNV, NULL);
+
+            return true;
+
+        }
+
+    }
+
+    //  Nobody has claimed this, so, ignore it
+    return INDI::Telescope::ISNewSwitch(dev,name,states,names,n);
+}
+
+
+
+bool ScopeSim::MoveNS(TelescopeMotionNS dir)
+{
+    static int last_motion=-1;
+
+    switch (dir)
+    {
+      case MOTION_NORTH:
+        if (last_motion != MOTION_NORTH)
+            last_motion = MOTION_NORTH;
+        else
+        {
+            IUResetSwitch(MovementNSSP);
+            MovementNSSP->s = IPS_IDLE;
+            IDSetSwitch(MovementNSSP, NULL);
+        }
+        break;
+
+    case MOTION_SOUTH:
+      if (last_motion != MOTION_SOUTH)
+          last_motion = MOTION_SOUTH;
+      else
+      {
+          IUResetSwitch(MovementNSSP);
+          MovementNSSP->s = IPS_IDLE;
+          IDSetSwitch(MovementNSSP, NULL);
+      }
+      break;
+    }
+
+    return true;
+}
+
+bool ScopeSim::MoveWE(TelescopeMotionWE dir)
+{
+    static int last_motion=-1;
+
+    switch (dir)
+    {
+      case MOTION_WEST:
+        if (last_motion != MOTION_WEST)
+            last_motion = MOTION_WEST;
+        else
+        {
+            IUResetSwitch(MovementWESP);
+            MovementWESP->s = IPS_IDLE;
+            IDSetSwitch(MovementWESP, NULL);
+        }
+        break;
+
+    case MOTION_EAST:
+      if (last_motion != MOTION_EAST)
+          last_motion = MOTION_EAST;
+      else
+      {
+          IUResetSwitch(MovementWESP);
+          MovementWESP->s = IPS_IDLE;
+          IDSetSwitch(MovementWESP, NULL);
+      }
+      break;
+    }
+
+    return true;
+
+}
+
Index: /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h	(revision 642)
@@ -15,4 +15,25 @@
 
         bool Parked;
+
+        INumber GuideNSN[2];
+        INumberVectorProperty *GuideNSNP;
+
+
+        INumber GuideWEN[2];
+        INumberVectorProperty *GuideWENP;
+
+        INumber GuideRateN[2];
+        INumberVectorProperty *GuideRateNP;
+
+        INumberVectorProperty *EqPECNV;
+        INumber EqPECN[2];
+
+        ISwitch PECErrNSS[2];
+        ISwitchVectorProperty *PECErrNSSP;
+
+        ISwitch PECErrWES[2];
+        ISwitchVectorProperty *PECErrWESP;
+
+
     public:
         ScopeSim();
@@ -24,4 +45,12 @@
         virtual bool Disconnect();
         virtual bool ReadScopeStatus();
+        virtual bool initProperties();
+        virtual void ISGetProperties (const char *dev);
+        virtual bool updateProperties();
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+
+        virtual bool MoveNS(TelescopeMotionNS dir);
+        virtual bool MoveWE(TelescopeMotionWE dir);
 
         bool Goto(double,double);
Index: /BAORadio/libindi/libindi/drivers/telescope/temmadriver.c
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/temmadriver.c	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/telescope/temmadriver.c	(revision 642)
@@ -803,5 +803,5 @@
 
 	if((status=portRead(local_buffer,-1,TEMMA_TIMEOUT)==SUCCESS)){
-		if(strstr(local_buffer, "stn")==local_buffer){
+                if( ( (unsigned char *) strstr(local_buffer, "stn"))==local_buffer){
 			local_buffer[7]=0;
 			if (strstr(local_buffer,"on")){ /* stanby on */
Index: /BAORadio/libindi/libindi/drivers/video/v4ldriver.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/video/v4ldriver.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/drivers/video/v4ldriver.cpp	(revision 642)
@@ -565,6 +565,14 @@
   int status=0; 
 
- fits_update_key(fptr, TLONG, "EXPOSURE", &(V4LFrame->expose), "Total Exposure Time (ms)", &status); 
- fits_update_key(fptr, TSTRING, "INSTRUME", v4l_base->getDeviceName(), "Webcam Name", &status);
+  char keyname[32], comment[64];
+
+ strncpy(keyname, "EXPOSURE", 32);
+ strncpy(comment, "Total Exposure Time (ms)", 64);
+ fits_update_key(fptr, TLONG, keyname , &(V4LFrame->expose), comment, &status);
+
+ strncpy(keyname, "INSTRUME", 32);
+ strncpy(comment, "Webcam Name", 64);
+ fits_update_key(fptr, TSTRING, keyname, v4l_base->getDeviceName(), comment, &status);
+
  fits_write_date(fptr, &status);
 }
Index: /BAORadio/libindi/libindi/eventloop.c
===================================================================
--- /BAORadio/libindi/libindi/eventloop.c	(revision 641)
+++ /BAORadio/libindi/libindi/eventloop.c	(revision 642)
@@ -422,5 +422,5 @@
 	if (ns < 0) {
 	    perror ("select");
-	    exit(1);
+            return;
 	}
 	
@@ -480,5 +480,5 @@
 	if (read (fd, &c, 1) != 1) {
 	    perror ("read");
-	    exit(1);
+            return;
 	}
 
Index: /BAORadio/libindi/libindi/examples/tutorial_dome.c
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_dome.c	(revision 641)
+++ /BAORadio/libindi/libindi/examples/tutorial_dome.c	(revision 642)
@@ -45,4 +45,6 @@
 #define SNOOP_GROUP     "Snooped"
 
+void closeDome();
+
 /* Connect/Disconnect */
 static ISwitch PowerS[]          	= {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
Index: /BAORadio/libindi/libindi/examples/tutorial_four.cpp
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_four.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/examples/tutorial_four.cpp	(revision 642)
@@ -199,5 +199,5 @@
 {
 	// Ignore if not ours 
-        if (strcmp (dev, deviceID))
+        if (strcmp (dev, deviceName()))
             return false;
 
@@ -212,5 +212,5 @@
 	
 	// Ignore if not ours
-        if (strcmp (dev, deviceID))
+        if (strcmp (dev, deviceName()))
             return false;
 
@@ -239,5 +239,5 @@
 {
 	// ignore if not ours //
-        if (strcmp (dev, deviceID))
+        if (strcmp (dev, deviceName()))
             return false;
 
@@ -258,4 +258,6 @@
         }*/
 
+    return DefaultDriver::ISNewSwitch(dev, name, states, names, n);
+
 
 }
Index: /BAORadio/libindi/libindi/indiapi.h
===================================================================
--- /BAORadio/libindi/libindi/indiapi.h	(revision 641)
+++ /BAORadio/libindi/libindi/indiapi.h	(revision 642)
@@ -46,8 +46,9 @@
 <ul>
 <li><a href="indidevapi_8h.html">INDI Device API</a></li>
+<li><a href="classINDI_1_1BaseClient.html">INDI Client API</a></li>
+<li><a href="namespaceINDI.html">INDI Base Drivers</a></li>
 <li><a href="indicom_8h.html">INDI Common Routine Library</a></li>
 <li><a href="lilxml_8h.html">INDI LilXML Library</a></li>
 <li><a href="group__configFunctions.html">Configuration</a></li>
-<li><a href="classINDI_1_1BaseClient.html">Client API</a></li>
 </ul>
 
@@ -75,5 +76,5 @@
 
 /* INDI Library version */
-#define INDI_LIBV	0.8
+#define INDI_LIBV	0.9
 
 /*******************************************************************************
Index: /BAORadio/libindi/libindi/indidriver.c
===================================================================
--- /BAORadio/libindi/libindi/indidriver.c	(revision 641)
+++ /BAORadio/libindi/libindi/indidriver.c	(revision 642)
@@ -236,5 +236,5 @@
   {
     np = IUFindNumber(nvp, names[i]);
-    np->value = values[i];
+    np->value = values[i];  
   }
 
Index: /BAORadio/libindi/libindi/indiserver.c
===================================================================
--- /BAORadio/libindi/libindi/indiserver.c	(revision 641)
+++ /BAORadio/libindi/libindi/indiserver.c	(revision 642)
@@ -752,5 +752,6 @@
     while ( fgets (line, MAXRBUF, fifo.fs) != NULL)
     {
-        fprintf(stderr, "FIFO: %s\n", line);
+        if (verbose)
+            fprintf(stderr, "FIFO: %s\n", line);
 
         tDev[0] = '\0', tDriver[0] = '\0', tConfig[0] = '\0', envDev[0] = '\0', envConfig[0] = '\0';
@@ -789,9 +790,9 @@
                 else if (strstr(token, "\"") || strstr(token, "'"))
                 {
-                    strncat(tDev, ++token, MAXRBUF);
+		    strncat(tDev, ++token, sizeof(tDev)-strlen(tDev)-1);
                     while (token = strsep(&cp, delm) )
                    {
                      strcat(tDev, " ");
-                     strncat(tDev, token, MAXRBUF);
+                     strncat(tDev, token, sizeof(tDev)-strlen(tDev)-1);
                      if ( (tp=strchr(tDev, '\"')) || (tp=strchr(tDev, '\'')))
                      {
@@ -816,9 +817,9 @@
                       if (strstr(token, "\"") || strstr(token, "'"))
                       {
-                       strncat(tConfig, ++token, MAXRBUF);
+                       strncat(tConfig, ++token, sizeof(tConfig)-strlen(tDev)-1);
                        while (token = strsep(&cp, delm) )
                        {
                           strcat(tConfig, " ");
-                          strncat(tConfig, token, MAXRBUF);
+                          strncat(tConfig, token, sizeof(tConfig)-strlen(tDev)-1);
 
                           if ( (tp=strchr(tConfig, '\"')) || (tp=strchr(tConfig, '\'')))
@@ -876,5 +877,5 @@
                   for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++)
                    {
-                       if (!strcmp(dp->name, tDriver))
+                       if (!strcmp(dp->name, tDriver) && dp->active==1)
                        {
                            /* If device name is given, check against it before shutting down */
Index: /BAORadio/libindi/libindi/libindi.pc.cmake
===================================================================
--- /BAORadio/libindi/libindi/libindi.pc.cmake	(revision 641)
+++ /BAORadio/libindi/libindi/libindi.pc.cmake	(revision 642)
@@ -6,7 +6,7 @@
 Name: libindi
 Description: Instrument Neutral Distributed Interface
-URL=http://www.indilib.org/
+URL: http://www.indilib.org/
 Version: @CMAKE_INDI_VERSION_STRING@
-Libs: -L@LIB_DESTINATION@ -lindi
-Cflags: -I@INCLUDE_INSTALL_DIR@ -@INCLUDE_INSTALL_DIR@/libindi
+Libs: -L${libdir} -lindi
+Cflags: -I${includedir} -I${includedir}/libindi
 
Index: /BAORadio/libindi/libindi/libs/indibase/baseclient.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/baseclient.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/baseclient.cpp	(revision 642)
@@ -1,2 +1,20 @@
+/*******************************************************************************
+  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #include <stdlib.h>
 #include <string.h>
@@ -159,8 +177,8 @@
 INDI::BaseDriver * INDI::BaseClient::getDriver(const char * deviceName)
 {
-    vector<devicePtr>::const_iterator devi;
+    vector<INDI::BaseDriver *>::const_iterator devi;
     for ( devi = cDevices.begin(); devi != cDevices.end(); devi++)
         if (!strcmp(deviceName, (*devi)->deviceName()))
-            return (*devi).get();
+            return (*devi);
 
     return NULL;
@@ -170,4 +188,5 @@
 {
   (static_cast<INDI::BaseClient *> (context))->listenINDI();
+  return NULL;
 }
 
@@ -291,16 +310,16 @@
 int INDI::BaseClient::removeDevice( const char * devName, char * errmsg )
 {
-    std::vector<devicePtr>::iterator devicei = cDevices.begin();
-
-    while (devicei != cDevices.end())
+    std::vector<INDI::BaseDriver *>::iterator devicei;
+
+    for (devicei =cDevices.begin(); devicei != cDevices.end();)
     {
       if (strcmp(devName, (*devicei)->deviceName()))
       {
-          cDevices.erase(devicei);
-          //delete (*devicei);
+          delete *devicei;
+          devicei = cDevices.erase(devicei);
           return 0;
       }
-
-      devicei++;
+      else
+          ++devicei;
     }
 
@@ -312,10 +331,10 @@
 {
 
-    std::vector<devicePtr>::const_iterator devicei;
+    std::vector<INDI::BaseDriver *>::const_iterator devicei;
 
     for (devicei = cDevices.begin(); devicei != cDevices.end(); devicei++)
     {
         if (!strcmp(devName, (*devicei)->deviceName()))
-         return (*devicei).get();
+         return (*devicei);
 
     }
@@ -328,5 +347,6 @@
 INDI::BaseDriver * INDI::BaseClient::addDevice (XMLEle *dep, char * errmsg)
 {
-    devicePtr dp(new INDI::BaseDriver());
+    //devicePtr dp(new INDI::BaseDriver());
+    INDI::BaseDriver *dp = new INDI::BaseDriver();
     XMLAtt *ap;
     char * device_name;
@@ -350,5 +370,5 @@
 
     /* ok */
-    return dp.get();
+    return dp;
 }
 
Index: /BAORadio/libindi/libindi/libs/indibase/baseclient.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/baseclient.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/baseclient.h	(revision 642)
@@ -1,2 +1,20 @@
+/*******************************************************************************
+  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #ifndef INDIBASECLIENT_H
 #define INDIBASECLIENT_H
@@ -4,5 +22,4 @@
 #include <vector>
 #include <map>
-#include <boost/shared_ptr.hpp>
 #include <string>
 
@@ -26,4 +43,6 @@
    \attention All notifications functions defined in INDI::BaseMediator must be implemented in the client class even if
    they are not used because these are pure virtual functions.
+
+   \see <a href=http://indilib.org/index.php?title=Learn_how_to_write_INDI_clients>INDI Client Tutorial</a> for more details.
    \author Jasem Mutlaq
 
@@ -33,5 +52,5 @@
 public:
     enum { INDI_DEVICE_NOT_FOUND=-1, INDI_PROPERTY_INVALID=-2, INDI_PROPERTY_DUPLICATED = -3, INDI_DISPATCH_ERROR=-4 };
-    typedef boost::shared_ptr<INDI::BaseDriver> devicePtr;
+    //typedef boost::shared_ptr<INDI::BaseDriver> devicePtr;
 
     BaseClient();
@@ -82,5 +101,5 @@
     /** \returns Returns a vector of all devices created in the client.
     */
-    const vector<devicePtr> & getDrivers() const { return cDevices; }
+    const vector<INDI::BaseDriver *> & getDrivers() const { return cDevices; }
 
     /** \brief Set Binary Large Object policy mode
@@ -152,5 +171,5 @@
     pthread_t listen_thread;
 
-    vector<devicePtr> cDevices;
+    vector<INDI::BaseDriver *> cDevices;
     vector<string> cDeviceNames;
 
Index: /BAORadio/libindi/libindi/libs/indibase/basedriver.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/basedriver.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/basedriver.cpp	(revision 642)
@@ -1,2 +1,20 @@
+/*******************************************************************************
+  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #include <stdlib.h>
 #include <string.h>
@@ -9,13 +27,77 @@
 #include "base64.h"
 
+PropertyContainer::PropertyContainer()
+{
+    pPtr = NULL;
+    pRegistered = false;
+    pDynamic = false;
+    pType = INDI_UNKNOWN;
+}
+
+PropertyContainer::~PropertyContainer()
+{
+    // Only delete properties if they were created dynamically via the buildSkeleton
+    // function. Other drivers are responsible for their own memory allocation.
+    if (pDynamic)
+    {
+        switch (pType)
+        {
+        case INDI_NUMBER:
+         delete ((INumberVectorProperty *) pPtr);
+         break;
+
+        case INDI_TEXT:
+        delete ((ITextVectorProperty *) pPtr);
+        break;
+
+        case INDI_SWITCH:
+        delete ((ISwitchVectorProperty *) pPtr);
+        break;
+
+        case INDI_LIGHT:
+        delete ((ILightVectorProperty *) pPtr);
+        break;
+
+        case INDI_BLOB:
+        delete ((IBLOBVectorProperty *) pPtr);
+        break;
+
+    }
+  }
+}
+
+void PropertyContainer::setProperty(void *p)
+{
+    pRegistered = true;
+    pPtr = p;
+
+}
+
+void PropertyContainer::setType(INDI_TYPE t)
+{
+    pType = t;
+}
+
+void PropertyContainer::setRegistered(bool r)
+{
+   pRegistered = r;
+}
+
+void PropertyContainer::setDynamic(bool d)
+{
+   pDynamic = d;
+}
+
 INDI::BaseDriver::BaseDriver()
 {
     mediator = NULL;
     lp = newLilXML();
+    char indidev[MAXINDIDEVICE];
+    strncpy(indidev, "INDIDEV=", MAXINDIDEVICE);
 
     if (getenv("INDIDEV") != NULL)
     {
-        strncpy(deviceID, getenv("INDIDEV"), MAXINDINAME);
-        putenv("INDIDEV=");
+        strncpy(deviceID, getenv("INDIDEV"), MAXINDIDEVICE);
+        putenv(indidev);
     }
 }
@@ -25,4 +107,9 @@
 {
     delLilXML (lp);
+    while(!pAll.empty())
+    {
+      delete pAll.back();
+      pAll.pop_back();
+    }
 }
 
@@ -31,5 +118,5 @@
     INumberVectorProperty * nvp = NULL;
 
-    nvp = static_cast<INumberVectorProperty *> (getProperty(name, INDI_NUMBER));
+    nvp = static_cast<INumberVectorProperty *> (getProperty(name, PropertyContainer::INDI_NUMBER));
 
     return nvp;
@@ -40,5 +127,5 @@
     ITextVectorProperty * tvp = NULL;
 
-    tvp = static_cast<ITextVectorProperty *> (getProperty(name, INDI_TEXT));
+    tvp = static_cast<ITextVectorProperty *> (getProperty(name, PropertyContainer::INDI_TEXT));
 
     return tvp;
@@ -49,5 +136,5 @@
     ISwitchVectorProperty * svp = NULL;
 
-    svp = static_cast<ISwitchVectorProperty *> (getProperty(name, INDI_SWITCH));
+    svp = static_cast<ISwitchVectorProperty *> (getProperty(name, PropertyContainer::INDI_SWITCH));
 
     return svp;
@@ -58,5 +145,5 @@
     ILightVectorProperty * lvp = NULL;
 
-    lvp = static_cast<ILightVectorProperty *> (getProperty(name, INDI_LIGHT));
+    lvp = static_cast<ILightVectorProperty *> (getProperty(name, PropertyContainer::INDI_LIGHT));
 
     return lvp;
@@ -67,12 +154,16 @@
   IBLOBVectorProperty * bvp = NULL;
 
-  bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, INDI_BLOB));
+  bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, PropertyContainer::INDI_BLOB));
 
   return bvp;
 }
 
-void * INDI::BaseDriver::getProperty(const char *name, INDI_TYPE type)
-{
-    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
+void * INDI::BaseDriver::getProperty(const char *name, PropertyContainer::INDI_TYPE type)
+{
+    PropertyContainer::INDI_TYPE pType;
+    void *pPtr;
+    bool pRegistered = false;
+
+    std::vector<PropertyContainer *>::iterator orderi;
 
     INumberVectorProperty *nvp;
@@ -84,33 +175,53 @@
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
-        if (type != INDI_UNKNOWN &&  orderi->second != type)
+        pType       = (*orderi)->getType();
+        pPtr        = (*orderi)->getProperty();
+        pRegistered = (*orderi)->getRegistered();
+
+        if (type != PropertyContainer::INDI_UNKNOWN && pType != type)
             continue;
 
-        switch (orderi->second)
-        {
-        case INDI_NUMBER:
-            nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
-            if (!strcmp(name, nvp->name))
-                return (orderi->first).get();
-             break;
-        case INDI_TEXT:
-             tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
-             if (!strcmp(name, tvp->name))
-                return (orderi->first).get();
-             break;
-        case INDI_SWITCH:
-             svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
-             if (!strcmp(name, svp->name))
-                 return (orderi->first).get();
-             break;
-        case INDI_LIGHT:
-             lvp = static_cast<ILightVectorProperty *>((orderi->first).get());
-             if (!strcmp(name, lvp->name))
-                 return (orderi->first).get();
-             break;
-        case INDI_BLOB:
-             bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
-             if (!strcmp(name, bvp->name))
-                 return (orderi->first).get();
+        switch (pType)
+        {
+        case PropertyContainer::INDI_NUMBER:
+            nvp = static_cast<INumberVectorProperty *>(pPtr);
+            if (nvp == NULL)
+                continue;
+
+            if (!strcmp(name, nvp->name) && pRegistered)
+                return pPtr;
+             break;
+        case PropertyContainer::INDI_TEXT:
+             tvp = static_cast<ITextVectorProperty *>(pPtr);
+             if (tvp == NULL)
+                 continue;
+
+             if (!strcmp(name, tvp->name)  && pRegistered)
+                return pPtr;
+             break;
+        case PropertyContainer::INDI_SWITCH:
+             svp = static_cast<ISwitchVectorProperty *>(pPtr);
+             if (svp == NULL)
+                 continue;
+
+             //IDLog("Switch %s and aux value is now %d\n", svp->name, regStatus );
+             if (!strcmp(name, svp->name) && pRegistered)
+                 return pPtr;
+             break;
+        case PropertyContainer::INDI_LIGHT:
+             lvp = static_cast<ILightVectorProperty *>(pPtr);
+             if (lvp == NULL)
+                 continue;
+
+             if (!strcmp(name, lvp->name)  && pRegistered)
+                 return pPtr;
+             break;
+        case PropertyContainer::INDI_BLOB:
+             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
+             if (bvp == NULL)
+                 continue;
+
+             if (!strcmp(name, bvp->name) && pRegistered)
+                 return pPtr;
              break;
         }
@@ -121,7 +232,11 @@
 }
 
-int INDI::BaseDriver::removeProperty(const char *name)
-{
-    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
+PropertyContainer * INDI::BaseDriver::getContainer(const char *name, PropertyContainer::INDI_TYPE type)
+{
+    PropertyContainer::INDI_TYPE pType;
+    void *pPtr;
+    bool pRegistered = false;
+
+    std::vector<PropertyContainer *>::iterator orderi;
 
     INumberVectorProperty *nvp;
@@ -133,43 +248,118 @@
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
-        switch (orderi->second)
-        {
-        case INDI_NUMBER:
-            nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
+        pType       = (*orderi)->getType();
+        pPtr        = (*orderi)->getProperty();
+        pRegistered = (*orderi)->getRegistered();
+
+        if (type != PropertyContainer::INDI_UNKNOWN && pType != type)
+            continue;
+
+        switch (pType)
+        {
+        case PropertyContainer::INDI_NUMBER:
+            nvp = static_cast<INumberVectorProperty *>(pPtr);
+            if (nvp == NULL)
+                continue;
+
+            if (!strcmp(name, nvp->name) && pRegistered)
+                return *orderi;
+             break;
+        case PropertyContainer::INDI_TEXT:
+             tvp = static_cast<ITextVectorProperty *>(pPtr);
+             if (tvp == NULL)
+                 continue;
+
+             if (!strcmp(name, tvp->name)  && pRegistered)
+                return *orderi;
+             break;
+        case PropertyContainer::INDI_SWITCH:
+             svp = static_cast<ISwitchVectorProperty *>(pPtr);
+             if (svp == NULL)
+                 continue;
+
+             //IDLog("Switch %s and aux value is now %d\n", svp->name, regStatus );
+             if (!strcmp(name, svp->name) && pRegistered)
+                 return *orderi;
+             break;
+        case PropertyContainer::INDI_LIGHT:
+             lvp = static_cast<ILightVectorProperty *>(pPtr);
+             if (lvp == NULL)
+                 continue;
+
+             if (!strcmp(name, lvp->name)  && pRegistered)
+                 return *orderi;
+             break;
+        case PropertyContainer::INDI_BLOB:
+             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
+             if (bvp == NULL)
+                 continue;
+
+             if (!strcmp(name, bvp->name) && pRegistered)
+                 return *orderi;
+             break;
+        }
+
+    }
+
+    return NULL;
+}
+
+int INDI::BaseDriver::removeProperty(const char *name)
+{    
+    std::vector<PropertyContainer *>::iterator orderi;
+
+    PropertyContainer::INDI_TYPE pType;
+    void *pPtr;
+
+    INumberVectorProperty *nvp;
+    ITextVectorProperty *tvp;
+    ISwitchVectorProperty *svp;
+    ILightVectorProperty *lvp;
+    IBLOBVectorProperty *bvp;
+
+    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
+    {
+        pType       = (*orderi)->getType();
+        pPtr        = (*orderi)->getProperty();
+
+        switch (pType)
+        {
+        case PropertyContainer::INDI_NUMBER:
+            nvp = static_cast<INumberVectorProperty *>(pPtr);
             if (!strcmp(name, nvp->name))
             {
-                 pAll.erase(orderi);
+                (*orderi)->setRegistered(false);
                  return 0;
              }
              break;
-        case INDI_TEXT:
-             tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_TEXT:
+             tvp = static_cast<ITextVectorProperty *>(pPtr);
              if (!strcmp(name, tvp->name))
              {
-                  pAll.erase(orderi);
+                  (*orderi)->setRegistered(false);
                   return 0;
               }
              break;
-        case INDI_SWITCH:
-             svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_SWITCH:
+             svp = static_cast<ISwitchVectorProperty *>(pPtr);
              if (!strcmp(name, svp->name))
              {
-                  pAll.erase(orderi);
+                 (*orderi)->setRegistered(false);
                   return 0;
               }
              break;
-        case INDI_LIGHT:
-             lvp = static_cast<ILightVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_LIGHT:
+             lvp = static_cast<ILightVectorProperty *>(pPtr);
              if (!strcmp(name, lvp->name))
              {
-                  pAll.erase(orderi);
+                 (*orderi)->setRegistered(false);
                   return 0;
               }
              break;
-        case INDI_BLOB:
-             bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_BLOB:
+             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
              if (!strcmp(name, bvp->name))
              {
-                  pAll.erase(orderi);
+                 (*orderi)->setRegistered(false);
                   return 0;
               }
@@ -215,8 +405,6 @@
     IPerm perm;
     IPState state;
-    ISRule rule;
     XMLEle *ep = NULL;
     char *rtag, *rname, *rdev;
-    //INDI_TYPE type;
     double timeout=0;
 
@@ -258,8 +446,7 @@
     if (!strcmp (rtag, "defNumberVector"))
     {
-
-        numberPtr nvp(new INumberVectorProperty);
-        //INumberVectorProperty *nvp = new INumberVectorProperty;
-        //INumberVectorProperty *nvp = (INumberVectorProperty *) malloc(sizeof(INumberVectorProperty));
+        PropertyContainer *indiProp = new PropertyContainer();
+        INumberVectorProperty *nvp = new INumberVectorProperty;
+
         INumber *np = NULL;
         int n=0;
@@ -281,5 +468,5 @@
             np = (INumber *) realloc(np, (n+1) * sizeof(INumber));
 
-            np[n].nvp = nvp.get();
+            np[n].nvp = nvp;
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -320,9 +507,11 @@
         nvp->nnp = n;
         nvp->np  = np;
-        //orderPtr o(new pOrder);
-        //o->p = &nvp;
-        //o->type = INDI_NUMBER;
-        //pAll.push_back(o);
-        pAll[nvp] = INDI_NUMBER;
+
+        indiProp->setProperty(nvp);
+        indiProp->setDynamic(true);
+        indiProp->setType(PropertyContainer::INDI_NUMBER);
+
+        pAll.push_back(indiProp);
+
         //IDLog("Adding number property %s to list.\n", nvp->name);
         if (mediator)
@@ -334,7 +523,7 @@
   else if (!strcmp (rtag, "defSwitchVector"))
         {
-            switchPtr svp(new ISwitchVectorProperty);
-            //ISwitchVectorProperty *svp = new ISwitchVectorProperty;
-            //ISwitchVectorProperty *svp = (ISwitchVectorProperty *) malloc(sizeof(ISwitchVectorProperty));
+            PropertyContainer *indiProp = new PropertyContainer();
+            ISwitchVectorProperty *svp = new ISwitchVectorProperty;
+
             ISwitch *sp = NULL;
             int n=0;
@@ -360,5 +549,5 @@
                 sp = (ISwitch *) realloc(sp, (n+1) * sizeof(ISwitch));
 
-                sp[n].svp = svp.get();
+                sp[n].svp = svp;
 
                 XMLAtt *na = findXMLAtt (ep, "name");
@@ -380,9 +569,10 @@
             svp->nsp = n;
             svp->sp  = sp;
-            //orderPtr o(new pOrder);
-            //o->p = &svp;
-            //o->type = INDI_SWITCH;
-            //pAll.push_back(o);
-            pAll[svp] = INDI_SWITCH;
+
+            indiProp->setProperty(svp);
+            indiProp->setDynamic(true);
+            indiProp->setType(PropertyContainer::INDI_SWITCH);
+
+            pAll.push_back(indiProp);
             //IDLog("Adding Switch property %s to list.\n", svp->name);
             if (mediator)
@@ -396,7 +586,6 @@
     {
 
-        //ITextVectorProperty *tvp = new ITextVectorProperty;
-        //ITextVectorProperty *tvp = (ITextVectorProperty *) malloc(sizeof(ITextVectorProperty));
-        textPtr tvp(new ITextVectorProperty);
+        PropertyContainer *indiProp = new PropertyContainer();
+        ITextVectorProperty *tvp = new ITextVectorProperty;
         IText *tp = NULL;
         int n=0;
@@ -418,5 +607,5 @@
             tp = (IText *) realloc(tp, (n+1) * sizeof(IText));
 
-            tp[n].tvp = tvp.get();
+            tp[n].tvp = tvp;
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -439,9 +628,10 @@
         tvp->ntp = n;
         tvp->tp  = tp;
-        //orderPtr o(new pOrder);
-        //o->p = &tvp;
-        //o->type = INDI_TEXT;
-        //pAll.push_back(o);
-        pAll[tvp] = INDI_TEXT;
+
+        indiProp->setProperty(tvp);
+        indiProp->setDynamic(true);
+        indiProp->setType(PropertyContainer::INDI_TEXT);
+
+        pAll.push_back(indiProp);
         //IDLog("Adding Text property %s to list.\n", tvp->name);
         if (mediator)
@@ -454,7 +644,6 @@
     {
 
-        //ILightVectorProperty *lvp = new ILightVectorProperty;
-        //ILightVectorProperty *lvp = (ILightVectorProperty *) malloc(sizeof(ILightVectorProperty));
-        lightPtr lvp(new ILightVectorProperty);
+        PropertyContainer *indiProp = new PropertyContainer();
+        ILightVectorProperty *lvp = new ILightVectorProperty;
         ILight *lp = NULL;
         int n=0;
@@ -474,5 +663,5 @@
             lp = (ILight *) realloc(lp, (n+1) * sizeof(ILight));
 
-            lp[n].lvp = lvp.get();
+            lp[n].lvp = lvp;
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -495,9 +684,11 @@
         lvp->nlp = n;
         lvp->lp  = lp;
-        //orderPtr o(new pOrder);
-        //o->p = &lvp;
-        //o->type = INDI_LIGHT;
-        //pAll.push_back(o);
-        pAll[lvp] = INDI_LIGHT;
+
+        indiProp->setProperty(lvp);
+        indiProp->setDynamic(true);
+        indiProp->setType(PropertyContainer::INDI_LIGHT);
+
+        pAll.push_back(indiProp);
+
         //IDLog("Adding Light property %s to list.\n", lvp->name);
         if (mediator)
@@ -509,8 +700,6 @@
 else if (!strcmp (rtag, "defBLOBVector"))
     {
-
-        //IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
-        //IBLOBVectorProperty *bvp = (IBLOBVectorProperty *) malloc(sizeof(IBLOBVectorProperty));
-        blobPtr bvp(new IBLOBVectorProperty);
+        PropertyContainer *indiProp = new PropertyContainer();
+        IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
         IBLOB *bp = NULL;
         int n=0;
@@ -530,5 +719,5 @@
             bp = (IBLOB *) realloc(bp, (n+1) * sizeof(IBLOB));
 
-            bp[n].bvp = bvp.get();
+            bp[n].bvp = bvp;
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -560,9 +749,10 @@
         bvp->nbp = n;
         bvp->bp  = bp;
-        //orderPtr o(new pOrder);
-        //o->p = &bvp;
-        //o->type = INDI_BLOB;
-        //pAll.push_back(o);
-        pAll[bvp] = INDI_BLOB;
+
+        indiProp->setProperty(bvp);
+        indiProp->setDynamic(true);
+        indiProp->setType(PropertyContainer::INDI_BLOB);
+
+        pAll.push_back(indiProp);
         //IDLog("Adding BLOB property %s to list.\n", bvp->name);
         if (mediator)
@@ -913,64 +1103,93 @@
 }
 
-void INDI::BaseDriver::registerProperty(void *p, INDI_TYPE type)
-{
-
-
-    if (type == INDI_NUMBER)
+void INDI::BaseDriver::registerProperty(void *p, PropertyContainer::INDI_TYPE type)
+{
+    PropertyContainer *pContainer;
+
+    if (type == PropertyContainer::INDI_NUMBER)
     {
         INumberVectorProperty *nvp = static_cast<INumberVectorProperty *> (p);
-        if (getProperty(nvp->name, INDI_NUMBER) != NULL)
+        if ( (pContainer = getContainer(nvp->name, PropertyContainer::INDI_NUMBER)) != NULL)
+        {
+            pContainer->setRegistered(true);
             return;
-
-        numberPtr ovp(nvp);
-
-        pAll[ovp] = INDI_NUMBER;
-    }
-    else if (type == INDI_TEXT)
+        }
+
+        pContainer = new PropertyContainer();
+        pContainer->setProperty(p);
+        pContainer->setType(type);
+
+        pAll.push_back(pContainer);
+
+    }
+    else if (type == PropertyContainer::INDI_TEXT)
     {
        ITextVectorProperty *tvp = static_cast<ITextVectorProperty *> (p);
-       if (getProperty(tvp->name, INDI_TEXT) != NULL)
+
+       if ( (pContainer = getContainer(tvp->name, PropertyContainer::INDI_TEXT)) != NULL)
+       {
+           pContainer->setRegistered(true);
            return;
-
-       textPtr ovp(tvp);
-       //o->p = &ovp;
-
-       pAll[ovp] = INDI_TEXT;
+       }
+
+       pContainer = new PropertyContainer();
+       pContainer->setProperty(p);
+       pContainer->setType(type);
+
+       pAll.push_back(pContainer);
+
+
    }
-    else if (type == INDI_SWITCH)
+    else if (type == PropertyContainer::INDI_SWITCH)
     {
        ISwitchVectorProperty *svp = static_cast<ISwitchVectorProperty *> (p);
-       if (getProperty(svp->name, INDI_SWITCH) != NULL)
+
+       if ( (pContainer = getContainer(svp->name, PropertyContainer::INDI_SWITCH)) != NULL)
+       {
+           pContainer->setRegistered(true);
            return;
-
-       switchPtr ovp(svp);
-       //o->p = &ovp;
-
-       IDLog("Registering switch %s\n", svp->name);
-
-       pAll[ovp] = INDI_SWITCH;
-    }
-    else if (type == INDI_LIGHT)
+       }
+
+       pContainer = new PropertyContainer();
+       pContainer->setProperty(p);
+       pContainer->setType(type);
+
+       pAll.push_back(pContainer);
+
+    }
+    else if (type == PropertyContainer::INDI_LIGHT)
     {
        ILightVectorProperty *lvp = static_cast<ILightVectorProperty *> (p);
-       if (getProperty(lvp->name, INDI_LIGHT) != NULL)
+
+       if ( (pContainer = getContainer(lvp->name, PropertyContainer::INDI_LIGHT)) != NULL)
+       {
+           pContainer->setRegistered(true);
            return;
-
-       lightPtr ovp(lvp);
-       //o->p = &ovp;
-       pAll[ovp] = INDI_LIGHT;
+       }
+
+       pContainer = new PropertyContainer();
+       pContainer->setProperty(p);
+       pContainer->setType(type);
+
+       pAll.push_back(pContainer);
    }
-    else if (type == INDI_BLOB)
+    else if (type == PropertyContainer::INDI_BLOB)
     {
        IBLOBVectorProperty *bvp = static_cast<IBLOBVectorProperty *> (p);
-       if (getProperty(bvp->name, INDI_BLOB) != NULL)
+
+       if ( (pContainer = getContainer(bvp->name, PropertyContainer::INDI_BLOB)) != NULL)
+       {
+           pContainer->setRegistered(true);
            return;
-
-       blobPtr ovp(bvp);
-       //o->p = &ovp;
-
-       pAll[ovp] = INDI_BLOB;
-    }
-
-}
-
+       }
+
+       pContainer = new PropertyContainer();
+       pContainer->setProperty(p);
+       pContainer->setType(type);
+
+       pAll.push_back(pContainer);
+
+    }
+
+}
+
Index: /BAORadio/libindi/libindi/libs/indibase/basedriver.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/basedriver.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/basedriver.h	(revision 642)
@@ -1,7 +1,24 @@
+/*******************************************************************************
+  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #ifndef INDIBASEDRIVER_H
 #define INDIBASEDRIVER_H
 
-#include <boost/shared_ptr.hpp>
-#include <map>
+#include <vector>
 #include <string>
 
@@ -11,4 +28,38 @@
 
 #define MAXRBUF 2048
+
+class PropertyContainer
+{
+public:
+    PropertyContainer();
+    ~PropertyContainer();
+
+    /*! INDI property type */
+    typedef enum
+    {
+        INDI_NUMBER, /*!< INumberVectorProperty. */
+        INDI_SWITCH, /*!< ISwitchVectorProperty. */
+        INDI_TEXT,   /*!< ITextVectorProperty. */
+        INDI_LIGHT,  /*!< ILightVectorProperty. */
+        INDI_BLOB,    /*!< IBLOBVectorProperty. */
+        INDI_UNKNOWN
+    } INDI_TYPE;
+
+    void setProperty(void *);
+    void setType(INDI_TYPE t);
+    void setRegistered(bool r);
+    void setDynamic(bool d);
+
+    void *getProperty() { return pPtr; }
+    INDI_TYPE getType() { return pType; }
+    bool getRegistered() { return pRegistered; }
+    bool getDynamic() { return pDynamic; }
+
+private:
+    void *pPtr;
+    INDI_TYPE pType;
+    bool pRegistered;
+    bool pDynamic;
+};
 
 /**
@@ -37,15 +88,4 @@
     };
 
-    /*! INDI property type */
-    typedef enum
-    {
-        INDI_NUMBER, /*!< INumberVectorProperty. */
-        INDI_SWITCH, /*!< ISwitchVectorProperty. */
-        INDI_TEXT,   /*!< ITextVectorProperty. */
-        INDI_LIGHT,  /*!< ILightVectorProperty. */
-        INDI_BLOB,    /*!< IBLOBVectorProperty. */
-        INDI_UNKNOWN
-    } INDI_TYPE;
-
     /** \return Return vector number property given its name */
     INumberVectorProperty * getNumber(const char *name);
@@ -59,5 +99,5 @@
     IBLOBVectorProperty * getBLOB(const char *name);
 
-    void registerProperty(void *p, INDI_TYPE type);
+    void registerProperty(void *p, PropertyContainer::INDI_TYPE type);
 
     /** \brief Remove a property
@@ -77,5 +117,7 @@
 
     */
-    void * getProperty(const char *name, INDI_TYPE type = INDI_UNKNOWN);
+    void * getProperty(const char *name, PropertyContainer::INDI_TYPE type = PropertyContainer::INDI_UNKNOWN);
+
+    PropertyContainer * getContainer(const char *name, PropertyContainer::INDI_TYPE type = PropertyContainer::INDI_UNKNOWN);
 
     /** \brief Build driver properties from a skeleton file.
@@ -133,15 +175,10 @@
     int setBLOB(IBLOBVectorProperty *pp, XMLEle * root, char * errmsg);
 
-    char deviceID[MAXINDINAME];
-
-    typedef boost::shared_ptr<INumberVectorProperty> numberPtr;
-    typedef boost::shared_ptr<ITextVectorProperty> textPtr;
-    typedef boost::shared_ptr<ISwitchVectorProperty> switchPtr;
-    typedef boost::shared_ptr<ILightVectorProperty> lightPtr;
-    typedef boost::shared_ptr<IBLOBVectorProperty> blobPtr;
 
 private:
 
-    std::map< boost::shared_ptr<void>, INDI_TYPE> pAll;
+    char deviceID[MAXINDINAME];
+
+    std::vector<PropertyContainer *> pAll;
 
     LilXML *lp;
Index: /BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp	(revision 642)
@@ -1,2 +1,20 @@
+/*******************************************************************************
+  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #include <stdlib.h>
 #include <string.h>
@@ -8,4 +26,13 @@
 #include "base64.h"
 
+const char *COMMUNICATION_TAB = "Communication";
+const char *MAIN_CONTROL_TAB = "Main Control";
+const char *MOTION_TAB = "Motion Control";
+const char *DATETIME_TAB = "Date/Time";
+const char *SITE_TAB = 	"Site Management";
+const char *OPTIONS_TAB = "Options";
+const char *FILTER_TAB = "Filter Wheel";
+const char *GUIDER_TAB = "Guide Wheel";
+
 void timerfunc(void *t)
 {
@@ -30,4 +57,7 @@
     //switchPtr conSw(new ISwitchVectorProperty);
     ConnectionSP = new ISwitchVectorProperty;
+    DebugSP = NULL;
+    SimulationSP = NULL;
+    ConfigProcessSP = NULL;
 
     IUFillSwitch(&ConnectionS[0],"CONNECT","Connect",ISS_OFF);
@@ -35,6 +65,14 @@
     IUFillSwitchVector(ConnectionSP,ConnectionS,2,deviceName(),"CONNECTION","Connection","Main Control",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
 
-    registerProperty(ConnectionSP, INDI_SWITCH);
-
+    registerProperty(ConnectionSP, PropertyContainer::INDI_SWITCH);
+
+}
+
+INDI::DefaultDriver::~DefaultDriver()
+{
+    delete ConnectionSP;
+    delete DebugSP;
+    delete SimulationSP;
+    delete ConfigProcessSP;
 }
 
@@ -47,5 +85,7 @@
 
    if (pResult)
-       IDMessage(deviceID, "Configuration successfully loaded.");
+       IDMessage(deviceID, "Configuration successfully loaded.\n");
+	else
+		IDMessage(deviceID,"Error loading configuration\n");
 
    IUSaveDefaultConfig(NULL, NULL, deviceID);
@@ -54,9 +94,10 @@
 }
 
-bool INDI::DefaultDriver::saveConfig()
-{
-    //std::vector<orderPtr>::iterator orderi;
-
-    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
+bool INDI::DefaultDriver::saveConfigItems(FILE *fp)
+{
+    std::vector<PropertyContainer *>::iterator orderi;
+
+    PropertyContainer::INDI_TYPE pType;
+    void *pPtr;
 
     ISwitchVectorProperty *svp=NULL;
@@ -64,33 +105,24 @@
     ITextVectorProperty   *tvp=NULL;
     IBLOBVectorProperty   *bvp=NULL;
-    char errmsg[MAXRBUF];
-    FILE *fp = NULL;
-
-    fp = IUGetConfigFP(NULL, deviceID, errmsg);
-
-    if (fp == NULL)
-    {
-        IDMessage(deviceID, "Error saving configuration. %s", errmsg);
-        return false;
-    }
-
-    IUSaveConfigTag(fp, 0);
 
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
 
-        switch (orderi->second)
+        pType       = (*orderi)->getType();
+        pPtr        = (*orderi)->getProperty();
+
+        switch (pType)
         {
-        case INDI_NUMBER:
-             nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
-             IDLog("Trying to save config for number %s\n", nvp->name);
+        case PropertyContainer::INDI_NUMBER:
+             nvp = static_cast<INumberVectorProperty *>(pPtr);
+             //IDLog("Trying to save config for number %s\n", nvp->name);
              IUSaveConfigNumber(fp, nvp);
              break;
-        case INDI_TEXT:
-             tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_TEXT:
+             tvp = static_cast<ITextVectorProperty *>(pPtr);
              IUSaveConfigText(fp, tvp);
              break;
-        case INDI_SWITCH:
-             svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_SWITCH:
+             svp = static_cast<ISwitchVectorProperty *>(pPtr);
              /* Never save CONNECTION property. Don't save switches with no switches on if the rule is one of many */
              if (!strcmp(svp->name, "CONNECTION") || (svp->r == ISR_1OFMANY && !IUFindOnSwitch(svp)))
@@ -98,10 +130,31 @@
              IUSaveConfigSwitch(fp, svp);
              break;
-        case INDI_BLOB:
-             bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
+        case PropertyContainer::INDI_BLOB:
+             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
              IUSaveConfigBLOB(fp, bvp);
              break;
         }
     }
+	return true;
+}
+
+bool INDI::DefaultDriver::saveConfig()
+{
+    //std::vector<orderPtr>::iterator orderi;
+    char errmsg[MAXRBUF];
+
+    FILE *fp = NULL;
+
+    fp = IUGetConfigFP(NULL, deviceID, errmsg);
+
+    if (fp == NULL)
+    {
+        IDMessage(deviceID, "Error saving configuration. %s\n", errmsg);
+        return false;
+    }
+
+    IUSaveConfigTag(fp, 0);
+
+	saveConfigItems(fp);
 
     IUSaveConfigTag(fp, 1);
@@ -142,5 +195,4 @@
 bool INDI::DefaultDriver::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
 {
-
     // ignore if not ours //
     if (strcmp (dev, deviceID))
@@ -160,4 +212,5 @@
         if ( !strcmp(names[i], "CONNECT") && (states[i] == ISS_ON))
         {
+
             // If not connected, attempt to connect
             if (isConnected() == false)
@@ -167,7 +220,8 @@
                 // If connection is successful, set it thus
                 if (rc)
-                  setConnected(true);
+                        setConnected(true, IPS_OK);
                 else
-                  setConnected(false, IPS_ALERT);
+                        setConnected(false, IPS_ALERT);
+
 
                 updateProperties();
@@ -261,10 +315,9 @@
     if (!DebugSP)
     {
-        switchPtr debSw(new ISwitchVectorProperty);
-        DebugSP = debSw.get();
+        DebugSP = new ISwitchVectorProperty;
         IUFillSwitch(&DebugS[0], "ENABLE", "Enable", ISS_OFF);
         IUFillSwitch(&DebugS[1], "DISABLE", "Disable", ISS_ON);
-        IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), deviceID, "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
-        pAll[debSw] = INDI_SWITCH;
+        IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), deviceName(), "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
+        registerProperty(DebugSP, PropertyContainer::INDI_SWITCH);
     }
     else
@@ -285,10 +338,9 @@
     if (!SimulationSP)
     {
-        switchPtr simSw(new ISwitchVectorProperty);
-        SimulationSP = simSw.get();
+        SimulationSP = new ISwitchVectorProperty;
         IUFillSwitch(&SimulationS[0], "ENABLE", "Enable", ISS_OFF);
         IUFillSwitch(&SimulationS[1], "DISABLE", "Disable", ISS_ON);
-        IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), deviceID, "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
-        pAll[simSw] = INDI_SWITCH;
+        IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), deviceName(), "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
+        registerProperty(SimulationSP, PropertyContainer::INDI_SWITCH);
     }
     else
@@ -307,11 +359,10 @@
     if (!ConfigProcessSP)
     {
-        switchPtr configSw(new ISwitchVectorProperty);
-        ConfigProcessSP = configSw.get();
+        ConfigProcessSP = new ISwitchVectorProperty;
         IUFillSwitch(&ConfigProcessS[0], "CONFIG_LOAD", "Load", ISS_OFF);
         IUFillSwitch(&ConfigProcessS[1], "CONFIG_SAVE", "Save", ISS_OFF);
         IUFillSwitch(&ConfigProcessS[2], "CONFIG_DEFAULT", "Default", ISS_OFF);
-        IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), deviceID, "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
-        pAll[configSw] = INDI_SWITCH;
+        IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), deviceName(), "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
+        registerProperty(ConfigProcessSP, PropertyContainer::INDI_SWITCH);
     }
     /**************************************************************************/
@@ -416,8 +467,9 @@
 void INDI::DefaultDriver::ISGetProperties (const char *dev)
 {
-    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
+    std::vector<PropertyContainer *>::iterator orderi;
     static int isInit = 0;
-
-    //fprintf(stderr,"Enter ISGetProperties '%s'\n",dev);
+    PropertyContainer::INDI_TYPE pType;
+    void *pPtr;
+
     if(isInit == 0)
     {
@@ -442,20 +494,23 @@
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
-        switch (orderi->second)
+        pType       = (*orderi)->getType();
+        pPtr        = (*orderi)->getProperty();
+
+        switch (pType)
         {
-        case INDI_NUMBER:
-             IDDefNumber(static_cast<INumberVectorProperty *>((orderi->first).get()) , NULL);
-             break;
-        case INDI_TEXT:
-             IDDefText(static_cast<ITextVectorProperty *>((orderi->first).get()) , NULL);
-             break;
-        case INDI_SWITCH:
-             IDDefSwitch(static_cast<ISwitchVectorProperty *>((orderi->first).get()) , NULL);
-             break;
-        case INDI_LIGHT:
-             IDDefLight(static_cast<ILightVectorProperty *>((orderi->first).get()) , NULL);
-             break;
-        case INDI_BLOB:
-             IDDefBLOB(static_cast<IBLOBVectorProperty *>((orderi->first).get()) , NULL);
+        case PropertyContainer::INDI_NUMBER:
+             IDDefNumber(static_cast<INumberVectorProperty *>(pPtr) , NULL);
+             break;
+        case PropertyContainer::INDI_TEXT:
+             IDDefText(static_cast<ITextVectorProperty *>(pPtr) , NULL);
+             break;
+        case PropertyContainer::INDI_SWITCH:
+             IDDefSwitch(static_cast<ISwitchVectorProperty *>(pPtr) , NULL);
+             break;
+        case PropertyContainer::INDI_LIGHT:
+             IDDefLight(static_cast<ILightVectorProperty *>(pPtr) , NULL);
+             break;
+        case PropertyContainer::INDI_BLOB:
+             IDDefBLOB(static_cast<IBLOBVectorProperty *>(pPtr) , NULL);
              break;
         }
@@ -535,13 +590,13 @@
 //  This is a helper function
 //  that just encapsulates the Indi way into our clean c++ way of doing things
-int INDI::DefaultDriver::SetTimer(int t)
-{
-    return IEAddTimer(t,timerfunc,this);
+int INDI::DefaultDriver::SetTimer(int ms)
+{
+    return IEAddTimer(ms,timerfunc,this);
 }
 
 //  Just another helper to help encapsulate indi into a clean class
-void INDI::DefaultDriver::RemoveTimer(int t)
-{
-    IERmTimer(t);
+void INDI::DefaultDriver::RemoveTimer(int id)
+{
+    IERmTimer(id);
     return;
 }
@@ -577,5 +632,5 @@
 void INDI::DefaultDriver::defineNumber(INumberVectorProperty *nvp)
 {
-    registerProperty(nvp, INDI_NUMBER);
+    registerProperty(nvp, PropertyContainer::INDI_NUMBER);
     IDDefNumber(nvp, NULL);
 }
@@ -583,5 +638,5 @@
 void INDI::DefaultDriver::defineText(ITextVectorProperty *tvp)
 {
-    registerProperty(tvp, INDI_TEXT);
+    registerProperty(tvp, PropertyContainer::INDI_TEXT);
     IDDefText(tvp, NULL);
 }
@@ -589,5 +644,5 @@
 void INDI::DefaultDriver::defineSwitch(ISwitchVectorProperty *svp)
 {
-    registerProperty(svp, INDI_SWITCH);
+    registerProperty(svp, PropertyContainer::INDI_SWITCH);
     IDDefSwitch(svp, NULL);
 }
@@ -595,5 +650,5 @@
 void INDI::DefaultDriver::defineLight(ILightVectorProperty *lvp)
 {
-    registerProperty(lvp, INDI_LIGHT);
+    registerProperty(lvp, PropertyContainer::INDI_LIGHT);
     IDDefLight(lvp, NULL);
 }
@@ -601,5 +656,5 @@
 void INDI::DefaultDriver::defineBLOB(IBLOBVectorProperty *bvp)
 {
-    registerProperty(bvp, INDI_BLOB);
+    registerProperty(bvp, PropertyContainer::INDI_BLOB);
     IDDefBLOB(bvp, NULL);
 }
Index: /BAORadio/libindi/libindi/libs/indibase/defaultdriver.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/defaultdriver.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/defaultdriver.h	(revision 642)
@@ -1,2 +1,20 @@
+/*******************************************************************************
+  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
+
 #ifndef INDIDEFAULTDRIVER_H
 #define INDIDEFAULTDRIVER_H
@@ -5,7 +23,18 @@
 #include "indidriver.h"
 
+#include <auto_ptr.h>
+
+extern const char *COMMUNICATION_TAB;
+extern const char *MAIN_CONTROL_TAB;
+extern const char *MOTION_TAB;
+extern const char *DATETIME_TAB;
+extern const char *SITE_TAB;
+extern const char *OPTIONS_TAB;
+extern const char *FILTER_TAB;
+extern const char *GUIDER_TAB;
+
 /**
  * \class INDI::DefaultDriver
-   \brief Class to provide extended functionary for drivers in addition
+   \brief Class to provide extended functionality for drivers in addition
 to the functionality provided by INDI::BaseDriver. This class should \e only be subclassed by
 drivers directly as it is linked with main(). Virtual drivers cannot employ INDI::DefaultDriver.
@@ -21,5 +50,5 @@
 public:
     DefaultDriver();
-    virtual ~DefaultDriver() {}
+    virtual ~DefaultDriver();
 
     /** \brief Add Debug, Simulation, and Configuration options to the driver */
@@ -74,13 +103,26 @@
     virtual bool deleteProperty(const char *propertyName);
 
-    /** \brief Connect or Disconnect a device.
+
+    /** \brief Set connection switch status in the client.
       \param status If true, the driver will attempt to connect to the device (CONNECT=ON). If false, it will attempt
 to disconnect the device.
-      \param msg A message to be sent along with connect/disconnect command.
+      \param status True to set CONNECT on, false to set DISCONNECT on.
+      \param state State of CONNECTION properti, by default IPS_OK.
+      \param msg A message to be sent along with connect/disconnect command, by default NULL.
     */
     virtual void setConnected(bool status, IPState state=IPS_OK, const char *msg = NULL);
 
-    int SetTimer(int);
-    void RemoveTimer(int);
+    /** \brief Set a timer to call the function TimerHit after ms milliseconds
+        \param ms timer duration in milliseconds.
+        \return id of the timer to be used with RemoveTimer
+   */
+    int SetTimer(int ms);
+
+    /** \brief Remove timer added with SetTimer
+        \param id ID of the timer as returned from SetTimer
+   */
+    void RemoveTimer(int id);
+
+    /** \brief Callback function to be called once SetTimer duration elapses. */
     virtual void TimerHit();
 
@@ -116,15 +158,17 @@
         \return True if successful, false otherwise.
     */
-    bool loadConfig();
+    virtual bool loadConfig();
 
     /** \brief Save the current properties in a configuration file
         \return True if successful, false otherwise.
     */
-    bool saveConfig();
+    virtual bool saveConfig();
+    virtual bool saveConfigItems(FILE *fp);
 
     /** \brief Load the default configuration file
         \return True if successful, false otherwise.
     */
-    bool loadDefaultConfig();
+    virtual bool loadDefaultConfig();
+
 
     // Simulatin & Debug
Index: /BAORadio/libindi/libindi/libs/indibase/indibase.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indibase.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indibase.h	(revision 642)
@@ -9,5 +9,7 @@
 /**
  * \namespace INDI
-   \brief Namespace to encapsulate INDI client, device, and mediator classes
+   \brief Namespace to encapsulate INDI client, drivers, and mediator classes.
+   Developers can subclass the base devices class to implement device specific functionality. This ensures interoperability and consistency among devices within the same family
+   and reduces code overhead.
 
    <ul>
@@ -18,4 +20,11 @@
    <li>DefaultDriver: INDI::BaseDriver with extended functionality such as debug, simulation, and configuration support.
        It is \e only used by drivers directly, it cannot be used by clients.</li>
+   <li>FilterInterface: Basic interface for filter wheels functions.</li>
+   <li>GuiderInterface: Basic interface for guider (ST4) port functions.</li>
+   <li>CCD: Base class for CCD drivers. Provides basic support for single chip CCD and CCDs with a guide head as well.</li>
+   <li>Telescope: Base class for telescope drivers.</li>
+   <li>FilterWheel: Base class for Filter Wheels. It implements the FilterInterface.</li>
+   <li>Focuser: Base class for focusers.</li>
+   <li>USBDevice: Base class for USB devices for direct read/write/control over USB.</li>
    </ul>
  */
@@ -26,9 +35,11 @@
     class BaseDriver;
     class DefaultDriver;
+    class FilterInterface;
+    class GuiderInterface;
     class CCD;
     class Telescope;
     class FilterWheel;
     class Focuser;
-    class USBDevice;
+    class USBDevice;   
 }
 
Index: /BAORadio/libindi/libindi/libs/indibase/indiccd.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiccd.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indiccd.cpp	(revision 642)
@@ -1,21 +1,18 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+  Copyright(c) 2010, 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -24,126 +21,232 @@
 #include <string.h>
 
-#include <fitsio.h>
 #include <zlib.h>
 
+const char *IMAGE_SETTINGS_TAB = "Image Settings";
+const char *IMAGE_INFO_TAB     = "Image Info";
+const char *GUIDE_HEAD_TAB     = "Guide Head";
+const char *GUIDE_CONTROL_TAB     = "Guider Control";
+
+CCDChip::CCDChip()
+{
+    SendCompressed=false;
+    Interlaced=false;
+
+    RawFrame=NULL;
+    RawFrameSize=0;
+
+    FrameType=LIGHT_FRAME;
+
+    ImageFrameNP = new INumberVectorProperty;
+    FrameTypeSP = new ISwitchVectorProperty;
+    ImageExposureNP = new INumberVectorProperty;
+    ImageBinNP = new INumberVectorProperty;
+    ImagePixelSizeNP = new INumberVectorProperty;
+    CompressSP = new ISwitchVectorProperty;
+    FitsBP = new IBLOBVectorProperty;
+
+}
+
+CCDChip::~CCDChip()
+{
+    delete RawFrame;
+    RawFrameSize=0;
+    RawFrame=NULL;
+
+    delete ImageFrameNP;
+    delete FrameTypeSP;
+    delete ImageExposureNP;
+    delete ImageBinNP;
+    delete ImagePixelSizeNP;
+    delete CompressSP;
+    delete FitsBP;
+}
+
+int CCDChip::setFrameType(CCD_FRAME t)
+{
+    //fprintf(stderr,"Set frame type to %d\n",t);
+    FrameType=t;
+    return 0;
+}
+
+void CCDChip::setResolutoin(int x, int y)
+{
+    XRes = x;
+    YRes = y;
+
+    ImagePixelSizeN[0].value=x;
+    ImagePixelSizeN[1].value=y;
+
+    IDSetNumber(ImagePixelSizeNP, NULL);
+}
+
+void CCDChip::setFrame(int subx, int suby, int subw, int subh)
+{
+    SubX = subx;
+    SubY = suby;
+    SubW = subw;
+    SubH = subh;
+
+    ImageFrameN[0].value = SubX;
+    ImageFrameN[1].value = SubY;
+    ImageFrameN[2].value = SubW;
+    ImageFrameN[3].value = SubH;
+
+    IDSetNumber(ImageFrameNP, NULL);
+}
+
+void CCDChip::setBin(int hor, int ver)
+{
+    BinX = hor;
+    BinY = ver;
+
+    ImageBinN[0].value = BinX;
+    ImageBinN[1].value = BinY;
+
+    IDSetNumber(ImageBinNP, NULL);
+}
+
+void CCDChip::setPixelSize(int x, int y)
+{
+    PixelSizex = x;
+    PixelSizey = y;
+
+    ImagePixelSizeN[2].value=x;
+    ImagePixelSizeN[3].value=x;
+    ImagePixelSizeN[4].value=y;
+
+    IDSetNumber(ImagePixelSizeNP, NULL);
+
+}
+
+void CCDChip::setBPP(int bbp)
+{
+    BPP = bbp;
+
+    ImagePixelSizeN[5].value = BPP;
+
+    IDSetNumber(ImagePixelSizeNP, NULL);
+}
+
+void CCDChip::setFrameBufferSize(int nbuf)
+{
+    if (RawFrame != NULL)
+        delete RawFrame;
+
+    RawFrameSize = nbuf;
+
+    RawFrame = new char[nbuf];
+}
+
+void CCDChip::setExposure(double duration)
+{
+    ImageExposureN[0].value = duration;
+    IDSetNumber(ImageExposureNP, NULL);
+}
+
+void CCDChip::setInterlaced(bool intr)
+{
+    Interlaced = intr;
+}
+
+void CCDChip::setExposureFailed()
+{
+    ImageExposureNP->s = IPS_ALERT;
+    IDSetNumber(ImageExposureNP, NULL);
+}
+
 INDI::CCD::CCD()
 {
     //ctor
-    SendCompressed=false;
-    GuiderCompressed=false;
     HasGuideHead=false;
     HasSt4Port=false;
-
-    RawFrame=NULL;
-    RawFrameSize=0;
-
-    RawGuideSize=0;
-    RawGuiderFrame=NULL;
-
-    FrameType=FRAME_TYPE_LIGHT;
-
+    InExposure=false;
+    TelescopeTP = new ITextVectorProperty;
 }
 
 INDI::CCD::~CCD()
 {
-    //dtor
+    delete TelescopeTP;
 }
 
 bool INDI::CCD::initProperties()
 {
-    //IDLog("INDI::CCD initProperties '%s'\n",deviceName());
-
     DefaultDriver::initProperties();   //  let the base class flesh in what it wants
 
-    //IDLog("INDI::CCD::initProperties()\n");
-    IUFillNumber(&ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
-    IUFillNumber(&ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
-    IUFillNumber(&ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
-    IUFillNumber(&ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
-    IUFillNumberVector(&ImageFrameNV,ImageFrameN,4,deviceName(),"CCD_FRAME","Frame","Image Settings",IP_RW,60,IPS_IDLE);
-
-    IUFillSwitch(&FrameTypeS[0],"FRAME_LIGHT","Light",ISS_ON);
-    IUFillSwitch(&FrameTypeS[1],"FRAME_BIAS","Bias",ISS_OFF);
-    IUFillSwitch(&FrameTypeS[2],"FRAME_DARK","Dark",ISS_OFF);
-    IUFillSwitch(&FrameTypeS[3],"FRAME_FLAT","Flat",ISS_OFF);
-    IUFillSwitchVector(&FrameTypeSV,FrameTypeS,4,deviceName(),"CCD_FRAME_TYPE","FrameType","Image Settings",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
-
-    IUFillNumber(&ImageExposureN[0],"CCD_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
-    IUFillNumberVector(&ImageExposureNV,ImageExposureN,1,deviceName(),"CCD_EXPOSURE","Expose","Main Control",IP_RW,60,IPS_IDLE);
-    //IUFillNumber(&CcdExposureReqN[0],"CCD_EXPOSURE_VALUE","Duration","%5.2f",0,36000,0,1.0);
-    //IUFillNumberVector(&CcdExposureReqNV,CcdExposureReqN,1,deviceName(),"CCD_EXPOSURE_REQUEST","Expose","Main Control",IP_WO,60,IPS_IDLE);
-
-    IUFillNumber(&ImageBinN[0],"HOR_BIN","X","%2.0f",1,4,1,1);
-    IUFillNumber(&ImageBinN[1],"VER_BIN","Y","%2.0f",1,4,1,1);
-    IUFillNumberVector(&ImageBinNV,ImageBinN,2,deviceName(),"CCD_BINNING","Binning","Image Settings",IP_RW,60,IPS_IDLE);
-
-    IUFillNumber(&ImagePixelSizeN[0],"CCD_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
-    IUFillNumber(&ImagePixelSizeN[1],"CCD_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
-    IUFillNumber(&ImagePixelSizeN[2],"CCD_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
-    IUFillNumber(&ImagePixelSizeN[3],"CCD_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
-    IUFillNumber(&ImagePixelSizeN[4],"CCD_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
-    IUFillNumber(&ImagePixelSizeN[5],"CCD_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
-    IUFillNumberVector(&ImagePixelSizeNV,ImagePixelSizeN,6,deviceName(),"CCD_INFO","Ccd Information","Image Info",IP_RO,60,IPS_IDLE);
-
-
-
-    IUFillNumber(&GuiderFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
-    IUFillNumber(&GuiderFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
-    IUFillNumber(&GuiderFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
-    IUFillNumber(&GuiderFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
-    IUFillNumberVector(&GuiderFrameNV,GuiderFrameN,4,deviceName(),"GUIDER_FRAME","Frame","Guidehead Settings",IP_RW,60,IPS_IDLE);
-
-
-    IUFillNumber(&GuiderPixelSizeN[0],"GUIDER_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
-    IUFillNumber(&GuiderPixelSizeN[1],"GUIDER_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
-    IUFillNumber(&GuiderPixelSizeN[2],"GUIDER_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
-    IUFillNumber(&GuiderPixelSizeN[3],"GUIDER_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
-    IUFillNumber(&GuiderPixelSizeN[4],"GUIDER_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
-    IUFillNumber(&GuiderPixelSizeN[5],"GUIDER_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
-    IUFillNumberVector(&GuiderPixelSizeNV,GuiderPixelSizeN,6,deviceName(),"GUIDER_INFO","Guidehead Information","Guidehead Info",IP_RO,60,IPS_IDLE);
-
-
-    IUFillNumber(&GuiderExposureN[0],"GUIDER_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
-    IUFillNumberVector(&GuiderExposureNV,GuiderExposureN,1,deviceName(),"GUIDER_EXPOSURE","Guider","Main Cntrol",IP_RW,60,IPS_IDLE);
-
-
-    IUFillSwitch(&GuiderVideoS[0],"ON","on",ISS_OFF);
-    IUFillSwitch(&GuiderVideoS[1],"OFF","off",ISS_OFF);
-    IUFillSwitchVector(&GuiderVideoSV,GuiderVideoS,2,deviceName(),"VIDEO_STREAM","Guider Stream","Guidehead Settings",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
-
-    //IDLog("Setting up blob\n");
-
-    IUFillSwitch(&CompressS[0],"COMPRESS","Compress",ISS_OFF);
-    IUFillSwitch(&CompressS[1],"RAW","Raw",ISS_ON);
-    IUFillSwitchVector(&CompressSV,CompressS,2,deviceName(),"COMPRESSION","Image","Data Channel",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
-
-    IUFillSwitch(&GuiderCompressS[0],"GCOMPRESS","Compress",ISS_OFF);
-    IUFillSwitch(&GuiderCompressS[1],"GRAW","Raw",ISS_ON);
-    IUFillSwitchVector(&GuiderCompressSV,GuiderCompressS,2,deviceName(),"GCOMPRESSION","Guider","Data Channel",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
-
-    IUFillBLOB(&FitsB,"CCD1","Image","");
-    IUFillBLOBVector(&FitsBV,&FitsB,1,deviceName(),"CCD1","Image Data","Data Channel",IP_RO,60,IPS_IDLE);
-
-    IUFillBLOB(&GuiderB,"CCD2","Guider","");
-    IUFillBLOBVector(&GuiderBV,&GuiderB,1,deviceName(),"CCD2","Guider Data","Data Channel",IP_RO,60,IPS_IDLE);
-
-    IUFillNumber(&GuideNS[0],"TIMED_GUIDE_N","North (sec)","%g",0,10,0.001,0);
-    IUFillNumber(&GuideNS[1],"TIMED_GUIDE_S","South (sec)","%g",0,10,0.001,0);
-    IUFillNumberVector(&GuideNSV,GuideNS,2,deviceName(),"TELESCOPE_TIMED_GUIDE_NS","Guide North/South","GuiderControl",IP_RW,60,IPS_IDLE);
-
-    IUFillNumber(&GuideEW[0],"TIMED_GUIDE_E","East (sec)","%g",0,10,0.001,0);
-    IUFillNumber(&GuideEW[1],"TIMED_GUIDE_W","West (sec)","%g",0,10,0.001,0);
-    IUFillNumberVector(&GuideEWV,GuideEW,2,deviceName(),"TELESCOPE_TIMED_GUIDE_WE","Guide East/West","GuiderControl",IP_RW,60,IPS_IDLE);
-
-
-    //IDLog("Setting up ccdpreview stuff\n");
-    //IUFillNumber(&GuiderN[0],"WIDTH","Width","%4.0f",0.,1392.0,0.,1392.);
-    //IUFillNumber(&GuiderN[1],"HEIGHT","Height","%4.0f",0.,1040.,0.,1040.);
-    //IUFillNumber(&GuiderN[2],"MAXGOODDATA","max good","%5.0f",0.,65535.0,0.,65535.0);
-    //IUFillNumber(&GuiderN[3],"BYTESPERPIXEL","BPP","%1.0f",1.,4.,1.,2.);
-    //IUFillNumber(&GuiderN[4],"BYTEORDER","BO","%1.0f",1.,2.,1.,1.);
-    //IUFillNumberVector(&GuiderNV,GuiderN,5,deviceName(),"CCDPREVIEW_CTRL","Image Size","Guider Settings",IP_RW,60,IPS_IDLE);
-
-    return 0;
+    // PRIMARY CCD Init
+
+    IUFillNumber(&PrimaryCCD.ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
+    IUFillNumber(&PrimaryCCD.ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
+    IUFillNumber(&PrimaryCCD.ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
+    IUFillNumber(&PrimaryCCD.ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
+    IUFillNumberVector(PrimaryCCD.ImageFrameNP,PrimaryCCD.ImageFrameN,4,deviceName(),"CCD_FRAME","Frame",IMAGE_SETTINGS_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillSwitch(&PrimaryCCD.FrameTypeS[0],"FRAME_LIGHT","Light",ISS_ON);
+    IUFillSwitch(&PrimaryCCD.FrameTypeS[1],"FRAME_BIAS","Bias",ISS_OFF);
+    IUFillSwitch(&PrimaryCCD.FrameTypeS[2],"FRAME_DARK","Dark",ISS_OFF);
+    IUFillSwitch(&PrimaryCCD.FrameTypeS[3],"FRAME_FLAT","Flat",ISS_OFF);
+    IUFillSwitchVector(PrimaryCCD.FrameTypeSP,PrimaryCCD.FrameTypeS,4,deviceName(),"CCD_FRAME_TYPE","FrameType",IMAGE_SETTINGS_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillNumber(&PrimaryCCD.ImageExposureN[0],"CCD_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
+    IUFillNumberVector(PrimaryCCD.ImageExposureNP,PrimaryCCD.ImageExposureN,1,deviceName(),"CCD_EXPOSURE_REQUEST","Expose",MAIN_CONTROL_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillNumber(&PrimaryCCD.ImageBinN[0],"HOR_BIN","X","%2.0f",1,4,1,1);
+    IUFillNumber(&PrimaryCCD.ImageBinN[1],"VER_BIN","Y","%2.0f",1,4,1,1);
+    IUFillNumberVector(PrimaryCCD.ImageBinNP,PrimaryCCD.ImageBinN,2,deviceName(),"CCD_BINNING","Binning",IMAGE_SETTINGS_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[0],"CCD_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
+    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[1],"CCD_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
+    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[2],"CCD_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
+    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[3],"CCD_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
+    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[4],"CCD_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
+    IUFillNumber(&PrimaryCCD.ImagePixelSizeN[5],"CCD_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
+    IUFillNumberVector(PrimaryCCD.ImagePixelSizeNP,PrimaryCCD.ImagePixelSizeN,6,deviceName(),"CCD_INFO","Ccd Information",IMAGE_INFO_TAB,IP_RO,60,IPS_IDLE);
+
+    IUFillSwitch(&PrimaryCCD.CompressS[0],"COMPRESS","Compress",ISS_OFF);
+    IUFillSwitch(&PrimaryCCD.CompressS[1],"RAW","Raw",ISS_ON);
+    IUFillSwitchVector(PrimaryCCD.CompressSP,PrimaryCCD.CompressS,2,deviceName(),"COMPRESSION","Image",IMAGE_SETTINGS_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillBLOB(&PrimaryCCD.FitsB,"CCD1","Image","");
+    IUFillBLOBVector(PrimaryCCD.FitsBP,&PrimaryCCD.FitsB,1,deviceName(),"CCD1","Image Data",OPTIONS_TAB,IP_RO,60,IPS_IDLE);
+
+    // GUIDER CCD Init
+
+    IUFillNumber(&GuideCCD.ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
+    IUFillNumber(&GuideCCD.ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
+    IUFillNumber(&GuideCCD.ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
+    IUFillNumber(&GuideCCD.ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
+    IUFillNumberVector(GuideCCD.ImageFrameNP,GuideCCD.ImageFrameN,4,deviceName(),"GUIDE_FRAME","Frame",GUIDE_HEAD_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillNumber(&GuideCCD.ImagePixelSizeN[0],"Image_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
+    IUFillNumber(&GuideCCD.ImagePixelSizeN[1],"Image_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
+    IUFillNumber(&GuideCCD.ImagePixelSizeN[2],"Image_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
+    IUFillNumber(&GuideCCD.ImagePixelSizeN[3],"Image_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
+    IUFillNumber(&GuideCCD.ImagePixelSizeN[4],"Image_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
+    IUFillNumber(&GuideCCD.ImagePixelSizeN[5],"Image_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
+    IUFillNumberVector(GuideCCD.ImagePixelSizeNP,GuideCCD.ImagePixelSizeN,6,deviceName(),"GUIDE_INFO",GUIDE_HEAD_TAB,GUIDE_HEAD_TAB,IP_RO,60,IPS_IDLE);
+
+    IUFillNumber(&GuideCCD.ImageExposureN[0],"GUIDER_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
+    IUFillNumberVector(GuideCCD.ImageExposureNP,GuideCCD.ImageExposureN,1,deviceName(),"GUIDER_EXPOSURE","Image",MAIN_CONTROL_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillSwitch(&GuideCCD.CompressS[0],"GCOMPRESS","Compress",ISS_OFF);
+    IUFillSwitch(&GuideCCD.CompressS[1],"GRAW","Raw",ISS_ON);
+    IUFillSwitchVector(GuideCCD.CompressSP,GuideCCD.CompressS,2,deviceName(),"GCOMPRESSION","Image",GUIDE_HEAD_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillBLOB(&GuideCCD.FitsB,"CCD2","Guider Image","");
+    IUFillBLOBVector(GuideCCD.FitsBP,&GuideCCD.FitsB,1,deviceName(),"CCD2","Image Data",OPTIONS_TAB,IP_RO,60,IPS_IDLE);
+
+    // CCD Class Init
+
+    IUFillText(&TelescopeT[0],"ACTIVE_TELESCOPE","Telescope","");
+    IUFillTextVector(TelescopeTP,TelescopeT,1,deviceName(),"ACTIVE_DEVICES","Snoop Scope",OPTIONS_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillNumber(&EqN[0],"RA_PEC","Ra (hh:mm:ss)","%010.6m",0,24,0,0);
+    IUFillNumber(&EqN[1],"DEC_PEC","Dec (dd:mm:ss)","%010.6m",-90,90,0,0);
+    IUFillNumberVector(&EqNP,EqN,2,"","EQUATORIAL_PEC","EQ PEC","Main Control",IP_RW,60,IPS_IDLE);
+
+    // Guider Interface
+    initGuiderProperties(deviceName(), GUIDE_CONTROL_TAB);
+
+    return true;
 }
 
@@ -162,67 +265,127 @@
 {
     //IDLog("INDI::CCD UpdateProperties isConnected returns %d %d\n",isConnected(),Connected);
-    if(isConnected()) {
-        defineNumber(&ImageExposureNV);
-        defineNumber(&ImageFrameNV);
-        defineNumber(&ImageBinNV);
-
-
-        if(HasGuideHead) {
+    if(isConnected())
+    {
+        defineNumber(PrimaryCCD.ImageExposureNP);
+        defineNumber(PrimaryCCD.ImageFrameNP);
+        defineNumber(PrimaryCCD.ImageBinNP);
+
+        if(HasGuideHead)
+        {
             IDLog("Sending Guider Stuff\n");
-            defineNumber(&GuiderExposureNV);
-            defineNumber(&GuiderFrameNV);
-            defineSwitch(&GuiderVideoSV);
-        }
-
-        defineNumber(&ImagePixelSizeNV);
-        if(HasGuideHead) {
-            defineNumber(&GuiderPixelSizeNV);
-        }
-        defineSwitch(&CompressSV);
-        defineBLOB(&FitsBV);
+            defineNumber(GuideCCD.ImageExposureNP);
+            defineNumber(GuideCCD.ImageFrameNP);
+        }
+
+        defineNumber(PrimaryCCD.ImagePixelSizeNP);
         if(HasGuideHead)
         {
-            defineSwitch(&GuiderCompressSV);
-            defineBLOB(&GuiderBV);
+            defineNumber(GuideCCD.ImagePixelSizeNP);
+        }
+        defineSwitch(PrimaryCCD.CompressSP);
+        defineBLOB(PrimaryCCD.FitsBP);
+        if(HasGuideHead)
+        {
+            defineSwitch(GuideCCD.CompressSP);
+            defineBLOB(GuideCCD.FitsBP);
         }
         if(HasSt4Port)
         {
-            defineNumber(&GuideNSV);
-            defineNumber(&GuideEWV);
-        }
-        defineSwitch(&FrameTypeSV);
-    } else {
-        deleteProperty(ImageFrameNV.name);
-        deleteProperty(ImageBinNV.name);
-        deleteProperty(ImagePixelSizeNV.name);
-        deleteProperty(ImageExposureNV.name);
-        deleteProperty(FitsBV.name);
-        deleteProperty(CompressSV.name);
-        if(HasGuideHead) {
-            deleteProperty(GuiderVideoSV.name);
-            deleteProperty(GuiderExposureNV.name);
-            deleteProperty(GuiderFrameNV.name);
-            deleteProperty(GuiderPixelSizeNV.name);
-            deleteProperty(GuiderBV.name);
-            deleteProperty(GuiderCompressSV.name);
-        }
-        if(HasSt4Port) {
-            deleteProperty(GuideNSV.name);
-            deleteProperty(GuideEWV.name);
-
-        }
-        deleteProperty(FrameTypeSV.name);
+            defineNumber(GuideNSP);
+            defineNumber(GuideEWP);
+        }
+        defineSwitch(PrimaryCCD.FrameTypeSP);
+        defineText(TelescopeTP);
+    }
+    else
+    {
+        deleteProperty(PrimaryCCD.ImageFrameNP->name);
+        deleteProperty(PrimaryCCD.ImageBinNP->name);
+        deleteProperty(PrimaryCCD.ImagePixelSizeNP->name);
+        deleteProperty(PrimaryCCD.ImageExposureNP->name);
+        deleteProperty(PrimaryCCD.FitsBP->name);
+        deleteProperty(PrimaryCCD.CompressSP->name);
+        if(HasGuideHead)
+        {
+            deleteProperty(GuideCCD.ImageExposureNP->name);
+            deleteProperty(GuideCCD.ImageFrameNP->name);
+            deleteProperty(GuideCCD.ImagePixelSizeNP->name);
+            deleteProperty(GuideCCD.FitsBP->name);
+            deleteProperty(GuideCCD.CompressSP->name);
+        }
+        if(HasSt4Port)
+        {
+            deleteProperty(GuideNSP->name);
+            deleteProperty(GuideEWP->name);
+
+        }
+        deleteProperty(PrimaryCCD.FrameTypeSP->name);
+        deleteProperty(TelescopeTP->name);
     }
     return true;
 }
 
+void INDI::CCD::ISSnoopDevice (XMLEle *root)
+ {
+     //fprintf(stderr," ################# CCDSim handling snoop ##############\n");
+     if(IUSnoopNumber(root,&EqNP)==0)
+     {
+        float newra,newdec;
+        newra=EqN[0].value;
+        newdec=EqN[1].value;
+        if((newra != RA)||(newdec != Dec))
+        {
+            //fprintf(stderr,"RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
+            RA=newra;
+            Dec=newdec;
+
+        }
+     }
+     else
+     {
+        //fprintf(stderr,"Snoop Failed\n");
+     }
+ }
+
+bool INDI::CCD::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    //  Ok, lets see if this is a property wer process
+    //IDLog("IndiTelescope got %d new text items name %s\n",n,name);
+    //  first check if it's for our device
+    if(strcmp(dev,deviceName())==0)
+    {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+        if(strcmp(name,TelescopeTP->name)==0)
+        {
+            int rc;
+            //IDLog("calling update text\n");
+            TelescopeTP->s=IPS_OK;
+            rc=IUUpdateText(TelescopeTP,texts,names,n);
+            //IDLog("update text returns %d\n",rc);
+            //  Update client display
+            IDSetText(TelescopeTP,NULL);
+            saveConfig();
+            IUFillNumberVector(&EqNP,EqN,2,TelescopeT[0].text,"EQUATORIAL_PEC","EQ PEC",MAIN_CONTROL_TAB,IP_RW,60,IPS_IDLE);
+            IDSnoopDevice(TelescopeT[0].text,"EQUATORIAL_PEC");
+            //  We processed this one, so, tell the world we did it
+            return true;
+        }
+
+    }
+
+    return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);
+}
+
 bool INDI::CCD::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
 {
     //  first check if it's for our device
     //IDLog("INDI::CCD::ISNewNumber %s\n",name);
-    if(strcmp(dev,deviceName())==0) {
+    if(strcmp(dev,deviceName())==0)
+    {
         //  This is for our device
         //  Now lets see if it's something we process here
-        if(strcmp(name,"CCD_EXPOSURE")==0) {
+        if(strcmp(name,"CCD_EXPOSURE_REQUEST")==0)
+        {
             float n;
             int rc;
@@ -230,6 +393,10 @@
             n=values[0];
 
-            ImageExposureN[0].value=n;
-            ImageExposureNV.s=IPS_BUSY;
+            PrimaryCCD.ImageExposureN[0].value=n;
+
+            if (PrimaryCCD.ImageExposureNP->s==IPS_BUSY)
+                AbortExposure();
+
+            PrimaryCCD.ImageExposureNP->s=IPS_BUSY;
             //  now we have a new number, this is our requested exposure time
             //  Tell the clients we are busy with this exposure
@@ -237,20 +404,22 @@
             //  And now call the physical hardware layer to start the exposure
             rc=StartExposure(n);
-            switch(rc) {
+            switch(rc)
+            {
                 case 0: //  normal case, exposure running on timers, callbacks when it's finished
-                    ImageExposureNV.s=IPS_BUSY;
+                    PrimaryCCD.ImageExposureNP->s=IPS_BUSY;
                     break;
                 case 1: //  Short exposure, it's already done
-                    ImageExposureNV.s=IPS_OK;
+                    PrimaryCCD.ImageExposureNP->s=IPS_OK;
                     break;
                 case -1:    //  error condition
-                    ImageExposureNV.s=IPS_ALERT;
+                    PrimaryCCD.ImageExposureNP->s=IPS_ALERT;
                 break;
             }
-            IDSetNumber(&ImageExposureNV,NULL);
-            return true;
-        }
-
-        if(strcmp(name,"GUIDER_EXPOSURE")==0) {
+            IDSetNumber(PrimaryCCD.ImageExposureNP,NULL);
+            return true;
+        }
+
+        if(strcmp(name,"GUIDER_EXPOSURE")==0)
+        {
             float n;
             int rc;
@@ -258,6 +427,6 @@
             n=values[0];
 
-            GuiderExposureN[0].value=n;
-            GuiderExposureNV.s=IPS_BUSY;
+            GuideCCD.ImageExposureN[0].value=n;
+            GuideCCD.ImageExposureNP->s=IPS_BUSY;
             //  now we have a new number, this is our requested exposure time
             //  Tell the clients we are busy with this exposure
@@ -270,69 +439,86 @@
             switch(rc) {
                 case 0: //  normal case, exposure running on timers, callbacks when it's finished
-                    GuiderExposureNV.s=IPS_BUSY;
+                    GuideCCD.ImageExposureNP->s=IPS_BUSY;
                     break;
                 case 1: //  Short exposure, it's already done
-                    GuiderExposureNV.s=IPS_OK;
+                    GuideCCD.ImageExposureNP->s=IPS_OK;
                     break;
                 case -1:    //  error condition
-                    GuiderExposureNV.s=IPS_ALERT;
+                    GuideCCD.ImageExposureNP->s=IPS_ALERT;
                 break;
             }
-            IDSetNumber(&GuiderExposureNV,NULL);
-            return true;
-        }
-        if(strcmp(name,"CCD_BINNING")==0) {
+            IDSetNumber(GuideCCD.ImageExposureNP,NULL);
+            return true;
+        }
+
+        if(strcmp(name,"CCD_BINNING")==0)
+        {
             //  We are being asked to set camera binning
-            ImageBinNV.s=IPS_OK;
-            IUUpdateNumber(&ImageBinNV,values,names,n);
+            PrimaryCCD.ImageBinNP->s=IPS_OK;
+            IUUpdateNumber(PrimaryCCD.ImageBinNP,values,names,n);
+
+            // Let child classes know of CCD BIN changes
+            // If child processes and updates bin (true) then no further action is needed
+            // if child class does not do any processing, then we simply update the values.
+            if (updateCCDBin(PrimaryCCD.ImageBinN[0].value, PrimaryCCD.ImageBinN[1].value) == false)
+                PrimaryCCD.setBin(PrimaryCCD.ImageBinN[0].value, PrimaryCCD.ImageBinN[1].value);
+
+            return true;
+
+        }
+
+        if(strcmp(name,"CCD_FRAME")==0)
+        {
+            //  We are being asked to set camera binning
+            PrimaryCCD.ImageFrameNP->s=IPS_OK;
+            IUUpdateNumber(PrimaryCCD.ImageFrameNP,values,names,n);
             //  Update client display
-            IDSetNumber(&ImageBinNV,NULL);
-
-            //IDLog("Binning set to %4.0f x %4.0f\n",CcdBinN[0].value,CcdBinN[1].value);
-            BinX=ImageBinN[0].value;
-            BinY=ImageBinN[1].value;
-        }
-        if(strcmp(name,"CCD_FRAME")==0) {
+            //IDSetNumber(PrimaryCCD.ImageFrameNP,NULL);
+
+            //IDLog("Frame set to %4.0f,%4.0f %4.0f x %4.0f\n",CcdFrameN[0].value,CcdFrameN[1].value,CcdFrameN[2].value,CcdFrameN[3].value);
+            //SubX=PrimaryCCD.ImageFrameN[0].value;
+            //SubY=PrimaryCCD.ImageFrameN[1].value;
+            //SubW=PrimaryCCD.ImageFrameN[2].value;
+            //SubH=PrimaryCCD.ImageFrameN[3].value;
+
+            if (updateCCDFrame(PrimaryCCD.ImageFrameN[0].value, PrimaryCCD.ImageFrameN[1].value, PrimaryCCD.ImageFrameN[2].value,
+                               PrimaryCCD.ImageFrameN[3].value) == false)
+                PrimaryCCD.setFrame(PrimaryCCD.ImageFrameN[0].value, PrimaryCCD.ImageFrameN[1].value, PrimaryCCD.ImageFrameN[2].value,
+                                    PrimaryCCD.ImageFrameN[3].value);
+            return true;
+        }
+
+        if(strcmp(name,"GUIDER_FRAME")==0)
+        {
             //  We are being asked to set camera binning
-            ImageFrameNV.s=IPS_OK;
-            IUUpdateNumber(&ImageFrameNV,values,names,n);
+            GuideCCD.ImageFrameNP->s=IPS_OK;
+            IUUpdateNumber(GuideCCD.ImageFrameNP,values,names,n);
             //  Update client display
-            IDSetNumber(&ImageFrameNV,NULL);
-
-            //IDLog("Frame set to %4.0f,%4.0f %4.0f x %4.0f\n",CcdFrameN[0].value,CcdFrameN[1].value,CcdFrameN[2].value,CcdFrameN[3].value);
-            SubX=ImageFrameN[0].value;
-            SubY=ImageFrameN[1].value;
-            SubW=ImageFrameN[2].value;
-            SubH=ImageFrameN[3].value;
-            return true;
-        }
-
-        if(strcmp(name,"GUIDER_FRAME")==0) {
-            //  We are being asked to set camera binning
-            GuiderFrameNV.s=IPS_OK;
-            IUUpdateNumber(&GuiderFrameNV,values,names,n);
+            //IDSetNumber(GuiderFrameNP,NULL);
+
+            IDLog("GuiderFrame set to %4.0f,%4.0f %4.0f x %4.0f\n",
+                  GuideCCD.ImageFrameN[0].value,GuideCCD.ImageFrameN[1].value,GuideCCD.ImageFrameN[2].value,GuideCCD.ImageFrameN[3].value);
+            //GSubX=GuiderFrameN[0].value;
+            //GSubY=GuiderFrameN[1].value;
+            //GSubW=GuiderFrameN[2].value;
+            //GSubH=GuiderFrameN[3].value;
+            GuideCCD.setFrame(GuideCCD.ImageFrameN[0].value, GuideCCD.ImageFrameN[1].value,
+                              GuideCCD.ImageFrameN[2].value,GuideCCD.ImageFrameN[3].value);
+
+            return true;
+        }
+
+        if(strcmp(name,GuideNSP->name)==0)
+        {
+            //  We are being asked to send a guide pulse north/south on the st4 port
+            GuideNSP->s=IPS_BUSY;
+            IUUpdateNumber(GuideNSP,values,names,n);
             //  Update client display
-            IDSetNumber(&GuiderFrameNV,NULL);
-
-            IDLog("GuiderFrame set to %4.0f,%4.0f %4.0f x %4.0f\n",
-                  GuiderFrameN[0].value,GuiderFrameN[1].value,GuiderFrameN[2].value,GuiderFrameN[3].value);
-            GSubX=GuiderFrameN[0].value;
-            GSubY=GuiderFrameN[1].value;
-            GSubW=GuiderFrameN[2].value;
-            GSubH=GuiderFrameN[3].value;
-            return true;
-        }
-
-        if(strcmp(name,GuideNSV.name)==0) {
-            //  We are being asked to send a guide pulse north/south on the st4 port
-            GuideNSV.s=IPS_BUSY;
-            IUUpdateNumber(&GuideNSV,values,names,n);
-            //  Update client display
-            IDSetNumber(&GuideNSV,NULL);
-
-            fprintf(stderr,"GuideNorthSouth set to %7.3f,%7.3f\n",
-                  GuideNS[0].value,GuideNS[1].value);
-
-            if(GuideNS[0].value != 0) {
+            IDSetNumber(GuideNSP,NULL);
+
+            fprintf(stderr,"GuideNorthSouth set to %7.3f,%7.3f\n", GuideNS[0].value,GuideNS[1].value);
+
+            if(GuideNS[0].value != 0)
+            {
                 GuideNorth(GuideNS[0].value);
             }
@@ -342,22 +528,26 @@
             GuideNS[0].value=0;
             GuideNS[1].value=0;
-            GuideNSV.s=IPS_OK;
-            IDSetNumber(&GuideNSV,NULL);
-
-            return true;
-        }
-        if(strcmp(name,GuideEWV.name)==0) {
+            GuideNSP->s=IPS_OK;
+            IDSetNumber(GuideNSP,NULL);
+
+            return true;
+        }
+
+        if(strcmp(name,GuideEWP->name)==0)
+        {
             //  We are being asked to send a guide pulse north/south on the st4 port
-            GuideEWV.s=IPS_BUSY;
-            IUUpdateNumber(&GuideEWV,values,names,n);
+            GuideEWP->s=IPS_BUSY;
+            IUUpdateNumber(GuideEWP,values,names,n);
             //  Update client display
-            IDSetNumber(&GuideEWV,NULL);
+            IDSetNumber(GuideEWP,NULL);
 
             fprintf(stderr,"GuiderEastWest set to %6.3f,%6.3f\n",
                   GuideEW[0].value,GuideEW[1].value);
 
-            if(GuideEW[0].value != 0) {
+            if(GuideEW[0].value != 0)
+            {
                 GuideEast(GuideEW[0].value);
-            } else {
+            } else
+            {
                 GuideWest(GuideEW[1].value);
             }
@@ -365,20 +555,9 @@
             GuideEW[0].value=0;
             GuideEW[1].value=0;
-            GuideEWV.s=IPS_OK;
-            IDSetNumber(&GuideEWV,NULL);
-
-            return true;
-        }
-
-        /*
-        if(strcmp(name,"CCDPREVIEW_CTRL")==0) {
-            //  We are being asked to set camera binning
-            GuiderNV.s=IPS_OK;
-            IUUpdateNumber(&GuiderNV,values,names,n);
-            //  Update client display
-            IDSetNumber(&GuiderNV,NULL);
-            return true;
-        }
-        */
+            GuideEWP->s=IPS_OK;
+            IDSetNumber(GuideEWP,NULL);
+
+            return true;
+        }
 
     }
@@ -391,69 +570,53 @@
 {
 
-    //  Ok, lets Process any switches we actually handle here
-    //IDLog("INDI::CCD IsNewSwitch %s %s\n",dev,name);
-
-
-    if(strcmp(dev,deviceName())==0) {
-        //  it's for this device
-
-        //for(int x=0; x<n; x++) {
-        //    IDLog("Switch %s\n",names[x]);
-        //}
-
-        if(strcmp(name,CompressSV.name)==0) {
-
-            IUUpdateSwitch(&CompressSV,states,names,n);
-            IDSetSwitch(&CompressSV,NULL);
-
-            if(CompressS[0].s==ISS_ON    ) {
-                SendCompressed=true;
-            } else {
-                SendCompressed=false;
+    if(strcmp(dev,deviceName())==0)
+    {
+
+
+        if(strcmp(name,PrimaryCCD.CompressSP->name)==0)
+        {
+
+            IUUpdateSwitch(PrimaryCCD.CompressSP,states,names,n);
+            IDSetSwitch(PrimaryCCD.CompressSP,NULL);
+
+            if(PrimaryCCD.CompressS[0].s==ISS_ON    )
+            {
+                PrimaryCCD.SendCompressed=true;
+            } else
+            {
+                PrimaryCCD.SendCompressed=false;
             }
             return true;
         }
-        if(strcmp(name,GuiderCompressSV.name)==0) {
-
-            IUUpdateSwitch(&GuiderCompressSV,states,names,n);
-            IDSetSwitch(&GuiderCompressSV,NULL);
-
-            if(GuiderCompressS[0].s==ISS_ON    ) {
-                SendCompressed=true;
-            } else {
-                SendCompressed=false;
+
+        if(strcmp(name,GuideCCD.CompressSP->name)==0)
+        {
+
+            IUUpdateSwitch(GuideCCD.CompressSP,states,names,n);
+            IDSetSwitch(GuideCCD.CompressSP,NULL);
+
+            if(GuideCCD.CompressS[0].s==ISS_ON    )
+            {
+                GuideCCD.SendCompressed=true;
+            } else
+            {
+                GuideCCD.SendCompressed=false;
             }
             return true;
         }
 
-        if(strcmp(name,GuiderVideoSV.name)==0) {
+        if(strcmp(name,PrimaryCCD.FrameTypeSP->name)==0)
+        {
             //  Compression Update
-            IUUpdateSwitch(&GuiderVideoSV,states,names,n);
-            if(GuiderVideoS[0].s==ISS_ON    ) {
-                GuiderVideoSV.s=IPS_OK;
-                StartGuideExposure(GuiderExposureN[0].value);
-            } else {
-                AbortGuideExposure();
-                GuiderVideoSV.s=IPS_IDLE;
-            }
-
-            IDSetSwitch(&GuiderVideoSV,NULL);
-            return true;
-        }
-
-        if(strcmp(name,FrameTypeSV.name)==0) {
-            //  Compression Update
-            IUUpdateSwitch(&FrameTypeSV,states,names,n);
-            FrameTypeSV.s=IPS_OK;
-            if(FrameTypeS[0].s==ISS_ON) SetFrameType(FRAME_TYPE_LIGHT);
-            if(FrameTypeS[1].s==ISS_ON) SetFrameType(FRAME_TYPE_BIAS);
-            if(FrameTypeS[2].s==ISS_ON) SetFrameType(FRAME_TYPE_DARK);
-            if(FrameTypeS[3].s==ISS_ON) SetFrameType(FRAME_TYPE_FLAT);
-
-
-            IDSetSwitch(&FrameTypeSV,NULL);
-            return true;
-        }
-
+            IUUpdateSwitch(PrimaryCCD.FrameTypeSP,states,names,n);
+            PrimaryCCD.FrameTypeSP->s=IPS_OK;
+            if(PrimaryCCD.FrameTypeS[0].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::LIGHT_FRAME);
+            if(PrimaryCCD.FrameTypeS[1].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::BIAS_FRAME);
+            if(PrimaryCCD.FrameTypeS[2].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::DARK_FRAME);
+            if(PrimaryCCD.FrameTypeS[3].s==ISS_ON) PrimaryCCD.setFrameType(CCDChip::FLAT_FRAME);
+
+            IDSetSwitch(PrimaryCCD.FrameTypeSP,NULL);
+            return true;
+        }
     }
 
@@ -475,4 +638,28 @@
     return -1;
 }
+
+bool INDI::CCD::AbortExposure()
+{
+    IDLog("INDI::CCD::AbortExposure -  Should never get here\n");
+    return false;
+}
+
+bool INDI::CCD::updateCCDFrame(int x, int y, int w, int h)
+{
+    // Nothing to do here. HW layer should take care of it if needed.
+    return false;
+}
+
+bool INDI::CCD::updateCCDBin(int hor, int ver)
+{
+    // Nothing to do here. HW layer should take care of it if needed.
+    return false;
+}
+
+void INDI::CCD::addFITSKeywords(fitsfile *fptr)
+{
+    // Nothing to do here. HW layer should take care of it if needed.
+}
+
 bool INDI::CCD::ExposureComplete()
 {
@@ -482,53 +669,57 @@
     long naxes[2];
     long naxis=2;
+    int numbytes=0;
 
     fitsfile *fptr=NULL;
 
-
     //IDLog("Enter Exposure Complete %d %d %d %d\n",SubW,SubH,BinX,BinY);
 
-
-    naxes[0]=SubW/BinX;
-    naxes[1]=SubH/BinY;
+    naxes[0]=PrimaryCCD.getSubW()/PrimaryCCD.getBinX();
+    naxes[1]=PrimaryCCD.getSubH()/PrimaryCCD.getBinY();
+
+    numbytes = naxes[0] * naxes[1];
+
     //  Now we have to send fits format data to the client
     memsize=5760;
     memptr=malloc(memsize);
-    if(!memptr) {
+    if(!memptr)
+    {
         IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize);
     }
+
     fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
-    if(status) {
+
+    if(status)
+    {
 		IDLog("Error: Failed to create FITS image\n");
 		fits_report_error(stderr, status);  /* print out any error messages */
 		return false;
     }
-  	fits_create_img(fptr, USHORT_IMG , naxis, naxes, &status);
-	if (status)
-	{
+
+    fits_create_img(fptr, USHORT_IMG , naxis, naxes, &status);
+
+    if (status)
+    {
 		IDLog("Error: Failed to create FITS image\n");
 		fits_report_error(stderr, status);  /* print out any error messages */
 		return false;
-	}
-
-    fits_write_img(fptr,TUSHORT,1,SubW*SubH/BinX/BinY,RawFrame,&status);
+    }
+
+    addFITSKeywords(fptr);
+
+    fits_write_img(fptr,TUSHORT,1,numbytes,PrimaryCCD.getFrameBuffer(),&status);
+
     if (status)
-	{
+    {
 		IDLog("Error: Failed to write FITS image\n");
 		fits_report_error(stderr, status);  /* print out any error messages */
 		return false;
-	}
-	fits_close_file(fptr,&status);
-	//IDLog("Built the fits file\n");
-
-    //  ok, undo the kludge we threw in for
-    //  guider frames, and set the resolution back
-
-    //ImageFrameN[2].value=SubW;
-    //ImageFrameN[3].value=SubH;
-    //IDSetNumber(&ImageFrameNV,NULL);
-
-
-    ImageExposureNV.s=IPS_OK;
-    IDSetNumber(&ImageExposureNV,NULL);
+    }
+
+    fits_close_file(fptr,&status);
+
+
+    PrimaryCCD.ImageExposureNP->s=IPS_OK;
+    IDSetNumber(PrimaryCCD.ImageExposureNP,NULL);
 
     uploadfile(memptr,memsize);
@@ -539,32 +730,4 @@
 bool INDI::CCD::GuideExposureComplete()
 {
-
-    //IDLog("Enter GuideExposure Complete %d %d\n",GSubW,GSubH);
-
-    if(GuiderVideoS[0].s==ISS_ON) {
-        //  if our stream switch for the guider
-        //  is on, then send this as a video stream
-        //  frame, and, start another frame
-
-        //  Ok, bit of a kludge here
-        //  we need to send a new size to kstars
-        //ImageFrameN[2].value=GSubW;
-        //ImageFrameN[3].value=GSubH;
-        //IDSetNumber(&ImageFrameNV,NULL);
-
-        //IDLog("Sending guider stream blob\n");
-
-        GuiderExposureNV.s=IPS_OK;
-        IDSetNumber(&GuiderExposureNV,NULL);
-        GuiderB.blob=RawGuiderFrame;
-        GuiderB.bloblen=GSubW*GSubH;
-        GuiderB.size=GSubW*GSubH;
-        strcpy(GuiderB.format,".stream");
-        GuiderBV.s=IPS_OK;
-        IDSetBLOB(&GuiderBV,NULL);
-        StartGuideExposure(GuiderExposureN[0].value);
-    } else {
-        //  We are not streaming
-        //  So, lets send this as an 8 bit fits frame
         void *memptr;
         size_t memsize;
@@ -574,14 +737,16 @@
 
         fitsfile *fptr=NULL;
-        naxes[0]=GSubW;
-        naxes[1]=GSubH;
+        naxes[0]=GuideCCD.getSubW();
+        naxes[1]=GuideCCD.getSubH();
         //  Now we have to send fits format data to the client
         memsize=5760;
         memptr=malloc(memsize);
-        if(!memptr) {
+        if(!memptr)
+        {
             IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize);
         }
         fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
-        if(status) {
+        if(status)
+        {
             IDLog("Error: Failed to create FITS image\n");
             fits_report_error(stderr, status);  /* print out any error messages */
@@ -596,5 +761,5 @@
         }
 
-        fits_write_img(fptr,TBYTE,1,GSubW*GSubH,RawGuiderFrame,&status);
+        fits_write_img(fptr,TBYTE,1,naxes[0]*naxes[1],GuideCCD.getFrameBuffer(),&status);
         if (status)
         {
@@ -605,17 +770,15 @@
         fits_close_file(fptr,&status);
         IDLog("Built the Guider fits file\n");
-        GuiderExposureNV.s=IPS_OK;
-        IDSetNumber(&GuiderExposureNV,NULL);
-
-        IDLog("Sending guider fits file via %s\n",GuiderBV.name);
-        GuiderB.blob=memptr;
-        GuiderB.bloblen=memsize;
-        GuiderB.size=memsize;
-        strcpy(GuiderB.format,".fits");
-        GuiderBV.s=IPS_OK;
-        IDSetBLOB(&GuiderBV,NULL);
+        GuideCCD.ImageExposureNP->s=IPS_OK;
+        IDSetNumber(GuideCCD.ImageExposureNP,NULL);
+
+        IDLog("Sending guider fits file via %s\n",GuideCCD.FitsBP->name);
+        GuideCCD.FitsB.blob=memptr;
+        GuideCCD.FitsB.bloblen=memsize;
+        GuideCCD.FitsB.size=memsize;
+        strcpy(GuideCCD.FitsB.format,".fits");
+        GuideCCD.FitsBP->s=IPS_OK;
+        IDSetBLOB(GuideCCD.FitsBP,NULL);
         free(memptr);
-    }
-
 
     return true;
@@ -623,108 +786,38 @@
 
 
-int INDI::CCD::sendPreview()
-{
-    int numbytes;
-    int xw;
-    int yw;
-    //unsigned char *compressed;
-    //uLongf compressedbytes=0;
-    //int ccount;
-    //int r;
+int INDI::CCD::uploadfile(void *fitsdata,int total)
+{
+    //  lets try sending a ccd preview
+    //IDLog("Enter Uploadfile with %d total sending via %s\n",total,FitsBP->name);
+    PrimaryCCD.FitsB.blob=fitsdata;
+    PrimaryCCD.FitsB.bloblen=total;
+    PrimaryCCD.FitsB.size=total;
+    strcpy(PrimaryCCD.FitsB.format,".fits");
+    PrimaryCCD.FitsBP->s=IPS_OK;
+    IDSetBLOB(PrimaryCCD.FitsBP,NULL);
 
     return 0;
-    xw=SubW/BinX;
-    yw=SubH/BinY;
-
-    //GuiderNV.s=IPS_OK;
-    //GuiderN[0].value=xw;
-    //GuiderN[1].value=yw;
-    //IDLog("Guider Frame %d x %d\n",xw,yw);
-    //IDSetNumber(&GuiderNV,"Starting to send new preview frame\n");
-
-    numbytes=xw*yw;
-    numbytes=numbytes*2;
-    //compressedbytes=numbytes+numbytes/64+16+3;
-    //compressed=(unsigned char *)malloc(numbytes+numbytes/64+16+3);
-    //r=compress2(compressed,&compressedbytes,(unsigned char *)RawFrame,numbytes,9);
-    //if(r != Z_OK) {
-    //    IDLog("Got an error from compress\n");
-    //    return -1;
-    //}
-
-
-    //FitsB.blob=compressed;
-    //FitsB.bloblen=compressedbytes;
-    FitsB.blob=RawFrame;
-    FitsB.bloblen=numbytes;
-    FitsB.size=numbytes;
-    FitsBV.s=IPS_OK;
-    strcpy(FitsB.format,".ccdpreview");
-    IDSetBLOB(&FitsBV,NULL);
-    //IDLog("Done with SetBlob with %d compressed to %d\n",numbytes,compressedbytes);
-    //free(compressed);
-    return 0;
-
-}
-
-int INDI::CCD::uploadfile(void *fitsdata,int total)
-{
-    //  lets try sending a ccd preview
-
-
-    //IDLog("Enter Uploadfile with %d total sending via %s\n",total,FitsBV.name);
-    FitsB.blob=fitsdata;
-    FitsB.bloblen=total;
-    FitsB.size=total;
-    strcpy(FitsB.format,".fits");
-    FitsBV.s=IPS_OK;
-    IDSetBLOB(&FitsBV,NULL);
-    //IDLog("Done with SetBlob\n");
-
-    return 0;
-}
-
-int INDI::CCD::SetCCDParams(int x,int y,int bpp,float xf,float yf)
-{
-    XRes=x;
-    YRes=y;
-    SubX=0;
-    SubY=0;
-    SubW=XRes;
-    SubH=YRes;
-    BinX=1;
-    BinY=1;
-
-    PixelSizex=xf;
-    PixelSizey=yf;
-    ImageFrameN[2].value=x;
-    ImageFrameN[3].value=y;
-    ImagePixelSizeN[0].value=x;
-    ImagePixelSizeN[1].value=y;
-    ImagePixelSizeN[2].value=xf;
-    ImagePixelSizeN[3].value=xf;
-    ImagePixelSizeN[4].value=yf;
-    ImagePixelSizeN[5].value=bpp;
-    return 0;
-}
-
-int INDI::CCD::SetGuidHeadParams(int x,int y,int bpp,float xf,float yf)
+}
+
+void INDI::CCD::SetCCDParams(int x,int y,int bpp,float xf,float yf)
+{
+    PrimaryCCD.setResolutoin(x, y);
+    PrimaryCCD.setFrame(0, 0, x, y);
+    PrimaryCCD.setBin(1,1);
+    PrimaryCCD.setPixelSize(xf, yf);
+    PrimaryCCD.setBPP(bpp/8);
+
+}
+
+void INDI::CCD::SetGuidHeadParams(int x,int y,int bpp,float xf,float yf)
 {
     HasGuideHead=true;
-    GXRes=x;
-    GYRes=y;
-    GSubX=0;
-    GSubY=0;
-    GSubW=GXRes;
-    GSubH=GYRes;
-    GuiderFrameN[2].value=x;
-    GuiderFrameN[3].value=y;
-    GuiderPixelSizeN[0].value=x;
-    GuiderPixelSizeN[1].value=y;
-    GuiderPixelSizeN[2].value=xf;
-    GuiderPixelSizeN[3].value=xf;
-    GuiderPixelSizeN[4].value=yf;
-    GuiderPixelSizeN[5].value=bpp;
-    return 0;
+
+    GuideCCD.setResolutoin(x, y);
+    GuideCCD.setFrame(0, 0, x, y);
+    GuideCCD.setBin(1,1);
+    GuideCCD.setPixelSize(xf, yf);
+    GuideCCD.setBPP(bpp/8);
+
 }
 
@@ -734,24 +827,20 @@
 }
 
-int INDI::CCD::GuideNorth(float)
-{
-    return -1;
-}
-int INDI::CCD::GuideSouth(float)
-{
-    return -1;
-}
-int INDI::CCD::GuideEast(float)
-{
-    return -1;
-}
-int INDI::CCD::GuideWest(float)
-{
-    return -1;
-}
-int INDI::CCD::SetFrameType(int t)
-{
-    //fprintf(stderr,"Set frame type to %d\n",t);
-    FrameType=t;
-    return 0;
-}
+
+bool INDI::CCD::GuideNorth(float ms)
+{
+    return false;
+}
+bool INDI::CCD::GuideSouth(float ms)
+{
+    return false;
+}
+bool INDI::CCD::GuideEast(float ms)
+{
+    return false;
+}
+bool INDI::CCD::GuideWest(float ms)
+{
+    return false;
+}
+
Index: /BAORadio/libindi/libindi/libs/indibase/indiccd.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiccd.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indiccd.h	(revision 642)
@@ -1,163 +1,262 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+  Copyright(c) 2010, 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
+
 
 #ifndef INDI_CCD_H
 #define INDI_CCD_H
 
+#include <fitsio.h>
+
 #include "defaultdriver.h"
-
-#define FRAME_TYPE_LIGHT 0
-#define FRAME_TYPE_BIAS 1
-#define FRAME_TYPE_DARK 2
-#define FRAME_TYPE_FLAT 3
-
-class INDI::CCD : public INDI::DefaultDriver
+#include "indiguiderinterface.h"
+
+extern const char *IMAGE_SETTINGS_TAB;
+extern const char *IMAGE_INFO_TAB;
+extern const char *GUIDE_HEAD_TAB;
+extern const char *GUIDE_CONTROL_TAB;
+
+class CCDChip
 {
-    protected:
-
-        char *RawFrame;
-        int RawFrameSize;
-
-        //  Altho these numbers are indeed stored in the indi properties
-        //  It makes for much cleaner code if we have 'plain old number' copies
-        //  So, when we process messages, just update both
-
-        int XRes;   //  native resolution of the ccd
-        int YRes;   //  ditto
-        int SubX;   //  left side of the subframe we are requesting
-        int SubY;   //  top of the subframe requested
-        int SubW;   //  width of the subframe
-        int SubH;   //  height of the subframe
-        int BinX;   //  Binning requested in the x direction
-        int BinY;   //  Binning requested in the Y direction
-        float PixelSizex;   //  pixel size in microns, x direction
-        float PixelSizey;   //  pixel size in microns, y direction
-        bool SendCompressed;
-
-        bool HasSt4Port;
-
-        //  If the camera has a second ccd, or integrated guide head
-        //  we need information on that one too
-        bool HasGuideHead;
-        char *RawGuiderFrame;
-        int RawGuideSize;
-        int GXRes;  //  native resolution of the guide head
-        int GYRes;  //  native resolution
-        int GSubX;  //  left side of the guide image subframe
-        int GSubY;  //  top of the guide image subframe
-        int GSubW;  //  Width of the guide image
-        int GSubH;  //  Height of the guide image
-        float GPixelSizex;  //  phyiscal size of the guider pixels
-        float GPixelSizey;
-        bool GuiderCompressed;
-
-        int FrameType;
-
-
-    private:
-    public:
+
+public:
+    CCDChip();
+    ~CCDChip();
+
+    typedef enum { LIGHT_FRAME=0, BIAS_FRAME, DARK_FRAME, FLAT_FRAME } CCD_FRAME;
+
+    int getXRes() { return XRes; }
+    int getYRes() { return YRes; }
+    int getSubX() { return SubX; }
+    int getSubY() { return SubY; }
+    int getSubW() { return SubW; }
+    int getSubH() { return SubH; }
+    int getBinX() { return BinX; }
+    int getBinY() { return BinY; }
+    int getPixelSizeX() { return PixelSizex; }
+    int getPixelSizeY() { return PixelSizey; }
+    int getBPP() { return BPP; }
+    int getFrameBufferSize() { return RawFrameSize; }
+    double getExposure() { return ImageExposureN[0].value; }
+    char *getFrameBuffer() { return RawFrame; }
+    bool isCompressed() { return SendCompressed; }
+    bool isInterlaced() { return Interlaced; }
+    CCD_FRAME getFrameType() { return FrameType; }
+
+    void setResolutoin(int x, int y);
+    void setFrame(int subx, int suby, int subw, int subh);
+    void setBin(int hor, int ver);
+    void setPixelSize(int x, int y);
+    void setCompressed (bool cmp);
+    void setInterlaced(bool intr);
+    void setFrameBufferSize(int nbuf);
+    void setBPP(int bpp);
+    int setFrameType(CCD_FRAME);
+    void setExposure(double duration);
+    void setExposureFailed();
+
+private:
+
+    int XRes;   //  native resolution of the ccd
+    int YRes;   //  ditto
+    int SubX;   //  left side of the subframe we are requesting
+    int SubY;   //  top of the subframe requested
+    int SubW;   //  width of the subframe
+    int SubH;   //  height of the subframe
+    int BinX;   //  Binning requested in the x direction
+    int BinY;   //  Binning requested in the Y direction
+    float PixelSizex;   //  pixel size in microns, x direction
+    float PixelSizey;   //  pixel size in microns, y direction
+    int BPP;            //  Bytes per Pixel
+    bool Interlaced;
+    char *RawFrame;
+    int RawFrameSize;
+    bool SendCompressed;
+    CCD_FRAME FrameType;
+
+    INumberVectorProperty *ImageExposureNP;
+    INumber ImageExposureN[1];
+
+    INumberVectorProperty *ImageFrameNP;
+    INumber ImageFrameN[4];
+
+    INumberVectorProperty *ImageBinNP;
+    INumber ImageBinN[2];
+
+    INumberVectorProperty *ImagePixelSizeNP;
+    INumber ImagePixelSizeN[6];
+
+    ISwitch FrameTypeS[4];
+    ISwitchVectorProperty *FrameTypeSP;
+
+    ISwitch CompressS[2];
+    ISwitchVectorProperty *CompressSP;
+
+    IBLOB FitsB;
+    IBLOBVectorProperty *FitsBP;
+
+    friend class INDI::CCD;
+};
+
+/**
+ * \class INDI::CCD
+   \brief Class to provide general functionality of CCD cameras with a single CCD sensor, or a primary CCD sensor in addition to a secondary CCD guide head.
+
+   It also implements the interface to perform guiding. The class enable the ability to \e snoop on telescope equatorial coordinates and record them in the
+   FITS file before upload. Developers need to subclass INDI::CCD to implement any driver for CCD cameras within INDI.
+
+\author Gerry Rozema, Jasem Mutlaq
+*/
+class INDI::CCD : public INDI::DefaultDriver, INDI::GuiderInterface
+{
+      public:
         CCD();
         virtual ~CCD();
 
-        //  A ccd needs to desribe the frame
-        //INumberVectorProperty CcdFrameNV;
-        //INumberVectorProperty CcdExposureNV;
-        //INumberVectorProperty CcdBinNV;
-        //INumberVectorProperty CcdPixelSizeNV;
-
-
-        INumberVectorProperty ImageFrameNV;
-        INumber ImageFrameN[4];
-
-        INumberVectorProperty ImageBinNV;
-        INumber ImageBinN[2];
-
-        INumberVectorProperty ImagePixelSizeNV;
-        INumber ImagePixelSizeN[6];
-
-        INumberVectorProperty ImageExposureNV;
-        INumber ImageExposureN[1];
-
-        //INumberVectorProperty ImageExposureReqNV;
-        //INumber ImageExposureReqN[1];
-
-        INumberVectorProperty GuiderFrameNV;
-        INumber GuiderFrameN[4];
-        INumberVectorProperty GuiderPixelSizeNV;
-        INumber GuiderPixelSizeN[6];
-        INumberVectorProperty GuiderExposureNV;
-        INumber GuiderExposureN[1];
-
-        ISwitch FrameTypeS[4];
-        ISwitchVectorProperty FrameTypeSV;
-
-
-        ISwitch CompressS[2];
-        ISwitchVectorProperty CompressSV;
-
-        ISwitch GuiderCompressS[2];
-        ISwitchVectorProperty GuiderCompressSV;
-
-
-        ISwitch GuiderVideoS[2];
-        ISwitchVectorProperty GuiderVideoSV;
-
-        INumber GuideNS[2];
-        INumberVectorProperty GuideNSV;
-        INumber GuideEW[2];
-        INumberVectorProperty GuideEWV;
-
-        IBLOB FitsB;
-        IBLOBVectorProperty FitsBV;
-
-        IBLOB GuiderB;
-        IBLOBVectorProperty GuiderBV;
-
-        virtual bool  initProperties();
+        virtual bool initProperties();
         virtual bool updateProperties();
         virtual void ISGetProperties (const char *dev);
-
         virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
         virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
-
-        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) {return false;}
-
-
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual void ISSnoopDevice (XMLEle *root);
+
+     protected:
+        /** \brief Start exposing primary CCD chip
+            \param duration Duration in seconds
+            \return 0 if OK and exposure will take some time to complete, 1 if exposure is short and complete already (e.g. bias), -1 on error.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
         virtual int StartExposure(float duration);
+
+        /** \brief Uploads primary CCD exposed buffer as FITS to the client. Dervied classes should class this function when an exposure is complete.
+             \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
         virtual bool ExposureComplete();
+
+        /** \brief Abort ongoing exposure
+            \return true is abort is successful, false otherwise.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
+        virtual bool AbortExposure();
+
+        /** \brief Start exposing guide CCD chip
+            \param duration Duration in seconds
+            \return 0 if OK and exposure will take some time to complete, 1 if exposure is short and complete already (e.g. bias), -1 on error.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
         virtual int StartGuideExposure(float duration);
+
+        /** \brief Abort ongoing exposure
+            \return true is abort is successful, false otherwise.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
         virtual bool AbortGuideExposure();
+
+        /** \brief Uploads Guide head CCD exposed buffer as FITS to the client. Dervied classes should class this function when an exposure is complete.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
         virtual bool GuideExposureComplete();
-        virtual int uploadfile(void *fitsdata,int total);
-        virtual int sendPreview();
-
-        //  Handy functions for child classes
-        virtual int SetCCDParams(int x,int y,int bpp,float xf,float yf);
-        virtual int SetGuidHeadParams(int x,int y,int bpp,float xf,float yf);
-
-        virtual int GuideNorth(float);
-        virtual int GuideSouth(float);
-        virtual int GuideEast(float);
-        virtual int GuideWest(float);
-
-        virtual int SetFrameType(int);
+
+        /** \brief INDI::CCD calls this function when CCD Frame dimension needs to be updated in the hardware. Derived classes should implement this function
+            \param x Subframe X coordinate in pixels.
+            \param y Subframe Y coordinate in pixels.
+            \param w Subframe width in pixels.
+            \param h Subframe height in pixels.
+            \note (0,0) is defined as most left, top pixel in the subframe.
+            \return true is CCD chip update is successful, false otherwise.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
+        virtual bool updateCCDFrame(int x, int y, int w, int h);
+
+        /** \brief INDI::CCD calls this function when CCD Binning needs to be updated in the hardware. Derived classes should implement this function
+            \param hor Horizontal binning.
+            \param ver Vertical binning.
+            \return true is CCD chip update is successful, false otherwise.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+        */
+        virtual bool updateCCDBin(int hor, int ver);
+
+
+        /** \brief Setup CCD paramters for primary CCD. Child classes call this function to update CCD paramaters
+            \param x Frame X coordinates in pixels.
+            \param y Frame Y coordinates in pixels.
+            \param bpp Bits Per Pixels.
+            \param xf X pixel size in microns.
+            \param yf Y pixel size in microns.
+        */
+        virtual void SetCCDParams(int x,int y,int bpp,float xf,float yf);
+
+        /** \brief Setup CCD paramters for guide head CCD. Child classes call this function to update CCD paramaters
+            \param x Frame X coordinates in pixels.
+            \param y Frame Y coordinates in pixels.
+            \param bpp Bits Per Pixels.
+            \param xf X pixel size in microns.
+            \param yf Y pixel size in microns.
+        */
+        virtual void SetGuidHeadParams(int x,int y,int bpp,float xf,float yf);
+
+
+        /** \brief Guide northward for ms milliseconds
+            \param ms Duration in milliseconds.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+            \return True if successful, false otherwise.
+        */
+        virtual bool GuideNorth(float ms);
+
+        /** \brief Guide southward for ms milliseconds
+            \param ms Duration in milliseconds.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+            \return 0 if successful, -1 otherwise.
+        */
+        virtual bool GuideSouth(float ms);
+
+        /** \brief Guide easward for ms milliseconds
+            \param ms Duration in milliseconds.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+            \return 0 if successful, -1 otherwise.
+        */
+        virtual bool GuideEast(float ms);
+
+        /** \brief Guide westward for ms milliseconds
+            \param ms Duration in milliseconds.
+            \note This function is not implemented in INDI::CCD, it must be implemented in the child class
+            \return 0 if successful, -1 otherwise.
+        */
+        virtual bool GuideWest(float ms);
+
+        float RA;
+        float Dec;
+        bool HasGuideHead;
+        bool HasSt4Port;
+        bool InExposure;
+
+        CCDChip PrimaryCCD;
+        CCDChip GuideCCD;
+
+ private:
+    //  We are going to snoop these from a telescope
+    INumberVectorProperty EqNP;
+    INumber EqN[2];
+
+    ITextVectorProperty *TelescopeTP;
+    IText TelescopeT[1];
+
+    void addFITSKeywords(fitsfile *fptr);
+    int uploadfile(void *fitsdata,int total);
 
 };
Index: /BAORadio/libindi/libindi/libs/indibase/indidevice.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indidevice.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indidevice.cpp	(revision 642)
@@ -299,4 +299,5 @@
     //  We dont actually implement a device here
     //  So we cannot connect to it
+IDLog("IndiDevice Connect, we should never get here\n");
     IDMessage(deviceName(),"IndiDevice:: has no device attached....");
     return false;
Index: /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp	(revision 642)
@@ -1,21 +1,18 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -27,5 +24,5 @@
 {
     //ctor
-    MaxFilter=12;
+    MaxFilter=-1;
 }
 
@@ -35,26 +32,10 @@
 }
 
+
 bool INDI::FilterWheel::initProperties()
 {
-    DefaultDriver::initProperties();   //  let the base class flesh in what it wants
+    DefaultDriver::initProperties();
 
-    IUFillNumber(&FilterSlotN[0],"FILTER_SLOT_VALUE","Filter","%3.0f",1.0,12.0,1.0,1.0);
-    IUFillNumberVector(&FilterSlotNV,FilterSlotN,1,deviceName(),"FILTER_SLOT","Filter","Main Control",IP_RW,60,IPS_IDLE);
-
-    IUFillText(&FilterNameT[0],"FILTER1","1","");
-    IUFillText(&FilterNameT[1],"FILTER2","2","");
-    IUFillText(&FilterNameT[2],"FILTER3","3","");
-    IUFillText(&FilterNameT[3],"FILTER4","4","");
-    IUFillText(&FilterNameT[4],"FILTER5","5","");
-    IUFillText(&FilterNameT[5],"FILTER6","6","");
-    IUFillText(&FilterNameT[6],"FILTER7","7","");
-    IUFillText(&FilterNameT[7],"FILTER8","8","");
-    IUFillText(&FilterNameT[8],"FILTER9","9","");
-    IUFillText(&FilterNameT[9],"FILTER10","10","");
-    IUFillText(&FilterNameT[10],"FILTER11","11","");
-    IUFillText(&FilterNameT[11],"FILTER12","12","");
-    IUFillTextVector(&FilterNameTV,FilterNameT,12,deviceName(),"FILTER_NAME","Filter","Filters",IP_RW,60,IPS_IDLE);
-
-    return 0;
+    initFilterProperties(deviceName(), FILTER_TAB);
 }
 
@@ -66,6 +47,8 @@
     if(isConnected())
     {
-        defineNumber(&FilterSlotNV);
-        defineText(&FilterNameTV);
+        defineNumber(FilterSlotNP);
+
+        if (GetFilterNames(deviceName(), FILTER_TAB))
+            defineText(FilterNameTP);
     }
     return;
@@ -79,16 +62,20 @@
     if(isConnected())
     {
-        IUFillNumber(&FilterSlotN[0],"FILTER_SLOT_VALUE","Filter","%3.0f",MinFilter,MaxFilter,1.0,CurrentFilter);
-        defineNumber(&FilterSlotNV);
-        IUFillTextVector(&FilterNameTV,FilterNameT,MaxFilter,deviceName(),"FILTER_NAME","Filter","Filters",IP_RW,60,IPS_IDLE);
-        defineText(&FilterNameTV);
-        //LoadFilterNames();
+        initFilterProperties(deviceName(), FILTER_TAB);
+        defineNumber(FilterSlotNP);
+        if (GetFilterNames(deviceName(), FILTER_TAB))
+            defineText(FilterNameTP);
     } else
     {
-        deleteProperty(FilterSlotNV.name);
-        deleteProperty(FilterNameTV.name);
+        deleteProperty(FilterSlotNP->name);
+        deleteProperty(FilterNameTP->name);
     }
 
     return true;
+}
+
+bool INDI::FilterWheel::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    return DefaultDriver::ISNewSwitch(dev, name, states, names,n);
 }
 
@@ -97,15 +84,18 @@
     //  first check if it's for our device
     //IDLog("INDI::FilterWheel::ISNewNumber %s\n",name);
-    if(strcmp(dev,deviceName())==0) {
+    if(strcmp(dev,deviceName())==0)
+    {
         //  This is for our device
         //  Now lets see if it's something we process here
 
-        if(strcmp(name,"FILTER_SLOT")==0) {
-
+        if(strcmp(name,"FILTER_SLOT")==0)
+        {
             int f;
 
             f=-1;
-            for(int x=0; x<n; x++) {
-                if(strcmp(names[x],"FILTER_SLOT_VALUE")==0) {
+            for(int x=0; x<n; x++)
+            {
+                if(strcmp(names[x],"FILTER_SLOT_VALUE")==0)
+                {
                     //  This is the new filter number we are being asked
                     //  to set as active
@@ -114,9 +104,10 @@
             }
 
-            if(f != -1) {
+            if(f != -1)
+            {
                 //IDLog("Filter wheel got a filter slot change\n");
                 //  tell the client we are busy changing the filter
-                FilterSlotNV.s=IPS_BUSY;
-                IDSetNumber(&FilterSlotNV,NULL);
+                FilterSlotNP->s=IPS_BUSY;
+                IDSetNumber(FilterSlotNP,NULL);
                 //  Tell the hardware to change
                 SelectFilter(f);
@@ -136,29 +127,22 @@
     //IDLog("INDI::FilterWheel got %d new text items name %s\n",n,name);
     //  first check if it's for our device
-    if(strcmp(dev,deviceName())==0) {
+    if(strcmp(dev,deviceName())==0)
+    {
         //  This is for our device
         //  Now lets see if it's something we process here
-        if(strcmp(name,FilterNameTV.name)==0) {
-            //  This is our port, so, lets process it
-
-            //  Some clients insist on sending a port
-            //  and they may not be configured for the
-            //  correct port
-            //  If we are already connected
-            //  and running, it makes absolutely no sense
-            //  to accept a new port value
-            //  so lets just lie to them and say
-            //  we did this, but, dont actually change anything
-            //if(Connected) return true;
-
+        if(strcmp(name,FilterNameTP->name)==0)
+        {
             int rc;
             //IDLog("calling update text\n");
-            FilterNameTV.s=IPS_OK;
-            rc=IUUpdateText(&FilterNameTV,texts,names,n);
-            //IDLog("update text returns %d\n",rc);
-            //  Update client display
-            IDSetText(&FilterNameTV,NULL);
-            //SaveConfig();
+            FilterNameTP->s=IPS_OK;
+            rc=IUUpdateText(FilterNameTP,texts,names,n);
 
+            if (SetFilterNames() == true)
+                IDSetText(FilterNameTP,NULL);
+            else
+            {
+                FilterNameTP->s = IPS_ALERT;
+                IDSetText(FilterNameTP, "Error updating names of filters.");
+            }
             //  We processed this one, so, tell the world we did it
             return true;
@@ -170,21 +154,4 @@
 }
 
-int INDI::FilterWheel::SelectFilterDone(int f)
-{
-    //  The hardware has finished changing
-    //  filters
-    FilterSlotN[0].value=f;
-    FilterSlotNV.s=IPS_OK;
-    // Tell the clients we are done, and
-    //  filter is now useable
-    IDSetNumber(&FilterSlotNV,NULL);
-    return 0;
-}
-
-int INDI::FilterWheel::SelectFilter(int)
-{
-    return -1;
-}
-
 int INDI::FilterWheel::QueryFilter()
 {
@@ -193,2 +160,26 @@
 
 
+bool INDI::FilterWheel::SelectFilter(int)
+{
+    return false;
+}
+
+bool INDI::FilterWheel::SetFilterNames()
+{
+    return true;
+}
+
+void INDI::FilterWheel::ISSnoopDevice (XMLEle *root)
+{
+ return;
+}
+
+
+bool INDI::FilterWheel::GetFilterNames(const char *deviceName, const char* groupName)
+{
+    INDI_UNUSED(deviceName);
+    INDI_UNUSED(groupName);
+    return false;
+}
+
+
Index: /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h	(revision 642)
@@ -1,64 +1,58 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
 
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-*******************************************************************************/
 #ifndef INDI_FILTERWHEEL_H
 #define INDI_FILTERWHEEL_H
 
 #include "defaultdriver.h"
+#include "indifilterinterface.h"
 
-class INDI::FilterWheel: public INDI::DefaultDriver
+/**
+ * \class INDI::FilterWheel
+   \brief Class to provide general functionality of a filter wheel device.
+
+   Developers need to subclass INDI::FilterWheel to implement any driver for filter wheels within INDI.
+
+\author Gerry Rozema, Jasem Mutlaq
+\see INDI::FilterInterface
+*/
+class INDI::FilterWheel: public INDI::DefaultDriver, public INDI::FilterInterface
 {
-    protected:
-    private:
+protected:
 
-    public:
-        FilterWheel();
-        virtual ~FilterWheel();
+    FilterWheel();
+    virtual ~FilterWheel();
 
-        INumberVectorProperty FilterSlotNV;   //  A number vector for filter slot
-        INumber FilterSlotN[1];
-
-        ITextVectorProperty FilterNameTV; //  A text vector that stores out physical port name
-        IText FilterNameT[12];
-
-        int MinFilter;
-        int MaxFilter;
-        int CurrentFilter;
-        int TargetFilter;
-
+public:
 
         virtual bool initProperties();
         virtual bool updateProperties();
         virtual void ISGetProperties (const char *dev);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);      
+        virtual void ISSnoopDevice (XMLEle *root);
 
-        //  Ok, we do need our virtual functions from the base class for processing
-        //  client requests
-        //  We process Numbers and text in a filter wheel
-        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
-        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
-        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { return false; }
+   protected:
 
-        virtual int SelectFilter(int);
-        virtual int SelectFilterDone(int);
-        virtual int QueryFilter();
-        //int SaveFilterNames();
-        //int LoadFilterNames();
+    virtual int QueryFilter();
+    virtual bool SelectFilter(int);
+    virtual bool SetFilterNames();
+    virtual bool GetFilterNames(const char *deviceName, const char* groupName);
 
 };
Index: /BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp	(revision 642)
@@ -1,22 +1,20 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2011 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*******************************************************************************/
 
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-*******************************************************************************/
 #include "indifocuser.h"
 
@@ -25,10 +23,15 @@
 INDI::Focuser::Focuser()
 {
-    //ctor
+    FocusSpeedNP  = new INumberVectorProperty;
+    FocusTimerNP  = new INumberVectorProperty;
+    FocusMotionSP = new ISwitchVectorProperty;
 }
 
 INDI::Focuser::~Focuser()
 {
-    //dtor
+    delete FocusSpeedNP;
+    delete FocusTimerNP;
+    delete FocusMotionSP;
+
 }
 
@@ -37,14 +40,13 @@
     DefaultDriver::initProperties();   //  let the base class flesh in what it wants
 
-    IUFillNumber(&FocusspeedN[0],"FOCUS_SPEED_VALUE","Focus Speed","%3.0f",0.0,255.0,1.0,255.0);
-    IUFillNumberVector(&FocusspeedNV,FocusspeedN,1,deviceName(),"FOCUS_SPEED","Speed","Main Control",IP_RW,60,IPS_OK);
+    IUFillNumber(&FocusSpeedN[0],"FOCUS_SPEED_VALUE","Focus Speed","%3.0f",0.0,255.0,1.0,255.0);
+    IUFillNumberVector(FocusSpeedNP,FocusSpeedN,1,deviceName(),"FOCUS_SPEED","Speed",MAIN_CONTROL_TAB,IP_RW,60,IPS_OK);
 
-    IUFillNumber(&FocustimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%4.0f",0.0,1000.0,10.0,1000.0);
-    IUFillNumberVector(&FocustimerNV,FocustimerN,1,deviceName(),"FOCUS_TIMER","Timer","Main Control",IP_RW,60,IPS_OK);
+    IUFillNumber(&FocusTimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%4.0f",0.0,1000.0,10.0,1000.0);
+    IUFillNumberVector(FocusTimerNP,FocusTimerN,1,deviceName(),"FOCUS_TIMER","Timer",MAIN_CONTROL_TAB,IP_RW,60,IPS_OK);
 
-    IUFillSwitch(&FocusmotionS[0],"FOCUS_INWARD","Focus In",ISS_ON);
-    IUFillSwitch(&FocusmotionS[1],"FOCUS_OUTWARD","Focus Out",ISS_OFF);
-    IUFillSwitchVector(&FocusmotionSV,FocusmotionS,2,deviceName(),"FOCUS_MOTION","Focus Direction","Main Control",IP_RW,ISR_1OFMANY,60,IPS_OK);
-
+    IUFillSwitch(&FocusMotionS[0],"FOCUS_INWARD","Focus In",ISS_ON);
+    IUFillSwitch(&FocusMotionS[1],"FOCUS_OUTWARD","Focus Out",ISS_OFF);
+    IUFillSwitchVector(FocusMotionSP,FocusMotionS,2,deviceName(),"FOCUS_MOTION","Direction",MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_OK);
 
     return 0;
@@ -54,5 +56,4 @@
 {
     //  First we let our parent populate
-    IDLog("INDI::Focuser::ISGetProperties %s\n",dev);
     DefaultDriver::ISGetProperties(dev);
 
@@ -65,12 +66,12 @@
     {
         //  Now we add our focusser specific stuff
-        IDDefSwitch(&FocusmotionSV, NULL);
-        IDDefNumber(&FocusspeedNV, NULL);
-        IDDefNumber(&FocustimerNV, NULL);
+        defineSwitch(FocusMotionSP);
+        defineNumber(FocusSpeedNP);
+        defineNumber(FocusTimerNP);
     } else
     {
-        deleteProperty(FocusmotionSV.name);
-        deleteProperty(FocusspeedNV.name);
-        deleteProperty(FocustimerNV.name);
+        deleteProperty(FocusMotionSP->name);
+        deleteProperty(FocusSpeedNP->name);
+        deleteProperty(FocusTimerNP->name);
     }
     return true;
@@ -81,11 +82,12 @@
 {
     //  first check if it's for our device
-    IDLog("INDI::Focuser::ISNewNumber %s\n",name);
-    if(strcmp(dev,deviceName())==0) {
+    if(strcmp(dev,deviceName())==0)
+    {
         //  This is for our device
         //  Now lets see if it's something we process here
-        if(strcmp(name,"FOCUS_TIMER")==0) {
+        if(strcmp(name,"FOCUS_TIMER")==0)
+        {
             //  Ok, gotta move the focusser now
-            int dir;
+            FocusDirection dir;
             int speed;
             int t;
@@ -93,32 +95,30 @@
             //IDLog(")
             //  first we get all the numbers just sent to us
-            FocustimerNV.s=IPS_OK;
-            IUUpdateNumber(&FocustimerNV,values,names,n);
+            FocusTimerNP->s=IPS_OK;
+            IUUpdateNumber(FocusTimerNP,values,names,n);
 
             //  Now lets find what we need for this move
-            speed=FocusspeedN[0].value;
-            if(FocusmotionS[0].s==ISS_ON) dir=1;
-            else dir=0;
-            t=FocustimerN[0].value;
+            speed=FocusSpeedN[0].value;
+            if(FocusMotionS[0].s==ISS_ON) dir=FOCUS_INWARD;
+            else dir=FOCUS_OUTWARD;
+            t=FocusTimerN[0].value;
 
-            Move(dir,speed,t);
+            if (Move(dir,speed,t) == false)
+                FocusTimerNP->s = IPS_ALERT;
 
-
-            //  Update client display
-            IDSetNumber(&FocustimerNV,NULL);
+            IDSetNumber(FocusTimerNP,NULL);
             return true;
         }
 
 
-        if(strcmp(name,"FOCUS_SPEED")==0) {
-
-
-            FocusspeedNV.s=IPS_OK;
-            IUUpdateNumber(&FocusspeedNV,values,names,n);
+        if(strcmp(name,"FOCUS_SPEED")==0)
+        {
+            FocusSpeedNP->s=IPS_OK;
+            IUUpdateNumber(FocusSpeedNP,values,names,n);
 
 
 
             //  Update client display
-            IDSetNumber(&FocusspeedNV,NULL);
+            IDSetNumber(FocusSpeedNP,NULL);
             return true;
         }
@@ -132,17 +132,15 @@
 bool INDI::Focuser::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
 {
-    IDLog("Enter IsNewSwitch for %s\n",name);
-    //for(int x=0; x<n; x++) {
-    //    IDLog("Switch %s %d\n",names[x],states[x]);
-    //}
 
-    if(strcmp(dev,deviceName())==0) {
+    if(strcmp(dev,deviceName())==0)
+    {
         //  This one is for us
-        if(strcmp(name,"FOCUS_MOTION")==0) {
+        if(strcmp(name,"FOCUS_MOTION")==0)
+        {
             //  client is telling us what to do with focus direction
-            FocusmotionSV.s=IPS_OK;
-            IUUpdateSwitch(&FocusmotionSV,states,names,n);
+            FocusMotionSP->s=IPS_OK;
+            IUUpdateSwitch(FocusMotionSP,states,names,n);
             //  Update client display
-            IDSetSwitch(&FocusmotionSV,NULL);
+            IDSetSwitch(FocusMotionSP,NULL);
 
             return true;
@@ -155,5 +153,15 @@
 }
 
-int INDI::Focuser::Move(int,int,int)
+bool INDI::Focuser::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    return DefaultDriver::ISNewText(dev, name, texts, names, n);
+}
+
+void INDI::Focuser::ISSnoopDevice (XMLEle *root)
+{
+ return;
+}
+
+bool INDI::Focuser::Move(FocusDirection dir, int speed, int duration)
 {
     //  This should be a virtual function, because the low level hardware class
@@ -161,5 +169,5 @@
     //  but it's much easier early development if the method actually
     //  exists for now
-    return -1;
+    return false;
 }
 
Index: /BAORadio/libindi/libindi/libs/indibase/indifocuser.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifocuser.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indifocuser.h	(revision 642)
@@ -1,21 +1,18 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2011 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -25,35 +22,44 @@
 #include "defaultdriver.h"
 
+/**
+ * \class INDI::Focuser
+   \brief Class to provide general functionality of a focuser device.
+
+   Developers need to subclass INDI::Focuser to implement any driver for focusers within INDI.
+
+\author Gerry Rozema
+*/
 class INDI::Focuser : public INDI::DefaultDriver
 {
-
-    protected:
-    private:
-
     public:
         Focuser();
         virtual ~Focuser();
 
-        INumberVectorProperty FocusspeedNV;
-        INumber FocusspeedN[1];
-        ISwitchVectorProperty FocusmotionSV; //  A Switch in the client interface to park the scope
-        ISwitch FocusmotionS[2];
-        INumberVectorProperty FocustimerNV;
-        INumber FocustimerN[1];
-
+        enum FocusDirection { FOCUS_INWARD, FOCUS_OUTWARD };
 
         virtual bool initProperties();
         virtual void ISGetProperties (const char *dev);
-        bool updateProperties();
-
-
-        //  Ok, we do need our virtual functions from the base class for processing
-        //  client requests
-        //  We process Numbers in a focusser
+        virtual bool updateProperties();
         virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
         virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual void ISSnoopDevice (XMLEle *root);
 
-        //  And here are the virtual functions we will have for easy overrides
-        virtual int Move(int, int, int);
+    protected:
+
+        /** \brief Move the focuser in a particular direction with a specific speed for a finite duration.
+            \param dir Direction of focuser, either FOCUS_INWARD or FOCUS_OUTWARD.
+            \param speed Speed of focuser if supported by the focuser.
+            \param duration The timeout in milliseconds before the focus motion halts.
+            \return True if succssfull, false otherwise.
+        */
+        virtual bool Move(FocusDirection dir, int speed, int duration);
+
+        INumberVectorProperty *FocusSpeedNP;
+        INumber FocusSpeedN[1];
+        ISwitchVectorProperty *FocusMotionSP; //  A Switch in the client interface to park the scope
+        ISwitch FocusMotionS[2];
+        INumberVectorProperty *FocusTimerNP;
+        INumber FocusTimerN[1];
 
 };
Index: /BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp	(revision 642)
@@ -1,22 +1,20 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+  Copyright(c) 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
+
 
 #include "inditelescope.h"
@@ -39,9 +37,27 @@
 {
     //ctor
+    EqNV = new INumberVectorProperty;
+    EqReqNV = new INumberVectorProperty;
+    LocationNV = new INumberVectorProperty;
+    CoordSV = new ISwitchVectorProperty;
+    ParkSV = new ISwitchVectorProperty;
+    PortTV = new ITextVectorProperty;
+    MovementNSSP = new ISwitchVectorProperty;
+    MovementWESP = new ISwitchVectorProperty;
+    ConfigSV = new ISwitchVectorProperty;
+
 }
 
 INDI::Telescope::~Telescope()
 {
-    //dtor
+    delete EqNV;
+    delete EqReqNV;
+    delete LocationNV;
+    delete CoordSV;
+    delete ParkSV;
+    delete PortTV;
+    delete MovementNSSP;
+    delete MovementWESP;
+    delete ConfigSV;
 }
 
@@ -49,39 +65,41 @@
 {
     DefaultDriver::initProperties();
-
-    EqNV = new INumberVectorProperty;
 
     IUFillNumber(&EqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
     IUFillNumber(&EqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
-    IUFillNumberVector(EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RO,60,IPS_IDLE);
-
-    EqReqNV = new INumberVectorProperty;
+    IUFillNumberVector(EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates",MAIN_CONTROL_TAB,IP_RO,60,IPS_IDLE);
 
     IUFillNumber(&EqReqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
     IUFillNumber(&EqReqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
-    IUFillNumberVector(EqReqNV,EqReqN,2,deviceName(),"EQUATORIAL_EOD_COORD_REQUEST","GOTO","Controls",IP_WO,60,IPS_IDLE);
-
-    LocationNV = new INumberVectorProperty;
+    IUFillNumberVector(EqReqNV,EqReqN,2,deviceName(),"EQUATORIAL_EOD_COORD_REQUEST","GOTO",MAIN_CONTROL_TAB,IP_WO,60,IPS_IDLE);
 
     IUFillNumber(&LocationN[0],"LAT","Lat (dd:mm:ss)","%010.6m",-90,90,0,0.0);
-    IUFillNumber(&LocationN[1],"LONG","Lon (dd:mm:ss)","%010.6m",0,360,0,0.0 );
-    IUFillNumberVector(LocationNV,LocationN,2,deviceName(),"GEOGRAPHIC_COORD","Scope Location","Location",IP_RW,60,IPS_OK);
-
-    CoordSV = new ISwitchVectorProperty;
+    IUFillNumber(&LocationN[1],"LONG","Lon (dd:mm:ss)","%010.6m",-180,180,0,0.0 );
+    IUFillNumberVector(LocationNV,LocationN,2,deviceName(),"GEOGRAPHIC_COORD","Scope Location",SITE_TAB,IP_RW,60,IPS_OK);
 
     IUFillSwitch(&CoordS[0],"TRACK","Track",ISS_OFF);
     IUFillSwitch(&CoordS[1],"SLEW","Slew",ISS_OFF);
     IUFillSwitch(&CoordS[2],"SYNC","Sync",ISS_OFF);
-    IUFillSwitchVector(CoordSV,CoordS,3,deviceName(),"ON_COORD_SET","On Set","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
-
-    ParkSV = new ISwitchVectorProperty;
+    IUFillSwitchVector(CoordSV,CoordS,3,deviceName(),"ON_COORD_SET","On Set",MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillSwitch(&ConfigS[0], "CONFIG_LOAD", "Load", ISS_OFF);
+    IUFillSwitch(&ConfigS[1], "CONFIG_SAVE", "Save", ISS_OFF);
+    IUFillSwitch(&ConfigS[2], "CONFIG_DEFAULT", "Default", ISS_OFF);
+    IUFillSwitchVector(ConfigSV, ConfigS, 3, deviceName(), "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
+
 
     IUFillSwitch(&ParkS[0],"PARK","Park",ISS_OFF);
-    IUFillSwitchVector(ParkSV,ParkS,1,deviceName(),"TELESCOPE_PARK","Park","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
-
-    PortTV = new ITextVectorProperty;
+    IUFillSwitchVector(ParkSV,ParkS,1,deviceName(),"TELESCOPE_PARK","Park",MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_IDLE);
 
     IUFillText(&PortT[0],"PORT","Port","/dev/ttyUSB0");
-    IUFillTextVector(PortTV,PortT,1,deviceName(),"DEVICE_PORT","Ports","Options",IP_RW,60,IPS_IDLE);
+    IUFillTextVector(PortTV,PortT,1,deviceName(),"DEVICE_PORT","Ports",OPTIONS_TAB,IP_RW,60,IPS_IDLE);
+
+    IUFillSwitch(&MovementNSS[MOTION_NORTH], "MOTION_NORTH", "North", ISS_OFF);
+    IUFillSwitch(&MovementNSS[MOTION_SOUTH], "MOTION_SOUTH", "South", ISS_OFF);
+    IUFillSwitchVector(MovementNSSP, MovementNSS, 2, deviceName(),"TELESCOPE_MOTION_NS", "North/South", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
+
+    IUFillSwitch(&MovementWES[MOTION_WEST], "MOTION_WEST", "West", ISS_OFF);
+    IUFillSwitch(&MovementWES[MOTION_EAST], "MOTION_EAST", "East", ISS_OFF);
+    IUFillSwitchVector(MovementWESP, MovementWES, 2, deviceName(),"TELESCOPE_MOTION_WE", "West/East", MOTION_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
 
     TrackState=SCOPE_PARKED;
@@ -96,5 +114,5 @@
 
     //  We may need the port set before we can connect
-    //IDDefText(&PortTV,NULL);
+    IDDefText(PortTV,NULL);
     //LoadConfig();
 
@@ -107,4 +125,8 @@
         defineNumber(LocationNV);
         defineSwitch(ParkSV);
+        defineSwitch(MovementNSSP);
+        defineSwitch(MovementWESP);
+		defineSwitch(ConfigSV);
+
     }
     return;
@@ -113,14 +135,16 @@
 bool INDI::Telescope::updateProperties()
 {
+    defineText(PortTV);
     if(isConnected())
     {
         //  Now we add our telescope specific stuff
-        //IDLog("INDI::Telescope adding properties\n");
         defineSwitch(CoordSV);
         defineNumber(EqNV);
         defineNumber(EqReqNV);
-        //IDDefText(&PortTV,NULL);
+        defineSwitch(MovementNSSP);
+        defineSwitch(MovementWESP);
         defineNumber(LocationNV);
         defineSwitch(ParkSV);
+
     } else
     {
@@ -129,19 +153,28 @@
         deleteProperty(EqNV->name);
         deleteProperty(EqReqNV->name);
-        //DeleteProperty(PortTV.name);
+        deleteProperty(MovementNSSP->name);
+        deleteProperty(MovementWESP->name);
         deleteProperty(LocationNV->name);
         deleteProperty(ParkSV->name);
 
-        initProperties();
-    }
+        //initProperties();
+    }
+	defineSwitch(ConfigSV);
+
     return true;
 }
 
-int INDI::Telescope::NewRaDec(double ra,double dec)
+bool INDI::Telescope::saveConfigItems(FILE *fp)
+{
+
+	IUSaveConfigNumber(fp,LocationNV);
+    return true;
+}
+
+void INDI::Telescope::NewRaDec(double ra,double dec)
 {
     //  Lets set our eq values to these numbers
     //  which came from the hardware
-    EqN[0].value=ra;
-    EqN[1].value=dec;
+    static int last_state=-1;
 
     if (TrackState == SCOPE_TRACKING && EqReqNV->s != IPS_OK)
@@ -150,5 +183,5 @@
         IDSetNumber(EqReqNV, NULL);
     }
-    if ( (TrackState == SCOPE_PARKED || TrackState == SCOPE_IDLE) && EqReqNV->s != IPS_IDLE)
+    else if ( (TrackState == SCOPE_PARKED || TrackState == SCOPE_IDLE) && EqReqNV->s != IPS_IDLE)
     {
         EqReqNV->s = IPS_IDLE;
@@ -156,5 +189,14 @@
     }
 
-    return 0;
+    //IDLog("newRA DEC RA %g - DEC %g --- EqN[0] %g --- EqN[1] %g --- EqN.state %d\n", ra, dec, EqN[0].value, EqN[1].value, EqNV->s);
+    if (EqN[0].value != ra || EqN[1].value != dec || EqNV->s != last_state)
+    {
+      //  IDLog("Not equal , send update to client...\n");
+        EqN[0].value=ra;
+        EqN[1].value=dec;
+        last_state = EqNV->s;
+        IDSetNumber(EqNV, NULL);
+    }
+
 }
 
@@ -176,4 +218,22 @@
     //  if we get here, our mount doesn't support sync
     IDMessage(deviceName(),"Mount does not support Sync");
+    return false;
+}
+
+bool INDI::Telescope::MoveNS(TelescopeMotionNS dir)
+{
+    IDMessage(deviceName(),"Mount does not support North/South motion");
+    IUResetSwitch(MovementNSSP);
+    MovementNSSP->s = IPS_IDLE;
+    IDSetSwitch(MovementNSSP, NULL);
+    return false;
+}
+
+bool INDI::Telescope::MoveWE(TelescopeMotionWE dir)
+{
+    IDMessage(deviceName(),"Mount does not support West/East motion");
+    IUResetSwitch(MovementWESP);
+    MovementWESP->s = IPS_IDLE;
+    IDSetSwitch(MovementWESP, NULL);
     return false;
 }
@@ -328,4 +388,33 @@
             Park();
         }
+
+        if(strcmp(name,"TELESCOPE_MOTION_NS")==0)
+        {
+            IUUpdateSwitch(MovementNSSP,states,names,n);
+
+            MovementNSSP->s = IPS_BUSY;
+
+            if (MovementNSS[MOTION_NORTH].s == ISS_ON)
+                MoveNS(MOTION_NORTH);
+            else
+                MoveNS(MOTION_SOUTH);
+
+            return true;
+        }
+
+        if(strcmp(name,"TELESCOPE_MOTION_WE")==0)
+        {
+            IUUpdateSwitch(MovementWESP,states,names,n);
+
+            MovementWESP->s = IPS_BUSY;
+
+            if (MovementWES[MOTION_WEST].s == ISS_ON)
+                MoveWE(MOTION_WEST);
+            else
+                MoveWE(MOTION_EAST);
+
+            return true;
+        }
+
     }
 
@@ -334,15 +423,22 @@
 }
 
+
 bool INDI::Telescope::Connect()
 {
     //  Parent class is wanting a connection
-    //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
+    if (isDebug())
+        IDLog("INDI::Telescope arrived in connect with %s\n",PortT[0].text);
     bool rc=false;
 
     if(isConnected()) return true;
 
-    //IDLog("Calling Connect\n");
+
+    if (isDebug())
+        IDLog("Telescope Calling Connect\n");
 
     rc=Connect(PortT[0].text);
+
+    if (isDebug())
+        IDLog("Telescope Connect returns %d\n",rc);
 
     if(rc)
@@ -351,4 +447,5 @@
 }
 
+
 bool INDI::Telescope::Connect(const char *port)
 {
@@ -361,10 +458,11 @@
     bool rc;
 
-
-    if ( (connectrc = tty_connect(port, B9600, 8, 0, 1, &PortFD)) != TTY_OK)
+	IDLog("Indi Telescope connecting to %s\n",port);
+
+    if ( (connectrc = tty_connect(port, 9600, 8, 0, 1, &PortFD)) != TTY_OK)
     {
         tty_error_msg(connectrc, errorMsg, MAXRBUF);
 
-        if (isDebug())
+        //if (isDebug())
             IDLog("Failed to connect o port %s. Error: %s", port, errorMsg);
         IDMessage(deviceName(), "Failed to connect to port %s. Error: %s", port, errorMsg);
@@ -373,8 +471,8 @@
 
     }
-
+	IDLog("Port Fd %d\n",PortFD);
     /* Flush the input (read) buffer */
 
-    tcflush(PortFD,TCIOFLUSH);
+    //tcflush(PortFD,TCIOFLUSH);
 
     /* Test connection */
@@ -401,4 +499,6 @@
     //Connected=false;
 
+	IDLog("IndiTelescope Disconnect\n");
+
     close(PortFD);
     IDMessage(deviceName(),"Telescope is offline.");
@@ -410,5 +510,5 @@
 void INDI::Telescope::TimerHit()
 {
-    //IDLog("Timer Hit\n");
+    //IDLog("Telescope Timer Hit\n");
     if(isConnected())
     {
@@ -417,31 +517,11 @@
         rc=ReadScopeStatus();
         //IDLog("TrackState after read is %d\n",TrackState);
-        if(rc)
-        {
-            //  read was good
-            switch(TrackState)
-            {
-              case SCOPE_IDLE:
-              case SCOPE_PARKED:
-                EqNV->s=IPS_IDLE;
-                break;
-
-             case SCOPE_SLEWING:
-             case SCOPE_PARKING:
-                EqNV->s=IPS_BUSY;
-                break;
-
-            case SCOPE_TRACKING:
-                EqNV->s=IPS_OK;
-                break;
-            }
-        } else
+        if(rc == false)
         {
             //  read was not good
             EqNV->s=IPS_ALERT;
-        }
-        //IDLog("IsConnected, re-arm timer\n");
-        //  Now update the Client data
-        IDSetNumber(EqNV,NULL);
+            IDSetNumber(EqNV, NULL);
+        }      
+
         SetTimer(POLLMS);
     }
Index: /BAORadio/libindi/libindi/libs/indibase/inditelescope.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/inditelescope.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/inditelescope.h	(revision 642)
@@ -1,21 +1,18 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2011 Gerry Rozema, Jasem Mutlaq. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -25,9 +22,26 @@
 #include "defaultdriver.h"
 
+/**
+ * \class INDI::Telescope
+   \brief Class to provide general functionality of a telescope device.
+
+   Developers need to subclass INDI::Telescope to implement any driver for telescopes within INDI.
+
+   Implementing a basic telescope driver involves the child class performing the following steps:
+   <ul>
+   <li>If the telescope has additional properties, the child class should override initProperties and initilize the respective additional properties.</li>
+   <li>Once the parent class calls Connect(), the child class attempts to connect to the telescope and return either success of failure</li>
+   <li>INDI::Telescope calls updateProperties() to enable the child class to define which properties to send to the client upon connection</li>
+   <li>INDI::Telescope calls ReadScopeStatus() to check the link to the telescope and update its state and position. The child class should call newRaDec() whenever
+   a new value is read from the telescope.</li>
+   <li>The child class should implmenet Goto() and Sync(), and Park() if applicable.</li>
+   <li>INDI::Telescope calls disconnect() when the client request a disconnection. The child class should remove any additional properties it defined in updateProperties() if applicable</li>
+   </ul>
+
+\author Gerry Rozema, Jasem Mutlaq
+\see TelescopeSimulator and SynScan drivers for examples of implementations of INDI::Telescope.
+*/
 class INDI::Telescope : public INDI::DefaultDriver
 {
-    protected:
-        //bool Connected;
-
     private:
 
@@ -37,4 +51,96 @@
 
         enum TelescopeStatus { SCOPE_IDLE, SCOPE_SLEWING, SCOPE_TRACKING, SCOPE_PARKING, SCOPE_PARKED };
+        enum TelescopeMotionNS { MOTION_NORTH, MOTION_SOUTH };
+        enum TelescopeMotionWE { MOTION_WEST, MOTION_EAST };
+
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+        virtual void ISGetProperties (const char *dev);
+
+        /** \brief Called to initialize basic properties required all the time */
+        virtual bool initProperties();
+        /** \brief Called when connected state changes, to add/remove properties */
+        virtual bool updateProperties();
+
+        /** \brief Called when setTimer() time is up */
+        virtual void TimerHit();
+
+        /** \brief Connect to the telescope.
+          \return True if connection is successful, false otherwise
+        */
+        virtual bool Connect();
+
+        /** \brief Disconnect from telescope
+            \return True if successful, false otherwise */
+        virtual bool Disconnect();
+
+        /** \brief INDI::Telescope implementation of Connect() assumes 9600 baud, 8 bit word, even parity, and no stop bit. Override function if communication paramaters
+          are different
+          \param port Port to connect to
+          \return True if connection is successful, false otherwise
+          \warning Do not call this function directly, it is called by INDI::Telescope Connect() function.
+        */
+        virtual bool Connect(const char *port);
+
+        protected:
+
+        virtual bool saveConfigItems(FILE *fp);
+
+        /** \brief The child class calls this function when it has updates */
+        void NewRaDec(double ra,double dec);
+
+        /** \brief Read telescope status.
+         This function checks the following:
+         <ol>
+           <li>Check if the link to the telescope is alive.</li>
+           <li>Update telescope status: Idle, Slewing, Parking..etc.</li>
+           <li>Read coordinates</li>
+         </ol>
+          \return True if reading scope status is OK, false if an error is encounterd.
+          \note This function is not implemented in INDI::Telescope, it must be implemented in the child class */
+        virtual bool ReadScopeStatus();
+
+        /** \brief Move the scope to the supplied RA and DEC coordinates
+            \return True if successful, false otherewise
+            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
+        */
+        virtual bool Goto(double ra,double dec);
+
+        /** \brief Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates
+            \return True if successful, false otherewise
+            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
+        */
+        virtual bool Sync(double ra,double dec);
+
+        /** \brief Move the telescope in the direction dir.
+            \return True if successful, false otherewise
+            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
+        */
+        virtual bool MoveNS(TelescopeMotionNS dir);
+
+        /** \brief Move the telescope in the direction dir.
+            \return True if successful, false otherewise
+            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
+        */
+        virtual bool MoveWE(TelescopeMotionWE dir);
+
+        /** \brief Part the telescope to its home position.
+            \return True if successful, false otherewise
+            \note This function is not implemented in INDI::Telescope, it must be implemented in the child class
+        */
+        virtual bool Park();
+
+
+        //  Since every mount I know of actually uses a serial port for control
+        //  We put the serial helper into the base telescope class
+        //  One less piece to worry about in the hardware specific
+        //  low level stuff
+        int PortFD;
+
+        //  This is a variable filled in by the ReadStatus telescope
+        //  low level code, used to report current state
+        //  are we slewing, tracking, or parked.
+        TelescopeStatus TrackState;
 
         //  All telescopes should produce equatorial co-ordinates
@@ -49,4 +155,7 @@
         ISwitch CoordS[3];              //  On a coord_set message, sync, or slew
 
+        ISwitchVectorProperty *ConfigSV; //  A switch vector that stores how we should readct
+        ISwitch ConfigS[3];              //  On a coord_set message, sync, or slew
+
         INumberVectorProperty *LocationNV;   //  A number vector that stores lattitude and longitude
         INumber LocationN[2];
@@ -55,69 +164,13 @@
         ISwitch ParkS[1];
 
-        //  I dont know of any telescopes that dont
-        //  need a port for connection
-        //  So lets put all the port connect framework
-        //  into our generic telescope super class
         ITextVectorProperty *PortTV; //  A text vector that stores out physical port name
         IText PortT[1];
 
+        ISwitch MovementNSS[2];     // A switch for North/South motion
+        ISwitchVectorProperty *MovementNSSP;
 
-        //  Ok, we do need our virtual functions from the base class for processing
-        //  client requests
-        //  We process numbers,switches and text in the telescope
-        //  These are the base IndiDevice overrides we process
-        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
-        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
-        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
-        virtual void ISGetProperties (const char *dev);
+        ISwitch MovementWES[2];     // A switch for West/East motion
+        ISwitchVectorProperty *MovementWESP;
 
-        //  overrides of base class virtual functions
-        //  that are specific to our way of implementing Indi
-        virtual bool initProperties();      //  Called to initialize basic properties required all the time
-        virtual bool updateProperties();    //  Called when connected state changes, to add/remove properties
-
-        virtual void TimerHit();
-        virtual bool Connect();
-        virtual bool Disconnect();
-
-        virtual bool Connect(const char *);
-
-
-        //  Since every mount I know of actually uses a serial port for control
-        //  We put the serial helper into the base telescope class
-        //  One less piece to worry about in the hardware specific
-        //  low level stuff
-        int PortFD;
-
-
-        //  This is a variable filled in by the ReadStatus telescope
-        //  low level code, used to report current state
-        //  are we slewing, tracking, or parked.
-        int TrackState;
-
-
-        //  These functions are telescope specific
-        //  and meant to make life really easy for deriving
-        //  hardware specific telescope classes
-        int NewRaDec(double,double);    //  The child class will call this when it has updates
-
-
-        //  And these are the hardware specific functions our children need to override
-        //  They are not pure virtual, because, not all functions are relavent for all types
-        //  of mount, ie, a Goto is not relavent for a Push-to mount
-
-        /** \brief Read telescope status.
-         This function checks the following:
-         <ol>
-           <li>Check if the link to the telescope is alive.</li>
-           <li>Update telescope status: Idle, Slewing, Parking..etc.</li>
-           <li>Read coordinates</li>
-         </ol>
-          \return True if reading scope status is OK, false if an error is encounterd. */
-        virtual bool ReadScopeStatus();
-
-        virtual bool Goto(double ra,double dec);
-        virtual bool Sync(double ra,double dec);
-        virtual bool Park();
 
 };
Index: /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp	(revision 642)
@@ -1,21 +1,18 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2011 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 #include "indiusbdevice.h"
@@ -149,15 +146,15 @@
 }
 
-int INDI::USBDevice::ReadBulk(char *buf,int c,int timeout)
+int INDI::USBDevice::ReadBulk(char *buf,int nbytes,int timeout)
 {
 	int rc;
 
 	//rc=usb_interrupt_read(usb_handle,InputEndpoint,buf,c,timeout);
-	rc=usb_bulk_read(usb_handle,InputEndpoint,buf,c,timeout);
+        rc=usb_bulk_read(usb_handle,InputEndpoint,buf,nbytes,timeout);
 	return rc;
 
 }
 
-int INDI::USBDevice::WriteBulk(char *buf,int c,int timeout)
+int INDI::USBDevice::WriteBulk(char *buf,int nbytes,int timeout)
 {
 	int rc;
@@ -165,5 +162,5 @@
 	//printf("Writing %02x to endpoint %d\n",buf[0],OutputEndpoint);
 	//rc=usb_interrupt_write(usb_handle,OutputEndpoint,buf,c,timeout);
-	rc=usb_bulk_write(usb_handle,OutputEndpoint,buf,c,timeout);
+        rc=usb_bulk_write(usb_handle,OutputEndpoint,buf,nbytes,timeout);
 	return rc;
 
Index: /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h	(revision 642)
@@ -1,21 +1,18 @@
 /*******************************************************************************
-  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+  Copyright(c) 2011 Gerry Rozema. All rights reserved.
 
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
 
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
 
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
 *******************************************************************************/
 
@@ -34,4 +31,13 @@
 #include "indibase.h"
 
+/**
+ * \class INDI::USBDevice
+   \brief Class to provide general functionality of a generic USB device.
+
+   Developers need to subclass INDI::USBDevice to implement any driver within INDI that requires direct read/write/control over USB.
+
+\author Gerry Rozema
+\see Starlight Xpress INDI CCD driver for an example implementation of INDI::USBDevice
+*/
 class INDI::USBDevice
 {
@@ -56,6 +62,6 @@
 	int ControlMessage();
 
-	int WriteBulk(char *,int,int);
-	int ReadBulk(char *,int,int);
+        int WriteBulk(char *buf,int nbytes,int timeout);
+        int ReadBulk(char *buf,int nbytes,int timeout);
 	int FindEndpoints();
 	int Open();
Index: /BAORadio/libindi/libindi/libs/indicom.c
===================================================================
--- /BAORadio/libindi/libindi/libs/indicom.c	(revision 641)
+++ /BAORadio/libindi/libindi/libs/indicom.c	(revision 642)
@@ -147,5 +147,5 @@
 	default:
 	    printf ("fs_sexa: unknown fracbase: %d\n", fracbase);
-	    exit(1);
+            return -1;
 	}
 
@@ -389,5 +389,5 @@
 }
 
-#ifdef BSD
+#if defined(BSD) && !defined(__GNU__)
 // BSD - OSX version
 int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd)
@@ -949,5 +949,5 @@
         default:
             fprintf (stderr, "Impossible IPState %d\n", s);
-            exit(1);
+            return NULL;
         }
 }
@@ -1007,4 +1007,5 @@
         default:
             fprintf (stderr, "Impossible ISState %d\n", s);
+            return NULL;
         }
 }
@@ -1020,4 +1021,5 @@
         default:
             fprintf (stderr, "Impossible ISRule %d\n", r);
+            return NULL;
         }
 }
@@ -1033,4 +1035,5 @@
         default:
             fprintf (stderr, "Impossible IPerm %d\n", p);
+            return NULL;
         }
 }
Index: /BAORadio/libindi/libindi/libs/lilxml.c
===================================================================
--- /BAORadio/libindi/libindi/libs/lilxml.c	(revision 641)
+++ /BAORadio/libindi/libindi/libs/lilxml.c	(revision 642)
@@ -15,5 +15,5 @@
     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 #endif
@@ -27,4 +27,5 @@
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -41,5 +42,5 @@
 #define	MINMEM	64			/* starting string length */
 
-static int oneXMLchar (LilXML *lp, int c, char errmsg[]);
+static int oneXMLchar (LilXML *lp, int c, char ynot[]);
 static void initParser(LilXML *lp);
 static void pushXMLEle(LilXML *lp);
@@ -111,5 +112,5 @@
 static char entities[] = "&<>'\"";
 
-/* default memory managers, override with indi_xmlMalloc() */
+/* default memory managers, override with lilxmlMalloc() */
 static void *(*mymalloc)(size_t size) = malloc;
 static void *(*myrealloc)(void *ptr, size_t size) = realloc;
@@ -120,11 +121,11 @@
  */
 void
-indi_xmlMalloc (void *(*newmalloc)(size_t size),
-	   void *(*newrealloc)(void *ptr, size_t size),
-	   void (*newfree)(void *ptr))
-{
-	mymalloc = newmalloc;
-	myrealloc = newrealloc;
-	myfree = newfree;
+lilxmlMalloc (void *(*newmalloc)(size_t size),
+           void *(*newrealloc)(void *ptr, size_t size),
+           void (*newfree)(void *ptr))
+{
+        mymalloc = newmalloc;
+        myrealloc = newrealloc;
+        myfree = newfree;
 }
 
@@ -133,8 +134,8 @@
 newLilXML ()
 {
-	LilXML *lp = (LilXML *) moremem (NULL, sizeof(LilXML));
-	memset (lp, 0, sizeof(LilXML));
-	initParser(lp);
-	return (lp);
+        LilXML *lp = (LilXML *) moremem (NULL, sizeof(LilXML));
+        memset (lp, 0, sizeof(LilXML));
+        initParser(lp);
+        return (lp);
 }
 
@@ -143,7 +144,7 @@
 delLilXML (LilXML *lp)
 {
-	delXMLEle (lp->ce);
-	freeString (&lp->endtag);
-	(*myfree) (lp);
+        delXMLEle (lp->ce);
+        freeString (&lp->endtag);
+        (*myfree) (lp);
 }
 
@@ -152,114 +153,149 @@
 delXMLEle (XMLEle *ep)
 {
-	int i;
-
-	/* benign if NULL */
-	if (!ep)
-	    return;
-
-	/* delete all parts of ep */
-	freeString (&ep->tag);
-	freeString (&ep->pcdata);
-	if (ep->at) {
-	    for (i = 0; i < ep->nat; i++)
-		freeAtt (ep->at[i]);
-	    (*myfree) (ep->at);
-	}
-	if (ep->el) {
-	    for (i = 0; i < ep->nel; i++) {
-		/* forget parent so deleting doesn't modify _this_ el[] */
-		ep->el[i]->pe = NULL;
-
-		delXMLEle (ep->el[i]);
-	    }
-	    (*myfree) (ep->el);
-	}
-
-	/* remove from parent's list if known */
-	if (ep->pe) {
-	    XMLEle *pe = ep->pe;
-	    for (i = 0; i < pe->nel; i++) {
-		if (pe->el[i] == ep) {
-		    memmove (&pe->el[i], &pe->el[i+1],
-					      (--pe->nel-i)*sizeof(XMLEle*));
-		    break;
-		}
-	    }
-	}
-
-	/* delete ep itself */
-	(*myfree) (ep);
+        int i;
+
+        /* benign if NULL */
+        if (!ep)
+            return;
+
+        /* delete all parts of ep */
+        freeString (&ep->tag);
+        freeString (&ep->pcdata);
+        if (ep->at) {
+            for (i = 0; i < ep->nat; i++)
+                freeAtt (ep->at[i]);
+            (*myfree) (ep->at);
+        }
+        if (ep->el) {
+            for (i = 0; i < ep->nel; i++) {
+                /* forget parent so deleting doesn't modify _this_ el[] */
+                ep->el[i]->pe = NULL;
+
+                delXMLEle (ep->el[i]);
+            }
+            (*myfree) (ep->el);
+        }
+
+        /* remove from parent's list if known */
+        if (ep->pe) {
+            XMLEle *pe = ep->pe;
+            for (i = 0; i < pe->nel; i++) {
+                if (pe->el[i] == ep) {
+                    memmove (&pe->el[i], &pe->el[i+1],
+                                              (--pe->nel-i)*sizeof(XMLEle*));
+                    break;
+                }
+            }
+        }
+
+        /* delete ep itself */
+        (*myfree) (ep);
 }
 
 /* process one more character of an XML file.
  * when find closure with outter element return root of complete tree.
- * when find error return NULL with reason in errmsg[].
- * when need more return NULL with errmsg[0] = '\0'.
+ * when find error return NULL with reason in ynot[].
+ * when need more return NULL with ynot[0] = '\0'.
  * N.B. it is up to the caller to delete any tree returned with delXMLEle().
  */
 XMLEle *
-readXMLEle (LilXML *lp, int newc, char errmsg[])
-{
-	XMLEle *root;
-	int s;
-
-	/* start optimistic */
-	errmsg[0] = '\0';
-
-	/* EOF? */
-	if (newc == 0) {
-	    sprintf (errmsg, "Line %d: early XML EOF", lp->ln);
-	    initParser(lp);
-	    return (NULL);
-	}
-
-	/* new line? */
-	if (newc == '\n')
-	    lp->ln++;
-
-	/* skip comments and declarations. requires 1 char history */
-	if (!lp->skipping && lp->lastc == '<' && (newc == '?' || newc == '!')) {
-	    lp->skipping = 1;
-	    lp->lastc = newc;
-	    return (NULL);
-	}
-	if (lp->skipping) {
-	    if (newc == '>')
-		lp->skipping = 0;
-	    lp->lastc = newc;
-	    return (NULL);
-	}
-	if (newc == '<') {
-	    lp->lastc = '<';
-	    return (NULL);
-	}
-
-	/* do a pending '<' first then newc */
-	if (lp->lastc == '<') {
-	    if (oneXMLchar (lp, '<', errmsg) < 0) {
-		initParser(lp);
-		return (NULL);
-	    }
-	    /* N.B. we assume '<' will never result in closure */
-	}
-
-	/* process newc (at last!) */
-	s = oneXMLchar (lp, newc, errmsg);
-	if (s == 0) {
-	    lp->lastc = newc;
-	    return (NULL);
-	}
-	if (s < 0) {
-	    initParser(lp);
-	    return (NULL);
-	}
-
-	/* Ok! return ce and we start over.
-	 * N.B. up to caller to call delXMLEle with what we return.
-	 */
-	root = lp->ce;
-	lp->ce = NULL;
-	initParser(lp);
-	return (root);
+readXMLEle (LilXML *lp, int newc, char ynot[])
+{
+        XMLEle *root;
+        int s;
+
+        /* start optimistic */
+        ynot[0] = '\0';
+
+        /* EOF? */
+        if (newc == 0) {
+            sprintf (ynot, "Line %d: early XML EOF", lp->ln);
+            initParser(lp);
+            return (NULL);
+        }
+
+        /* new line? */
+        if (newc == '\n')
+            lp->ln++;
+
+        /* skip comments and declarations. requires 1 char history */
+        if (!lp->skipping && lp->lastc == '<' && (newc == '?' || newc == '!')) {
+            lp->skipping = 1;
+            lp->lastc = newc;
+            return (NULL);
+        }
+        if (lp->skipping) {
+            if (newc == '>')
+                lp->skipping = 0;
+            lp->lastc = newc;
+            return (NULL);
+        }
+        if (newc == '<') {
+            lp->lastc = '<';
+            return (NULL);
+        }
+
+        /* do a pending '<' first then newc */
+        if (lp->lastc == '<') {
+            if (oneXMLchar (lp, '<', ynot) < 0) {
+                initParser(lp);
+                return (NULL);
+            }
+            /* N.B. we assume '<' will never result in closure */
+        }
+
+        /* process newc (at last!) */
+        s = oneXMLchar (lp, newc, ynot);
+        if (s == 0) {
+            lp->lastc = newc;
+            return (NULL);
+        }
+        if (s < 0) {
+            initParser(lp);
+            return (NULL);
+        }
+
+        /* Ok! return ce and we start over.
+         * N.B. up to caller to call delXMLEle with what we return.
+         */
+        root = lp->ce;
+        lp->ce = NULL;
+        initParser(lp);
+        return (root);
+}
+
+/* parse the given XML string.
+ * return XMLEle* else NULL with reason why in ynot[]
+ */
+XMLEle *
+parseXML (char buf[], char ynot[])
+{
+        LilXML *lp = newLilXML();
+        XMLEle *root;
+
+        do {
+            root = readXMLEle (lp, *buf++, ynot);
+        } while (!root && !ynot[0]);
+
+        delLilXML (lp);
+
+        return (root);
+}
+
+/* return a deep copy of the given XMLEle *
+ */
+XMLEle *
+cloneXMLEle (XMLEle *ep)
+{
+        char *buf;
+        char ynot[1024];
+        XMLEle *newep;
+
+        buf = (*mymalloc) (sprlXMLEle (ep, 0) + 1);
+        sprXMLEle (buf, ep, 0);
+        newep = parseXML (buf, ynot);
+        (*myfree) (buf);
+
+        return (newep);
 }
 
@@ -270,10 +306,10 @@
 findXMLAtt (XMLEle *ep, const char *name)
 {
-	int i;
-
-	for (i = 0; i < ep->nat; i++)
-	    if (!strcmp (ep->at[i]->name.s, name))
-		return (ep->at[i]);
-	return (NULL);
+        int i;
+
+        for (i = 0; i < ep->nat; i++)
+            if (!strcmp (ep->at[i]->name.s, name))
+                return (ep->at[i]);
+        return (NULL);
 }
 
@@ -284,13 +320,13 @@
 findXMLEle (XMLEle *ep, const char *tag)
 {
-	int tl = strlen (tag);
-	int i;
-
-	for (i = 0; i < ep->nel; i++) {
-	    String *sp = &ep->el[i]->tag;
-	    if (sp->sl == tl && !strcmp (sp->s, tag))
-		return (ep->el[i]);
-	}
-	return (NULL);
+        int tl = strlen (tag);
+        int i;
+
+        for (i = 0; i < ep->nel; i++) {
+            String *sp = &ep->el[i]->tag;
+            if (sp->sl == tl && !strcmp (sp->s, tag))
+                return (ep->el[i]);
+        }
+        return (NULL);
 }
 
@@ -302,13 +338,13 @@
 nextXMLEle (XMLEle *ep, int init)
 {
-	int eit;
-	
-	if (init)
-	    ep->eit = 0;
-
-	eit = ep->eit++;
-	if (eit < 0 || eit >= ep->nel)
-	    return (NULL);
-	return (ep->el[eit]);
+        int eit;
+
+        if (init)
+            ep->eit = 0;
+
+        eit = ep->eit++;
+        if (eit < 0 || eit >= ep->nel)
+            return (NULL);
+        return (ep->el[eit]);
 }
 
@@ -320,13 +356,13 @@
 nextXMLAtt (XMLEle *ep, int init)
 {
-	int ait;
-
-	if (init)
-	    ep->ait = 0;
-
-	ait = ep->ait++;
-	if (ait < 0 || ait >= ep->nat)
-	    return (NULL);
-	return (ep->at[ait]);
+        int ait;
+
+        if (init)
+            ep->ait = 0;
+
+        ait = ep->ait++;
+        if (ait < 0 || ait >= ep->nat)
+            return (NULL);
+        return (ep->at[ait]);
 }
 
@@ -335,5 +371,5 @@
 parentXMLEle (XMLEle *ep)
 {
-	return (ep->pe);
+        return (ep->pe);
 }
 
@@ -342,5 +378,5 @@
 parentXMLAtt (XMLAtt *ap)
 {
-	return (ap->ce);
+        return (ap->ce);
 }
 
@@ -351,5 +387,5 @@
 tagXMLEle (XMLEle *ep)
 {
-	return (ep->tag.s);
+        return (ep->tag.s);
 }
 
@@ -358,12 +394,12 @@
 pcdataXMLEle (XMLEle *ep)
 {
-	return (ep->pcdata.s);
+        return (ep->pcdata.s);
 }
 
 /* return the number of characters in the pcdata portion of the given element */
-int 
+int
 pcdatalenXMLEle (XMLEle *ep)
 {
-	return (ep->pcdata.sl);
+        return (ep->pcdata.sl);
 }
 
@@ -372,5 +408,5 @@
 nameXMLAtt (XMLAtt *ap)
 {
-	return (ap->name.s);
+        return (ap->name.s);
 }
 
@@ -379,5 +415,5 @@
 valuXMLAtt (XMLAtt *ap)
 {
-	return (ap->valu.s);
+        return (ap->valu.s);
 }
 
@@ -386,5 +422,5 @@
 nXMLEle (XMLEle *ep)
 {
-	return (ep->nel);
+        return (ep->nel);
 }
 
@@ -393,5 +429,5 @@
 nXMLAtt (XMLEle *ep)
 {
-	return (ep->nat);
+        return (ep->nat);
 }
 
@@ -403,23 +439,23 @@
 findXMLAttValu (XMLEle *ep, const char *name)
 {
-	XMLAtt *a = findXMLAtt (ep, name);
-	return (a ? a->valu.s : "");
+        XMLAtt *a = findXMLAtt (ep, name);
+        return (a ? a->valu.s : "");
 }
 
 /* handy wrapper to read one xml file.
- * return root element else NULL with report in errmsg[]
+ * return root element else NULL with report in ynot[]
  */
 XMLEle *
-readXMLFile (FILE *fp, LilXML *lp, char errmsg[])
-{
-	int c;
-
-	while ((c = fgetc(fp)) != EOF) {
-	    XMLEle *root = readXMLEle (lp, c, errmsg);
-	    if (root || errmsg[0])
-		return (root);
-	}
-
-	return (NULL);
+readXMLFile (FILE *fp, LilXML *lp, char ynot[])
+{
+        int c;
+
+        while ((c = fgetc(fp)) != EOF) {
+            XMLEle *root = readXMLEle (lp, c, ynot);
+            if (root || ynot[0])
+                return (root);
+        }
+
+        return (NULL);
 }
 
@@ -430,7 +466,17 @@
 addXMLEle (XMLEle *parent, const char *tag)
 {
-	XMLEle *ep = growEle (parent);
-	appendString (&ep->tag, tag);
-	return (ep);
+        XMLEle *ep = growEle (parent);
+        appendString (&ep->tag, tag);
+        return (ep);
+}
+
+/* append an existing element to the given element.
+ * N.B. be mindful of when these are deleted, this is not a deep copy.
+ */
+void
+appXMLEle (XMLEle *ep, XMLEle *newep)
+{
+        ep->el = (XMLEle **) moremem (ep->el, (ep->nel+1)*sizeof(XMLEle *));
+        ep->el[ep->nel++] = newep;
 }
 
@@ -439,7 +485,7 @@
 editXMLEle (XMLEle *ep, const char *pcdata)
 {
-	freeString (&ep->pcdata);
-	appendString (&ep->pcdata, pcdata);
-	ep->pcdata_hasent = (strpbrk (pcdata, entities) != NULL);
+        freeString (&ep->pcdata);
+        appendString (&ep->pcdata, pcdata);
+        ep->pcdata_hasent = (strpbrk (pcdata, entities) != NULL);
 }
 
@@ -448,8 +494,8 @@
 addXMLAtt (XMLEle *ep, const char *name, const char *valu)
 {
-	XMLAtt *ap = growAtt (ep);
-	appendString (&ap->name, name);
-	appendString (&ap->valu, valu);
-	return (ap);
+        XMLAtt *ap = growAtt (ep);
+        appendString (&ap->name, name);
+        appendString (&ap->valu, valu);
+        return (ap);
 }
 
@@ -458,13 +504,13 @@
 rmXMLAtt (XMLEle *ep, const char *name)
 {
-	int i;
-
-	for (i = 0; i < ep->nat; i++) {
-	    if (strcmp (ep->at[i]->name.s, name) == 0) {
-		freeAtt (ep->at[i]);
-		memmove (&ep->at[i],&ep->at[i+1],(--ep->nat-i)*sizeof(XMLAtt*));
-		return;
-	    }
-	}
+        int i;
+
+        for (i = 0; i < ep->nat; i++) {
+            if (strcmp (ep->at[i]->name.s, name) == 0) {
+                freeAtt (ep->at[i]);
+                memmove (&ep->at[i],&ep->at[i+1],(--ep->nat-i)*sizeof(XMLAtt*));
+                return;
+            }
+        }
 }
 
@@ -473,6 +519,6 @@
 editXMLAtt (XMLAtt *ap, const char *str)
 {
-	freeString (&ap->valu);
-	appendString (&ap->valu, str);
+        freeString (&ap->valu);
+        appendString (&ap->valu, str);
 }
 
@@ -484,30 +530,30 @@
 prXMLEle (FILE *fp, XMLEle *ep, int level)
 {
-	int indent = level*PRINDENT;
-	int i;
-
-	fprintf (fp, "%*s<%s", indent, "", ep->tag.s);
-	for (i = 0; i < ep->nat; i++)
-	    fprintf (fp, " %s=\"%s\"", ep->at[i]->name.s,
-						entityXML(ep->at[i]->valu.s));
-	if (ep->nel > 0) {
-	    fprintf (fp, ">\n");
-	    for (i = 0; i < ep->nel; i++)
-		prXMLEle (fp, ep->el[i], level+1);
-	}
-	if (ep->pcdata.sl > 0) {
-	    if (ep->nel == 0)
-		fprintf (fp, ">\n");
-	    if (ep->pcdata_hasent)
-		fprintf (fp, "%s", entityXML(ep->pcdata.s));
-	    else
-		fprintf (fp, "%s", ep->pcdata.s);
-	    if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
-		fprintf (fp, "\n");
-	}
-	if (ep->nel > 0 || ep->pcdata.sl > 0)
-	    fprintf (fp, "%*s</%s>\n", indent, "", ep->tag.s);
-	else
-	    fprintf (fp, "/>\n");
+        int indent = level*PRINDENT;
+        int i;
+
+        fprintf (fp, "%*s<%s", indent, "", ep->tag.s);
+        for (i = 0; i < ep->nat; i++)
+            fprintf (fp, " %s=\"%s\"", ep->at[i]->name.s,
+                                                entityXML(ep->at[i]->valu.s));
+        if (ep->nel > 0) {
+            fprintf (fp, ">\n");
+            for (i = 0; i < ep->nel; i++)
+                prXMLEle (fp, ep->el[i], level+1);
+        }
+        if (ep->pcdata.sl > 0) {
+            if (ep->nel == 0)
+                fprintf (fp, ">\n");
+            if (ep->pcdata_hasent)
+                fprintf (fp, "%s", entityXML(ep->pcdata.s));
+            else
+                fprintf (fp, "%s", ep->pcdata.s);
+            if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
+                fprintf (fp, "\n");
+        }
+        if (ep->nel > 0 || ep->pcdata.sl > 0)
+            fprintf (fp, "%*s</%s>\n", indent, "", ep->tag.s);
+        else
+            fprintf (fp, "/>\n");
 }
 
@@ -520,35 +566,35 @@
 sprXMLEle (char *s, XMLEle *ep, int level)
 {
-	int indent = level*PRINDENT;
-	int sl = 0;
-	int i;
-
-	sl += sprintf (s+sl, "%*s<%s", indent, "", ep->tag.s);
-	for (i = 0; i < ep->nat; i++)
-	    sl += sprintf (s+sl, " %s=\"%s\"", ep->at[i]->name.s,
-						entityXML(ep->at[i]->valu.s));
-	if (ep->nel > 0) {
-	    sl += sprintf (s+sl, ">\n");
-	    for (i = 0; i < ep->nel; i++)
-		sl += sprXMLEle (s+sl, ep->el[i], level+1);
-	}
-	if (ep->pcdata.sl > 0) {
-	    if (ep->nel == 0)
-		sl += sprintf (s+sl, ">\n");
-	    if (ep->pcdata_hasent)
-		sl += sprintf (s+sl, "%s", entityXML(ep->pcdata.s));
-	    else {
-		strcpy (s+sl, ep->pcdata.s);
-		sl += ep->pcdata.sl;
-	    }
-	    if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
-		sl += sprintf (s+sl, "\n");
-	}
-	if (ep->nel > 0 || ep->pcdata.sl > 0)
-	    sl += sprintf (s+sl, "%*s</%s>\n", indent, "", ep->tag.s);
-	else
-	    sl += sprintf (s+sl, "/>\n");
-
-	return (sl);
+        int indent = level*PRINDENT;
+        int sl = 0;
+        int i;
+
+        sl += sprintf (s+sl, "%*s<%s", indent, "", ep->tag.s);
+        for (i = 0; i < ep->nat; i++)
+            sl += sprintf (s+sl, " %s=\"%s\"", ep->at[i]->name.s,
+                                                entityXML(ep->at[i]->valu.s));
+        if (ep->nel > 0) {
+            sl += sprintf (s+sl, ">\n");
+            for (i = 0; i < ep->nel; i++)
+                sl += sprXMLEle (s+sl, ep->el[i], level+1);
+        }
+        if (ep->pcdata.sl > 0) {
+            if (ep->nel == 0)
+                sl += sprintf (s+sl, ">\n");
+            if (ep->pcdata_hasent)
+                sl += sprintf (s+sl, "%s", entityXML(ep->pcdata.s));
+            else {
+                strcpy (s+sl, ep->pcdata.s);
+                sl += ep->pcdata.sl;
+            }
+            if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
+                sl += sprintf (s+sl, "\n");
+        }
+        if (ep->nel > 0 || ep->pcdata.sl > 0)
+            sl += sprintf (s+sl, "%*s</%s>\n", indent, "", ep->tag.s);
+        else
+            sl += sprintf (s+sl, "/>\n");
+
+        return (sl);
 }
 
@@ -560,33 +606,33 @@
 sprlXMLEle (XMLEle *ep, int level)
 {
-	int indent = level*PRINDENT;
-	int l = 0;
-	int i;
-
-	l += indent + 1 + ep->tag.sl;
-	for (i = 0; i < ep->nat; i++)
-	    l += ep->at[i]->name.sl + 4 + strlen(entityXML(ep->at[i]->valu.s));
-
-	if (ep->nel > 0) {
-	    l += 2;
-	    for (i = 0; i < ep->nel; i++)
-		l += sprlXMLEle (ep->el[i], level+1);
-	}
-	if (ep->pcdata.sl > 0) {
-	    if (ep->nel == 0)
-		l += 2;
-	    if (ep->pcdata_hasent)
-		l += strlen (entityXML(ep->pcdata.s));
-	    else
-		l += ep->pcdata.sl;
-	    if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
-		l += 1;
-	}
-	if (ep->nel > 0 || ep->pcdata.sl > 0)
-	    l += indent + 4 + ep->tag.sl;
-	else
-	    l += 3;
-
-	return (l);
+        int indent = level*PRINDENT;
+        int l = 0;
+        int i;
+
+        l += indent + 1 + ep->tag.sl;
+        for (i = 0; i < ep->nat; i++)
+            l += ep->at[i]->name.sl + 4 + strlen(entityXML(ep->at[i]->valu.s));
+
+        if (ep->nel > 0) {
+            l += 2;
+            for (i = 0; i < ep->nel; i++)
+                l += sprlXMLEle (ep->el[i], level+1);
+        }
+        if (ep->pcdata.sl > 0) {
+            if (ep->nel == 0)
+                l += 2;
+            if (ep->pcdata_hasent)
+                l += strlen (entityXML(ep->pcdata.s));
+            else
+                l += ep->pcdata.sl;
+            if (ep->pcdata.s[ep->pcdata.sl-1] != '\n')
+                l += 1;
+        }
+        if (ep->nel > 0 || ep->pcdata.sl > 0)
+            l += indent + 4 + ep->tag.sl;
+        else
+            l += 3;
+
+        return (l);
 }
 
@@ -598,56 +644,59 @@
 entityXML (char *s)
 {
-	static char *malbuf;
-	int nmalbuf = 0;
-	char *sret;
-	char *ep;
-
-	/* scan for each entity, if any */
-	for (sret = s; (ep = strpbrk (s, entities)) != NULL; s = ep+1) {
-
-	    /* found another entity, copy preceding to malloced buffer */
-	    int nnew = ep - s;			/* all but entity itself */
-	    sret = malbuf = moremem (malbuf, nmalbuf + nnew + 10);
-	    memcpy (malbuf+nmalbuf, s, nnew);
-	    nmalbuf += nnew;
-
-	    /* replace with entity encoding */
-	    switch (*ep) {
-	    case '&':
-		nmalbuf += sprintf (malbuf+nmalbuf, "&amp;");
-		break;
-	    case '<':
-		nmalbuf += sprintf (malbuf+nmalbuf, "&lt;");
-		break;
-	    case '>':
-		nmalbuf += sprintf (malbuf+nmalbuf, "&gt;");
-		break;
-	    case '\'':
-		nmalbuf += sprintf (malbuf+nmalbuf, "&apos;");
-		break;
-	    case '"':
-		nmalbuf += sprintf (malbuf+nmalbuf, "&quot;");
-		break;
-
-	    }
-
-	}
-
-	/* return s if no entities, else malloc cleaned-up copy */
-	if (sret == s) {
-	    /* using s, so free any malloced memory from last time */
-	    if (malbuf) {
-		free (malbuf);
-		malbuf = NULL;
-	    }
-	} else {
-	    /* put remaining part of s into malbuf */
-	    int nleft = strlen (s) + 1;		/* include \0 */
-	    sret = malbuf = moremem (malbuf, nmalbuf + nleft);
-	    memcpy (malbuf+nmalbuf, s, nleft);
-	}
-
-	return (sret);
-}
+        static char *malbuf;
+        int nmalbuf = 0;
+        char *sret;
+        char *ep;
+
+        /* scan for each entity, if any */
+        for (sret = s; (ep = strpbrk (s, entities)) != NULL; s = ep+1) {
+
+            /* found another entity, copy preceding to malloced buffer */
+            int nnew = ep - s;			/* all but entity itself */
+            sret = malbuf = moremem (malbuf, nmalbuf + nnew + 10);
+            memcpy (malbuf+nmalbuf, s, nnew);
+            nmalbuf += nnew;
+
+            /* replace with entity encoding */
+            switch (*ep) {
+            case '&':
+                nmalbuf += sprintf (malbuf+nmalbuf, "&amp;");
+                break;
+            case '<':
+                nmalbuf += sprintf (malbuf+nmalbuf, "&lt;");
+                break;
+            case '>':
+                nmalbuf += sprintf (malbuf+nmalbuf, "&gt;");
+                break;
+            case '\'':
+                nmalbuf += sprintf (malbuf+nmalbuf, "&apos;");
+                break;
+            case '"':
+                nmalbuf += sprintf (malbuf+nmalbuf, "&quot;");
+                break;
+
+            }
+
+        }
+
+        /* return s if no entities, else malloc cleaned-up copy */
+        if (sret == s) {
+            /* using s, so free any malloced memory from last time */
+            if (malbuf) {
+                free (malbuf);
+                malbuf = NULL;
+            }
+        } else {
+            /* put remaining part of s into malbuf */
+            int nleft = strlen (s) + 1;		/* include \0 */
+            sret = malbuf = moremem (malbuf, nmalbuf + nleft);
+            memcpy (malbuf+nmalbuf, s, nleft);
+        }
+
+        return (sret);
+}
+
+
+
 
 /* if ent is a recognized xml entity sequence, set *cp to char and return 1
@@ -657,24 +706,24 @@
 decodeEntity (char *ent, int *cp)
 {
-	static struct {
-	    const char *ent;
-	    char c;
-	} enttable[] = {
-	    {"&amp;",  '&'},
-	    {"&apos;", '\''},
-	    {"&lt;",   '<'},
-	    {"&gt;",   '>'},
-	    {"&quot;", '"'},
-	};
-	unsigned int i;
-
-	for (i = 0; i < sizeof(enttable)/sizeof(enttable[0]); i++) {
-	    if (strcmp (ent, enttable[i].ent) == 0) {
-		*cp = enttable[i].c;
-		return (1);
-	    }
-	}
-	
-	return (0);
+        static struct {
+            char *ent;
+            char c;
+        } enttable[] = {
+            {"&amp;",  '&'},
+            {"&apos;", '\''},
+            {"&lt;",   '<'},
+            {"&gt;",   '>'},
+            {"&quot;", '"'},
+        };
+        int i;
+
+        for (i = 0; i < sizeof(enttable)/sizeof(enttable[0]); i++) {
+            if (strcmp (ent, enttable[i].ent) == 0) {
+                *cp = enttable[i].c;
+                return (1);
+            }
+        }
+
+        return (0);
 }
 
@@ -682,200 +731,200 @@
  * if find final closure, return 1 and tree is in ce.
  * if need more, return 0.
- * if real trouble, return -1 and put reason in errmsg.
+ * if real trouble, return -1 and put reason in ynot.
  */
 static int
-oneXMLchar (LilXML *lp, int c, char errmsg[])
-{
-	switch (lp->cs) {
-	case LOOK4START:		/* looking for first element start */
-	    if (c == '<') {
-		pushXMLEle(lp);
-		lp->cs = LOOK4TAG;
-	    }
-	    /* silently ignore until resync */
-	    break;
-
-	case LOOK4TAG:			/* looking for element tag */
-	    if (isTokenChar (1, c)) {
-		growString (&lp->ce->tag, c);
-		lp->cs = INTAG;
-	    } else if (!isspace(c)) {
-		sprintf (errmsg, "Line %d: Bogus tag char %c", lp->ln, c);
-		return (-1);
-	    }
-	    break;
-		
-	case INTAG:			/* reading tag */
-	    if (isTokenChar (0, c))
-		growString (&lp->ce->tag, c);
-	    else if (c == '>')
-		lp->cs = LOOK4CON;
-	    else if (c == '/')
-		lp->cs = SAWSLASH;
-	    else 
-		lp->cs = LOOK4ATTRN;
-	    break;
-
-	case LOOK4ATTRN:		/* looking for attr name, > or / */
-	    if (c == '>')
-		lp->cs = LOOK4CON;
-	    else if (c == '/')
-		lp->cs = SAWSLASH;
-	    else if (isTokenChar (1, c)) {
-		XMLAtt *ap = growAtt(lp->ce);
-		growString (&ap->name, c);
-		lp->cs = INATTRN;
-	    } else if (!isspace(c)) {
-		sprintf (errmsg, "Line %d: Bogus leading attr name char: %c",
-								    lp->ln, c);
-		return (-1);
-	    }
-	    break;
-
-	case SAWSLASH:			/* saw / in element opening */
-	    if (c == '>') {
-		if (!lp->ce->pe)
-		    return(1);		/* root has no content */
-		popXMLEle(lp);
-		lp->cs = LOOK4CON;
-	    } else {
-		sprintf (errmsg, "Line %d: Bogus char %c before >", lp->ln, c);
-		return (-1);
-	    }
-	    break;
-		
-	case INATTRN:			/* reading attr name */
-	    if (isTokenChar (0, c))
-		growString (&lp->ce->at[lp->ce->nat-1]->name, c);
-	    else if (isspace(c) || c == '=')
-		lp->cs = LOOK4ATTRV;
-	    else {
-		sprintf (errmsg, "Line %d: Bogus attr name char: %c", lp->ln,c);
-		return (-1);
-	    }
-	    break;
-
-	case LOOK4ATTRV:		/* looking for attr value */
-	    if (c == '\'' || c == '"') {
-		lp->delim = c;
-		lp->cs = INATTRV;
-	    } else if (!(isspace(c) || c == '=')) {
-		sprintf (errmsg, "Line %d: No value for attribute %s", lp->ln,
-					lp->ce->at[lp->ce->nat-1]->name.s);
-		return (-1);
-	    }
-	    break;
-
-	case INATTRV:			/* in attr value */
-	    if (c == '&') {
-		newString (&lp->entity);
-		growString (&lp->entity, c);
-		lp->cs = ENTINATTRV;
-	    } else if (c == lp->delim)
-		lp->cs = LOOK4ATTRN;
-	    else if (!iscntrl(c))
-		growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
-	    break;
-
-	case ENTINATTRV:		/* working on entity in attr valu */
-	    if (c == ';') {
-		/* if find a recongized esp seq, add equiv char else raw seq */
-		growString (&lp->entity, c);
-		if (decodeEntity (lp->entity.s, &c))
-		    growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
-		else
-		    appendString(&lp->ce->at[lp->ce->nat-1]->valu,lp->entity.s);
-		freeString (&lp->entity);
-		lp->cs = INATTRV;
-	    } else
-		growString (&lp->entity, c);
-	    break;
-
-	case LOOK4CON:			/* skipping leading content whitespace*/
-	    if (c == '<')
-		lp->cs = SAWLTINCON;
-	    else if (!isspace(c)) {
-		growString (&lp->ce->pcdata, c);
-		lp->cs = INCON;
-	    }
-	    break;
-
-	case INCON:			/* reading content */
-	    if (c == '&') {
-		newString (&lp->entity);
-		growString (&lp->entity, c);
-		lp->cs = ENTINCON;
-	    } else if (c == '<') {
-		/* chomp trailing whitespace */
-		while (lp->ce->pcdata.sl > 0 &&
-			    isspace(lp->ce->pcdata.s[lp->ce->pcdata.sl-1]))
-		    lp->ce->pcdata.s[--(lp->ce->pcdata.sl)] = '\0';
-		lp->cs = SAWLTINCON;
-	    } else {
-		growString (&lp->ce->pcdata, c);
-	    }
-	    break;
-
-	case ENTINCON:			/* working on entity in content */
-	    if (c == ';') {
-		/* if find a recognized esc seq, add equiv char else raw seq */
-		growString (&lp->entity, c);
-		if (decodeEntity (lp->entity.s, &c))
-		    growString (&lp->ce->pcdata, c);
-		else {
-		    appendString(&lp->ce->pcdata, lp->entity.s);
-		    lp->ce->pcdata_hasent = 1;
-		}
-		freeString (&lp->entity);
-		lp->cs = INCON;
-	    } else
-		growString (&lp->entity, c);
-	    break;
-
-	case SAWLTINCON:		/* saw < in content */
-	    if (c == '/') {
-		resetEndTag(lp);
-		lp->cs = LOOK4CLOSETAG;
-	    } else {
-		pushXMLEle(lp);
-		if (isTokenChar(1,c)) {
-		    growString (&lp->ce->tag, c);
-		    lp->cs = INTAG;
-		} else
-		    lp->cs = LOOK4TAG;
-	    }
-	    break;
-
-	case LOOK4CLOSETAG:		/* looking for closing tag after < */
-	    if (isTokenChar (1, c)) {
-		growString (&lp->endtag, c);
-		lp->cs = INCLOSETAG;
-	    } else if (!isspace(c)) {
-		sprintf (errmsg, "Line %d: Bogus preend tag char %c", lp->ln,c);
-		return (-1);
-	    }
-	    break;
-
-	case INCLOSETAG:		/* reading closing tag */
-	    if (isTokenChar(0, c))
-		growString (&lp->endtag, c);
-	    else if (c == '>') {
-		if (strcmp (lp->ce->tag.s, lp->endtag.s)) {
-		    sprintf (errmsg,"Line %d: closing tag %s does not match %s",
-				    lp->ln, lp->endtag.s, lp->ce->tag.s);
-		    return (-1);
-		} else if (lp->ce->pe) {
-		    popXMLEle(lp);
-		    lp->cs = LOOK4CON;	/* back to content after nested elem */
-		} else
-		    return (1);		/* yes! */
-	    } else if (!isspace(c)) {
-		sprintf (errmsg, "Line %d: Bogus end tag char %c", lp->ln, c);
-		return (-1);
-	    }
-	    break;
-	}
-
-	return (0);
+oneXMLchar (LilXML *lp, int c, char ynot[])
+{
+        switch (lp->cs) {
+        case LOOK4START:		/* looking for first element start */
+            if (c == '<') {
+                pushXMLEle(lp);
+                lp->cs = LOOK4TAG;
+            }
+            /* silently ignore until resync */
+            break;
+
+        case LOOK4TAG:			/* looking for element tag */
+            if (isTokenChar (1, c)) {
+                growString (&lp->ce->tag, c);
+                lp->cs = INTAG;
+            } else if (!isspace(c)) {
+                sprintf (ynot, "Line %d: Bogus tag char %c", lp->ln, c);
+                return (-1);
+            }
+            break;
+
+        case INTAG:			/* reading tag */
+            if (isTokenChar (0, c))
+                growString (&lp->ce->tag, c);
+            else if (c == '>')
+                lp->cs = LOOK4CON;
+            else if (c == '/')
+                lp->cs = SAWSLASH;
+            else
+                lp->cs = LOOK4ATTRN;
+            break;
+
+        case LOOK4ATTRN:		/* looking for attr name, > or / */
+            if (c == '>')
+                lp->cs = LOOK4CON;
+            else if (c == '/')
+                lp->cs = SAWSLASH;
+            else if (isTokenChar (1, c)) {
+                XMLAtt *ap = growAtt(lp->ce);
+                growString (&ap->name, c);
+                lp->cs = INATTRN;
+            } else if (!isspace(c)) {
+                sprintf (ynot, "Line %d: Bogus leading attr name char: %c",
+                                                                    lp->ln, c);
+                return (-1);
+            }
+            break;
+
+        case SAWSLASH:			/* saw / in element opening */
+            if (c == '>') {
+                if (!lp->ce->pe)
+                    return(1);		/* root has no content */
+                popXMLEle(lp);
+                lp->cs = LOOK4CON;
+            } else {
+                sprintf (ynot, "Line %d: Bogus char %c before >", lp->ln, c);
+                return (-1);
+            }
+            break;
+
+        case INATTRN:			/* reading attr name */
+            if (isTokenChar (0, c))
+                growString (&lp->ce->at[lp->ce->nat-1]->name, c);
+            else if (isspace(c) || c == '=')
+                lp->cs = LOOK4ATTRV;
+            else {
+                sprintf (ynot, "Line %d: Bogus attr name char: %c", lp->ln,c);
+                return (-1);
+            }
+            break;
+
+        case LOOK4ATTRV:		/* looking for attr value */
+            if (c == '\'' || c == '"') {
+                lp->delim = c;
+                lp->cs = INATTRV;
+            } else if (!(isspace(c) || c == '=')) {
+                sprintf (ynot, "Line %d: No value for attribute %s", lp->ln,
+                                        lp->ce->at[lp->ce->nat-1]->name.s);
+                return (-1);
+            }
+            break;
+
+        case INATTRV:			/* in attr value */
+            if (c == '&') {
+                newString (&lp->entity);
+                growString (&lp->entity, c);
+                lp->cs = ENTINATTRV;
+            } else if (c == lp->delim)
+                lp->cs = LOOK4ATTRN;
+            else if (!iscntrl(c))
+                growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
+            break;
+
+        case ENTINATTRV:		/* working on entity in attr valu */
+            if (c == ';') {
+                /* if find a recongized esp seq, add equiv char else raw seq */
+                growString (&lp->entity, c);
+                if (decodeEntity (lp->entity.s, &c))
+                    growString (&lp->ce->at[lp->ce->nat-1]->valu, c);
+                else
+                    appendString(&lp->ce->at[lp->ce->nat-1]->valu,lp->entity.s);
+                freeString (&lp->entity);
+                lp->cs = INATTRV;
+            } else
+                growString (&lp->entity, c);
+            break;
+
+        case LOOK4CON:			/* skipping leading content whitespace*/
+            if (c == '<')
+                lp->cs = SAWLTINCON;
+            else if (!isspace(c)) {
+                growString (&lp->ce->pcdata, c);
+                lp->cs = INCON;
+            }
+            break;
+
+        case INCON:			/* reading content */
+            if (c == '&') {
+                newString (&lp->entity);
+                growString (&lp->entity, c);
+                lp->cs = ENTINCON;
+            } else if (c == '<') {
+                /* chomp trailing whitespace */
+                while (lp->ce->pcdata.sl > 0 &&
+                            isspace(lp->ce->pcdata.s[lp->ce->pcdata.sl-1]))
+                    lp->ce->pcdata.s[--(lp->ce->pcdata.sl)] = '\0';
+                lp->cs = SAWLTINCON;
+            } else {
+                growString (&lp->ce->pcdata, c);
+            }
+            break;
+
+        case ENTINCON:			/* working on entity in content */
+            if (c == ';') {
+                /* if find a recognized esc seq, add equiv char else raw seq */
+                growString (&lp->entity, c);
+                if (decodeEntity (lp->entity.s, &c))
+                    growString (&lp->ce->pcdata, c);
+                else {
+                    appendString(&lp->ce->pcdata, lp->entity.s);
+                    lp->ce->pcdata_hasent = 1;
+                }
+                freeString (&lp->entity);
+                lp->cs = INCON;
+            } else
+                growString (&lp->entity, c);
+            break;
+
+        case SAWLTINCON:		/* saw < in content */
+            if (c == '/') {
+                resetEndTag(lp);
+                lp->cs = LOOK4CLOSETAG;
+            } else {
+                pushXMLEle(lp);
+                if (isTokenChar(1,c)) {
+                    growString (&lp->ce->tag, c);
+                    lp->cs = INTAG;
+                } else
+                    lp->cs = LOOK4TAG;
+            }
+            break;
+
+        case LOOK4CLOSETAG:		/* looking for closing tag after < */
+            if (isTokenChar (1, c)) {
+                growString (&lp->endtag, c);
+                lp->cs = INCLOSETAG;
+            } else if (!isspace(c)) {
+                sprintf (ynot, "Line %d: Bogus preend tag char %c", lp->ln,c);
+                return (-1);
+            }
+            break;
+
+        case INCLOSETAG:		/* reading closing tag */
+            if (isTokenChar(0, c))
+                growString (&lp->endtag, c);
+            else if (c == '>') {
+                if (strcmp (lp->ce->tag.s, lp->endtag.s)) {
+                    sprintf (ynot,"Line %d: closing tag %s does not match %s",
+                                    lp->ln, lp->endtag.s, lp->ce->tag.s);
+                    return (-1);
+                } else if (lp->ce->pe) {
+                    popXMLEle(lp);
+                    lp->cs = LOOK4CON;	/* back to content after nested elem */
+                } else
+                    return (1);		/* yes! */
+            } else if (!isspace(c)) {
+                sprintf (ynot, "Line %d: Bogus end tag char %c", lp->ln, c);
+                return (-1);
+            }
+            break;
+        }
+
+        return (0);
 }
 
@@ -884,10 +933,10 @@
 initParser(LilXML *lp)
 {
-	delXMLEle (lp->ce);
-	freeString (&lp->endtag);
-	memset (lp, 0, sizeof(*lp));
-	newString (&lp->endtag);
-	lp->cs = LOOK4START;
-	lp->ln = 1;
+        delXMLEle (lp->ce);
+        freeString (&lp->endtag);
+        memset (lp, 0, sizeof(*lp));
+        newString (&lp->endtag);
+        lp->cs = LOOK4START;
+        lp->ln = 1;
 }
 
@@ -900,6 +949,6 @@
 pushXMLEle(LilXML *lp)
 {
-	lp->ce = growEle (lp->ce);
-	resetEndTag(lp);
+        lp->ce = growEle (lp->ce);
+        resetEndTag(lp);
 }
 
@@ -910,6 +959,6 @@
 popXMLEle(LilXML *lp)
 {
-	lp->ce = lp->ce->pe;
-	resetEndTag(lp);
+        lp->ce = lp->ce->pe;
+        resetEndTag(lp);
 }
 
@@ -918,17 +967,17 @@
 growEle (XMLEle *pe)
 {
-	XMLEle *newe = (XMLEle *) moremem (NULL, sizeof(XMLEle));
-
-	memset (newe, 0, sizeof(XMLEle));
-	newString (&newe->tag);
-	newString (&newe->pcdata);
-	newe->pe = pe;
-
-	if (pe) {
-	    pe->el = (XMLEle **) moremem (pe->el, (pe->nel+1)*sizeof(XMLEle *));
-	    pe->el[pe->nel++] = newe;
-	}
-
-	return (newe);
+        XMLEle *newe = (XMLEle *) moremem (NULL, sizeof(XMLEle));
+
+        memset (newe, 0, sizeof(XMLEle));
+        newString (&newe->tag);
+        newString (&newe->pcdata);
+        newe->pe = pe;
+
+        if (pe) {
+            pe->el = (XMLEle **) moremem (pe->el, (pe->nel+1)*sizeof(XMLEle *));
+            pe->el[pe->nel++] = newe;
+        }
+
+        return (newe);
 }
 
@@ -937,15 +986,15 @@
 growAtt(XMLEle *ep)
 {
-	XMLAtt *newa = (XMLAtt *) moremem (NULL, sizeof(XMLAtt));
-
-	memset (newa, 0, sizeof(*newa));
-	newString(&newa->name);
-	newString(&newa->valu);
-	newa->ce = ep;
-
-	ep->at = (XMLAtt **) moremem (ep->at, (ep->nat+1)*sizeof(XMLAtt *));
-	ep->at[ep->nat++] = newa;
-
-	return (newa);
+        XMLAtt *newa = (XMLAtt *) moremem (NULL, sizeof(XMLAtt));
+
+        memset (newa, 0, sizeof(*newa));
+        newString(&newa->name);
+        newString(&newa->valu);
+        newa->ce = ep;
+
+        ep->at = (XMLAtt **) moremem (ep->at, (ep->nat+1)*sizeof(XMLAtt *));
+        ep->at[ep->nat++] = newa;
+
+        return (newa);
 }
 
@@ -954,9 +1003,9 @@
 freeAtt (XMLAtt *a)
 {
-	if (!a)
-	    return;
-	freeString (&a->name);
-	freeString (&a->valu);
-	(*myfree)(a);
+        if (!a)
+            return;
+        freeString (&a->name);
+        freeString (&a->valu);
+        (*myfree)(a);
 }
 
@@ -965,6 +1014,6 @@
 resetEndTag(LilXML *lp)
 {
-	freeString (&lp->endtag);
-	newString (&lp->endtag);
+        freeString (&lp->endtag);
+        newString (&lp->endtag);
 }
 
@@ -975,5 +1024,5 @@
 isTokenChar (int start, int c)
 {
-	return (isalpha(c) || c == '_' || (!start && isdigit(c)));
+        return (isalpha(c) || c == '_' || (!start && isdigit(c)));
 }
 
@@ -982,15 +1031,15 @@
 growString (String *sp, int c)
 {
-	int l = sp->sl + 2;		/* need room for '\0' plus c */
-
-	if (l > sp->sm) {
-	    if (!sp->s)
-		newString (sp);
-	    else
-		sp->s = (char *) moremem (sp->s, sp->sm *= 2);
-	}
-	sp->s[--l] = '\0';
-	sp->s[--l] = (char)c;
-	sp->sl++;
+        int l = sp->sl + 2;		/* need room for '\0' plus c */
+
+        if (l > sp->sm) {
+            if (!sp->s)
+                newString (sp);
+            else
+                sp->s = (char *) moremem (sp->s, sp->sm *= 2);
+        }
+        sp->s[--l] = '\0';
+        sp->s[--l] = (char)c;
+        sp->sl++;
 }
 
@@ -999,15 +1048,15 @@
 appendString (String *sp, const char *str)
 {
-	int strl = strlen (str);
-	int l = sp->sl + strl + 1;	/* need room for '\0' */
-
-	if (l > sp->sm) {
-	    if (!sp->s)
-		newString (sp);
-	    if (l > sp->sm)
-		sp->s = (char *) moremem (sp->s, (sp->sm = l));
-	}
-	strcpy (&sp->s[sp->sl], str);
-	sp->sl += strl;		
+        int strl = strlen (str);
+        int l = sp->sl + strl + 1;	/* need room for '\0' */
+
+        if (l > sp->sm) {
+            if (!sp->s)
+                newString (sp);
+            if (l > sp->sm)
+                sp->s = (char *) moremem (sp->s, (sp->sm = l));
+        }
+        strcpy (&sp->s[sp->sl], str);
+        sp->sl += strl;
 }
 
@@ -1016,8 +1065,8 @@
 newString(String *sp)
 {
-	sp->s = (char *)moremem(NULL, MINMEM);
-	sp->sm = MINMEM;
-	*sp->s = '\0';
-	sp->sl = 0;
+        sp->s = (char *)moremem(NULL, MINMEM);
+        sp->sm = MINMEM;
+        *sp->s = '\0';
+        sp->sl = 0;
 }
 
@@ -1026,9 +1075,9 @@
 freeString (String *sp)
 {
-	if (sp->s)
-	    (*myfree) (sp->s);
-	sp->s = NULL;
-	sp->sl = 0;
-	sp->sm = 0;
+        if (sp->s)
+            (*myfree) (sp->s);
+        sp->s = NULL;
+        sp->sl = 0;
+        sp->sm = 0;
 }
 
@@ -1037,5 +1086,5 @@
 moremem (void *old, int n)
 {
-	return (old ? (*myrealloc)(old, n) : (*mymalloc)(n));
+        return (old ? (*myrealloc)(old, n) : (*mymalloc)(n));
 }
 
@@ -1044,37 +1093,36 @@
 main (int ac, char *av[])
 {
-	LilXML *lp = newLilXML();
-	char errmsg[1024];
-	XMLEle *root;
-
-	root = readXMLFile (stdin, lp, errmsg);
-	if (root) {
-	    char *str;
-	    int l;
-
-	    if (ac > 1) {
-		XMLEle *theend = addXMLEle (root, "theend");
-		editXMLEle (theend, "Added to test editing");
-		addXMLAtt (theend, "hello", "world");
-	    }
-
-	    fprintf (stderr, "::::::::::::: %s\n", tagXMLEle(root));
-	    prXMLEle (stdout, root, 0);
-
-	    l = sprlXMLEle (root, 0);
-	    str = malloc (l+1);
-	    fprintf (stderr, "::::::::::::: %s : %d : %d",
-				tagXMLEle(root), l, sprXMLEle (str, root, 0));
-	    fprintf (stderr, ": %d\n", printf ("%s", str));
-
-	    delXMLEle (root);
-	} else if (errmsg[0]) {
-	    fprintf (stderr, "Error: %s\n", errmsg);
-	}
-
-	delLilXML (lp);
-
-	return (0);
+        LilXML *lp = newLilXML();
+        char ynot[1024];
+        XMLEle *root;
+
+        root = readXMLFile (stdin, lp, ynot);
+        if (root) {
+            char *str;
+            int l;
+
+            if (ac > 1) {
+                XMLEle *theend = addXMLEle (root, "theend");
+                editXMLEle (theend, "Added to test editing");
+                addXMLAtt (theend, "hello", "world");
+            }
+
+            fprintf (stderr, "::::::::::::: %s\n", tagXMLEle(root));
+            prXMLEle (stdout, root, 0);
+
+            l = sprlXMLEle (root, 0);
+            str = malloc (l+1);
+            fprintf (stderr, "::::::::::::: %s : %d : %d",
+                                tagXMLEle(root), l, sprXMLEle (str, root, 0));
+            fprintf (stderr, ": %d\n", printf ("%s", str));
+
+            delXMLEle (root);
+        } else if (ynot[0]) {
+            fprintf (stderr, "Error: %s\n", ynot);
+        }
+
+        delLilXML (lp);
+
+        return (0);
 }
 #endif
-
Index: /BAORadio/libindi/libindi/libs/webcam/port.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/webcam/port.cpp	(revision 641)
+++ /BAORadio/libindi/libindi/libs/webcam/port.cpp	(revision 642)
@@ -38,11 +38,18 @@
 #include <sys/stat.h>
 #endif /* LOCKING */
-
 #ifdef __linux__
-  #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
+#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) \
+	|| defined(__powerpc__) || defined(__s390__) || defined(__s390x__)\
+	|| defined(__mips__) || defined(__mc68000__) || defined(__sh__)
+#define NO_SYSIO
+#endif /* architechtures */
+#endif /* __linux__ */
+
+#ifdef __linux__
+  #if defined(NO_SYSIO)
   #include <fcntl.h>
   #else
   #include <sys/io.h>
-  #endif /* arm */
+  #endif /* NO_SYSIO */
 #elif defined(QNX)
 #include <conio.h>
@@ -77,5 +84,5 @@
 
 #ifdef LINUX
-#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
+#ifdef NO_SYSIO
   if ((devport = open("/dev/port", O_RDWR)) < 0) {
     perror("open /dev/port");
@@ -87,5 +94,5 @@
     return;
   }
-#endif /* arm */
+#endif /* NO_SYSIO */
 #elif defined(FREEBSD)
   if ((devio = fopen("/dev/io", "r+")) == NULL) {
@@ -121,5 +128,5 @@
 #endif /* LOCKING */
 #ifdef LINUX
-#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
+#ifdef NO_SYSIO
   if (devport >= 0)
     close(devport);
@@ -129,5 +136,5 @@
                                   // be root
       perror("ioperm()");
-#endif /* arm */
+#endif /* NO_SYSIO */
 #elif defined(FREEBSD)
   if (devio != NULL)
Index: /BAORadio/libindi/libindi/tools/compiler.c
===================================================================
--- /BAORadio/libindi/libindi/tools/compiler.c	(revision 641)
+++ /BAORadio/libindi/libindi/tools/compiler.c	(revision 642)
@@ -267,7 +267,7 @@
 next_token ()
 {
-	static char toomv[] = "More than %d variables";
-	static char toomc[] = "More than %d constants";
-	static char badop[] = "Illegal operator";
+	static const char toomv[] = "More than %d variables";
+	static const char toomc[] = "More than %d constants";
+	static const char badop[] = "Illegal operator";
 	int tok = ERR;	/* just something illegal */
 	char c;
@@ -295,13 +295,13 @@
 	case '|':
 	    if (*cexpr == '|') { cexpr++; tok = OR; }
-	    else { (void) sprintf (err_msg, badop); return (ERR); }
+            else { (void) strcpy (err_msg, badop); return (ERR); }
 	    break;
 	case '&':
 	    if (*cexpr == '&') { cexpr++; tok = AND; }
-	    else { (void) sprintf (err_msg, badop); return (ERR); }
+            else { (void) strcpy (err_msg, badop); return (ERR); }
 	    break;
 	case '=':
 	    if (*cexpr == '=') { cexpr++; tok = EQ; }
-	    else { (void) sprintf (err_msg, badop); return (ERR); }
+            else { (void) strcpy (err_msg, badop); return (ERR); }
 	    break;
 	case '!':
Index: /BAORadio/libindi/libindi/tools/evalINDI.c
===================================================================
--- /BAORadio/libindi/libindi/tools/evalINDI.c	(revision 641)
+++ /BAORadio/libindi/libindi/tools/evalINDI.c	(revision 642)
@@ -347,6 +347,6 @@
 {
 	char *t = tagXMLEle (root);
-	char *d = findXMLAttValu (root, "device");
-	char *n = findXMLAttValu (root, "name");
+        const char *d = findXMLAttValu (root, "device");
+        const char *n = findXMLAttValu (root, "name");
 	int nset = 0;
 	double v;
@@ -397,5 +397,5 @@
 
 	/* check special elements */
-	t = findXMLAttValu (root, "state");
+        t = (char *) findXMLAttValu (root, "state");
 	if (t[0]) {
 	    sprintf (prop, "%s.%s._STATE", d, n);
@@ -407,5 +407,5 @@
 	    }
 	}
-	t = findXMLAttValu (root, "timestamp");
+        t = (char *) findXMLAttValu (root, "timestamp");
 	if (t[0]) {
 	    sprintf (prop, "%s.%s._TS", d, n);
Index: /BAORadio/libindi/libindi/tools/getINDIproperty.c
===================================================================
--- /BAORadio/libindi/libindi/tools/getINDIproperty.c	(revision 641)
+++ /BAORadio/libindi/libindi/tools/getINDIproperty.c	(revision 642)
@@ -446,13 +446,13 @@
 		if (strcmp (tagXMLEle (root), defs[j].vec) == 0) {
 		    /* legal defXXXVector, check device */
-		    char *dev = findXMLAttValu (root, "device");
+                    char *dev = (char *) findXMLAttValu (root, "device");
 		    char *idev = srchs[i].d;
 		    if (idev[0] == WILDCARD || !strcmp (dev,idev)) {
 			/* found device, check name */
-			char *nam = findXMLAttValu (root, "name");
+                        char *nam = (char *) findXMLAttValu (root, "name");
 			char *iprop = srchs[i].p;
 			if (iprop[0] == WILDCARD || !strcmp (nam,iprop)) {
 			    /* found device and name, check perm */
-			    char *perm = findXMLAttValu (root, "perm");
+                            char *perm = (char *) findXMLAttValu (root, "perm");
 			    if (!wflag && perm[0] && !strchr (perm, 'r')) {
 				if (verbose)
@@ -491,5 +491,5 @@
 	    if (strcmp (iele, kwattr[i].keyword) == 0) {
 		/* just print the property state, not the element values */
-		char *s = findXMLAttValu (root, kwattr[i].indiattr);
+                char *s = (char *) findXMLAttValu (root, kwattr[i].indiattr);
 		sp->ok = 1;   			/* progress */
 		if (onematch && justvalue)
@@ -505,5 +505,5 @@
 	    if (!strcmp (tagXMLEle (ep), defone)) {
 		/* legal defXXX, check deeper */
-		char *enam = findXMLAttValu (ep, "name");
+                char *enam = (char *) findXMLAttValu (ep, "name");
 		if (iele[0]==WILDCARD || !strcmp(enam,iele)) {
 		    /* found it! */
@@ -556,5 +556,5 @@
 
 	/* get format and length */
-	format = findXMLAttValu (root, "format");
+        format = (char *) findXMLAttValu (root, "format");
 	isz = !strcmp (&format[strlen(format)-2], ".z");
 
Index: /BAORadio/libindi/libindi/tools/setINDIproperty.c
===================================================================
--- /BAORadio/libindi/libindi/tools/setINDIproperty.c	(revision 641)
+++ /BAORadio/libindi/libindi/tools/setINDIproperty.c	(revision 642)
@@ -419,6 +419,6 @@
 
 	/* check each set for matching device and property name, send if ok */
-	rdev  = findXMLAttValu (root, "device");
-	rprop = findXMLAttValu (root, "name");
+        rdev  = (char *) findXMLAttValu (root, "device");
+        rprop = (char *) findXMLAttValu (root, "name");
 	if (verbose > 1)
 	    fprintf (stderr, "Read definition for %s.%s\n", rdev, rprop);
