summaryrefslogtreecommitdiff
path: root/common/eda_dde.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/eda_dde.cpp')
-rw-r--r--common/eda_dde.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/common/eda_dde.cpp b/common/eda_dde.cpp
new file mode 100644
index 0000000..92f965d
--- /dev/null
+++ b/common/eda_dde.cpp
@@ -0,0 +1,211 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eda_dde.cpp
+ */
+
+#include <fctsys.h>
+#include <eda_dde.h>
+#include <draw_frame.h>
+#include <id.h>
+#include <common.h>
+#include <macros.h>
+
+static const wxString HOSTNAME( wxT( "localhost" ) );
+
+// buffer for read and write data in socket connections
+#define IPC_BUF_SIZE 4096
+static char client_ipc_buffer[IPC_BUF_SIZE];
+
+static wxSocketServer* server;
+
+
+/**********************************/
+/* Routines related to the server */
+/**********************************/
+
+/* Function to initialize a server socket
+ */
+wxSocketServer* CreateServer( wxWindow* window, int service, bool local )
+{
+ wxIPV4address addr;
+
+ // Set the port number
+ addr.Service( service );
+
+ // Listen on localhost only if requested
+ if( local )
+ addr.Hostname( HOSTNAME );
+
+ server = new wxSocketServer( addr );
+
+ if( server )
+ {
+ server->SetNotify( wxSOCKET_CONNECTION_FLAG );
+ server->SetEventHandler( *window, ID_EDA_SOCKET_EVENT_SERV );
+ server->Notify( true );
+ }
+
+ return server;
+}
+
+
+/* Function called on every client request.
+ */
+void EDA_DRAW_FRAME::OnSockRequest( wxSocketEvent& evt )
+{
+ size_t len;
+ wxSocketBase* sock = evt.GetSocket();
+
+ switch( evt.GetSocketEvent() )
+ {
+ case wxSOCKET_INPUT:
+ sock->Read( client_ipc_buffer, 1 );
+
+ if( sock->LastCount() == 0 )
+ break; // No data, occurs on opening connection
+
+ sock->Read( client_ipc_buffer + 1, IPC_BUF_SIZE - 2 );
+ len = 1 + sock->LastCount();
+ client_ipc_buffer[len] = 0;
+ ExecuteRemoteCommand( client_ipc_buffer );
+ break;
+
+ case wxSOCKET_LOST:
+ return;
+ break;
+
+ default:
+ wxPrintf( wxT( "EDA_DRAW_FRAME::OnSockRequest() error: Invalid event !" ) );
+ break;
+ }
+}
+
+
+/* Function called when a connection is requested by a client.
+ */
+void EDA_DRAW_FRAME::OnSockRequestServer( wxSocketEvent& evt )
+{
+ wxSocketBase* sock2;
+ wxSocketServer* server = (wxSocketServer*) evt.GetSocket();
+
+ sock2 = server->Accept();
+
+ if( sock2 == NULL )
+ return;
+
+ sock2->Notify( true );
+ sock2->SetEventHandler( *this, ID_EDA_SOCKET_EVENT );
+ sock2->SetNotify( wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG );
+}
+
+
+/**********************************/
+/* Routines related to the CLIENT */
+/**********************************/
+
+/* Used by a client to sent (by a socket connection) a data to a server.
+ * - Open a Socket Client connection
+ * - Send the buffer cmdline
+ * - Close the socket connection
+ *
+ * service is the service number for the TC/IP connection
+ */
+bool SendCommand( int service, const char* cmdline )
+{
+ wxSocketClient* sock_client;
+ bool success = false;
+ wxIPV4address addr;
+
+ // Create a connexion
+ addr.Hostname( HOSTNAME );
+ addr.Service( service );
+
+ // Mini-tutorial for Connect() :-)
+ // (JP CHARRAS Note: see wxWidgets: sockets/client.cpp sample)
+ // ---------------------------
+ //
+ // There are two ways to use Connect(): blocking and non-blocking,
+ // depending on the value passed as the 'wait' (2nd) parameter.
+ //
+ // Connect(addr, true) will wait until the connection completes,
+ // returning true on success and false on failure. This call blocks
+ // the GUI (this might be changed in future releases to honor the
+ // wxSOCKET_BLOCK flag).
+ //
+ // Connect(addr, false) will issue a nonblocking connection request
+ // and return immediately. If the return value is true, then the
+ // connection has been already successfully established. If it is
+ // false, you must wait for the request to complete, either with
+ // WaitOnConnect() or by watching wxSOCKET_CONNECTION / LOST
+ // events (please read the documentation).
+ //
+ // WaitOnConnect() itself never blocks the GUI (this might change
+ // in the future to honor the wxSOCKET_BLOCK flag). This call will
+ // return false on timeout, or true if the connection request
+ // completes, which in turn might mean:
+ //
+ // a) That the connection was successfully established
+ // b) That the connection request failed (for example, because
+ // it was refused by the peer.
+ //
+ // Use IsConnected() to distinguish between these two.
+ //
+ // So, in a brief, you should do one of the following things:
+ //
+ // For blocking Connect:
+ //
+ // bool success = client->Connect(addr, true);
+ //
+ // For nonblocking Connect:
+ //
+ // client->Connect(addr, false);
+ //
+ // bool waitmore = true;
+ // while (! client->WaitOnConnect(seconds, millis) && waitmore )
+ // {
+ // // possibly give some feedback to the user,
+ // // update waitmore if needed.
+ // }
+ // bool success = client->IsConnected();
+ //
+ // And that's all :-)
+
+ sock_client = new wxSocketClient();
+ sock_client->SetTimeout( 2 ); // Time out in Seconds
+ sock_client->Connect( addr, false );
+ sock_client->WaitOnConnect( 0, 100 );
+
+ if( sock_client->Ok() && sock_client->IsConnected() )
+ {
+ success = true;
+ sock_client->SetFlags( wxSOCKET_NOWAIT /*wxSOCKET_WAITALL*/ );
+ sock_client->Write( cmdline, strlen( cmdline ) );
+ }
+
+ sock_client->Close();
+ sock_client->Destroy();
+ return success;
+}