summaryrefslogtreecommitdiff
path: root/Ivy/IvyWatcher.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Ivy/IvyWatcher.cxx')
-rw-r--r--Ivy/IvyWatcher.cxx124
1 files changed, 124 insertions, 0 deletions
diff --git a/Ivy/IvyWatcher.cxx b/Ivy/IvyWatcher.cxx
new file mode 100644
index 0000000..4cbf604
--- /dev/null
+++ b/Ivy/IvyWatcher.cxx
@@ -0,0 +1,124 @@
+// IvyWatcher.cpp : implementation file
+//
+
+#include "IvyStdAfx.h"
+
+
+#include "IvyWatcher.h"
+#include "IvyApplication.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyWatcher
+
+
+#define VERSION 3
+
+IvyWatcher::IvyWatcher(Ivy * bus)
+{
+ this->bus = bus;
+}
+IvyWatcher::~IvyWatcher()
+{
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyWatcher member functions
+
+void IvyWatcher::OnReceive(int nErrorCode)
+{
+ size_t err;
+ int version;
+ char buffer[2048];
+ ivy::string remotehost;
+ UINT remoteport;
+ UINT serviceport;
+ char appid[2048];
+ char appname[2048];
+
+ memset( appid, 0, sizeof( appid ) );
+ memset( appname, 0, sizeof( appname ) );
+
+ err = ReceiveFrom( buffer, sizeof(buffer), remotehost, remoteport );
+ if ( err == SOCKET_ERROR )
+ {
+ TRACE("Receive Broadcast error %d\n",this->GetLastError());
+ return;
+ }
+ if ( err < 255 ) buffer[err] ='\0';
+ err = sscanf_s(buffer,"%d %u %s %[^\n]",&version, &serviceport,appid, sizeof(appid), appname,sizeof(appname));
+ if ( err < 2 )
+ {
+ /* ignore the message */
+ TRACE(" Bad Supervision message expected 'version port'\n");
+ return;
+ }
+ if ( version != VERSION )
+ {
+ /* ignore the message */
+ TRACE(" Bad Ivy verion number expected %d receive %d from %s:%d\n", VERSION,version, remotehost.c_str(), remoteport);
+ return;
+ }
+ /* check if we received our own message. SHOULD ALSO TEST THE HOST */
+ if ( strcmp( appid , bus->ApplicationID.c_str()) ==0 ) return;
+
+ /* check if we receive our own message should test also the host */
+ if ( serviceport == bus->GetApplicationPort() /*&& remotehost == "localhost"*/) return;
+ TRACE(" Broadcast de %s:%u port %u\n", remotehost.c_str(), remoteport, serviceport );
+
+ /* connect to the service and send the regexp */
+ IvyApplication *newapp = new IvyApplication(bus);
+ // exception to catch
+ newapp->Create(remotehost.c_str(), serviceport, appname );
+ // delete newapp;
+ // return;
+
+ bus->AddApplication( newapp );
+ TRACE(" Connecting to %s:%u\n", remotehost.c_str(), serviceport );
+
+}
+
+void IvyWatcher::start(const char *domainlist)
+{
+ BOOL reuse = TRUE;
+ ivy::string domain;
+ UINT port=0;
+ // determine domain to use
+ domain = bus->GetDomain( domainlist );
+
+ // first find our UDP port
+ size_t sep_index = domain.rfind( ':' );
+ if ( sep_index != -1 )
+ {
+ port = atoi ( domain.substr( sep_index +1 ).c_str() );
+ // supress port number from end of domain list
+ domain.erase( sep_index, domain.length() - sep_index );
+ }
+ // create UDP receiver
+ // catch exception !!!
+ Socket(SOCK_DGRAM);
+ SetSockOpt( SO_REUSEADDR, &reuse, sizeof(BOOL) );
+ Bind(port);
+ StartListener();
+
+ ivy::string addr;
+ char hello[2048];
+ int len = _snprintf_s( hello, sizeof(hello), sizeof(hello)-1, "%d %u %s %s\n", VERSION, bus->GetApplicationPort(), bus->ApplicationID.c_str(), bus->ApplicationName.c_str() );
+
+ // send broadcast to domain list
+ while ( !domain.empty() )
+ {
+ // find addr up to separator
+ size_t index = domain.find_first_of( ", \t" );
+ addr = domain.substr( 0, index );
+ domain.erase( 0, addr.length() +1 );
+ TRACE("Ivy Broadcasting on %s:%d\n", addr.c_str(), port );
+ AddMember( addr.c_str() );
+ SendTo( hello, len, port, addr.c_str() );
+ }
+}
+void IvyWatcher::stop()
+{
+ Close();
+}