Instrument Neutral Distributed Interface INDI  2.0.2
flip_flat.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2015 Jasem Mutlaq. All rights reserved.
3 
4  Simple GPS Simulator
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by the Free
8  Software Foundation; either version 2 of the License, or (at your option)
9  any later version.
10 
11  This program is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 
21  The full GNU General Public License is included in this distribution in the
22  file called LICENSE.
23 *******************************************************************************/
24 
25 #include "flip_flat.h"
26 
27 #include "indicom.h"
29 
30 #include <cerrno>
31 #include <cstring>
32 #include <memory>
33 #include <termios.h>
34 #include <unistd.h>
35 #include <inttypes.h>
36 #include <sys/ioctl.h>
37 
38 // We declare an auto pointer to FlipFlat.
39 static std::unique_ptr<FlipFlat> flipflat(new FlipFlat());
40 
41 #define FLAT_CMD 6
42 #define FLAT_RES 8
43 #define FLAT_TIMEOUT 3
44 
46 {
47  setVersion(1, 1);
48 }
49 
51 {
53 
54  // Status
55  IUFillText(&StatusT[0], "Cover", "Cover", nullptr);
56  IUFillText(&StatusT[1], "Light", "Light", nullptr);
57  IUFillText(&StatusT[2], "Motor", "Motor", nullptr);
58  IUFillTextVector(&StatusTP, StatusT, 3, getDeviceName(), "Status", "Status", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);
59 
60  // Firmware version
61  IUFillText(&FirmwareT[0], "Version", "Version", nullptr);
62  IUFillTextVector(&FirmwareTP, FirmwareT, 1, getDeviceName(), "Firmware", "Firmware", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);
63 
66 
67  LightIntensityN[0].min = 0;
68  LightIntensityN[0].max = 255;
69  LightIntensityN[0].step = 10;
70 
71  // Set DUSTCAP_INTEFACE later on connect after we verify whether it's flip-flat (dust cover + light) or just flip-man (light only)
73 
75 
76  serialConnection = new Connection::Serial(this);
77  serialConnection->registerHandshake([&]()
78  {
79  return Handshake();
80  });
81  registerConnection(serialConnection);
82 
83  return true;
84 }
85 
86 void FlipFlat::ISGetProperties(const char *dev)
87 {
89 
90  // Get Light box properties
92 }
93 
95 {
97 
98  if (isConnected())
99  {
100  if (m_Type == FLIP_FLAT || m_Type == ALNITAK_DUST_COVER)
104  defineProperty(&StatusTP);
105  defineProperty(&FirmwareTP);
106 
108 
109  getStartupData();
110  }
111  else
112  {
113  if (m_Type == FLIP_FLAT || m_Type == ALNITAK_DUST_COVER)
117  deleteProperty(StatusTP.name);
118  deleteProperty(FirmwareTP.name);
119 
121  }
122 
123  return true;
124 }
125 
127 {
128  return "Flip Flat";
129 }
130 
131 bool FlipFlat::Handshake()
132 {
133  if (isSimulation())
134  {
135  LOGF_INFO("Connected successfully to simulated %s. Retrieving startup data...", getDeviceName());
136 
138 
140  syncDriverInfo();
141  m_Type = FLIP_FLAT;
142 
143  return true;
144  }
145 
146  PortFD = serialConnection->getPortFD();
147 
148  /* Drop RTS */
149  int i = 0;
150  i |= TIOCM_RTS;
151  if (ioctl(PortFD, TIOCMBIC, &i) != 0)
152  {
153  LOGF_ERROR("IOCTL error %s.", strerror(errno));
154  return false;
155  }
156 
157  i |= TIOCM_RTS;
158  if (ioctl(PortFD, TIOCMGET, &i) != 0)
159  {
160  LOGF_ERROR("IOCTL error %s.", strerror(errno));
161  return false;
162  }
163 
164  if (!ping())
165  {
166  LOG_ERROR("Device ping failed.");
167  return false;
168  }
169 
170  return true;
171 }
172 
173 bool FlipFlat::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
174 {
175  if (processLightBoxNumber(dev, name, values, names, n))
176  return true;
177 
178  return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
179 }
180 
181 bool FlipFlat::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
182 {
183  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
184  {
185  if (processLightBoxText(dev, name, texts, names, n))
186  return true;
187  }
188 
189  return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
190 }
191 
192 bool FlipFlat::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
193 {
194  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
195  {
196  if (processDustCapSwitch(dev, name, states, names, n))
197  return true;
198 
199  if (processLightBoxSwitch(dev, name, states, names, n))
200  return true;
201  }
202 
203  return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
204 }
205 
207 {
208  snoopLightBox(root);
209 
211 }
212 
214 {
216 
217  return saveLightBoxConfigItems(fp);
218 }
219 
220 bool FlipFlat::ping()
221 {
222  char response[FLAT_RES] = {0};
223 
224  if (!sendCommand(">P000", response))
225  return false;
226 
227  char productString[3] = { 0 };
228  snprintf(productString, 3, "%s", response + 2);
229 
230  int rc = sscanf(productString, "%" SCNu16, &productID);
231  if (rc <= 0)
232  {
233  LOGF_ERROR("Unable to parse input (%s)", response);
234  return false;
235  }
236 
237  // Flip Flat
238  if (productID == 99)
239  {
241  syncDriverInfo();
242  m_Type = FLIP_FLAT;
243  }
244  // AlNitak Dust Cover
245  else if (productID == 98)
246  {
248  syncDriverInfo();
249  }
250  // Flip Man
251  else
252  m_Type = FLIP_MAN;
253 
254  return true;
255 }
256 
257 bool FlipFlat::getStartupData()
258 {
259  bool rc1 = getFirmwareVersion();
260  bool rc2 = getStatus();
261  bool rc3 = getBrightness();
262 
263  return (rc1 && rc2 && rc3);
264 }
265 
267 {
268  if (isSimulation())
269  {
270  simulationWorkCounter = 3;
271  return IPS_BUSY;
272  }
273 
274  char response[FLAT_RES];
275  if (!sendCommand(">C000", response))
276  return IPS_ALERT;
277 
278  char expectedResponse[FLAT_RES];
279  snprintf(expectedResponse, FLAT_RES, "*C%02d", productID);
280 
281  if (strstr(response, expectedResponse))
282  {
283  // Set cover status to random value outside of range to force it to refresh
284  prevCoverStatus = 10;
285 
286  IERmTimer(parkTimeoutID);
287  parkTimeoutID = IEAddTimer(30000, parkTimeoutHelper, this);
288  return IPS_BUSY;
289  }
290  else
291  return IPS_ALERT;
292 }
293 
295 {
296  if (isSimulation())
297  {
298  simulationWorkCounter = 3;
299  return IPS_BUSY;
300  }
301 
302  char response[FLAT_RES];
303  if (!sendCommand(">O000", response))
304  return IPS_ALERT;
305 
306  char expectedResponse[FLAT_RES];
307  snprintf(expectedResponse, FLAT_RES, "*O%02d", productID);
308 
309  if (strstr(response, expectedResponse))
310  {
311  // Set cover status to random value outside of range to force it to refresh
312  prevCoverStatus = 10;
313 
314  IERmTimer(unparkTimeoutID);
315  unparkTimeoutID = IEAddTimer(30000, unparkTimeoutHelper, this);
316 
317  return IPS_BUSY;
318  }
319  else
320  return IPS_ALERT;
321 }
322 
323 bool FlipFlat::EnableLightBox(bool enable)
324 {
325  char command[FLAT_CMD];
326  char response[FLAT_RES];
327 
328  if (m_Type == FLIP_FLAT && ParkCapS[1].s == ISS_ON)
329  {
330  LOG_ERROR("Cannot control light while cap is unparked.");
331  return false;
332  }
333 
334  if (isSimulation())
335  return true;
336 
337  if (enable)
338  strncpy(command, ">L000", FLAT_CMD);
339  else
340  strncpy(command, ">D000", FLAT_CMD);
341 
342  if (!sendCommand(command, response))
343  return false;
344 
345  char expectedResponse[FLAT_RES];
346  if (enable)
347  snprintf(expectedResponse, FLAT_RES, "*L%02d", productID);
348  else
349  snprintf(expectedResponse, FLAT_RES, "*D%02d", productID);
350 
351  // JM 2022.11.06 find if the response contains expected response.
352  // We no longer check for zero-fillers since some implementations wrong interpreted as 0.
353  return (strstr(response, expectedResponse));
354 }
355 
356 bool FlipFlat::getStatus()
357 {
358  char response[FLAT_RES];
359 
360  if (isSimulation())
361  {
362  if (ParkCapSP.s == IPS_BUSY && --simulationWorkCounter <= 0)
363  {
364  ParkCapSP.s = IPS_OK;
365  IDSetSwitch(&ParkCapSP, nullptr);
366  simulationWorkCounter = 0;
367  }
368 
369  if (ParkCapSP.s == IPS_BUSY)
370  {
371  response[4] = '1';
372  response[6] = '0';
373  }
374  else
375  {
376  response[4] = '0';
377  // Parked/Closed
378  if (ParkCapS[CAP_PARK].s == ISS_ON)
379  response[6] = '1';
380  else
381  response[6] = '2';
382  }
383 
384  response[5] = (LightS[FLAT_LIGHT_ON].s == ISS_ON) ? '1' : '0';
385  }
386  else
387  {
388  if (!sendCommand(">S000", response))
389  return false;
390  }
391 
392  char motorStatus = *(response + 4) - '0';
393  char lightStatus = *(response + 5) - '0';
394  char coverStatus = *(response + 6) - '0';
395 
396  bool statusUpdated = false;
397 
398  if (coverStatus != prevCoverStatus)
399  {
400  prevCoverStatus = coverStatus;
401 
402  statusUpdated = true;
403 
404  switch (coverStatus)
405  {
406  case 0:
407  IUSaveText(&StatusT[0], "Not Open/Closed");
408  break;
409 
410  case 1:
411  IUSaveText(&StatusT[0], "Closed");
412  if (ParkCapSP.s == IPS_BUSY || ParkCapSP.s == IPS_IDLE)
413  {
415  ParkCapS[0].s = ISS_ON;
416  ParkCapSP.s = IPS_OK;
417  LOG_INFO("Cover closed.");
418  IDSetSwitch(&ParkCapSP, nullptr);
419  }
420  break;
421 
422  case 2:
423  IUSaveText(&StatusT[0], "Open");
424  if (ParkCapSP.s == IPS_BUSY || ParkCapSP.s == IPS_IDLE)
425  {
427  ParkCapS[1].s = ISS_ON;
428  ParkCapSP.s = IPS_OK;
429  LOG_INFO("Cover open.");
430  IDSetSwitch(&ParkCapSP, nullptr);
431  }
432  break;
433 
434  case 3:
435  IUSaveText(&StatusT[0], "Timed out");
436  break;
437  }
438  }
439 
440  if (lightStatus != prevLightStatus)
441  {
442  prevLightStatus = lightStatus;
443 
444  statusUpdated = true;
445 
446  switch (lightStatus)
447  {
448  case 0:
449  IUSaveText(&StatusT[1], "Off");
450  if (LightS[0].s == ISS_ON)
451  {
452  LightS[0].s = ISS_OFF;
453  LightS[1].s = ISS_ON;
454  IDSetSwitch(&LightSP, nullptr);
455  }
456  break;
457 
458  case 1:
459  IUSaveText(&StatusT[1], "On");
460  if (LightS[1].s == ISS_ON)
461  {
462  LightS[0].s = ISS_ON;
463  LightS[1].s = ISS_OFF;
464  IDSetSwitch(&LightSP, nullptr);
465  }
466  break;
467  }
468  }
469 
470  if (motorStatus != prevMotorStatus)
471  {
472  prevMotorStatus = motorStatus;
473 
474  statusUpdated = true;
475 
476  switch (motorStatus)
477  {
478  case 0:
479  IUSaveText(&StatusT[2], "Stopped");
480  break;
481 
482  case 1:
483  IUSaveText(&StatusT[2], "Running");
484  break;
485  }
486  }
487 
488  if (statusUpdated)
489  IDSetText(&StatusTP, nullptr);
490 
491  return true;
492 }
493 
494 bool FlipFlat::getFirmwareVersion()
495 {
496  if (isSimulation())
497  {
498  IUSaveText(&FirmwareT[0], "Simulation");
499  IDSetText(&FirmwareTP, nullptr);
500  return true;
501  }
502 
503  char response[FLAT_RES] = {0};
504  if (!sendCommand(">V000", response))
505  return false;
506 
507  char versionString[4] = { 0 };
508  snprintf(versionString, 4, "%s", response + 4);
509  IUSaveText(&FirmwareT[0], versionString);
510  IDSetText(&FirmwareTP, nullptr);
511 
512  return true;
513 }
514 
516 {
517  if (!isConnected())
518  return;
519 
520  getStatus();
521 
522  // parking or unparking timed out, try again
523  if (ParkCapSP.s == IPS_BUSY && !strcmp(StatusT[0].text, "Timed out"))
524  {
525  if (ParkCapS[0].s == ISS_ON)
526  ParkCap();
527  else
528  UnParkCap();
529  }
530 
532 }
533 
534 bool FlipFlat::getBrightness()
535 {
536  if (isSimulation())
537  {
538  return true;
539  }
540 
541  char response[FLAT_RES] = {0};
542  if (!sendCommand(">J000", response))
543  return false;
544 
545  char brightnessString[4] = { 0 };
546  snprintf(brightnessString, 4, "%s", response + 4);
547 
548  int brightnessValue = 0;
549  int rc = sscanf(brightnessString, "%d", &brightnessValue);
550 
551  if (rc <= 0)
552  {
553  LOGF_ERROR("Unable to parse brightness value (%s)", response);
554  return false;
555  }
556 
557  if (brightnessValue != prevBrightness)
558  {
559  prevBrightness = brightnessValue;
560  LightIntensityN[0].value = brightnessValue;
561  IDSetNumber(&LightIntensityNP, nullptr);
562  }
563 
564  return true;
565 }
566 
568 {
569  if (isSimulation())
570  {
571  LightIntensityN[0].value = value;
572  IDSetNumber(&LightIntensityNP, nullptr);
573  return true;
574  }
575 
576  char command[FLAT_CMD] = {0};
577  char response[FLAT_RES] = {0};
578 
579  snprintf(command, FLAT_CMD, ">B%03d", value);
580 
581  if (!sendCommand(command, response))
582  return false;
583 
584  char brightnessString[4] = { 0 };
585  snprintf(brightnessString, 4, "%s", response + 4);
586 
587  int brightnessValue = 0;
588  int rc = sscanf(brightnessString, "%d", &brightnessValue);
589 
590  if (rc <= 0)
591  {
592  LOGF_ERROR("Unable to parse brightness value (%s)", response);
593  return false;
594  }
595 
596  if (brightnessValue != prevBrightness)
597  {
598  prevBrightness = brightnessValue;
599  LightIntensityN[0].value = brightnessValue;
600  IDSetNumber(&LightIntensityNP, nullptr);
601  }
602 
603  return true;
604 }
605 
606 bool FlipFlat::sendCommand(const char *command, char *response)
607 {
608  int nbytes_written = 0, nbytes_read = 0, rc = -1;
609  char errstr[MAXRBUF] = {0};
610  int i = 0;
611 
612  tcflush(PortFD, TCIOFLUSH);
613 
614  LOGF_DEBUG("CMD <%s>", command);
615 
616  char buffer[FLAT_CMD + 1] = {0}; // space for terminating null
617  snprintf(buffer, FLAT_CMD + 1, "%s\n", command);
618 
619  for (i = 0; i < 3; i++)
620  {
621  if ((rc = tty_write(PortFD, buffer, FLAT_CMD, &nbytes_written)) != TTY_OK)
622  {
623  usleep(50000);
624  continue;
625  }
626 
627  if ((rc = tty_nread_section(PortFD, response, FLAT_RES, 0xA, FLAT_TIMEOUT, &nbytes_read)) != TTY_OK)
628  usleep(50000);
629  else
630  break;
631  }
632 
633  if (i == 3)
634  {
635  tty_error_msg(rc, errstr, MAXRBUF);
636  LOGF_ERROR("%s error: %s.", command, errstr);
637  return false;
638  }
639 
640  response[nbytes_read - 1] = 0; // strip \n
641 
642  LOGF_DEBUG("RES <%s>", response);
643  return true;
644 }
645 
646 void FlipFlat::parkTimeoutHelper(void *context)
647 {
648  static_cast<FlipFlat*>(context)->parkTimeout();
649 }
650 
651 void FlipFlat::unparkTimeoutHelper(void *context)
652 {
653  static_cast<FlipFlat*>(context)->unparkTimeout();
654 }
655 
656 void FlipFlat::parkTimeout()
657 {
658  if (ParkCapSP.s == IPS_BUSY)
659  {
660  LOG_WARN("Parking cap timed out. Retrying...");
661  ParkCap();
662  }
663 }
664 
665 void FlipFlat::unparkTimeout()
666 {
667  if (ParkCapSP.s == IPS_BUSY)
668  {
669  LOG_WARN("UnParking cap timed out. Retrying...");
670  UnParkCap();
671  }
672 }
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
virtual bool EnableLightBox(bool enable) override
EnableLightBox Turn on/off on a light box. Must be impelemented in the child class.
Definition: flip_flat.cpp:323
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: flip_flat.cpp:173
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: flip_flat.cpp:213
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: flip_flat.cpp:86
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: flip_flat.cpp:192
static void parkTimeoutHelper(void *context)
Definition: flip_flat.cpp:646
virtual IPState UnParkCap() override
unPark dust cap (open cover). Must be implemented by child.
Definition: flip_flat.cpp:294
const char * getDefaultName() override
Definition: flip_flat.cpp:126
@ ALNITAK_DUST_COVER
Definition: flip_flat.h:60
@ FLIP_MAN
Definition: flip_flat.h:59
@ FLIP_FLAT
Definition: flip_flat.h:58
virtual bool SetLightBoxBrightness(uint16_t value) override
setBrightness Set light level. Must be impelemented in the child class, if supported.
Definition: flip_flat.cpp:567
virtual IPState ParkCap() override
Park dust cap (close cover). Must be implemented by child.
Definition: flip_flat.cpp:266
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: flip_flat.cpp:94
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition: flip_flat.cpp:515
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
Definition: flip_flat.cpp:181
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
Definition: flip_flat.cpp:206
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: flip_flat.cpp:50
static void unparkTimeoutHelper(void *context)
Definition: flip_flat.cpp:651
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
bool isSimulation() const
void syncDriverInfo()
syncDriverInfo sends the current driver information to the client.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
void initDustCapProperties(const char *deviceName, const char *groupName)
Initilize dust cap properties. It is recommended to call this function within initProperties() of you...
bool processDustCapSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process dust cap switch properties.
ISwitchVectorProperty ParkCapSP
INumberVectorProperty LightIntensityNP
bool processLightBoxNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process light box number properties.
ISwitchVectorProperty LightSP
bool processLightBoxSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process light box switch properties.
void initLightBoxProperties(const char *deviceName, const char *groupNam)
Initilize light box properties. It is recommended to call this function within initProperties() of yo...
bool processLightBoxText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process light box text properties.
void isGetLightBoxProperties(const char *deviceName)
isGetLightBoxProperties Get light box properties
Provides interface to implement controllable light box/switch device.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
void IERmTimer(int timerid)
Remove the timer with the given timerid, as returned from IEAddTimer() or IEAddPeriodicTimer().
Definition: eventloop.c:602
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
Definition: eventloop.c:582
int errno
#define FLAT_CMD
Definition: flip_flat.cpp:41
#define FLAT_TIMEOUT
Definition: flip_flat.cpp:43
#define FLAT_RES
Definition: flip_flat.cpp:42
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RO
Definition: indiapi.h:184
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:666
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:291
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indidevapi.c:36
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidevapi.c:198
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
#define LOG_WARN(txt)
Definition: indilogger.h:73
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define LOG_INFO(txt)
Definition: indilogger.h:74
#define MAXRBUF
Definition: indiserver.cpp:102
std::vector< uint8_t > buffer
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:371
char name[MAXINDINAME]
Definition: indiapi.h:250