You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
4.5 KiB

// \file props.cxx
// Property server class.
//
// Written by Curtis Olson, started September 2000.
// Modified by Bernie Bright, May 2002.
//
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#include <simgear/io/sg_netChat.hxx>
#include <simgear/structure/commands.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/debug/logstream.hxx>
#include <cstdio>
#include <sstream>
#include "UGear_command.hxx"
#include "UGear_telnet.hxx"
using std::stringstream;
using std::ends;
/**
* Props connection class.
* This class represents a connection to props client.
*/
class PropsChannel : public simgear::NetChat
{
simgear::NetBuffer buffer;
/**
* Current property node name.
*/
string path;
enum Mode {
PROMPT,
DATA
};
Mode mode;
public:
/**
* Constructor.
*/
PropsChannel();
/**
* Append incoming data to our request buffer.
*
* @param s Character string to append to buffer
* @param n Number of characters to append.
*/
void collectIncomingData( const char* s, int n );
/**
* Process a complete request from the props client.
*/
void foundTerminator();
private:
/**
* Return a "Node no found" error message to the client.
*/
void node_not_found_error( const string& node_name );
};
/**
*
*/
PropsChannel::PropsChannel()
: buffer(512),
path("/"),
mode(PROMPT)
{
setTerminator( "\r\n" );
}
/**
*
*/
void
PropsChannel::collectIncomingData( const char* s, int n )
{
buffer.append( s, n );
}
/**
*
*/
void
PropsChannel::node_not_found_error( const string& node_name )
{
string error = "-ERR Node \"";
error += node_name;
error += "\" not found.";
push( error.c_str() );
push( getTerminator() );
}
/**
* We have a command.
*
*/
void
PropsChannel::foundTerminator()
{
const char* cmd = buffer.getData();
SG_LOG( SG_IO, SG_INFO, "processing command = \"" << cmd << "\"" );
std::vector<std::string> tokens = simgear::strutils::split( cmd );
if (!tokens.empty()) {
string command = tokens[0];
if ( command == "send" ) {
command_mgr.add( tokens[1] );
} else if ( command == "quit" ) {
close();
shouldDelete();
return;
} else if ( command == "data" ) {
mode = DATA;
} else if ( command == "prompt" ) {
mode = PROMPT;
} else {
const char* msg = "\
Valid commands are:\r\n\
\r\n\
data switch to raw data mode\r\n\
prompt switch to interactive mode (default)\r\n\
quit terminate connection\r\n\
send <command> send <command> to UAS\r\n";
push( msg );
}
}
if (mode == PROMPT) {
string prompt = "> ";
push( prompt.c_str() );
}
buffer.remove();
}
/**
*
*/
UGTelnet::UGTelnet( const int port_num ):
enabled(false)
{
port = port_num;
}
/**
*
*/
UGTelnet::~UGTelnet()
{
}
/**
*
*/
bool
UGTelnet::open()
{
if (enabled ) {
printf("This shouldn't happen, but the telnet channel is already in use, ignoring\n" );
return false;
}
simgear::NetChannel::open();
simgear::NetChannel::bind( "", port );
simgear::NetChannel::listen( 5 );
printf("Telnet server started on port %d\n", port );
enabled = true;
poller.addChannel(this);
return true;
}
/**
*
*/
bool
UGTelnet::close()
{
SG_LOG( SG_IO, SG_INFO, "closing UGTelnet" );
return true;
}
/**
*
*/
bool
UGTelnet::process()
{
poller.poll();
return true;
}
/**
*
*/
void
UGTelnet::handleAccept()
{
simgear::IPAddress addr;
int handle = simgear::NetChannel::accept( &addr );
printf("Telent server accepted connection from %s:%d\n",
addr.getHost(), addr.getPort() );
PropsChannel* channel = new PropsChannel();
channel->setHandle( handle );
poller.addChannel(channel);
}