Instrument Neutral Distributed Interface INDI  1.9.5
connectionserial.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2017 Jasem Mutlaq. All rights reserved.
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 *******************************************************************************/
18 
19 #include "connectionserial.h"
20 #include "indistandardproperty.h"
21 #include "indicom.h"
22 #include "indilogger.h"
23 
24 #include <dirent.h>
25 #include <cerrno>
26 #include <cstring>
27 #include <algorithm>
28 #include <thread>
29 #include <chrono>
30 #include <regex>
31 
32 namespace Connection
33 {
34 extern const char *CONNECTION_TAB;
35 
36 Serial::Serial(INDI::DefaultDevice *dev) : Interface(dev, CONNECTION_SERIAL)
37 {
38  char configPort[256] = {0};
39  // Try to load the port from the config file. If that fails, use default port.
40  if (IUGetConfigText(dev->getDeviceName(), INDI::SP::DEVICE_PORT, "PORT", configPort, 256) == 0)
41  {
42  m_ConfigPort = configPort;
43  IUFillText(&PortT[0], "PORT", "Port", configPort);
44  }
45  else
46  {
47 #ifdef __APPLE__
48  IUFillText(&PortT[0], "PORT", "Port", "/dev/cu.usbserial");
49 #else
50  IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyUSB0");
51 #endif
52  }
54  IPS_IDLE);
55 
56  int autoSearchIndex = 0;
57  // Try to load the port from the config file. If that fails, use default port.
59  IUFillSwitch(&AutoSearchS[INDI::DefaultDevice::INDI_ENABLED], "INDI_ENABLED", "Enabled",
60  autoSearchIndex == 0 ? ISS_ON : ISS_OFF);
61  IUFillSwitch(&AutoSearchS[INDI::DefaultDevice::INDI_DISABLED], "INDI_DISABLED", "Disabled",
62  autoSearchIndex == 0 ? ISS_OFF : ISS_ON);
63  IUFillSwitchVector(&AutoSearchSP, AutoSearchS, 2, dev->getDeviceName(), INDI::SP::DEVICE_AUTO_SEARCH, "Auto Search",
65 
66  IUFillSwitch(&RefreshS[0], "Scan Ports", "Scan Ports", ISS_OFF);
67  IUFillSwitchVector(&RefreshSP, RefreshS, 1, dev->getDeviceName(), "DEVICE_PORT_SCAN", "Refresh", CONNECTION_TAB,
68  IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
69 
70  IUFillSwitch(&BaudRateS[0], "9600", "", ISS_ON);
71  IUFillSwitch(&BaudRateS[1], "19200", "", ISS_OFF);
72  IUFillSwitch(&BaudRateS[2], "38400", "", ISS_OFF);
73  IUFillSwitch(&BaudRateS[3], "57600", "", ISS_OFF);
74  IUFillSwitch(&BaudRateS[4], "115200", "", ISS_OFF);
75  IUFillSwitch(&BaudRateS[5], "230400", "", ISS_OFF);
76  IUFillSwitchVector(&BaudRateSP, BaudRateS, 6, dev->getDeviceName(), INDI::SP::DEVICE_BAUD_RATE, "Baud Rate", CONNECTION_TAB,
77  IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
78 
79  // Try to load the port from the config file. If that fails, use default port.
81  // If we have a valid config entry, se it.
82  if (m_ConfigBaudRate >= 0)
83  {
84  IUResetSwitch(&BaudRateSP);
85  BaudRateS[m_ConfigBaudRate].s = ISS_ON;
86  }
87 }
88 
90 {
91  delete[] SystemPortS;
92 }
93 
94 bool Serial::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
95 {
96  if (!strcmp(dev, m_Device->getDeviceName()))
97  {
98  // Serial Port
99  if (!strcmp(name, PortTP.name))
100  {
101  IUUpdateText(&PortTP, texts, names, n);
102  PortTP.s = IPS_OK;
103  IDSetText(&PortTP, nullptr);
104 
105  auto pos = std::find_if(m_SystemPorts.begin(), m_SystemPorts.end(), [&](const std::string onePort)
106  {
107  return !strcmp(PortT[0].text, onePort.c_str());
108  });
109  if (pos != m_SystemPorts.end())
110  {
111  LOGF_DEBUG("Auto search is disabled because %s is not a system port.", PortT[0].text);
112  AutoSearchS[0].s = ISS_OFF;
113  AutoSearchS[1].s = ISS_ON;
114  IDSetSwitch(&AutoSearchSP, nullptr);
115  }
116  }
117  return true;
118  }
119 
120  return false;
121 }
122 
123 bool Serial::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
124 {
125  if (!strcmp(dev, m_Device->getDeviceName()))
126  {
127  // Change Baud Rate
128  if (!strcmp(name, BaudRateSP.name))
129  {
130  IUUpdateSwitch(&BaudRateSP, states, names, n);
131  BaudRateSP.s = IPS_OK;
132  IDSetSwitch(&BaudRateSP, nullptr);
133  return true;
134  }
135 
136  // Auto Search Devices on connection failure
137  if (!strcmp(name, AutoSearchSP.name))
138  {
139  bool wasEnabled = (AutoSearchS[0].s == ISS_ON);
140 
141  IUUpdateSwitch(&AutoSearchSP, states, names, n);
143 
144  // Only display message if there is an actual change
145  if (wasEnabled == false && AutoSearchS[0].s == ISS_ON)
146  LOG_INFO("Auto search is enabled. When connecting, the driver shall attempt to "
147  "communicate with all available system ports until a connection is "
148  "established.");
149  else if (wasEnabled && AutoSearchS[1].s == ISS_ON)
150  LOG_INFO("Auto search is disabled.");
151  IDSetSwitch(&AutoSearchSP, nullptr);
152 
153  return true;
154  }
155 
156  // Refresh Serial Devices
157  if (!strcmp(name, RefreshSP.name))
158  {
160  IDSetSwitch(&RefreshSP, nullptr);
161  return true;
162  }
163 
164  // Check if a system port is selected.
165  if (!strcmp(name, SystemPortSP.name))
166  {
167  IUUpdateSwitch(&SystemPortSP, states, names, n);
168 
169  int index = IUFindOnSwitchIndex(&SystemPortSP);
170  if (index >= 0)
171  {
172  IUSaveText(&PortT[0], m_SystemPorts[index].c_str());
173  IDSetText(&PortTP, nullptr);
174  }
175 
177  IDSetSwitch(&SystemPortSP, nullptr);
178  return true;
179  }
180  }
181 
182  return false;
183 }
184 
185 bool Serial::Connect()
186 {
187  uint32_t baud = atoi(IUFindOnSwitch(&BaudRateSP)->name);
188  if (Connect(PortT[0].text, baud) && processHandshake())
189  return true;
190 
191  // Important, disconnect from port immediately
192  // to release the lock, otherwise another driver will find it busy.
194 
195  // Start auto-search if option was selected and IF we have system ports to try connecting to
196  if (AutoSearchS[0].s == ISS_ON && SystemPortS != nullptr && SystemPortSP.nsp > 1)
197  {
198  LOGF_WARN("Communication with %s @ %d failed. Starting Auto Search...", PortT[0].text,
199  baud);
200 
201  std::this_thread::sleep_for(std::chrono::milliseconds(500 + (rand() % 1000)));
202 
203  // Try to connect "randomly" so that competing devices don't all try to connect to the same
204  // ports at the same time.
205  std::vector<std::string> systemPorts;
206  for (int i = 0; i < SystemPortSP.nsp; i++)
207  {
208  // Only try the same port last again.
209  if (!strcmp(m_SystemPorts[i].c_str(), PortT[0].text))
210  continue;
211 
212  systemPorts.push_back(m_SystemPorts[i].c_str());
213  }
214  std::random_shuffle (systemPorts.begin(), systemPorts.end());
215 
216  std::vector<std::string> doubleSearch = systemPorts;
217 
218  // Try the current port as LAST port again
219  systemPorts.push_back(PortT[0].text);
220 
221  // Double search just in case some items were BUSY in the first pass
222  systemPorts.insert(systemPorts.end(), doubleSearch.begin(), doubleSearch.end());
223 
224  for (const auto &port : systemPorts)
225  {
226  LOGF_INFO("Trying connecting to %s @ %d ...", port.c_str(), baud);
227  if (Connect(port.c_str(), baud) && processHandshake())
228  {
229  IUSaveText(&PortT[0], port.c_str());
230  IDSetText(&PortTP, nullptr);
231 
232 #ifdef __linux__
233  bool saveConfig = false;
234  // Disable auto-search on Linux if not disabled already
236  {
237  saveConfig = true;
240  IDSetSwitch(&AutoSearchSP, nullptr);
241  }
242  // Only save config if different from default port
243  if (m_ConfigPort != std::string(PortT[0].text))
244  {
245  saveConfig = true;
246  }
247 
248  if (saveConfig)
249  m_Device->saveConfig(true);
250 #else
251  // Do not overwrite custom ports because it can be actually cause
252  // temporary failure. For users who use mapped named ports (e.g. /dev/mount), it's not good to override their choice.
253  // So only write to config if the port was a system port.
254  if (std::find(m_SystemPorts.begin(), m_SystemPorts.end(), PortT[0].text) != m_SystemPorts.end())
255  m_Device->saveConfig(true, PortTP.name);
256 #endif
257  return true;
258  }
259 
261  // sleep randomly anytime between 0.5s and ~1.5s
262  // This enables different competing devices to connect
263  std::this_thread::sleep_for(std::chrono::milliseconds(500 + (rand() % 1000)));
264  }
265  }
266 
267  return false;
268 }
269 
271 {
272  LOG_DEBUG("Connection successful, attempting handshake...");
273  bool rc = Handshake();
274  if (rc)
275  {
276  LOGF_INFO("%s is online.", getDeviceName());
277  if (std::string(PortT[0].text) != m_ConfigPort || IUFindOnSwitchIndex(&BaudRateSP) != m_ConfigBaudRate)
278  {
281  }
282  }
283  else
284  LOG_DEBUG("Handshake failed.");
285 
286  return rc;
287 }
288 
289 bool Serial::Connect(const char *port, uint32_t baud)
290 {
291  if (m_Device->isSimulation())
292  return true;
293 
294  int connectrc = 0;
295  char errorMsg[MAXRBUF];
296 
297  LOGF_DEBUG("Connecting to %s @ %d", port, baud);
298 
299  if ((connectrc = tty_connect(port, baud, wordSize, parity, stopBits, &PortFD)) != TTY_OK)
300  {
301  if (connectrc == TTY_PORT_BUSY)
302  {
303  LOGF_WARN("Port %s is already used by another driver or process.", port);
304  return false;
305  }
306 
307  tty_error_msg(connectrc, errorMsg, MAXRBUF);
308  LOGF_ERROR("Failed to connect to port (%s). Error: %s", port, errorMsg);
309  return false;
310  }
311 
312  LOGF_DEBUG("Port FD %d", PortFD);
313 
314  return true;
315 }
316 
317 bool Serial::Disconnect()
318 {
319  if (PortFD > 0)
320  {
322  PortFD = -1;
323  }
324  return true;
325 }
326 
327 void Serial::Activated()
328 {
329  Refresh(true);
334 }
335 
336 void Serial::Deactivated()
337 {
339  delete[] SystemPortS;
340  SystemPortS = nullptr;
345 }
346 
347 bool Serial::saveConfigItems(FILE *fp)
348 {
349  IUSaveConfigText(fp, &PortTP);
352 
353  return true;
354 }
355 
356 void Serial::setDefaultPort(const char *port)
357 {
358  // JM 2021.09.19: Only set default port if configuration port was not loaded already.
359  if (m_ConfigPort.empty())
360  IUSaveText(&PortT[0], port);
362  IDSetText(&PortTP, nullptr);
363 }
364 
365 void Serial::setDefaultBaudRate(BaudRate newRate)
366 {
367  // JM 2021.09.19: Only set default baud rate if configuration baud rate was not loaded already.
368  if (m_ConfigBaudRate == -1)
369  {
371  BaudRateS[newRate].s = ISS_ON;
372  }
373 
375  IDSetSwitch(&BaudRateSP, nullptr);
376 }
377 
378 uint32_t Serial::baud()
379 {
380  return atoi(IUFindOnSwitch(&BaudRateSP)->name);
381 }
382 
383 int serial_dev_file_select(const dirent *entry)
384 {
385 #if defined(__APPLE__)
386  static const char *filter_names[] = { "cu.", nullptr };
387 #else
388  static const char *filter_names[] = { "ttyUSB", "ttyACM", nullptr };
389 #endif
390  const char **filter;
391 
392  for (filter = filter_names; *filter; ++filter)
393  {
394  if (strstr(entry->d_name, *filter) != nullptr)
395  {
396  return (true);
397  }
398  }
399  return (false);
400 }
401 
402 int usb_dev_file_select(const dirent *entry)
403 {
404  static const char *filter_names[] = { "usb-", nullptr };
405  const char **filter;
406 
407  for (filter = filter_names; *filter; ++filter)
408  {
409  if (strstr(entry->d_name, *filter) != nullptr)
410  {
411  return (true);
412  }
413  }
414  return (false);
415 }
416 
417 int bluetooth_dev_file_select(const dirent *entry)
418 {
419  static const char *filter_names[] = {"rfcomm", nullptr };
420  const char **filter;
421 
422  for (filter = filter_names; *filter; ++filter)
423  {
424  if (strstr(entry->d_name, *filter) != nullptr)
425  {
426  return (true);
427  }
428  }
429  return (false);
430 }
431 
432 bool Serial::Refresh(bool silent)
433 {
434  std::vector<std::string> m_Ports;
435 
436  // 0 Serial Only, 1 By USB-ID, 2 Bluetooth
437  auto searchPath = [&](std::string prefix, uint8_t searchType)
438  {
439  struct dirent **namelist;
440  std::vector<std::string> detectedDevices;
441  int devCount = 0;
442  if (searchType == SERIAL_DEV)
443  devCount = scandir(prefix.c_str(), &namelist, serial_dev_file_select, alphasort);
444  else if (searchType == USB_ID_DEV)
445  devCount = scandir(prefix.c_str(), &namelist, usb_dev_file_select, alphasort);
446  else
447  devCount = scandir(prefix.c_str(), &namelist, bluetooth_dev_file_select, alphasort);
448  if (devCount > 0)
449  {
450  while (devCount--)
451  {
452  if (detectedDevices.size() < 10)
453  {
454  std::string s(namelist[devCount]->d_name);
455  s.erase(s.find_last_not_of(" \n\r\t") + 1);
456  detectedDevices.push_back(prefix + s);
457  }
458  else
459  {
460  LOGF_DEBUG("Ignoring devices over %d : %s", detectedDevices.size(),
461  namelist[devCount]->d_name);
462  }
463  free(namelist[devCount]);
464  }
465  free(namelist);
466  }
467 
468  return detectedDevices;
469  };
470 
471 #ifdef __linux__
472  // Search for serial, usb, and bluetooth devices.
473  const std::vector<std::string> serialDevices = searchPath("/dev/", SERIAL_DEV);
474  const std::vector<std::string> usbIDDevices = searchPath("/dev/serial/by-id/", USB_ID_DEV);
475  const std::vector<std::string> btDevices = searchPath("/dev/", BLUETOOTH_DEV);
476  m_Ports.insert(m_Ports.end(), btDevices.begin(), btDevices.end());
477  // Linux Kernel does not add identical VID:PID adapter to serial/by-id
478  // Therefore, we check if there is a 1:1 correspondence between serial/by-id and /dev/ttyUSBX nodes
479  // In case we have more by-id devices then /dev/ttyUSBX, we use them since these symlinks are more reusable in subsequence
480  // sessions
481  if (usbIDDevices.size() >= serialDevices.size())
482  m_Ports.insert(m_Ports.end(), usbIDDevices.begin(), usbIDDevices.end());
483  else
484  m_Ports.insert(m_Ports.end(), serialDevices.begin(), serialDevices.end());
485 #else
486  const std::vector<std::string> serialDevices = searchPath("/dev/", SERIAL_DEV);
487  m_Ports.insert(m_Ports.end(), serialDevices.begin(), serialDevices.end());
488 #endif
489 
490  const int pCount = m_Ports.size();
491 
492  if (pCount == 0)
493  {
494  if (!silent)
495  LOG_WARN("No candidate ports found on the system.");
496  return false;
497  }
498  else
499  {
500  if (!silent)
501  LOGF_INFO("Scan complete. Found %d port(s).", pCount);
502  }
503 
504  // Check if anything changed and the property is already defined then we return.
505  if (m_Ports == m_SystemPorts && SystemPortS)
506  {
508  return true;
509  }
510 
511  m_SystemPorts = m_Ports;
512 
513  if (SystemPortS)
515 
516  delete[] SystemPortS;
517 
518  SystemPortS = new ISwitch[pCount];
519  ISwitch *sp = SystemPortS;
520 
521  for (const auto &onePort : m_Ports)
522  {
523  // Simplify label by removing directory prefix
524  std::string name = onePort.substr(onePort.find_last_of("/\\") + 1);
525  std::string label = name;
526 
527  // Remove Linux extra stuff to simplify string
528 #ifdef __linux__
529  std::regex re("usb-(.[^-]+)");
530  std::smatch match;
531  if (std::regex_search(onePort, match, re))
532  {
533  name = label = match.str(1);
534  // Simplify further by removing non-unique strings
535  std::regex target("FTDI_|UART_|USB_|Bridge_Controller_|to_");
536  label = std::regex_replace(label, target, "");
537  // Protect against too-short of a label
538  if (label.length() <= 2)
539  label = match.str(1);
540  }
541 #endif
542  IUFillSwitch(sp++, name.c_str(), label.c_str(), ISS_OFF);
543  }
544 
545  IUFillSwitchVector(&SystemPortSP, SystemPortS, pCount, m_Device->getDeviceName(), "SYSTEM_PORTS", "System Ports",
547 
549 
550  // If we have one physical port only, set it to the device port if the current port
551  // is the default port.
552  if (pCount == 1 && std::string(PortT[0].text) == m_ConfigPort)
553  IUSaveText(&PortT[0], m_Ports[0].c_str());
554  return true;
555 }
556 }
Connection::Serial::port
virtual const char * port()
Definition: connectionserial.h:108
Connection::Serial::parity
uint8_t parity
Definition: connectionserial.h:227
Connection::Serial::m_ConfigBaudRate
int m_ConfigBaudRate
Definition: connectionserial.h:231
indistandardproperty.h
Connection::Serial::wordSize
uint8_t wordSize
Definition: connectionserial.h:226
Connection::Interface::Handshake
std::function< bool()> Handshake
Definition: connectioninterface.h:129
Connection::usb_dev_file_select
int usb_dev_file_select(const dirent *entry)
Definition: connectionserial.cpp:418
LOGF_ERROR
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
Connection::Serial::Connect
virtual bool Connect() override
Connect Connect to device via the implemented communication medium. Do not perform any handshakes.
Definition: connectionserial.cpp:201
ISwitch
One switch descriptor.
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
Connection::Serial::stopBits
uint8_t stopBits
Definition: connectionserial.h:228
IDSetText
void IDSetText(const ITextVectorProperty *t, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing text vector property.
tty_disconnect
int tty_disconnect(int fd)
Closes a tty connection and flushes the bus.
Definition: indicom.c:1137
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
Connection::Serial::Refresh
bool Refresh(bool silent=false)
Definition: connectionserial.cpp:448
INDI::DefaultDevice::isSimulation
bool isSimulation() const
Definition: defaultdevice.cpp:734
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
Connection::Serial::Serial
Serial(INDI::DefaultDevice *dev)
Definition: connectionserial.cpp:52
Connection::Serial::AutoSearchSP
ISwitchVectorProperty AutoSearchSP
Definition: connectionserial.h:215
IUFillTextVector
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: indidriver.c:477
INDI::DefaultDevice::isInitializationComplete
bool isInitializationComplete() const
isInitializationComplete Check if driver initialization is complete.
Definition: defaultdevice.cpp:1263
Connection::Serial::PortTP
ITextVectorProperty PortTP
Definition: connectionserial.h:208
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
Connection::Serial::~Serial
virtual ~Serial()
Definition: connectionserial.cpp:105
INDI::SP::DEVICE_BAUD_RATE
const char * DEVICE_BAUD_RATE
Set device baud rate.
Definition: indistandardproperty.cpp:67
IUFillText
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: indidriver.c:369
IUUpdateText
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:259
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
IUResetSwitch
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indicom.c:1442
Connection::Serial::Disconnect
virtual bool Disconnect() override
Disconnect Disconnect from device.
Definition: connectionserial.cpp:333
Connection::Interface::getDeviceName
const char * getDeviceName()
Definition: connectioninterface.cpp:53
tty_error_msg
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1156
Connection::Serial::m_ConfigPort
std::string m_ConfigPort
Definition: connectionserial.h:230
Connection::Serial::BLUETOOTH_DEV
@ BLUETOOTH_DEV
Definition: connectionserial.h:204
IUFindOnSwitch
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *sp)
Returns the first ON switch it finds in the vector switch property.
Definition: indicom.c:1414
indilogger.h
Connection::Serial::name
virtual std::string name() override
Definition: connectionserial.h:95
Connection::Serial::setDefaultPort
void setDefaultPort(const char *port)
setDefaultPort Set default port. Call this function in initProperties() of your driver if you want to...
Definition: connectionserial.cpp:372
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
Connection::Serial::setDefaultBaudRate
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
Definition: connectionserial.cpp:381
Connection::Serial::SERIAL_DEV
@ SERIAL_DEV
Definition: connectionserial.h:202
IUGetConfigText
int IUGetConfigText(const char *dev, const char *property, const char *member, char *value, int len)
IUGetConfigText Opens configuration file and reads single text property.
Definition: indidriver.c:1448
Connection::Serial::SystemPortSP
ISwitchVectorProperty SystemPortSP
Definition: connectionserial.h:218
Connection::Serial::label
virtual std::string label() override
Definition: connectionserial.h:100
Connection::Serial::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
Definition: connectionserial.cpp:363
IUSaveConfigText
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indicom.c:1460
_ISwitchVectorProperty::nsp
int nsp
Definition: indiapi.h:386
LOGF_WARN
#define LOGF_WARN(fmt,...)
Definition: indilogger.h:81
IUFillSwitchVector
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:412
INDI::BaseDevice::INDI_ENABLED
@ INDI_ENABLED
Definition: basedevice.h:64
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
Connection::Interface::m_Device
INDI::DefaultDevice * m_Device
Definition: connectioninterface.h:130
connectionserial.h
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
Connection::CONNECTION_TAB
const char * CONNECTION_TAB
CONNECTION_TAB Where all device connection settings (serial, usb, ethernet) are defined and controlle...
Definition: connectioninterface.cpp:41
tty_connect
int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd)
Establishes a tty connection to a terminal device.
Definition: indicom.c:937
Connection::Serial::RefreshSP
ISwitchVectorProperty RefreshSP
Definition: connectionserial.h:221
ISR_ATMOST1
@ ISR_ATMOST1
Definition: indiapi.h:173
IUUpdateSwitch
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:171
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
Connection::Serial::m_SystemPorts
std::vector< std::string > m_SystemPorts
Definition: connectionserial.h:232
LOG_DEBUG
#define LOG_DEBUG(txt)
Definition: indilogger.h:75
Connection::Serial::USB_ID_DEV
@ USB_ID_DEV
Definition: connectionserial.h:203
Connection::Serial::PortFD
int PortFD
Definition: connectionserial.h:223
LOGF_INFO
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
Connection::Serial::ISNewText
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Definition: connectionserial.cpp:110
Connection::Serial::BaudRateSP
ISwitchVectorProperty BaudRateSP
Definition: connectionserial.h:212
Connection
Combines all INDI Connection Plugins. Each INDI connection plugin is responsible of managing communic...
Definition: arduino_st4.h:33
IUSaveText
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indicom.c:1449
name
const char * name
Definition: indiserver.c:116
Connection::Serial::AutoSearchS
ISwitch AutoSearchS[2]
Definition: connectionserial.h:214
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
Connection::Serial::baud
virtual uint32_t baud()
Definition: connectionserial.cpp:394
Connection::Serial::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Definition: connectionserial.cpp:139
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
Connection::Serial::processHandshake
virtual bool processHandshake()
Definition: connectionserial.cpp:286
INDI::DefaultDevice::saveConfig
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
Definition: defaultdevice.cpp:221
IP_RW
@ IP_RW
Definition: indiapi.h:185
LOG_WARN
#define LOG_WARN(txt)
Definition: indilogger.h:73
INDI::SP::DEVICE_PORT
const char * DEVICE_PORT
Device serial (or bluetooth) connection port. The default value on Linux is /dev/ttyUSB0 while on Mac...
Definition: indistandardproperty.cpp:64
TTY_PORT_BUSY
@ TTY_PORT_BUSY
Definition: indicom.h:103
Connection::serial_dev_file_select
int serial_dev_file_select(const dirent *entry)
Definition: connectionserial.cpp:399
Connection::Serial::SystemPortS
ISwitch * SystemPortS
Definition: connectionserial.h:217
Connection::Serial::Deactivated
virtual void Deactivated() override
Deactivated Function called by the framework when the plugin is deactivated. It is usually used to de...
Definition: connectionserial.cpp:352
ISState
ISState
Switch state.
Definition: indiapi.h:148
INDI::SP::DEVICE_AUTO_SEARCH
const char * DEVICE_AUTO_SEARCH
Toggle device auto search. If enabled and on connection failure with the default port,...
Definition: indistandardproperty.cpp:65
IUGetConfigOnSwitchIndex
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
Definition: indidriver.c:1270
IUFindOnSwitchIndex
int IUFindOnSwitchIndex(const ISwitchVectorProperty *sp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indicom.c:1424
Connection::Serial::PortT
IText PortT[1]
Definition: connectionserial.h:209
IUSaveConfigSwitch
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indicom.c:1465
INDI::DefaultDevice
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
Definition: defaultdevice.h:118
TTY_OK
@ TTY_OK
Definition: indicom.h:94
Connection::Serial::Activated
virtual void Activated() override
Activated Function called by the framework when the plugin is activated (i.e. selected by the user)....
Definition: connectionserial.cpp:343
PortTP
ITextVectorProperty PortTP
Definition: magellan1.cpp:64
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
Connection::Serial::BaudRateS
ISwitch BaudRateS[6]
Definition: connectionserial.h:211
Connection::bluetooth_dev_file_select
int bluetooth_dev_file_select(const dirent *entry)
Definition: connectionserial.cpp:433
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
IUFillSwitch
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidriver.c:320
INDI::BaseDevice::INDI_DISABLED
@ INDI_DISABLED
Definition: basedevice.h:65
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
ISS_ON
@ ISS_ON
Definition: indiapi.h:151