32 #include <arpa/inet.h>
33 #include <netinet/in.h>
34 #include <sys/socket.h>
61 int connectionTypeIndex = 0;
69 int autoSearchIndex = 1;
84 bool TCP::ISNewText(
const char *dev,
const char *name,
char *texts[],
char *names[],
int n)
128 LOG_INFO(
"LAN search is enabled. When connecting, the driver shall attempt to "
129 "communicate with all devices on the local network until a connection is "
132 LOG_INFO(
"Auto search is disabled.");
147 struct sockaddr_in serv_addr;
148 struct hostent *hp =
nullptr;
158 LOGF_INFO(
"Connecting to %s@%s ...", hostname.c_str(),
port.c_str());
160 LOGF_DEBUG(
"Connecting to %s@%s ...", hostname.c_str(),
port.c_str());
164 hp = gethostbyname(hostname.c_str());
168 LOG_ERROR(
"Failed to lookup IP Address or hostname.");
172 memset(&serv_addr, 0,
sizeof(serv_addr));
173 serv_addr.sin_family = AF_INET;
174 serv_addr.sin_addr.s_addr = ((
struct in_addr *)(hp->h_addr_list[0]))->s_addr;
175 serv_addr.sin_port = htons(atoi(
port.c_str()));
180 socketType = SOCK_STREAM;
184 socketType = SOCK_DGRAM;
187 if ((
m_SockFD = socket(AF_INET, socketType, 0)) < 0)
194 setsockopt(
m_SockFD, SOL_SOCKET, SO_RCVTIMEO, &ts,
sizeof(
struct timeval));
195 setsockopt(
m_SockFD, SOL_SOCKET, SO_SNDTIMEO, &ts,
sizeof(
struct timeval));
198 if (::connect(
m_SockFD, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
201 LOGF_ERROR(
"Failed to connect to %s@%s: %s.", hostname.c_str(),
port.c_str(), strerror(
errno));
218 LOG_ERROR(
"Error! Server address is missing or invalid.");
222 bool handshakeResult =
true;
223 std::string hostname =
AddressT[0].text;
232 handshakeResult =
false;
233 std::regex ipv4(
"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
234 const auto isIPv4 = regex_match(hostname, ipv4);
240 LOGF_DEBUG(
"Connection to %s@%s is successful, attempting handshake...", hostname.c_str(),
port.c_str());
254 if (handshakeResult ==
false &&
258 size_t found = hostname.find_last_of(
".");
260 if (found != std::string::npos)
263 const auto sourceSubnet = hostname.substr(0, found);
264 std::deque<std::string> subnets;
268 for (
auto &oneInterfaceAddress : addrs_ipv4)
271 if (oneInterfaceAddress.rfind(
"127", 0) == 0)
274 size_t found = oneInterfaceAddress.find_last_of(
".");
275 if (found != std::string::npos)
278 const auto targetSubnet = oneInterfaceAddress.substr(0, found);
280 if (targetSubnet == sourceSubnet)
281 subnets.push_front(targetSubnet);
283 subnets.push_back(targetSubnet);
288 for (
auto &oneSubnet : subnets)
290 LOGF_INFO(
"Searching %s subnet, this operation will take a few minutes to complete. Stand by...", oneSubnet.c_str());
294 for (
int i = 1; i < 255; i++)
297 if (newAddress == hostname)
303 LOGF_DEBUG(
"Connection to %s@%s is successful, attempting handshake...", hostname.c_str(),
port.c_str());
307 hostname = newAddress;
339 return handshakeResult;
407 snprintf(portStr, 8,
"%d", addressPort);
The Interface class is the base class for all INDI connection plugins.
virtual Type type()
type Return connection type
const char * getDeviceName()
std::function< bool()> Handshake
INDI::DefaultDevice * m_Device
void setDefaultHost(const char *addressHost)
ISwitchVectorProperty TcpUdpSP
int m_ConfigConnectionType
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
static constexpr uint8_t SOCKET_TIMEOUT
void setLANSearchEnabled(bool enabled)
virtual std::string name() override
virtual bool Disconnect() override
Disconnect Disconnect from device.
void setConnectionType(int type)
TODO should be renamed to setDefaultConnectionType.
virtual void Activated() override
Activated Function called by the framework when the plugin is activated (i.e. selected by the user)....
void setDefaultPort(uint32_t addressPort)
virtual bool Connect() override
Connect Connect to device via the implemented communication medium. Do not perform any handshakes.
virtual uint32_t port() const
virtual bool saveConfigItems(FILE *fp) override
ISwitchVectorProperty LANSearchSP
bool establishConnection(const std::string &hostname, const std::string &port, int timeout=-1)
establishConnection Create a socket connection to the host and port. If successful,...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
ITextVectorProperty AddressTP
Properties.
virtual void Deactivated() override
Deactivated Function called by the framework when the plugin is deactivated. It is usually used to de...
TCP(INDI::DefaultDevice *dev)
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 IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
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.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
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.
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.
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
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.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector 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 ...
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
Combines all INDI Connection Plugins. Each INDI connection plugin is responsible of managing communic...
const char * CONNECTION_TAB
const char * DEVICE_AUTO_SEARCH
Toggle device auto search. If enabled and on connection failure with the default port,...
const char * DEVICE_ADDRESS
Device hostname and port. It is part of Connection::TCPInterface to manage connections to devices ove...
const char * DEVICE_LAN_SEARCH
Toggle device LAN search. If the initial handshake with the specified hostname and port number fails,...
std::vector< std::string > getInterfaceAddressesV4()
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values