1 /*!
2 * \file ClientAPIForAlignmentDatabase.cpp
3 *
4 * \author Roger James
5 * \date 13th November 2013
6 *
7 */
8
9 #include "ClientAPIForAlignmentDatabase.h"
10
11 #include "indicom.h"
12
13 namespace INDI
14 {
15 namespace AlignmentSubsystem
16 {
ClientAPIForAlignmentDatabase()17 ClientAPIForAlignmentDatabase::ClientAPIForAlignmentDatabase()
18 {
19 pthread_cond_init(&DriverActionCompleteCondition, nullptr);
20 pthread_mutex_init(&DriverActionCompleteMutex, nullptr);
21 }
22
~ClientAPIForAlignmentDatabase()23 ClientAPIForAlignmentDatabase::~ClientAPIForAlignmentDatabase()
24 {
25 pthread_cond_destroy(&DriverActionCompleteCondition);
26 pthread_mutex_destroy(&DriverActionCompleteMutex);
27 }
28
AppendSyncPoint(const AlignmentDatabaseEntry & CurrentValues)29 bool ClientAPIForAlignmentDatabase::AppendSyncPoint(const AlignmentDatabaseEntry &CurrentValues)
30 {
31 // Wait for driver to initialise if neccessary
32 WaitForDriverCompletion();
33
34 ISwitchVectorProperty *pAction = Action->getSwitch();
35 ISwitchVectorProperty *pCommit = Commit->getSwitch();
36
37 if (APPEND != IUFindOnSwitchIndex(pAction))
38 {
39 // Request Append mode
40 IUResetSwitch(pAction);
41 pAction->sp[APPEND].s = ISS_ON;
42 SetDriverBusy();
43 BaseClient->sendNewSwitch(pAction);
44 WaitForDriverCompletion();
45 if (IPS_OK != pAction->s)
46 {
47 IDLog("AppendSyncPoint - Bad Action switch state %s\n", pstateStr(pAction->s));
48 return false;
49 }
50 }
51
52 if (!SendEntryData(CurrentValues))
53 return false;
54
55 // Commit the entry to the database
56 IUResetSwitch(pCommit);
57 pCommit->sp[0].s = ISS_ON;
58 SetDriverBusy();
59 BaseClient->sendNewSwitch(pCommit);
60 WaitForDriverCompletion();
61 if (IPS_OK != pCommit->s)
62 {
63 IDLog("AppendSyncPoint - Bad Commit switch state %s\n", pstateStr(pCommit->s));
64 return false;
65 }
66
67 return true;
68 }
69
ClearSyncPoints()70 bool ClientAPIForAlignmentDatabase::ClearSyncPoints()
71 {
72 // Wait for driver to initialise if neccessary
73 WaitForDriverCompletion();
74
75 ISwitchVectorProperty *pAction = Action->getSwitch();
76 ISwitchVectorProperty *pCommit = Commit->getSwitch();
77
78 // Select the required action
79 if (CLEAR != IUFindOnSwitchIndex(pAction))
80 {
81 // Request Clear mode
82 IUResetSwitch(pAction);
83 pAction->sp[CLEAR].s = ISS_ON;
84 SetDriverBusy();
85 BaseClient->sendNewSwitch(pAction);
86 WaitForDriverCompletion();
87 if (IPS_OK != pAction->s)
88 {
89 IDLog("ClearSyncPoints - Bad Action switch state %s\n", pstateStr(pAction->s));
90 return false;
91 }
92 }
93
94 IUResetSwitch(pCommit);
95 pCommit->sp[0].s = ISS_ON;
96 SetDriverBusy();
97 BaseClient->sendNewSwitch(pCommit);
98 WaitForDriverCompletion();
99 if (IPS_OK != pCommit->s)
100 {
101 IDLog("ClearSyncPoints - Bad Commit switch state %s\n", pstateStr(pCommit->s));
102 return false;
103 }
104
105 return true;
106 }
107
DeleteSyncPoint(unsigned int Offset)108 bool ClientAPIForAlignmentDatabase::DeleteSyncPoint(unsigned int Offset)
109 {
110 // Wait for driver to initialise if neccessary
111 WaitForDriverCompletion();
112
113 ISwitchVectorProperty *pAction = Action->getSwitch();
114 INumberVectorProperty *pCurrentEntry = CurrentEntry->getNumber();
115 ISwitchVectorProperty *pCommit = Commit->getSwitch();
116
117 // Select the required action
118 if (DELETE != IUFindOnSwitchIndex(pAction))
119 {
120 // Request Delete mode
121 IUResetSwitch(pAction);
122 pAction->sp[DELETE].s = ISS_ON;
123 SetDriverBusy();
124 BaseClient->sendNewSwitch(pAction);
125 WaitForDriverCompletion();
126 if (IPS_OK != pAction->s)
127 {
128 IDLog("DeleteSyncPoint - Bad Action switch state %s\n", pstateStr(pAction->s));
129 return false;
130 }
131 }
132
133 // Send the offset
134 pCurrentEntry->np[0].value = Offset;
135 SetDriverBusy();
136 BaseClient->sendNewNumber(pCurrentEntry);
137 WaitForDriverCompletion();
138 if (IPS_OK != pCurrentEntry->s)
139 {
140 IDLog("DeleteSyncPoint - Bad Current Entry state %s\n", pstateStr(pCurrentEntry->s));
141 return false;
142 }
143
144 // Commit the entry to the database
145 IUResetSwitch(pCommit);
146 pCommit->sp[0].s = ISS_ON;
147 SetDriverBusy();
148 BaseClient->sendNewSwitch(pCommit);
149 WaitForDriverCompletion();
150 if (IPS_OK != pCommit->s)
151 {
152 IDLog("DeleteSyncPoint - Bad Commit switch state %s\n", pstateStr(pCommit->s));
153 return false;
154 }
155
156 return true;
157 }
158
EditSyncPoint(unsigned int Offset,const AlignmentDatabaseEntry & CurrentValues)159 bool ClientAPIForAlignmentDatabase::EditSyncPoint(unsigned int Offset, const AlignmentDatabaseEntry &CurrentValues)
160 {
161 // Wait for driver to initialise if neccessary
162 WaitForDriverCompletion();
163
164 ISwitchVectorProperty *pAction = Action->getSwitch();
165 INumberVectorProperty *pCurrentEntry = CurrentEntry->getNumber();
166 ISwitchVectorProperty *pCommit = Commit->getSwitch();
167
168 // Select the required action
169 if (EDIT != IUFindOnSwitchIndex(pAction))
170 {
171 // Request Edit mode
172 IUResetSwitch(pAction);
173 pAction->sp[EDIT].s = ISS_ON;
174 SetDriverBusy();
175 BaseClient->sendNewSwitch(pAction);
176 WaitForDriverCompletion();
177 if (IPS_OK != pAction->s)
178 {
179 IDLog("EditSyncPoint - Bad Action switch state %s\n", pstateStr(pAction->s));
180 return false;
181 }
182 }
183
184 // Send the offset
185 pCurrentEntry->np[0].value = Offset;
186 SetDriverBusy();
187 BaseClient->sendNewNumber(pCurrentEntry);
188 WaitForDriverCompletion();
189 if (IPS_OK != pCurrentEntry->s)
190 {
191 IDLog("EditSyncPoint - Bad Current Entry state %s\n", pstateStr(pCurrentEntry->s));
192 return false;
193 }
194
195 if (!SendEntryData(CurrentValues))
196 return false;
197
198 // Commit the entry to the database
199 IUResetSwitch(pCommit);
200 pCommit->sp[0].s = ISS_ON;
201 SetDriverBusy();
202 BaseClient->sendNewSwitch(pCommit);
203 WaitForDriverCompletion();
204 if (IPS_OK != pCommit->s)
205 {
206 IDLog("EditSyncPoint - Bad Commit switch state %s\n", pstateStr(pCommit->s));
207 return false;
208 }
209
210 return true;
211 }
212
GetDatabaseSize()213 int ClientAPIForAlignmentDatabase::GetDatabaseSize()
214 {
215 return 0;
216 }
217
Initialise(INDI::BaseClient * BaseClient)218 void ClientAPIForAlignmentDatabase::Initialise(INDI::BaseClient *BaseClient)
219 {
220 ClientAPIForAlignmentDatabase::BaseClient = BaseClient;
221 }
222
InsertSyncPoint(unsigned int Offset,const AlignmentDatabaseEntry & CurrentValues)223 bool ClientAPIForAlignmentDatabase::InsertSyncPoint(unsigned int Offset, const AlignmentDatabaseEntry &CurrentValues)
224 {
225 // Wait for driver to initialise if neccessary
226 WaitForDriverCompletion();
227
228 ISwitchVectorProperty *pAction = Action->getSwitch();
229 INumberVectorProperty *pCurrentEntry = CurrentEntry->getNumber();
230 ISwitchVectorProperty *pCommit = Commit->getSwitch();
231
232 // Select the required action
233 if (INSERT != IUFindOnSwitchIndex(pAction))
234 {
235 // Request Insert mode
236 IUResetSwitch(pAction);
237 pAction->sp[INSERT].s = ISS_ON;
238 SetDriverBusy();
239 BaseClient->sendNewSwitch(pAction);
240 WaitForDriverCompletion();
241 if (IPS_OK != pAction->s)
242 {
243 IDLog("InsertSyncPoint - Bad Action switch state %s\n", pstateStr(pAction->s));
244 return false;
245 }
246 }
247
248 // Send the offset
249 pCurrentEntry->np[0].value = Offset;
250 SetDriverBusy();
251 BaseClient->sendNewNumber(pCurrentEntry);
252 WaitForDriverCompletion();
253 if (IPS_OK != pCurrentEntry->s)
254 {
255 IDLog("InsertSyncPoint - Bad Current Entry state %s\n", pstateStr(pCurrentEntry->s));
256 return false;
257 }
258
259 if (!SendEntryData(CurrentValues))
260 return false;
261
262 // Commit the entry to the database
263 IUResetSwitch(pCommit);
264 pCommit->sp[0].s = ISS_ON;
265 SetDriverBusy();
266 BaseClient->sendNewSwitch(pCommit);
267 WaitForDriverCompletion();
268 if (IPS_OK != pCommit->s)
269 {
270 IDLog("InsertSyncPoint - Bad Commit switch state %s\n", pstateStr(pCommit->s));
271 return false;
272 }
273
274 return true;
275 }
276
LoadDatabase()277 bool ClientAPIForAlignmentDatabase::LoadDatabase()
278 {
279 // Wait for driver to initialise if neccessary
280 WaitForDriverCompletion();
281
282 ISwitchVectorProperty *pAction = Action->getSwitch();
283 ISwitchVectorProperty *pCommit = Commit->getSwitch();
284
285 // Select the required action
286 if (LOAD_DATABASE != IUFindOnSwitchIndex(pAction))
287 {
288 // Request Load Database mode
289 IUResetSwitch(pAction);
290 pAction->sp[LOAD_DATABASE].s = ISS_ON;
291 SetDriverBusy();
292 BaseClient->sendNewSwitch(pAction);
293 WaitForDriverCompletion();
294 if (IPS_OK != pAction->s)
295 {
296 IDLog("LoadDatabase - Bad Action switch state %s\n", pstateStr(pAction->s));
297 return false;
298 }
299 }
300
301 // Commit the Load Database
302 IUResetSwitch(pCommit);
303 pCommit->sp[0].s = ISS_ON;
304 SetDriverBusy();
305 BaseClient->sendNewSwitch(pCommit);
306 WaitForDriverCompletion();
307 if (IPS_OK != pCommit->s)
308 {
309 IDLog("LoadDatabase - Bad Commit state %s\n", pstateStr(pCommit->s));
310 return false;
311 }
312
313 return true;
314 }
315
ProcessNewBLOB(IBLOB * BLOBPointer)316 void ClientAPIForAlignmentDatabase::ProcessNewBLOB(IBLOB *BLOBPointer)
317 {
318 if (strcmp(BLOBPointer->bvp->name, "ALIGNMENT_POINT_OPTIONAL_BINARY_BLOB") == 0)
319 {
320 if (IPS_BUSY != BLOBPointer->bvp->s)
321 {
322 ISwitchVectorProperty *pAction = Action->getSwitch();
323 int Index = IUFindOnSwitchIndex(pAction);
324 if ((READ != Index) && (READ_INCREMENT != Index))
325 SignalDriverCompletion();
326 }
327 }
328 }
329
ProcessNewDevice(INDI::BaseDevice * DevicePointer)330 void ClientAPIForAlignmentDatabase::ProcessNewDevice(INDI::BaseDevice *DevicePointer)
331 {
332 Device = DevicePointer;
333 }
334
ProcessNewNumber(INumberVectorProperty * NumberVectorProperty)335 void ClientAPIForAlignmentDatabase::ProcessNewNumber(INumberVectorProperty *NumberVectorProperty)
336 {
337 if (strcmp(NumberVectorProperty->name, "ALIGNMENT_POINT_MANDATORY_NUMBERS") == 0)
338 {
339 if (IPS_BUSY != NumberVectorProperty->s)
340 {
341 ISwitchVectorProperty *pAction = Action->getSwitch();
342 int Index = IUFindOnSwitchIndex(pAction);
343 if ((READ != Index) && (READ_INCREMENT != Index))
344 SignalDriverCompletion();
345 }
346 }
347 else if (strcmp(NumberVectorProperty->name, "ALIGNMENT_POINTSET_CURRENT_ENTRY") == 0)
348 {
349 if (IPS_BUSY != NumberVectorProperty->s)
350 {
351 ISwitchVectorProperty *pAction = Action->getSwitch();
352 int Index = IUFindOnSwitchIndex(pAction);
353 if (READ_INCREMENT != Index)
354 SignalDriverCompletion();
355 }
356 }
357 }
358
ProcessNewProperty(INDI::Property * PropertyPointer)359 void ClientAPIForAlignmentDatabase::ProcessNewProperty(INDI::Property *PropertyPointer)
360 {
361 bool GotOneOfMine = true;
362
363 if (strcmp(PropertyPointer->getName(), "ALIGNMENT_POINT_MANDATORY_NUMBERS") == 0)
364 MandatoryNumbers = PropertyPointer;
365 else if (strcmp(PropertyPointer->getName(), "ALIGNMENT_POINT_OPTIONAL_BINARY_BLOB") == 0)
366 {
367 OptionalBinaryBlob = PropertyPointer;
368 // Make sure the format string is set up
369 strncpy(OptionalBinaryBlob->getBLOB()->bp->format, "alignmentPrivateData", MAXINDIBLOBFMT);
370 }
371 else if (strcmp(PropertyPointer->getName(), "ALIGNMENT_POINTSET_SIZE") == 0)
372 PointsetSize = PropertyPointer;
373 else if (strcmp(PropertyPointer->getName(), "ALIGNMENT_POINTSET_CURRENT_ENTRY") == 0)
374 CurrentEntry = PropertyPointer;
375 else if (strcmp(PropertyPointer->getName(), "ALIGNMENT_POINTSET_ACTION") == 0)
376 Action = PropertyPointer;
377 else if (strcmp(PropertyPointer->getName(), "ALIGNMENT_POINTSET_COMMIT") == 0)
378 Commit = PropertyPointer;
379 else
380 GotOneOfMine = false;
381
382 // Tell the client when all the database proeprties have been set up
383 if (GotOneOfMine && (nullptr != MandatoryNumbers) && (nullptr != OptionalBinaryBlob) && (nullptr != PointsetSize) &&
384 (nullptr != CurrentEntry) && (nullptr != Action) && (nullptr != Commit))
385 {
386 // The DriverActionComplete state variable is initialised to false
387 // So I need to call this to set it to true and signal anyone
388 // waiting for the driver to initialise etc.
389 SignalDriverCompletion();
390 }
391 }
392
ProcessNewSwitch(ISwitchVectorProperty * SwitchVectorProperty)393 void ClientAPIForAlignmentDatabase::ProcessNewSwitch(ISwitchVectorProperty *SwitchVectorProperty)
394 {
395 if (strcmp(SwitchVectorProperty->name, "ALIGNMENT_POINTSET_ACTION") == 0)
396 {
397 if (IPS_BUSY != SwitchVectorProperty->s)
398 SignalDriverCompletion();
399 }
400 else if (strcmp(SwitchVectorProperty->name, "ALIGNMENT_POINTSET_COMMIT") == 0)
401 {
402 if (IPS_BUSY != SwitchVectorProperty->s)
403 SignalDriverCompletion();
404 }
405 }
406
ReadIncrementSyncPoint(AlignmentDatabaseEntry & CurrentValues)407 bool ClientAPIForAlignmentDatabase::ReadIncrementSyncPoint(AlignmentDatabaseEntry &CurrentValues)
408 {
409 // Wait for driver to initialise if neccessary
410 WaitForDriverCompletion();
411
412 ISwitchVectorProperty *pAction = Action->getSwitch();
413 INumberVectorProperty *pMandatoryNumbers = MandatoryNumbers->getNumber();
414 IBLOBVectorProperty *pBLOB = OptionalBinaryBlob->getBLOB();
415 INumberVectorProperty *pCurrentEntry = CurrentEntry->getNumber();
416 ISwitchVectorProperty *pCommit = Commit->getSwitch();
417
418 // Select the required action
419 if (READ_INCREMENT != IUFindOnSwitchIndex(pAction))
420 {
421 // Request Read Increment mode
422 IUResetSwitch(pAction);
423 pAction->sp[READ_INCREMENT].s = ISS_ON;
424 SetDriverBusy();
425 BaseClient->sendNewSwitch(pAction);
426 WaitForDriverCompletion();
427 if (IPS_OK != pAction->s)
428 {
429 IDLog("ReadIncrementSyncPoint - Bad Action switch state %s\n", pstateStr(pAction->s));
430 return false;
431 }
432 }
433
434 // Commit the read increment
435 IUResetSwitch(pCommit);
436 pCommit->sp[0].s = ISS_ON;
437 SetDriverBusy();
438 BaseClient->sendNewSwitch(pCommit);
439 WaitForDriverCompletion();
440 if ((IPS_OK != pCommit->s) || (IPS_OK != pMandatoryNumbers->s) || (IPS_OK != pBLOB->s) ||
441 (IPS_OK != pCurrentEntry->s))
442 {
443 IDLog("ReadIncrementSyncPoint - Bad Commit/Mandatory numbers/Blob/Current entry state %s %s %s %s\n",
444 pstateStr(pCommit->s), pstateStr(pMandatoryNumbers->s), pstateStr(pBLOB->s), pstateStr(pCurrentEntry->s));
445 return false;
446 }
447
448 // Read the entry data
449 CurrentValues.ObservationJulianDate = pMandatoryNumbers->np[ENTRY_OBSERVATION_JULIAN_DATE].value;
450 CurrentValues.RightAscension = pMandatoryNumbers->np[ENTRY_RA].value;
451 CurrentValues.Declination = pMandatoryNumbers->np[ENTRY_DEC].value;
452 CurrentValues.TelescopeDirection.x = pMandatoryNumbers->np[ENTRY_VECTOR_X].value;
453 CurrentValues.TelescopeDirection.y = pMandatoryNumbers->np[ENTRY_VECTOR_Y].value;
454 CurrentValues.TelescopeDirection.z = pMandatoryNumbers->np[ENTRY_VECTOR_Z].value;
455
456 return true;
457 }
458
ReadSyncPoint(unsigned int Offset,AlignmentDatabaseEntry & CurrentValues)459 bool ClientAPIForAlignmentDatabase::ReadSyncPoint(unsigned int Offset, AlignmentDatabaseEntry &CurrentValues)
460 {
461 // Wait for driver to initialise if neccessary
462 WaitForDriverCompletion();
463
464 ISwitchVectorProperty *pAction = Action->getSwitch();
465 INumberVectorProperty *pMandatoryNumbers = MandatoryNumbers->getNumber();
466 IBLOBVectorProperty *pBLOB = OptionalBinaryBlob->getBLOB();
467 INumberVectorProperty *pCurrentEntry = CurrentEntry->getNumber();
468 ISwitchVectorProperty *pCommit = Commit->getSwitch();
469
470 // Select the required action
471 if (READ != IUFindOnSwitchIndex(pAction))
472 {
473 // Request Read mode
474 IUResetSwitch(pAction);
475 pAction->sp[READ].s = ISS_ON;
476 SetDriverBusy();
477 BaseClient->sendNewSwitch(pAction);
478 WaitForDriverCompletion();
479 if (IPS_OK != pAction->s)
480 {
481 IDLog("ReadSyncPoint - Bad Action switch state %s\n", pstateStr(pAction->s));
482 return false;
483 }
484 }
485
486 // Send the offset
487 pCurrentEntry->np[0].value = Offset;
488 SetDriverBusy();
489 BaseClient->sendNewNumber(pCurrentEntry);
490 WaitForDriverCompletion();
491 if (IPS_OK != pCurrentEntry->s)
492 {
493 IDLog("ReadSyncPoint - Bad Current Entry state %s\n", pstateStr(pCurrentEntry->s));
494 return false;
495 }
496
497 // Commit the read
498 IUResetSwitch(pCommit);
499 pCommit->sp[0].s = ISS_ON;
500 SetDriverBusy();
501 BaseClient->sendNewSwitch(pCommit);
502 WaitForDriverCompletion();
503 if ((IPS_OK != pCommit->s) || (IPS_OK != pMandatoryNumbers->s) || (IPS_OK != pBLOB->s))
504 {
505 IDLog("ReadSyncPoint - Bad Commit/Mandatory numbers/Blob state %s %s %s\n", pstateStr(pCommit->s),
506 pstateStr(pMandatoryNumbers->s), pstateStr(pBLOB->s));
507 return false;
508 }
509
510 // Read the entry data
511 CurrentValues.ObservationJulianDate = pMandatoryNumbers->np[ENTRY_OBSERVATION_JULIAN_DATE].value;
512 CurrentValues.RightAscension = pMandatoryNumbers->np[ENTRY_RA].value;
513 CurrentValues.Declination = pMandatoryNumbers->np[ENTRY_DEC].value;
514 CurrentValues.TelescopeDirection.x = pMandatoryNumbers->np[ENTRY_VECTOR_X].value;
515 CurrentValues.TelescopeDirection.y = pMandatoryNumbers->np[ENTRY_VECTOR_Y].value;
516 CurrentValues.TelescopeDirection.z = pMandatoryNumbers->np[ENTRY_VECTOR_Z].value;
517
518 return true;
519 }
520
SaveDatabase()521 bool ClientAPIForAlignmentDatabase::SaveDatabase()
522 {
523 // Wait for driver to initialise if neccessary
524 WaitForDriverCompletion();
525
526 ISwitchVectorProperty *pAction = Action->getSwitch();
527 ISwitchVectorProperty *pCommit = Commit->getSwitch();
528
529 // Select the required action
530 if (SAVE_DATABASE != IUFindOnSwitchIndex(pAction))
531 {
532 // Request Load Database mode
533 IUResetSwitch(pAction);
534 pAction->sp[SAVE_DATABASE].s = ISS_ON;
535 SetDriverBusy();
536 BaseClient->sendNewSwitch(pAction);
537 WaitForDriverCompletion();
538 if (IPS_OK != pAction->s)
539 {
540 IDLog("SaveDatabase - Bad Action switch state %s\n", pstateStr(pAction->s));
541 return false;
542 }
543 }
544
545 // Commit the Save Database
546 IUResetSwitch(pCommit);
547 pCommit->sp[0].s = ISS_ON;
548 SetDriverBusy();
549 BaseClient->sendNewSwitch(pCommit);
550 WaitForDriverCompletion();
551 if (IPS_OK != pCommit->s)
552 {
553 IDLog("Save Database - Bad Commit state %s\n", pstateStr(pCommit->s));
554 return false;
555 }
556
557 return true;
558 }
559
560 // Private methods
561
SendEntryData(const AlignmentDatabaseEntry & CurrentValues)562 bool ClientAPIForAlignmentDatabase::SendEntryData(const AlignmentDatabaseEntry &CurrentValues)
563 {
564 INumberVectorProperty *pMandatoryNumbers = MandatoryNumbers->getNumber();
565 IBLOBVectorProperty *pBLOB = OptionalBinaryBlob->getBLOB();
566 // Send the entry data
567 pMandatoryNumbers->np[ENTRY_OBSERVATION_JULIAN_DATE].value = CurrentValues.ObservationJulianDate;
568 pMandatoryNumbers->np[ENTRY_RA].value = CurrentValues.RightAscension;
569 pMandatoryNumbers->np[ENTRY_DEC].value = CurrentValues.Declination;
570 pMandatoryNumbers->np[ENTRY_VECTOR_X].value = CurrentValues.TelescopeDirection.x;
571 pMandatoryNumbers->np[ENTRY_VECTOR_Y].value = CurrentValues.TelescopeDirection.y;
572 pMandatoryNumbers->np[ENTRY_VECTOR_Z].value = CurrentValues.TelescopeDirection.z;
573 SetDriverBusy();
574 BaseClient->sendNewNumber(pMandatoryNumbers);
575 WaitForDriverCompletion();
576 if (IPS_OK != pMandatoryNumbers->s)
577 {
578 IDLog("SendEntryData - Bad mandatory numbers state %s\n", pstateStr(pMandatoryNumbers->s));
579 return false;
580 }
581
582 if ((0 != CurrentValues.PrivateDataSize) && (nullptr != CurrentValues.PrivateData.get()))
583 {
584 // I have a BLOB to send
585 SetDriverBusy();
586 BaseClient->startBlob(Device->getDeviceName(), pBLOB->name, timestamp());
587 BaseClient->sendOneBlob(pBLOB->bp->name, CurrentValues.PrivateDataSize, pBLOB->bp->format,
588 CurrentValues.PrivateData.get());
589 BaseClient->finishBlob();
590 WaitForDriverCompletion();
591 if (IPS_OK != pBLOB->s)
592 {
593 IDLog("SendEntryData - Bad BLOB state %s\n", pstateStr(pBLOB->s));
594 return false;
595 }
596 }
597 return true;
598 }
599
SetDriverBusy()600 bool ClientAPIForAlignmentDatabase::SetDriverBusy()
601 {
602 int ReturnCode = pthread_mutex_lock(&DriverActionCompleteMutex);
603
604 if (ReturnCode != 0)
605 return false;
606 DriverActionComplete = false;
607 IDLog("SetDriverBusy\n");
608 ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
609 return ReturnCode == 0;
610 }
611
SignalDriverCompletion()612 bool ClientAPIForAlignmentDatabase::SignalDriverCompletion()
613 {
614 int ReturnCode = pthread_mutex_lock(&DriverActionCompleteMutex);
615
616 if (ReturnCode != 0)
617 return false;
618 DriverActionComplete = true;
619 ReturnCode = pthread_cond_signal(&DriverActionCompleteCondition);
620 if (ReturnCode != 0)
621 {
622 ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
623 return false;
624 }
625 IDLog("SignalDriverCompletion\n");
626 ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
627 return ReturnCode == 0;
628 }
629
WaitForDriverCompletion()630 bool ClientAPIForAlignmentDatabase::WaitForDriverCompletion()
631 {
632 int ReturnCode = pthread_mutex_lock(&DriverActionCompleteMutex);
633
634 while (!DriverActionComplete)
635 {
636 IDLog("WaitForDriverCompletion - Waiting\n");
637 ReturnCode = pthread_cond_wait(&DriverActionCompleteCondition, &DriverActionCompleteMutex);
638 IDLog("WaitForDriverCompletion - Back from wait ReturnCode = %d\n", ReturnCode);
639 if (ReturnCode != 0)
640 {
641 ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
642 return false;
643 }
644 }
645 IDLog("WaitForDriverCompletion - Finished waiting\n");
646 ReturnCode = pthread_mutex_unlock(&DriverActionCompleteMutex);
647 return ReturnCode == 0;
648 }
649
650 } // namespace AlignmentSubsystem
651 } // namespace INDI
652