40 char configPort[256] = {0};
50 PortTP[0].
fill(
"PORT",
"Port",
"/dev/cu.usbserial");
52 PortTP[0].
fill(
"PORT",
"Port",
"/dev/ttyUSB0");
57 int autoSearchIndex = 0;
95bool Serial::ISNewText(
const char *dev,
const char *name,
char *texts[],
char *names[],
int n)
112 LOGF_DEBUG(
"Auto search is disabled because %s is not a system port.",
PortTP[0].getText());
147 LOG_INFO(
"Auto search is enabled. When connecting, the driver shall attempt to "
148 "communicate with all available system ports until a connection is "
151 LOG_INFO(
"Auto search is disabled.");
197 std::vector<std::string> systemPorts;
201 if (onePort ==
PortTP[0].getText())
204 systemPorts.push_back(onePort);
210 LOGF_WARN(
"Communication with %s @ %d failed. Starting Auto Search...",
PortTP[0].getText(),
213 std::this_thread::sleep_for(std::chrono::milliseconds(500 + (rand() % 1000)));
217 std::random_device rd;
218 std::minstd_rand g(rd());
219 std::shuffle(systemPorts.begin(), systemPorts.end(), g);
221 std::vector<std::string> doubleSearch = systemPorts;
224 systemPorts.push_back(
PortTP[0].getText());
227 systemPorts.insert(systemPorts.end(), doubleSearch.begin(), doubleSearch.end());
229 for (
const auto &
port : systemPorts)
269 std::this_thread::sleep_for(std::chrono::milliseconds(500 + (rand() % 1000)));
278 LOG_DEBUG(
"Connection successful, attempting handshake...");
311 LOGF_WARN(
"Port %s is already used by another driver or process.",
port);
316 LOGF_ERROR(
"Failed to connect to port (%s). Error: %s",
port, errorMsg);
406 return onSwitch ? atoi(onSwitch->getName()) : 9600;
411#if defined(__APPLE__)
412 static const char *filter_names[] = {
"cu.",
nullptr };
414 static const char *filter_names[] = {
"ttyUSB",
"ttyACM",
nullptr };
418 for (filter = filter_names; *filter; ++filter)
420 if (strstr(entry->d_name, *filter) !=
nullptr)
430 static const char *filter_names[] = {
"usb-",
nullptr };
433 for (filter = filter_names; *filter; ++filter)
435 if (strstr(entry->d_name, *filter) !=
nullptr)
445 static const char *filter_names[] = {
"rfcomm",
nullptr };
448 for (filter = filter_names; *filter; ++filter)
450 if (strstr(entry->d_name, *filter) !=
nullptr)
460 std::vector<std::string> m_Ports;
463 auto searchPath = [&](std::string prefix, uint8_t searchType)
465 struct dirent **namelist;
466 std::vector<std::string> detectedDevices;
478 if (detectedDevices.size() < 10)
480 std::string s(namelist[devCount]->d_name);
481 s.erase(s.find_last_not_of(
" \n\r\t") + 1);
482 detectedDevices.push_back(prefix + s);
486 LOGF_DEBUG(
"Ignoring devices over %d : %s", detectedDevices.size(),
487 namelist[devCount]->d_name);
489 free(namelist[devCount]);
494 return detectedDevices;
499 const std::vector<std::string> serialDevices = searchPath(
"/dev/",
SERIAL_DEV);
500 const std::vector<std::string> usbIDDevices = searchPath(
"/dev/serial/by-id/",
USB_ID_DEV);
501 const std::vector<std::string> btDevices = searchPath(
"/dev/",
BLUETOOTH_DEV);
502 m_Ports.insert(m_Ports.end(), btDevices.begin(), btDevices.end());
507 if (usbIDDevices.size() >= serialDevices.size())
508 m_Ports.insert(m_Ports.end(), usbIDDevices.begin(), usbIDDevices.end());
510 m_Ports.insert(m_Ports.end(), serialDevices.begin(), serialDevices.end());
512 const std::vector<std::string> serialDevices = searchPath(
"/dev/",
SERIAL_DEV);
513 m_Ports.insert(m_Ports.end(), serialDevices.begin(), serialDevices.end());
516 const int pCount = m_Ports.size();
521 LOG_WARN(
"No candidate ports found on the system.");
527 LOGF_INFO(
"Scan complete. Found %d port(s).", pCount);
544 for (
const auto &onePort : m_Ports)
547 std::string
name = onePort.substr(onePort.find_last_of(
"/\\") + 1);
552 std::regex re(
"usb-(.[^-]+)");
554 if (std::regex_search(onePort, match, re))
558 std::regex target(
"FTDI_|UART_|USB_|Bridge_Controller_|to_");
559 label = std::regex_replace(
label, target,
"");
561 if (
label.length() <= 2)
562 label = match.str(1);
577 const bool configPortAvailable =
584 if (pCount == 1 && !configPortAvailable)
587 LOGF_INFO(
"Saved port %s is no longer available. Using the only detected port %s instead.",
590 PortTP[0].setText(m_Ports[0]);
602 if (!configPortAvailable)
609 if (std::regex_search(onePort, portRe))
611 LOGF_INFO(
"Auto-selected port %s based on device name pattern \"%s\".",
613 PortTP[0].setText(onePort);
619 catch (
const std::regex_error &e)
621 LOGF_WARN(
"Port match pattern \"%s\" is not a valid regex: %s",
The Interface class is the base class for all INDI connection plugins.
const char * getDeviceName()
std::function< bool()> Handshake
INDI::DefaultDevice * m_Device
INDI::PropertySwitch RefreshSP
std::string m_PortMatchPattern
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
virtual const char * port()
INDI::PropertySwitch AutoSearchSP
virtual std::string name() override
BaudRate
Supported baud rates.
INDI::PropertySwitch SystemPortSP
std::vector< std::string > m_SystemPorts
INDI::PropertySwitch BaudRateSP
virtual void Activated() override
Activated Function called by the framework when the plugin is activated (i.e. selected by the user)....
void setPortMatchPattern(const std::string &pattern)
setPortMatchPattern Set a regex pattern used to automatically select a serial port from the discovere...
bool Refresh(bool silent=false)
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
virtual void Deactivated() override
Deactivated Function called by the framework when the plugin is deactivated. It is usually used to de...
virtual bool Disconnect() override
Disconnect Disconnect from device.
virtual bool saveConfigItems(FILE *fp) override
void setDefaultPort(const char *port)
setDefaultPort Set default port. Call this function in initProperties() of your driver if you want to...
virtual bool Connect() override
Connect Connect to device via the implemented communication medium. Do not perform any handshakes.
Serial(INDI::DefaultDevice *dev, IPerm permission=IP_RW)
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
virtual bool processHandshake()
virtual std::string label() override
INDI::PropertyText PortTP
const char * getDeviceName() const
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
bool isInitializationComplete() const
isInitializationComplete Check if driver initialization is complete.
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
bool isSimulation() const
void push(WidgetView< T > &&item)
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void save(FILE *f) const
save Save property to configuration file.
const char * getName() const
bool isNameMatch(const char *otherName) const
int findWidgetIndexByName(const char *name) const
bool update(const ISState states[], const char *const names[], int n)
INDI::WidgetViewSwitch * findOnSwitch() const
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
bool update(const char *const texts[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
INDI::PropertyViewText * getText() const
IPerm
Permission hint, with respect to client.
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.
int tty_disconnect(int fd)
Closes a tty connection and flushes the bus.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
int IUGetConfigOnSwitchName(const char *dev, const char *property, char *name, size_t size)
IUGetConfigOnSwitchLabel Opens configuration file and returns the name of the ON switch property,...
int IUGetConfigText(const char *dev, const char *property, const char *member, char *value, int len)
IUGetConfigText Opens configuration file and reads single text property.
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
Combines all INDI Connection Plugins. Each INDI connection plugin is responsible of managing communic...
const char * CONNECTION_TAB
int usb_dev_file_select(const dirent *entry)
int bluetooth_dev_file_select(const dirent *entry)
int serial_dev_file_select(const dirent *entry)
const char * DEVICE_AUTO_SEARCH
Toggle device auto search. If enabled and on connection failure with the default port,...
const char * DEVICE_PORT
Device serial (or bluetooth) connection port. The default value on Linux is /dev/ttyUSB0 while on Mac...
const char * DEVICE_BAUD_RATE
Set device baud rate.