diff options
Diffstat (limited to 'common/eda_dde.cpp')
-rw-r--r-- | common/eda_dde.cpp | 211 |
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; +} |