1 /* nutclient.cpp - nutclient C++ library implementation
3 Copyright (C) 2012 Emilien Kia <emilien.kia@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "nutclient.h"
28 /* Windows/Linux Socket compatibility layer: */
29 /* Thanks to Benjamin Roux (http://broux.developpez.com/articles/c/sockets/) */
31 # include <winsock2.h>
33 # include <sys/types.h>
34 # include <sys/socket.h>
35 # include <netinet/in.h>
36 # include <arpa/inet.h>
37 # include <unistd.h> /* close */
38 # include <netdb.h> /* gethostbyname */
40 # define INVALID_SOCKET -1
41 # define SOCKET_ERROR -1
42 # define closesocket(s) close(s)
44 typedef struct sockaddr_in SOCKADDR_IN
;
45 typedef struct sockaddr SOCKADDR
;
46 typedef struct in_addr IN_ADDR
;
48 /* End of Windows/Linux Socket compatibility layer: */
51 /* Include nut common utility functions or define simple ones if not */
54 #else /* HAVE_NUTCOMMON */
57 static inline void *xmalloc(size_t size
){return malloc(size
);}
58 static inline void *xcalloc(size_t number
, size_t size
){return calloc(number
, size
);}
59 static inline void *xrealloc(void *ptr
, size_t size
){return realloc(ptr
, size
);}
60 static inline char *xstrdup(const char *string
){return strdup(string
);}
61 #endif /* HAVE_NUTCOMMON */
67 SystemException::SystemException():
72 std::string
SystemException::err()
75 return "Undefined system error";
78 std::stringstream str
;
79 str
<< "System error " << errno
<< ": " << strerror(errno
);
89 * Internal socket wrapper.
90 * Provides only client socket functions.
92 * Implemented as separate internal class to easily hide plateform specificities.
99 void connect(const std::string
& host
, int port
)throw(nut::IOException
);
101 bool isConnected()const;
103 void setTimeout(long timeout
);
104 bool hasTimeout()const{return _tv
.tv_sec
>=0;}
106 size_t read(void* buf
, size_t sz
)throw(nut::IOException
);
107 size_t write(const void* buf
, size_t sz
)throw(nut::IOException
);
109 std::string
read()throw(nut::IOException
);
110 void write(const std::string
& str
)throw(nut::IOException
);
116 std::string _buffer
; /* Received buffer, string because data should be text only. */
120 _sock(INVALID_SOCKET
),
127 void Socket::setTimeout(long timeout
)
129 _tv
.tv_sec
= timeout
;
132 void Socket::connect(const std::string
& host
, int port
)throw(nut::IOException
)
135 struct addrinfo hints
, *res
, *ai
;
136 char sport
[NI_MAXSERV
];
140 socklen_t error_size
;
146 throw nut::UnknownHostException();
149 snprintf(sport
, sizeof(sport
), "%hu", (unsigned short int)port
);
151 memset(&hints
, 0, sizeof(hints
));
152 hints
.ai_family
= AF_UNSPEC
;
153 hints
.ai_socktype
= SOCK_STREAM
;
154 hints
.ai_protocol
= IPPROTO_TCP
;
156 while ((v
= getaddrinfo(host
.c_str(), sport
, &hints
, &res
)) != 0) {
162 throw nut::UnknownHostException();
164 throw nut::SystemException();
166 throw nut::NutException("Out of memory");
168 throw nut::NutException("Unknown error");
172 for (ai
= res
; ai
!= NULL
; ai
= ai
->ai_next
) {
174 sock_fd
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
183 throw nut::SystemException();
188 /* non blocking connect */
190 fd_flags
= fcntl(sock_fd
, F_GETFL
);
191 fd_flags
|= O_NONBLOCK
;
192 fcntl(sock_fd
, F_SETFL
, fd_flags
);
195 while ((v
= ::connect(sock_fd
, ai
->ai_addr
, ai
->ai_addrlen
)) < 0) {
196 if(errno
== EINPROGRESS
) {
198 FD_SET(sock_fd
, &wfds
);
199 select(sock_fd
+1,NULL
,&wfds
,NULL
, hasTimeout()?&_tv
:NULL
);
200 if (FD_ISSET(sock_fd
, &wfds
)) {
201 error_size
= sizeof(error
);
202 getsockopt(sock_fd
,SOL_SOCKET
,SO_ERROR
,
205 /* connect successful */
226 // ups->upserror = UPSCLI_ERR_CONNFAILURE;
227 // ups->syserrno = errno;
238 /* switch back to blocking operation */
240 fd_flags
= fcntl(sock_fd
, F_GETFL
);
241 fd_flags
&= ~O_NONBLOCK
;
242 fcntl(sock_fd
, F_SETFL
, fd_flags
);
246 // ups->upserror = 0;
247 // ups->syserrno = 0;
254 throw nut::IOException("Cannot connect to host");
259 struct hostent
*hostinfo
= NULL
;
260 SOCKADDR_IN sin
= { 0 };
261 hostinfo
= ::gethostbyname(host
.c_str());
262 if(hostinfo
== NULL
) /* Host doesnt exist */
264 throw nut::UnknownHostException();
268 _sock
= ::socket(PF_INET
, SOCK_STREAM
, 0);
269 if(_sock
== INVALID_SOCKET
)
271 throw nut::IOException("Cannot create socket");
275 sin
.sin_addr
= *(IN_ADDR
*) hostinfo
->h_addr
;
276 sin
.sin_port
= htons(port
);
277 sin
.sin_family
= AF_INET
;
278 if(::connect(_sock
,(SOCKADDR
*) &sin
, sizeof(SOCKADDR
)) == SOCKET_ERROR
)
280 _sock
= INVALID_SOCKET
;
281 throw nut::IOException("Cannot connect to host");
286 void Socket::disconnect()
288 if(_sock
!= INVALID_SOCKET
)
290 ::closesocket(_sock
);
291 _sock
= INVALID_SOCKET
;
296 bool Socket::isConnected()const
298 return _sock
!=INVALID_SOCKET
;
301 size_t Socket::read(void* buf
, size_t sz
)throw(nut::IOException
)
305 throw nut::NotConnectedException();
313 int ret
= select(_sock
+1, &fds
, NULL
, NULL
, &_tv
);
315 throw nut::TimeoutException();
319 ssize_t res
= ::read(_sock
, buf
, sz
);
323 throw nut::IOException("Error while reading on socket");
328 size_t Socket::write(const void* buf
, size_t sz
)throw(nut::IOException
)
332 throw nut::NotConnectedException();
340 int ret
= select(_sock
+1, NULL
, &fds
, NULL
, &_tv
);
342 throw nut::TimeoutException();
346 ssize_t res
= ::write(_sock
, buf
, sz
);
350 throw nut::IOException("Error while writing on socket");
355 std::string
Socket::read()throw(nut::IOException
)
362 // Look at already read data in _buffer
365 size_t idx
= _buffer
.find('\n');
366 if(idx
!=std::string::npos
)
368 res
+= _buffer
.substr(0, idx
);
369 _buffer
.erase(0, idx
+1);
376 size_t sz
= read(&buff
, 256);
377 _buffer
.assign(buff
, sz
);
381 void Socket::write(const std::string
& str
)throw(nut::IOException
)
383 // write(str.c_str(), str.size());
385 std::string buff
= str
+ "\n";
386 write(buff
.c_str(), buff
.size());
389 }/* namespace internal */
394 * Client implementation
406 bool Client::hasDevice(const std::string
& dev
)throw(NutException
)
408 std::set
<std::string
> devs
= getDeviceNames();
409 return devs
.find(dev
) != devs
.end();
412 Device
Client::getDevice(const std::string
& name
)throw(NutException
)
415 return Device(this, name
);
417 return Device(NULL
, "");
420 std::set
<Device
> Client::getDevices()throw(NutException
)
422 std::set
<Device
> res
;
424 std::set
<std::string
> devs
= getDeviceNames();
425 for(std::set
<std::string
>::iterator it
=devs
.begin(); it
!=devs
.end(); ++it
)
427 res
.insert(Device(this, *it
));
433 bool Client::hasDeviceVariable(const std::string
& dev
, const std::string
& name
)throw(NutException
)
435 std::set
<std::string
> names
= getDeviceVariableNames(dev
);
436 return names
.find(name
) != names
.end();
439 std::map
<std::string
,std::vector
<std::string
> > Client::getDeviceVariableValues(const std::string
& dev
)throw(NutException
)
441 std::map
<std::string
,std::vector
<std::string
> > res
;
443 std::set
<std::string
> names
= getDeviceVariableNames(dev
);
444 for(std::set
<std::string
>::iterator it
=names
.begin(); it
!=names
.end(); ++it
)
446 const std::string
& name
= *it
;
447 res
[name
] = getDeviceVariableValue(dev
, name
);
453 bool Client::hasDeviceCommand(const std::string
& dev
, const std::string
& name
)throw(NutException
)
455 std::set
<std::string
> names
= getDeviceCommandNames(dev
);
456 return names
.find(name
) != names
.end();
462 * TCP Client implementation
466 TcpClient::TcpClient():
470 _socket(new internal::Socket
)
472 // Do not connect now
475 TcpClient::TcpClient(const std::string
& host
, int port
)throw(IOException
):
477 _socket(new internal::Socket
)
482 TcpClient::~TcpClient()
487 void TcpClient::connect(const std::string
& host
, int port
)throw(IOException
)
494 void TcpClient::connect()throw(nut::IOException
)
496 _socket
->connect(_host
, _port
);
499 std::string
TcpClient::getHost()const
504 int TcpClient::getPort()const
509 bool TcpClient::isConnected()const
511 return _socket
->isConnected();
514 void TcpClient::disconnect()
516 _socket
->disconnect();
519 void TcpClient::setTimeout(long timeout
)
524 long TcpClient::getTimeout()const
529 void TcpClient::authenticate(const std::string
& user
, const std::string
& passwd
)
532 detectError(sendQuery("USERNAME " + user
));
533 detectError(sendQuery("PASSWORD " + passwd
));
536 void TcpClient::logout()throw(NutException
)
538 detectError(sendQuery("LOGOUT"));
539 _socket
->disconnect();
542 Device
TcpClient::getDevice(const std::string
& name
)throw(NutException
)
546 get("UPSDESC", name
);
548 catch(NutException
& ex
)
550 if(ex
.str()=="UNKNOWN-UPS")
551 return Device(NULL
, "");
555 return Device(this, name
);
558 std::set
<std::string
> TcpClient::getDeviceNames()throw(NutException
)
560 std::set
<std::string
> res
;
562 std::vector
<std::vector
<std::string
> > devs
= list("UPS");
563 for(std::vector
<std::vector
<std::string
> >::iterator it
=devs
.begin();
564 it
!=devs
.end(); ++it
)
566 std::string id
= (*it
)[0];
574 std::string
TcpClient::getDeviceDescription(const std::string
& name
)throw(NutException
)
576 return get("UPSDESC", name
)[0];
579 std::set
<std::string
> TcpClient::getDeviceVariableNames(const std::string
& dev
)throw(NutException
)
581 std::set
<std::string
> set
;
583 std::vector
<std::vector
<std::string
> > res
= list("VAR", dev
);
584 for(size_t n
=0; n
<res
.size(); ++n
)
586 set
.insert(res
[n
][0]);
592 std::set
<std::string
> TcpClient::getDeviceRWVariableNames(const std::string
& dev
)throw(NutException
)
594 std::set
<std::string
> set
;
596 std::vector
<std::vector
<std::string
> > res
= list("RW", dev
);
597 for(size_t n
=0; n
<res
.size(); ++n
)
599 set
.insert(res
[n
][0]);
605 std::string
TcpClient::getDeviceVariableDescription(const std::string
& dev
, const std::string
& name
)throw(NutException
)
607 return get("DESC", dev
+ " " + name
)[0];
610 std::vector
<std::string
> TcpClient::getDeviceVariableValue(const std::string
& dev
, const std::string
& name
)throw(NutException
)
612 return get("VAR", dev
+ " " + name
);
615 std::map
<std::string
,std::vector
<std::string
> > TcpClient::getDeviceVariableValues(const std::string
& dev
)throw(NutException
)
618 std::map
<std::string
,std::vector
<std::string
> > map
;
620 std::vector
<std::vector
<std::string
> > res
= list("VAR", dev
);
621 for(size_t n
=0; n
<res
.size(); ++n
)
623 std::vector
<std::string
>& vals
= res
[n
];
624 std::string var
= vals
[0];
625 vals
.erase(vals
.begin());
632 void TcpClient::setDeviceVariable(const std::string
& dev
, const std::string
& name
, const std::string
& value
)throw(NutException
)
634 std::string query
= "SET VAR " + dev
+ " " + name
+ " " + escape(value
);
635 detectError(sendQuery(query
));
638 void TcpClient::setDeviceVariable(const std::string
& dev
, const std::string
& name
, const std::vector
<std::string
>& values
)throw(NutException
)
640 std::string query
= "SET VAR " + dev
+ " " + name
;
641 for(size_t n
=0; n
<values
.size(); ++n
)
643 query
+= " " + escape(values
[n
]);
645 detectError(sendQuery(query
));
648 std::set
<std::string
> TcpClient::getDeviceCommandNames(const std::string
& dev
)throw(NutException
)
650 std::set
<std::string
> cmds
;
652 std::vector
<std::vector
<std::string
> > res
= list("CMD", dev
);
653 for(size_t n
=0; n
<res
.size(); ++n
)
655 cmds
.insert(res
[n
][0]);
661 std::string
TcpClient::getDeviceCommandDescription(const std::string
& dev
, const std::string
& name
)throw(NutException
)
663 return get("CMDDESC", dev
+ " " + name
)[0];
666 void TcpClient::executeDeviceCommand(const std::string
& dev
, const std::string
& name
)throw(NutException
)
668 detectError(sendQuery("INSTCMD " + dev
+ " " + name
));
671 void TcpClient::deviceLogin(const std::string
& dev
)throw(NutException
)
673 detectError(sendQuery("LOGIN " + dev
));
676 void TcpClient::deviceMaster(const std::string
& dev
)throw(NutException
)
678 detectError(sendQuery("MASTER " + dev
));
681 void TcpClient::deviceForcedShutdown(const std::string
& dev
)throw(NutException
)
683 detectError(sendQuery("FSD " + dev
));
686 int TcpClient::deviceGetNumLogins(const std::string
& dev
)throw(NutException
)
688 std::string num
= get("NUMLOGINS", dev
)[0];
689 return atoi(num
.c_str());
693 std::vector
<std::string
> TcpClient::get
694 (const std::string
& subcmd
, const std::string
& params
) throw(NutException
)
696 std::string req
= subcmd
;
701 std::string res
= sendQuery("GET " + req
);
703 if(res
.substr(0, req
.size()) != req
)
705 throw NutException("Invalid response");
708 return explode(res
, req
.size());
711 std::vector
<std::vector
<std::string
> > TcpClient::list
712 (const std::string
& subcmd
, const std::string
& params
) throw(NutException
)
714 std::string req
= subcmd
;
719 std::string res
= sendQuery("LIST " + req
);
721 if(res
!= ("BEGIN LIST " + req
))
723 throw NutException("Invalid response");
726 std::vector
<std::vector
<std::string
> > arr
;
729 res
= _socket
->read();
731 if(res
== ("END LIST " + req
))
735 if(res
.substr(0, req
.size()) == req
)
737 arr
.push_back(explode(res
, req
.size()));
741 throw NutException("Invalid response");
746 std::string
TcpClient::sendQuery(const std::string
& req
)throw(IOException
)
749 return _socket
->read();
752 void TcpClient::detectError(const std::string
& req
)throw(NutException
)
754 if(req
.substr(0,3)=="ERR")
756 throw NutException(req
.substr(4));
760 std::vector
<std::string
> TcpClient::explode(const std::string
& str
, size_t begin
)
762 std::vector
<std::string
> res
;
773 for(size_t idx
=begin
; idx
<str
.size(); ++idx
)
779 if(c
==' ' /* || c=='\t' */)
783 state
= QUOTED_STRING
;
787 state
= SIMPLE_ESCAPE
;
789 /* What about bad characters ? */
793 state
= SIMPLE_STRING
;
797 if(c
==' ' /* || c=='\t' */)
799 /* if(!temp.empty()) : Must not occur */
806 state
= SIMPLE_ESCAPE
;
810 /* if(!temp.empty()) : Must not occur */
813 state
= QUOTED_STRING
;
815 /* What about bad characters ? */
824 state
= QUOTED_ESCAPE
;
832 /* What about bad characters ? */
839 if(c
=='\\' || c
=='"' || c
==' ' /* || c=='\t'*/)
845 temp
+= '\\' + c
; // Really do this ?
847 state
= SIMPLE_STRING
;
850 if(c
=='\\' || c
=='"')
856 temp
+= '\\' + c
; // Really do this ?
858 state
= QUOTED_STRING
;
871 std::string
TcpClient::escape(const std::string
& str
)
873 std::string res
= "\"";
875 for(size_t n
=0; n
<str
.size(); n
++)
892 * Device implementation
896 Device::Device(Client
* client
, const std::string
& name
):
902 Device::Device(const Device
& dev
):
903 _client(dev
._client
),
912 std::string
Device::getName()const
917 const Client
* Device::getClient()const
922 Client
* Device::getClient()
927 bool Device::isOk()const
929 return _client
!=NULL
&& !_name
.empty();
932 Device::operator bool()const
937 bool Device::operator!()const
942 bool Device::operator==(const Device
& dev
)const
944 return dev
._client
==_client
&& dev
._name
==_name
;
947 bool Device::operator<(const Device
& dev
)const
949 return getName()<dev
.getName();
952 std::string
Device::getDescription()throw(NutException
)
954 return getClient()->getDeviceDescription(getName());
957 std::vector
<std::string
> Device::getVariableValue(const std::string
& name
)
960 return getClient()->getDeviceVariableValue(getName(), name
);
963 std::map
<std::string
,std::vector
<std::string
> > Device::getVariableValues()
966 return getClient()->getDeviceVariableValues(getName());
969 std::set
<std::string
> Device::getVariableNames()throw(NutException
)
971 return getClient()->getDeviceVariableNames(getName());
974 std::set
<std::string
> Device::getRWVariableNames()throw(NutException
)
976 return getClient()->getDeviceRWVariableNames(getName());
979 void Device::setVariable(const std::string
& name
, const std::string
& value
)throw(NutException
)
981 getClient()->setDeviceVariable(getName(), name
, value
);
984 void Device::setVariable(const std::string
& name
, const std::vector
<std::string
>& values
)
987 getClient()->setDeviceVariable(getName(), name
, values
);
992 Variable
Device::getVariable(const std::string
& name
)throw(NutException
)
994 if(getClient()->hasDeviceVariable(getName(), name
))
995 return Variable(this, name
);
997 return Variable(NULL
, "");
1000 std::set
<Variable
> Device::getVariables()throw(NutException
)
1002 std::set
<Variable
> set
;
1004 std::set
<std::string
> names
= getClient()->getDeviceVariableNames(getName());
1005 for(std::set
<std::string
>::iterator it
=names
.begin(); it
!=names
.end(); ++it
)
1007 set
.insert(Variable(this, *it
));
1013 std::set
<Variable
> Device::getRWVariables()throw(NutException
)
1015 std::set
<Variable
> set
;
1017 std::set
<std::string
> names
= getClient()->getDeviceRWVariableNames(getName());
1018 for(std::set
<std::string
>::iterator it
=names
.begin(); it
!=names
.end(); ++it
)
1020 set
.insert(Variable(this, *it
));
1026 std::set
<std::string
> Device::getCommandNames()throw(NutException
)
1028 return getClient()->getDeviceCommandNames(getName());
1031 std::set
<Command
> Device::getCommands()throw(NutException
)
1033 std::set
<Command
> cmds
;
1035 std::set
<std::string
> res
= getCommandNames();
1036 for(std::set
<std::string
>::iterator it
=res
.begin(); it
!=res
.end(); ++it
)
1038 cmds
.insert(Command(this, *it
));
1044 Command
Device::getCommand(const std::string
& name
)throw(NutException
)
1046 if(getClient()->hasDeviceCommand(getName(), name
))
1047 return Command(this, name
);
1049 return Command(NULL
, "");
1052 void Device::executeCommand(const std::string
& name
)throw(NutException
)
1054 getClient()->executeDeviceCommand(getName(), name
);
1057 void Device::login()throw(NutException
)
1059 getClient()->deviceLogin(getName());
1062 void Device::master()throw(NutException
)
1064 getClient()->deviceMaster(getName());
1067 void Device::forcedShutdown()throw(NutException
)
1071 int Device::getNumLogins()throw(NutException
)
1073 return getClient()->deviceGetNumLogins(getName());
1078 * Variable implementation
1082 Variable::Variable(Device
* dev
, const std::string
& name
):
1088 Variable::Variable(const Variable
& var
):
1089 _device(var
._device
),
1094 Variable::~Variable()
1098 std::string
Variable::getName()const
1103 const Device
* Variable::getDevice()const
1108 Device
* Variable::getDevice()
1113 bool Variable::isOk()const
1115 return _device
!=NULL
&& !_name
.empty();
1119 Variable::operator bool()const
1124 bool Variable::operator!()const
1129 bool Variable::operator==(const Variable
& var
)const
1131 return var
._device
==_device
&& var
._name
==_name
;
1134 bool Variable::operator<(const Variable
& var
)const
1136 return getName()<var
.getName();
1139 std::vector
<std::string
> Variable::getValue()throw(NutException
)
1141 return getDevice()->getClient()->getDeviceVariableValue(getDevice()->getName(), getName());
1144 std::string
Variable::getDescription()throw(NutException
)
1146 return getDevice()->getClient()->getDeviceVariableDescription(getDevice()->getName(), getName());
1149 void Variable::setValue(const std::string
& value
)throw(NutException
)
1151 getDevice()->setVariable(getName(), value
);
1154 void Variable::setValues(const std::vector
<std::string
>& values
)throw(NutException
)
1156 getDevice()->setVariable(getName(), values
);
1162 * Command implementation
1166 Command::Command(Device
* dev
, const std::string
& name
):
1172 Command::Command(const Command
& cmd
):
1173 _device(cmd
._device
),
1182 std::string
Command::getName()const
1187 const Device
* Command::getDevice()const
1192 Device
* Command::getDevice()
1197 bool Command::isOk()const
1199 return _device
!=NULL
&& !_name
.empty();
1203 Command::operator bool()const
1208 bool Command::operator!()const
1213 bool Command::operator==(const Command
& cmd
)const
1215 return cmd
._device
==_device
&& cmd
._name
==_name
;
1218 bool Command::operator<(const Command
& cmd
)const
1220 return getName()<cmd
.getName();
1223 std::string
Command::getDescription()throw(NutException
)
1225 return getDevice()->getClient()->getDeviceCommandDescription(getDevice()->getName(), getName());
1228 void Command::execute()throw(NutException
)
1230 getDevice()->executeCommand(getName());
1233 } /* namespace nut */
1242 strarr
strarr_alloc(unsigned short count
)
1244 strarr arr
= (strarr
)xcalloc(count
+1, sizeof(char*));
1249 void strarr_free(strarr arr
)
1261 static strarr
stringset_to_strarr(const std::set
<std::string
>& strset
)
1263 strarr arr
= strarr_alloc(strset
.size());
1265 for(std::set
<std::string
>::const_iterator it
=strset
.begin(); it
!=strset
.end(); ++it
)
1267 *pstr
= xstrdup(it
->c_str());
1272 static strarr
stringvector_to_strarr(const std::vector
<std::string
>& strset
)
1274 strarr arr
= strarr_alloc(strset
.size());
1276 for(std::vector
<std::string
>::const_iterator it
=strset
.begin(); it
!=strset
.end(); ++it
)
1278 *pstr
= xstrdup(it
->c_str());
1284 NUTCLIENT_TCP_t
nutclient_tcp_create_client(const char* host
, unsigned short port
)
1286 nut::TcpClient
* client
= new nut::TcpClient
;
1289 client
->connect(host
, port
);
1290 return (NUTCLIENT_TCP_t
)client
;
1292 catch(nut::NutException
& ex
)
1294 // TODO really catch it
1301 void nutclient_destroy(NUTCLIENT_t client
)
1305 delete (nut::Client
*)client
;
1309 int nutclient_tcp_is_connected(NUTCLIENT_TCP_t client
)
1313 nut::TcpClient
* cl
= dynamic_cast<nut::TcpClient
*>((nut::Client
*)client
);
1316 return cl
->isConnected() ? 1 : 0;
1322 void nutclient_tcp_disconnect(NUTCLIENT_TCP_t client
)
1326 nut::TcpClient
* cl
= dynamic_cast<nut::TcpClient
*>((nut::Client
*)client
);
1335 int nutclient_tcp_reconnect(NUTCLIENT_TCP_t client
)
1339 nut::TcpClient
* cl
= dynamic_cast<nut::TcpClient
*>((nut::Client
*)client
);
1353 void nutclient_tcp_set_timeout(NUTCLIENT_TCP_t client
, long timeout
)
1357 nut::TcpClient
* cl
= dynamic_cast<nut::TcpClient
*>((nut::Client
*)client
);
1360 cl
->setTimeout(timeout
);
1365 long nutclient_tcp_get_timeout(NUTCLIENT_TCP_t client
)
1369 nut::TcpClient
* cl
= dynamic_cast<nut::TcpClient
*>((nut::Client
*)client
);
1372 return cl
->getTimeout();
1379 void nutclient_authenticate(NUTCLIENT_t client
, const char* login
, const char* passwd
)
1383 nut::Client
* cl
= (nut::Client
*)client
;
1388 cl
->authenticate(login
, passwd
);
1395 void nutclient_logout(NUTCLIENT_t client
)
1399 nut::Client
* cl
= (nut::Client
*)client
;
1411 void nutclient_device_login(NUTCLIENT_t client
, const char* dev
)
1415 nut::Client
* cl
= (nut::Client
*)client
;
1420 cl
->deviceLogin(dev
);
1427 int nutclient_get_device_num_logins(NUTCLIENT_t client
, const char* dev
)
1431 nut::Client
* cl
= (nut::Client
*)client
;
1436 return cl
->deviceGetNumLogins(dev
);
1445 void nutclient_device_master(NUTCLIENT_t client
, const char* dev
)
1449 nut::Client
* cl
= (nut::Client
*)client
;
1454 cl
->deviceMaster(dev
);
1461 void nutclient_device_forced_shutdown(NUTCLIENT_t client
, const char* dev
)
1465 nut::Client
* cl
= (nut::Client
*)client
;
1470 cl
->deviceForcedShutdown(dev
);
1477 strarr
nutclient_get_devices(NUTCLIENT_t client
)
1481 nut::Client
* cl
= (nut::Client
*)client
;
1486 return stringset_to_strarr(cl
->getDeviceNames());
1494 int nutclient_has_device(NUTCLIENT_t client
, const char* dev
)
1498 nut::Client
* cl
= (nut::Client
*)client
;
1503 return cl
->hasDevice(dev
)?1:0;
1511 char* nutclient_get_device_description(NUTCLIENT_t client
, const char* dev
)
1515 nut::Client
* cl
= (nut::Client
*)client
;
1520 return xstrdup(cl
->getDeviceDescription(dev
).c_str());
1528 strarr
nutclient_get_device_variables(NUTCLIENT_t client
, const char* dev
)
1532 nut::Client
* cl
= (nut::Client
*)client
;
1537 return stringset_to_strarr(cl
->getDeviceVariableNames(dev
));
1545 strarr
nutclient_get_device_rw_variables(NUTCLIENT_t client
, const char* dev
)
1549 nut::Client
* cl
= (nut::Client
*)client
;
1554 return stringset_to_strarr(cl
->getDeviceRWVariableNames(dev
));
1562 int nutclient_has_device_variable(NUTCLIENT_t client
, const char* dev
, const char* var
)
1566 nut::Client
* cl
= (nut::Client
*)client
;
1571 return cl
->hasDeviceVariable(dev
, var
)?1:0;
1579 char* nutclient_get_device_variable_description(NUTCLIENT_t client
, const char* dev
, const char* var
)
1583 nut::Client
* cl
= (nut::Client
*)client
;
1588 return xstrdup(cl
->getDeviceVariableDescription(dev
, var
).c_str());
1596 strarr
nutclient_get_device_variable_values(NUTCLIENT_t client
, const char* dev
, const char* var
)
1600 nut::Client
* cl
= (nut::Client
*)client
;
1605 return stringvector_to_strarr(cl
->getDeviceVariableValue(dev
, var
));
1613 void nutclient_set_device_variable_value(NUTCLIENT_t client
, const char* dev
, const char* var
, const char* value
)
1617 nut::Client
* cl
= (nut::Client
*)client
;
1622 cl
->setDeviceVariable(dev
, var
, value
);
1629 void nutclient_set_device_variable_values(NUTCLIENT_t client
, const char* dev
, const char* var
, const strarr values
)
1633 nut::Client
* cl
= (nut::Client
*)client
;
1638 std::vector
<std::string
> vals
;
1639 strarr pstr
= (strarr
)values
;
1642 vals
.push_back(std::string(*pstr
));
1646 cl
->setDeviceVariable(dev
, var
, vals
);
1655 strarr
nutclient_get_device_commands(NUTCLIENT_t client
, const char* dev
)
1659 nut::Client
* cl
= (nut::Client
*)client
;
1664 return stringset_to_strarr(cl
->getDeviceCommandNames(dev
));
1673 int nutclient_has_device_command(NUTCLIENT_t client
, const char* dev
, const char* cmd
)
1677 nut::Client
* cl
= (nut::Client
*)client
;
1682 return cl
->hasDeviceCommand(dev
, cmd
)?1:0;
1691 char* nutclient_get_device_command_description(NUTCLIENT_t client
, const char* dev
, const char* cmd
)
1695 nut::Client
* cl
= (nut::Client
*)client
;
1700 return xstrdup(cl
->getDeviceCommandDescription(dev
, cmd
).c_str());
1708 void nutclient_execute_device_command(NUTCLIENT_t client
, const char* dev
, const char* cmd
)
1712 nut::Client
* cl
= (nut::Client
*)client
;
1717 cl
->executeDeviceCommand(dev
, cmd
);