kopia lustrzana https://github.com/jamescoxon/dl-fldigi
rodzic
a2624ebbc8
commit
9750f38994
47
m4/xmlrpc.m4
47
m4/xmlrpc.m4
|
@ -1,33 +1,4 @@
|
|||
AC_DEFUN([AC_FLDIGI_XMLRPC_CONFIG], [
|
||||
ac_cv_xmlrpc=no
|
||||
|
||||
if test "x$XMLRPC_CFLAGS" != "x" && test "x$XMLRPC_LIBS" != "x"; then
|
||||
ac_cv_xmlrpc=yes
|
||||
else
|
||||
if test "x$XMLRPC_C_CONFIG" = "x"; then
|
||||
AC_PATH_PROG([XMLRPC_C_CONFIG], [xmlrpc-c-config], [no])
|
||||
fi
|
||||
if test "x$XMLRPC_C_CONFIG" != "xno" && $XMLRPC_C_CONFIG c++2 abyss-server; then
|
||||
ac_cv_xmlrpc=yes
|
||||
|
||||
test "x$XMLRPC_CFLAGS" = "x" && XMLRPC_CFLAGS=`$XMLRPC_C_CONFIG c++2 abyss-server --cflags`
|
||||
if test "x$XMLRPC_LIBS" = "x"; then
|
||||
XMLRPC_LIBS=`$XMLRPC_C_CONFIG c++2 abyss-server --ldadd | \
|
||||
sed -e 's/^-lpthread$//' \
|
||||
-e 's/^-lpthread / /' \
|
||||
-e 's/ -lpthread$//' \
|
||||
-e 's/ -lpthread / /' `
|
||||
test "$ac_cv_static" = "yes" && XMLRPC_LIBS="-Wl,-Bstatic $XMLRPC_LIBS -Wl,-Bdynamic"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_FLDIGI_XMLRPC], [
|
||||
AC_ARG_VAR([XMLRPC_C_CONFIG], [Path to xmlrpc-c-config utility])
|
||||
AC_ARG_VAR([XMLRPC_CFLAGS], [C compiler flags for libxmlrpc-c, overrriding xmlrpc-c-config])
|
||||
AC_ARG_VAR([XMLRPC_LIBS], [linker flags for libxmlrpc-c, overrriding xmlrpc-c-config])
|
||||
|
||||
AC_ARG_WITH([xmlrpc],
|
||||
AC_HELP_STRING([--with-xmlrpc], [enable xmlrpc server support @<:@autodetect@:>@]),
|
||||
[case "${withval}" in
|
||||
|
@ -40,24 +11,12 @@ AC_DEFUN([AC_FLDIGI_XMLRPC], [
|
|||
AC_DEFINE(USE_XMLRPC, 0, [Define to 1 if we are using xmlrpc])
|
||||
ac_cv_xmlrpc=no
|
||||
else
|
||||
AC_FLDIGI_XMLRPC_CONFIG
|
||||
if test "x$ac_cv_want_xmlrpc" = "xcheck"; then
|
||||
if test "x$ac_cv_xmlrpc" = "xyes"; then
|
||||
AC_DEFINE(USE_XMLRPC, 1, [Define to 1 if we are using xmlrpc])
|
||||
else
|
||||
AC_DEFINE(USE_XMLRPC, 0, [Define to 1 if we are using xmlrpc])
|
||||
fi
|
||||
else # $ac_cv_want_xmlrpc is yes
|
||||
if test "x$ac_cv_xmlrpc" = "xno"; then
|
||||
AC_MSG_FAILURE([--with-xmlrpc was given, but check for libxmlrpc-c failed])
|
||||
else
|
||||
AC_DEFINE(USE_XMLRPC, 1, [Define to 1 if we are using xmlrpc])
|
||||
fi
|
||||
fi
|
||||
ac_cv_xmlrpc=yes
|
||||
AC_DEFINE(USE_XMLRPC, 1, [Define to 1 if we are using xmlrpc])
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_xmlrpc" = "xyes"; then
|
||||
AC_DEFINE_UNQUOTED([XMLRPC_BUILD_VERSION], ["`$XMLRPC_C_CONFIG --version`"], [XMLRPC-C version])
|
||||
AC_DEFINE_UNQUOTED([XMLRPC_BUILD_VERSION], ["Builtin"], [XMLRPC-C version])
|
||||
else
|
||||
AC_DEFINE_UNQUOTED([XMLRPC_BUILD_VERSION], [""], [XMLRPC-C version])
|
||||
fi
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <iosfwd>
|
||||
|
||||
class Socket;
|
||||
class XmlRpcImpl;
|
||||
|
||||
class XML_RPC_Server
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ private:
|
|||
private:
|
||||
static XML_RPC_Server* inst;
|
||||
bool run;
|
||||
Socket* server_socket;
|
||||
XmlRpcImpl* server_impl;
|
||||
};
|
||||
|
||||
void xmlrpc_set_qsy(long long rfc);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
// Stelios Bounanos, M0GLD
|
||||
// Copyright (C) 2008-2010
|
||||
// Dave Freese, W1HKJ
|
||||
// Copyright (C) 2013
|
||||
// Remi Chateauneu, F4ECW
|
||||
//
|
||||
// See EOF for a list of method names. Run "fldigi --xmlrpc-list"
|
||||
// to see a list of method names, signatures and descriptions.
|
||||
|
@ -41,14 +43,15 @@
|
|||
|
||||
#include <signal.h>
|
||||
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
#include <xmlrpc-c/girerr.hpp>
|
||||
#include <xmlrpc-c/registry.hpp>
|
||||
#include <xmlrpc-c/server_abyss.hpp>
|
||||
#include <xmlrpcpp/XmlRpcServer.h>
|
||||
#include <xmlrpcpp/XmlRpcServerMethod.h>
|
||||
#include <xmlrpcpp/XmlRpcValue.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "configuration.h"
|
||||
#include "socket.h"
|
||||
#ifdef HAVE_VALUES_H
|
||||
# include <values.h>
|
||||
#endif
|
||||
#include "threads.h"
|
||||
#include "modem.h"
|
||||
#include "trx.h"
|
||||
|
@ -79,12 +82,129 @@
|
|||
LOG_FILE_SOURCE(debug::LOG_RPC);
|
||||
|
||||
using namespace std;
|
||||
using namespace XmlRpc;
|
||||
|
||||
/// Not defined the usual way on Mingw
|
||||
#ifndef DBL_MAX
|
||||
#define DBL_MAX 1.7976931348623157e+308
|
||||
#endif
|
||||
|
||||
namespace xmlrpc_c
|
||||
{
|
||||
struct method
|
||||
{
|
||||
const char * _signature ;
|
||||
const char * _help ;
|
||||
virtual std::string help(void) const { return _help;}
|
||||
const char * signature() const { return _signature; }
|
||||
virtual ~method() {}
|
||||
};
|
||||
|
||||
typedef method * methodPtr ;
|
||||
typedef XmlRpcValue value ;
|
||||
typedef XmlRpcValue value_string ;
|
||||
typedef XmlRpcValue value_bytestring ;
|
||||
typedef XmlRpcValue value_struct ;
|
||||
typedef XmlRpcValue value_nil ;
|
||||
typedef XmlRpcValue value_array ;
|
||||
typedef XmlRpcValue value_double ;
|
||||
typedef XmlRpcValue value_int ;
|
||||
typedef XmlRpcValue value_boolean ;
|
||||
|
||||
struct fault : public std::runtime_error
|
||||
{
|
||||
typedef enum { CODE_INTERNAL } Codes;
|
||||
|
||||
fault( const char * msg, Codes cd = CODE_INTERNAL ) : std::runtime_error(msg) {}
|
||||
};
|
||||
|
||||
struct paramList
|
||||
{
|
||||
const XmlRpcValue & _params ;
|
||||
paramList( const XmlRpcValue & prm ) : _params(prm) {}
|
||||
|
||||
int getInt(int i, int mini = INT_MIN, int maxi = INT_MAX ) const
|
||||
{
|
||||
int tmp = _params[i];
|
||||
if( tmp < mini ) tmp = mini ;
|
||||
else if(tmp > maxi) tmp = maxi ;
|
||||
return tmp ;
|
||||
}
|
||||
string getString(int i) const { return _params[i]; }
|
||||
std::vector<unsigned char> getBytestring(int i) const
|
||||
{
|
||||
return _params[i];
|
||||
}
|
||||
double getDouble(int i, double mini = -DBL_MAX, double maxi = DBL_MAX) const
|
||||
{
|
||||
double tmp = _params[i];
|
||||
if( tmp < mini ) tmp = mini ;
|
||||
else if(tmp > maxi) tmp = maxi ;
|
||||
return tmp ;
|
||||
}
|
||||
bool getBoolean(int i) const { return _params[i]; }
|
||||
const std::vector<value> & getArray(int i) const { return _params[i]; }
|
||||
void verifyEnd(size_t sz) const
|
||||
{
|
||||
const std::vector<value> & tmpRef = _params ;
|
||||
if( sz != tmpRef.size() ) throw std::runtime_error("Bad size");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template< class RPC_METHOD >
|
||||
struct Method : public RPC_METHOD, public XmlRpcServerMethod
|
||||
{
|
||||
Method( const char * n )
|
||||
: XmlRpcServerMethod( n ) {}
|
||||
|
||||
void execute (XmlRpcValue ¶ms, XmlRpcValue &result)
|
||||
{
|
||||
xmlrpc_c::paramList params2(params) ;
|
||||
RPC_METHOD::execute( params2, &result );
|
||||
}
|
||||
};
|
||||
|
||||
typedef XmlRpcServerMethod * (*RpcFactory)( const char * );
|
||||
|
||||
template<class RPC_METHOD>
|
||||
struct RpcBuilder
|
||||
{
|
||||
static XmlRpcServerMethod * factory( const char * name )
|
||||
{
|
||||
return new Method< RPC_METHOD >( name );
|
||||
}
|
||||
};
|
||||
|
||||
struct XmlRpcImpl : public XmlRpcServer
|
||||
{
|
||||
void open(const char * port)
|
||||
{
|
||||
bindAndListen( atoi( port ) );
|
||||
|
||||
enableIntrospection(true);
|
||||
}
|
||||
void run()
|
||||
{
|
||||
double milli_secs = -1.0 ;
|
||||
// Tell our server to wait indefinately for messages
|
||||
work(milli_secs);
|
||||
}
|
||||
/// BEWARE IT IS CALLED FROM ANOTHER THREAD.
|
||||
void close()
|
||||
{
|
||||
LOG_INFO("Stopping XML-RPC server");
|
||||
exit();
|
||||
shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
struct rpc_method
|
||||
{
|
||||
rpc_method(const xmlrpc_c::methodPtr& m, const char* n)
|
||||
: method(m), name(n) { }
|
||||
xmlrpc_c::methodPtr method;
|
||||
RpcFactory m_fact ;
|
||||
~rpc_method() { delete method ; }
|
||||
xmlrpc_c::method * method ;
|
||||
const char* name;
|
||||
};
|
||||
typedef list<rpc_method> methods_t;
|
||||
|
@ -97,29 +217,30 @@ XML_RPC_Server* XML_RPC_Server::inst = 0;
|
|||
|
||||
XML_RPC_Server::XML_RPC_Server()
|
||||
{
|
||||
server_socket = new Socket;
|
||||
server_impl = new XmlRpcImpl;
|
||||
add_methods();
|
||||
|
||||
for( methods_t::iterator it = methods->begin(), en = methods->end(); it != en; ++it )
|
||||
{
|
||||
XmlRpcServerMethod * mth = dynamic_cast< XmlRpcServerMethod * >( it->method );
|
||||
server_impl->addMethod( mth );
|
||||
}
|
||||
|
||||
server_thread = new pthread_t;
|
||||
server_mutex = new pthread_mutex_t;
|
||||
pthread_mutex_init(server_mutex, NULL);
|
||||
run = true;
|
||||
// run = true;
|
||||
}
|
||||
|
||||
XML_RPC_Server::~XML_RPC_Server()
|
||||
{
|
||||
run = false;
|
||||
if (server_thread) {
|
||||
CANCEL_THREAD(*server_thread);
|
||||
pthread_join(*server_thread, NULL);
|
||||
delete server_thread;
|
||||
server_thread = 0;
|
||||
}
|
||||
delete methods;
|
||||
delete server_socket;
|
||||
methods = 0;
|
||||
// run = false;
|
||||
// the xmlrpc server is closed and deleted when
|
||||
// XML_RPC_Server::stop();
|
||||
// is called from main
|
||||
// delete methods;
|
||||
}
|
||||
|
||||
|
||||
void XML_RPC_Server::start(const char* node, const char* service)
|
||||
{
|
||||
if (inst)
|
||||
|
@ -128,8 +249,7 @@ void XML_RPC_Server::start(const char* node, const char* service)
|
|||
inst = new XML_RPC_Server;
|
||||
|
||||
try {
|
||||
inst->server_socket->open(Address(node, service));
|
||||
inst->server_socket->bind();
|
||||
inst->server_impl->open(service);
|
||||
if (pthread_create(server_thread, NULL, thread_func, NULL) != 0)
|
||||
throw runtime_error(strerror(errno));
|
||||
}
|
||||
|
@ -143,38 +263,26 @@ void XML_RPC_Server::start(const char* node, const char* service)
|
|||
}
|
||||
}
|
||||
|
||||
/// BEWARE IT IS CALLED FROM ANOTHER THREAD.
|
||||
void XML_RPC_Server::stop(void)
|
||||
{
|
||||
// FIXME: uncomment when we have an xmlrpc server that can be interrupted
|
||||
// if (!inst)
|
||||
// return;
|
||||
// inst->server_socket->close();
|
||||
// delete inst;
|
||||
// inst = 0;
|
||||
// return;
|
||||
inst->server_impl->close();
|
||||
delete inst;
|
||||
inst = 0;
|
||||
}
|
||||
|
||||
void* XML_RPC_Server::thread_func(void*)
|
||||
{
|
||||
SET_THREAD_ID(XMLRPC_TID);
|
||||
|
||||
xmlrpc_c::registry reg;
|
||||
for (methods_t::iterator i = methods->begin(); i != methods->end(); ++i)
|
||||
reg.addMethod(i->name, i->method);
|
||||
|
||||
save_signals();
|
||||
xmlrpc_c::serverAbyss server(xmlrpc_c::serverAbyss::constrOpt()
|
||||
.registryP(®)
|
||||
.keepaliveMaxConn(INT_MAX)
|
||||
.socketFd(inst->server_socket->fd())
|
||||
#ifndef NDEBUG
|
||||
.logFileName(HomeDir + "xmlrpc.log")
|
||||
#endif
|
||||
);
|
||||
inst->server_impl->run();
|
||||
restore_signals();
|
||||
|
||||
SET_THREAD_CANCEL();
|
||||
server.run();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -405,7 +513,8 @@ public:
|
|||
}
|
||||
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
|
||||
{
|
||||
*retval = xmlrpc_c::value_string(mode_info[active_modem->get_mode()].sname);
|
||||
const char* cur = mode_info[active_modem->get_mode()].sname;
|
||||
*retval = xmlrpc_c::value_string(cur);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -437,7 +546,8 @@ public:
|
|||
}
|
||||
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
|
||||
{
|
||||
*retval = xmlrpc_c::value_int(active_modem->get_mode());
|
||||
int md = active_modem->get_mode();
|
||||
*retval = xmlrpc_c::value_int(md);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -927,7 +1037,8 @@ public:
|
|||
}
|
||||
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
|
||||
{
|
||||
*retval = xmlrpc_c::value_double(wf->rfcarrier());
|
||||
double rfc = wf->rfcarrier();
|
||||
*retval = xmlrpc_c::value_double(rfc);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2902,7 +3013,7 @@ void XML_RPC_Server::add_methods(void)
|
|||
if (methods)
|
||||
return;
|
||||
#undef ELEM_
|
||||
#define ELEM_(class_, name_) rpc_method(new class_, name_),
|
||||
#define ELEM_(class_, name_) { RpcBuilder<class_>::factory, NULL, name_ },
|
||||
rpc_method m[] = { METHOD_LIST };
|
||||
methods = new methods_t(m, m + sizeof(m)/sizeof(*m));
|
||||
|
||||
|
@ -2910,4 +3021,10 @@ void XML_RPC_Server::add_methods(void)
|
|||
methods->remove_if(rm_pred(progdefaults.xmlrpc_deny.c_str(), false));
|
||||
else if (!progdefaults.xmlrpc_allow.empty())
|
||||
methods->remove_if(rm_pred(progdefaults.xmlrpc_allow.c_str(), true));
|
||||
|
||||
for( methods_t::iterator it = methods->begin(), en = methods->end(); it != en; ++it )
|
||||
{
|
||||
XmlRpcServerMethod * mth = it->m_fact( it->name );
|
||||
it->method = dynamic_cast< xmlrpc_c::method * >( mth );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace XmlRpc {
|
|||
TypeNil,
|
||||
TypeBoolean,
|
||||
TypeInt,
|
||||
TypeUnsigned,
|
||||
TypeLongLong,
|
||||
TypeDouble,
|
||||
TypeString,
|
||||
TypeDateTime,
|
||||
|
@ -41,7 +43,7 @@ namespace XmlRpc {
|
|||
};
|
||||
|
||||
// Non-primitive types
|
||||
typedef std::vector<char> BinaryData;
|
||||
typedef std::vector<unsigned char> BinaryData;
|
||||
typedef std::vector<XmlRpcValue> ValueArray;
|
||||
typedef std::map<std::string, XmlRpcValue> ValueStruct;
|
||||
|
||||
|
@ -59,6 +61,10 @@ namespace XmlRpc {
|
|||
//! Construct an XmlRpcValue with an int value
|
||||
XmlRpcValue(int value) : _type(TypeInt) { _value.asInt = value; }
|
||||
|
||||
XmlRpcValue(unsigned int value) : _type(TypeUnsigned) { _value.asUnsigned = value; }
|
||||
|
||||
XmlRpcValue(long long value) : _type(TypeLongLong) { _value.asLongLong = value; }
|
||||
|
||||
//! Construct an XmlRpcValue with a double value
|
||||
XmlRpcValue(double value) : _type(TypeDouble) { _value.asDouble = value; }
|
||||
|
||||
|
@ -71,6 +77,15 @@ namespace XmlRpc {
|
|||
XmlRpcValue(const char* value) : _type(TypeString)
|
||||
{ _value.asString = new std::string(value); }
|
||||
|
||||
XmlRpcValue(BinaryData const& value) : _type(TypeBase64)
|
||||
{ _value.asBinary = new BinaryData(value); }
|
||||
|
||||
XmlRpcValue(ValueStruct const& value) : _type(TypeStruct)
|
||||
{ _value.asStruct = new ValueStruct(value); }
|
||||
|
||||
XmlRpcValue(ValueArray const& value) : _type(TypeArray)
|
||||
{ _value.asArray = new ValueArray(value); }
|
||||
|
||||
//! Construct an XmlRpcValue with a date/time value.
|
||||
//! @param value A pointer to a struct tm (see localtime)
|
||||
XmlRpcValue(struct tm* value) : _type(TypeDateTime)
|
||||
|
@ -135,6 +150,12 @@ namespace XmlRpc {
|
|||
operator int&() { assertType(TypeInt); return _value.asInt; }
|
||||
operator int() const { assertType(TypeInt); return _value.asInt; }
|
||||
|
||||
operator unsigned int&() { assertType(TypeUnsigned); return _value.asUnsigned; }
|
||||
operator unsigned int() const { assertType(TypeUnsigned); return _value.asUnsigned; }
|
||||
|
||||
operator long long&() { assertType(TypeLongLong); return _value.asLongLong; }
|
||||
operator long long() const { assertType(TypeLongLong); return _value.asLongLong; }
|
||||
|
||||
//! Treat an XmlRpcValue as a double.
|
||||
//! Throws XmlRpcException if the value is initialized to
|
||||
//! a type that is not TypeDouble.
|
||||
|
@ -183,6 +204,8 @@ namespace XmlRpc {
|
|||
//! Can be used to iterate over the entries in the map to find all defined entries.
|
||||
operator ValueStruct const&() { assertStruct(); return *_value.asStruct; }
|
||||
|
||||
operator ValueArray const&() const { assertType(TypeArray); return *_value.asArray; }
|
||||
|
||||
// Accessors
|
||||
//! Return true if the value has been set to something.
|
||||
bool valid() const { return _type != TypeInvalid; }
|
||||
|
@ -259,6 +282,8 @@ namespace XmlRpc {
|
|||
union {
|
||||
bool asBool;
|
||||
int asInt;
|
||||
unsigned int asUnsigned;
|
||||
long long asLongLong;
|
||||
double asDouble;
|
||||
struct tm* asTime;
|
||||
std::string* asString;
|
||||
|
|
Ładowanie…
Reference in New Issue