diff options
author | Tom Rondeau <tom@trondeau.com> | 2015-02-26 11:59:03 -0500 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2015-04-02 15:38:56 -0700 |
commit | 450f3471ebe36f80c05ddff242b8771dec891638 (patch) | |
tree | 6cfef8460b4f0514f25996cdb264d1987cdd7679 | |
parent | fe14ba8cadf3a691f459f0997e281b2d99b26b0e (diff) |
controlport: reorg abstraction layers for RPC connections.
ThriftRadioClient has merged with and renamed to RPCConnectionThrift.
5 files changed, 322 insertions, 291 deletions
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/CMakeLists.txt b/gnuradio-runtime/python/gnuradio/ctrlport/CMakeLists.txt index 225f3b004e..f40f253a72 100644 --- a/gnuradio-runtime/python/gnuradio/ctrlport/CMakeLists.txt +++ b/gnuradio-runtime/python/gnuradio/ctrlport/CMakeLists.txt @@ -34,6 +34,7 @@ GR_PYTHON_INSTALL( ${CMAKE_CURRENT_SOURCE_DIR}/GrDataPlotter.py ${CMAKE_CURRENT_SOURCE_DIR}/monitor.py ${CMAKE_CURRENT_SOURCE_DIR}/GNURadioControlPortClient.py + ${CMAKE_CURRENT_SOURCE_DIR}/RPCConnection.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/ COMPONENT "runtime_python" ) @@ -57,7 +58,13 @@ EXECUTE_PROCESS( GR_PYTHON_INSTALL( FILES - ${CMAKE_CURRENT_SOURCE_DIR}/ThriftRadioClient.py + ${CMAKE_CURRENT_SOURCE_DIR}/RPCConnectionThrift.py + DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/ + COMPONENT "runtime_python" +) + +GR_PYTHON_INSTALL( + FILES ${CMAKE_CURRENT_BINARY_DIR}/GNURadio/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/GNURadio/constants.py ${CMAKE_CURRENT_BINARY_DIR}/GNURadio/ControlPort.py diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py b/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py index 8f8895916b..87d2cf5658 100644 --- a/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py +++ b/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py @@ -28,246 +28,7 @@ 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 sys, 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() - - def printProperties(self, props): - 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): - class Knob(): - def __init__(self, key, value=None, ktype=0): - (self.key, self.value, self.ktype) = (key, value, ktype) - - def __repr__(self): - return "({0} = {1})".format(self.key, self.value) - - def __init__(self, host=None, port=None): - from gnuradio.ctrlport.GNURadio import ttypes - self.BaseTypes = ttypes.BaseTypes - self.KnobBase = ttypes.KnobBase - - if port is None: - port = 9090 - super(RPCConnectionThrift, self).__init__(method='thrift', port=port, host=host) - self.newConnection(host, port) - - self.unpack_dict = { - self.BaseTypes.BOOL: lambda k,b: self.Knob(k, b.value.a_bool, self.BaseTypes.BOOL), - self.BaseTypes.BYTE: lambda k,b: self.Knob(k, b.value.a_byte, self.BaseTypes.BYTE), - self.BaseTypes.SHORT: lambda k,b: self.Knob(k, b.value.a_short, self.BaseTypes.SHORT), - self.BaseTypes.INT: lambda k,b: self.Knob(k, b.value.a_int, self.BaseTypes.INT), - self.BaseTypes.LONG: lambda k,b: self.Knob(k, b.value.a_long, self.BaseTypes.LONG), - self.BaseTypes.DOUBLE: lambda k,b: self.Knob(k, b.value.a_double, self.BaseTypes.DOUBLE), - self.BaseTypes.STRING: lambda k,b: self.Knob(k, b.value.a_string, self.BaseTypes.STRING), - self.BaseTypes.COMPLEX: lambda k,b: self.Knob(k, b.value.a_complex, self.BaseTypes.COMPLEX), - self.BaseTypes.F32VECTOR: lambda k,b: self.Knob(k, b.value.a_f32vector, self.BaseTypes.F32VECTOR), - self.BaseTypes.F64VECTOR: lambda k,b: self.Knob(k, b.value.a_f64vector, self.BaseTypes.F64VECTOR), - self.BaseTypes.S64VECTOR: lambda k,b: self.Knob(k, b.value.a_s64vector, self.BaseTypes.S64VECTOR), - self.BaseTypes.S32VECTOR: lambda k,b: self.Knob(k, b.value.a_s32vector, self.BaseTypes.S32VECTOR), - self.BaseTypes.S16VECTOR: lambda k,b: self.Knob(k, b.value.a_s16vector, self.BaseTypes.S16VECTOR), - self.BaseTypes.S8VECTOR: lambda k,b: self.Knob(k, b.value.a_s8vector, self.BaseTypes.S8VECTOR), - self.BaseTypes.C32VECTOR: lambda k,b: self.Knob(k, b.value.a_c32vector, self.BaseTypes.C32VECTOR), - } - - self.pack_dict = { - self.BaseTypes.BOOL: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_bool = k.value)), - self.BaseTypes.BYTE: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_byte = k.value)), - self.BaseTypes.SHORT: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_short = k.value)), - self.BaseTypes.INT: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_int = k.value)), - self.BaseTypes.LONG: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_long = k.value)), - self.BaseTypes.DOUBLE: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_double = k.value)), - self.BaseTypes.STRING: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_string = k.value)), - self.BaseTypes.COMPLEX: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_complex = k.value)), - self.BaseTypes.F32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_f32vector = k.value)), - self.BaseTypes.F64VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_f64vector = k.value)), - self.BaseTypes.S64VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s64vector = k.value)), - self.BaseTypes.S32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s32vector = k.value)), - self.BaseTypes.S16VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s16vector = k.value)), - self.BaseTypes.S8VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s8vector = k.value)), - self.BaseTypes.C32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_c32vector = k.value)), - } - - def unpackKnob(self, key, knob): - f = self.unpack_dict.get(knob.type, None) - if(f): - return f(key, knob) - else: - sys.stderr.write("unpackKnobs: Incorrect Knob type: {0}\n".format(knob.type)) - raise exceptions.ValueError - - def packKnob(self, knob): - f = self.pack_dict.get(knob.ktype, None) - if(f): - return f(knob) - else: - sys.stderr.write("packKnobs: Incorrect Knob type: {0}\n".format(knob.type)) - raise exceptions.ValueError - - def newConnection(self, host=None, port=None): - from gnuradio.ctrlport.ThriftRadioClient import ThriftRadioClient - import thrift - try: - self.thriftclient = ThriftRadioClient(self.getHost(), self.getPort()) - except thrift.transport.TTransport.TTransportException: - sys.stderr.write("Could not connect to ControlPort endpoint at {0}:{1}.\n\n".format(host, port)) - sys.exit(1) - - def properties(self, *args): - knobprops = self.thriftclient.radio.properties(*args) - for key, knobprop in knobprops.iteritems(): - #print("key:", key, "value:", knobprop, "type:", knobprop.type) - knobprops[key].min = self.unpackKnob(key, knobprop.min) - knobprops[key].max = self.unpackKnob(key, knobprop.max) - knobprops[key].defaultvalue = self.unpackKnob(key, knobprop.defaultvalue) - return knobprops - - def getKnobs(self, *args): - result = {} - for key, knob in self.thriftclient.radio.getKnobs(*args).iteritems(): - #print("key:", key, "value:", knob, "type:", knob.type) - result[key] = self.unpackKnob(key, knob) - return result - - def getKnobsRaw(self, *args): - result = {} - for key, knob in self.thriftclient.radio.getKnobs(*args).iteritems(): - #print("key:", key, "value:", knob, "type:", knob.type) - result[key] = knob - return result - - def getRe(self,*args): - result = {} - for key, knob in self.thriftclient.radio.getRe(*args).iteritems(): - result[key] = self.unpackKnob(key, knob) - return result - - def setKnobs(self, *args): - if(type(*args) == dict): - a = dict(*args) - result = {} - for key, knob in a.iteritems(): - result[key] = self.packKnob(knob) - self.thriftclient.radio.setKnobs(result) - elif(type(*args) == list or type(*args) == tuple): - a = list(*args) - result = {} - for k in a: - result[k.key] = self.packKnob(k) - self.thriftclient.radio.setKnobs(result) - else: - sys.stderr.write("setKnobs: Invalid type; must be dict, list, or tuple\n") - - def shutdown(self): - self.thriftclient.radio.shutdown() - - def printProperties(self, props): - info = "" - info += "Item:\t\t{0}\n".format(props.description) - info += "units:\t\t{0}\n".format(props.units) - info += "min:\t\t{0}\n".format(props.min.value) - info += "max:\t\t{0}\n".format(props.max.value) - info += "default:\t\t{0}\n".format(props.defaultvalue.value) - info += "Type Code:\t0x{0:x}\n".format(props.type) - info += "Disp Code:\t0x{0:x}\n".format(props.display) - return info +import exceptions """ GNURadioControlPortClient is the main class for creating a GNU Radio @@ -351,17 +112,21 @@ class GNURadioControlPortClient(): self.client = None + from gnuradio.ctrlport.RPCConnection import RPCMethods if RPCMethods.has_key(rpcmethod): + from gnuradio.ctrlport.RPCConnectionThrift import RPCConnectionThrift if rpcmethod == 'thrift': -# print("making RPCConnectionThrift") + #print("making RPCConnectionThrift") self.client = RPCConnectionThrift(host, port) -# print("made %s" % self.client) + #print("made %s" % self.client) -# print("making callback call") - if not callback is None: callback(self.client) + #print("making callback call") + if not callback is None: + callback(self.client) -# print("making blockingcallback call") - if not blockingcallback is None: blockingcallback() + #print("making blockingcallback call") + if not blockingcallback is None: + blockingcallback() else: print("Unsupported RPC method: ", rpcmethod) raise exceptions.ValueError() diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnection.py b/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnection.py new file mode 100644 index 0000000000..e14cc0cea7 --- /dev/null +++ b/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnection.py @@ -0,0 +1,115 @@ +# +# 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. +# + +import exceptions + +""" +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' + } + + +""" +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() + + def printProperties(self, props): + raise exceptions.NotImplementedError() diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py b/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py new file mode 100644 index 0000000000..f086b85834 --- /dev/null +++ b/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# +# 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from thrift import Thrift +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol +from gnuradio.ctrlport.GNURadio import ControlPort +from gnuradio.ctrlport import RPCConnection +import sys + +class ThriftRadioClient: + def __init__(self, host, port): + self.tsocket = TSocket.TSocket(host, port) + self.transport = TTransport.TBufferedTransport(self.tsocket) + self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport) + + self.radio = ControlPort.Client(self.protocol) + self.transport.open() + + def __del__(self): + self.transport.close() + + def getRadio(self, host, port): + return self.radio + +""" +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.RPCConnection): + class Knob(): + def __init__(self, key, value=None, ktype=0): + (self.key, self.value, self.ktype) = (key, value, ktype) + + def __repr__(self): + return "({0} = {1})".format(self.key, self.value) + + def __init__(self, host=None, port=None): + from gnuradio.ctrlport.GNURadio import ttypes + self.BaseTypes = ttypes.BaseTypes + self.KnobBase = ttypes.KnobBase + + if port is None: + port = 9090 + super(RPCConnectionThrift, self).__init__(method='thrift', port=port, host=host) + self.newConnection(host, port) + + self.unpack_dict = { + self.BaseTypes.BOOL: lambda k,b: self.Knob(k, b.value.a_bool, self.BaseTypes.BOOL), + self.BaseTypes.BYTE: lambda k,b: self.Knob(k, b.value.a_byte, self.BaseTypes.BYTE), + self.BaseTypes.SHORT: lambda k,b: self.Knob(k, b.value.a_short, self.BaseTypes.SHORT), + self.BaseTypes.INT: lambda k,b: self.Knob(k, b.value.a_int, self.BaseTypes.INT), + self.BaseTypes.LONG: lambda k,b: self.Knob(k, b.value.a_long, self.BaseTypes.LONG), + self.BaseTypes.DOUBLE: lambda k,b: self.Knob(k, b.value.a_double, self.BaseTypes.DOUBLE), + self.BaseTypes.STRING: lambda k,b: self.Knob(k, b.value.a_string, self.BaseTypes.STRING), + self.BaseTypes.COMPLEX: lambda k,b: self.Knob(k, b.value.a_complex, self.BaseTypes.COMPLEX), + self.BaseTypes.F32VECTOR: lambda k,b: self.Knob(k, b.value.a_f32vector, self.BaseTypes.F32VECTOR), + self.BaseTypes.F64VECTOR: lambda k,b: self.Knob(k, b.value.a_f64vector, self.BaseTypes.F64VECTOR), + self.BaseTypes.S64VECTOR: lambda k,b: self.Knob(k, b.value.a_s64vector, self.BaseTypes.S64VECTOR), + self.BaseTypes.S32VECTOR: lambda k,b: self.Knob(k, b.value.a_s32vector, self.BaseTypes.S32VECTOR), + self.BaseTypes.S16VECTOR: lambda k,b: self.Knob(k, b.value.a_s16vector, self.BaseTypes.S16VECTOR), + self.BaseTypes.S8VECTOR: lambda k,b: self.Knob(k, b.value.a_s8vector, self.BaseTypes.S8VECTOR), + self.BaseTypes.C32VECTOR: lambda k,b: self.Knob(k, b.value.a_c32vector, self.BaseTypes.C32VECTOR), + } + + self.pack_dict = { + self.BaseTypes.BOOL: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_bool = k.value)), + self.BaseTypes.BYTE: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_byte = k.value)), + self.BaseTypes.SHORT: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_short = k.value)), + self.BaseTypes.INT: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_int = k.value)), + self.BaseTypes.LONG: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_long = k.value)), + self.BaseTypes.DOUBLE: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_double = k.value)), + self.BaseTypes.STRING: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_string = k.value)), + self.BaseTypes.COMPLEX: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_complex = k.value)), + self.BaseTypes.F32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_f32vector = k.value)), + self.BaseTypes.F64VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_f64vector = k.value)), + self.BaseTypes.S64VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s64vector = k.value)), + self.BaseTypes.S32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s32vector = k.value)), + self.BaseTypes.S16VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s16vector = k.value)), + self.BaseTypes.S8VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_s8vector = k.value)), + self.BaseTypes.C32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_c32vector = k.value)), + } + + def unpackKnob(self, key, knob): + f = self.unpack_dict.get(knob.type, None) + if(f): + return f(key, knob) + else: + sys.stderr.write("unpackKnobs: Incorrect Knob type: {0}\n".format(knob.type)) + raise exceptions.ValueError + + def packKnob(self, knob): + f = self.pack_dict.get(knob.ktype, None) + if(f): + return f(knob) + else: + sys.stderr.write("packKnobs: Incorrect Knob type: {0}\n".format(knob.type)) + raise exceptions.ValueError + + def newConnection(self, host=None, port=None): + try: + self.thriftclient = ThriftRadioClient(self.getHost(), self.getPort()) + except TTransport.TTransportException: + sys.stderr.write("Could not connect to ControlPort endpoint at {0}:{1}.\n\n".format(host, port)) + sys.exit(1) + + def properties(self, *args): + knobprops = self.thriftclient.radio.properties(*args) + for key, knobprop in knobprops.iteritems(): + #print("key:", key, "value:", knobprop, "type:", knobprop.type) + knobprops[key].min = self.unpackKnob(key, knobprop.min) + knobprops[key].max = self.unpackKnob(key, knobprop.max) + knobprops[key].defaultvalue = self.unpackKnob(key, knobprop.defaultvalue) + return knobprops + + def getKnobs(self, *args): + result = {} + for key, knob in self.thriftclient.radio.getKnobs(*args).iteritems(): + #print("key:", key, "value:", knob, "type:", knob.type) + result[key] = self.unpackKnob(key, knob) + return result + + def getKnobsRaw(self, *args): + result = {} + for key, knob in self.thriftclient.radio.getKnobs(*args).iteritems(): + #print("key:", key, "value:", knob, "type:", knob.type) + result[key] = knob + return result + + def getRe(self,*args): + result = {} + for key, knob in self.thriftclient.radio.getRe(*args).iteritems(): + result[key] = self.unpackKnob(key, knob) + return result + + def setKnobs(self, *args): + if(type(*args) == dict): + a = dict(*args) + result = {} + for key, knob in a.iteritems(): + result[key] = self.packKnob(knob) + self.thriftclient.radio.setKnobs(result) + elif(type(*args) == list or type(*args) == tuple): + a = list(*args) + result = {} + for k in a: + result[k.key] = self.packKnob(k) + self.thriftclient.radio.setKnobs(result) + else: + sys.stderr.write("setKnobs: Invalid type; must be dict, list, or tuple\n") + + def shutdown(self): + self.thriftclient.radio.shutdown() + + def printProperties(self, props): + info = "" + info += "Item:\t\t{0}\n".format(props.description) + info += "units:\t\t{0}\n".format(props.units) + info += "min:\t\t{0}\n".format(props.min.value) + info += "max:\t\t{0}\n".format(props.max.value) + info += "default:\t\t{0}\n".format(props.defaultvalue.value) + info += "Type Code:\t0x{0:x}\n".format(props.type) + info += "Disp Code:\t0x{0:x}\n".format(props.display) + return info diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/ThriftRadioClient.py b/gnuradio-runtime/python/gnuradio/ctrlport/ThriftRadioClient.py deleted file mode 100644 index eca49dca76..0000000000 --- a/gnuradio-runtime/python/gnuradio/ctrlport/ThriftRadioClient.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -# -# 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -from thrift import Thrift -from thrift.transport import TSocket -from thrift.transport import TTransport -from thrift.protocol import TBinaryProtocol -#from ControlPort.GNURadio import ControlPort -from gnuradio.ctrlport.GNURadio import ControlPort -import sys - -class ThriftRadioClient: - def __init__(self, host, port): - self.tsocket = TSocket.TSocket(host, port) - self.transport = TTransport.TBufferedTransport(self.tsocket) - self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport) - - self.radio = ControlPort.Client(self.protocol) - self.transport.open() - - def __del__(self): - self.transport.close() - - def getRadio(self, host, port): - return self.radio |