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)19bool 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)34void ClientAPIForMathPluginManagement::Initialise(INDI::BaseClient *BaseClient) 35 { 36 ClientAPIForMathPluginManagement::BaseClient = BaseClient; 37 } 38 ProcessNewDevice(INDI::BaseDevice * DevicePointer)39void ClientAPIForMathPluginManagement::ProcessNewDevice(INDI::BaseDevice *DevicePointer) 40 { 41 Device = DevicePointer; 42 } 43 ProcessNewProperty(INDI::Property * PropertyPointer)44void 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)65void 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)79bool 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()108bool 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()130bool 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()142bool 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()160bool 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