summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py')
-rw-r--r--gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py276
1 files changed, 276 insertions, 0 deletions
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py b/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py
new file mode 100644
index 0000000000..3cf5186594
--- /dev/null
+++ b/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py
@@ -0,0 +1,276 @@
+#
+# Copyright 2015 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+Python Client classes for interfacing with the GNU Radio ControlPort interface
+and for accessing Performance Counters.
+
+While ControlPort and these client classes are designed to support multiple
+Remote Procedure Call (RPC) transports, the Apache Thrift middle-ware RPC
+is currently the only supported transport.
+
+"""
+
+"""
+RPCMethods is a dictionary listing RPC transports currently supported
+by this client.
+
+Args:
+ function: the function whose parameter list will be examined
+ excluded_args: function arguments that are NOT to be added to the dictionary (sequence of strings)
+ options: result of command argument parsing (optparse.Values)
+"""
+
+RPCMethods = {'thrift': 'Apache Thrift',
+ #'ice': 'Zeroc ICE'
+ }
+
+import exceptions
+
+"""
+Base class for RPC transport clients
+
+Methods that all RPC clients should implement include:
+
+ def newConnection(host,port): Method for re-establishing a new client
+ connection to a different host / port
+
+ def properties([]): Given a list of ControlPort property names,
+ or an empty list to specify all currently registered properties,
+ this method returns a dictionary of metadata describing the
+ the specified properties. The dictionary key contains the name
+ of each returned properties.
+
+ def getKnobs([]): Given a list of ControlPort property names,
+ or an empty list to specify all currently registered properties,
+ this method returns a dictionary of the current value of
+ the specified properties.
+
+ def getRe([]): Given a list of regular expression strings,
+ this method returns a dictionary of the current value of
+ the all properties with names that match the specified
+ expressions.
+
+ def setKnobs({}): Given a dictionary of ControlPort property
+ key / value pairs, this method requests that ControlPort
+ attempt to set the specified named properties to the
+ value given. Success in setting each property to the
+ value specified requires that the property be registered
+ as a 'setable' ControlPort property, that the client have the
+ requisite privilege level to set the property, and
+ the underlying Block's implementation in handling
+ the set request.
+
+Args:
+ method: name of the RPC transport
+ port: port number of the connection
+ host: hostname of the connection
+"""
+
+class RPCConnection(object):
+ def __init__(self, method, port, host=None):
+ (self.method, self.port) = (method, port)
+ if host is None: self.host = '127.0.0.1'
+ else: self.host = host
+
+ def __str__(self):
+ return "%s connection on %s:%s"%(self.getName(), self.getHost(), self.getPort())
+
+ def getName(self):
+ return RPCMethods[self.method]
+
+ def getHost(self):
+ return self.host
+
+ def getPort(self):
+ return self.port
+
+ def newConnection(self, host=None, port=None):
+ raise exceptions.NotImplementedError()
+
+ def properties(self, *args):
+ raise exceptions.NotImplementedError()
+
+ def getKnobs(self, *args):
+ raise exceptions.NotImplementedError()
+
+ def getRe(self,*args):
+ raise exceptions.NotImplementedError()
+
+ def setKnobs(self,*args):
+ raise exceptions.NotImplementedError()
+
+ def shutdown(self):
+ raise exceptions.NotImplementedError()
+
+"""
+RPC Client interface for the Apache Thrift middle-ware RPC transport.
+
+Args:
+ port: port number of the connection
+ host: hostname of the connection
+"""
+
+class RPCConnectionThrift(RPCConnection):
+ def __init__(self, host=None, port=None):
+ if port is None: port = 9090
+ super(RPCConnectionThrift, self).__init__(method='thrift', port=port, host=host)
+ self.newConnection(host, port)
+
+ def newConnection(self, host=None, port=None):
+ from gnuradio.ctrlport.ThriftRadioClient import ThriftRadioClient
+ self.thriftclient = ThriftRadioClient(self.getHost(), self.getPort())
+
+ def properties(self, *args):
+ return self.thriftclient.radio.properties(*args)
+
+ def getKnobs(self, *args):
+ class Knob():
+ def __init__(self, key, value):
+ (self.key, self.value) = (key, value)
+
+ result = {}
+ for key, knob in self.thriftclient.radio.getKnobs(*args).iteritems():
+ if knob.type == 0: result[key] = Knob(key, knob.value.a_bool)
+ elif knob.type == 1: result[key] = Knob(key, knob.value.a_byte)
+ elif knob.type == 2: result[key] = Knob(key, knob.value.a_short)
+ elif knob.type == 3: result[key] = Knob(key, knob.value.a_int)
+ elif knob.type == 4: result[key] = Knob(key, knob.value.a_long)
+ elif knob.type == 5: result[key] = Knob(key, knob.value.a_double)
+ elif knob.type == 6: result[key] = Knob(key, knob.value.a_string)
+ elif knob.type == 7: result[key] = Knob(key, knob.value.a_complex)
+ elif knob.type == 8: result[key] = Knob(key, knob.value.a_f32vector)
+ elif knob.type == 9: result[key] = Knob(key, knob.value.a_f64vector)
+ elif knob.type == 10: result[key] = Knob(key, knob.value.a_s64vector)
+ elif knob.type == 11: result[key] = Knob(key, knob.value.a_s32vector)
+ elif knob.type == 12: result[key] = Knob(key, knob.value.a_s16vector)
+ elif knob.type == 13: result[key] = Knob(key, knob.value.a_s8vector)
+ elif knob.type == 14: result[key] = Knob(key, knob.value.a_s32vector)
+ elif knob.type == 15: result[key] = Knob(key, knob.value.byte)
+ else:
+ raise exceptions.ValueError
+
+ return result
+
+ def getRe(self,*args):
+ return self.thriftclient.radio.getRe(*args)
+
+ def setKnobs(self,*args):
+ self.thriftclient.radio.setKnobs(*args)
+
+ def shutdown(self):
+ self.thriftclient.radio.shutdown()
+
+"""
+GNURadioControlPortClient is the main class for creating a GNU Radio
+ControlPort client application for all transports.
+
+Two constructors are provided for creating a connection to ControlPort.
+
+"""
+
+class GNURadioControlPortClient():
+ """
+ Constructor for creating a ControlPort connection to a specified host / port
+
+ Args:
+ host: hostname of the connection. Specifying None (default) will
+ select the loopback interface.
+
+ port: port number to use for the connection. Specifying None (default)
+ will select the specified RPC transport's default port number, if
+ the transport has a default.
+
+ rpcmethod: This string specifies the RPC transport to use for the
+ client connection. The default implementation currently uses
+ the Apache Thrift RPC transport. The value specified here must
+ be one of the transport keys listed in the RPCMethods dictionary
+ above
+
+ callback: This optional parameter is a callback function that will be passed
+ a reference to the Client implementation for the RPC transport specified
+ by rpcmethod. The callback will be executed after the client has been
+ constructed, but before __init__ returns.
+
+ blockingcallback: This optional parameter is a callback function with
+ no parameters that will be executed after callback() is executed,
+ but before __init__ returns. It is useful if your application
+ requires that a blocking function be called to start the application,
+ such as QtGui.QApplication.exec_
+
+ """
+
+ def __init__(self, host = None, port = None, rpcmethod = 'thrift', callback = None, blockingcallback = None):
+ __init__([host, port], rpcmethod, callback, blockingcallback)
+
+ """
+ Constructor for creating a ControlPort from a tuple of command line arguments (i.e. sys.argv)
+
+ Args:
+ argv: List of command line arguments. Future implementations may parse the argument list
+ for OptionParser style key / value pairs, however the current implementation
+ simply takes argv[1] and argv[2] as the connection hostname and port, respectively.
+
+ Example Usage:
+
+ In the following QT client example, the ControlPort host and port are specified to
+ the Client application as the first two command line arguments. The MAINWindow class is
+ of the type QtGui.QMainWindow, and is the main window for the QT application. MyApp
+ is a simple helper class for starting the application.
+
+ class MAINWindow(QtGui.QMainWindow):
+ ... QT Application implementation ...
+
+ class MyApp(object):
+ def __init__(self, args):
+ from GNURadioControlPortClient import GNURadioControlPortClient
+ GNURadioControlPortClient(args, 'thrift', self.run, QtGui.QApplication(sys.argv).exec_)
+
+ def run(self, client):
+ MAINWindow(client).show()
+
+ MyApp(sys.argv)
+
+
+ """
+
+ def __init__(self, argv = [], rpcmethod = 'thrift', callback = None, blockingcallback = None):
+ if len(argv) > 1: host = argv[1]
+ else: host = None
+
+ if len(argv) > 2: port = argv[2]
+ else: port = None
+
+ self.client = None
+
+ if RPCMethods.has_key(rpcmethod):
+ if rpcmethod == 'thrift':
+# print("making RPCConnectionThrift")
+ self.client = RPCConnectionThrift(host, port)
+# print("made %s" % self.client)
+
+# print("making callback call")
+ if not callback is None: callback(self.client)
+
+# print("making blockingcallback call")
+ if not blockingcallback is None: blockingcallback()
+ else:
+ print("Unsupported RPC method: ", rpcmethod)
+ raise exceptions.ValueError()