INDI Alignment Layer  0.0
AlignmentLayer.cpp
00001 #include "AlignmentLayer.h"
00002 #include "config.h"
00003 #include <memory>
00004 #include <cstdlib>
00005 #include <sstream>
00006 #include <sys/stat.h>
00007 
00008 // We declare an auto pointer to ScopeSim.
00009 std::auto_ptr<CAlignmentLayer> AlignmentLayer(0);
00010 
00011 void ISInit()
00012 {
00013     static int isInit =0;
00014 
00015     if (isInit == 1)
00016        return;
00017 
00018     isInit = 1;
00019     if(AlignmentLayer.get() == 0) AlignmentLayer.reset(new CAlignmentLayer);
00020 }
00021 
00022 void ISGetProperties(const char *dev)
00023 {
00024     ISInit();
00025     AlignmentLayer->ISGetProperties(dev);
00026 }
00027 
00028 void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
00029 {
00030     ISInit();
00031     AlignmentLayer->ISNewNumber(dev, name, values, names, num);
00032 }
00033 
00034 void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
00035 {
00036     ISInit();
00037     AlignmentLayer->ISNewSwitch(dev, name, states, names, num);
00038 }
00039 
00040 void ISNewText( const char *dev, const char *name, char *texts[], char *names[], int num)
00041 {
00042     ISInit();
00043     AlignmentLayer->ISNewText(dev, name, texts, names, num);
00044 }
00045 
00046 void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
00047 {
00048     ISInit();
00049     AlignmentLayer->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
00050 }
00051 
00052 void ISSnoopDevice (XMLEle *root)
00053 {
00054     INDI_UNUSED(root);
00055 }
00056 
00057 CAlignmentLayer::CAlignmentLayer()
00058 {
00059     pLowerLayerDevice = NULL;
00060 }
00061 
00062 bool CAlignmentLayer::initProperties()
00063 {
00064     if (INDI::DefaultDevice::initProperties())
00065     {
00066         // Remove the CONNECTION property
00067         char errmsg[MAXRBUF];
00068         INDI::DefaultDevice::removeProperty("CONNECTION", errmsg);
00069 
00070         std::stringstream SkeletonPath;
00071         SkeletonPath << INDI_DATA_DIR << "/indi_alignment_layer_sk.xml";
00072 
00073         struct stat st;
00074         if (stat(SkeletonPath.str().c_str(), &st) == 0)
00075             buildSkeleton(SkeletonPath.str().c_str());
00076         else
00077         {
00078             IDLog("No skeleton file was specified\n");
00079             return false;
00080         }
00081         ISwitch *pSwitch = IUFindOnSwitch(getSwitch("LOWER_UNITS"));
00082         if (!strcmp(pSwitch->name, "HOURS_DEGREES"))
00083             AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::HOURS_DEGREES);
00084         else if (!strcmp(pSwitch->name, "DEGREES_DEGREES"))
00085             AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::DEGREES_DEGREES);
00086         else if (!strcmp(pSwitch->name, "RADIANS_RADIANS"))
00087             AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::RADIANS_RADIANS);
00088         return true;
00089     }
00090     else
00091         return false;
00092 }
00093 
00094 void CAlignmentLayer::ISGetProperties (const char *dev)
00095 {
00096     INDI::DefaultDevice::ISGetProperties (dev);
00097 }
00098 
00099 // Upper to lower property communication routines
00100 
00101 bool CAlignmentLayer::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
00102 {
00103     //  first check if it's for our device
00104     IDLog("CAlignmentLayer::ISNewNumber %s\n",name);
00105     if(strcmp(dev,getDeviceName())==0)
00106     {
00107         INumberVectorProperty *pUpperLayerNumber = getNumber(name);
00108         INumberVectorProperty *pLowerLayerNumber = (NULL == pLowerLayerDevice) ? NULL : pLowerLayerDevice->getNumber(name);
00109 #ifdef DUAL_MAPPING
00110         ITextVectorProperty *pDownwardMapping = getText("DOWNWARD_MAPPING");
00111 #else
00112         ITextVectorProperty *pCoordinateMapping = getText("COORDINATE_MAPPING");
00113 #endif
00114         if ((strcmp(name, "NEW_ALIGNMENT_POINT") == 0) && (NULL != pUpperLayerNumber))
00115         {
00116             IUUpdateNumber(pUpperLayerNumber, values, names, n);
00117             pUpperLayerNumber->s = IPS_OK;
00118             IDSetNumber(pUpperLayerNumber, NULL);
00119             AlignmentDatabase.AddAlignmentPoint(pUpperLayerNumber->np[0].value, pUpperLayerNumber->np[1].value, pUpperLayerNumber->np[2].value,
00120                                                 pUpperLayerNumber->np[3].value, pUpperLayerNumber->np[4].value);
00121         }
00122 #ifdef DUAL_MAPPING
00123         else if ((NULL != pDownwardMapping) && (strcmp(name, pDownwardMapping->tp[0].text) == 0)
00124                     && (NULL != pUpperLayerNumber) && (NULL != (pLowerLayerNumber = pLowerLayerDevice->getNumber(pDownwardMapping->tp[1].text))))
00125 #else
00126         else if ((NULL != pCoordinateMapping) && (strcmp(name, pCoordinateMapping->tp[0].text) == 0)
00127                     && (NULL != pUpperLayerNumber) && (NULL != (pLowerLayerNumber = pLowerLayerDevice->getNumber(pCoordinateMapping->tp[1].text))))
00128 #endif
00129         {
00130             IUUpdateNumber(pUpperLayerNumber, values, names, n);
00131             AlignmentDatabase.TransformUpperToLower(pUpperLayerNumber->np[0].value, pUpperLayerNumber->np[1].value,
00132                                                     pLowerLayerNumber->np[0].value, pLowerLayerNumber->np[1].value);
00133             sendNewNumber(pLowerLayerNumber);
00134         }
00135         else if ((NULL != pLowerLayerNumber) && (NULL != pUpperLayerNumber))
00136         {
00137             IUUpdateNumber(pUpperLayerNumber, values, names, n);
00138             // Map the number across
00139             IUUpdateNumber(pLowerLayerNumber, values, names, n);
00140             sendNewNumber(pLowerLayerNumber);
00141             return true;
00142         }
00143         else
00144             return false;
00145     }
00146     else
00147         return INDI::DefaultDevice::ISNewNumber(dev,name,values,names,n);
00148 }
00149 
00150 bool CAlignmentLayer::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
00151 {
00152     IDLog("CAlignmentLayer::ISNewSwitch %s\n",name);
00153     if(strcmp(dev,getDeviceName())==0)
00154     {
00155         ISwitchVectorProperty *pUpperLayerSwitch = getSwitch(name);
00156         ISwitchVectorProperty *pLowerLayerSwitch = (NULL == pLowerLayerDevice) ? NULL : pLowerLayerDevice->getSwitch(name);
00157         if(strcmp(name,"LAYERING")==0)
00158         {
00159             IUUpdateSwitch(pUpperLayerSwitch, states, names, n);
00160             ISwitch *pSwitch = IUFindOnSwitch(pUpperLayerSwitch);
00161             if (!strcmp(pSwitch->name, "ASSOCIATE"))
00162             {
00163                 // Associate
00164                 // Connect as client to lower layer driver
00165                 setServer("localhost", 7624);
00166                 watchDevice(getText("LOWER_LAYER")->tp[0].text);
00167                 connectServer();
00168             }
00169             else
00170             {
00171                 // Disassociate
00172                 disconnectServer();
00173             }
00174             pUpperLayerSwitch->s = IPS_OK;
00175             IDSetSwitch(pUpperLayerSwitch, NULL);
00176             return true;
00177         }
00178         else if(strcmp(name,"LOWER_UNITS")==0)
00179         {
00180             IUUpdateSwitch(pUpperLayerSwitch, states, names, n);
00181             ISwitch *pSwitch = IUFindOnSwitch(pUpperLayerSwitch);
00182             if (!strcmp(pSwitch->name, "HOURS_DEGREES"))
00183                 AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::HOURS_DEGREES);
00184             else if (!strcmp(pSwitch->name, "DEGREES_DEGREES"))
00185                 AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::DEGREES_DEGREES);
00186             else if (!strcmp(pSwitch->name, "RADIANS_RADIANS"))
00187                 AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::RADIANS_RADIANS);
00188             pUpperLayerSwitch->s = IPS_OK;
00189             IDSetSwitch(pUpperLayerSwitch, NULL);
00190             return true;
00191         }
00192         else if(strcmp(name,"ALIGNMENT_POINTS_FILE_ACTION")==0)
00193         {
00194             IUUpdateSwitch(pUpperLayerSwitch, states, names, n);
00195             ISwitch *pSwitch = IUFindOnSwitch(pUpperLayerSwitch);
00196             std::stringstream FileName;
00197             FileName << getenv("HOME") << "/.indi/" << getText("ALIGNMENT_POINTS_FILENAME")->tp[0].text;
00198             if (!strcmp(pSwitch->name, "LOAD"))
00199                 AlignmentDatabase.Load(FileName.str());
00200             else if (!strcmp(pSwitch->name, "APPEND"))
00201                 AlignmentDatabase.Append(FileName.str());
00202             else if (!strcmp(pSwitch->name, "SAVE"))
00203                 AlignmentDatabase.Save(FileName.str());
00204             pUpperLayerSwitch->s = IPS_OK;
00205             IDSetSwitch(pUpperLayerSwitch, NULL);
00206             return true;
00207         }
00208         else if(strcmp(name,"CONFIG_PROCESS")==0)
00209         {
00210             // Trap configuration changes
00211             bool bRet = INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
00212             ISwitch *pSwitch = IUFindOnSwitch(getSwitch("LOWER_UNITS"));
00213             if (!strcmp(pSwitch->name, "HOURS_DEGREES"))
00214                 AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::HOURS_DEGREES);
00215             else if (!strcmp(pSwitch->name, "DEGREES_DEGREES"))
00216                 AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::DEGREES_DEGREES);
00217             else if (!strcmp(pSwitch->name, "RADIANS_RADIANS"))
00218                 AlignmentDatabase.SetLowerCoordinateSystemUnits(CAlignmentDatabase::RADIANS_RADIANS);
00219             return bRet;
00220         }
00221         else if ((NULL != pLowerLayerSwitch) && (NULL != pUpperLayerSwitch))
00222         {
00223             IUUpdateSwitch(pUpperLayerSwitch, states, names, n);
00224             // Map the switch across
00225             IUUpdateSwitch(pLowerLayerSwitch, states, names, n);
00226             sendNewSwitch(pLowerLayerSwitch);
00227             return true;
00228         }
00229         else
00230             return false;
00231     }
00232     else
00233         return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
00234 }
00235 
00236 bool CAlignmentLayer::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
00237 {
00238     IDLog("CAlignmentLayer::ISNewText %s\n",name);
00239     if(strcmp(dev,getDeviceName())==0)
00240     {
00241         ITextVectorProperty *pUpperLayerText = getText(name);
00242         ITextVectorProperty *pLowerLayerText = (NULL == pLowerLayerDevice) ? NULL : pLowerLayerDevice->getText(name);
00243         if(strcmp(name,"LOWER_LAYER")==0)
00244         {
00245             IUUpdateText(pUpperLayerText, texts, names, n);
00246             pUpperLayerText->s = IPS_OK;
00247             IDSetText(pUpperLayerText, NULL);
00248         }
00249 #ifdef DUAL_MAPPING
00250         else if(strcmp(name,"DOWNWARD_MAPPING")==0)
00251         {
00252             IUUpdateText(pUpperLayerText, texts, names, n);
00253             pUpperLayerText->s = IPS_OK;
00254             IDSetText(pUpperLayerText, NULL);
00255         }
00256         else if(strcmp(name,"UPWARD_MAPPING")==0)
00257         {
00258             IUUpdateText(pUpperLayerText, texts, names, n);
00259             pUpperLayerText->s = IPS_OK;
00260             IDSetText(pUpperLayerText, NULL);
00261         }
00262 #else
00263         else if(strcmp(name,"COORDINATE_MAPPING")==0)
00264         {
00265             IUUpdateText(pUpperLayerText, texts, names, n);
00266             pUpperLayerText->s = IPS_OK;
00267             IDSetText(pUpperLayerText, NULL);
00268         }
00269 #endif
00270         else if(strcmp(name,"ALIGNMENT_POINTS_FILENAME")==0)
00271         {
00272             IUUpdateText(pUpperLayerText, texts, names, n);
00273             pUpperLayerText->s = IPS_OK;
00274             IDSetText(pUpperLayerText, NULL);
00275         }
00276         else if ((NULL != pLowerLayerText) && (NULL != pUpperLayerText))
00277         {
00278             IUUpdateText(pUpperLayerText, texts, names, n);
00279             // Map the text across
00280             IUUpdateText(pLowerLayerText, texts, names, n);
00281             sendNewText(pLowerLayerText);
00282             return true;
00283         }
00284         else
00285             return false;
00286     }
00287     else
00288         return INDI::DefaultDevice::ISNewText (dev, name, texts, names, n);
00289 }
00290 
00291 bool CAlignmentLayer::ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
00292 {
00293     IDLog("CAlignmentLayer::ISNewBLOB %s\n",name);
00294     if(strcmp(dev,getDeviceName())==0)
00295     {
00296         IBLOBVectorProperty *pUpperLayerBLOB = getBLOB(name);
00297         IBLOBVectorProperty *pLowerLayerBLOB = (NULL == pLowerLayerDevice) ? NULL : pLowerLayerDevice->getBLOB(name);
00298         if ((NULL != pLowerLayerBLOB) && (NULL != pUpperLayerBLOB))
00299         {
00300             IUUpdateBLOB(pUpperLayerBLOB, sizes, blobsizes, blobs, formats, names, n);
00301             // Map the BLOB across
00302             IUUpdateBLOB(pLowerLayerBLOB, sizes, blobsizes, blobs, formats, names, n);
00303             // TODO - handle BLOBS
00304             //sendNewBLOB(pLowerLayerBLOB);
00305             return true;
00306         }
00307         else
00308             return false;
00309     }
00310     else
00311     return INDI::DefaultDevice::ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
00312 }
00313 
00314 
00315 // Lower to upper property communication routines
00316 
00317 void CAlignmentLayer::newDevice(INDI::BaseDevice *dp)
00318 {
00319     IDLog("CAlignmentLayer::newDevice %s\n", dp->getDeviceName());
00320     // Watch filter should ensure I do not see notifications other than the one I want
00321     pLowerLayerDevice = dp;
00322 }
00323 
00324 void CAlignmentLayer::newProperty(INDI::Property *property)
00325 {
00326     IDLog("CAlignmentLayer::newProperty %s dynamic %d\n", property->getName(), property->isDynamic());
00327     // Register property with upper client
00328     switch(property->getType())
00329     {
00330         case INDI_NUMBER:
00331         {
00332             INumberVectorProperty *pUpperLayerNumber = new INumberVectorProperty;
00333             INumberVectorProperty *pLowerLayerNumber = property->getNumber();
00334             *pUpperLayerNumber = *pLowerLayerNumber;
00335             strncpy(pUpperLayerNumber->device, getDeviceName(), MAXINDIDEVICE);
00336             pUpperLayerNumber->np = (INumber*)malloc(sizeof(INumber) * pLowerLayerNumber->nnp);
00337             for (int i = 0; i < pLowerLayerNumber->nnp; i++)
00338             {
00339                 pUpperLayerNumber->np[i] = pLowerLayerNumber->np[i];
00340                 pUpperLayerNumber->np[i].nvp = pUpperLayerNumber;
00341             }
00342             defineNumber(pUpperLayerNumber);
00343             break;
00344         }
00345         case INDI_SWITCH:
00346         {
00347             ISwitchVectorProperty *pUpperLayerSwitch = new ISwitchVectorProperty;
00348             ISwitchVectorProperty *pLowerLayerSwitch = property->getSwitch();
00349             *pUpperLayerSwitch = *pLowerLayerSwitch;
00350             strncpy(pUpperLayerSwitch->device, getDeviceName(), MAXINDIDEVICE);
00351             pUpperLayerSwitch->sp = (ISwitch*)malloc(sizeof(ISwitch) * pLowerLayerSwitch->nsp);
00352             for (int i = 0; i < pLowerLayerSwitch->nsp; i++)
00353             {
00354                 pUpperLayerSwitch->sp[i] = pLowerLayerSwitch->sp[i];
00355                 pUpperLayerSwitch->sp[i].svp = pUpperLayerSwitch;
00356             }
00357             defineSwitch(pUpperLayerSwitch);
00358             break;
00359         }
00360         case INDI_TEXT:
00361         {
00362             // TODO At the moment this code does not duplicate the actual text strings
00363             ITextVectorProperty *pUpperLayerText = new ITextVectorProperty;
00364             ITextVectorProperty *old_tvp = property->getText();
00365             *pUpperLayerText = *old_tvp;
00366             strncpy(pUpperLayerText->device, getDeviceName(), MAXINDIDEVICE);
00367             pUpperLayerText->tp = (IText*)malloc(sizeof(IText) * old_tvp->ntp);
00368             for (int i = 0; i < old_tvp->ntp; i++)
00369             {
00370                 pUpperLayerText->tp[i] = old_tvp->tp[i];
00371                 pUpperLayerText->tp[i].tvp = pUpperLayerText;
00372             }
00373             defineText(pUpperLayerText);
00374             break;
00375         }
00376         case INDI_LIGHT:
00377         {
00378             ILightVectorProperty *pUpperLayerLight = new ILightVectorProperty;
00379             ILightVectorProperty *pLowerLayerLight = property->getLight();
00380             *pUpperLayerLight = *pLowerLayerLight;
00381             strncpy(pUpperLayerLight->device, getDeviceName(), MAXINDIDEVICE);
00382             pUpperLayerLight->lp = (ILight*)malloc(sizeof(ILight) * pLowerLayerLight->nlp);
00383             for (int i = 0; i < pLowerLayerLight->nlp; i++)
00384             {
00385                 pUpperLayerLight->lp[i] = pLowerLayerLight->lp[i];
00386                 pUpperLayerLight->lp[i].lvp = pUpperLayerLight;
00387             }
00388             defineLight(pUpperLayerLight);
00389             break;
00390         }
00391         case INDI_BLOB:
00392         {
00393             // TODO At the moment this code does not duplicate the actual BLOB bytes
00394             IBLOBVectorProperty *pUpperLayerBLOB = new IBLOBVectorProperty;
00395             IBLOBVectorProperty *pLowerLayerBLOB = property->getBLOB();
00396             *pUpperLayerBLOB = *pLowerLayerBLOB;
00397             strncpy(pUpperLayerBLOB->device, getDeviceName(), MAXINDIDEVICE);
00398             pUpperLayerBLOB->bp = (IBLOB*)malloc(sizeof(IBLOB) * pLowerLayerBLOB->nbp);
00399             for (int i = 0; i < pLowerLayerBLOB->nbp; i++)
00400             {
00401                 pUpperLayerBLOB->bp[i] = pLowerLayerBLOB->bp[i];
00402                 pUpperLayerBLOB->bp[i].bvp = pUpperLayerBLOB;
00403             }
00404             defineBLOB(pUpperLayerBLOB);
00405             break;
00406         }
00407     }
00408 
00409 }
00410 
00411 void CAlignmentLayer::removeProperty(INDI::Property *property)
00412 {
00413     IDLog("CAlignmentLayer::removeProperty %s\n", property->getName());
00414     INDI::Property *pProperty = getProperty(property->getName());
00415     if (NULL != pProperty)
00416     {
00417         INDI_TYPE Type = pProperty->getType();
00418         // Clean up any allocated memory
00419         switch (Type)
00420         {
00421             case INDI_NUMBER:
00422             {
00423                 INumberVectorProperty *pUpperLayerNumber = pProperty->getNumber();
00424                 if (NULL != pUpperLayerNumber->np);
00425                     free(pUpperLayerNumber->np);
00426                 break;
00427             }
00428             case INDI_SWITCH:
00429             {
00430                 ISwitchVectorProperty *pUpperLayerSwitch = pProperty->getSwitch();
00431                 if (NULL != pUpperLayerSwitch->sp);
00432                     free(pUpperLayerSwitch->sp);
00433                 break;
00434             }
00435             case INDI_TEXT:
00436             {
00437                 // TODO At the moment this code does not duplicate the actual text strings
00438                 ITextVectorProperty *pUpperLayerText = pProperty->getText();
00439                 if (NULL != pUpperLayerText->tp);
00440                     free(pUpperLayerText->tp);
00441                 break;
00442             }
00443             case INDI_LIGHT:
00444             {
00445                 ILightVectorProperty *pUpperLayerLight = pProperty->getLight();
00446                 if (NULL != pUpperLayerLight->lp);
00447                     free(pUpperLayerLight->lp);
00448                 break;
00449             }
00450             case INDI_BLOB:
00451             {
00452                 // TODO At the moment this code does not duplicate the actual BLOB bytes
00453                 IBLOBVectorProperty *pUpperLayerBLOB = pProperty->getBLOB();
00454                 if (NULL != pUpperLayerBLOB->bp);
00455                     free(pUpperLayerBLOB->bp);
00456                 break;
00457             }
00458         }
00459         deleteProperty(pProperty->getName());
00460     }
00461 }
00462 
00463 void CAlignmentLayer::newBLOB(IBLOB *bp)
00464 {
00465     IDLog("CAlignmentLayer::newBLOB %s\n", bp->name);
00466     // TODO work out how to do this
00467 }
00468 
00469 void CAlignmentLayer::newSwitch(ISwitchVectorProperty *svp)
00470 {
00471     IDLog("CAlignmentLayer::newSwitch %s\n", svp->name);
00472     // Send the new switch up to the upper layer
00473     ISwitchVectorProperty *pUpperLayerSwitch = getSwitch(svp->name);
00474     ISwitchVectorProperty *pLowerLayerSwitch = svp;
00475     *pUpperLayerSwitch = *pLowerLayerSwitch;
00476     strncpy(pUpperLayerSwitch->device, getDeviceName(), MAXINDIDEVICE);
00477     if (pLowerLayerSwitch->nsp != pUpperLayerSwitch->nsp)
00478         pUpperLayerSwitch->sp = (ISwitch*)realloc((void*)pUpperLayerSwitch, sizeof(ISwitch) * pLowerLayerSwitch->nsp);
00479     for (int i = 0; i < pLowerLayerSwitch->nsp; i++)
00480     {
00481         pUpperLayerSwitch->sp[i] = pLowerLayerSwitch->sp[i];
00482         pUpperLayerSwitch->sp[i].svp = pUpperLayerSwitch;
00483     }
00484     IDSetSwitch(pUpperLayerSwitch, NULL);
00485 }
00486 
00487 void CAlignmentLayer::newNumber(INumberVectorProperty *nvp)
00488 {
00489     IDLog("CAlignmentLayer::newNumber %s\n", nvp->name);
00490     // Send the new number up to the upper layer
00491 #ifdef DUAL_MAPPING
00492     ITextVectorProperty *pUpwardMapping = getText("UPWARD_MAPPING");
00493 #else
00494     ITextVectorProperty *pCoordinateMapping = getText("COORDINATE_MAPPING");
00495 #endif
00496     INumberVectorProperty *pUpperLayerNumber = getNumber(nvp->name);
00497     INumberVectorProperty *pLowerLayerNumber = nvp;
00498 #ifdef DUAL_MAPPING
00499     if ((NULL != pUpwardMapping) && (strcmp(nvp->name, pUpwardMapping->tp[1].text) == 0)
00500          && (NULL != pLowerLayerNumber) && (NULL != (pUpperLayerNumber = getNumber(pUpwardMapping->tp[0].text))))
00501 #else
00502     if ((NULL != pCoordinateMapping) && (strcmp(nvp->name, pCoordinateMapping->tp[1].text) == 0)
00503          && (NULL != pLowerLayerNumber) && (NULL != (pUpperLayerNumber = getNumber(pCoordinateMapping->tp[0].text))))
00504 #endif
00505     {
00506         AlignmentDatabase.TransformLowerToUpper(pLowerLayerNumber->np[0].value, pLowerLayerNumber->np[1].value,
00507                                                 pUpperLayerNumber->np[0].value, pUpperLayerNumber->np[1].value);
00508         IDSetNumber(pUpperLayerNumber, NULL);
00509     }
00510     else if ((NULL != pLowerLayerNumber) && (NULL != pUpperLayerNumber))
00511     {
00512         *pUpperLayerNumber = *pLowerLayerNumber;
00513         strncpy(pUpperLayerNumber->device, getDeviceName(), MAXINDIDEVICE);
00514         if (pLowerLayerNumber->nnp != pUpperLayerNumber->nnp)
00515             pUpperLayerNumber->np = (INumber*)realloc((void*)pUpperLayerNumber, sizeof(INumber) * pLowerLayerNumber->nnp);
00516         for (int i = 0; i < pLowerLayerNumber->nnp; i++)
00517         {
00518             pUpperLayerNumber->np[i] = pLowerLayerNumber->np[i];
00519             pUpperLayerNumber->np[i].nvp = pUpperLayerNumber;
00520         }
00521         IDSetNumber(pUpperLayerNumber, NULL);
00522     }
00523 }
00524 
00525 void CAlignmentLayer::newMessage(INDI::BaseDevice *dp, int messageID)
00526 {
00527     IDLog("CAlignmentLayer::newMessage device %s messageID %d\n", dp->getDeviceName(), messageID);
00528 
00529 }
00530 
00531 void CAlignmentLayer::newText(ITextVectorProperty *tvp)
00532 {
00533     IDLog("CAlignmentLayer::newText %s\n", tvp->name);
00534     // Send the new number up to the upper layer
00535     ITextVectorProperty *pUpperLayerText = getText(tvp->name);
00536     ITextVectorProperty *pLowerLayerText = tvp;
00537     *pUpperLayerText = *pLowerLayerText;
00538     strncpy(pUpperLayerText->device, getDeviceName(), MAXINDIDEVICE);
00539     if (pLowerLayerText->ntp != pUpperLayerText->ntp)
00540         pUpperLayerText->tp = (IText*)realloc((void*)pUpperLayerText, sizeof(IText) * pLowerLayerText->ntp);
00541     for (int i = 0; i < pLowerLayerText->ntp; i++)
00542     {
00543         pUpperLayerText->tp[i] = pLowerLayerText->tp[i];
00544         pUpperLayerText->tp[i].tvp = pUpperLayerText;
00545     }
00546     IDSetText(pUpperLayerText, NULL);
00547 }
00548 
00549 void CAlignmentLayer::newLight(ILightVectorProperty *lvp)
00550 {
00551     IDLog("CAlignmentLayer::newLight %s\n", lvp->name);
00552     // Send the new kight up to the upper layer
00553     ILightVectorProperty *pUpperLayerLight = getLight(lvp->name);
00554     ILightVectorProperty *pLowerLayerLight = lvp;
00555     *pUpperLayerLight = *pLowerLayerLight;
00556     strncpy(pUpperLayerLight->device, getDeviceName(), MAXINDIDEVICE);
00557     if (pLowerLayerLight->nlp != pUpperLayerLight->nlp)
00558         pUpperLayerLight->lp = (ILight*)realloc((void*)pUpperLayerLight, sizeof(ILight) * pLowerLayerLight->nlp);
00559     for (int i = 0; i < pLowerLayerLight->nlp; i++)
00560     {
00561         pUpperLayerLight->lp[i] = pLowerLayerLight->lp[i];
00562         pUpperLayerLight->lp[i].lvp = pUpperLayerLight;
00563     }
00564     IDSetLight(pUpperLayerLight, NULL);
00565 }
00566 
00567 void CAlignmentLayer::serverConnected()
00568 {
00569     IDLog("CAlignmentLayer::serverConnected\n");
00570 
00571 }
00572 
00573 void CAlignmentLayer::serverDisconnected(int exit_code)
00574 {
00575     IDLog("CAlignmentLayer::serverDisconnected\n");
00576 
00577 }
00578 
00579