1 // ----------------------------------------------------------------------------
2 //      xmlrpc.cxx
3 //
4 // Copyright (C) 2008-2010
5 //              Stelios Bounanos, M0GLD
6 // Copyright (C) 2008-2010
7 //              Dave Freese, W1HKJ
8 // Copyright (C) 2013
9 //              Remi Chateauneu, F4ECW
10 //
11 // See EOF for a list of method names. Run "fldigi --xmlrpc-list"
12 // to see a list of method names, signatures and descriptions.
13 //
14 //
15 // This file is part of fldigi.
16 //
17 // fldigi is free software; you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation; either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 // fldigi is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
29 // ----------------------------------------------------------------------------
30 
31 #include <config.h>
32 
33 #include "xmlrpc.h"
34 
35 #include <iostream>
36 #include <iomanip>
37 #include <string>
38 #include <vector>
39 #include <list>
40 #include <map>
41 #include <exception>
42 #include <cstdlib>
43 #include <signal.h>
44 
45 #include "threads.h"
46 
47 struct XmlRpcImpl;
48 
49 #include "globals.h"
50 #include "configuration.h"
51 #ifdef HAVE_VALUES_H
52 #	include <values.h>
53 #endif
54 
55 #include "modem.h"
56 #include "trx.h"
57 #include "fl_digi.h"
58 #include "configuration.h"
59 #include "main.h"
60 #include "waterfall.h"
61 #include "macros.h"
62 #include "qrunner.h"
63 #include "wefax.h"
64 #include "wefax-pic.h"
65 #include "navtex.h"
66 #include "ascii.h"
67 
68 #if USE_HAMLIB
69 #include "hamlib.h"
70 #endif
71 #include "rigio.h"
72 #include "debug.h"
73 #include "re.h"
74 #include "pskrep.h"
75 
76 // required for flrig support
77 #include "fl_digi.h"
78 #include "rigsupport.h"
79 
80 #include "confdialog.h"
81 #include "arq_io.h"
82 #include "status.h"
83 
84 LOG_FILE_SOURCE(debug::LOG_RPC_SERVER);
85 
86 using namespace std;
87 using namespace XmlRpc;
88 
89 /// Not defined the usual way on Mingw
90 #ifndef DBL_MAX
91 #define DBL_MAX 1.7976931348623157e+308
92 #endif
93 
94 namespace xmlrpc_c
95 {
96 	struct method
97 	{
98 		const char * _signature ;
99 		const char * _help ;
helpxmlrpc_c::method100 		virtual std::string help(void) const { return _help;}
signaturexmlrpc_c::method101 		const char * signature() const { return _signature; }
~methodxmlrpc_c::method102 		virtual ~method() {}
103 	};
104 
105 	typedef method * methodPtr ;
106 	typedef XmlRpcValue value ;
107 	typedef XmlRpcValue value_string ;
108 	typedef XmlRpcValue value_bytestring ;
109 	typedef XmlRpcValue value_struct ;
110 	typedef XmlRpcValue value_nil ;
111 	typedef XmlRpcValue value_array ;
112 	typedef XmlRpcValue value_double ;
113 	typedef XmlRpcValue value_int ;
114 	typedef XmlRpcValue value_boolean ;
115 
116 	struct fault : public std::runtime_error
117 	{
118 		typedef enum { CODE_INTERNAL } Codes;
119 
faultxmlrpc_c::fault120 		fault( const char * msg, Codes cd = CODE_INTERNAL ) : std::runtime_error(msg) {}
121 	};
122 
123 	struct paramList
124 	{
125 		const XmlRpcValue & _params ;
paramListxmlrpc_c::paramList126 		paramList( const XmlRpcValue & prm ) : _params(prm) {}
127 
getIntxmlrpc_c::paramList128 		int getInt(int i, int mini = INT_MIN, int maxi = INT_MAX ) const
129 		{
130 			int tmp = _params[i];
131 			if( tmp < mini ) tmp = mini ;
132 			else if(tmp > maxi) tmp = maxi ;
133 			return tmp ;
134 		}
getStringxmlrpc_c::paramList135 		string getString(int i) const { return _params[i]; }
getBytestringxmlrpc_c::paramList136 		std::vector<unsigned char> getBytestring(int i) const
137 		{
138 			return _params[i];
139 		}
getDoublexmlrpc_c::paramList140 		double getDouble(int i, double mini = -DBL_MAX, double maxi = DBL_MAX) const
141 		{
142 			double tmp = _params[i];
143 			if( tmp < mini ) tmp = mini ;
144 			else if(tmp > maxi) tmp = maxi ;
145 			return tmp ;
146 		}
getBooleanxmlrpc_c::paramList147 		bool getBoolean(int i) const { return _params[i]; }
getArrayxmlrpc_c::paramList148 		const std::vector<value> & getArray(int i) const { return _params[i]; }
verifyEndxmlrpc_c::paramList149 		void verifyEnd(size_t sz) const
150 		{
151 			const std::vector<value> & tmpRef = _params ;
152 			if( sz != tmpRef.size() ) throw std::runtime_error("Bad size");
153 		}
154 	};
155 
156 }
157 
158 template< class RPC_METHOD >
159 struct Method : public RPC_METHOD, public XmlRpcServerMethod
160 {
MethodMethod161 	Method( const char * n )
162 	: XmlRpcServerMethod( n ) {}
163 
executeMethod164 	void execute (XmlRpcValue &params, XmlRpcValue &result)
165 	{
166 		xmlrpc_c::paramList params2(params) ;
167 		RPC_METHOD::execute( params2, &result );
168 	}
169 };
170 
171 typedef XmlRpcServerMethod * (*RpcFactory)( const char * );
172 
173 template<class RPC_METHOD>
174 struct RpcBuilder
175 {
factoryRpcBuilder176 	static XmlRpcServerMethod * factory( const char * name )
177 	{
178 		return new Method< RPC_METHOD >( name );
179 	}
180 };
181 
182 struct XmlRpcImpl : public XmlRpcServer
183 {
fl_openXmlRpcImpl184 	void fl_open(const char * port)
185 	{
186 		bindAndListen( atoi( port ) );
187 
188 		enableIntrospection(true);
189 	}
runXmlRpcImpl190 	void run()
191 	{
192 		double milli_secs = -1.0 ;
193 		// Tell our server to wait indefinately for messages
194 		work(milli_secs);
195 	}
196 	/// BEWARE IT IS CALLED FROM ANOTHER THREAD.
closeXmlRpcImpl197 	void close()
198 	{
199 		exit();
200 		shutdown();
201 	}
202 };
203 
204 struct rpc_method
205 {
206 	RpcFactory m_fact ;
~rpc_methodrpc_method207 	~rpc_method() { delete method ; }
208 	xmlrpc_c::method * method ;
209 	const char* name;
210 };
211 typedef list<rpc_method> methods_t;
212 static methods_t* methods = 0;
213 
214 pthread_t* server_thread;
215 pthread_mutex_t* server_mutex;
216 
217 XML_RPC_Server* XML_RPC_Server::inst = 0;
218 
XML_RPC_Server()219 XML_RPC_Server::XML_RPC_Server()
220 {
221 	server_impl = new XmlRpcImpl;
222 	add_methods();
223 
224 	for( methods_t::iterator it = methods->begin(), en = methods->end(); it != en; ++it )
225 	{
226 		XmlRpcServerMethod * mth = dynamic_cast< XmlRpcServerMethod * >( it->method );
227 		server_impl->addMethod( mth );
228 	}
229 
230 	server_thread = new pthread_t;
231 	server_mutex = new pthread_mutex_t;
232 	pthread_mutex_init(server_mutex, NULL);
233 	//	run = true;
234 }
235 
~XML_RPC_Server()236 XML_RPC_Server::~XML_RPC_Server()
237 {
238 	//	run = false;
239 	// the xmlrpc server is closed and deleted  when
240 	// 	XML_RPC_Server::stop();
241 	// is called from main
242 	//	delete methods;
243 }
244 
start(const char * node,const char * service)245 void XML_RPC_Server::start(const char* node, const char* service)
246 {
247 	if (inst)
248 		return;
249 
250 	inst = new XML_RPC_Server;
251 
252 	try {
253 		inst->server_impl->fl_open(service);
254 		if (pthread_create(server_thread, NULL, thread_func, NULL) != 0)
255 			throw runtime_error(strerror(errno));
256 	}
257 	catch (const exception& e) {
258 		LOG_ERROR("Could not start XML-RPC server (%s)", e.what());
259 		delete server_thread;
260 		server_thread = 0;
261 		delete inst;
262 		inst = 0;
263 		return;
264 	}
265 }
266 
267 /// BEWARE IT IS CALLED FROM ANOTHER THREAD.
stop(void)268 void XML_RPC_Server::stop(void)
269 {
270 	// FIXME: uncomment when we have an xmlrpc server that can be interrupted
271 	// if (!inst)
272 	//	return;
273 	inst->server_impl->close();
274 	delete inst;
275 	inst = 0;
276 }
277 
thread_func(void *)278 void* XML_RPC_Server::thread_func(void*)
279 {
280 	SET_THREAD_ID(XMLRPC_TID);
281 
282 	save_signals();
283 	inst->server_impl->run();
284 	restore_signals();
285 
286 	SET_THREAD_CANCEL();
287 	return NULL;
288 }
289 
list_methods(ostream & out)290 ostream& XML_RPC_Server::list_methods(ostream& out)
291 {
292 	add_methods();
293 
294 	ios_base::fmtflags f = out.flags(ios::left);
295 	for (methods_t::const_iterator i = methods->begin(); i != methods->end(); ++i)
296 		out << setw(32) << i->name << setw(8) << i->method->signature()
297 		<< i->method->help() << '\n';
298 
299 	return out << setiosflags(f);
300 }
301 
302 // =============================================================================
303 // Methods that change the server state must call XMLRPC_LOCK
304 // guard_lock (include/threads.h) ensures that mutex are always unlocked.
305 #define XMLRPC_LOCK SET_THREAD_ID(XMLRPC_TID); guard_lock autolock_(server_mutex)
306 
307 // =============================================================================
308 
309 // generic helper functions
310 
set_button(Fl_Button * button,bool value)311 static void set_button(Fl_Button* button, bool value)
312 {
313 	button->value(value);
314 	button->do_callback();
315 }
set_valuator(Fl_Valuator * valuator,double value)316 static void set_valuator(Fl_Valuator* valuator, double value)
317 {
318 	valuator->value(value);
319 	valuator->do_callback();
320 }
set_text(Fl_Input * textw,string & value)321 static void set_text(Fl_Input* textw, string& value)
322 {
323 	textw->value(value.c_str());
324 	textw->do_callback();
325 }
326 
set_text2(Fl_Input2 * textw,string & value)327 static void set_text2(Fl_Input2* textw, string& value)
328 {
329 	textw->value(value.c_str());
330 	textw->do_callback();
331 }
332 
set_combo_contents(Fl_ComboBox * box,const vector<string> * items)333 static void set_combo_contents(Fl_ComboBox* box, const vector<string>* items)
334 {
335 	box->clear();
336 
337 	if (items->empty()) {
338 		box->add("");
339 		box->index(0);
340 		box->deactivate();
341 		return;
342 	}
343 
344 	for (vector<string>::const_iterator i = items->begin(); i != items->end(); ++i) {
345 		box->add(i->c_str());
346 	}
347 
348 	box->index(0);
349 	box->activate();
350 }
351 
set_combo_value(Fl_ComboBox * box,const string & s)352 static void set_combo_value(Fl_ComboBox* box, const string& s)
353 {
354 	box->value(s.c_str());
355 	box->do_callback();
356 }
357 
get_combo_contents(Fl_ComboBox * box,vector<xmlrpc_c::value> * items)358 static void get_combo_contents(Fl_ComboBox* box, vector<xmlrpc_c::value>* items)
359 {
360 	int n = box->lsize(), p = box->index();
361 	items->reserve(n);
362 	for (int i = 0; i < n; i++) {
363 		box->index(i);
364 		items->push_back(xmlrpc_c::value_string(box->value()));
365 	}
366 	box->index(p);
367 }
368 
369 // =============================================================================
370 
371 // XML-RPC interface definition
372 
373 // =============================================================================
374 
375 class Fldigi_list : public xmlrpc_c::method
376 {
377 public:
Fldigi_list()378 	Fldigi_list()
379 	{
380 		_signature = "A:n";
381 		_help = "Returns the list of methods.";
382 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)383 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
384 	{
385 		vector<xmlrpc_c::value> help;
386 		for (methods_t::const_iterator i = methods->begin(); i != methods->end(); ++i) {
387 			map<string, xmlrpc_c::value> item;
388 			item["name"] = xmlrpc_c::value_string(i->name);
389 			item["signature"] = xmlrpc_c::value_string(i->method->signature());
390 			item["help"] = xmlrpc_c::value_string(i->method->help());
391 			help.push_back(xmlrpc_c::value_struct(item));
392 		}
393 
394 		*retval = xmlrpc_c::value_array(help);
395 	}
396 };
397 
398 class Fldigi_name : public xmlrpc_c::method
399 {
400 public:
Fldigi_name()401 	Fldigi_name()
402 	{
403 		_signature = "s:n";
404 		_help = "Returns the program name.";
405 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)406 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
407 	{
408 		*retval = xmlrpc_c::value_string(PACKAGE_TARNAME);
409 	}
410 };
411 
412 class Fldigi_version_struct : public xmlrpc_c::method
413 {
414 public:
Fldigi_version_struct()415 	Fldigi_version_struct()
416 	{
417 		_signature = "S:n";
418 		_help = "Returns the program version as a struct.";
419 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)420 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
421 	{
422 		map<string, xmlrpc_c::value> vstruct;
423 		vstruct["major"] = xmlrpc_c::value_int(FLDIGI_VERSION_MAJOR);
424 		vstruct["minor"] = xmlrpc_c::value_int(FLDIGI_VERSION_MINOR);
425 		vstruct["patch"] = xmlrpc_c::value_string(FLDIGI_VERSION_PATCH);
426 		*retval = xmlrpc_c::value_struct(vstruct);
427 	}
428 };
429 
430 class Fldigi_version_string : public xmlrpc_c::method
431 {
432 public:
Fldigi_version_string()433 	Fldigi_version_string()
434 	{
435 		_signature = "s:n";
436 		_help = "Returns the program version as a string.";
437 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)438 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
439 	{
440 		LOG_INFO("[%s] fldigi.version_string: %s",
441 			XmlRpc::client_id.c_str(),
442 			PACKAGE_VERSION);
443 		*retval = xmlrpc_c::value_string(PACKAGE_VERSION);
444 	}
445 };
446 
447 class Fldigi_name_version : public xmlrpc_c::method
448 {
449 public:
Fldigi_name_version()450 	Fldigi_name_version()
451 	{
452 		_signature = "s:n";
453 		_help = "Returns the program name and version.";
454 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)455 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
456 	{
457 		LOG_INFO("[%s] fldigi.name_version: %s",
458 			XmlRpc::client_id.c_str(),
459 			PACKAGE_STRING);
460 		*retval = xmlrpc_c::value_string(PACKAGE_STRING);
461 	}
462 };
463 
464 class Fldigi_config_dir : public xmlrpc_c::method
465 {
466 public:
Fldigi_config_dir()467 	Fldigi_config_dir()
468 	{
469 		_signature = "s:n";
470 		_help = "Returns the name of the configuration directory.";
471 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)472 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
473 	{
474 		LOG_INFO("[%s] fldigi.config_dir %s",
475 			XmlRpc::client_id.c_str(),
476 			HomeDir.c_str());
477 		*retval = xmlrpc_c::value_string(HomeDir);
478 	}
479 };
480 
481 class Fldigi_terminate : public xmlrpc_c::method
482 {
483 public:
Fldigi_terminate()484 	Fldigi_terminate()
485 	{
486 		_signature = "n:i";
487 		_help = "Terminates fldigi. ``i'' is bitmask specifying data to save: 0=options; 1=log; 2=macros.";
488 	}
489 	enum {
490 		TERM_SAVE_OPTIONS = 1 << 0,
491 		TERM_SAVE_LOG = 1 << 1,
492 		TERM_SAVE_MACROS = 1 << 2
493 	};
terminate(int how)494 	static void terminate(int how)
495 	{
496 		if (how & TERM_SAVE_OPTIONS)
497 			progdefaults.saveDefaults();
498 		progdefaults.changed = false;
499 		progdefaults.confirmExit = false;
500 
501 		extern bool oktoclear;
502 		if (how & TERM_SAVE_LOG && !oktoclear)
503 			qsoSave->do_callback();
504 		oktoclear = true;
505 		progdefaults.NagMe = false;
506 
507 		if (how & TERM_SAVE_MACROS && macros.changed)
508 			macros.saveMacroFile();
509 		macros.changed = false;
510 
511 		fl_digi_main->do_callback();
512 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)513 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
514 	{
515 		XMLRPC_LOCK;
516 		LOG_INFO("[%s] fldigi.terminate: %d",
517 			XmlRpc::client_id.c_str(),
518 			int(params.getInt(0)));
519 		REQ(terminate, params.getInt(0));
520 		*retval = xmlrpc_c::value_nil();
521 	}
522 };
523 
524 // =============================================================================
525 
526 class Modem_get_name : public xmlrpc_c::method
527 {
528 public:
Modem_get_name()529 	Modem_get_name()
530 	{
531 		_signature = "s:n";
532 		_help = "Returns the name of the current modem.";
533 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)534 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
535 	{
536 		const char* cur = mode_info[active_modem->get_mode()].sname;
537 		LOG_INFO("[%s] modem.get_name: %s",
538 			XmlRpc::client_id.c_str(),
539 			cur);
540 		*retval = xmlrpc_c::value_string(cur);
541 	}
542 };
543 
544 class Modem_get_names : public xmlrpc_c::method
545 {
546 public:
Modem_get_names()547 	Modem_get_names()
548 	{
549 		_signature = "A:n";
550 		_help = "Returns all modem names.";
551 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)552 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
553 	{
554 		vector<xmlrpc_c::value> names;
555 		names.reserve(NUM_MODES);
556 		string snames;
557 		for (size_t i = 0; i < NUM_MODES; i++) {
558 			names.push_back(xmlrpc_c::value_string(mode_info[i].sname));
559 			snames.append("\n").append(mode_info[i].sname);
560 		}
561 		LOG_INFO("[%s] modem.get_names: %s",
562 			XmlRpc::client_id.c_str(),
563 			snames.c_str());
564 		*retval = xmlrpc_c::value_array(names);
565 	}
566 };
567 
568 class Modem_get_id : public xmlrpc_c::method
569 {
570 public:
Modem_get_id()571 	Modem_get_id()
572 	{
573 		_signature = "i:n";
574 		_help = "Returns the ID of the current modem.";
575 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)576 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
577 	{
578 		int md = active_modem->get_mode();
579 		LOG_INFO("[%s] modem.get_id %d",
580 			XmlRpc::client_id.c_str(),
581 			md);
582 		*retval = xmlrpc_c::value_int(md);
583 	}
584 };
585 
586 class Modem_get_max_id : public xmlrpc_c::method
587 {
588 public:
Modem_get_max_id()589 	Modem_get_max_id()
590 	{
591 		_signature = "i:n";
592 		_help = "Returns the maximum modem ID number.";
593 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)594 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
595 	{
596 		LOG_INFO("[%s] modem.get_max_id: %d",
597 			XmlRpc::client_id.c_str(),
598 			NUM_MODES -1);
599 		*retval = xmlrpc_c::value_int(NUM_MODES - 1);
600 	}
601 };
602 
603 class Modem_set_by_name : public xmlrpc_c::method
604 {
605 public:
Modem_set_by_name()606 	Modem_set_by_name()
607 	{
608 		_signature = "s:s";
609 		_help = "Sets the current modem. Returns old name.";
610 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)611 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
612 	{
613 		XMLRPC_LOCK;
614 		const char* cur = mode_info[active_modem->get_mode()].sname;
615 
616 		string s = params.getString(0);
617 		LOG_INFO("[%s] modem.set_by_name: %s",
618 			XmlRpc::client_id.c_str(),
619 			s.c_str());
620 		for (size_t i = 0; i < NUM_MODES; i++) {
621 			if (s == mode_info[i].sname) {
622 				REQ_SYNC(init_modem_sync, i, 0);
623 				*retval = xmlrpc_c::value_string(cur);
624 				return;
625 			}
626 		}
627 		*retval = "No such modem";
628 		return;
629 	}
630 };
631 
632 class Modem_set_by_id : public xmlrpc_c::method
633 {
634 public:
Modem_set_by_id()635 	Modem_set_by_id()
636 	{
637 		_signature = "i:i";
638 		_help = "Sets the current modem. Returns old ID.";
639 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)640 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
641 	{
642 		XMLRPC_LOCK;
643 		int cur = active_modem->get_mode();
644 
645 		int i = params.getInt(0, 0, NUM_MODES-1);
646 		REQ_SYNC(init_modem_sync, i, 0);
647 
648 		*retval = xmlrpc_c::value_int(cur);
649 	}
650 };
651 
652 // =============================================================================
653 
654 class Modem_set_carrier : public xmlrpc_c::method
655 {
656 public:
Modem_set_carrier()657 	Modem_set_carrier()
658 	{
659 		_signature = "i:i";
660 		_help = "Sets modem carrier. Returns old carrier.";
661 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)662 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
663 	{
664 		XMLRPC_LOCK;
665 		int cur = active_modem->get_freq();
666 		LOG_INFO("[%s] modem.set_carrier: %d",
667 			XmlRpc::client_id.c_str(),
668 			int(params.getInt(0,1)));
669 		active_modem->set_freq(params.getInt(0, 1));
670 		*retval = xmlrpc_c::value_int(cur);
671 	}
672 };
673 
674 class Modem_inc_carrier : public xmlrpc_c::method
675 {
676 public:
Modem_inc_carrier()677 	Modem_inc_carrier()
678 	{
679 		_signature = "i:i";
680 		_help = "Increments the modem carrier frequency. Returns the new carrier.";
681 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)682 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
683 	{
684 		XMLRPC_LOCK;
685 		int cur = active_modem->get_freq();
686 		LOG_INFO("[%s] modem.inc_carrier: %d",
687 			XmlRpc::client_id.c_str(),
688 			int(params.getInt(0)));
689 		active_modem->set_freq(cur + params.getInt(0));
690 		*retval = xmlrpc_c::value_int(active_modem->get_freq());
691 	}
692 };
693 
694 class Modem_get_carrier : public xmlrpc_c::method
695 {
696 public:
Modem_get_carrier()697 	Modem_get_carrier()
698 	{
699 		_signature = "i:n";
700 		_help = "Returns the modem carrier frequency.";
701 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)702 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
703 	{
704 		LOG_INFO("[%s] modem.get_carrier: %d",
705 			XmlRpc::client_id.c_str(),
706 			int(active_modem->get_freq()));
707 		*retval = xmlrpc_c::value_int(active_modem->get_freq());
708 	}
709 };
710 
711 // =============================================================================
712 
713 class Modem_get_afc_sr : public xmlrpc_c::method
714 {
715 public:
Modem_get_afc_sr()716 	Modem_get_afc_sr()
717 	{
718 		_signature = "i:n";
719 		_help = "Returns the modem AFC search range.";
720 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)721 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
722 	{
723 		if (!(active_modem->get_cap() & modem::CAP_AFC_SR)) {
724 			LOG_ERROR("[%s] modem.get_afc_sr: %s",
725 				XmlRpc::client_id.c_str(),
726 				"Operation not supported by modem");
727 			*retval = "Operation not supported by modem";
728 		} else {
729 			LOG_INFO("[%s] modem.get_afc_sr: %d",
730 				XmlRpc::client_id.c_str(),
731 				int(cntSearchRange->value()));
732 			*retval = xmlrpc_c::value_int((int)cntSearchRange->value());
733 		}
734 	}
735 };
736 
737 class Modem_set_afc_sr : public xmlrpc_c::method
738 {
739 public:
Modem_set_afc_sr()740 	Modem_set_afc_sr()
741 	{
742 		_signature = "i:i";
743 		_help = "Sets the modem AFC search range. Returns the old value.";
744 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)745 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
746 	{
747 		XMLRPC_LOCK;
748 		if (!(active_modem->get_cap() & modem::CAP_AFC_SR)) {
749 			LOG_DEBUG("[%s] modem.set_afc_sr %s",
750 				XmlRpc::client_id.c_str(),
751 				"Operation not supported by modem");
752 			*retval = "Operation not supported by modem";
753 			return;
754 		}
755 
756 		int v = (int)(cntSearchRange->value());
757 		LOG_INFO("[%s] modem.set_afc_sr: %d",
758 			XmlRpc::client_id.c_str(),
759 			v);
760 		REQ(set_valuator, cntSearchRange, params.getInt(0, (int)cntSearchRange->minimum(), (int)cntSearchRange->maximum()));
761 		*retval = xmlrpc_c::value_int(v);
762 	}
763 };
764 
765 class Modem_inc_afc_sr : public xmlrpc_c::method
766 {
767 public:
Modem_inc_afc_sr()768 	Modem_inc_afc_sr()
769 	{
770 		_signature = "i:i";
771 		_help = "Increments the modem AFC search range. Returns the new value.";
772 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)773 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
774 	{
775 		XMLRPC_LOCK;
776 		if (!(active_modem->get_cap() & modem::CAP_AFC_SR)) {
777 			LOG_DEBUG("[%s] modem.inc_afc_sr: %s",
778 				XmlRpc::client_id.c_str(),
779 				"Operation not supported by modem");
780 			*retval = "Operation not supported by modem";
781 			return;
782 		}
783 
784 		int v = (int)(cntSearchRange->value() + params.getInt(0));
785 		LOG_INFO("[%s] modem.inc_afc_sr: %d",
786 			XmlRpc::client_id.c_str(),
787 			v);
788 		REQ(set_valuator, cntSearchRange, v);
789 		*retval = xmlrpc_c::value_int(v);
790 	}
791 };
792 
793 // =============================================================================
794 
get_bw_val(void)795 static Fl_Valuator* get_bw_val(void)
796 {
797 	if (!(active_modem->get_cap() & modem::CAP_BW))
798 		return 0;
799 
800 	trx_mode m = active_modem->get_mode();
801 	if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST)
802 		return sldrHellBW;
803 	else if (m == MODE_CW)
804 		return sldrCWbandwidth;
805 	return 0;
806 }
807 
808 class Modem_get_bw : public xmlrpc_c::method
809 {
810 public:
Modem_get_bw()811 	Modem_get_bw()
812 	{
813 		_signature = "i:n";
814 		_help = "Returns the modem bandwidth.";
815 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)816 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
817 	{
818 		Fl_Valuator* val = get_bw_val();
819 		LOG_INFO("[%s] modem.get_bw: %d",
820 			XmlRpc::client_id.c_str(),
821 			int(get_bw_val()->value()));
822 		if (val)
823 			*retval = xmlrpc_c::value_int((int)get_bw_val()->value());
824 		else
825 			*retval = xmlrpc_c::value_int(0);
826 	}
827 };
828 
829 class Modem_set_bw : public xmlrpc_c::method
830 {
831 public:
Modem_set_bw()832 	Modem_set_bw()
833 	{
834 		_signature = "i:i";
835 		_help = "Sets the modem bandwidth. Returns the old value.";
836 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)837 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
838 	{
839 		XMLRPC_LOCK;
840 		Fl_Valuator* val = get_bw_val();
841 		if (val) {
842 			int v = (int)(val->value());
843 			LOG_INFO("[%s] modem.set_bw: %d",
844 				XmlRpc::client_id.c_str(),
845 				v);
846 			REQ(set_valuator, val, params.getInt(0, (int)val->minimum(), (int)val->maximum()));
847 			*retval = xmlrpc_c::value_int(v);
848 		} else
849 			*retval = xmlrpc_c::value_int(0);
850 	}
851 };
852 
853 class Modem_inc_bw : public xmlrpc_c::method
854 {
855 public:
Modem_inc_bw()856 	Modem_inc_bw()
857 	{
858 		_signature = "i:i";
859 		_help = "Increments the modem bandwidth. Returns the new value.";
860 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)861 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
862 	{
863 		XMLRPC_LOCK;
864 		Fl_Valuator* val = get_bw_val();
865 		if (val) {
866 			int v = (int)(val->value() + params.getInt(0));
867 			LOG_INFO("[%s] modem.inc_bw: %d",
868 				XmlRpc::client_id.c_str(),
869 				v);
870 			REQ(set_valuator, val, v);
871 			*retval = xmlrpc_c::value_int(v);
872 		} else
873 			*retval = xmlrpc_c::value_int(0);
874 	}
875 };
876 
877 // =============================================================================
878 
879 class Modem_get_quality : public xmlrpc_c::method
880 {
881 public:
Modem_get_quality()882 	Modem_get_quality()
883 	{
884 		_signature = "d:n";
885 		_help = "Returns the modem signal quality in the range [0:100].";
886 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)887 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
888 	{
889 		LOG_INFO("[%s] modem.get_quality: %f",
890 			XmlRpc::client_id.c_str(),
891 			pgrsSquelch->value());
892 		*retval = xmlrpc_c::value_double(pgrsSquelch->value());
893 	}
894 };
895 
896 class Modem_search_up : public xmlrpc_c::method
897 {
898 public:
Modem_search_up()899 	Modem_search_up()
900 	{
901 		_signature = "n:n";
902 		_help = "Searches upward in frequency.";
903 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)904 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
905 	{
906 		XMLRPC_LOCK;
907 		LOG_INFO("[%s] %s",
908 			XmlRpc::client_id.c_str(),
909 			"modem.search_up");
910 		REQ(&modem::searchUp, active_modem);
911 		*retval = xmlrpc_c::value_nil();
912 	}
913 };
914 
915 class Modem_search_down : public xmlrpc_c::method
916 {
917 public:
Modem_search_down()918 	Modem_search_down()
919 	{
920 		_signature = "n:n";
921 		_help = "Searches downward in frequency.";
922 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)923 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
924 	{
925 		XMLRPC_LOCK;
926 		LOG_INFO("[%s] %s",
927 			XmlRpc::client_id.c_str(),
928 			"modem.search_down");
929 		REQ(&modem::searchDown, active_modem);
930 		*retval = xmlrpc_c::value_nil();
931 	}
932 };
933 
934 class Modem_olivia_set_bandwidth : public xmlrpc_c::method
935 {
936 public:
Modem_olivia_set_bandwidth()937 	Modem_olivia_set_bandwidth()
938 	{
939 		_signature = "n:i";
940 		_help = "Sets the Olivia bandwidth.";
941 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)942 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
943 	{
944 		int bw;
945 		switch (bw = params.getInt(0)) {
946 			case 125: case 250: case 500: case 1000: case 2000:
947 			{
948 				XMLRPC_LOCK;
949 				LOG_INFO("[%s] modem.olivia_set_bandwidth: %d",
950 					XmlRpc::client_id.c_str(),
951 					bw);
952 				REQ_SYNC(set_olivia_bw, bw);
953 				*retval = xmlrpc_c::value_nil();
954 			}
955 				break;
956 			default:
957 				LOG_INFO("[%s] modem.olivia_set_bandiwidth: %s",
958 					XmlRpc::client_id.c_str(),
959 					"Invalid bandwidth");
960 				*retval = "Invalid Olivia bandwidth";
961 		}
962 	}
963 };
964 
965 class Modem_olivia_get_bandwidth : public xmlrpc_c::method
966 {
967 public:
Modem_olivia_get_bandwidth()968 	Modem_olivia_get_bandwidth()
969 	{
970 		_signature = "i:n";
971 		_help = "Returns the Olivia bandwidth.";
972 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)973 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
974 	{
975 		int bw, v = i_listbox_olivia_bandwidth->index() + 1;
976 
977 		if (v == 0)
978 			bw = 125;
979 		else if (v == 1)
980 			bw = 250;
981 		else if (v == 2)
982 			bw = 500;
983 		else if (v == 3)
984 			bw = 1000;
985 		else
986 			bw = 2000;
987 			LOG_INFO("[%s] modem.olivia_get_bandwidth: %d",
988 				XmlRpc::client_id.c_str(),
989 				bw);
990 		*retval = xmlrpc_c::value_int(bw);
991 	}
992 };
993 
994 class Modem_olivia_set_tones : public xmlrpc_c::method
995 {
996 public:
Modem_olivia_set_tones()997 	Modem_olivia_set_tones()
998 	{
999 		_signature = "n:i";
1000 		_help = "Sets the Olivia tones.";
1001 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1002 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1003 	{
1004 		int tones = params.getInt(0, 2, 256);
1005 		if (powerof2(tones)) {
1006 			XMLRPC_LOCK;
1007 			LOG_INFO("[%s] modem.olivia_set_tones: %d",
1008 				XmlRpc::client_id.c_str(),
1009 				tones);
1010 			REQ_SYNC(set_olivia_tones, tones);
1011 			*retval = xmlrpc_c::value_nil();
1012 		}
1013 		else {
1014 			LOG_INFO("[%s] modem.olivia_set_tones: %s",
1015 				XmlRpc::client_id.c_str(),
1016 				"Invalid olivia tones");
1017 			*retval = "Invalid Olivia tones";
1018 		}
1019 	}
1020 };
1021 
1022 class Modem_olivia_get_tones : public xmlrpc_c::method
1023 {
1024 public:
Modem_olivia_get_tones()1025 	Modem_olivia_get_tones()
1026 	{
1027 		_signature = "i:n";
1028 		_help = "Returns the Olivia tones.";
1029 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1030 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1031 	{
1032 		LOG_INFO("[%s] modem.olivia_get_tones: %d",
1033 			XmlRpc::client_id.c_str(),
1034 			int(1 << (i_listbox_olivia_tones->index() + 1)));
1035 		*retval = xmlrpc_c::value_int(1 << (i_listbox_olivia_tones->index() + 1));
1036 	}
1037 };
1038 
1039 // =============================================================================
1040 
1041 class Main_get_status1 : public xmlrpc_c::method
1042 {
1043 public:
Main_get_status1()1044 	Main_get_status1()
1045 	{
1046 		_signature = "s:n";
1047 		_help = "Returns the contents of the first status field (typically s/n).";
1048 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1049 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1050 	{
1051 		LOG_INFO("[%s] main.get_status1: %s",
1052 			XmlRpc::client_id.c_str(),
1053 			Status1->label());
1054 		*retval = xmlrpc_c::value_string(Status1->label());
1055 	}
1056 };
1057 
1058 class Main_get_status2 : public xmlrpc_c::method
1059 {
1060 public:
Main_get_status2()1061 	Main_get_status2()
1062 	{
1063 		_signature = "s:n";
1064 		_help = "Returns the contents of the second status field.";
1065 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1066 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1067 	{
1068 		LOG_INFO("[%s] main.get_status2: %s",
1069 			XmlRpc::client_id.c_str(),
1070 			Status2->label());
1071 		*retval = xmlrpc_c::value_string(Status2->label());
1072 	}
1073 };
1074 
1075 class Main_get_sb : public xmlrpc_c::method
1076 {
1077 public:
Main_get_sb()1078 	Main_get_sb()
1079 	{
1080 		_signature = "s:n";
1081 		_help = "[DEPRECATED; use main.get_wf_sideband and/or rig.get_mode]";
1082 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1083 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1084 	{
1085 		LOG_INFO("[%s] main.get_sb (DEPRECATED): %s",
1086 			XmlRpc::client_id.c_str(),
1087 			wf->USB() ? "USB" : "LSB");
1088 		*retval = xmlrpc_c::value_string(wf->USB() ? "USB" : "LSB");
1089 	}
1090 };
1091 
1092 class Main_set_sb : public xmlrpc_c::method
1093 {
1094 public:
Main_set_sb()1095 	Main_set_sb()
1096 	{
1097 		_signature = "n:s";
1098 		_help = "[DEPRECATED; use main.set_wf_sideband and/or rig.set_mode]";
1099 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1100 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1101 	{
1102 		XMLRPC_LOCK;
1103 		string s = params.getString(0);
1104 		if (s != "LSB" && s != "USB") {
1105 			*retval = "Invalid argument";
1106 			return;
1107 		}
1108 		LOG_INFO("[%s] main.set_sb (DEPRECATED): %s",
1109 			XmlRpc::client_id.c_str(),
1110 			s.c_str());
1111 		REQ(static_cast<void (waterfall::*)(bool)>(&waterfall::USB), wf, s == "USB");
1112 
1113 		*retval = xmlrpc_c::value_nil();
1114 	}
1115 };
1116 
1117 class Main_get_wf_sideband : public xmlrpc_c::method
1118 {
1119 public:
Main_get_wf_sideband()1120 	Main_get_wf_sideband()
1121 	{
1122 		_signature = "s:n";
1123 		_help = "Returns the current waterfall sideband.";
1124 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1125 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1126 	{
1127 		LOG_INFO("[%s] main.get_wf_sideband: %s",
1128 			 XmlRpc::client_id.c_str(),
1129 			 wf->USB() ? "USB" : "LSB");
1130 		*retval = xmlrpc_c::value_string(wf->USB() ? "USB" : "LSB");
1131 	}
1132 };
1133 
1134 class Main_set_wf_sideband : public xmlrpc_c::method
1135 {
1136 public:
Main_set_wf_sideband()1137 	Main_set_wf_sideband()
1138 	{
1139 		_signature = "n:s";
1140 		_help = "Sets the waterfall sideband to USB or LSB.";
1141 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1142 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1143 	{
1144 		XMLRPC_LOCK;
1145 		string s = params.getString(0);
1146 		if (s != "USB" && s != "LSB")
1147 			*retval = "Invalid argument";
1148 		else
1149 			REQ(static_cast<void (waterfall::*)(bool)>(&waterfall::USB), wf, s == "USB");
1150 			LOG_INFO("[%s] main.set_wf_sideband %s",
1151 				 XmlRpc::client_id.c_str(),
1152 				 s.c_str());
1153 		*retval = xmlrpc_c::value_nil();
1154 	}
1155 };
1156 
xmlrpc_set_qsy(long long rfc)1157 void xmlrpc_set_qsy(long long rfc)
1158 {
1159 	unsigned long int freq = static_cast<unsigned long int>(rfc);
1160 	wf->rfcarrier(freq);
1161 	wf->movetocenter();
1162 	show_frequency(freq);
1163 }
1164 
1165 class Main_set_freq : public xmlrpc_c::method
1166 {
1167 public:
Main_set_freq()1168 	Main_set_freq()
1169 	{
1170 		_signature = "d:d";
1171 		_help = "Sets the RF carrier frequency. Returns the old value.";
1172 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1173 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1174 	{
1175 		XMLRPC_LOCK;
1176 		double rfc = wf->rfcarrier();
1177 		LOG_INFO("[%s] main.set_freq: %f",
1178 			XmlRpc::client_id.c_str(),
1179 			rfc);
1180 		qsy((long long int)params.getDouble(0, 0.0));
1181 		*retval = xmlrpc_c::value_double(rfc);
1182 	}
1183 };
1184 
1185 class Main_inc_freq : public xmlrpc_c::method
1186 {
1187 public:
Main_inc_freq()1188 	Main_inc_freq()
1189 	{
1190 		_signature = "d:d";
1191 		_help = "Increments the RF carrier frequency. Returns the new value.";
1192 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1193 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1194 	{
1195 		XMLRPC_LOCK;
1196 		double rfc = wf->rfcarrier() + params.getDouble(0);
1197 		qsy((long long int)rfc);
1198 		LOG_INFO("[%s] main.inc_freq: %f",
1199 			XmlRpc::client_id.c_str(),
1200 			rfc);
1201 		*retval = xmlrpc_c::value_double(rfc);
1202 	}
1203 };
1204 
1205 // =============================================================================
1206 
1207 class Main_get_afc : public xmlrpc_c::method
1208 {
1209 public:
Main_get_afc()1210 	Main_get_afc()
1211 	{
1212 		_signature = "b:n";
1213 		_help = "Returns the AFC state.";
1214 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1215 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1216 	{
1217 		LOG_INFO("[%s] main.get_afc: %s",
1218 			 XmlRpc::client_id.c_str(),
1219 			 (btnAFC->value() ? "ON" : "OFF"));
1220 		*retval = xmlrpc_c::value_boolean(btnAFC->value());
1221 	}
1222 };
1223 
1224 class Main_set_afc : public xmlrpc_c::method
1225 {
1226 public:
Main_set_afc()1227 	Main_set_afc()
1228 	{
1229 		_signature = "b:b";
1230 		_help = "Sets the AFC state. Returns the old state.";
1231 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1232 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1233 	{
1234 		XMLRPC_LOCK;
1235 		bool v = btnAFC->value();
1236 		LOG_INFO("[%s] main.set_afc: %s",
1237 			XmlRpc::client_id.c_str(),
1238 			(v ? "ON" : "OFF"));
1239 		REQ(set_button, btnAFC, params.getBoolean(0));
1240 		*retval = xmlrpc_c::value_boolean(v);
1241 	}
1242 };
1243 
1244 class Main_toggle_afc : public xmlrpc_c::method
1245 {
1246 public:
Main_toggle_afc()1247 	Main_toggle_afc()
1248 	{
1249 		_signature = "b:n";
1250 		_help = "Toggles the AFC state. Returns the new state.";
1251 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1252 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1253 	{
1254 		XMLRPC_LOCK;
1255 		bool v = !btnAFC->value();
1256 		LOG_INFO("[%s] main.toggle_afc: %s",
1257 			XmlRpc::client_id.c_str(),
1258 			(v ? "ON" : "OFF"));
1259 		REQ(set_button, btnAFC, v);
1260 		*retval = xmlrpc_c::value_boolean(v);
1261 	}
1262 };
1263 
1264 // =============================================================================
1265 
1266 class Main_get_sql : public xmlrpc_c::method
1267 {
1268 public:
Main_get_sql()1269 	Main_get_sql()
1270 	{
1271 		_signature = "b:n";
1272 		_help = "Returns the squelch state.";
1273 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1274 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1275 	{
1276 		LOG_INFO("[%s] main.get_sql: %s",
1277 			 XmlRpc::client_id.c_str(),
1278 			 (btnSQL->value() ? "ON" : "OFF"));
1279 		*retval = xmlrpc_c::value_boolean(btnSQL->value());
1280 	}
1281 };
1282 
1283 class Main_set_sql : public xmlrpc_c::method
1284 {
1285 public:
Main_set_sql()1286 	Main_set_sql()
1287 	{
1288 		_signature = "b:b";
1289 		_help = "Sets the squelch state. Returns the old state.";
1290 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1291 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1292 	{
1293 		XMLRPC_LOCK;
1294 		bool v = btnSQL->value();
1295 		LOG_INFO("[%s] main.set_sql: %s",
1296 			 XmlRpc::client_id.c_str(),
1297 			 (btnSQL->value() ? "ON" : "OFF"));
1298 		REQ(set_button, btnSQL, params.getBoolean(0));
1299 		*retval = xmlrpc_c::value_boolean(v);
1300 	}
1301 };
1302 
1303 class Main_toggle_sql : public xmlrpc_c::method
1304 {
1305 public:
Main_toggle_sql()1306 	Main_toggle_sql()
1307 	{
1308 		_signature = "b:n";
1309 		_help = "Toggles the squelch state. Returns the new state.";
1310 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1311 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1312 	{
1313 		XMLRPC_LOCK;
1314 		bool v = !btnSQL->value();
1315 		LOG_INFO("[%s] main.toggle_sql: %s",
1316 			 XmlRpc::client_id.c_str(),
1317 			 (v ? "ON" : "OFF"));
1318 		REQ(set_button, btnSQL, v);
1319 		*retval = xmlrpc_c::value_boolean(v);
1320 	}
1321 };
1322 
1323 // =============================================================================
1324 
1325 class Main_get_sql_level : public xmlrpc_c::method
1326 {
1327 public:
Main_get_sql_level()1328 	Main_get_sql_level()
1329 	{
1330 		_signature = "d:n";
1331 		_help = "Returns the squelch level.";
1332 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1333 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1334 	{
1335 		LOG_INFO("[%s] main.get_sql_level: %f",
1336 			 XmlRpc::client_id.c_str(),
1337 			 sldrSquelch->value());
1338 		*retval = xmlrpc_c::value_double(sldrSquelch->value());
1339 	}
1340 };
1341 
1342 class Main_set_sql_level : public xmlrpc_c::method
1343 {
1344 public:
Main_set_sql_level()1345 	Main_set_sql_level()
1346 	{
1347 		_signature = "d:d";
1348 		_help = "Sets the squelch level. Returns the old level.";
1349 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1350 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1351 	{
1352 		XMLRPC_LOCK;
1353 		double v = sldrSquelch->value();
1354 		LOG_INFO("[%s] main.set_sql_level: %f",
1355 			XmlRpc::client_id.c_str(),
1356 			v);
1357 		REQ(set_valuator, sldrSquelch, params.getDouble(0, sldrSquelch->maximum(), sldrSquelch->minimum()));
1358 		*retval = xmlrpc_c::value_double(v);
1359 	}
1360 };
1361 
1362 class Main_inc_sql_level : public xmlrpc_c::method
1363 {
1364 public:
Main_inc_sql_level()1365 	Main_inc_sql_level()
1366 	{
1367 		_signature = "d:d";
1368 		_help = "Increments the squelch level. Returns the new level.";
1369 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1370 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1371 	{
1372 		XMLRPC_LOCK;
1373 		double v = sldrSquelch->value();
1374 		LOG_INFO("[%s] main.inc_sql_level: %f",
1375 			XmlRpc::client_id.c_str(),
1376 			v);
1377 		REQ(set_valuator, sldrSquelch, v + params.getDouble(0)); // FIXME: check range
1378 		*retval = xmlrpc_c::value_double(sldrSquelch->value());
1379 	}
1380 };
1381 
1382 // =============================================================================
1383 
1384 class Main_get_rev : public xmlrpc_c::method
1385 {
1386 public:
Main_get_rev()1387 	Main_get_rev()
1388 	{
1389 		_signature = "b:n";
1390 		_help = "Returns the Reverse Sideband state.";
1391 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1392 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1393 	{
1394 		LOG_INFO("[%s] main.get_rev: %s",
1395 			 XmlRpc::client_id.c_str(),
1396 			 (wf->btnRev->value() ? "ON" : "OFF"));
1397 		*retval = xmlrpc_c::value_boolean(wf->btnRev->value());
1398 	}
1399 };
1400 
1401 class Main_set_rev : public xmlrpc_c::method
1402 {
1403 public:
Main_set_rev()1404 	Main_set_rev()
1405 	{
1406 		_signature = "b:b";
1407 		_help = "Sets the Reverse Sideband state. Returns the old state.";
1408 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1409 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1410 	{
1411 		XMLRPC_LOCK;
1412 		bool v = wf->btnRev->value();
1413 		LOG_INFO("[%s] main.set_rev: %s",
1414 			 XmlRpc::client_id.c_str(),
1415 			 (v ? "ON" : "OFF"));
1416 		REQ(set_button, wf->btnRev, params.getBoolean(0));
1417 		*retval = xmlrpc_c::value_boolean(v);
1418 	}
1419 };
1420 
1421 class Main_toggle_rev : public xmlrpc_c::method
1422 {
1423 public:
Main_toggle_rev()1424 	Main_toggle_rev()
1425 	{
1426 		_signature = "b:n";
1427 		_help = "Toggles the Reverse Sideband state. Returns the new state.";
1428 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1429 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1430 	{
1431 		XMLRPC_LOCK;
1432 		bool v = !wf->btnRev->value();
1433 		LOG_INFO("[%s] main.toggle_rev: %s",
1434 			 XmlRpc::client_id.c_str(),
1435 			 (v ? "ON" : "OFF"));
1436 		REQ(set_button, wf->btnRev, v);
1437 		*retval = xmlrpc_c::value_boolean(v);
1438 	}
1439 };
1440 
1441 // =============================================================================
1442 
1443 class Main_get_lock : public xmlrpc_c::method
1444 {
1445 public:
Main_get_lock()1446 	Main_get_lock()
1447 	{
1448 		_signature = "b:n";
1449 		_help = "Returns the Transmit Lock state.";
1450 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1451 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1452 	{
1453 		LOG_INFO("[%s] main.get_lock: %s",
1454 			 XmlRpc::client_id.c_str(),
1455 			 (wf->xmtlock->value() ? "ON" : "OFF"));
1456 		*retval = xmlrpc_c::value_boolean(wf->xmtlock->value());
1457 	}
1458 };
1459 
1460 class Main_set_lock : public xmlrpc_c::method
1461 {
1462 public:
Main_set_lock()1463 	Main_set_lock()
1464 	{
1465 		_signature = "b:b";
1466 		_help = "Sets the Transmit Lock state. Returns the old state.";
1467 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1468 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1469 	{
1470 		XMLRPC_LOCK;
1471 		bool v = wf->xmtlock->value();
1472 		LOG_INFO("[%s] main.set_lock: %s",
1473 			 XmlRpc::client_id.c_str(),
1474 			 (v ? "ON" : "OFF"));
1475 		REQ(set_button, wf->xmtlock, params.getBoolean(0));
1476 		*retval = xmlrpc_c::value_boolean(v);
1477 	}
1478 };
1479 
1480 class Main_toggle_lock : public xmlrpc_c::method
1481 {
1482 public:
Main_toggle_lock()1483 	Main_toggle_lock()
1484 	{
1485 		_signature = "b:n";
1486 		_help = "Toggles the Transmit Lock state. Returns the new state.";
1487 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1488 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1489 	{
1490 		XMLRPC_LOCK;
1491 		bool v = !wf->xmtlock->value();
1492 		LOG_INFO("[%s] main.toggle_lock: %s",
1493 			 XmlRpc::client_id.c_str(),
1494 			 (v ? "ON" : "OFF"));
1495 		REQ(set_button, wf->xmtlock, v);
1496 		*retval = xmlrpc_c::value_boolean(v);
1497 	}
1498 };
1499 
1500 // =============================================================================
1501 class Main_get_txid : public xmlrpc_c::method
1502 {
1503 public:
Main_get_txid()1504 	Main_get_txid()
1505 	{
1506 		_signature = "b:n";
1507 		_help = "Returns the TXID state.";
1508 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1509 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1510 	{
1511 		LOG_INFO("[%s] main.get_txid: %s",
1512 			 XmlRpc::client_id.c_str(),
1513 			 (btnTxRSID->value() ? "ON" : "OFF"));
1514 		*retval = xmlrpc_c::value_boolean(btnTxRSID->value());
1515 	}
1516 };
1517 
1518 class Main_set_txid : public xmlrpc_c::method
1519 {
1520 public:
Main_set_txid()1521 	Main_set_txid()
1522 	{
1523 		_signature = "b:b";
1524 		_help = "Sets the TXID state. Returns the old state.";
1525 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1526 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1527 	{
1528 		XMLRPC_LOCK;
1529 		bool v = btnTxRSID->value();
1530 		LOG_INFO("[%s] main.set_txid: %s",
1531 			 XmlRpc::client_id.c_str(),
1532 			 (v ? "ON" : "OFF"));
1533 		REQ(set_button, btnTxRSID, params.getBoolean(0));
1534 		*retval = xmlrpc_c::value_boolean(v);
1535 	}
1536 };
1537 
1538 class Main_toggle_txid : public xmlrpc_c::method
1539 {
1540 public:
Main_toggle_txid()1541 	Main_toggle_txid()
1542 	{
1543 		_signature = "b:n";
1544 		_help = "Toggles the TXID state. Returns the new state.";
1545 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1546 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1547 	{
1548 		XMLRPC_LOCK;
1549 		bool v = !btnTxRSID->value();
1550 		LOG_INFO("[%s] main.toggle_txid: %s",
1551 			 XmlRpc::client_id.c_str(),
1552 			 (v ? "ON" : "OFF"));
1553 		REQ(set_button, btnTxRSID, v);
1554 		*retval = xmlrpc_c::value_boolean(v);
1555 	}
1556 };
1557 
1558 class Main_get_rsid : public xmlrpc_c::method
1559 {
1560 public:
Main_get_rsid()1561 	Main_get_rsid()
1562 	{
1563 		_signature = "b:n";
1564 		_help = "Returns the RSID state.";
1565 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1566 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1567 	{
1568 		LOG_INFO("[%s] main.get_rsid: %s",
1569 			 XmlRpc::client_id.c_str(),
1570 			 (btnRSID->value() ? "ON" : "OFF"));
1571 		*retval = xmlrpc_c::value_boolean(btnRSID->value());
1572 	}
1573 };
1574 
1575 class Main_set_rsid : public xmlrpc_c::method
1576 {
1577 public:
Main_set_rsid()1578 	Main_set_rsid()
1579 	{
1580 		_signature = "b:b";
1581 		_help = "Sets the RSID state. Returns the old state.";
1582 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1583 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1584 	{
1585 		XMLRPC_LOCK;
1586 		bool v = btnRSID->value();
1587 		LOG_INFO("[%s] main.set_rsid: %s",
1588 			 XmlRpc::client_id.c_str(),
1589 			 (v ? "ON" : "OFF"));
1590 		REQ(set_button, btnRSID, params.getBoolean(0));
1591 		*retval = xmlrpc_c::value_boolean(v);
1592 	}
1593 };
1594 
1595 class Main_toggle_rsid : public xmlrpc_c::method
1596 {
1597 public:
Main_toggle_rsid()1598 	Main_toggle_rsid()
1599 	{
1600 		_signature = "b:n";
1601 		_help = "Toggles the RSID state. Returns the new state.";
1602 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1603 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1604 	{
1605 		XMLRPC_LOCK;
1606 		bool v = !btnRSID->value();
1607 		LOG_INFO("[%s] main.toggle_rsid: %s",
1608 			 XmlRpc::client_id.c_str(),
1609 			 (v ? "ON" : "OFF"));
1610 		REQ(set_button, btnRSID, v);
1611 		*retval = xmlrpc_c::value_boolean(v);
1612 	}
1613 };
1614 
1615 // =============================================================================
1616 
1617 class Main_get_trx_status : public xmlrpc_c::method
1618 {
1619 public:
Main_get_trx_status()1620 	Main_get_trx_status()
1621 	{
1622 		_signature = "s:n";
1623 		_help = "Returns transmit/tune/receive status.";
1624 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1625 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1626 	{
1627 		string st;
1628 		if (btnTune->value())
1629 			st = "tune";
1630 		else if (wf->xmtrcv->value())
1631 			st = "tx";
1632 		else
1633 			st = "rx";
1634 		LOG_INFO("[%s] main.get_trx_status: %s",
1635 			 XmlRpc::client_id.c_str(),
1636 			 st.c_str());
1637 		*retval = xmlrpc_c::value_string(st.c_str());
1638 	}
1639 };
1640 
1641 class Main_tx : public xmlrpc_c::method
1642 {
1643 public:
Main_tx()1644 	Main_tx()
1645 	{
1646 		_signature = "n:n";
1647 		_help = "Transmits.";
1648 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1649 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1650 	{
1651 		XMLRPC_LOCK;
1652 		if (!wf->xmtrcv->value()) {
1653 			LOG_INFO("[%s] %s",
1654 				XmlRpc::client_id.c_str(),
1655 				"main.tx");
1656 			REQ(set_button, wf->xmtrcv, true);
1657 		}
1658 		*retval = xmlrpc_c::value_nil();
1659 	}
1660 };
1661 
1662 class Main_tune : public xmlrpc_c::method
1663 {
1664 public:
Main_tune()1665 	Main_tune()
1666 	{
1667 		_signature = "n:n";
1668 		_help = "Tunes.";
1669 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1670 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1671 	{
1672 		XMLRPC_LOCK;
1673 		if (!btnTune->value()) {
1674 			LOG_INFO("[%s] %s",
1675 				XmlRpc::client_id.c_str(),
1676 				"main.tune");
1677 			REQ(set_button, btnTune, !btnTune->value());
1678 		}
1679 		*retval = xmlrpc_c::value_nil();
1680 	}
1681 };
1682 
1683 class Main_rx : public xmlrpc_c::method
1684 {
1685 public:
Main_rx()1686 	Main_rx()
1687 	{
1688 		_signature = "n:n";
1689 		_help = "Receives.";
1690 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1691 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1692 	{
1693 		XMLRPC_LOCK;
1694 		if (wf->xmtrcv->value()) {
1695 			LOG_INFO("[%s] %s",
1696 				XmlRpc::client_id.c_str(),
1697 				"main.rx");
1698 			REQ(set_button, wf->xmtrcv, false);
1699 		}
1700 		*retval = xmlrpc_c::value_nil();
1701 	}
1702 };
1703 
1704 class Main_abort : public xmlrpc_c::method
1705 {
1706 public:
Main_abort()1707 	Main_abort()
1708 	{
1709 		_signature = "n:n";
1710 		_help = "Aborts a transmit or tune.";
1711 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1712 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1713 	{
1714 		XMLRPC_LOCK;
1715 		if (trx_state == STATE_TX || trx_state == STATE_TUNE) {
1716 			REQ(abort_tx);
1717 			REQ(AbortARQ);
1718 		}
1719 		LOG_INFO("[%s] %s",
1720 			XmlRpc::client_id.c_str(),
1721 			"main.abort");
1722 		*retval = xmlrpc_c::value_nil();
1723 	}
1724 };
1725 
1726 class Main_rx_tx : public xmlrpc_c::method
1727 {
1728 public:
Main_rx_tx()1729 	Main_rx_tx()
1730 	{
1731 		_signature = "n:n";
1732 		_help = "Sets normal Rx/Tx switching.";
1733 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1734 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1735 	{
1736 		XMLRPC_LOCK;
1737 		if (trx_state == STATE_TX || trx_state == STATE_TUNE) {
1738 			REQ(abort_tx);
1739 			REQ(AbortARQ);
1740 		}
1741 		LOG_INFO("[%s] %s",
1742 			XmlRpc::client_id.c_str(),
1743 			"main.rx_tx");
1744 		REQ(set_rx_tx);
1745 		*retval = xmlrpc_c::value_nil();
1746 	}
1747 };
1748 
1749 class Main_rx_only : public xmlrpc_c::method
1750 {
1751 public:
Main_rx_only()1752 	Main_rx_only()
1753 	{
1754 		_signature = "n:n";
1755 		_help = "Disables Tx.";
1756 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1757 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1758 	{
1759 		XMLRPC_LOCK;
1760 		if (trx_state == STATE_TX || trx_state == STATE_TUNE) {
1761 			REQ(abort_tx);
1762 			REQ(AbortARQ);
1763 		}
1764 		LOG_INFO("[%s] %s",
1765 			XmlRpc::client_id.c_str(),
1766 			"main.rx_only");
1767 		REQ(set_rx_only);
1768 		*retval = xmlrpc_c::value_nil();
1769 	}
1770 };
1771 
1772 //----------------------------------------------------------------------
1773 // flmsg i/o
1774 //----------------------------------------------------------------------
1775 bool flmsg_is_online = false;
flmsg_defeat(void *)1776 void flmsg_defeat(void *)
1777 {
1778 	flmsg_is_online = false;
1779 }
1780 
reset_flmsg()1781 static void reset_flmsg()
1782 {
1783 	flmsg_is_online = true;
1784 	Fl::remove_timeout(flmsg_defeat);
1785 	Fl::add_timeout(5.0, flmsg_defeat);
1786 }
1787 
1788 class flmsg_online : public xmlrpc_c::method
1789 {
1790 public:
flmsg_online()1791 	flmsg_online()
1792 	{
1793 		_signature = "n:n";
1794 		_help = "flmsg online indication";
1795 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1796 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1797 	{
1798 		XMLRPC_LOCK;
1799 		reset_flmsg();
1800 		LOG_INFO("[%s] main.flmsg_online: %s",
1801 			XmlRpc::client_id.c_str(),
1802 			"true");
1803 	}
1804 };
1805 
1806 class flmsg_get_data : public xmlrpc_c::method
1807 {
1808 public:
flmsg_get_data()1809 	flmsg_get_data()
1810 	{
1811 		_signature = "6:n";
1812 		_help = "Returns all RX data received since last query.";
1813 	}
get_rx(char ** text,int * size)1814 	static void get_rx(char **text, int *size)
1815 	{
1816 		// the get* methods may throw but this function is not allowed to do so
1817 		*text = get_rx_data();
1818 		*size = strlen(*text);
1819 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1820 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1821 	{
1822 		XMLRPC_LOCK;
1823 		char *text;
1824 		int size;
1825 		REQ_SYNC(get_rx, &text, &size);
1826 
1827 		vector<unsigned char> bytes;
1828 		if (size) {
1829 			bytes.resize(size, 0);
1830 			memcpy(&bytes[0], text, size);
1831 		}
1832 		reset_flmsg();
1833 		LOG_INFO("[%s] flmsg_get_data: %s",
1834 			XmlRpc::client_id.c_str(),
1835 			text);
1836 		*retval = xmlrpc_c::value_bytestring(bytes);
1837 	}
1838 };
1839 
1840 string flmsg_data;
1841 
1842 class flmsg_available : public xmlrpc_c::method
1843 {
1844 public:
flmsg_available()1845 	flmsg_available()
1846 	{
1847 		_signature = "n:n";
1848 		_help = "flmsg data available";
1849 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1850 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1851 	{
1852 		XMLRPC_LOCK;
1853 		int data_ready = (int)flmsg_data.size();
1854 		reset_flmsg();
1855 		LOG_INFO("[%s] main.flmsg_available: %d",
1856 			 XmlRpc::client_id.c_str(),
1857 			 data_ready);
1858 		*retval = xmlrpc_c::value_int(data_ready);
1859 	}
1860 };
1861 
1862 class flmsg_transfer : public xmlrpc_c::method
1863 {
1864 public:
flmsg_transfer()1865 	flmsg_transfer()
1866 	{
1867 		_signature = "n:n";
1868 		_help = "data transfer to flmsg";
1869 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1870 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1871 	{
1872 		XMLRPC_LOCK;
1873 		string tempstr = flmsg_data;
1874 		reset_flmsg();
1875 		LOG_INFO("[%s] main.flmsg_transfer:\n%s",
1876 			 XmlRpc::client_id.c_str(),
1877 			 tempstr.c_str());
1878 		*retval = xmlrpc_c::value_string(tempstr);
1879 		flmsg_data.clear();
1880 	}
1881 };
1882 
1883 class flmsg_squelch : public xmlrpc_c::method
1884 {
1885 public:
flmsg_squelch()1886 	flmsg_squelch()
1887 	{
1888 		_signature = "b:n";
1889 		_help = "Returns the squelch state.";
1890 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1891 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1892 	{
1893 		reset_flmsg();
1894 		LOG_INFO("[%s] main.flmsg_squelch: %s",
1895 			XmlRpc::client_id.c_str(),
1896 			(active_modem->get_metric() > progStatus.sldrSquelchValue ? "ACTIVE" : "NOT ACTIVE"));
1897 		*retval = xmlrpc_c::value_boolean(active_modem->get_metric() > progStatus.sldrSquelchValue);
1898 	}
1899 };
1900 
1901 //----------------------------------------------------------------------
1902 // BACKWARD COMPATABILITY
1903 //----------------------------------------------------------------------
1904 class Main_flmsg_online : public xmlrpc_c::method
1905 {
1906 public:
Main_flmsg_online()1907 	Main_flmsg_online()
1908 	{
1909 		_signature = "n:n";
1910 		_help = "flmsg online indication";
1911 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1912 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1913 	{
1914 		XMLRPC_LOCK;
1915 		reset_flmsg();
1916 		LOG_INFO("[%s] main.flmsg_online: %s",
1917 			XmlRpc::client_id.c_str(),
1918 			"true");
1919 	}
1920 };
1921 
1922 class Main_flmsg_available : public xmlrpc_c::method
1923 {
1924 public:
Main_flmsg_available()1925 	Main_flmsg_available()
1926 	{
1927 		_signature = "n:n";
1928 		_help = "flmsg data available";
1929 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1930 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1931 	{
1932 		XMLRPC_LOCK;
1933 		int data_ready = (int)flmsg_data.size();
1934 		reset_flmsg();
1935 		LOG_INFO("[%s] main.flmsg_available: %d",
1936 			 XmlRpc::client_id.c_str(),
1937 			 data_ready);
1938 		*retval = xmlrpc_c::value_int(data_ready);
1939 	}
1940 };
1941 
1942 class Main_flmsg_transfer : public xmlrpc_c::method
1943 {
1944 public:
Main_flmsg_transfer()1945 	Main_flmsg_transfer()
1946 	{
1947 		_signature = "n:n";
1948 		_help = "data transfer to flmsg";
1949 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1950 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1951 	{
1952 		XMLRPC_LOCK;
1953 		string tempstr = flmsg_data;
1954 		reset_flmsg();
1955 		LOG_INFO("[%s] main.flmsg_transfer:\n%s",
1956 			 XmlRpc::client_id.c_str(),
1957 			 tempstr.c_str());
1958 		*retval = xmlrpc_c::value_string(tempstr);
1959 		flmsg_data.clear();
1960 	}
1961 };
1962 
1963 class Main_flmsg_squelch : public xmlrpc_c::method
1964 {
1965 public:
Main_flmsg_squelch()1966 	Main_flmsg_squelch()
1967 	{
1968 		_signature = "b:n";
1969 		_help = "Returns the squelch state.";
1970 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1971 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1972 	{
1973 		reset_flmsg();
1974 		LOG_INFO("[%s] main.flmsg_squelch: %s",
1975 			XmlRpc::client_id.c_str(),
1976 			(active_modem->get_metric() > progStatus.sldrSquelchValue ? "ACTIVE" : "NOT ACTIVE"));
1977 		*retval = xmlrpc_c::value_boolean(active_modem->get_metric() > progStatus.sldrSquelchValue);
1978 	}
1979 };
1980 
1981 //----------------------------------------------------------------------
1982 
1983 class Main_run_macro : public xmlrpc_c::method
1984 {
1985 public:
Main_run_macro()1986 	Main_run_macro()
1987 	{
1988 		_signature = "n:i";
1989 		_help = "Runs a macro.";
1990 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)1991 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
1992 	{
1993 		XMLRPC_LOCK;
1994 		LOG_INFO("[%s] main.run_macro: %d",
1995 			XmlRpc::client_id.c_str(),
1996 			int(params.getInt(0,0,MAXMACROS-1)));
1997 		REQ(&Main_run_macro::run_macro, params.getInt(0, 0, MAXMACROS-1));
1998 		*retval = xmlrpc_c::value_nil();
1999 	}
run_macro(int i)2000 	static void run_macro(int i) { macros.execute(i); }
2001 };
2002 
2003 class Main_get_max_macro_id : public xmlrpc_c::method
2004 {
2005 public:
Main_get_max_macro_id()2006 	Main_get_max_macro_id()
2007 	{
2008 		_signature = "i:n";
2009 		_help = "Returns the maximum macro ID number.";
2010 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2011 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2012 	{
2013 		LOG_INFO("[%s] main.get_max_macro_id: %d",
2014 			XmlRpc::client_id.c_str(),
2015 			MAXMACROS - 1);
2016 		*retval = xmlrpc_c::value_int(MAXMACROS - 1);
2017 	}
2018 };
2019 
2020 class Main_rsid : public xmlrpc_c::method
2021 {
2022 public:
Main_rsid()2023 	Main_rsid()
2024 	{
2025 		_signature = "n:n";
2026 		_help = "[DEPRECATED; use main.{get,set,toggle}_rsid]";
2027 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2028 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2029 	{
2030 		XMLRPC_LOCK;
2031 		if (!(wf->xmtrcv->value() || btnTune->value() || btnRSID->value())) {
2032 			LOG_INFO("[%s] main.rsid: %s",
2033 				XmlRpc::client_id.c_str(),
2034 				"ENABLE");
2035 			REQ(set_button, btnRSID, true);
2036 		}
2037 		*retval = xmlrpc_c::value_nil();
2038 	}
2039 };
2040 
2041 // =============================================================================
2042 // classes added to support flrig
2043 //
2044 // dhf 6/23/09
2045 
2046 class Main_get_trx_state : public xmlrpc_c::method
2047 {
2048 public:
Main_get_trx_state()2049 	Main_get_trx_state()
2050 	{
2051 		_signature = "s:n";
2052 		_help = "Returns T/R state.";
2053 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2054 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2055 	{
2056 		string st;
2057 		if (trx_state == STATE_TX || trx_state == STATE_TUNE)
2058 			st = "TX";
2059 		else if (trx_state == STATE_RX)
2060 			st = "RX";
2061 		else
2062 			st = "OTHER";
2063 			LOG_INFO("[%s] main.get_trx_state: %s",
2064 				XmlRpc::client_id.c_str(),
2065 				st.c_str());
2066 		*retval = xmlrpc_c::value_string(st.c_str());
2067 	}
2068 };
2069 
2070 pthread_mutex_t tx_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
2071 
2072 static string xmlchars;
2073 bool xmltest_char_available;
2074 static size_t pxmlchar = 0;
2075 static char xml_status_msg[50];
2076 
xmltest_char()2077 int xmltest_char()
2078 {
2079 	guard_lock xmlchr_lock(&tx_queue_mutex);
2080 	if (xmlchars.empty() || !xmltest_char_available)
2081 		return -3;
2082 	if (pxmlchar >= xmlchars.length() ) {
2083 		xmlchars.clear();
2084 		pxmlchar = 0;
2085 		xmltest_char_available = false;
2086 		return -3;
2087 	}
2088 	snprintf(xml_status_msg, sizeof(xml_status_msg), "%d%% sent",
2089 		static_cast<int>(100*pxmlchar/xmlchars.length()));
2090 	put_status(xml_status_msg, 1.0);
2091 	return xmlchars[pxmlchar++] & 0xFF;
2092 }
2093 
reset_xmlchars()2094 void reset_xmlchars()
2095 {
2096 	xmlchars.clear();
2097 	pxmlchar = 0;
2098 	xmltest_char_available = false;
2099 }
2100 
number_of_samples(string s)2101 int number_of_samples( string s)
2102 {
2103 	active_modem->XMLRPC_CPS_TEST = true;
2104 	xmlchars = s;
2105 	pxmlchar = 0;
2106 	xmltest_char_available = true;
2107 
2108 	active_modem->set_stopflag(false);
2109 	trx_transmit();
2110 
2111 	MilliSleep(10);
2112 	while(trx_state != STATE_RX) {
2113 		MilliSleep(10);
2114 		Fl::awake();
2115 	}
2116 	xmltest_char_available = false;
2117 	active_modem->XMLRPC_CPS_TEST = false;
2118 	return active_modem->tx_sample_count;
2119 }
2120 
2121 class Main_get_char_rates : public xmlrpc_c::method
2122 {
2123 public:
Main_get_char_rates()2124 	Main_get_char_rates()
2125 	{
2126 		_signature = "s:n";
2127 		_help = "Returns table of char rates.";
2128 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2129 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2130 	{
2131 		trx_mode id = active_modem->get_mode();
2132 		if ( id == MODE_SSB || id == MODE_WWV || id == MODE_ANALYSIS ||
2133 			id == MODE_WEFAX_576 || id == MODE_WEFAX_288 ) {
2134 			*retval = xmlrpc_c::value_string("0:1:0");
2135 			return;
2136 		}
2137 
2138 		XMLRPC_LOCK;
2139 		REQ(stopMacroTimer);
2140 		int s0 = 0;//number_of_samples("");
2141 		int s1 = 0;
2142 
2143 		string xmlbuf;
2144 		static char result[100];
2145 		static string  line;
2146 		int  chsamples = 0;
2147 		int i = 0;
2148 		for (int m = 0; m < 32; m++) {
2149 			line.clear();
2150 			for (int n = 0; n < 8; n++) {
2151 				i = m*8+n;
2152 
2153 				if ( (id >= MODE_PSK31 && id <= MODE_PSK1000R) ||
2154 					(id >= MODE_4X_PSK63R && id <= MODE_2X_PSK1000R) ||
2155 					id == MODE_CW || id == MODE_RTTY ) {
2156 					s1 = number_of_samples(string(1,i));
2157 					chsamples = active_modem->char_samples;
2158 				} else {
2159 					s0 = number_of_samples(string(1, i));
2160 					int j;
2161 					for(j = 2; j < 32; j++) {
2162 						s1 = number_of_samples(string(j, i));
2163 						if(s1 > s0) break;
2164 					}
2165 					chsamples = (s1 - s0) / (j-1);
2166 				}
2167 				snprintf(result, sizeof(result),
2168 						 n == 7 ? " %.8f\n" : n == 0 ? "%.8f," : " %.8f,",
2169 						 1.0 * chsamples / active_modem->get_samplerate());
2170 				line.append(result);
2171 			}
2172 			xmlbuf.append(line);
2173 		}
2174 		LOG_INFO("[%s] main.get_char_rates:\n%s",
2175 			XmlRpc::client_id.c_str(),
2176 			xmlbuf.c_str());
2177 		*retval = xmlrpc_c::value_string(xmlbuf);
2178 	}
2179 };
2180 
2181 class Main_get_char_timing : public xmlrpc_c::method
2182 {
2183 public:
Main_get_char_timing()2184 	Main_get_char_timing()
2185 	{
2186 		_signature = "n:i";
2187 		_help = "Input: value of character. Returns transmit duration for specified character (samples:sample rate).";
2188 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2189 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2190 	{
2191 		trx_mode id = active_modem->get_mode();
2192 		if ( id == MODE_SSB || id == MODE_WWV || id == MODE_ANALYSIS ||
2193 			id == MODE_WEFAX_576 || id == MODE_WEFAX_288 ) {
2194 			*retval = xmlrpc_c::value_string("0:1:0");
2195 			return;
2196 		}
2197 
2198 		XMLRPC_LOCK;
2199 		REQ(stopMacroTimer);
2200 
2201 		vector<unsigned char> bytes = params.getBytestring(0);
2202 		bytes.push_back(0);
2203 		std::string totest = (const char*)&bytes[0];
2204 
2205 		if (totest.empty() || !active_modem) {
2206 			*retval = xmlrpc_c::value_string("0:1:0");
2207 			return;
2208 		}
2209 
2210 		static std::string xmlbuf;
2211 		char result[64];
2212 		int character = 0;
2213 
2214 		int count = sscanf(totest.c_str(), "%d", &character);
2215 
2216 		if(count != 1) {
2217 			*retval = xmlrpc_c::value_string("0:1:0");
2218 			return;
2219 		}
2220 
2221 		unsigned int s0 = 0, chsamples = 0, over_head = 0;
2222 		int factor = 4;
2223 		unsigned int min_char = 2;
2224 
2225 		bool psk_8_flag = false;
2226 		bool fast_flag  = false;
2227 
2228 		if((id >= MODE_8PSK_FIRST) && (id <= MODE_8PSK_LAST))
2229 		   psk_8_flag = true;
2230 
2231 		if (((id >= MODE_4X_PSK63R) && (id <= MODE_2X_PSK1000R)) ||
2232 			((id >= MODE_PSK31)     && (id <= MODE_PSK1000R))    ||
2233 			 (id == MODE_CW)        || (id == MODE_RTTY)) {
2234 			if(psk_8_flag) fast_flag = false;
2235 			else fast_flag = true;
2236 		}
2237 
2238 		if(((id >= MODE_THOR_FIRST)   && (id <= MODE_THOR_LAST))   ||
2239 		   ((id >= MODE_OLIVIA_FIRST) && (id <= MODE_OLIVIA_LAST))) {
2240 			fast_flag = false;
2241 			psk_8_flag = false;
2242 		}
2243 
2244 		if(fast_flag) {
2245 			s0 = number_of_samples(string(1,character));
2246 			chsamples = active_modem->char_samples;
2247 			over_head = active_modem->ovhd_samples;
2248 		} else if(psk_8_flag) { // This doens't seem to work with the MFSK modes
2249 			int n = 16;
2250             over_head = number_of_samples("");
2251 			chsamples = number_of_samples(string(n, character)) - over_head;
2252 			chsamples /= n;
2253 		} else { // This works for all of the remaining modes.
2254 			unsigned int s1 = 0, s2 = 0;
2255 			unsigned int temp = 0, no_of_chars = 1, k = 0;
2256 			s0 = s1 = s2 = number_of_samples(string(no_of_chars, character));
2257 			for(int i = no_of_chars + 1; i < 32; i++) {
2258 				s2 = number_of_samples(string(i, character));
2259 				if(s2 > s1 && temp++ > min_char) {
2260 					break;
2261 				}
2262 				s0 = s2;
2263 				no_of_chars++;
2264 			}
2265 			k = no_of_chars * factor;
2266 			s1 = number_of_samples(string(k, character));
2267 			chsamples = (s1 - s0) / (k - no_of_chars);
2268 			over_head = s1 - (chsamples * k);
2269 		}
2270 
2271 		snprintf(result, sizeof(result), "%5u:%6u:%6u", chsamples,
2272 				 active_modem->get_samplerate(),
2273 				 over_head);
2274 		xmlbuf.assign(result);
2275 
2276 		LOG_INFO("[%s] main.get_char_timing:\n%s",
2277 			XmlRpc::client_id.c_str(),
2278 			xmlbuf.c_str());
2279 		*retval = xmlrpc_c::value_string(xmlbuf);
2280 	}
2281 };
2282 
2283 class Main_get_tx_timing : public xmlrpc_c::method
2284 {
2285 public:
Main_get_tx_timing()2286 	Main_get_tx_timing()
2287 	{
2288 		_signature = "n:s";
2289 		_help = "Returns transmit duration for test string (samples:sample rate:secs).";
2290 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2291 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2292 	{
2293 		trx_mode id = active_modem->get_mode();
2294 		if ( id == MODE_SSB || id == MODE_WWV || id == MODE_ANALYSIS ||
2295 			id == MODE_WEFAX_576 || id == MODE_WEFAX_288 ||
2296 			id == MODE_SITORB || id == MODE_NAVTEX ) {
2297 			*retval = xmlrpc_c::value_string("0:1:0.0");
2298 			return;
2299 		}
2300 		XMLRPC_LOCK;
2301 		vector<unsigned char> bytes = params.getBytestring(0);
2302 		bytes.push_back(0);
2303 		std::string totest = (const char*)&bytes[0];
2304 		if (totest.empty() || !active_modem) {
2305 			*retval = xmlrpc_c::value_string("0:1:0.0");
2306 			return;
2307 		}
2308 
2309 		int chsamples = number_of_samples(totest);// - start_stop_samples;
2310 
2311 		std::string xmlbuf;
2312 		char buf[64];
2313 		memset(buf, 0, sizeof(buf));
2314 		snprintf(buf, sizeof(buf) - 1, "%u : %u : %.9f", \
2315 				 chsamples,  active_modem->tx_sample_rate,
2316 				 1.0 * chsamples / active_modem->tx_sample_rate);
2317 		xmlbuf.assign(buf);
2318 
2319 		LOG_INFO("[%s] main.get_tx_timing:\n%s",
2320 			XmlRpc::client_id.c_str(),
2321 			xmlbuf.c_str());
2322 		*retval = xmlrpc_c::value_string(xmlbuf);
2323 	}
2324 };
2325 
2326 class Rig_set_name : public xmlrpc_c::method
2327 {
2328 public:
Rig_set_name()2329 	Rig_set_name()
2330 	{
2331 		_signature = "n:s";
2332 		_help = "Sets the rig name for xmlrpc rig";
2333 	}
set_rig_name(const string & name)2334 	static void set_rig_name(const string& name)
2335 	{
2336 		windowTitle = name;
2337 		if (main_window_title.find(windowTitle) == string::npos)
2338 			setTitle();
2339 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2340 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2341 	{
2342 		XMLRPC_LOCK;
2343 		LOG_INFO("[%s] main.set_name: %s",
2344 			XmlRpc::client_id.c_str(),
2345 			string(params.getString(0)).c_str());
2346 		REQ(set_rig_name, params.getString(0));
2347 		*retval = xmlrpc_c::value_nil();
2348 	}
2349 };
2350 
2351 class Rig_get_name : public xmlrpc_c::method
2352 {
2353 public:
Rig_get_name()2354 	Rig_get_name()
2355 	{
2356 		_signature = "s:n";
2357 		_help = "Returns the rig name previously set via rig.set_name";
2358 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2359 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2360 	{
2361 		LOG_INFO("[%s] rig.get_name: %s",
2362 			XmlRpc::client_id.c_str(),
2363 			windowTitle.c_str());
2364 		*retval = xmlrpc_c::value_string(windowTitle);
2365 	}
2366 };
2367 
2368 class Rig_set_frequency : public xmlrpc_c::method
2369 {
2370 public:
Rig_set_frequency()2371 	Rig_set_frequency()
2372 	{
2373 		_signature = "d:d";
2374 		_help = "Sets the RF carrier frequency. Returns the old value.";
2375 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2376 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2377 	{
2378 		XMLRPC_LOCK;
2379 		double rfc = wf->rfcarrier();
2380 		unsigned long int f = (long int)(params.getDouble(0,0.0));
2381 		LOG_INFO("[%s] rig.set_frequency %lu",
2382 			XmlRpc::client_id.c_str(),
2383 			f);
2384 		qsy(f);
2385 		*retval = xmlrpc_c::value_double(rfc);
2386 	}
2387 };
2388 
2389 class Rig_get_freq : public xmlrpc_c::method
2390 {
2391 public:
Rig_get_freq()2392 	Rig_get_freq()
2393 	{
2394 		_signature = "d:n";
2395 		_help = "Returns the RF carrier frequency.";
2396 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2397 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2398 	{
2399 		double rfc = wf->rfcarrier();
2400 		LOG_INFO("[%s] rig.get_frequency %f",
2401 			XmlRpc::client_id.c_str(),
2402 			rfc);
2403 		*retval = xmlrpc_c::value_double(rfc);
2404 	}
2405 };
2406 
2407 class Rig_set_smeter : public xmlrpc_c::method
2408 {
2409 public:
Rig_set_smeter()2410 	Rig_set_smeter()
2411 	{
2412 		_signature = "n:i";
2413 		_help = "Sets the smeter returns null.";
2414 	}
set_smeter(int rfc)2415 	static void set_smeter(int rfc)
2416 	{
2417 		if (smeter && pwrmeter && progStatus.meters) {
2418 			smeter->value(rfc);
2419 			pwrmeter->hide();
2420 			smeter->show();
2421 		}
2422 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2423 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2424 	{
2425 		XMLRPC_LOCK;
2426 		LOG_INFO("[%s] rig.set_smeter: %d",
2427 			XmlRpc::client_id.c_str(),
2428 			int(params.getInt(0)));
2429 		REQ(set_smeter, params.getInt(0));
2430 		*retval = xmlrpc_c::value_nil();
2431 	}
2432 };
2433 
2434 class Rig_set_pwrmeter : public xmlrpc_c::method
2435 {
2436 public:
Rig_set_pwrmeter()2437 	Rig_set_pwrmeter()
2438 	{
2439 		_signature = "n:i";
2440 		_help = "Sets the power meter returns null.";
2441 	}
set_pwrmeter(int rfc)2442 	static void set_pwrmeter(int rfc)
2443 	{
2444 		if (pwrmeter && smeter && progStatus.meters) {
2445 			pwrmeter->value(rfc);
2446 			smeter->hide();
2447 			pwrmeter->show();
2448 		}
2449 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2450 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2451 	{
2452 		XMLRPC_LOCK;
2453 		LOG_INFO("[%s] rig.set_pwrmeter: %d",
2454 			XmlRpc::client_id.c_str(),
2455 			int(params.getInt(0)));
2456 		REQ(set_pwrmeter, params.getInt(0));
2457 		*retval = xmlrpc_c::value_nil();
2458 	}
2459 };
2460 
2461 class Rig_set_modes : public xmlrpc_c::method
2462 {
2463 public:
Rig_set_modes()2464 	Rig_set_modes()
2465 	{
2466 		_signature = "n:A";
2467 		_help = "Sets the list of available rig modes";
2468 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2469 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2470 	{
2471 		XMLRPC_LOCK;
2472 		vector<xmlrpc_c::value> v = params.getArray(0);
2473 
2474 		vector<string> modes;
2475 		string smodes;
2476 		modes.reserve(v.size());
2477 		// copy
2478 		for (vector<xmlrpc_c::value>::const_iterator i = v.begin(); i != v.end(); ++i) {
2479 			modes.push_back(static_cast<string>(xmlrpc_c::value_string(*i)));
2480 			smodes.append("\n").append(static_cast<string>(xmlrpc_c::value_string(*i)));
2481 		}
2482 		LOG_INFO("[%s] rig.set_modes:%s",
2483 			XmlRpc::client_id.c_str(),
2484 			smodes.c_str());
2485 		REQ_SYNC(set_combo_contents, qso_opMODE, &modes);
2486 
2487 		*retval = xmlrpc_c::value_nil();
2488 	}
2489 };
2490 
2491 class Rig_set_mode : public xmlrpc_c::method
2492 {
2493 public:
Rig_set_mode()2494 	Rig_set_mode()
2495 	{
2496 		_signature = "n:s";
2497 		_help = "Selects a mode previously added by rig.set_modes";
2498 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2499 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2500 	{
2501 		XMLRPC_LOCK;
2502 		LOG_INFO("[%s] rig_set_mode: %s",
2503 			XmlRpc::client_id.c_str(),
2504 			string(params.getString(0)).c_str());
2505 		REQ(set_combo_value, qso_opMODE, params.getString(0));
2506 		*retval = xmlrpc_c::value_nil();
2507 	}
2508 };
2509 
2510 class Rig_get_modes : public xmlrpc_c::method
2511 {
2512 public:
Rig_get_modes()2513 	Rig_get_modes()
2514 	{
2515 		_signature = "A:n";
2516 		_help = "Returns the list of available rig modes";
2517 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2518 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2519 	{
2520 		XMLRPC_LOCK;
2521 		vector<xmlrpc_c::value> modes;
2522 		REQ_SYNC(get_combo_contents, qso_opMODE, &modes);
2523 
2524 		string smodes;
2525 		for (size_t n = 0; n < modes.size(); n++)
2526 			smodes.append("\n").append(string(modes[n]));
2527 
2528 		LOG_INFO("[%s] rig.get_modes:%s",
2529 			XmlRpc::client_id.c_str(),
2530 			smodes.c_str());
2531 
2532 		*retval = xmlrpc_c::value_array(modes);
2533 	}
2534 };
2535 
2536 class Rig_get_mode : public xmlrpc_c::method
2537 {
2538 public:
Rig_get_mode()2539 	Rig_get_mode()
2540 	{
2541 		_signature = "s:n";
2542 		_help = "Returns the name of the current transceiver mode";
2543 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2544 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2545 	{
2546 		LOG_INFO("[%s] rig.get_mode: %s",
2547 			XmlRpc::client_id.c_str(),
2548 			qso_opMODE->value());
2549 		*retval = xmlrpc_c::value_string(qso_opMODE->value());
2550 	}
2551 };
2552 
2553 
2554 class Rig_set_bandwidths : public xmlrpc_c::method
2555 {
2556 public:
Rig_set_bandwidths()2557 	Rig_set_bandwidths()
2558 	{
2559 		_signature = "n:A";
2560 		_help = "Sets the list of available rig bandwidths";
2561 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2562 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2563 	{
2564 		XMLRPC_LOCK;
2565 		vector<xmlrpc_c::value> v = params.getArray(0);
2566 
2567 		vector<string> bws;
2568 		string s_bws;
2569 		bws.reserve(v.size());
2570 		for (vector<xmlrpc_c::value>::const_iterator i = v.begin(); i != v.end(); ++i) {
2571 			bws.push_back(static_cast<string>(xmlrpc_c::value_string(*i)));
2572 			s_bws.append("\n").append(static_cast<string>(xmlrpc_c::value_string(*i)));
2573 		}
2574 		LOG_INFO("[%s] rig.set_bandwidths:%s",
2575 			XmlRpc::client_id.c_str(),
2576 			s_bws.c_str());
2577 
2578 		REQ_SYNC(set_combo_contents, qso_opBW, &bws);
2579 
2580 		*retval = xmlrpc_c::value_nil();
2581 	}
2582 };
2583 
2584 class Rig_set_bandwidth : public xmlrpc_c::method
2585 {
2586 public:
Rig_set_bandwidth()2587 	Rig_set_bandwidth()
2588 	{
2589 		_signature = "n:s";
2590 		_help = "Selects a bandwidth previously added by rig.set_bandwidths";
2591 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2592 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2593 	{
2594 		XMLRPC_LOCK;
2595 		LOG_INFO("[%s] rig.set_bandwidth: %s",
2596 			XmlRpc::client_id.c_str(),
2597 			string(params.getString(0)).c_str());
2598 		REQ(set_combo_value, qso_opBW, params.getString(0));
2599 		*retval = xmlrpc_c::value_nil();
2600 	}
2601 };
2602 
2603 class Rig_get_bandwidths : public xmlrpc_c::method
2604 {
2605 public:
Rig_get_bandwidths()2606 	Rig_get_bandwidths()
2607 	{
2608 		_signature = "A:n";
2609 		_help = "Returns the list of available rig bandwidths";
2610 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2611 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2612 	{
2613 		XMLRPC_LOCK;
2614 		vector<xmlrpc_c::value> bws;
2615 
2616 		REQ_SYNC(get_combo_contents, qso_opBW, &bws);
2617 
2618 		string sbws;
2619 		for (size_t n = 0; n < bws.size(); n++)
2620 			sbws.append("\n").append(string(bws[n]));
2621 
2622 		LOG_INFO("[%s] rig.get_modes:%s",
2623 			XmlRpc::client_id.c_str(),
2624 			sbws.c_str());
2625 
2626 		*retval = xmlrpc_c::value_array(bws);
2627 	}
2628 };
2629 
2630 class Rig_get_bandwidth : public xmlrpc_c::method
2631 {
2632 public:
Rig_get_bandwidth()2633 	Rig_get_bandwidth()
2634 	{
2635 		_signature = "s:n";
2636 		_help = "Returns the name of the current transceiver bandwidth";
2637 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2638 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2639 	{
2640 		LOG_INFO("[%s] rig.get_bandwidth: %s",
2641 			XmlRpc::client_id.c_str(),
2642 			string(qso_opBW->value()).c_str());
2643 		*retval = xmlrpc_c::value_string(qso_opBW->value());
2644 	}
2645 };
2646 
2647 class Rig_get_notch : public xmlrpc_c::method
2648 {
2649 public:
Rig_get_notch()2650 	Rig_get_notch()
2651 	{
2652 		_signature = "s:n";
2653 		_help = "Reports a notch filter frequency based on WF action";
2654 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2655 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2656 	{
2657 		LOG_INFO("[%s] rig.get_notch: %d",
2658 			XmlRpc::client_id.c_str(),
2659 			notch_frequency);
2660 		*retval = xmlrpc_c::value_int(notch_frequency);
2661 	}
2662 };
2663 
2664 class Rig_set_notch : public xmlrpc_c::method
2665 {
2666 public:
Rig_set_notch()2667 	Rig_set_notch()
2668 	{
2669 		_signature = "n:i";
2670 		_help = "Sets the notch filter position on WF";
2671 	}
set_notch(int freq)2672 	static void set_notch(int freq)
2673 	{
2674 		notch_frequency = freq;
2675 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2676 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2677 	{
2678 		XMLRPC_LOCK;
2679 		int notch = notch_frequency;
2680 		REQ(set_notch, params.getInt(0));
2681 		LOG_INFO("[%s] rig.set_notch: %d",
2682 			XmlRpc::client_id.c_str(),
2683 			notch);
2684 		*retval = xmlrpc_c::value_int(notch);
2685 	}
2686 };
2687 
2688 // =============================================================================
2689 
2690 class Main_set_rig_name : public Rig_set_name
2691 {
2692 public:
Main_set_rig_name()2693 	Main_set_rig_name() { _help = "[DEPRECATED; use rig.set_name]"; }
2694 };
2695 class Main_set_rig_frequency : public Rig_set_frequency
2696 {
2697 public:
Main_set_rig_frequency()2698 	Main_set_rig_frequency() { _help = "[DEPRECATED; use rig.set_frequency]"; }
2699 };
2700 class Main_set_rig_modes : public Rig_set_modes
2701 {
2702 public:
Main_set_rig_modes()2703 	Main_set_rig_modes() { _help = "[DEPRECATED; use rig.set_modes"; }
2704 };
2705 class Main_set_rig_mode : public Rig_set_mode
2706 {
2707 public:
Main_set_rig_mode()2708 	Main_set_rig_mode() { _help = "[DEPRECATED; use rig.set_mode"; }
2709 };
2710 class Main_get_freq : public Rig_get_freq
2711 {
2712 public:
Main_get_freq()2713 	Main_get_freq() {_help = "[DEPRECATED; use rig.get_frequency"; }
2714 };
2715 class Main_get_rig_modes : public Rig_get_modes
2716 {
2717 public:
Main_get_rig_modes()2718 	Main_get_rig_modes() { _help = "[DEPRECATED; use rig.get_modes]"; }
2719 };
2720 class Main_get_rig_mode : public Rig_get_mode
2721 {
2722 public:
Main_get_rig_mode()2723 	Main_get_rig_mode() { _help = "[DEPRECATED; use rig.get_mode]"; }
2724 };
2725 class Main_set_rig_bandwidths : public Rig_set_bandwidths
2726 {
2727 public:
Main_set_rig_bandwidths()2728 	Main_set_rig_bandwidths() { _help = "[DEPRECATED; use rig.set_bandwidths]"; }
2729 };
2730 class Main_set_rig_bandwidth : public Rig_set_bandwidth
2731 {
2732 public:
Main_set_rig_bandwidth()2733 	Main_set_rig_bandwidth() { _help = "[DEPRECATED; use rig.set_bandwidth]"; }
2734 };
2735 class Main_get_rig_bandwidths : public Rig_set_bandwidths
2736 {
2737 public:
Main_get_rig_bandwidths()2738 	Main_get_rig_bandwidths() { _help = "[DEPRECATED; use rig.get_bandwidths]"; }
2739 };
2740 class Main_get_rig_bandwidth : public Rig_get_bandwidth
2741 {
2742 public:
Main_get_rig_bandwidth()2743 	Main_get_rig_bandwidth() { _help = "[DEPRECATED; use rig.get_bandwidth]"; }
2744 };
2745 
2746 // =============================================================================
2747 
2748 class Log_get_freq : public xmlrpc_c::method
2749 {
2750 public:
Log_get_freq()2751 	Log_get_freq()
2752 	{
2753 		_signature = "s:n";
2754 		_help = "Returns the Frequency field contents.";
2755 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2756 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2757 	{
2758 		LOG_INFO("[%s] log.get_freq: %s",
2759 			XmlRpc::client_id.c_str(),
2760 			inpFreq->value());
2761 		*retval = xmlrpc_c::value_string(inpFreq->value());
2762 	}
2763 };
2764 
2765 class Log_get_time_on : public xmlrpc_c::method
2766 {
2767 public:
Log_get_time_on()2768 	Log_get_time_on()
2769 	{
2770 		_signature = "s:n";
2771 		_help = "Returns the Time-On field contents.";
2772 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2773 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2774 	{
2775 		LOG_INFO("[%s] log.get_time_on: %s",
2776 			XmlRpc::client_id.c_str(),
2777 			inpTimeOn->value());
2778 		*retval = xmlrpc_c::value_string(inpTimeOn->value());
2779 	}
2780 };
2781 
2782 class Log_get_time_off : public xmlrpc_c::method
2783 {
2784 public:
Log_get_time_off()2785 	Log_get_time_off()
2786 	{
2787 		_signature = "s:n";
2788 		_help = "Returns the Time-Off field contents.";
2789 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2790 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2791 	{
2792 		LOG_INFO("[%s] log.get_time_off: %s",
2793 			XmlRpc::client_id.c_str(),
2794 			inpTimeOff->value());
2795 		*retval = xmlrpc_c::value_string(inpTimeOff->value());
2796 	}
2797 };
2798 
2799 class Log_get_call : public xmlrpc_c::method
2800 {
2801 public:
Log_get_call()2802 	Log_get_call()
2803 	{
2804 		_signature = "s:n";
2805 		_help = "Returns the Call field contents.";
2806 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2807 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2808 	{
2809 		LOG_INFO("[%s] log.get_call: %s",
2810 			XmlRpc::client_id.c_str(),
2811 			inpCall->value());
2812 		*retval = xmlrpc_c::value_string(inpCall->value());
2813 	}
2814 };
2815 
2816 class Log_set_call : public xmlrpc_c::method
2817 {
2818 public:
Log_set_call()2819 	Log_set_call()
2820 	{
2821 		_signature = "n:s";
2822 		_help = "Sets the Call field contents.";
2823 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2824 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2825 	{
2826 		XMLRPC_LOCK;
2827 		LOG_INFO("[%s] log.set_call: %s",
2828 			XmlRpc::client_id.c_str(),
2829 			string(params.getString(0)).c_str());
2830 
2831 		REQ(set_text, inpCall, params.getString(0));
2832 
2833 		*retval = xmlrpc_c::value_nil();
2834 	}
2835 };
2836 
2837 class Log_get_name : public xmlrpc_c::method
2838 {
2839 public:
Log_get_name()2840 	Log_get_name()
2841 	{
2842 		_signature = "s:n";
2843 		_help = "Returns the Name field contents.";
2844 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2845 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2846 	{
2847 		LOG_INFO("[%s] log.get_Name: %s",
2848 			XmlRpc::client_id.c_str(),
2849 			inpName->value());
2850 		*retval = xmlrpc_c::value_string(inpName->value());
2851 	}
2852 };
2853 
2854 class Log_set_name : public xmlrpc_c::method
2855 {
2856 public:
Log_set_name()2857 	Log_set_name()
2858 	{
2859 		_signature = "n:s";
2860 		_help = "Sets the Name field contents.";
2861 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2862 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2863 	{
2864 		XMLRPC_LOCK;
2865 		LOG_INFO("[%s] log.set_name: %s",
2866 			XmlRpc::client_id.c_str(),
2867 			string(params.getString(0)).c_str());
2868 		REQ(set_text, inpName, params.getString(0));
2869 
2870 		*retval = xmlrpc_c::value_nil();
2871 	}
2872 };
2873 
2874 class Log_set_qth : public xmlrpc_c::method
2875 {
2876 public:
Log_set_qth()2877 	Log_set_qth()
2878 	{
2879 		_signature = "n:s";
2880 		_help = "Sets the QTH field contents.";
2881 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2882 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2883 	{
2884 		XMLRPC_LOCK;
2885 		LOG_INFO("[%s] log.set_qth: %s",
2886 			XmlRpc::client_id.c_str(),
2887 			string(params.getString(0)).c_str());
2888 		REQ(set_text, inpQth, params.getString(0));
2889 
2890 		*retval = xmlrpc_c::value_nil();
2891 	}
2892 };
2893 
2894 class Log_set_locator : public xmlrpc_c::method
2895 {
2896 public:
Log_set_locator()2897 	Log_set_locator()
2898 	{
2899 		_signature = "n:s";
2900 		_help = "Sets the Locator field contents.";
2901 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2902 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2903 	{
2904 		XMLRPC_LOCK;
2905 		LOG_INFO("[%s] log.set_locator: %s",
2906 			XmlRpc::client_id.c_str(),
2907 			string(params.getString(0)).c_str());
2908 		REQ(set_text, inpLoc, params.getString(0));
2909 
2910 		*retval = xmlrpc_c::value_nil();
2911 	}
2912 };
2913 
2914 class Log_get_rst_in : public xmlrpc_c::method
2915 {
2916 public:
Log_get_rst_in()2917 	Log_get_rst_in()
2918 	{
2919 		_signature = "s:n";
2920 		_help = "Returns the RST(r) field contents.";
2921 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2922 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2923 	{
2924 		LOG_INFO("[%s] log.get_rst_in: %s",
2925 			XmlRpc::client_id.c_str(),
2926 			inpRstIn->value());
2927 		*retval = xmlrpc_c::value_string(inpRstIn->value());
2928 	}
2929 };
2930 
2931 class Log_set_rst_in : public xmlrpc_c::method
2932 {
2933 public:
Log_set_rst_in()2934 	Log_set_rst_in()
2935 	{
2936 		_signature = "n:s";
2937 		_help = "Sets the RST(r) field contents.";
2938 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2939 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2940 	{
2941 		XMLRPC_LOCK;
2942 		LOG_INFO("[%s] log.set_rst_in: %s",
2943 			XmlRpc::client_id.c_str(),
2944 			string(params.getString(0)).c_str());
2945 		REQ(set_text2, inpRstIn, params.getString(0));
2946 
2947 		*retval = xmlrpc_c::value_nil();
2948 	}
2949 };
2950 
2951 class Log_get_rst_out : public xmlrpc_c::method
2952 {
2953 public:
Log_get_rst_out()2954 	Log_get_rst_out()
2955 	{
2956 		_signature = "s:n";
2957 		_help = "Returns the RST(s) field contents.";
2958 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2959 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2960 	{
2961 		LOG_INFO("[%s] log.get_rst_out: %s",
2962 			XmlRpc::client_id.c_str(),
2963 			inpRstOut->value());
2964 		*retval = xmlrpc_c::value_string(inpRstOut->value());
2965 	}
2966 };
2967 
2968 class Log_set_rst_out : public xmlrpc_c::method
2969 {
2970 public:
Log_set_rst_out()2971 	Log_set_rst_out()
2972 	{
2973 		_signature = "n:s";
2974 		_help = "Sets the RST(s) field contents.";
2975 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2976 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2977 	{
2978 		XMLRPC_LOCK;
2979 		LOG_INFO("[%s] log.set_rst_out: %s",
2980 			XmlRpc::client_id.c_str(),
2981 			string(params.getString(0)).c_str());
2982 		REQ(set_text2, inpRstOut, params.getString(0));
2983 
2984 		*retval = xmlrpc_c::value_nil();
2985 	}
2986 };
2987 
2988 class Log_get_serial_number : public xmlrpc_c::method
2989 {
2990 public:
Log_get_serial_number()2991 	Log_get_serial_number()
2992 	{
2993 		_signature = "s:n";
2994 		_help = "Returns the serial number field contents.";
2995 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)2996 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
2997 	{
2998 		LOG_INFO("[%s] log.get_serial_number: %s",
2999 			XmlRpc::client_id.c_str(),
3000 			inpSerNo->value());
3001 		*retval = xmlrpc_c::value_string(inpSerNo->value());
3002 	}
3003 };
3004 
3005 class Log_set_serial_number : public xmlrpc_c::method
3006 {
3007 public:
Log_set_serial_number()3008 	Log_set_serial_number()
3009 	{
3010 		_signature = "n:s";
3011 		_help = "Sets the serial number field contents.";
3012 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3013 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3014 	{
3015 		XMLRPC_LOCK;
3016 		LOG_INFO("[%s] log.set_serial_number: %s",
3017 			XmlRpc::client_id.c_str(),
3018 			string(params.getString(0)).c_str());
3019 		REQ(set_text, inpSerNo, params.getString(0));
3020 		*retval = xmlrpc_c::value_nil();
3021 	}
3022 };
3023 
3024 class Log_get_serial_number_sent : public xmlrpc_c::method
3025 {
3026 public:
Log_get_serial_number_sent()3027 	Log_get_serial_number_sent()
3028 	{
3029 		_signature = "s:n";
3030 		_help = "Returns the serial number (sent) field contents.";
3031 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3032 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3033 	{
3034 		LOG_INFO("[%s] log.get_serial_number_sent: %s",
3035 			XmlRpc::client_id.c_str(),
3036 			outSerNo->value());
3037 		*retval = xmlrpc_c::value_string(outSerNo->value());
3038 	}
3039 };
3040 
3041 class Log_get_exchange : public xmlrpc_c::method
3042 {
3043 public:
Log_get_exchange()3044 	Log_get_exchange()
3045 	{
3046 		_signature = "s:n";
3047 		_help = "Returns the contest exchange field contents.";
3048 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3049 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3050 	{
3051 		LOG_INFO("[%s] log.get_exchange: %s",
3052 			XmlRpc::client_id.c_str(),
3053 			inpXchgIn->value());
3054 		*retval = xmlrpc_c::value_string(inpXchgIn->value());
3055 	}
3056 };
3057 
3058 class Log_set_exchange : public xmlrpc_c::method
3059 {
3060 public:
Log_set_exchange()3061 	Log_set_exchange()
3062 	{
3063 		_signature = "n:s";
3064 		_help = "Sets the contest exchange field contents.";
3065 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3066 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3067 	{
3068 		XMLRPC_LOCK;
3069 		LOG_INFO("[%s] log.set_exchange: %s",
3070 			XmlRpc::client_id.c_str(),
3071 			string(params.getString(0)).c_str());
3072 		REQ(set_text, inpXchgIn, params.getString(0));
3073 		*retval = xmlrpc_c::value_nil();
3074 	}
3075 };
3076 
3077 class Log_get_state : public xmlrpc_c::method
3078 {
3079 public:
Log_get_state()3080 	Log_get_state()
3081 	{
3082 		_signature = "s:n";
3083 		_help = "Returns the State field contents.";
3084 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3085 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3086 	{
3087 		LOG_INFO("[%s] log.get_state: %s",
3088 			XmlRpc::client_id.c_str(),
3089 			inpState->value());
3090 		*retval = xmlrpc_c::value_string(inpState->value());
3091 	}
3092 };
3093 
3094 class Log_get_province : public xmlrpc_c::method
3095 {
3096 public:
Log_get_province()3097 	Log_get_province()
3098 	{
3099 		_signature = "s:n";
3100 		_help = "Returns the Province field contents.";
3101 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3102 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3103 	{
3104 		LOG_INFO("[%s] log.get_province: %s",
3105 			XmlRpc::client_id.c_str(),
3106 			inpVEprov->value());
3107 		*retval = xmlrpc_c::value_string(inpVEprov->value());
3108 	}
3109 };
3110 
3111 class Log_get_country : public xmlrpc_c::method
3112 {
3113 public:
Log_get_country()3114 	Log_get_country()
3115 	{
3116 		_signature = "s:n";
3117 		_help = "Returns the Country field contents.";
3118 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3119 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3120 	{
3121 		LOG_INFO("[%s] log.get_country: %s",
3122 			XmlRpc::client_id.c_str(),
3123 			cboCountry->value());
3124 		*retval = xmlrpc_c::value_string(cboCountry->value());
3125 	}
3126 };
3127 
3128 class Log_get_qth : public xmlrpc_c::method
3129 {
3130 public:
Log_get_qth()3131 	Log_get_qth()
3132 	{
3133 		_signature = "s:n";
3134 		_help = "Returns the QTH field contents.";
3135 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3136 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3137 	{
3138 		LOG_INFO("[%s] log.get_qth: %s",
3139 			XmlRpc::client_id.c_str(),
3140 			inpQTH->value());
3141 		*retval = xmlrpc_c::value_string(inpQth->value());
3142 	}
3143 };
3144 
3145 class Log_get_band : public xmlrpc_c::method
3146 {
3147 public:
Log_get_band()3148 	Log_get_band()
3149 	{
3150 		_signature = "s:n";
3151 		_help = "Returns the current band name.";
3152 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3153 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3154 	{
3155 		LOG_INFO("[%s] log.get_band: %s",
3156 			XmlRpc::client_id.c_str(),
3157 			band_name(band(wf->rfcarrier())));
3158 		*retval = xmlrpc_c::value_string(band_name(band(wf->rfcarrier())));
3159 	}
3160 };
3161 
3162 class Log_get_sb : public Main_get_wf_sideband
3163 {
3164 public:
Log_get_sb()3165 	Log_get_sb() { _help = "[DEPRECATED; use main.get_wf_sideband]"; }
3166 };
3167 
3168 class Log_get_notes : public xmlrpc_c::method
3169 {
3170 public:
Log_get_notes()3171 	Log_get_notes()
3172 	{
3173 		_signature = "s:n";
3174 		_help = "Returns the Notes field contents.";
3175 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3176 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3177 	{
3178 		LOG_INFO("[%s] log.get_notes: %s",
3179 			XmlRpc::client_id.c_str(),
3180 			inpNotes->value());
3181 		*retval = xmlrpc_c::value_string(inpNotes->value());
3182 	}
3183 };
3184 
3185 class Log_get_locator : public xmlrpc_c::method
3186 {
3187 public:
Log_get_locator()3188 	Log_get_locator()
3189 	{
3190 		_signature = "s:n";
3191 		_help = "Returns the Locator field contents.";
3192 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3193 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3194 	{
3195 		LOG_INFO("[%s] log.get_locator: %s",
3196 			XmlRpc::client_id.c_str(),
3197 			inpLoc->value());
3198 		*retval = xmlrpc_c::value_string(inpLoc->value());
3199 	}
3200 };
3201 
3202 class Log_get_az : public xmlrpc_c::method
3203 {
3204 public:
Log_get_az()3205 	Log_get_az()
3206 	{
3207 		_signature = "s:n";
3208 		_help = "Returns the AZ field contents.";
3209 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3210 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3211 	{
3212 		LOG_INFO("[%s] log.get_az: %s",
3213 			XmlRpc::client_id.c_str(),
3214 			inpAZ->value());
3215 		*retval = xmlrpc_c::value_string(inpAZ->value());
3216 	}
3217 };
3218 
3219 class Log_clear : public xmlrpc_c::method
3220 {
3221 public:
Log_clear()3222 	Log_clear()
3223 	{
3224 		_signature = "n:n";
3225 		_help = "Clears the contents of the log fields.";
3226 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3227 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3228 	{
3229 		XMLRPC_LOCK;
3230 		LOG_INFO("[%s] %s",
3231 			XmlRpc::client_id.c_str(),
3232 			"log.clear");
3233 		REQ(clearQSO);
3234 		*retval = xmlrpc_c::value_nil();
3235 	}
3236 };
3237 
3238 // =============================================================================
3239 
3240 class Io_in_use : public xmlrpc_c::method
3241 {
3242 public:
Io_in_use()3243 	Io_in_use()
3244 	{
3245 		_signature = "s:n";
3246 		_help = "Returns the IO port in use (ARQ/KISS).";
3247 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3248 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3249 	{
3250 		string s;
3251 		if(data_io_enabled == KISS_IO)
3252 			s = "KISS";
3253 		else if(data_io_enabled == ARQ_IO)
3254 			s = "ARQ";
3255 		else
3256 			s = "";
3257 		LOG_INFO("[%s] Io.in_use: %s",
3258 			XmlRpc::client_id.c_str(),
3259 			s.c_str());
3260 		*retval = xmlrpc_c::value_string(s.c_str());
3261 	}
3262 };
3263 
3264 class Io_enable_kiss : public xmlrpc_c::method
3265 {
3266 public:
Io_enable_kiss()3267 	Io_enable_kiss()
3268 	{
3269 		_signature = "n:n";
3270 		_help = "Switch to KISS I/O";
3271 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3272 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3273 	{
3274 		XMLRPC_LOCK;
3275 		LOG_INFO("[%s] %s",
3276 			XmlRpc::client_id.c_str(),
3277 			"Io.enable_kiss");
3278 		REQ(enable_kiss);
3279 		*retval = xmlrpc_c::value_nil();
3280 	}
3281 };
3282 
3283 class Io_enable_arq : public xmlrpc_c::method
3284 {
3285 public:
Io_enable_arq()3286 	Io_enable_arq()
3287 	{
3288 		_signature = "n:n";
3289 		_help = "Switch to ARQ I/O";
3290 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3291 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3292 	{
3293 		XMLRPC_LOCK;
3294 		LOG_INFO("[%s] %s",
3295 			XmlRpc::client_id.c_str(),
3296 			"Io.enable_arq");
3297 		REQ(enable_arq);
3298 		*retval = xmlrpc_c::value_nil();
3299 	}
3300 };
3301 
3302 // =============================================================================
3303 
3304 class Text_get_rx_length : public xmlrpc_c::method
3305 {
3306 public:
Text_get_rx_length()3307 	Text_get_rx_length()
3308 	{
3309 		_signature = "i:n";
3310 		_help = "Returns the number of characters in the RX widget.";
3311 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3312 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3313 	{
3314 		LOG_INFO("[%s] Text.get_rx_length: %d",
3315 			XmlRpc::client_id.c_str(),
3316 			(int)(ReceiveText->buffer()->length()));
3317 		*retval = xmlrpc_c::value_int(ReceiveText->buffer()->length());
3318 	}
3319 };
3320 
3321 class Text_get_rx : public xmlrpc_c::method
3322 {
3323 public:
Text_get_rx()3324 	Text_get_rx()
3325 	{
3326 		_signature = "6:ii";
3327 		_help = "Returns a range of characters (start, length) from the RX text widget.";
3328 	}
get_rx_text_range(const xmlrpc_c::paramList * params,xmlrpc_c::fault ** err,char ** text,int * size)3329 	static void get_rx_text_range(const xmlrpc_c::paramList* params, xmlrpc_c::fault** err,
3330 								  char** text, int* size)
3331 	{
3332 		// the get* methods may throw but this function is not allowed to do so
3333 		try {
3334 			params->verifyEnd(2);
3335 
3336 			Fl_Text_Buffer_mod* tbuf = ReceiveText->buffer();
3337 			int len = tbuf->length();
3338 			int start = params->getInt(0, 0, len - 1);
3339 			int n = params->getInt(1, -1, len - start);
3340 			if (n == -1)
3341 				n = len; // we can request more text than is available
3342 
3343 			*text = tbuf->text_range(start, start + n);
3344 			*size = n;
3345 		}
3346 		catch (const xmlrpc_c::fault& f) {
3347 			*err = new xmlrpc_c::fault(f);
3348 		}
3349 		catch (const exception& e) {
3350 			*err = new xmlrpc_c::fault(e.what(), xmlrpc_c::fault::CODE_INTERNAL);
3351 		}
3352 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3353 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3354 	{
3355 		XMLRPC_LOCK;
3356 		xmlrpc_c::fault* err = NULL;
3357 		char* text;
3358 		int size;
3359 
3360 		REQ_SYNC(get_rx_text_range, &params, &err, &text, &size);
3361 		if (unlikely(err)) {
3362 			xmlrpc_c::fault f(*err);
3363 			delete err;
3364 			throw f;
3365 		}
3366 
3367 		vector<unsigned char> bytes;
3368 		if (size) {
3369 			bytes.resize(size, 0);
3370 			memcpy(&bytes[0], text, size);
3371 		}
3372 		*retval = xmlrpc_c::value_bytestring(bytes);
3373 		LOG_INFO("[%s] Text.get_rx: %s",
3374 			XmlRpc::client_id.c_str(),
3375 			text);
3376 		free(text);
3377 	}
3378 };
3379 
3380 class Text_clear_rx : public xmlrpc_c::method
3381 {
3382 public:
Text_clear_rx()3383 	Text_clear_rx()
3384 	{
3385 		_signature = "n:n";
3386 		_help = "Clears the RX text widget.";
3387 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3388 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3389 	{
3390 		XMLRPC_LOCK;
3391 		REQ(&FTextBase::clear, ReceiveText);
3392 		LOG_INFO("[%s] %s",
3393 			XmlRpc::client_id.c_str(),
3394 			"Text.clear_rx");
3395 		*retval = xmlrpc_c::value_nil();
3396 	}
3397 };
3398 
3399 class Text_add_tx_queu : public xmlrpc_c::method
3400 {
3401 public:
Text_add_tx_queu()3402 	Text_add_tx_queu()
3403 	{
3404 		_signature = "n:s";
3405 		_help = "Adds a string to the TX transmit queu.";
3406 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3407 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3408 	{
3409 		XMLRPC_LOCK;
3410 		guard_lock xmlchr_lock(&tx_queue_mutex);
3411 		std::string txt2send = params.getString(0);
3412 		if (xmlchars.empty()) {
3413 			xmlchars = txt2send;
3414 			xmltest_char_available = true;
3415 			pxmlchar = 0;
3416 		}
3417 		else {
3418 			xmlchars.append(txt2send);
3419 		}
3420 		LOG_INFO("[%s] Text.add_tx_queue: %s",
3421 			XmlRpc::client_id.c_str(),
3422 			txt2send.c_str());
3423 		*retval = xmlrpc_c::value_nil();
3424 	}
3425 };
3426 
3427 
3428 class Text_add_tx : public xmlrpc_c::method
3429 {
3430 public:
Text_add_tx()3431 	Text_add_tx()
3432 	{
3433 		_signature = "n:s";
3434 		_help = "Adds a string to the TX text widget.";
3435 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3436 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3437 	{
3438 		XMLRPC_LOCK;
3439 		LOG_INFO("[%s] Text.add_tx: %s",
3440 			XmlRpc::client_id.c_str(),
3441 			string(params.getString(0)).c_str());
3442 		REQ_SYNC(&FTextTX::add_text, TransmitText, params.getString(0));
3443 		*retval = xmlrpc_c::value_nil();
3444 	}
3445 };
3446 
3447 class Text_add_tx_bytes : public xmlrpc_c::method
3448 {
3449 public:
Text_add_tx_bytes()3450 	Text_add_tx_bytes()
3451 	{
3452 		_signature = "n:6";
3453 		_help = "Adds a byte string to the TX text widget.";
3454 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3455 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3456 	{
3457 		XMLRPC_LOCK;
3458 		vector<unsigned char> bytes = params.getBytestring(0);
3459 		bytes.push_back(0);
3460 		LOG_INFO("[%s] Text.add_tx_bytes: %s",
3461 			XmlRpc::client_id.c_str(),
3462 			string((const char*)&bytes[0]).c_str());
3463 		REQ_SYNC(&FTextTX::add_text, TransmitText, string((const char*)&bytes[0]));
3464 
3465 		*retval = xmlrpc_c::value_nil();
3466 	}
3467 };
3468 
3469 class Text_clear_tx : public xmlrpc_c::method
3470 {
3471 public:
Text_clear_tx()3472 	Text_clear_tx()
3473 	{
3474 		_signature = "n:n";
3475 		_help = "Clears the TX text widget.";
3476 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3477 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3478 	{
3479 		XMLRPC_LOCK;
3480 		REQ(&FTextBase::clear, TransmitText);
3481 		LOG_INFO("[%s] %s",
3482 			XmlRpc::client_id.c_str(),
3483 			"Text.clear_tx");
3484 		*retval = xmlrpc_c::value_nil();
3485 	}
3486 };
3487 
3488 // =============================================================================
3489 
3490 class RXTX_get_data : public xmlrpc_c::method
3491 {
3492 public:
RXTX_get_data()3493 	RXTX_get_data()
3494 	{
3495 		_signature = "6:n";
3496 		_help = "Returns all RXTX combined data since last query.";
3497 	}
get_rxtx(char ** text,int * size)3498 	static void get_rxtx(char **text, int *size)
3499 	{
3500 		// the get* methods may throw but this function is not allowed to do so
3501 		*text = get_rxtx_data();
3502 		*size = strlen(*text);
3503 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3504 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3505 	{
3506 		XMLRPC_LOCK;
3507 		char *text;
3508 		int size;
3509 		REQ_SYNC(get_rxtx, &text, &size);
3510 
3511 		vector<unsigned char> bytes;
3512 		if (size) {
3513 			bytes.resize(size, 0);
3514 			memcpy(&bytes[0], text, size);
3515 		}
3516 		LOG_INFO("[%s] RXTX.get_data: %s",
3517 			XmlRpc::client_id.c_str(),
3518 			text);
3519 		*retval = xmlrpc_c::value_bytestring(bytes);
3520 	}
3521 };
3522 
3523 // =============================================================================
3524 
3525 class RX_get_data : public xmlrpc_c::method
3526 {
3527 public:
RX_get_data()3528 	RX_get_data()
3529 	{
3530 		_signature = "6:n";
3531 		_help = "Returns all RX data received since last query.";
3532 	}
get_rx(char ** text,int * size)3533 	static void get_rx(char **text, int *size)
3534 	{
3535 		// the get* methods may throw but this function is not allowed to do so
3536 		*text = get_rx_data();
3537 		*size = strlen(*text);
3538 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3539 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3540 	{
3541 		XMLRPC_LOCK;
3542 		char *text;
3543 		int size;
3544 		REQ_SYNC(get_rx, &text, &size);
3545 
3546 		vector<unsigned char> bytes;
3547 		if (size) {
3548 			bytes.resize(size, 0);
3549 			memcpy(&bytes[0], text, size);
3550 		}
3551 		LOG_INFO("[%s] RX.get_data: %s",
3552 			XmlRpc::client_id.c_str(),
3553 			text);
3554 		*retval = xmlrpc_c::value_bytestring(bytes);
3555 	}
3556 };
3557 
3558 // =============================================================================
3559 
3560 class TX_get_data : public xmlrpc_c::method
3561 {
3562 public:
TX_get_data()3563 	TX_get_data()
3564 	{
3565 		_signature = "6:n";
3566 		_help = "Returns all TX data transmitted since last query.";
3567 	}
get_tx(char ** text,int * size)3568 	static void get_tx(char **text, int *size)
3569 	{
3570 		// the get* methods may throw but this function is not allowed to do so
3571 		*text = get_tx_data();
3572 		*size = strlen(*text);
3573 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3574 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3575 	{
3576 		XMLRPC_LOCK;
3577 		char *text;
3578 		int size;
3579 		REQ_SYNC(get_tx, &text, &size);
3580 
3581 		vector<unsigned char> bytes;
3582 		if (size) {
3583 			bytes.resize(size, 0);
3584 			memcpy(&bytes[0], text, size);
3585 		}
3586 		LOG_INFO("[%s] TX.get_data: %s",
3587 			XmlRpc::client_id.c_str(),
3588 			text);
3589 		*retval = xmlrpc_c::value_bytestring(bytes);
3590 	}
3591 };
3592 
3593 // =============================================================================
3594 
3595 class Spot_get_auto : public xmlrpc_c::method
3596 {
3597 public:
Spot_get_auto()3598 	Spot_get_auto()
3599 	{
3600 		_signature = "b:n";
3601 		_help = "Returns the autospotter state.";
3602 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3603 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3604 	{
3605 		LOG_INFO("[%s] Spot.get_auto: %s",
3606 			XmlRpc::client_id.c_str(),
3607 			(btnAutoSpot->value() ? "ON" : "OFF"));
3608 		*retval = xmlrpc_c::value_boolean(btnAutoSpot->value());
3609 	}
3610 };
3611 
3612 class Spot_set_auto : public xmlrpc_c::method
3613 {
3614 public:
Spot_set_auto()3615 	Spot_set_auto()
3616 	{
3617 		_signature = "b:b";
3618 		_help = "Sets the autospotter state. Returns the old state.";
3619 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3620 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3621 	{
3622 		XMLRPC_LOCK;
3623 		bool v = btnAutoSpot->value();
3624 		REQ(set_button, (Fl_Button *) btnAutoSpot, params.getBoolean(0));
3625 		LOG_INFO("[%s] Spot.set_auto: %s",
3626 			XmlRpc::client_id.c_str(),
3627 			(v ? "ON" : "OFF"));
3628 		*retval = xmlrpc_c::value_boolean(v);
3629 	}
3630 };
3631 
3632 class Spot_toggle_auto : public xmlrpc_c::method
3633 {
3634 public:
Spot_toggle_auto()3635 	Spot_toggle_auto()
3636 	{
3637 		_signature = "b:n";
3638 		_help = "Toggles the autospotter state. Returns the new state.";
3639 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3640 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3641 	{
3642 		XMLRPC_LOCK;
3643 		bool v = !btnAutoSpot->value();
3644 		LOG_INFO("[%s] Spot.toggle_auto: %s",
3645 			XmlRpc::client_id.c_str(),
3646 			(v ? "ON" : "OFF"));
3647 		REQ(set_button, (Fl_Button *) btnAutoSpot, v);
3648 		*retval = xmlrpc_c::value_boolean(v);
3649 	}
3650 };
3651 
3652 class Spot_pskrep_get_count : public xmlrpc_c::method
3653 {
3654 public:
Spot_pskrep_get_count()3655 	Spot_pskrep_get_count()
3656 	{
3657 		_signature = "i:n";
3658 		_help = "Returns the number of callsigns spotted in the current session.";
3659 	}
execute(const xmlrpc_c::paramList & params,xmlrpc_c::value * retval)3660 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3661 	{
3662 		int cnt = static_cast<int>(pskrep_count());
3663 		LOG_INFO("[%s] Spot.pskrep_get_count: %d",
3664 			XmlRpc::client_id.c_str(),
3665 			cnt);
3666 		*retval = xmlrpc_c::value_int(cnt);
3667 	}
3668 };
3669 
3670 // =============================================================================
3671 
3672 // Returns the current wefax modem pointer.
get_wefax(void)3673 static wefax * get_wefax(void)
3674 {
3675 	if( ( active_modem->get_mode() >= MODE_WEFAX_FIRST )
3676 	   && ( active_modem->get_mode() <= MODE_WEFAX_LAST ) )
3677 	{
3678 		wefax * ptr = dynamic_cast<wefax *>( active_modem );
3679 		if( ptr == NULL ) throw runtime_error("Inconsistent wefax object");
3680 		return ptr ;
3681 	}
3682 	throw runtime_error("Not in wefax mode");
3683 }
3684 
3685 struct Wefax_state_string : public xmlrpc_c::method
3686 {
Wefax_state_stringWefax_state_string3687 	Wefax_state_string() {
3688 		_signature = "s:n";
3689 		_help = "Returns Wefax engine state (tx and rx) for information."; }
3690 
executeWefax_state_string3691 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3692 	try
3693 	{
3694 		string wfs = get_wefax()->state_string();
3695 		LOG_INFO("[%s] wefax.state_string: %s",
3696 			XmlRpc::client_id.c_str(),
3697 			wfs.c_str());
3698 		*retval = xmlrpc_c::value_string( wfs.c_str() );
3699 	}
3700 	catch( const exception & e )
3701 	{
3702 		LOG_ERROR("[%s] wefax.state_string: %s",
3703 			XmlRpc::client_id.c_str(),
3704 			e.what());
3705 		*retval = xmlrpc_c::value_string( e.what());
3706 	}
3707 };
3708 
3709 struct Wefax_skip_apt : public xmlrpc_c::method
3710 {
Wefax_skip_aptWefax_skip_apt3711 	Wefax_skip_apt() {
3712 		_signature = "s:n";
3713 		_help = "Skip APT during Wefax reception"; }
3714 
executeWefax_skip_apt3715 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3716 	try
3717 	{
3718 		get_wefax()->skip_apt();
3719 		LOG_INFO("[%s] %s",
3720 			XmlRpc::client_id.c_str(),
3721 			"wefax.skip_apt");
3722 		*retval = xmlrpc_c::value_string( "" );
3723 	}
3724 	catch( const exception & e )
3725 	{
3726 		LOG_ERROR("[%s] wefax.skip_apt: %s",
3727 			XmlRpc::client_id.c_str(),
3728 			e.what());
3729 		*retval = xmlrpc_c::value_string( e.what() );
3730 	}
3731 };
3732 
3733 /// TODO: Refresh the screen with the new value.
3734 struct Wefax_skip_phasing : public xmlrpc_c::method
3735 {
Wefax_skip_phasingWefax_skip_phasing3736 	Wefax_skip_phasing() {
3737 		_signature = "s:n";
3738 		_help = "Skip phasing during Wefax reception"; }
3739 
executeWefax_skip_phasing3740 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3741 	try
3742 	{
3743 		get_wefax()->skip_phasing(true);
3744 		LOG_INFO("[%s] %s",
3745 			XmlRpc::client_id.c_str(),
3746 			"wefax.skip_phasing");
3747 		*retval = xmlrpc_c::value_string( "" );
3748 	}
3749 	catch( const exception & e )
3750 	{
3751 		LOG_ERROR("[%s] wefax.skip_phasing: %s",
3752 			XmlRpc::client_id.c_str(),
3753 			e.what());
3754 		*retval = xmlrpc_c::value_string( e.what() );
3755 	}
3756 };
3757 
3758 // TODO: The image should be reloaded just like cancelling from the GUI.
3759 struct Wefax_set_tx_abort_flag : public xmlrpc_c::method
3760 {
Wefax_set_tx_abort_flagWefax_set_tx_abort_flag3761 	Wefax_set_tx_abort_flag() {
3762 		_signature = "s:n";
3763 		_help = "Cancels Wefax image transmission"; }
3764 
executeWefax_set_tx_abort_flag3765 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3766 	try
3767 	{
3768 		get_wefax()->set_tx_abort_flag();
3769 		LOG_INFO("[%s] %s",
3770 			XmlRpc::client_id.c_str(),
3771 			"wefax.set_tx_abort_flag");
3772 		*retval = xmlrpc_c::value_string( "" );
3773 	}
3774 	catch( const exception & e )
3775 	{
3776 		LOG_ERROR("[%s] wefax.set_tx_abort_flag: %s",
3777 			XmlRpc::client_id.c_str(),
3778 			e.what());
3779 		*retval = xmlrpc_c::value_string( e.what() );
3780 	}
3781 };
3782 
3783 struct Wefax_end_reception : public xmlrpc_c::method
3784 {
Wefax_end_receptionWefax_end_reception3785 	Wefax_end_reception() {
3786 		_signature = "s:n";
3787 		_help = "End Wefax image reception"; }
3788 
executeWefax_end_reception3789 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3790 	try
3791 	{
3792 		get_wefax()->end_reception();
3793 		LOG_INFO("[%s] %s",
3794 			XmlRpc::client_id.c_str(),
3795 			"wefax.end_reception");
3796 		*retval = xmlrpc_c::value_string( "" );
3797 	}
3798 	catch( const exception & e )
3799 	{
3800 		LOG_ERROR("[%s] wefax.end_reception: %s",
3801 			XmlRpc::client_id.c_str(),
3802 			e.what());
3803 		*retval = xmlrpc_c::value_string( e.what() );
3804 	}
3805 };
3806 
3807 struct Wefax_start_manual_reception : public xmlrpc_c::method
3808 {
Wefax_start_manual_receptionWefax_start_manual_reception3809 	Wefax_start_manual_reception() {
3810 		_signature = "s:n";
3811 		_help = "Starts fax image reception in manual mode"; }
3812 
executeWefax_start_manual_reception3813 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3814 	try
3815 	{
3816 		get_wefax()->set_rx_manual_mode(true);
3817 		get_wefax()->skip_apt();
3818 		get_wefax()->skip_phasing(true);
3819 		LOG_INFO("[%s] %s",
3820 			XmlRpc::client_id.c_str(),
3821 			"wefax.start_manual_reception");
3822 		*retval = xmlrpc_c::value_string( "" );
3823 	}
3824 	catch( const exception & e )
3825 	{
3826 		LOG_ERROR("[%s] wefax.start_manual_reception: %s",
3827 			XmlRpc::client_id.c_str(),
3828 			e.what());
3829 		*retval = xmlrpc_c::value_string( e.what() );
3830 	}
3831 };
3832 
3833 struct Wefax_set_adif_log : public xmlrpc_c::method
3834 {
Wefax_set_adif_logWefax_set_adif_log3835 	Wefax_set_adif_log() {
3836 		_signature = "s:b";
3837 		_help = "Set/reset logging to received/transmit images to ADIF log file"; }
3838 
executeWefax_set_adif_log3839 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3840 	try
3841 	{
3842 		progdefaults.WEFAX_AdifLog = params.getBoolean(0);
3843 		LOG_INFO("[%s] %s",
3844 			XmlRpc::client_id.c_str(),
3845 			"wefax.set_adif_log");
3846 		*retval = xmlrpc_c::value_string( "" );
3847 	}
3848 	catch( const exception & e )
3849 	{
3850 		LOG_ERROR("[%s] wefax.set_adif_log: %s",
3851 			XmlRpc::client_id.c_str(),
3852 			e.what());
3853 		*retval = xmlrpc_c::value_string( e.what() );
3854 	}
3855 };
3856 
3857 struct Wefax_set_max_lines : public xmlrpc_c::method
3858 {
Wefax_set_max_linesWefax_set_max_lines3859 	Wefax_set_max_lines() {
3860 		_signature = "s:i";
3861 		_help = "Set maximum lines for fax image reception"; }
3862 
executeWefax_set_max_lines3863 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3864 	try
3865 	{
3866 		progdefaults.WEFAX_MaxRows = params.getInt(0);
3867 		/// This updates the GUI.
3868 		LOG_INFO("[%s] wefax.set_max_lines: %d",
3869 			XmlRpc::client_id.c_str(),
3870 			progdefaults.WEFAX_MaxRows);
3871 		*retval = xmlrpc_c::value_string( "" );
3872 	}
3873 	catch( const exception & e )
3874 	{
3875 		LOG_ERROR("[%s] wefax.set_max_lines: %s",
3876 			XmlRpc::client_id.c_str(),
3877 			e.what());
3878 		*retval = xmlrpc_c::value_string( e.what() );
3879 	}
3880 };
3881 
3882 struct Wefax_get_received_file : public xmlrpc_c::method
3883 {
Wefax_get_received_fileWefax_get_received_file3884 	Wefax_get_received_file() {
3885 		_signature = "s:i";
3886 		_help = "Waits for next received fax file, returns its name with a delay. Empty string if timeout."; }
3887 
executeWefax_get_received_file3888 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3889 	try
3890 	{
3891 		std::string filename = get_wefax()->get_received_file( params.getInt(0));
3892 		LOG_INFO("[%s] wefax.get_received_file: %s",
3893 			XmlRpc::client_id.c_str(),
3894 			filename.c_str());
3895 		*retval = xmlrpc_c::value_string( filename );
3896 	}
3897 	catch( const exception & e )
3898 	{
3899 		LOG_ERROR("[%s] wefax.get_received_file: %s",
3900 			XmlRpc::client_id.c_str(),
3901 			e.what());
3902 		*retval = xmlrpc_c::value_string( e.what() );
3903 	}
3904 };
3905 
3906 struct Wefax_send_file : public xmlrpc_c::method
3907 {
Wefax_send_fileWefax_send_file3908 	Wefax_send_file() {
3909 		_signature = "s:si";
3910 		_help = "Send file. returns an empty string if OK otherwise an error message."; }
3911 
executeWefax_send_file3912 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3913 	try
3914 	{
3915 		std::string status = get_wefax()->send_file( params.getString(0), params.getInt(1) );
3916 		LOG_INFO("[%s] wefax.send_file: %s",
3917 			XmlRpc::client_id.c_str(),
3918 			status.c_str());
3919 		*retval = xmlrpc_c::value_string( status );
3920 	}
3921 	catch( const exception & e )
3922 	{
3923 		LOG_ERROR("[%s] wefax.send_file: %s",
3924 			XmlRpc::client_id.c_str(),
3925 			e.what());
3926 		*retval = xmlrpc_c::value_string( e.what() );
3927 	}
3928 };
3929 
3930 // =============================================================================
3931 
3932 // Returns the current navtex modem pointer.
get_navtex(void)3933 static navtex * get_navtex(void)
3934 {
3935 	if( ( active_modem->get_mode() != MODE_NAVTEX )
3936 	   && ( active_modem->get_mode() != MODE_SITORB ) )
3937 	{
3938 		navtex * ptr = dynamic_cast<navtex *>( active_modem );
3939 		if( ptr == NULL ) throw runtime_error("Inconsistent navtex object");
3940 		return ptr ;
3941 	}
3942 	throw runtime_error("Not in navtex or sitorB mode");
3943 }
3944 
3945 struct Navtex_get_message : public xmlrpc_c::method
3946 {
Navtex_get_messageNavtex_get_message3947 	Navtex_get_message() {
3948 		_signature = "s:i";
3949 		_help = "Returns next Navtex/SitorB message with a max delay in seconds.. Empty string if timeout."; }
3950 
executeNavtex_get_message3951 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3952 	try
3953 	{
3954 		LOG_INFO("[%s] navtex.get_message: %s",
3955 			XmlRpc::client_id.c_str(),
3956 			string( get_navtex()->get_message( params.getInt(0))).c_str());
3957 		*retval = xmlrpc_c::value_string( get_navtex()->get_message( params.getInt(0)) );
3958 	}
3959 	catch( const exception & e )
3960 	{
3961 		LOG_ERROR("[%s] navtex.get_message: %s",
3962 			XmlRpc::client_id.c_str(),
3963 			e.what());
3964 		*retval = xmlrpc_c::value_string( e.what());
3965 	}
3966 };
3967 
3968 struct Navtex_send_message : public xmlrpc_c::method
3969 {
Navtex_send_messageNavtex_send_message3970 	Navtex_send_message() {
3971 		_signature = "s:s";
3972 		_help = "Send a Navtex/SitorB message. Returns an empty string if OK otherwise an error message."; }
3973 
executeNavtex_send_message3974 	void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
3975 	try
3976 	{
3977 		std::string status = get_navtex()->send_message( params.getString(0) );
3978 		LOG_INFO("[%s] navtex.send_message: %s",
3979 			XmlRpc::client_id.c_str(),
3980 			status.c_str());
3981 		*retval = xmlrpc_c::value_string( status );
3982 	}
3983 	catch( const exception & e )
3984 	{
3985 		LOG_ERROR("[%s] navtex.send_message: %s",
3986 			XmlRpc::client_id.c_str(),
3987 			e.what());
3988 		*retval = xmlrpc_c::value_string( e.what() );
3989 	}
3990 };
3991 // =============================================================================
3992 
3993 // End XML-RPC interface
3994 
3995 // method list: ELEM_(class_name, "method_name")
3996 #undef ELEM_
3997 #define METHOD_LIST                                                    \
3998 ELEM_(Fldigi_list, "fldigi.list")                                      \
3999 ELEM_(Fldigi_name, "fldigi.name")                                      \
4000 ELEM_(Fldigi_version_struct, "fldigi.version_struct")                  \
4001 ELEM_(Fldigi_version_string, "fldigi.version")                         \
4002 ELEM_(Fldigi_name_version, "fldigi.name_version")                      \
4003 ELEM_(Fldigi_config_dir, "fldigi.config_dir")                          \
4004 ELEM_(Fldigi_terminate, "fldigi.terminate")                            \
4005 \
4006 ELEM_(Modem_get_name, "modem.get_name")                                \
4007 ELEM_(Modem_get_names, "modem.get_names")                              \
4008 ELEM_(Modem_get_id, "modem.get_id")                                    \
4009 ELEM_(Modem_get_max_id, "modem.get_max_id")                            \
4010 ELEM_(Modem_set_by_name, "modem.set_by_name")                          \
4011 ELEM_(Modem_set_by_id, "modem.set_by_id")                              \
4012 \
4013 ELEM_(Modem_set_carrier, "modem.set_carrier")                          \
4014 ELEM_(Modem_inc_carrier, "modem.inc_carrier")                          \
4015 ELEM_(Modem_get_carrier, "modem.get_carrier")                          \
4016 \
4017 ELEM_(Modem_get_afc_sr, "modem.get_afc_search_range")                  \
4018 ELEM_(Modem_set_afc_sr, "modem.set_afc_search_range")                  \
4019 ELEM_(Modem_inc_afc_sr, "modem.inc_afc_search_range")                  \
4020 \
4021 ELEM_(Modem_get_bw, "modem.get_bandwidth")                             \
4022 ELEM_(Modem_set_bw, "modem.set_bandwidth")                             \
4023 ELEM_(Modem_inc_bw, "modem.inc_bandwidth")                             \
4024 \
4025 ELEM_(Modem_get_quality, "modem.get_quality")                          \
4026 ELEM_(Modem_search_up, "modem.search_up")                              \
4027 ELEM_(Modem_search_down, "modem.search_down")                          \
4028 \
4029 ELEM_(Modem_olivia_set_bandwidth, "modem.olivia.set_bandwidth")        \
4030 ELEM_(Modem_olivia_get_bandwidth, "modem.olivia.get_bandwidth")        \
4031 ELEM_(Modem_olivia_set_tones, "modem.olivia.set_tones")                \
4032 ELEM_(Modem_olivia_get_tones, "modem.olivia.get_tones")                \
4033 \
4034 ELEM_(Main_get_status1, "main.get_status1")                            \
4035 ELEM_(Main_get_status2, "main.get_status2")                            \
4036 \
4037 ELEM_(Main_get_sb, "main.get_sideband")                                \
4038 ELEM_(Main_set_sb, "main.set_sideband")                                \
4039 ELEM_(Main_get_wf_sideband, "main.get_wf_sideband")                    \
4040 ELEM_(Main_set_wf_sideband, "main.set_wf_sideband")                    \
4041 ELEM_(Main_get_freq, "main.get_frequency")                             \
4042 ELEM_(Main_set_freq, "main.set_frequency")                             \
4043 ELEM_(Main_inc_freq, "main.inc_frequency")                             \
4044 \
4045 ELEM_(Main_get_afc, "main.get_afc")                                    \
4046 ELEM_(Main_set_afc, "main.set_afc")                                    \
4047 ELEM_(Main_toggle_afc, "main.toggle_afc")                              \
4048 \
4049 ELEM_(Main_get_sql, "main.get_squelch")                                \
4050 ELEM_(Main_set_sql, "main.set_squelch")                                \
4051 ELEM_(Main_toggle_sql, "main.toggle_squelch")                          \
4052 \
4053 ELEM_(Main_get_sql_level, "main.get_squelch_level")                    \
4054 ELEM_(Main_set_sql_level, "main.set_squelch_level")                    \
4055 ELEM_(Main_inc_sql_level, "main.inc_squelch_level")                    \
4056 \
4057 ELEM_(Main_get_rev, "main.get_reverse")                                \
4058 ELEM_(Main_set_rev, "main.set_reverse")                                \
4059 ELEM_(Main_toggle_rev, "main.toggle_reverse")                          \
4060 \
4061 ELEM_(Main_get_lock, "main.get_lock")                                  \
4062 ELEM_(Main_set_lock, "main.set_lock")                                  \
4063 ELEM_(Main_toggle_lock, "main.toggle_lock")                            \
4064 \
4065 ELEM_(Main_get_txid, "main.get_txid")                                  \
4066 ELEM_(Main_set_txid, "main.set_txid")                                  \
4067 ELEM_(Main_toggle_txid, "main.toggle_txid")                            \
4068 \
4069 ELEM_(Main_get_rsid, "main.get_rsid")                                  \
4070 ELEM_(Main_set_rsid, "main.set_rsid")                                  \
4071 ELEM_(Main_toggle_rsid, "main.toggle_rsid")                            \
4072 \
4073 ELEM_(Main_get_trx_status, "main.get_trx_status")                      \
4074 ELEM_(Main_tx, "main.tx")                                              \
4075 ELEM_(Main_tune, "main.tune")                                          \
4076 ELEM_(Main_rsid, "main.rsid")                                          \
4077 ELEM_(Main_rx, "main.rx")                                              \
4078 ELEM_(Main_rx_tx, "main.rx_tx")                                        \
4079 ELEM_(Main_rx_only, "main.rx_only")                                    \
4080 ELEM_(Main_abort, "main.abort")                                        \
4081 \
4082 ELEM_(Main_get_trx_state, "main.get_trx_state")                        \
4083 ELEM_(Main_get_tx_timing, "main.get_tx_timing")                        \
4084 ELEM_(Main_get_char_rates, "main.get_char_rates")                      \
4085 ELEM_(Main_get_char_timing, "main.get_char_timing")                    \
4086 ELEM_(Main_set_rig_name, "main.set_rig_name")                          \
4087 ELEM_(Main_set_rig_frequency, "main.set_rig_frequency")                \
4088 ELEM_(Main_set_rig_modes, "main.set_rig_modes")                        \
4089 ELEM_(Main_set_rig_mode, "main.set_rig_mode")                          \
4090 ELEM_(Main_get_rig_modes, "main.get_rig_modes")                        \
4091 ELEM_(Main_get_rig_mode, "main.get_rig_mode")                          \
4092 ELEM_(Main_set_rig_bandwidths, "main.set_rig_bandwidths")              \
4093 ELEM_(Main_set_rig_bandwidth, "main.set_rig_bandwidth")                \
4094 ELEM_(Main_get_rig_bandwidth, "main.get_rig_bandwidth")                \
4095 ELEM_(Main_get_rig_bandwidths, "main.get_rig_bandwidths")              \
4096 \
4097 ELEM_(Main_run_macro, "main.run_macro")                                \
4098 ELEM_(Main_get_max_macro_id, "main.get_max_macro_id")                  \
4099 \
4100 ELEM_(Rig_set_name, "rig.set_name")                                    \
4101 ELEM_(Rig_get_name, "rig.get_name")                                    \
4102 ELEM_(Rig_set_frequency, "rig.set_frequency")                          \
4103 ELEM_(Rig_set_smeter, "rig.set_smeter")                                \
4104 ELEM_(Rig_set_pwrmeter, "rig.set_pwrmeter")                            \
4105 ELEM_(Rig_set_modes, "rig.set_modes")                                  \
4106 ELEM_(Rig_set_mode, "rig.set_mode")                                    \
4107 ELEM_(Rig_get_modes, "rig.get_modes")                                  \
4108 ELEM_(Rig_get_mode, "rig.get_mode")                                    \
4109 ELEM_(Rig_set_bandwidths, "rig.set_bandwidths")                        \
4110 ELEM_(Rig_set_bandwidth, "rig.set_bandwidth")                          \
4111 ELEM_(Rig_get_freq, "rig.get_frequency")                               \
4112 ELEM_(Rig_get_bandwidth, "rig.get_bandwidth")                          \
4113 ELEM_(Rig_get_bandwidths, "rig.get_bandwidths")                        \
4114 ELEM_(Rig_get_notch, "rig.get_notch")                                  \
4115 ELEM_(Rig_set_notch, "rig.set_notch")                                  \
4116 \
4117 ELEM_(Log_get_freq, "log.get_frequency")                               \
4118 ELEM_(Log_get_time_on, "log.get_time_on")                              \
4119 ELEM_(Log_get_time_off, "log.get_time_off")                            \
4120 ELEM_(Log_get_call, "log.get_call")                                    \
4121 ELEM_(Log_get_name, "log.get_name")                                    \
4122 ELEM_(Log_get_rst_in, "log.get_rst_in")                                \
4123 ELEM_(Log_get_rst_out, "log.get_rst_out")                              \
4124 ELEM_(Log_set_rst_in, "log.set_rst_in")                                \
4125 ELEM_(Log_set_rst_out, "log.set_rst_out")                              \
4126 ELEM_(Log_get_serial_number, "log.get_serial_number")                  \
4127 ELEM_(Log_set_serial_number, "log.set_serial_number")                  \
4128 ELEM_(Log_get_serial_number_sent, "log.get_serial_number_sent")        \
4129 ELEM_(Log_get_exchange, "log.get_exchange")                            \
4130 ELEM_(Log_set_exchange, "log.set_exchange")                            \
4131 ELEM_(Log_get_state, "log.get_state")                                  \
4132 ELEM_(Log_get_province, "log.get_province")                            \
4133 ELEM_(Log_get_country, "log.get_country")                              \
4134 ELEM_(Log_get_qth, "log.get_qth")                                      \
4135 ELEM_(Log_get_band, "log.get_band")                                    \
4136 ELEM_(Log_get_sb, "log.get_sideband")                                  \
4137 ELEM_(Log_get_notes, "log.get_notes")                                  \
4138 ELEM_(Log_get_locator, "log.get_locator")                              \
4139 ELEM_(Log_get_az, "log.get_az")                                        \
4140 ELEM_(Log_clear, "log.clear")                                          \
4141 ELEM_(Log_set_call, "log.set_call")                                    \
4142 ELEM_(Log_set_name, "log.set_name")                                    \
4143 ELEM_(Log_set_qth, "log.set_qth")                                      \
4144 ELEM_(Log_set_locator, "log.set_locator")                              \
4145 ELEM_(Log_set_rst_in, "log.set_rst_in")                                \
4146 ELEM_(Log_set_rst_out, "log.set_rst_out")                              \
4147 \
4148 ELEM_(Main_flmsg_online, "main.flmsg_online")                          \
4149 ELEM_(Main_flmsg_available, "main.flmsg_available")                    \
4150 ELEM_(Main_flmsg_transfer, "main.flmsg_transfer")                      \
4151 ELEM_(Main_flmsg_squelch, "main.flmsg_squelch")                        \
4152 \
4153 ELEM_(flmsg_online, "flmsg.online")                                    \
4154 ELEM_(flmsg_available, "flmsg.available")                              \
4155 ELEM_(flmsg_transfer, "flmsg.transfer")                                \
4156 ELEM_(flmsg_squelch, "flmsg.squelch")                                  \
4157 ELEM_(flmsg_get_data, "flmsg.get_data")                                \
4158 \
4159 ELEM_(Io_in_use, "io.in_use")                                          \
4160 ELEM_(Io_enable_kiss, "io.enable_kiss")                                \
4161 ELEM_(Io_enable_arq, "io.enable_arq")                                  \
4162 \
4163 ELEM_(Text_get_rx_length, "text.get_rx_length")                        \
4164 ELEM_(Text_get_rx, "text.get_rx")                                      \
4165 ELEM_(Text_clear_rx, "text.clear_rx")                                  \
4166 ELEM_(Text_add_tx, "text.add_tx")                                      \
4167 ELEM_(Text_add_tx_queu, "text.add_tx_queu")                            \
4168 ELEM_(Text_add_tx_bytes, "text.add_tx_bytes")                          \
4169 ELEM_(Text_clear_tx, "text.clear_tx")                                  \
4170 \
4171 ELEM_(RXTX_get_data, "rxtx.get_data")                                  \
4172 ELEM_(RX_get_data, "rx.get_data")                                      \
4173 ELEM_(TX_get_data, "tx.get_data")                                      \
4174 \
4175 ELEM_(Spot_get_auto, "spot.get_auto")                                  \
4176 ELEM_(Spot_set_auto, "spot.set_auto")                                  \
4177 ELEM_(Spot_toggle_auto, "spot.toggle_auto")                            \
4178 ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count")                  \
4179 \
4180 ELEM_(Wefax_state_string, "wefax.state_string")                        \
4181 ELEM_(Wefax_skip_apt, "wefax.skip_apt")                                \
4182 ELEM_(Wefax_skip_phasing, "wefax.skip_phasing")                        \
4183 ELEM_(Wefax_set_tx_abort_flag, "wefax.set_tx_abort_flag")              \
4184 ELEM_(Wefax_end_reception, "wefax.end_reception")                      \
4185 ELEM_(Wefax_start_manual_reception, "wefax.start_manual_reception")    \
4186 ELEM_(Wefax_set_adif_log, "wefax.set_adif_log")                        \
4187 ELEM_(Wefax_set_max_lines, "wefax.set_max_lines")                      \
4188 ELEM_(Wefax_get_received_file, "wefax.get_received_file")              \
4189 ELEM_(Wefax_send_file, "wefax.send_file")                              \
4190 \
4191 ELEM_(Navtex_get_message, "navtex.get_message")                        \
4192 ELEM_(Navtex_send_message, "navtex.send_message")                      \
4193 
4194 struct rm_pred
4195 {
4196 	re_t filter;
4197 	bool allow;
rm_predrm_pred4198 	rm_pred(const char* re, bool allow_)
4199 	: filter(re, REG_EXTENDED | REG_NOSUB), allow(allow_) { }
operator ()rm_pred4200 	bool operator()(const methods_t::value_type& v)
4201 	{
4202 		return filter.match(v.name) ^ allow && !strstr(v.name, "fldigi.");
4203 	}
4204 };
4205 
add_methods(void)4206 void XML_RPC_Server::add_methods(void)
4207 {
4208 	if (methods)
4209 		return;
4210 #undef ELEM_
4211 #define ELEM_(class_, name_) { RpcBuilder<class_>::factory, NULL, name_ },
4212 	rpc_method m[] = { METHOD_LIST };
4213 	methods = new methods_t(m, m + sizeof(m)/sizeof(*m));
4214 
4215 	if (!progdefaults.xmlrpc_deny.empty())
4216 		methods->remove_if(rm_pred(progdefaults.xmlrpc_deny.c_str(), false));
4217 	else if (!progdefaults.xmlrpc_allow.empty())
4218 		methods->remove_if(rm_pred(progdefaults.xmlrpc_allow.c_str(), true));
4219 
4220 	for( methods_t::iterator it = methods->begin(), en = methods->end(); it != en; ++it )
4221 	{
4222 		XmlRpcServerMethod * mth = it->m_fact( it->name );
4223 		it->method = dynamic_cast< xmlrpc_c::method * >( mth );
4224 	}
4225 }
4226