summaryrefslogtreecommitdiff
path: root/Bus
diff options
context:
space:
mode:
Diffstat (limited to 'Bus')
-rw-r--r--Bus/Ivy/IvyApplication.cxx307
1 files changed, 307 insertions, 0 deletions
diff --git a/Bus/Ivy/IvyApplication.cxx b/Bus/Ivy/IvyApplication.cxx
new file mode 100644
index 0000000..26d0adf
--- /dev/null
+++ b/Bus/Ivy/IvyApplication.cxx
@@ -0,0 +1,307 @@
+// IvyApplication.cpp : implementation file
+//
+
+#include "stdafx.h"
+//#include "libIvy.h"
+#include "IvyApplication.h"
+#include "Regexp.h"
+
+//#define DEBUG
+
+#define ARG_START "\002"
+#define ARG_END "\003"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyApplication
+
+IvyApplication::IvyApplication(Ivy * bus)
+{
+ this->bus = bus;
+ remoteService = 0; /* unknown or unconnected application */
+ appname = "Unknown";
+ AppConnectedCallbackCalled = false;
+}
+
+IvyApplication::~IvyApplication()
+{
+// bus->RemoveApplication( this );
+ for ( int i = 0; i < regexp_in.size(); i++)
+ delete regexp_in[i];
+ regexp_in.clear();
+ if ( m_hSocket != INVALID_SOCKET )
+ Close();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyApplication member functions
+
+
+void IvyApplication::Create(const char* host, UINT & port)
+{
+ // Exception to catch
+ CBufferedSocket::Create();
+ Connect(host, port);
+}
+
+
+
+UINT IvyApplication::Create()
+{
+ string host;
+ UINT port;
+ CBufferedSocket::Create();
+ // Max Listen Connexion
+ Listen( SOMAXCONN );
+ GetSockName( host, port );
+ TRACE(" TCP %s:%d\n", host.c_str(), port );
+#ifdef DEBUG
+ TRACE( "IvyApplication::Create server socket %d\n", m_hSocket );
+#endif
+ return port;
+}
+
+void IvyApplication::OnReceive(char * line)
+{
+ int err,id;
+ int kind_of_msg = Bye;
+ Regexp *exp;
+
+
+ int argc = 0;
+ const char *argv[Regexp::NSUBEXP];
+ char *arg;
+
+#ifdef DEBUG
+ TRACE("Receive %s\n",line);
+#endif //DEBUG
+
+ err = sscanf( line ,"%d %d", &kind_of_msg, &id);
+ arg = strstr( line , ARG_START );
+ if ( (err != 2) || (arg == NULL) )
+ {
+ TRACE("Quitting bad format %s\n", line);
+ SendMsg(Error, Error, "bad format request expected 'type id ...'");
+// bus->RemoveApplication( this );
+ Close();
+ return;
+ }
+ arg++;
+ switch( kind_of_msg )
+ {
+ case Bye:
+
+#ifdef DEBUG
+ TRACE("Quitting %s\n", line);
+#endif //DEBUG
+
+// bus->RemoveApplication( this );
+ Close();
+ break;
+ case Error:
+
+#ifdef DEBUG
+ TRACE("Receive error %d %s\n", id, arg);
+#endif //DEBUG
+
+ break;
+ case AddRegexp:
+
+#ifdef DEBUG
+ TRACE("Regexp id=%d exp='%s'\n", id, arg);
+#endif //DEBUG
+
+ if ( !bus->CheckRegexp( arg ) )
+ {
+#ifdef DEBUG
+ TRACE("Warning exp='%s' can't match removing from %s\n",arg,appname);
+#endif //DEBUG
+ return;
+ }
+ exp = new Regexp( arg );
+ if ( !exp->CompiledOK() )
+ {
+ string regerr = exp->GetErrorString();
+ string err;
+ err = "Error can't compile regexp '"+string(arg)+"' error "+regerr;
+ SendMsg( Error, Error, err.c_str() );
+ TRACE("IvyApplication %s\n",err.c_str());
+ return;
+ }
+ if ( id +1 < regexp_in.size() )
+ regexp_in[ id ] = exp ;
+ else regexp_in.push_back( exp );
+ break;
+ case DelRegexp:
+
+#ifdef DEBUG
+ TRACE("Regexp Delete id=%d\n", id);
+#endif //DEBUG
+ if ( id < regexp_in.size() )
+ {
+ exp = regexp_in[ id ];
+ delete exp;
+ regexp_in[ id ] = NULL ;
+ }
+ break;
+ case StartRegexp:
+
+#ifdef DEBUG
+ TRACE("Regexp Start id=%d\n", id);
+#endif //DEBUG
+
+ appname = arg;
+ /* remote socket port */
+ remoteService = id;
+ if ( bus->CheckConnected( this ) )
+ {
+ TRACE("Quitting already connected %s\n", appname);
+ SendMsg( Error, Error, "already connected" );
+// bus->RemoveApplication( this );
+ Close();
+ }
+ break;
+ case EndRegexp:
+
+#ifdef DEBUG
+ TRACE("Regexp End id=%d\n", id);
+#endif //DEBUG
+
+ bus->CallApplicationConnectedCallback( this );
+ AppConnectedCallbackCalled = true;
+ if ( !bus->ready_message.empty() )
+ SendMsg( bus->ready_message.c_str() );
+ break;
+ case Msg:
+
+#ifdef DEBUG
+ TRACE("Message id=%d msg='%s'\n", id, arg);
+#endif //DEBUG
+
+ arg = strtok( arg, ARG_END);
+ while ( arg )
+ {
+ argv[argc++] = arg;
+ arg = strtok( NULL, ARG_END );
+ }
+ bus->CallMessageCallback( this, id, argc, argv );
+ break;
+ case DirectMsg:
+
+#ifdef DEBUG
+ TRACE("Direct Message id=%d msg='%s'\n", id, arg);
+#endif //DEBUG
+
+ bus->CallDirectMessageCallback( this, id, arg );
+ break;
+ case Die:
+
+#ifdef DEBUG
+ TRACE("Die Message id=%d msg='%s'\n", id, arg);
+#endif //DEBUG
+
+ if ( bus->CallDieCallback( this, id, arg ) )
+ {
+ PostMessage( NULL, WM_CLOSE, 0, 0);
+ }
+ break;
+
+ default:
+ TRACE("Receive unhandled message %s\n", line);
+ break;
+ }
+}
+
+
+void IvyApplication::SendMsg(MsgType msg, int id, const char * arg)
+{
+ char buffer[1024];
+ if ( arg )
+ sprintf( buffer, "%d %d" ARG_START "%s\n", msg, id, arg );
+ else sprintf( buffer, "%d %d" ARG_START "\n", msg, id );
+
+#ifdef DEBUG
+ TRACE("SendMsg %s\n",buffer);
+#endif //DEBUG
+ Send( buffer );
+}
+
+void IvyApplication::OnAccept(int nErrorCode)
+{
+ string remotehost;
+ UINT remoteport;
+
+ // construct a new, empty socket
+
+ IvyApplication *newapp = new IvyApplication(bus);
+
+ // accept connection
+
+ Accept( *newapp );
+ newapp->GetPeerName( remotehost, remoteport );
+ TRACE("Connexion de %s:%u\n", remotehost.c_str(), remoteport );
+ bus->AddApplication( newapp );
+}
+
+void IvyApplication::OnClose(int nErrorCode)
+{
+ string remotehost;
+ UINT remoteport;
+ GetPeerName( remotehost, remoteport );
+ TRACE("Deconnexion de %s:%u\n", remotehost.c_str(), remoteport );
+ if ( AppConnectedCallbackCalled )
+ bus->CallApplicationDisconnectedCallback( this );
+// bus->RemoveApplication( this );
+ for ( int i = 0; i < regexp_in.size(); i++)
+ delete regexp_in[i];
+ regexp_in.clear();
+ Close();
+}
+
+int IvyApplication::SendMsg(const char *message)
+{
+ int count = 0;
+ Regexp *exp;
+
+ /* send to already connected */
+ for ( int id = 0; id < regexp_in.size(); id++ )
+ {
+ exp = regexp_in[ id ];
+
+ if ( exp && exp->Match( message ) )
+ {
+ string buffer;
+ for ( int i = 1; i < exp->SubStrings()+1; i++ )
+ {
+ buffer += (*exp)[i];
+ buffer += ARG_END;
+ }
+ SendMsg( Msg, id, buffer.c_str() );
+ count++;
+ }
+ }
+ return count;
+}
+
+const char *IvyApplication::GetName(void)
+{
+return appname.c_str();
+}
+
+
+BOOL IvyApplication::SameApplication(IvyApplication * app)
+{
+ string host1;
+ UINT port1;
+ string host2;
+ UINT port2;
+ if ( (remoteService != 0) && (remoteService == app->remoteService) )
+ {
+ GetPeerName( host1, port1 );
+ app->GetPeerName( host2, port2 );
+ TRACE( "IvyApplication::SameApplication %s:%d %s:%d\n", host1.c_str(),port1, host2.c_str(),port2);
+ return ( host1 == host2 );
+ }
+ return false;
+}