53 if(
mPort<=0)
return false;
54 if(
mIp==
"")
return false;
55 if(
mIp.find(
':',0)!=std::string::npos)
return false;
62 if(!
Valid())
return res;
69 FD_DHV(
"SimplenetAddress::IpColonPort(): " << ipcolonport <<
" --> ?");
74 std::size_t cpos = ipcolonport.find(
':',0);
75 if(cpos==std::string::npos)
return;
77 if(cpos+1>= ipcolonport.length())
return;
79 mIp=ipcolonport.substr(0,cpos);
83 FD_DHV(
"SimplenetAddress::IpColonPort(): " << ipcolonport <<
" --> " <<
IpColonPort());
93 if(this->
mIp < rOther.
mIp)
return true;
94 if(this->
mIp > rOther.
mIp)
return false;
101 #ifdef FAUDES_IODEVICE_SIMPLENET
121 (void) rLabel; (void) pContext;
127 (void) rLabel; (void) pContext;
129 FD_DHV(
"AttributeSimplenetOutput(" <<
this <<
")::DoRead(tr)");
161 (void) rLabel; (void) pContext;
167 (void) rLabel; (void) pContext;
169 FD_DHV(
"AttributeSimplenetInput(" <<
this <<
")::DoRead(tr)");
203 FD_DHV(
"AttributeSimplenetEvent::AttributeSimplenetEvent(" <<
this <<
")");;
204 pOutputPrototype=OutputPrototypep();
205 pInputPrototype=InputPrototypep();
212 FD_DHV(
"AttributeSimplenetEvent(" <<
this <<
"): form other attr " << &rOtherAttr);
248 int syncSend(
int dest,
const char* data,
int len,
int flag) {
252 int rc=send(dest, data+from, left, 0);
254 std::stringstream errstr;
255 errstr <<
"Simplenet fatal network error (cannot send message)";
256 throw Exception(
"nDevice::syncSend", errstr.str(), 553,
true);
266 FD_DHV(
"nDevice(" <<
this <<
")::nDevice()");
272 mName=
"SimplenetNode";
277 faudes_mutex_init(&
mMutex);
284 FD_DHV(
"nDevice(" <<
this <<
")::~nDevice()");
288 faudes_mutex_destroy(&
mMutex);
293 FD_DHV(
"nDevice(" <<
this <<
")::Clear()");
360 FD_DHV(
"nDevice(" <<
this <<
")::Compile()");
368 FD_DHV(
"nDevice::DoWrite()");
386 std::map<std::string,std::string>::const_iterator nit;
391 if(defaddress.
Valid())
400 FD_DHV(
"nDevice::DoReadPreface()");
410 std::stringstream errstr;
411 errstr <<
"Simplenet address expected at " << rTr.
FileLine();
412 throw Exception(
"nDevice::DoRead", errstr.str(), 50);
417 while(!rTr.
Eos(
"Network")) {
429 std::stringstream errstr;
430 errstr <<
"Simplenet address expected at " << rTr.
FileLine();
431 throw Exception(
"nDevice::DoRead", errstr.str(), 50);
437 if(token.
IsBegin(
"BroadcastAddress")) {
441 std::stringstream errstr;
442 errstr <<
"Simplenet address expected at " << rTr.
FileLine();
443 throw Exception(
"nDevice::DoRead", errstr.str(), 50);
445 rTr.
ReadEnd(
"BroadcastAddress");
452 while(!rTr.
Eos(
"Network")) {
455 std::stringstream errstr;
456 errstr <<
"Simplenet node name expected at " << rTr.
FileLine();
457 throw Exception(
"nDevice::DoRead", errstr.str(), 50);
465 if(!defaddress.
Valid()) {
466 std::stringstream errstr;
467 errstr <<
"Simplenet node address expected at " << rTr.
FileLine();
468 throw Exception(
"nDevice::DoRead", errstr.str(), 50);
479 #define LOCK_E {int rc = faudes_mutex_lock(&mMutex); \
480 if(rc) {FD_ERR("nDevice::LOCK_E: lock mutex error\n"); exit(1); }}
481 #define UNLOCK_E {int rc = faudes_mutex_unlock(&mMutex); \
482 if(rc) {FD_ERR("nDevice::LOCK_E: unlock mutex error\n"); exit(1); }}
483 #define TLOCK_E {int rc = faudes_mutex_lock(&ndevice->mMutex); \
484 if(rc) {FD_ERR("nDevice::TLOCK_E: lock mutex error\n"); exit(1); }}
485 #define TUNLOCK_E {int rc = faudes_mutex_unlock(&ndevice->mMutex); \
486 if(rc) {FD_ERR("nDevice::TLOCK_E: unlock mutex error\n"); exit(1); }}
499 std::stringstream errstr;
500 errstr <<
"Unknown output event " << output;
501 throw Exception(
"nDevice::WriteOutput", errstr.str(), 65);
507 std::stringstream errstr;
508 errstr <<
"Invalid output attribute " << output;
509 throw Exception(
"nDevice::WriteOutput", errstr.str(), 65);
514 FD_DHV(
"nDevice::WriteOutput(): message: " << message.substr(0,message.length()-1));
522 if(!sit->second.mEvents.Empty())
523 if(!sit->second.mEvents.Exists(output))
525 clientsock=sit->second.mClientSocket;
527 FD_DHV(
"nDevice::WriteOutput(): to socket " << clientsock);
528 syncSend(clientsock, message.c_str(), message.length(), 0);
532 FD_DH(
"nDevice::WriteOutput(): failed to notify client on socket " << clientsock);
535 FD_DHV(
"nDevice::WriteOutput(): done");
549 std::map<std::string,std::string>::iterator nit;
551 if(nit->first ==
mName)
continue;
561 int hostname_len =1023;
562 if(gethostname(hostname,hostname_len)!=0) {
563 std::stringstream errstr;
564 errstr <<
"Simplenet fatal network error (cannot get hostname)";
565 throw Exception(
"nDevice::Start", errstr.str(), 553);
567 hostname[hostname_len]=0;
574 std::stringstream errstr;
575 errstr <<
"Simplenet fatal network error (cannot open server socket)";
576 throw Exception(
"nDevice::Start", errstr.str(), 553);
579 faudes_setsockopt(
mListenSocket,SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
581 struct sockaddr_in serveraddr;
582 memset(&serveraddr, 0,
sizeof(serveraddr));
583 serveraddr.sin_family = AF_INET;
584 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
587 if(bind(
mListenSocket, (
struct sockaddr *) &serveraddr,
sizeof(serveraddr)) <0) {
588 std::stringstream errstr;
589 errstr <<
"Simplenet fatal network error (cannot bind socket)";
590 throw Exception(
"nDevice::Start", errstr.str(), 553);
594 std::stringstream errstr;
595 errstr <<
"Simplenet fatal network error (cannot listen from socket)";
596 throw Exception(
"nDevice::Start", errstr.str(), 553);
601 std::stringstream errstr;
602 errstr <<
"Simplenet fatal network error (cannot open broadcast socket)";
603 throw Exception(
"nDevice::Start", errstr.str(), 553);
606 faudes_setsockopt(
mBroadcastSocket,SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
607 faudes_setsockopt(
mBroadcastSocket,SOL_SOCKET, SO_REUSEPORT, &reuse,
sizeof(reuse));
610 if(faudes_setsockopt(
mBroadcastSocket, SOL_SOCKET, SO_BROADCAST, &reuse,
sizeof(reuse)) ) {
611 std::stringstream errstr;
612 errstr <<
"Simplenet fatal network error (cannot setopt broadcast socket)";
613 throw Exception(
"nDevice::Start", errstr.str(), 553);
616 struct sockaddr_in broadcastaddr;
617 memset(&broadcastaddr, 0,
sizeof(broadcastaddr));
618 broadcastaddr.sin_family = AF_INET;
619 broadcastaddr.sin_addr.s_addr = htonl(INADDR_ANY);
622 if(bind(
mBroadcastSocket, (
struct sockaddr *) &broadcastaddr,
sizeof(broadcastaddr)) <0) {
623 std::stringstream errstr;
624 errstr <<
"Simplenet fatal network error (cannot bind broadcast socket)";
625 throw Exception(
"nDevice::Start", errstr.str(), 553);
632 std::stringstream errstr;
633 errstr <<
"Simplenet fatal thread error (cannot create thread)";
634 throw Exception(
"nDevice::Start", errstr.str(), 554);
642 FD_DH(
"nDevice::Stop()");
648 std::string message=
"<Stop> " +
mNetwork +
" " +
mName +
" </Stop>\n";
649 struct sockaddr_in broadcastaddr;
650 memset(&broadcastaddr,
'\0',
sizeof(broadcastaddr));
651 broadcastaddr.sin_family=AF_INET;
656 (
struct sockaddr *) & broadcastaddr,
sizeof(broadcastaddr));
659 FD_DH(
"nDevice::Stop(): waiting for listen thread");
661 FD_DH(
"nDevice::Stop(): listen thread finished");
684 std::map<std::string,nDevice::ServerState>::iterator sit;
685 std::map<int,nDevice::ClientState>::iterator cit;
689 FD_DH(
"nDevice::Listen(" << ndevice <<
")");
691 faudes_systime_t lastbroadcast;
692 lastbroadcast.tv_sec=0;
693 lastbroadcast.tv_nsec=0;
694 #ifdef FAUDES_DEBUG_IODEVICE
707 if(!sit->second.mAddress.Valid()) {
708 FD_DH(
"nDevice::Listen(): missing server address for node: " << sit->first);
714 if(sit->second.mServerSocket<=0) {
715 FD_DH(
"nDevice::Listen(): missing server connection for node: " << sit->first);
724 if(cit->second.mClientSocket<0)
continue;
725 if(cit->second.mConnected) clientmis--;
727 #ifdef FAUDES_DEBUG_IODEVICE
728 if(clientmis!=servermis)
729 FD_DH(
"nDevice::Listen(): missing clients to subscribe: #"<< clientmis);
748 faudes_systime_t now;
749 faudes_gettimeofday(&now);
750 faudes_mstime_t diffms;
754 std::string message=
"<Request> "
755 + ndevice->
mNetwork +
" " + ndevice->
mName +
" </Request>\n";
757 struct sockaddr_in broadcastaddr;
758 memset(&broadcastaddr,
'\0',
sizeof(broadcastaddr));
759 broadcastaddr.sin_family=AF_INET;
764 0,(
struct sockaddr *) & broadcastaddr,
sizeof(broadcastaddr));
766 FD_DH(
"nDevice::Listen(): broadcast request: " << message.substr(0,message.length()-1) <<
" #" << rc);
768 faudes_gettimeofday(&lastbroadcast);
775 if(sit->second.mServerSocket>0)
continue;
777 if(!sit->second.mAddress.Valid())
continue;
779 FD_DH(
"nDevice::Listen(): subscribing to " << sit->first <<
780 " at " << sit->second.mAddress.IpColonPort());
782 int serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
784 FD_DH(
"nDevice::Listen(): subscription failed: no socket");
788 unsigned long int serverinaddr = INADDR_NONE;
789 if(serverinaddr==INADDR_NONE) {
790 FD_DH(
"nDevice::Listen(): using address as advertised");
791 serverinaddr = inet_addr(sit->second.mAddress.Ip().c_str());
793 if(serverinaddr==INADDR_NONE) {
794 struct hostent *host;
795 host = gethostbyname(sit->second.mAddress.Ip().c_str());
797 FD_DH(
"nDevice::Listen(): using address by name lookup");
798 serverinaddr = *(
unsigned long int*) host->h_addr;
801 if(serverinaddr==INADDR_NONE) {
802 FD_DH(
"nDevice::Listen(): subscription failed: invalid address " << sit->second.mAddress.Ip());
803 faudes_closesocket(serversock);
807 struct sockaddr_in serveraddress;
808 memset(&serveraddress, 0,
sizeof(serveraddress));
809 serveraddress.sin_family = AF_INET;
810 serveraddress.sin_addr.s_addr=serverinaddr;
811 serveraddress.sin_port = htons(sit->second.mAddress.Port());
813 if(connect(serversock, (
struct sockaddr*) &serveraddress,
sizeof(serveraddress))<0) {
814 FD_DH(
"nDevice::Listen(): subscription failed: connect");
815 faudes_closesocket(serversock);
821 hello=
"% Simplenet universal event subscription: "+ndevice->
mName+
" subscribing from "+sit->first+
"\n";
822 syncSend(serversock, hello.c_str(), hello.length(), 0);
823 hello=
"% Expecting notifications in format '<Notify> event_name </Notify>'\n";
824 syncSend(serversock, hello.c_str(), hello.length(), 0);
825 hello=
"% Trying to subscribe to all required events\n";
826 syncSend(serversock, hello.c_str(), hello.length(), 0);
828 faudes_closesocket(serversock);
832 FD_DH(
"nDevice::Listen(): subscription failed: cannot write");
833 faudes_closesocket(serversock);
837 FD_DH(
"nDevice::Listen(): subscribing to " << sit->first <<
" via socket " << serversock);
838 sit->second.mServerSocket=serversock;
841 sevents.
Name(
"Subscribe");
842 std::string message=sevents.
ToString() +
"\n";
843 syncSend(serversock,message.c_str(), message.length(),0);
850 FD_DH(
"nDevice::Listen(): subscribing to " << sit->first <<
" via socket " << serversock <<
": ok");
859 if(mysocks_max<ndevice->mListenSocket) mysocks_max=ndevice->
mListenSocket;
860 if(mysocks_max>= FD_SETSIZE)
FD_ERR(
"NDeviceListen: fail to select socket " << mysocks_max);
863 if(mysocks_max< ndevice->mBroadcastSocket) mysocks_max=ndevice->
mBroadcastSocket;
864 if(mysocks_max>= FD_SETSIZE)
FD_ERR(
"NDeviceListen: fail to select socket " << mysocks_max);
868 int serversock=sit->second.mServerSocket;
869 if(serversock<0)
continue;
870 if(mysocks_max< serversock) mysocks_max=serversock;
871 if(mysocks_max>= FD_SETSIZE)
FD_ERR(
"NDeviceListen: fail to select socket " << mysocks_max);
872 FD_SET(serversock, &mysocks);
876 int clientsock=cit->second.mClientSocket;
877 if(clientsock<0)
continue;
878 if(mysocks_max< clientsock) mysocks_max=clientsock;
879 if(mysocks_max>= FD_SETSIZE)
FD_ERR(
"NDeviceListen: fail to select socket " << mysocks_max);
880 FD_SET(clientsock, &mysocks);
887 int avail=select(mysocks_max+1, &mysocks, NULL, NULL, &tv);
896 #ifdef FAUDES_DEBUG_IODEVICE
898 if((debuglisten>10) || (avail>0)) {
899 FD_DH(
"nDevice::Listen(): listen as node \"" << ndevice->
mName <<
"\" on network \"" << ndevice->
mNetwork <<
"\"" <<
" #" << avail);
909 struct sockaddr_in clientaddr;
910 socklen_t clientaddr_len =
sizeof(clientaddr);
911 clientsock=accept(ndevice->
mListenSocket, (
struct sockaddr *) &clientaddr, &clientaddr_len );
913 FD_DH(
"nDevice::Listen(): failed to accept incomming connection");
916 FD_DH(
"nDevice::Listen(): accepted connection from client " << inet_ntoa(clientaddr.sin_addr) <<
917 " on socket " << clientsock);
921 hello=
"% Simplenet Event Server: "+ndevice->
mName+
" providing events\n";
922 syncSend(clientsock, hello.c_str(), hello.length(), 0);
923 hello=
"% Notifications will have format '<Notify> event_name </Notify>'\n";
924 syncSend(clientsock, hello.c_str(), hello.length(), 0);
925 hello=
"% Commands are accepted in format '<Cmd> cmd_name </Cmd>'\n";
926 syncSend(clientsock, hello.c_str(), hello.length(), 0);
927 hello=
"% Supported commands are Subscribe, Info, Status, and ResetRequest\n";
928 syncSend(clientsock, hello.c_str(), hello.length(), 0);
930 faudes_closesocket(clientsock);
934 FD_DH(
"nDevice::Listen(): connection test failed: cannot write");
935 faudes_closesocket(clientsock);
955 struct sockaddr_in fromaddr;
956 socklen_t fromaddr_len =
sizeof(fromaddr);
957 data_len=recvfrom(ndevice->
mBroadcastSocket,data,data_len,0, (
struct sockaddr*) &fromaddr,&fromaddr_len);
958 if(data_len<0) data_len=0;
960 if(data_len>=1)
if(data[data_len-1]==
'\n') data[data_len-1]=0;
961 FD_DH(
"nDevice::Listen(): received udp datagram " << data <<
962 " from " << inet_ntoa(fromaddr.sin_addr));
980 if(sit->second.mServerSocket==-1) {
981 lastbroadcast.tv_sec=0;
982 lastbroadcast.tv_nsec=0;
986 if(snode!=ndevice->
mName) {
988 std::string message=
"<Advert> "
990 + ndevice->
mName +
" " +
993 struct sockaddr_in replyaddr;
994 memset(&replyaddr,
'\0',
sizeof(replyaddr));
995 replyaddr.sin_family=AF_INET;
1001 int rc = sendto(ndevice->
mBroadcastSocket,message.c_str(),message.length(),0,(
struct sockaddr *) & replyaddr,
sizeof(replyaddr));
1003 FD_DH(
"nDevice::Listen(): reply advert: " << message.substr(0,message.length()-1) <<
" #" << rc);
1005 FD_DH(
"nDevice::Listen(): ingoring request from myself");
1008 FD_DH(
"nDevice::Listen(): ingoring request from other network");
1018 addr.
Ip(inet_ntoa(fromaddr.sin_addr));
1019 FD_DHV(
"nDevice::Listen(): figure actual ip address " << addr.
Ip());
1022 FD_DH(
"nDevice::Listen(): fallback to explicit ip address " << addr.
Ip());
1024 std::map<std::string,nDevice::ServerState>::iterator sit;
1027 FD_DH(
"nDevice::Listen(): ignoring irrelevant advert from " << node);
1028 }
else if(sit->second.mAddress.Valid()) {
1029 FD_DH(
"nDevice::Listen(): ignoring address overwrite (hardwired?) " << node);
1032 if(!sit->second.mAddress.Valid()) {
1033 FD_DH(
"nDevice::Listen(): accept advert " << node);
1034 sit->second.mAddress=addr;
1035 if(sit->second.mServerSocket>=0) faudes_closesocket(sit->second.mServerSocket);
1036 sit->second.mServerSocket=-1;
1039 FD_DH(
"nDevice::Listen(): ingoring advert from other network");
1043 FD_DH(
"nDevice::Listen(): ignore invalid udp message");
1052 int serversock=sit->second.mServerSocket;
1053 if(serversock<0)
continue;
1054 if(FD_ISSET(serversock, &mysocks)) {
1056 FD_DH(
"nDevice::Listen(): reading sock " << serversock);
1059 int count = recv(serversock, buffer, 1024, 0);
1061 FD_DH(
"nDevice::Listen(): reading server sock " << serversock <<
" : eof");
1062 faudes_closesocket(serversock);
1063 sit->second.mServerSocket=-1;
1066 FD_DH(
"nDevice::Listen(): reading server sock " << serversock <<
": #" << count);
1068 sit->second.mLineBuffer +=std::string(buffer);
1071 if(buffer[count-1]==
'\n')
1072 if(sit->second.mLineBuffer.length()>0)
1074 const std::string& linebuffer = sit->second.mLineBuffer;
1075 #ifdef FAUDES_DEBUG_IODEVICE
1076 if(linebuffer.length()>0)
1077 if(linebuffer[0]!=
'%')
1078 FD_DH(
"nDevice::Listen(): reading server sock " << serversock <<
": line: " << linebuffer);
1084 while(tr.
Peek(token)) {
1091 FD_DH(
"nDevice::Listen(): found event " << event);
1100 FD_DH(
"nDevice::Listen(): found device info");
1121 while(!tr.
Eos(section)) tr.
Get(token);
1126 FD_DH(
"nDevice::Listen(): error: ignore token");
1130 FD_DH(
"nDevice::Listen(): " << serversock <<
": invalid notification");
1132 sit->second.mLineBuffer.clear();
1140 int clientsock=cit->second.mClientSocket;
1141 if(clientsock<0)
continue;
1142 if(FD_ISSET(clientsock, &mysocks)) {
1144 FD_DH(
"nDevice::Listen(): reading client sock " << clientsock);
1147 int count = recv(clientsock, buffer, 1024, 0);
1149 FD_DH(
"nDevice::Listen(): reading client sock " << clientsock <<
" : eof");
1151 faudes_closesocket(clientsock);
1152 cit->second.mClientSocket=-1;
1153 cit->second.mConnected=
false;
1157 FD_DH(
"nDevice::Listen(): reading client sock " << clientsock <<
": #" << count);
1159 cit->second.mLineBuffer +=std::string(buffer);
1162 if(buffer[count-1]==
'\n')
1163 if(cit->second.mLineBuffer.length()>0)
1165 const std::string& linebuffer = cit->second.mLineBuffer;
1166 #ifdef FAUDES_DEBUG_IODEVICE
1167 if(linebuffer.length()>0)
1168 if(linebuffer[0]!=
'%')
1169 FD_DH(
"nDevice::Listen(): reading client sock " << clientsock <<
": line: " << linebuffer);
1175 while(tr.
Peek(token)) {
1181 std::string response=
"<NAck> </NAck>\n";
1182 FD_DH(
"nDevice::Reply(" << clientsock <<
"): received cmd " << cmd);
1186 response=ndevice->
ToString() +
"\n";
1198 if(cmd==
"ResetRequest") {
1199 FD_DH(
"nDevice::Reply(" << clientsock <<
"): reset request");
1207 syncSend(clientsock, response.c_str(), response.length(), 0);
1210 if(token.
IsBegin(
"Subscribe")) {
1212 sevents.
Read(tr,
"Subscribe");
1214 sevents.
Name(
"Subscribed");
1215 FD_DH(
"nDevice::Reply(" << clientsock <<
"): providing events " << sevents.
ToString());
1217 cit->second.mEvents.Clear();
1218 cit->second.mEvents.InsertSet(sevents);
1219 cit->second.mConnected=
true;
1220 std::string response=sevents.
ToString()+
"\n";
1223 syncSend(clientsock, response.c_str(), response.length(), 0);
1227 FD_DH(
"nDevice::Reply(" << clientsock <<
"): invalid cmd");
1229 cit->second.mLineBuffer.clear();
1236 FD_DH(
"nDevice::Listen(): broadcast condition");
1248 FD_DH(
"nDevice::Listen(): select error");
1254 FD_DH(
"nDevice::Listen(): close client sockets");
1257 int clientsock= cit->second.mClientSocket;
1258 if(clientsock>0) faudes_closesocket(clientsock);
1259 cit->second.mClientSocket=-1;
1260 cit->second.mConnected=
false;
1265 FD_DH(
"nDevice::Listen(): close server sockets");
1267 int serversock=sit->second.mServerSocket;
1268 if(serversock>0) faudes_closesocket(serversock);
1269 sit->second.mServerSocket=-1;
1271 FD_DH(
"nDevice::Listen(): terminating listen thread");
1272 faudes_thread_exit(NULL);
1286 std::string message=
"<Cmd> ResetRequest </Cmd>\n";
1291 int serversock=sit->second.mServerSocket;
1292 if(serversock<0)
continue;
1293 FD_DH(
"nDevice::Reset(): sending reset request to socket " << serversock);
1294 syncSend(serversock, message.c_str(), message.length(), 0);
#define FD_ERR(message)
Debug: report more errors with file/line info.
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
faudes type implementation macros, overall
Attribute for the configuration of a input or output mapping.
const AttributeVoid * pOutputPrototype
Output Prototype (set to nontrivial attribute in derived classes)
void DefaultOutput(void)
Set to default output attribute.
const AttributeVoid * pInputPrototype
Input Prototype (set to nontrivial attribute in derived classes)
void DefaultInput(void)
Set to default input attribute.
Configuration of a networked input or output.
void DoAssign(const AttributeSimplenetEvent &rSrc)
DoAssign.
AttributeSimplenetEvent(void)
Default constructor (no mapping at all)
static const AttributeSimplenetInput * InputPrototypep(void)
Prototype, input (construct on first use static)
static const AttributeSimplenetOutput * OutputPrototypep(void)
Prototype, output (construct on first use static)
Configuration of a network output mapping.
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
Auto register faudes-type with specified type name.
Set of indices with symbolic names.
bool Exists(const Idx &rIndex) const
Test existence of index.
void SymbolicName(Idx index, const std::string &rName)
Set new name for existing index.
Idx Index(const std::string &rName) const
Index lookup.
void RestrictSet(const NameSet &rOtherSet)
Restrict to elements specified by rOtherSet.
int Port(void) const
Get TCP port.
bool operator<(const SimplenetAddress &rOther) const
Order for sorting containers of addresses.
std::string IpColonPort(void) const
Get as colon seperated string.
bool Valid(void) const
Return true if valid.
SimplenetAddress(void)
Default constructor.
std::string mIp
Ip address.
std::string Ip(void) const
Get IP address.
Set of indices with symbolic names and attributes.
A TokenReader reads sequential tokens from a file or string.
std::string FileLine(void) const
Return "filename:line".
bool Eos(const std::string &rLabel)
Peek a token and check whether it ends the specified section.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
std::string ReadString(void)
Read string token.
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
bool Get(Token &token)
Get next token.
bool Peek(Token &token)
Peek next token.
A TokenWriter writes sequential tokens to a file, a string or stdout.
void WriteEnd(const std::string &rLabel)
Write end label.
Tokens model atomic data for stream IO.
const std::string & StringValue(void) const
Get string value of a name token.
@ Begin
<label> (begin of section)
bool IsString(void) const
Test token Type.
bool ExistsAttributeString(const std::string &name)
Test attibute existence.
bool IsBegin(void) const
Test token Type.
void SetEmpty(const std::string &rName)
Initialize as empty-tag token.
void SetBegin(const std::string &rName)
Initialize as Begin token.
void InsAttributeString(const std::string &name, const std::string &value)
Insert named attribute with string value.
const std::string & AttributeStringValue(const std::string &name)
Access attribute value.
TokenType Type(void) const
Get token Type.
Base class of all libFAUDES objects that participate in the run-time interface.
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Read configuration data from file with label specified.
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
An nDevice implements networked IO via a simple TCP/IP protocol.
void BroadcastAddress(const std::string &rAddr)
Set broadcast address for address resolution Note: you can only set the broadcast address while the d...
void InsNode(const std::string &rNodeName)
Add a node to the network configuration.
void ServerAddress(const std::string &rAddr)
Set server address of this node.
virtual void Compile(void)
Set up internal data structures.
virtual void DoReadPreface(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Actual method to read device configuration from tokenreader.
virtual void Clear(void)
Clear all configuration.
void InsNodeAddress(const std::string &rNode, const std::string &rAddress)
Add entry to node name resolution.
SimplenetAddress mListenAddress
Simplenet: address of my server incl port (localhost:40000)
TaNameSet< AttributeSimplenetEvent > * pConfiguration
Overall configuration (with actual type)
std::string mNetwork
Simplenet: network id.
std::map< std::string, EventSet > mInputSubscriptions
Compiled data: map subscriptions.
void NetworkName(const std::string &rNetwork)
Set network name to participate.
faudes_thread_t mThreadListen
Background: thread handle (global)
virtual ~nDevice(void)
Explicit destructor.
std::map< std::string, ServerState > mInputServerStates
Background: connection states to event servers (by node name)
void InsOutputEvent(const std::string &event)
Insert event as output event.
int mBroadcastSocket
Background: udp broadcast socket (background only)
void ClearNodes(void)
Add a node to the network configuration.
virtual void DoWritePreface(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Actual method to write the device configuration to a TokenWriter.
std::map< int, ClientState > mOutputClientStates
Background: map sockets to connection states (shared)
faudes_mutex_t mMutex
Background: mutex for below shared variables.
friend void * NDeviceListen(void *)
nDevice(void)
Default constructor.
SimplenetAddress mEffectiveListenAddress
Simplenet: effective address of my server port.
virtual void Stop(void)
Deactivate the device.
virtual void WriteOutput(Idx output)
Run output command.
SimplenetAddress mBroadcastAddress
Simplenet: address for udp broadcast (255.255.255.255:40000.
bool mStopListen
Background: request to join via flag (mutexed)
virtual void Reset(void)
Reset device.
std::map< std::string, std::string > mNetworkNodes
Simplenet: list of nodes in this network incl default addresses.
int mListenSocket
Background: server socket to listen (background only)
virtual void Start(void)
Activate the device.
void InsInputEvent(const std::string &event)
Insert event as input event.
Virtual base class to define the interface for event io.
bool mResetRequest
Reset request marker (mutexed)
faudes_mutex_t * pBufferMutex
Actual mutex for input buffer (mutexted)
virtual void Clear(void)
Clear all configuration.
virtual const EventSet & Inputs(void) const
Get inputs as plain set.
virtual void Compile(void)
Compile inner data-structures.
std::string mDefaultLabel
Default label for token io.
faudes_cond_t * pWaitCondition
Actual Wait Condition.
virtual void DoReadPreface(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Reads non-event-configuration data from TokenReader.
virtual void Stop(void)
Deactivate the device.
virtual void Start(void)
Activate the device.
EventSet * mpConfiguration
Overall event configuration (uses cast for type)
EventSet mInputs
All inputs.
EventSet mOutputs
All outputs.
virtual void Reset(void)
Reset device.
virtual void DoWritePreface(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Writes non-event-configuration data from TokenWriter.
faudes_mutex_t * pWaitMutex
Actual Wait Condition Mutex.
std::deque< Idx > * pInputBuffer
Actual Fifo buffer for input readings.
DeviceState mState
Status: running, starting etc.
virtual const EventSet & Outputs(void) const
Get outputs as plain set.
virtual void Clear(void)
Clear all set.
NameSet EventSet
Convenience typedef for plain event sets.
const std::string & Name(void) const
Return name of TBaseSet.
Simple networked events via TCP/IP.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
void * NDeviceListen(void *arg)
Idx ToIdx(const std::string &rString)
Convert a string to Idx.
std::string ToStringInteger(Int number)
integer to string
int syncSend(int dest, const char *data, int len, int flag)
AutoRegisterType< nDevice > gRtiRegisterSimplenetDevice("SimplenetDevice")
Background: state of a connection to a client (shared)