source: BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp @ 642

Last change on this file since 642 was 642, checked in by frichard, 12 years ago

-Alignement des antennes
-Version 0.0.9 de libindi

File size: 17.1 KB
Line 
1/*******************************************************************************
2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB.  If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17*******************************************************************************/
18
19#include <stdlib.h>
20#include <string.h>
21#include <errno.h>
22#include <zlib.h>
23
24#include "defaultdriver.h"
25#include "indicom.h"
26#include "base64.h"
27
28const char *COMMUNICATION_TAB = "Communication";
29const char *MAIN_CONTROL_TAB = "Main Control";
30const char *MOTION_TAB = "Motion Control";
31const char *DATETIME_TAB = "Date/Time";
32const char *SITE_TAB =  "Site Management";
33const char *OPTIONS_TAB = "Options";
34const char *FILTER_TAB = "Filter Wheel";
35const char *GUIDER_TAB = "Guide Wheel";
36
37void timerfunc(void *t)
38{
39    //fprintf(stderr,"Got a timer hit with %x\n",t);
40    INDI::DefaultDriver *devPtr = static_cast<INDI::DefaultDriver *> (t);
41    if (devPtr != NULL)
42    {
43        //  this was for my device
44        //  but we dont have a way of telling
45        //  WHICH timer was hit :(
46        devPtr->TimerHit();
47    }
48    return;
49}
50
51
52INDI::DefaultDriver::DefaultDriver()
53{
54    pDebug = false;
55    pSimulation = false;
56
57    //switchPtr conSw(new ISwitchVectorProperty);
58    ConnectionSP = new ISwitchVectorProperty;
59    DebugSP = NULL;
60    SimulationSP = NULL;
61    ConfigProcessSP = NULL;
62
63    IUFillSwitch(&ConnectionS[0],"CONNECT","Connect",ISS_OFF);
64    IUFillSwitch(&ConnectionS[1],"DISCONNECT","Disconnect",ISS_ON);
65    IUFillSwitchVector(ConnectionSP,ConnectionS,2,deviceName(),"CONNECTION","Connection","Main Control",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
66
67    registerProperty(ConnectionSP, PropertyContainer::INDI_SWITCH);
68
69}
70
71INDI::DefaultDriver::~DefaultDriver()
72{
73    delete ConnectionSP;
74    delete DebugSP;
75    delete SimulationSP;
76    delete ConfigProcessSP;
77}
78
79bool INDI::DefaultDriver::loadConfig()
80{
81    char errmsg[MAXRBUF];
82    bool pResult = false;
83
84    pResult = IUReadConfig(NULL, deviceID, errmsg) == 0 ? true : false;
85
86   if (pResult)
87       IDMessage(deviceID, "Configuration successfully loaded.\n");
88        else
89                IDMessage(deviceID,"Error loading configuration\n");
90
91   IUSaveDefaultConfig(NULL, NULL, deviceID);
92
93   return pResult;
94}
95
96bool INDI::DefaultDriver::saveConfigItems(FILE *fp)
97{
98    std::vector<PropertyContainer *>::iterator orderi;
99
100    PropertyContainer::INDI_TYPE pType;
101    void *pPtr;
102
103    ISwitchVectorProperty *svp=NULL;
104    INumberVectorProperty *nvp=NULL;
105    ITextVectorProperty   *tvp=NULL;
106    IBLOBVectorProperty   *bvp=NULL;
107
108    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
109    {
110
111        pType       = (*orderi)->getType();
112        pPtr        = (*orderi)->getProperty();
113
114        switch (pType)
115        {
116        case PropertyContainer::INDI_NUMBER:
117             nvp = static_cast<INumberVectorProperty *>(pPtr);
118             //IDLog("Trying to save config for number %s\n", nvp->name);
119             IUSaveConfigNumber(fp, nvp);
120             break;
121        case PropertyContainer::INDI_TEXT:
122             tvp = static_cast<ITextVectorProperty *>(pPtr);
123             IUSaveConfigText(fp, tvp);
124             break;
125        case PropertyContainer::INDI_SWITCH:
126             svp = static_cast<ISwitchVectorProperty *>(pPtr);
127             /* Never save CONNECTION property. Don't save switches with no switches on if the rule is one of many */
128             if (!strcmp(svp->name, "CONNECTION") || (svp->r == ISR_1OFMANY && !IUFindOnSwitch(svp)))
129                 continue;
130             IUSaveConfigSwitch(fp, svp);
131             break;
132        case PropertyContainer::INDI_BLOB:
133             bvp = static_cast<IBLOBVectorProperty *>(pPtr);
134             IUSaveConfigBLOB(fp, bvp);
135             break;
136        }
137    }
138        return true;
139}
140
141bool INDI::DefaultDriver::saveConfig()
142{
143    //std::vector<orderPtr>::iterator orderi;
144    char errmsg[MAXRBUF];
145
146    FILE *fp = NULL;
147
148    fp = IUGetConfigFP(NULL, deviceID, errmsg);
149
150    if (fp == NULL)
151    {
152        IDMessage(deviceID, "Error saving configuration. %s\n", errmsg);
153        return false;
154    }
155
156    IUSaveConfigTag(fp, 0);
157
158        saveConfigItems(fp);
159
160    IUSaveConfigTag(fp, 1);
161
162    fclose(fp);
163
164    IUSaveDefaultConfig(NULL, NULL, deviceID);
165
166    IDMessage(deviceID, "Configuration successfully saved.");
167
168    return true;
169}
170
171bool INDI::DefaultDriver::loadDefaultConfig()
172{
173    char configDefaultFileName[MAXRBUF];
174    char errmsg[MAXRBUF];
175    bool pResult = false;
176
177    if (getenv("INDICONFIG"))
178        snprintf(configDefaultFileName, MAXRBUF, "%s.default", getenv("INDICONFIG"));
179    else
180        snprintf(configDefaultFileName, MAXRBUF, "%s/.indi/%s_config.xml.default", getenv("HOME"), deviceID);
181
182    if (pDebug)
183        IDLog("Requesting to load default config with: %s\n", configDefaultFileName);
184
185    pResult = IUReadConfig(configDefaultFileName, deviceID, errmsg) == 0 ? true : false;
186
187    if (pResult)
188        IDMessage(deviceID, "Default configuration loaded.");
189    else
190        IDMessage(deviceID, "Error loading default configuraiton. %s", errmsg);
191
192    return pResult;
193}
194
195bool INDI::DefaultDriver::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
196{
197    // ignore if not ours //
198    if (strcmp (dev, deviceID))
199        return false;
200
201    ISwitchVectorProperty *svp = getSwitch(name);
202
203    if (!svp)
204        return false;
205
206     if(!strcmp(svp->name,ConnectionSP->name))
207     {
208        bool rc;
209       
210      for (int i=0; i < n; i++)
211      {
212        if ( !strcmp(names[i], "CONNECT") && (states[i] == ISS_ON))
213        {
214
215            // If not connected, attempt to connect
216            if (isConnected() == false)
217            {
218                rc = Connect();
219
220                // If connection is successful, set it thus
221                if (rc)
222                        setConnected(true, IPS_OK);
223                else
224                        setConnected(false, IPS_ALERT);
225
226
227                updateProperties();
228            }
229            else
230                // Just tell client we're connected yes
231                setConnected(true);
232        }
233        else if ( !strcmp(names[i], "DISCONNECT") && (states[i] == ISS_ON))
234        {
235            // If connected, then true to disconnect.
236            if (isConnected() == true)
237                rc = Disconnect();
238            else
239                rc = true;
240
241            if (rc)
242                setConnected(false, IPS_IDLE);
243            else
244                setConnected(true, IPS_ALERT);
245
246            updateProperties();
247        }
248    }
249
250        return true;
251    }
252
253
254    if (!strcmp(svp->name, "DEBUG"))
255    {
256        IUUpdateSwitch(svp, states, names, n);
257        ISwitch *sp = IUFindOnSwitch(svp);
258        if (!sp)
259            return false;
260
261        if (!strcmp(sp->name, "ENABLE"))
262            setDebug(true);
263        else
264            setDebug(false);
265        return true;
266    }
267
268    if (!strcmp(svp->name, "SIMULATION"))
269    {
270        IUUpdateSwitch(svp, states, names, n);
271        ISwitch *sp = IUFindOnSwitch(svp);
272        if (!sp)
273            return false;
274
275        if (!strcmp(sp->name, "ENABLE"))
276            setSimulation(true);
277        else
278            setSimulation(false);
279        return true;
280    }
281
282    if (!strcmp(svp->name, "CONFIG_PROCESS"))
283    {
284        IUUpdateSwitch(svp, states, names, n);
285        ISwitch *sp = IUFindOnSwitch(svp);
286        IUResetSwitch(svp);
287        bool pResult = false;
288        if (!sp)
289            return false;
290
291        if (!strcmp(sp->name, "CONFIG_LOAD"))
292            pResult = loadConfig();
293        else if (!strcmp(sp->name, "CONFIG_SAVE"))
294            pResult = saveConfig();
295        else if (!strcmp(sp->name, "CONFIG_DEFAULT"))
296            pResult = loadDefaultConfig();
297
298        if (pResult)
299            svp->s = IPS_OK;
300        else
301            svp->s = IPS_ALERT;
302
303        IDSetSwitch(svp, NULL);
304        return true;
305    }
306
307    return false;
308
309}
310
311void INDI::DefaultDriver::addDebugControl()
312{
313    /**************************************************************************/
314    DebugSP = getSwitch("DEBUG");
315    if (!DebugSP)
316    {
317        DebugSP = new ISwitchVectorProperty;
318        IUFillSwitch(&DebugS[0], "ENABLE", "Enable", ISS_OFF);
319        IUFillSwitch(&DebugS[1], "DISABLE", "Disable", ISS_ON);
320        IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), deviceName(), "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
321        registerProperty(DebugSP, PropertyContainer::INDI_SWITCH);
322    }
323    else
324    {
325        ISwitch *sp = IUFindSwitch(DebugSP, "ENABLE");
326        if (sp)
327            if (sp->s == ISS_ON)
328                pDebug = true;
329    }
330    /**************************************************************************/
331
332}
333
334void INDI::DefaultDriver::addSimulationControl()
335{
336    /**************************************************************************/
337    SimulationSP = getSwitch("SIMULATION");
338    if (!SimulationSP)
339    {
340        SimulationSP = new ISwitchVectorProperty;
341        IUFillSwitch(&SimulationS[0], "ENABLE", "Enable", ISS_OFF);
342        IUFillSwitch(&SimulationS[1], "DISABLE", "Disable", ISS_ON);
343        IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), deviceName(), "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
344        registerProperty(SimulationSP, PropertyContainer::INDI_SWITCH);
345    }
346    else
347    {
348        ISwitch *sp = IUFindSwitch(SimulationSP, "ENABLE");
349        if (sp)
350            if (sp->s == ISS_ON)
351                pSimulation = true;
352    }
353}
354
355void INDI::DefaultDriver::addConfigurationControl()
356{
357    /**************************************************************************/
358    ConfigProcessSP = getSwitch("CONFIG_PROCESS");
359    if (!ConfigProcessSP)
360    {
361        ConfigProcessSP = new ISwitchVectorProperty;
362        IUFillSwitch(&ConfigProcessS[0], "CONFIG_LOAD", "Load", ISS_OFF);
363        IUFillSwitch(&ConfigProcessS[1], "CONFIG_SAVE", "Save", ISS_OFF);
364        IUFillSwitch(&ConfigProcessS[2], "CONFIG_DEFAULT", "Default", ISS_OFF);
365        IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), deviceName(), "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
366        registerProperty(ConfigProcessSP, PropertyContainer::INDI_SWITCH);
367    }
368    /**************************************************************************/
369
370}
371
372void INDI::DefaultDriver::addAuxControls()
373{
374   addDebugControl();
375   addSimulationControl();
376   addConfigurationControl();
377}
378
379void INDI::DefaultDriver::setDebug(bool enable)
380{
381    if (!DebugSP)
382        return;
383
384    if (pDebug == enable)
385    {
386        DebugSP->s = IPS_OK;
387        IDSetSwitch(DebugSP, NULL);
388        return;
389    }
390
391    IUResetSwitch(DebugSP);
392
393    if (enable)
394    {
395        ISwitch *sp = IUFindSwitch(DebugSP, "ENABLE");
396        if (sp)
397        {
398            sp->s = ISS_ON;
399            IDMessage(deviceID, "Debug is enabled.");
400        }
401    }
402    else
403    {
404        ISwitch *sp = IUFindSwitch(DebugSP, "DISABLE");
405        if (sp)
406        {
407            sp->s = ISS_ON;
408            IDMessage(deviceID, "Debug is disabled.");
409        }
410    }
411
412    pDebug = enable;
413    DebugSP->s = IPS_OK;
414    IDSetSwitch(DebugSP, NULL);
415
416}
417
418void INDI::DefaultDriver::setSimulation(bool enable)
419{
420    if (!SimulationSP)
421        return;
422
423   if (pSimulation == enable)
424   {
425       SimulationSP->s = IPS_OK;
426       IDSetSwitch(SimulationSP, NULL);
427       return;
428   }
429
430   IUResetSwitch(SimulationSP);
431
432   if (enable)
433   {
434       ISwitch *sp = IUFindSwitch(SimulationSP, "ENABLE");
435       if (sp)
436       {
437           IDMessage(deviceID, "Simulation is enabled.");
438           sp->s = ISS_ON;
439       }
440   }
441   else
442   {
443       ISwitch *sp = IUFindSwitch(SimulationSP, "DISABLE");
444       if (sp)
445       {
446           sp->s = ISS_ON;
447           IDMessage(deviceID, "Simulation is disabled.");
448       }
449   }
450
451   pSimulation = enable;
452   SimulationSP->s = IPS_OK;
453   IDSetSwitch(SimulationSP, NULL);
454
455}
456
457bool INDI::DefaultDriver::isDebug()
458{
459  return pDebug;
460}
461
462bool INDI::DefaultDriver::isSimulation()
463{
464 return pSimulation;
465}
466
467void INDI::DefaultDriver::ISGetProperties (const char *dev)
468{
469    std::vector<PropertyContainer *>::iterator orderi;
470    static int isInit = 0;
471    PropertyContainer::INDI_TYPE pType;
472    void *pPtr;
473
474    if(isInit == 0)
475    {
476        if(dev != NULL)
477             setDeviceName(dev);
478        else
479        {
480            char *envDev = getenv("INDIDEV");
481            if (envDev != NULL)
482                setDeviceName(envDev);
483            else
484               setDeviceName(getDefaultName());
485        }
486
487        strncpy(ConnectionSP->device, deviceName(), MAXINDIDEVICE);
488        initProperties();
489        addConfigurationControl();
490
491        isInit = 1;
492    }
493
494    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
495    {
496        pType       = (*orderi)->getType();
497        pPtr        = (*orderi)->getProperty();
498
499        switch (pType)
500        {
501        case PropertyContainer::INDI_NUMBER:
502             IDDefNumber(static_cast<INumberVectorProperty *>(pPtr) , NULL);
503             break;
504        case PropertyContainer::INDI_TEXT:
505             IDDefText(static_cast<ITextVectorProperty *>(pPtr) , NULL);
506             break;
507        case PropertyContainer::INDI_SWITCH:
508             IDDefSwitch(static_cast<ISwitchVectorProperty *>(pPtr) , NULL);
509             break;
510        case PropertyContainer::INDI_LIGHT:
511             IDDefLight(static_cast<ILightVectorProperty *>(pPtr) , NULL);
512             break;
513        case PropertyContainer::INDI_BLOB:
514             IDDefBLOB(static_cast<IBLOBVectorProperty *>(pPtr) , NULL);
515             break;
516        }
517    }
518}
519
520void INDI::DefaultDriver::resetProperties()
521{
522    /*std::vector<numberPtr>::const_iterator numi;
523    std::vector<switchPtr>::const_iterator switchi;
524    std::vector<textPtr>::const_iterator texti;
525    std::vector<lightPtr>::const_iterator lighti;
526    std::vector<blobPtr>::const_iterator blobi;
527
528    for ( numi = pNumbers.begin(); numi != pNumbers.end(); numi++)
529    {
530        (*numi)->s = IPS_IDLE;
531        IDSetNumber( (*numi).get(), NULL);
532    }
533
534   for ( switchi = pSwitches.begin(); switchi != pSwitches.end(); switchi++)
535   {
536       (*switchi)->s = IPS_IDLE;
537       IDSetSwitch( (*switchi).get(), NULL);
538   }
539
540   for ( texti = pTexts.begin(); texti != pTexts.end(); texti++)
541   {
542      (*texti)->s = IPS_IDLE;
543      IDSetText( (*texti).get(), NULL);
544   }
545
546   for ( lighti = pLights.begin(); lighti != pLights.end(); lighti++)
547   {
548       (*lighti)->s = IPS_IDLE;
549       IDSetLight( (*lighti).get(), NULL);
550   }
551
552   for ( blobi = pBlobs.begin(); blobi != pBlobs.end(); blobi++)
553   {
554       (*blobi)->s = IPS_IDLE;
555       IDSetBLOB( (*blobi).get(), NULL);
556   }*/
557}
558
559void INDI::DefaultDriver::setConnected(bool status, IPState state, const char *msg)
560{
561    ISwitch *sp = NULL;
562    ISwitchVectorProperty *svp = getSwitch("CONNECTION");
563    if (!svp)
564        return;
565
566    IUResetSwitch(svp);
567
568    // Connect
569    if (status)
570    {
571        sp = IUFindSwitch(svp, "CONNECT");
572        if (!sp)
573            return;
574        sp->s = ISS_ON;
575    }
576    // Disconnect
577    else
578    {
579        sp = IUFindSwitch(svp, "DISCONNECT");
580        if (!sp)
581            return;
582        sp->s = ISS_ON;
583    }
584
585    svp->s = state;
586
587    IDSetSwitch(svp, msg, NULL);
588}
589
590//  This is a helper function
591//  that just encapsulates the Indi way into our clean c++ way of doing things
592int INDI::DefaultDriver::SetTimer(int ms)
593{
594    return IEAddTimer(ms,timerfunc,this);
595}
596
597//  Just another helper to help encapsulate indi into a clean class
598void INDI::DefaultDriver::RemoveTimer(int id)
599{
600    IERmTimer(id);
601    return;
602}
603
604//  This is just a placeholder
605//  This function should be overriden by child classes if they use timers
606//  So we should never get here
607void INDI::DefaultDriver::TimerHit()
608{
609    return;
610}
611
612
613bool INDI::DefaultDriver::updateProperties()
614{
615    //  The base device has no properties to update
616    return true;
617}
618
619
620bool INDI::DefaultDriver::initProperties()
621{
622   return true;
623}
624
625bool INDI::DefaultDriver::deleteProperty(const char *propertyName)
626{
627    removeProperty(propertyName);
628    IDDelete(deviceName(), propertyName ,NULL);
629    return true;
630}
631
632void INDI::DefaultDriver::defineNumber(INumberVectorProperty *nvp)
633{
634    registerProperty(nvp, PropertyContainer::INDI_NUMBER);
635    IDDefNumber(nvp, NULL);
636}
637
638void INDI::DefaultDriver::defineText(ITextVectorProperty *tvp)
639{
640    registerProperty(tvp, PropertyContainer::INDI_TEXT);
641    IDDefText(tvp, NULL);
642}
643
644void INDI::DefaultDriver::defineSwitch(ISwitchVectorProperty *svp)
645{
646    registerProperty(svp, PropertyContainer::INDI_SWITCH);
647    IDDefSwitch(svp, NULL);
648}
649
650void INDI::DefaultDriver::defineLight(ILightVectorProperty *lvp)
651{
652    registerProperty(lvp, PropertyContainer::INDI_LIGHT);
653    IDDefLight(lvp, NULL);
654}
655
656void INDI::DefaultDriver::defineBLOB(IBLOBVectorProperty *bvp)
657{
658    registerProperty(bvp, PropertyContainer::INDI_BLOB);
659    IDDefBLOB(bvp, NULL);
660}
Note: See TracBrowser for help on using the repository browser.