summaryrefslogtreecommitdiff
path: root/Bus/Ivy/IvyWatcher.cxx
blob: 099e67025e9b43d103c33f26467df45198e53ef1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// IvyWatcher.cpp : implementation file
//

#include "stdafx.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) 
{
	int err;
	int version;
	char buffer[256];
	string remotehost;
	UINT remoteport;
	UINT serviceport;


	err = ReceiveFrom( buffer, sizeof(buffer), remotehost, remoteport );
	if ( err == SOCKET_ERROR )
		{
		TRACE("Receive Broadcast error %d\n",GetLastError());
		return;
		}
	buffer[err] ='\0';
	err = sscanf(buffer,"%d %u",&version, &serviceport);
	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, remoteport);
		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);
	//	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;
	string domain;
	UINT port;
	// determine domain to use
	domain = bus->GetDomain( domainlist );
	
	// first find our UDP port
	int 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);
	
	string addr;
	char hello[1024];
	int len = sprintf( hello, "%d %u\n", VERSION, bus->GetApplicationPort() );

	// send broadcast to domain list
	while ( !domain.empty() ) 
	{
	// find addr up to separator
	int 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();
}