1 /*!
2  * \file ClientAPIForMathPluginManagement.cpp
3  *
4  * \author Roger James
5  * \date 13th November 2013
6  *
7  */
8 
9 #include "ClientAPIForMathPluginManagement.h"
10 
11 #include <cstring>
12 
13 namespace INDI
14 {
15 namespace AlignmentSubsystem
16 {
17 // Public methods
18 
EnumerateMathPlugins(MathPluginsList & AvailableMathPlugins)19 bool ClientAPIForMathPluginManagement::EnumerateMathPlugins(MathPluginsList &AvailableMathPlugins)
20 {
21     // Wait for driver to initialise if neccessary
22     WaitForDriverCompletion();
23 
24     AvailableMathPlugins.clear();
25 
26     ISwitchVectorProperty *pPlugins = MathPlugins->getSwitch();
27 
28     for (int i = 0; i < pPlugins->nsp; i++)
29         AvailableMathPlugins.emplace_back(std::string(pPlugins->sp[i].label));
30 
31     return true;
32 }
33 
Initialise(INDI::BaseClient * BaseClient)34 void ClientAPIForMathPluginManagement::Initialise(INDI::BaseClient *BaseClient)
35 {
36     ClientAPIForMathPluginManagement::BaseClient = BaseClient;
37 }
38 
ProcessNewDevice(INDI::BaseDevice * DevicePointer)39 void ClientAPIForMathPluginManagement::ProcessNewDevice(INDI::BaseDevice *DevicePointer)
40 {
41     Device = DevicePointer;
42 }
43 
ProcessNewProperty(INDI::Property * PropertyPointer)44 void ClientAPIForMathPluginManagement::ProcessNewProperty(INDI::Property *PropertyPointer)
45 {
46     bool GotOneOfMine = true;
47 
48     if (strcmp(PropertyPointer->getName(), "ALIGNMENT_SUBSYSTEM_MATH_PLUGINS") == 0)
49         MathPlugins = PropertyPointer;
50     else if (strcmp(PropertyPointer->getName(), "ALIGNMENT_SUBSYSTEM_MATH_PLUGIN_INITIALISE") == 0)
51         PluginInitialise = PropertyPointer;
52     else
53         GotOneOfMine = false;
54 
55     // Tell the client when all the database proeprties have been set up
56     if (GotOneOfMine && (nullptr != MathPlugins) && (nullptr != PluginInitialise))
57     {
58         // The DriverActionComplete state variable is initialised to false
59         // So I need to call this to set it to true and signal anyone
60         // waiting for the driver to initialise etc.
61         SignalDriverCompletion();
62     }
63 }
64 
ProcessNewSwitch(ISwitchVectorProperty * SwitchVectorProperty)65 void ClientAPIForMathPluginManagement::ProcessNewSwitch(ISwitchVectorProperty *SwitchVectorProperty)
66 {
67     if (strcmp(SwitchVectorProperty->name, "ALIGNMENT_SUBSYSTEM_MATH_PLUGINS") == 0)
68     {
69         if (IPS_BUSY != SwitchVectorProperty->s)
70             SignalDriverCompletion();
71     }
72     else if (strcmp(SwitchVectorProperty->name, "ALIGNMENT_SUBSYSTEM_MATH_PLUGIN_INITIALISE") == 0)
73     {
74         if (IPS_BUSY != SwitchVectorProperty->s)
75             SignalDriverCompletion();
76     }
77 }
78 
SelectMathPlugin(const std::string & MathPluginName)79 bool ClientAPIForMathPluginManagement::SelectMathPlugin(const std::string &MathPluginName)
80 {
81     // Wait for driver to initialise if neccessary
82     WaitForDriverCompletion();
83 
84     ISwitchVectorProperty *pPlugins = MathPlugins->getSwitch();
85 
86     int i;
87     for (i = 0; i < pPlugins->nsp; i++)
88     {
89         if (0 == strcmp(MathPluginName.c_str(), pPlugins->sp[i].label))
90             break;
91     }
92     if (i >= pPlugins->nsp)
93         return false;
94 
95     IUResetSwitch(pPlugins);
96     pPlugins->sp[i].s = ISS_ON;
97     SetDriverBusy();
98     BaseClient->sendNewSwitch(pPlugins);
99     WaitForDriverCompletion();
100     if (IPS_OK != pPlugins->s)
101     {
102         IDLog("SelectMathPlugin - Bad MathPlugins switch state %s\n", pstateStr(pPlugins->s));
103         return false;
104     }
105     return true;
106 }
107 
ReInitialiseMathPlugin()108 bool ClientAPIForMathPluginManagement::ReInitialiseMathPlugin()
109 {
110     // Wait for driver to initialise if neccessary
111     WaitForDriverCompletion();
112 
113     ISwitchVectorProperty *pPluginInitialise = PluginInitialise->getSwitch();
114 
115     IUResetSwitch(pPluginInitialise);
116     pPluginInitialise->sp[0].s = ISS_ON;
117     SetDriverBusy();
118     BaseClient->sendNewSwitch(pPluginInitialise);
119     WaitForDriverCompletion();
120     if (IPS_OK != pPluginInitialise->s)
121     {
122         IDLog("ReInitialiseMathPlugin - Bad PluginInitialise switch state %s\n", pstateStr(pPluginInitialise->s));
123         return false;
124     }
125     return true;
126 }
127 
128 // Private methods
129 
SetDriverBusy()130 bool ClientAPIForMathPluginManagement::SetDriverBusy()
131 {
132     int ReturnCode = pthread_mutex_lock(&DriverActionCompleteMutex);
133 
134     if (ReturnCode != 0)
135         return false;
136     DriverActionComplete = false;
137     IDLog("SetDriverBusy\n");
138     ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
139     return ReturnCode == 0;
140 }
141 
SignalDriverCompletion()142 bool ClientAPIForMathPluginManagement::SignalDriverCompletion()
143 {
144     int ReturnCode = pthread_mutex_lock(&DriverActionCompleteMutex);
145 
146     if (ReturnCode != 0)
147         return false;
148     DriverActionComplete = true;
149     ReturnCode           = pthread_cond_signal(&DriverActionCompleteCondition);
150     if (ReturnCode != 0)
151     {
152         ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
153         return false;
154     }
155     IDLog("SignalDriverCompletion\n");
156     ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
157     return ReturnCode == 0;
158 }
159 
WaitForDriverCompletion()160 bool ClientAPIForMathPluginManagement::WaitForDriverCompletion()
161 {
162     int ReturnCode = pthread_mutex_lock(&DriverActionCompleteMutex);
163 
164     while (!DriverActionComplete)
165     {
166         IDLog("WaitForDriverCompletion - Waiting\n");
167         ReturnCode = pthread_cond_wait(&DriverActionCompleteCondition, &DriverActionCompleteMutex);
168         IDLog("WaitForDriverCompletion - Back from wait ReturnCode = %d\n", ReturnCode);
169         if (ReturnCode != 0)
170         {
171             ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
172             return false;
173         }
174     }
175     IDLog("WaitForDriverCompletion - Finished waiting\n");
176     ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
177     return ReturnCode == 0;
178 }
179 
180 } // namespace AlignmentSubsystem
181 } // namespace INDI
182