207 lines
6.3 KiB
C++
207 lines
6.3 KiB
C++
/*
|
|
* 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 <eda_dde.h>
|
|
#include <eda_draw_frame.h>
|
|
#include <id.h>
|
|
|
|
#include <wx/wx.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];
|
|
|
|
|
|
/**********************************/
|
|
/* Routines related to the server */
|
|
/**********************************/
|
|
|
|
/* Function to initialize a server socket
|
|
*/
|
|
void EDA_DRAW_FRAME::CreateServer( int service, bool local )
|
|
{
|
|
wxIPV4address addr;
|
|
|
|
// Set the port number
|
|
addr.Service( service );
|
|
|
|
// Listen on localhost only if requested
|
|
if( local )
|
|
addr.Hostname( HOSTNAME );
|
|
|
|
delete m_socketServer;
|
|
m_socketServer = new wxSocketServer( addr );
|
|
|
|
m_socketServer->SetNotify( wxSOCKET_CONNECTION_FLAG );
|
|
m_socketServer->SetEventHandler( *this, ID_EDA_SOCKET_EVENT_SERV );
|
|
m_socketServer->Notify( true );
|
|
}
|
|
|
|
|
|
/* 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* socket;
|
|
wxSocketServer* server = (wxSocketServer*) evt.GetSocket();
|
|
|
|
socket = server->Accept();
|
|
|
|
if( socket == NULL )
|
|
return;
|
|
|
|
m_sockets.push_back( socket );
|
|
|
|
socket->Notify( true );
|
|
socket->SetEventHandler( *this, ID_EDA_SOCKET_EVENT );
|
|
socket->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;
|
|
}
|