1 /*
2     IEQ Pro driver
3 
4     Copyright (C) 2015 Jasem Mutlaq
5 
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10 
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Lesser General Public License for more details.
15 
16     You should have received a copy of the GNU Lesser General Public
17     License along with this library; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20 
21 #include "ieqprolegacydriver.h"
22 
23 #include "indicom.h"
24 #include "indilogger.h"
25 
26 #include <libnova/julian_day.h>
27 
28 #include <cmath>
29 #include <map>
30 #include <cstring>
31 #include <termios.h>
32 #include <unistd.h>
33 
34 #define IEQPRO_TIMEOUT 5 /* FD timeout in seconds */
35 
36 static bool ieqpro_debug                 = false;
37 static bool ieqpro_simulation            = false;
38 static char ieqpro_device[MAXINDIDEVICE] = "iEQ";
39 static IEQInfo simInfo;
40 
41 struct
42 {
43     double ra;
44     double dec;
45     double ra_guide_rate;
46     double de_guide_rate;
47 } simData;
48 
set_ieqpro_debug(bool enable)49 void set_ieqpro_debug(bool enable)
50 {
51     ieqpro_debug = enable;
52 }
53 
set_ieqpro_simulation(bool enable)54 void set_ieqpro_simulation(bool enable)
55 {
56     ieqpro_simulation = enable;
57     if (enable)
58     {
59         simData.ra_guide_rate = 0.5;
60         simData.de_guide_rate = 0.5;
61     }
62 }
63 
set_ieqpro_device(const char * name)64 void set_ieqpro_device(const char *name)
65 {
66     strncpy(ieqpro_device, name, MAXINDIDEVICE);
67 }
68 
set_sim_gps_status(IEQ_GPS_STATUS value)69 void set_sim_gps_status(IEQ_GPS_STATUS value)
70 {
71     simInfo.gpsStatus = value;
72 }
73 
set_sim_system_status(IEQ_SYSTEM_STATUS value)74 void set_sim_system_status(IEQ_SYSTEM_STATUS value)
75 {
76     simInfo.systemStatus = value;
77 }
78 
set_sim_track_rate(IEQ_TRACK_RATE value)79 void set_sim_track_rate(IEQ_TRACK_RATE value)
80 {
81     simInfo.trackRate = value;
82 }
83 
set_sim_slew_rate(IEQ_SLEW_RATE value)84 void set_sim_slew_rate(IEQ_SLEW_RATE value)
85 {
86     simInfo.slewRate = value;
87 }
88 
set_sim_time_source(IEQ_TIME_SOURCE value)89 void set_sim_time_source(IEQ_TIME_SOURCE value)
90 {
91     simInfo.timeSource = value;
92 }
93 
set_sim_hemisphere(IEQ_HEMISPHERE value)94 void set_sim_hemisphere(IEQ_HEMISPHERE value)
95 {
96     simInfo.hemisphere = value;
97 }
98 
set_sim_ra(double ra)99 void set_sim_ra(double ra)
100 {
101     simData.ra = ra;
102 }
103 
set_sim_dec(double dec)104 void set_sim_dec(double dec)
105 {
106     simData.dec = dec;
107 }
108 
set_sim_guide_rate(double ra,double de)109 void set_sim_guide_rate(double ra, double de)
110 {
111     simData.ra_guide_rate = ra;
112     simData.de_guide_rate = de;
113 }
114 
check_ieqpro_connection(int fd)115 bool check_ieqpro_connection(int fd)
116 {
117     char initCMD[] = ":V#";
118     int errcode    = 0;
119     char errmsg[MAXRBUF];
120     char response[8];
121     int nbytes_read    = 0;
122     int nbytes_written = 0;
123 
124     DEBUGDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "Initializing IOptron using :V# CMD...");
125 
126     for (int i = 0; i < 2; i++)
127     {
128         if (ieqpro_simulation)
129         {
130             strcpy(response, "V1.00#");
131             nbytes_read = strlen(response);
132         }
133         else
134         {
135             tcflush(fd, TCIFLUSH);
136 
137             if ((errcode = tty_write(fd, initCMD, 3, &nbytes_written)) != TTY_OK)
138             {
139                 tty_error_msg(errcode, errmsg, MAXRBUF);
140                 DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
141                 usleep(50000);
142                 continue;
143             }
144 
145             if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
146             {
147                 tty_error_msg(errcode, errmsg, MAXRBUF);
148                 DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
149                 usleep(50000);
150                 continue;
151             }
152         }
153 
154         if (nbytes_read > 0)
155         {
156             response[nbytes_read] = '\0';
157             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
158 
159             if (!strcmp(response, "V1.00#"))
160                 return true;
161         }
162 
163         usleep(50000);
164     }
165 
166     return false;
167 }
168 
get_ieqpro_status(int fd,IEQInfo * info)169 bool get_ieqpro_status(int fd, IEQInfo *info)
170 {
171     char cmd[]  = ":GAS#";
172     int errcode = 0;
173     char errmsg[MAXRBUF];
174     char response[8];
175     int nbytes_read    = 0;
176     int nbytes_written = 0;
177 
178     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_EXTRA_1, "CMD <%s>", cmd);
179 
180     if (ieqpro_simulation)
181     {
182         snprintf(response, 8, "%d%d%d%d%d%d#", simInfo.gpsStatus, simInfo.systemStatus, simInfo.trackRate,
183                  simInfo.slewRate + 1, simInfo.timeSource, simInfo.hemisphere);
184         nbytes_read = strlen(response);
185     }
186     else
187     {
188         tcflush(fd, TCIFLUSH);
189 
190         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
191         {
192             tty_error_msg(errcode, errmsg, MAXRBUF);
193             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
194             return false;
195         }
196 
197         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
198         {
199             tty_error_msg(errcode, errmsg, MAXRBUF);
200             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
201             return false;
202         }
203     }
204 
205     if (nbytes_read > 0)
206     {
207         response[nbytes_read] = '\0';
208         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_EXTRA_1, "RES <%s>", response);
209 
210         if (nbytes_read == 7)
211         {
212             info->gpsStatus    = (IEQ_GPS_STATUS)(response[0] - '0');
213             info->systemStatus = (IEQ_SYSTEM_STATUS)(response[1] - '0');
214             info->trackRate    = (IEQ_TRACK_RATE)(response[2] - '0');
215             info->slewRate     = (IEQ_SLEW_RATE)(response[3] - '0' - 1);
216             info->timeSource   = (IEQ_TIME_SOURCE)(response[4] - '0');
217             info->hemisphere   = (IEQ_HEMISPHERE)(response[5] - '0');
218 
219             tcflush(fd, TCIFLUSH);
220 
221             return true;
222         }
223     }
224 
225     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 7.", nbytes_read);
226     return false;
227 }
228 
get_ieqpro_firmware(int fd,FirmwareInfo * info)229 bool get_ieqpro_firmware(int fd, FirmwareInfo *info)
230 {
231     bool rc = false;
232 
233     rc = get_ieqpro_model(fd, info);
234 
235     if (!rc)
236         return rc;
237 
238     rc = get_ieqpro_main_firmware(fd, info);
239 
240     if (!rc)
241         return rc;
242 
243     rc = get_ieqpro_radec_firmware(fd, info);
244 
245     return rc;
246 }
247 
get_ieqpro_model(int fd,FirmwareInfo * info)248 bool get_ieqpro_model(int fd, FirmwareInfo *info)
249 {
250     char cmd[]  = ":MountInfo#";
251     int errcode = 0;
252     char errmsg[MAXRBUF];
253     char response[16];
254     int nbytes_read    = 0;
255     int nbytes_written = 0;
256 
257     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
258 
259     if (ieqpro_simulation)
260     {
261         strcpy(response, "0045");
262         nbytes_read = strlen(response);
263     }
264     else
265     {
266         tcflush(fd, TCIFLUSH);
267 
268         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
269         {
270             tty_error_msg(errcode, errmsg, MAXRBUF);
271             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
272             return false;
273         }
274 
275         if ((errcode = tty_read(fd, response, 4, IEQPRO_TIMEOUT, &nbytes_read)))
276         {
277             tty_error_msg(errcode, errmsg, MAXRBUF);
278             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
279             return false;
280         }
281     }
282 
283     if (nbytes_read > 0)
284     {
285         response[nbytes_read] = '\0';
286         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
287 
288         if (nbytes_read == 4)
289         {
290             std::map<std::string, std::string> models =
291             {
292                 {"0010", "Cube II EQ"},
293                 {"0011", "Smart EQ Pro+"},
294                 {"0025", "CEM25"},
295                 {"0026", "CEM25-EC"},
296                 {"0030", "iEQ30Pro"},
297                 {"0040", "CEM40"},
298                 {"0041", "CEM40-EC"},
299                 {"0043", "GEM45"},
300                 {"0045", "iEQ45 Pro EQ"},
301                 {"0046", "iEQ45 Pro AA"},
302                 {"0060", "CEM60"},
303                 {"0061", "CEM60-EC"},
304                 {"0120", "CEM120"},
305                 {"0121", "CEM120-EC"},
306                 {"0122", "CEM120-EC2"},
307                 {"5010", "Cube II AA"},
308                 {"5035", "AZ Mount Pro"},
309                 {"5045", "iEQ45 Pro AA"},
310             };
311 
312             if (models.find(response) != models.end())
313                 info->Model = models[response];
314             else
315                 info->Model = "Unknown";
316 
317             tcflush(fd, TCIFLUSH);
318 
319             return true;
320         }
321     }
322 
323     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 4.", nbytes_read);
324     return false;
325 }
326 
get_ieqpro_main_firmware(int fd,FirmwareInfo * info)327 bool get_ieqpro_main_firmware(int fd, FirmwareInfo *info)
328 {
329     char cmd[]  = ":FW1#";
330     int errcode = 0;
331     char errmsg[MAXRBUF];
332     char response[16];
333     int nbytes_read    = 0;
334     int nbytes_written = 0;
335 
336     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
337 
338     if (ieqpro_simulation)
339     {
340         strcpy(response, "150324150101#");
341         nbytes_read = strlen(response);
342     }
343     else
344     {
345         tcflush(fd, TCIFLUSH);
346 
347         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
348         {
349             tty_error_msg(errcode, errmsg, MAXRBUF);
350             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
351             return false;
352         }
353 
354         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
355         {
356             tty_error_msg(errcode, errmsg, MAXRBUF);
357             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
358             return false;
359         }
360     }
361 
362     if (nbytes_read > 0)
363     {
364         response[nbytes_read] = '\0';
365         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
366 
367         if (nbytes_read == 13)
368         {
369             char board[8] = {0}, controller[8] = {0};
370 
371             strncpy(board, response, 6);
372             strncpy(controller, response + 6, 6);
373 
374             info->MainBoardFirmware.assign(board, 6);
375             info->ControllerFirmware.assign(controller, 6);
376 
377             tcflush(fd, TCIFLUSH);
378 
379             return true;
380         }
381     }
382 
383     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 13.", nbytes_read);
384     return false;
385 }
386 
get_ieqpro_radec_firmware(int fd,FirmwareInfo * info)387 bool get_ieqpro_radec_firmware(int fd, FirmwareInfo *info)
388 {
389     char cmd[]  = ":FW2#";
390     int errcode = 0;
391     char errmsg[MAXRBUF];
392     char response[16];
393     int nbytes_read    = 0;
394     int nbytes_written = 0;
395 
396     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
397 
398     if (ieqpro_simulation)
399     {
400         strcpy(response, "140324140101#");
401         nbytes_read = strlen(response);
402     }
403     else
404     {
405         tcflush(fd, TCIFLUSH);
406 
407         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
408         {
409             tty_error_msg(errcode, errmsg, MAXRBUF);
410             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
411             return false;
412         }
413 
414         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
415         {
416             tty_error_msg(errcode, errmsg, MAXRBUF);
417             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
418             return false;
419         }
420     }
421 
422     if (nbytes_read > 0)
423     {
424         response[nbytes_read] = '\0';
425         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
426 
427         if (nbytes_read == 13)
428         {
429             char ra[8] = {0}, dec[8] = {0};
430 
431             strncpy(ra, response, 6);
432             strncpy(dec, response + 6, 6);
433 
434             info->RAFirmware.assign(ra, 6);
435             info->DEFirmware.assign(dec, 6);
436 
437             tcflush(fd, TCIFLUSH);
438 
439             return true;
440         }
441     }
442 
443     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 13.", nbytes_read);
444     return false;
445 }
446 
start_ieqpro_motion(int fd,IEQ_DIRECTION dir)447 bool start_ieqpro_motion(int fd, IEQ_DIRECTION dir)
448 {
449     char cmd[16];
450     int errcode = 0;
451     char errmsg[MAXRBUF];
452     int nbytes_written = 0;
453 
454     switch (dir)
455     {
456         case IEQ_N:
457             strcpy(cmd, ":mn#");
458             break;
459         case IEQ_S:
460             strcpy(cmd, ":ms#");
461             break;
462         //        case IEQ_W:
463         //            strcpy(cmd, ":mw#");
464         //            break;
465         //        case IEQ_E:
466         //            strcpy(cmd, ":me#");
467         //            break;
468         // JM 2019-01-17: Appears iOptron implementation is reversed?
469         case IEQ_W:
470             strcpy(cmd, ":me#");
471             break;
472         case IEQ_E:
473             strcpy(cmd, ":mw#");
474             break;
475     }
476 
477     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
478 
479     if (ieqpro_simulation)
480         return true;
481 
482     tcflush(fd, TCIFLUSH);
483 
484     if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
485     {
486         tty_error_msg(errcode, errmsg, MAXRBUF);
487         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
488         return false;
489     }
490 
491     tcflush(fd, TCIFLUSH);
492     return true;
493 }
494 
stop_ieqpro_motion(int fd,IEQ_DIRECTION dir)495 bool stop_ieqpro_motion(int fd, IEQ_DIRECTION dir)
496 {
497     char cmd[16];
498     int errcode = 0;
499     char errmsg[MAXRBUF];
500     char response[8];
501     int nbytes_read    = 0;
502     int nbytes_written = 0;
503 
504     switch (dir)
505     {
506         case IEQ_N:
507         case IEQ_S:
508             strcpy(cmd, ":qD#");
509             break;
510 
511         case IEQ_W:
512         case IEQ_E:
513             strcpy(cmd, ":qR#");
514             break;
515     }
516 
517     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
518 
519     if (ieqpro_simulation)
520     {
521         strcpy(response, "1");
522         nbytes_read = strlen(response);
523     }
524     else
525     {
526         tcflush(fd, TCIFLUSH);
527 
528         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
529         {
530             tty_error_msg(errcode, errmsg, MAXRBUF);
531             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
532             return false;
533         }
534 
535         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
536         {
537             tty_error_msg(errcode, errmsg, MAXRBUF);
538             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
539             return false;
540         }
541     }
542 
543     if (nbytes_read > 0)
544     {
545         response[nbytes_read] = '\0';
546         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
547 
548         tcflush(fd, TCIFLUSH);
549         return true;
550     }
551 
552     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
553     return false;
554 }
555 
find_ieqpro_home(int fd)556 bool find_ieqpro_home(int fd)
557 {
558     char cmd[]  = ":MSH#";
559     int errcode = 0;
560     char errmsg[MAXRBUF];
561     char response[8];
562     int nbytes_read    = 0;
563     int nbytes_written = 0;
564 
565     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
566 
567     if (ieqpro_simulation)
568     {
569         strcpy(response, "1");
570         nbytes_read = strlen(response);
571     }
572     else
573     {
574         tcflush(fd, TCIFLUSH);
575 
576         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
577         {
578             tty_error_msg(errcode, errmsg, MAXRBUF);
579             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
580             return false;
581         }
582 
583         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
584         {
585             tty_error_msg(errcode, errmsg, MAXRBUF);
586             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
587             return false;
588         }
589     }
590 
591     if (nbytes_read > 0)
592     {
593         response[nbytes_read] = '\0';
594         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
595 
596         tcflush(fd, TCIFLUSH);
597         return true;
598     }
599 
600     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
601     return false;
602 }
603 
goto_ieqpro_home(int fd)604 bool goto_ieqpro_home(int fd)
605 {
606     char cmd[]  = ":MH#";
607     int errcode = 0;
608     char errmsg[MAXRBUF];
609     char response[8];
610     int nbytes_read    = 0;
611     int nbytes_written = 0;
612 
613     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
614 
615     if (ieqpro_simulation)
616     {
617         strcpy(response, "1");
618         nbytes_read = strlen(response);
619     }
620     else
621     {
622         tcflush(fd, TCIFLUSH);
623 
624         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
625         {
626             tty_error_msg(errcode, errmsg, MAXRBUF);
627             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
628             return false;
629         }
630 
631         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
632         {
633             tty_error_msg(errcode, errmsg, MAXRBUF);
634             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
635             return false;
636         }
637     }
638 
639     if (nbytes_read > 0)
640     {
641         response[nbytes_read] = '\0';
642         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
643 
644         tcflush(fd, TCIFLUSH);
645         return true;
646     }
647 
648     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
649     return false;
650 }
651 
set_ieqpro_current_home(int fd)652 bool set_ieqpro_current_home(int fd)
653 {
654     char cmd[]  = ":SZP#";
655     int errcode = 0;
656     char errmsg[MAXRBUF];
657     char response[8];
658     int nbytes_read    = 0;
659     int nbytes_written = 0;
660 
661     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
662 
663     if (ieqpro_simulation)
664     {
665         strcpy(response, "1");
666         nbytes_read = strlen(response);
667     }
668     else
669     {
670         tcflush(fd, TCIFLUSH);
671 
672         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
673         {
674             tty_error_msg(errcode, errmsg, MAXRBUF);
675             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
676             return false;
677         }
678 
679         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
680         {
681             tty_error_msg(errcode, errmsg, MAXRBUF);
682             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
683             return false;
684         }
685     }
686 
687     if (nbytes_read > 0)
688     {
689         response[nbytes_read] = '\0';
690         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
691 
692         tcflush(fd, TCIFLUSH);
693         return true;
694     }
695 
696     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
697     return false;
698 }
699 
set_ieqpro_slew_rate(int fd,IEQ_SLEW_RATE rate)700 bool set_ieqpro_slew_rate(int fd, IEQ_SLEW_RATE rate)
701 {
702     char cmd[16];
703     int errcode = 0;
704     char errmsg[MAXRBUF];
705     char response[8];
706     int nbytes_read    = 0;
707     int nbytes_written = 0;
708 
709     snprintf(cmd, 16, ":SR%d#", ((int)rate) + 1);
710 
711     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
712 
713     if (ieqpro_simulation)
714     {
715         simInfo.slewRate = rate;
716         strcpy(response, "1");
717         nbytes_read = strlen(response);
718     }
719     else
720     {
721         tcflush(fd, TCIFLUSH);
722 
723         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
724         {
725             tty_error_msg(errcode, errmsg, MAXRBUF);
726             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
727             return false;
728         }
729 
730         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
731         {
732             tty_error_msg(errcode, errmsg, MAXRBUF);
733             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
734             return false;
735         }
736     }
737 
738     if (nbytes_read > 0)
739     {
740         response[nbytes_read] = '\0';
741         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
742 
743         tcflush(fd, TCIFLUSH);
744         return true;
745     }
746 
747     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
748     return false;
749 }
750 
set_ieqpro_track_mode(int fd,IEQ_TRACK_RATE rate)751 bool set_ieqpro_track_mode(int fd, IEQ_TRACK_RATE rate)
752 {
753     char cmd[16];
754     int errcode = 0;
755     char errmsg[MAXRBUF];
756     char response[8];
757     int nbytes_read    = 0;
758     int nbytes_written = 0;
759 
760     switch (rate)
761     {
762         case TR_SIDEREAL:
763             strcpy(cmd, ":RT0#");
764             break;
765         case TR_LUNAR:
766             strcpy(cmd, ":RT1#");
767             break;
768         case TR_SOLAR:
769             strcpy(cmd, ":RT2#");
770             break;
771         case TR_KING:
772             strcpy(cmd, ":RT3#");
773             break;
774         case TR_CUSTOM:
775             strcpy(cmd, ":RT4#");
776             break;
777     }
778 
779     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
780 
781     if (ieqpro_simulation)
782     {
783         simInfo.trackRate = rate;
784         strcpy(response, "1");
785         nbytes_read = strlen(response);
786     }
787     else
788     {
789         tcflush(fd, TCIFLUSH);
790 
791         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
792         {
793             tty_error_msg(errcode, errmsg, MAXRBUF);
794             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
795             return false;
796         }
797 
798         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
799         {
800             tty_error_msg(errcode, errmsg, MAXRBUF);
801             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
802             return false;
803         }
804     }
805 
806     if (nbytes_read > 0)
807     {
808         response[nbytes_read] = '\0';
809         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
810 
811         tcflush(fd, TCIFLUSH);
812         return true;
813     }
814 
815     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
816     return false;
817 }
818 
set_ieqpro_custom_ra_track_rate(int fd,double rate)819 bool set_ieqpro_custom_ra_track_rate(int fd, double rate)
820 {
821     char cmd[16];
822     char sign;
823     int errcode = 0;
824     char errmsg[MAXRBUF];
825     char response[8];
826     int nbytes_read    = 0;
827     int nbytes_written = 0;
828 
829     if (rate < 0)
830         sign = '-';
831     else
832         sign = '+';
833 
834     snprintf(cmd, 16, ":RR%c%07.4f#", sign, fabs(rate));
835 
836     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
837 
838     if (ieqpro_simulation)
839     {
840         strcpy(response, "1");
841         nbytes_read = strlen(response);
842     }
843     else
844     {
845         tcflush(fd, TCIFLUSH);
846 
847         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
848         {
849             tty_error_msg(errcode, errmsg, MAXRBUF);
850             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
851             return false;
852         }
853 
854         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
855         {
856             tty_error_msg(errcode, errmsg, MAXRBUF);
857             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
858             return false;
859         }
860     }
861 
862     if (nbytes_read > 0)
863     {
864         response[nbytes_read] = '\0';
865         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
866 
867         tcflush(fd, TCIFLUSH);
868         return true;
869     }
870 
871     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
872     return false;
873 }
874 
set_ieqpro_custom_de_track_rate(int fd,double rate)875 bool set_ieqpro_custom_de_track_rate(int fd, double rate)
876 {
877     char cmd[16];
878     char sign;
879     int errcode = 0;
880     char errmsg[MAXRBUF];
881     char response[8];
882     int nbytes_read    = 0;
883     int nbytes_written = 0;
884 
885     if (rate < 0)
886         sign = '-';
887     else
888         sign = '+';
889 
890     snprintf(cmd, 16, ":RD%c%07.4f#", sign, fabs(rate));
891 
892     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
893 
894     if (ieqpro_simulation)
895     {
896         strcpy(response, "1");
897         nbytes_read = strlen(response);
898     }
899     else
900     {
901         tcflush(fd, TCIFLUSH);
902 
903         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
904         {
905             tty_error_msg(errcode, errmsg, MAXRBUF);
906             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
907             return false;
908         }
909 
910         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
911         {
912             tty_error_msg(errcode, errmsg, MAXRBUF);
913             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
914             return false;
915         }
916     }
917 
918     if (nbytes_read > 0)
919     {
920         response[nbytes_read] = '\0';
921         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
922 
923         tcflush(fd, TCIFLUSH);
924         return true;
925     }
926 
927     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
928     return false;
929 }
930 
set_ieqpro_guide_rate(int fd,double raRate,double deRate)931 bool set_ieqpro_guide_rate(int fd, double raRate, double deRate)
932 {
933     char cmd[16] = {0};
934     int errcode = 0;
935     char errmsg[MAXRBUF];
936     char response[8];
937     int nbytes_read    = 0;
938     int nbytes_written = 0;
939 
940     snprintf(cmd, 16, ":RG%02d%02d#", static_cast<int>(raRate * 100.0), static_cast<int>(deRate * 100.0));
941 
942     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
943 
944     if (ieqpro_simulation)
945     {
946         simData.ra_guide_rate = raRate;
947         simData.de_guide_rate = deRate;
948         strcpy(response, "1");
949         nbytes_read = strlen(response);
950     }
951     else
952     {
953         tcflush(fd, TCIFLUSH);
954 
955         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
956         {
957             tty_error_msg(errcode, errmsg, MAXRBUF);
958             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
959             return false;
960         }
961 
962         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
963         {
964             tty_error_msg(errcode, errmsg, MAXRBUF);
965             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
966             return false;
967         }
968     }
969 
970     if (nbytes_read > 0)
971     {
972         response[nbytes_read] = '\0';
973         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
974 
975         tcflush(fd, TCIFLUSH);
976         return true;
977     }
978 
979     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
980     return false;
981 }
982 
get_ieqpro_guide_rate(int fd,double * raRate,double * deRate)983 bool get_ieqpro_guide_rate(int fd, double *raRate, double *deRate)
984 {
985     char cmd[]  = ":AG#";
986     int errcode = 0;
987     char errmsg[MAXRBUF];
988     char response[8] = {0};
989     int nbytes_read    = 0;
990     int nbytes_written = 0;
991 
992     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
993 
994     if (ieqpro_simulation)
995     {
996         snprintf(response, 8, "%02d%02d#", static_cast<int>(simData.ra_guide_rate * 100), static_cast<int>(simData.de_guide_rate * 100));
997         nbytes_read = strlen(response);
998     }
999     else
1000     {
1001         tcflush(fd, TCIFLUSH);
1002 
1003         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1004         {
1005             tty_error_msg(errcode, errmsg, MAXRBUF);
1006             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1007             return false;
1008         }
1009 
1010         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
1011         {
1012             tty_error_msg(errcode, errmsg, MAXRBUF);
1013             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1014             return false;
1015         }
1016     }
1017 
1018     if (nbytes_read > 0)
1019     {
1020         response[nbytes_read - 1] = '\0';
1021         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1022 
1023         char raRateStr[8] = {0}, deRateStr[8] = {0};
1024         strncpy(response, raRateStr, 2);
1025         strncpy(response + 2, deRateStr, 2);
1026         *raRate = atoi(raRateStr) / 100.0;
1027         *deRate = atoi(deRateStr) / 100.0;
1028         tcflush(fd, TCIFLUSH);
1029         return true;
1030     }
1031 
1032     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1033     return false;
1034 }
1035 
start_ieqpro_guide(int fd,IEQ_DIRECTION dir,uint32_t ms)1036 bool start_ieqpro_guide(int fd, IEQ_DIRECTION dir, uint32_t ms)
1037 {
1038     char cmd[16];
1039     int errcode = 0;
1040     char errmsg[MAXRBUF];
1041     int nbytes_written = 0;
1042 
1043     char dir_c = 0;
1044 
1045     switch (dir)
1046     {
1047         case IEQ_N:
1048             dir_c = 'n';
1049             break;
1050 
1051         case IEQ_S:
1052             dir_c = 's';
1053             break;
1054 
1055         case IEQ_W:
1056             dir_c = 'w';
1057             break;
1058 
1059         case IEQ_E:
1060             dir_c = 'e';
1061             break;
1062     }
1063 
1064     snprintf(cmd, 16, ":M%c%05d#", dir_c, ms);
1065 
1066     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1067 
1068     if (ieqpro_simulation)
1069         return true;
1070     else
1071     {
1072         tcflush(fd, TCIFLUSH);
1073 
1074         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1075         {
1076             tty_error_msg(errcode, errmsg, MAXRBUF);
1077             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1078             return false;
1079         }
1080     }
1081 
1082     tcflush(fd, TCIFLUSH);
1083     return true;
1084 }
1085 
park_ieqpro(int fd)1086 bool park_ieqpro(int fd)
1087 {
1088     char cmd[]  = ":MP1#";
1089     int errcode = 0;
1090     char errmsg[MAXRBUF];
1091     char response[8];
1092     int nbytes_read    = 0;
1093     int nbytes_written = 0;
1094 
1095     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1096 
1097     if (ieqpro_simulation)
1098     {
1099         simInfo.rememberSystemStatus = simInfo.systemStatus;
1100         set_sim_system_status(ST_SLEWING);
1101         strcpy(response, "1");
1102         nbytes_read = strlen(response);
1103     }
1104     else
1105     {
1106         tcflush(fd, TCIFLUSH);
1107 
1108         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1109         {
1110             tty_error_msg(errcode, errmsg, MAXRBUF);
1111             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1112             return false;
1113         }
1114 
1115         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1116         {
1117             tty_error_msg(errcode, errmsg, MAXRBUF);
1118             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1119             return false;
1120         }
1121     }
1122 
1123     if (nbytes_read > 0)
1124     {
1125         response[nbytes_read] = '\0';
1126         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1127 
1128         if (!strcmp(response, "1"))
1129         {
1130             tcflush(fd, TCIFLUSH);
1131             return true;
1132         }
1133         else
1134         {
1135             DEBUGDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Error: Requested parking position is below horizon.");
1136             return false;
1137         }
1138     }
1139 
1140     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1141     return false;
1142 }
1143 
unpark_ieqpro(int fd)1144 bool unpark_ieqpro(int fd)
1145 {
1146     char cmd[]  = ":MP0#";
1147     int errcode = 0;
1148     char errmsg[MAXRBUF];
1149     char response[8];
1150     int nbytes_read    = 0;
1151     int nbytes_written = 0;
1152 
1153     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1154 
1155     if (ieqpro_simulation)
1156     {
1157         set_sim_system_status(ST_STOPPED);
1158         strcpy(response, "1");
1159         nbytes_read = strlen(response);
1160     }
1161     else
1162     {
1163         tcflush(fd, TCIFLUSH);
1164 
1165         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1166         {
1167             tty_error_msg(errcode, errmsg, MAXRBUF);
1168             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1169             return false;
1170         }
1171 
1172         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1173         {
1174             tty_error_msg(errcode, errmsg, MAXRBUF);
1175             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1176             return false;
1177         }
1178     }
1179 
1180     if (nbytes_read > 0)
1181     {
1182         response[nbytes_read] = '\0';
1183         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1184 
1185         tcflush(fd, TCIFLUSH);
1186         return true;
1187     }
1188 
1189     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1190     return false;
1191 }
1192 
abort_ieqpro(int fd)1193 bool abort_ieqpro(int fd)
1194 {
1195     char cmd[]  = ":Q#";
1196     int errcode = 0;
1197     char errmsg[MAXRBUF];
1198     char response[8];
1199     int nbytes_read    = 0;
1200     int nbytes_written = 0;
1201 
1202     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1203 
1204     if (ieqpro_simulation)
1205     {
1206         if (simInfo.systemStatus == ST_SLEWING)
1207             simInfo.systemStatus =  simInfo.rememberSystemStatus;
1208         strcpy(response, "1");
1209         nbytes_read = strlen(response);
1210     }
1211     else
1212     {
1213         tcflush(fd, TCIFLUSH);
1214 
1215         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1216         {
1217             tty_error_msg(errcode, errmsg, MAXRBUF);
1218             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1219             return false;
1220         }
1221 
1222         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1223         {
1224             tty_error_msg(errcode, errmsg, MAXRBUF);
1225             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1226             return false;
1227         }
1228     }
1229 
1230     if (nbytes_read > 0)
1231     {
1232         response[nbytes_read] = '\0';
1233         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1234 
1235         tcflush(fd, TCIFLUSH);
1236         return true;
1237     }
1238 
1239     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1240     return false;
1241 }
1242 
slew_ieqpro(int fd)1243 bool slew_ieqpro(int fd)
1244 {
1245     char cmd[]  = ":MS#";
1246     int errcode = 0;
1247     char errmsg[MAXRBUF];
1248     char response[8];
1249     int nbytes_read    = 0;
1250     int nbytes_written = 0;
1251 
1252     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1253 
1254     if (ieqpro_simulation)
1255     {
1256         simInfo.rememberSystemStatus = simInfo.systemStatus;
1257         simInfo.systemStatus = ST_SLEWING;
1258         strcpy(response, "1");
1259         nbytes_read = strlen(response);
1260     }
1261     else
1262     {
1263         tcflush(fd, TCIFLUSH);
1264 
1265         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1266         {
1267             tty_error_msg(errcode, errmsg, MAXRBUF);
1268             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1269             return false;
1270         }
1271 
1272         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1273         {
1274             tty_error_msg(errcode, errmsg, MAXRBUF);
1275             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1276             return false;
1277         }
1278     }
1279 
1280     if (nbytes_read > 0)
1281     {
1282         response[nbytes_read] = '\0';
1283         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1284 
1285         if (!strcmp(response, "1"))
1286         {
1287             tcflush(fd, TCIFLUSH);
1288             return true;
1289         }
1290         else
1291         {
1292             DEBUGDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Requested object is below horizon.");
1293             tcflush(fd, TCIFLUSH);
1294             return false;
1295         }
1296     }
1297 
1298     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1299     return false;
1300 }
1301 
sync_ieqpro(int fd)1302 bool sync_ieqpro(int fd)
1303 {
1304     char cmd[]  = ":CM#";
1305     int errcode = 0;
1306     char errmsg[MAXRBUF];
1307     char response[8];
1308     int nbytes_read    = 0;
1309     int nbytes_written = 0;
1310 
1311     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1312 
1313     if (ieqpro_simulation)
1314     {
1315         strcpy(response, "1");
1316         nbytes_read = strlen(response);
1317     }
1318     else
1319     {
1320         tcflush(fd, TCIFLUSH);
1321 
1322         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1323         {
1324             tty_error_msg(errcode, errmsg, MAXRBUF);
1325             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1326             return false;
1327         }
1328 
1329         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1330         {
1331             tty_error_msg(errcode, errmsg, MAXRBUF);
1332             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1333             return false;
1334         }
1335     }
1336 
1337     if (nbytes_read > 0)
1338     {
1339         response[nbytes_read] = '\0';
1340         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1341 
1342         tcflush(fd, TCIFLUSH);
1343         return true;
1344     }
1345 
1346     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1347     return false;
1348 }
1349 
set_ieqpro_track_enabled(int fd,bool enabled)1350 bool set_ieqpro_track_enabled(int fd, bool enabled)
1351 {
1352     char cmd[32];
1353     int errcode = 0;
1354     char errmsg[MAXRBUF];
1355     char response[8];
1356     int nbytes_read    = 0;
1357     int nbytes_written = 0;
1358 
1359     snprintf(cmd, 32, ":ST%d#", enabled ? 1 : 0);
1360 
1361     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1362 
1363     if (ieqpro_simulation)
1364     {
1365         simInfo.systemStatus = enabled ? ST_TRACKING_PEC_ON : ST_STOPPED;
1366         strcpy(response, "1");
1367         nbytes_read = strlen(response);
1368     }
1369     else
1370     {
1371         tcflush(fd, TCIFLUSH);
1372 
1373         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1374         {
1375             tty_error_msg(errcode, errmsg, MAXRBUF);
1376             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1377             return false;
1378         }
1379 
1380         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1381         {
1382             tty_error_msg(errcode, errmsg, MAXRBUF);
1383             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1384             return false;
1385         }
1386     }
1387 
1388     if (nbytes_read > 0)
1389     {
1390         response[nbytes_read] = '\0';
1391         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1392 
1393         tcflush(fd, TCIFLUSH);
1394         return true;
1395     }
1396 
1397     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1398     return false;
1399 }
1400 
set_ieqpro_ra(int fd,double ra)1401 bool set_ieqpro_ra(int fd, double ra)
1402 {
1403     char cmd[32];
1404     int errcode = 0;
1405     char errmsg[MAXRBUF];
1406     char response[8];
1407     int nbytes_read    = 0;
1408     int nbytes_written = 0;
1409 
1410     // Send as milliseconds resolution
1411     int ieqValue = ra * 60 * 60 * 1000;
1412 
1413     snprintf(cmd, 32, ":Sr%08d#", ieqValue);
1414 
1415     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1416 
1417     if (ieqpro_simulation)
1418     {
1419         simData.ra = ra;
1420         strcpy(response, "1");
1421         nbytes_read = strlen(response);
1422     }
1423     else
1424     {
1425         tcflush(fd, TCIFLUSH);
1426 
1427         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1428         {
1429             tty_error_msg(errcode, errmsg, MAXRBUF);
1430             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1431             return false;
1432         }
1433 
1434         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1435         {
1436             tty_error_msg(errcode, errmsg, MAXRBUF);
1437             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1438             return false;
1439         }
1440     }
1441 
1442     if (nbytes_read > 0)
1443     {
1444         response[nbytes_read] = '\0';
1445         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1446 
1447         tcflush(fd, TCIFLUSH);
1448         return true;
1449     }
1450 
1451     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1452     return false;
1453 }
1454 
set_ieqpro_dec(int fd,double dec)1455 bool set_ieqpro_dec(int fd, double dec)
1456 {
1457     char cmd[32];
1458     char sign;
1459     int errcode = 0;
1460     char errmsg[MAXRBUF];
1461     char response[8];
1462     int nbytes_read    = 0;
1463     int nbytes_written = 0;
1464 
1465     if (dec >= 0)
1466         sign = '+';
1467     else
1468         sign = '-';
1469 
1470     // Send as 0.01 arcseconds resolution
1471     int ieqValue = fabs(dec) * 60 * 60 * 100;
1472 
1473     snprintf(cmd, 32, ":Sd%c%08d#", sign, ieqValue);
1474 
1475     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1476 
1477     if (ieqpro_simulation)
1478     {
1479         simData.dec = dec;
1480         strcpy(response, "1");
1481         nbytes_read = strlen(response);
1482     }
1483     else
1484     {
1485         tcflush(fd, TCIFLUSH);
1486 
1487         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1488         {
1489             tty_error_msg(errcode, errmsg, MAXRBUF);
1490             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1491             return false;
1492         }
1493 
1494         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1495         {
1496             tty_error_msg(errcode, errmsg, MAXRBUF);
1497             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1498             return false;
1499         }
1500     }
1501 
1502     if (nbytes_read > 0)
1503     {
1504         response[nbytes_read] = '\0';
1505         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1506 
1507         tcflush(fd, TCIFLUSH);
1508         return true;
1509     }
1510 
1511     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1512     return false;
1513 }
1514 
set_ieqpro_longitude(int fd,double longitude)1515 bool set_ieqpro_longitude(int fd, double longitude)
1516 {
1517     char cmd[16];
1518     char sign;
1519     int errcode = 0;
1520     char errmsg[MAXRBUF];
1521     char response[8];
1522     int nbytes_read    = 0;
1523     int nbytes_written = 0;
1524 
1525     if (longitude >= 0)
1526         sign = '+';
1527     else
1528         sign = '-';
1529 
1530     int longitude_arcsecs = fabs(longitude) * 60 * 60;
1531     snprintf(cmd, 16, ":Sg%c%06d#", sign, longitude_arcsecs);
1532 
1533     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1534 
1535     if (ieqpro_simulation)
1536     {
1537         strcpy(response, "1");
1538         nbytes_read = strlen(response);
1539     }
1540     else
1541     {
1542         tcflush(fd, TCIFLUSH);
1543 
1544         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1545         {
1546             tty_error_msg(errcode, errmsg, MAXRBUF);
1547             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1548             return false;
1549         }
1550 
1551         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1552         {
1553             tty_error_msg(errcode, errmsg, MAXRBUF);
1554             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1555             return false;
1556         }
1557     }
1558 
1559     if (nbytes_read > 0)
1560     {
1561         response[nbytes_read] = '\0';
1562         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1563 
1564         tcflush(fd, TCIFLUSH);
1565         return true;
1566     }
1567 
1568     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1569     return false;
1570 }
1571 
set_ieqpro_latitude(int fd,double latitude)1572 bool set_ieqpro_latitude(int fd, double latitude)
1573 {
1574     char cmd[16];
1575     char sign;
1576     int errcode = 0;
1577     char errmsg[MAXRBUF];
1578     char response[8];
1579     int nbytes_read    = 0;
1580     int nbytes_written = 0;
1581 
1582     if (latitude >= 0)
1583         sign = '+';
1584     else
1585         sign = '-';
1586 
1587     int latitude_arcsecs = fabs(latitude) * 60 * 60;
1588     snprintf(cmd, 16, ":St%c%06d#", sign, latitude_arcsecs);
1589 
1590     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1591 
1592     if (ieqpro_simulation)
1593     {
1594         strcpy(response, "1");
1595         nbytes_read = strlen(response);
1596     }
1597     else
1598     {
1599         tcflush(fd, TCIFLUSH);
1600 
1601         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1602         {
1603             tty_error_msg(errcode, errmsg, MAXRBUF);
1604             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1605             return false;
1606         }
1607 
1608         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1609         {
1610             tty_error_msg(errcode, errmsg, MAXRBUF);
1611             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1612             return false;
1613         }
1614     }
1615 
1616     if (nbytes_read > 0)
1617     {
1618         response[nbytes_read] = '\0';
1619         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1620 
1621         tcflush(fd, TCIFLUSH);
1622         return true;
1623     }
1624 
1625     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1626     return false;
1627 }
1628 
get_ieqpro_longitude(int fd,double * longitude)1629 bool get_ieqpro_longitude(int fd, double *longitude)
1630 {
1631     char cmd[16];
1632     int errcode = 0;
1633     char errmsg[MAXRBUF];
1634     char response[8];
1635     int nbytes_read    = 0;
1636     int nbytes_written = 0;
1637 
1638     strcpy(cmd, ":Gg#");
1639 
1640     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1641 
1642     if (ieqpro_simulation)
1643     {
1644         strcpy(response, "+172800");
1645         nbytes_read = strlen(response);
1646     }
1647     else
1648     {
1649         tcflush(fd, TCIFLUSH);
1650 
1651         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1652         {
1653             tty_error_msg(errcode, errmsg, MAXRBUF);
1654             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1655             return false;
1656         }
1657         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
1658         {
1659             tty_error_msg(errcode, errmsg, MAXRBUF);
1660             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1661             return false;
1662         }
1663     }
1664 
1665     if (nbytes_read > 0)
1666     {
1667         response[nbytes_read - 1] = '\0';
1668         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1669 
1670         tcflush(fd, TCIFLUSH);
1671 
1672         int longitude_arcsecs = 0;
1673 
1674         if (sscanf(response, "%d", &longitude_arcsecs) > 0)
1675         {
1676             *longitude = longitude_arcsecs / 3600.0;
1677             return true;
1678         }
1679 
1680         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Error: Malformed result (%s).", response);
1681         return false;
1682     }
1683 
1684     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 8.", nbytes_read);
1685     return false;
1686 }
1687 
get_ieqpro_latitude(int fd,double * latitude)1688 bool get_ieqpro_latitude(int fd, double *latitude)
1689 {
1690     char cmd[16];
1691     int errcode = 0;
1692     char errmsg[MAXRBUF];
1693     char response[8];
1694     int nbytes_read    = 0;
1695     int nbytes_written = 0;
1696 
1697     strcpy(cmd, ":Gt#");
1698 
1699     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1700 
1701     if (ieqpro_simulation)
1702     {
1703         strcpy(response, "+106200");
1704         nbytes_read = strlen(response);
1705     }
1706     else
1707     {
1708         tcflush(fd, TCIFLUSH);
1709 
1710         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1711         {
1712             tty_error_msg(errcode, errmsg, MAXRBUF);
1713             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1714             return false;
1715         }
1716         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
1717         {
1718             tty_error_msg(errcode, errmsg, MAXRBUF);
1719             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1720             return false;
1721         }
1722     }
1723 
1724     if (nbytes_read > 0)
1725     {
1726         response[nbytes_read - 1] = '\0';
1727         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1728 
1729         tcflush(fd, TCIFLUSH);
1730 
1731         int latitude_arcsecs = 0;
1732 
1733         if (sscanf(response, "%d", &latitude_arcsecs) > 0)
1734         {
1735             *latitude = latitude_arcsecs / 3600.0;
1736             return true;
1737         }
1738 
1739         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Error: Malformed result (%s).", response);
1740         return false;
1741     }
1742 
1743     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 8.", nbytes_read);
1744     return false;
1745 }
1746 
set_ieqpro_local_date(int fd,int yy,int mm,int dd)1747 bool set_ieqpro_local_date(int fd, int yy, int mm, int dd)
1748 {
1749     char cmd[16];
1750     int errcode = 0;
1751     char errmsg[MAXRBUF];
1752     char response[8];
1753     int nbytes_read    = 0;
1754     int nbytes_written = 0;
1755 
1756     snprintf(cmd, 16, ":SC%02d%02d%02d#", yy, mm, dd);
1757 
1758     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1759 
1760     if (ieqpro_simulation)
1761     {
1762         strcpy(response, "1");
1763         nbytes_read = strlen(response);
1764     }
1765     else
1766     {
1767         tcflush(fd, TCIFLUSH);
1768 
1769         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1770         {
1771             tty_error_msg(errcode, errmsg, MAXRBUF);
1772             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1773             return false;
1774         }
1775 
1776         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1777         {
1778             tty_error_msg(errcode, errmsg, MAXRBUF);
1779             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1780             return false;
1781         }
1782     }
1783 
1784     if (nbytes_read > 0)
1785     {
1786         response[nbytes_read] = '\0';
1787         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1788 
1789         tcflush(fd, TCIFLUSH);
1790         return true;
1791     }
1792 
1793     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1794     return false;
1795 }
1796 
set_ieqpro_local_time(int fd,int hh,int mm,int ss)1797 bool set_ieqpro_local_time(int fd, int hh, int mm, int ss)
1798 {
1799     char cmd[16];
1800     int errcode = 0;
1801     char errmsg[MAXRBUF];
1802     char response[8];
1803     int nbytes_read    = 0;
1804     int nbytes_written = 0;
1805 
1806     snprintf(cmd, 16, ":SL%02d%02d%02d#", hh, mm, ss);
1807 
1808     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1809 
1810     if (ieqpro_simulation)
1811     {
1812         strcpy(response, "1");
1813         nbytes_read = strlen(response);
1814     }
1815     else
1816     {
1817         tcflush(fd, TCIFLUSH);
1818 
1819         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1820         {
1821             tty_error_msg(errcode, errmsg, MAXRBUF);
1822             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1823             return false;
1824         }
1825 
1826         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1827         {
1828             tty_error_msg(errcode, errmsg, MAXRBUF);
1829             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1830             return false;
1831         }
1832     }
1833 
1834     if (nbytes_read > 0)
1835     {
1836         response[nbytes_read] = '\0';
1837         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1838 
1839         tcflush(fd, TCIFLUSH);
1840         return true;
1841     }
1842 
1843     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1844     return false;
1845 }
1846 
set_ieqpro_daylight_saving(int fd,bool enabled)1847 bool set_ieqpro_daylight_saving(int fd, bool enabled)
1848 {
1849     char cmd[16];
1850     int errcode = 0;
1851     char errmsg[MAXRBUF];
1852     char response[8];
1853     int nbytes_read    = 0;
1854     int nbytes_written = 0;
1855 
1856     if (enabled)
1857         strcpy(cmd, ":SDS1#");
1858     else
1859         strcpy(cmd, ":SDS0#");
1860 
1861     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1862 
1863     if (ieqpro_simulation)
1864     {
1865         strcpy(response, "1");
1866         nbytes_read = strlen(response);
1867     }
1868     else
1869     {
1870         tcflush(fd, TCIFLUSH);
1871 
1872         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1873         {
1874             tty_error_msg(errcode, errmsg, MAXRBUF);
1875             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1876             return false;
1877         }
1878 
1879         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1880         {
1881             tty_error_msg(errcode, errmsg, MAXRBUF);
1882             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1883             return false;
1884         }
1885     }
1886 
1887     if (nbytes_read > 0)
1888     {
1889         response[nbytes_read] = '\0';
1890         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1891 
1892         tcflush(fd, TCIFLUSH);
1893         return true;
1894     }
1895 
1896     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1897     return false;
1898 }
1899 
set_ieqpro_utc_offset(int fd,double offset)1900 bool set_ieqpro_utc_offset(int fd, double offset)
1901 {
1902     char cmd[16];
1903     char sign;
1904     int errcode = 0;
1905     char errmsg[MAXRBUF];
1906     char response[8];
1907     int nbytes_read    = 0;
1908     int nbytes_written = 0;
1909 
1910     if (offset >= 0)
1911         sign = '+';
1912     else
1913         sign = '-';
1914 
1915     int offset_minutes = fabs(offset) * 60.0;
1916 
1917     snprintf(cmd, 16, ":SG%c%03d#", sign, offset_minutes);
1918 
1919     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
1920 
1921     if (ieqpro_simulation)
1922     {
1923         strcpy(response, "1");
1924         nbytes_read = strlen(response);
1925     }
1926     else
1927     {
1928         tcflush(fd, TCIFLUSH);
1929 
1930         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1931         {
1932             tty_error_msg(errcode, errmsg, MAXRBUF);
1933             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1934             return false;
1935         }
1936 
1937         if ((errcode = tty_read(fd, response, 1, IEQPRO_TIMEOUT, &nbytes_read)))
1938         {
1939             tty_error_msg(errcode, errmsg, MAXRBUF);
1940             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1941             return false;
1942         }
1943     }
1944 
1945     if (nbytes_read > 0)
1946     {
1947         response[nbytes_read] = '\0';
1948         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
1949 
1950         tcflush(fd, TCIFLUSH);
1951         return true;
1952     }
1953 
1954     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
1955     return false;
1956 }
1957 
get_ieqpro_coords(int fd,double * ra,double * dec)1958 bool get_ieqpro_coords(int fd, double *ra, double *dec)
1959 {
1960     char cmd[]  = ":GEC#";
1961     int errcode = 0;
1962     char errmsg[MAXRBUF];
1963     char response[32];
1964     int nbytes_read    = 0;
1965     int nbytes_written = 0;
1966 
1967     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_EXTRA_1, "CMD <%s>", cmd);
1968 
1969     if (ieqpro_simulation)
1970     {
1971         char ra_str[16], dec_str[16];
1972 
1973         char sign;
1974         if (simData.dec >= 0)
1975             sign = '+';
1976         else
1977             sign = '-';
1978 
1979         int ieqDEC = fabs(simData.dec) * 60 * 60 * 100;
1980 
1981         snprintf(dec_str, 16, "%c%08d", sign, ieqDEC);
1982 
1983         int ieqRA = simData.ra * 60 * 60 * 1000;
1984         snprintf(ra_str, 16, "%08d", ieqRA);
1985 
1986         snprintf(response, 32, "%s%s#", dec_str, ra_str);
1987         nbytes_read = strlen(response);
1988     }
1989     else
1990     {
1991         tcflush(fd, TCIFLUSH);
1992 
1993         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
1994         {
1995             tty_error_msg(errcode, errmsg, MAXRBUF);
1996             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
1997             return false;
1998         }
1999 
2000         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
2001         {
2002             tty_error_msg(errcode, errmsg, MAXRBUF);
2003             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
2004             return false;
2005         }
2006     }
2007 
2008     if (nbytes_read > 0)
2009     {
2010         tcflush(fd, TCIFLUSH);
2011         response[nbytes_read] = '\0';
2012         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_EXTRA_1, "RES <%s>", response);
2013 
2014         char ra_str[16] = {0}, dec_str[16] = {0};
2015 
2016         strncpy(dec_str, response, 9);
2017         strncpy(ra_str, response + 9, 8);
2018 
2019         int ieqDEC = atoi(dec_str);
2020         int ieqRA  = atoi(ra_str);
2021 
2022         *ra  = ieqRA / (60.0 * 60.0 * 1000.0);
2023         *dec = ieqDEC / (60.0 * 60.0 * 100.0);
2024 
2025         return true;
2026     }
2027 
2028     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
2029     return false;
2030 }
2031 
get_ieqpro_utc_date_time(int fd,double * utc_hours,int * yy,int * mm,int * dd,int * hh,int * minute,int * ss)2032 bool get_ieqpro_utc_date_time(int fd, double *utc_hours, int *yy, int *mm, int *dd, int *hh, int *minute, int *ss)
2033 {
2034     char cmd[]  = ":GLT#";
2035     int errcode = 0;
2036     char errmsg[MAXRBUF];
2037     char response[32];
2038     int nbytes_read    = 0;
2039     int nbytes_written = 0;
2040 
2041     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "CMD <%s>", cmd);
2042 
2043     // Format according to Manual is sMMMYYMMDDHHMMSS#
2044     // However as pointed out by user Shepherd on INDI forums, actual format is
2045     // sMMMxYYMMDDHHMMSS#
2046     // Where x is either 0 or 1 denoting daying savings
2047     if (ieqpro_simulation)
2048     {
2049         strncpy(response, "+1800150321173000#", 32);
2050         nbytes_read = strlen(response);
2051     }
2052     else
2053     {
2054         tcflush(fd, TCIFLUSH);
2055 
2056         if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
2057         {
2058             tty_error_msg(errcode, errmsg, MAXRBUF);
2059             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
2060             return false;
2061         }
2062 
2063         if ((errcode = tty_read_section(fd, response, '#', IEQPRO_TIMEOUT, &nbytes_read)))
2064         {
2065             tty_error_msg(errcode, errmsg, MAXRBUF);
2066             DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "%s", errmsg);
2067             return false;
2068         }
2069     }
2070 
2071     if (nbytes_read > 0)
2072     {
2073         tcflush(fd, TCIFLUSH);
2074         response[nbytes_read] = '\0';
2075         DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_DEBUG, "RES <%s>", response);
2076 
2077         char utc_str[8] = {0}, yy_str[8] = {0}, mm_str[8] = {0}, dd_str[8] = {0}, hh_str[8] = {0}, minute_str[8] = {0}, ss_str[8] = {0}, dst_str[8] = {0};
2078 
2079         // UTC Offset
2080         strncpy(utc_str, response, 4);
2081         // Daylight savings
2082         strncpy(dst_str, response + 4, 1);
2083         // Year
2084         strncpy(yy_str, response + 5, 2);
2085         // Month
2086         strncpy(mm_str, response + 7, 2);
2087         // Day
2088         strncpy(dd_str, response + 9, 2);
2089         // Hour
2090         strncpy(hh_str, response + 11, 2);
2091         // Minute
2092         strncpy(minute_str, response + 13, 2);
2093         // Second
2094         strncpy(ss_str, response + 15, 2);
2095 
2096         *utc_hours = atoi(utc_str) / 60.0;
2097         *yy        = atoi(yy_str) + 2000;
2098         //*mm        = atoi(mm_str) + 1;
2099         *mm        = atoi(mm_str);
2100         *dd        = atoi(dd_str);
2101         *hh        = atoi(hh_str);
2102         *minute    = atoi(minute_str);
2103         *ss        = atoi(ss_str);
2104 
2105         ln_zonedate localTime;
2106         ln_date utcTime;
2107 
2108         localTime.years   = *yy;
2109         localTime.months  = *mm;
2110         localTime.days    = *dd;
2111         localTime.hours   = *hh;
2112         localTime.minutes = *minute;
2113         localTime.seconds = *ss;
2114         localTime.gmtoff  = *utc_hours * 3600;
2115 
2116         ln_zonedate_to_date(&localTime, &utcTime);
2117 
2118         *yy     = utcTime.years;
2119         *mm     = utcTime.months;
2120         *dd     = utcTime.days;
2121         *hh     = utcTime.hours;
2122         *minute = utcTime.minutes;
2123         *ss     = utcTime.seconds;
2124 
2125         return true;
2126     }
2127 
2128     DEBUGFDEVICE(ieqpro_device, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
2129     return false;
2130 }
2131