summaryrefslogtreecommitdiff
path: root/gnuradio-runtime
diff options
context:
space:
mode:
authorBastian Bloessl <mail@bastibl.net>2019-06-18 09:24:35 +0200
committerMartin Braun <martin.braun@ettus.com>2019-06-19 13:00:00 -0700
commitcb044a4c4b2c6657876f996617a24a44d1ac3b5d (patch)
treedd6815d0eb2fc9173f726dc602e994a01e94e418 /gnuradio-runtime
parent3750f748501ec83d60c489dfa700522f3be21b00 (diff)
ctrport-monitor: fix error handling
Diffstat (limited to 'gnuradio-runtime')
-rw-r--r--gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py55
-rw-r--r--gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py18
-rw-r--r--gnuradio-runtime/python/gnuradio/ctrlport/gr-ctrlport-monitor121
-rw-r--r--gnuradio-runtime/python/gnuradio/ctrlport/monitor.py16
4 files changed, 87 insertions, 123 deletions
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py b/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py
index bee5cd15ed..46ef3cbbae 100644
--- a/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py
+++ b/gnuradio-runtime/python/gnuradio/ctrlport/GNURadioControlPortClient.py
@@ -30,14 +30,12 @@ is currently the only supported transport.
from __future__ import print_function
from __future__ import unicode_literals
-from argparse import ArgumentParser
-
from gnuradio.ctrlport.RPCConnection import RPCMethods
try:
from gnuradio.ctrlport.RPCConnectionThrift import RPCConnectionThrift
from thrift.transport.TTransport import TTransportException
except ImportError:
- # Thrift support not provided we should remove it from RPCMethods
+ print("ControlPort requires Thrift, but it was not found!")
pass
@@ -45,8 +43,6 @@ except ImportError:
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(object):
@@ -79,61 +75,16 @@ class GNURadioControlPortClient(object):
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):
-
- parser = ArgumentParser(description="GNU Radio Control Port Monitor")
- parser.add_argument("host", nargs="?", default="localhost", help="host name or IP")
- parser.add_argument("port", help="port")
- args = parser.parse_args()
-
+ def __init__(self, host=None, port=None, rpcmethod='thrift', callback=None, blockingcallback=None):
self.client = None
if rpcmethod in RPCMethods:
if rpcmethod == 'thrift':
- #print("making RPCConnectionThrift")
- self.client = RPCConnectionThrift(args.host, args.port)
- #print("made %s" % self.client)
+ self.client = RPCConnectionThrift(host, port)
- #print("making callback call")
if not callback is None:
callback(self.client)
- #print("making blockingcallback call")
if not blockingcallback is None:
blockingcallback()
else:
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py b/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py
index 3bc4c87308..25618e892c 100644
--- a/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py
+++ b/gnuradio-runtime/python/gnuradio/ctrlport/RPCConnectionThrift.py
@@ -39,6 +39,8 @@ class ThriftRadioClient(object):
self.radio = ControlPort.Client(self.protocol)
self.transport.open()
+ self.host = host
+ self.port = port
def __del__(self):
try:
@@ -75,7 +77,7 @@ class RPCConnectionThrift(RPCConnection.RPCConnection):
# config file, if one is set. Defaults to 9090 otherwise.
if port is None:
p = gr.prefs()
- thrift_config_file = p.get_string("ControlPort", "config", "");
+ thrift_config_file = p.get_string("ControlPort", "config", "")
if(len(thrift_config_file) > 0):
p.add_config_file(thrift_config_file)
port = p.get_long("thrift", "port", 9090)
@@ -123,6 +125,11 @@ class RPCConnectionThrift(RPCConnection.RPCConnection):
self.BaseTypes.C32VECTOR: lambda k: ttypes.Knob(type=k.ktype, value=ttypes.KnobBase(a_c32vector = k.value)),
}
+ def __str__(self):
+ return "Apache Thrift connection to {0}:{1}".format(
+ self.thriftclient.host,
+ self.thriftclient.port)
+
def unpackKnob(self, key, knob):
f = self.unpack_dict.get(knob.type, None)
if(f):
@@ -140,11 +147,7 @@ class RPCConnectionThrift(RPCConnection.RPCConnection):
raise exceptions.ValueError
def newConnection(self, host=None, port=None):
- try:
- self.thriftclient = ThriftRadioClient(host, int(port))
- except:
- return None
- return self
+ self.thriftclient = ThriftRadioClient(host, int(port))
def properties(self, *args):
knobprops = self.thriftclient.radio.properties(*args)
@@ -215,8 +218,7 @@ class RPCConnectionThrift(RPCConnection.RPCConnection):
'''
self.thriftclient.radio.postMessage(pmt.serialize_str(pmt.intern(blk_alias)),
pmt.serialize_str(pmt.intern(port)),
- pmt.serialize_str(msg));
-
+ pmt.serialize_str(msg))
def printProperties(self, props):
info = ""
info += "Item:\t\t{0}\n".format(props.description)
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/gr-ctrlport-monitor b/gnuradio-runtime/python/gnuradio/ctrlport/gr-ctrlport-monitor
index dfaba52c0c..b1f4f321ec 100644
--- a/gnuradio-runtime/python/gnuradio/ctrlport/gr-ctrlport-monitor
+++ b/gnuradio-runtime/python/gnuradio/ctrlport/gr-ctrlport-monitor
@@ -21,27 +21,30 @@
#
from PyQt5 import QtCore, Qt
+from argparse import ArgumentParser
+
import os, sys, time, struct
from gnuradio import gr, ctrlport
from gnuradio.ctrlport.GrDataPlotter import *
+from gnuradio.ctrlport.GNURadioControlPortClient import GNURadioControlPortClient
class RateDialog(Qt.QDialog):
def __init__(self, delay, parent=None):
super(RateDialog, self).__init__(parent)
self.gridLayout = Qt.QGridLayout(self)
- self.setWindowTitle("Update Delay (ms)");
- self.delay = Qt.QLineEdit(self);
- self.delay.setText(str(delay));
+ self.setWindowTitle("Update Delay (ms)")
+ self.delay = Qt.QLineEdit(self)
+ self.delay.setText(str(delay))
self.buttonBox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel)
- self.gridLayout.addWidget(self.delay);
- self.gridLayout.addWidget(self.buttonBox);
+ self.gridLayout.addWidget(self.delay)
+ self.gridLayout.addWidget(self.buttonBox)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
def accept(self):
- self.done(1);
+ self.done(1)
def reject(self):
- self.done(0);
+ self.done(0)
class MAINWindow(Qt.QMainWindow):
def minimumSizeHint(self):
@@ -50,8 +53,7 @@ class MAINWindow(Qt.QMainWindow):
def __init__(self, radioclient):
super(MAINWindow, self).__init__()
- self.radioclient = radioclient
- self.updateRate = 1000;
+ self.updateRate = 1000
self.conns = []
self.plots = []
self.knobprops = []
@@ -85,16 +87,17 @@ class MAINWindow(Qt.QMainWindow):
os.environ['GR_CONF_CONTROLPORT_ON'] = 'False'
def setUpdateRate(self,nur):
- self.updateRate = int(nur);
+ self.updateRate = int(nur)
for c in self.conns:
- c.updateRate = self.updateRate;
- c.timer.setInterval(self.updateRate);
+ c.updateRate = self.updateRate
+ c.timer.setInterval(self.updateRate)
- def newCon(self, csomeBool):
- child = MForm(self.radioclient, len(self.conns), parent = self, dialogprompt = not csomeBool)
+ def newCon(self, radioclient=None):
+ child = MForm(radioclient, len(self.conns), parent = self)
if(child.radioclient is not None):
child.setWindowTitle(str(child.radioclient))
self.mdiArea.addSubWindow(child)
+ child.show()
self.mdiArea.currentSubWindow().showMaximized()
self.conns.append(child)
self.plots.append([])
@@ -316,7 +319,7 @@ class MAINWindow(Qt.QMainWindow):
def createActions(self):
self.newConAct = Qt.QAction("&New Connection",
self, shortcut=Qt.QKeySequence.New,
- statusTip="Create a new file", triggered=self.newCon)
+ statusTip="Create a new file", triggered=lambda x: self.newCon(None))
self.exitAct = Qt.QAction("E&xit", self, shortcut="Ctrl+Q",
statusTip="Exit the application",
@@ -334,13 +337,13 @@ class MAINWindow(Qt.QMainWindow):
statusTip="Change Update Rate",
triggered=self.updateRateShow)
- qks = Qt.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T);
+ qks = Qt.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T)
self.tileAct = Qt.QAction("&Tile", self,
statusTip="Tile the windows",
triggered=self.mdiArea.tileSubWindows,
shortcut=qks)
- qks = Qt.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_C);
+ qks = Qt.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_C)
self.cascadeAct = Qt.QAction("&Cascade", self,
statusTip="Cascade the windows", shortcut=qks,
triggered=self.mdiArea.cascadeSubWindows)
@@ -384,13 +387,13 @@ class MAINWindow(Qt.QMainWindow):
self.helpMenu.addAction(self.aboutQtAct)
def updateRateShow(self):
- askrate = RateDialog(self.updateRate, self);
+ askrate = RateDialog(self.updateRate, self)
if askrate.exec_():
- ur = float(str(askrate.delay.text()));
- self.setUpdateRate(ur);
- return;
+ ur = float(str(askrate.delay.text()))
+ self.setUpdateRate(ur)
+ return
else:
- return;
+ return
def createToolBars(self):
self.fileToolBar = self.addToolBar("File")
@@ -451,33 +454,33 @@ class ConInfoDialog(Qt.QDialog):
self.gridLayout = Qt.QGridLayout(self)
- self.host = Qt.QLineEdit(self);
- self.port = Qt.QLineEdit(self);
- self.host.setText("localhost");
- self.port.setText("43243");
+ self.host = Qt.QLineEdit(self)
+ self.port = Qt.QLineEdit(self)
+ self.host.setText("localhost")
+ self.port.setText("43243")
self.buttonBox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel)
- self.gridLayout.addWidget(self.host);
- self.gridLayout.addWidget(self.port);
- self.gridLayout.addWidget(self.buttonBox);
+ self.gridLayout.addWidget(self.host)
+ self.gridLayout.addWidget(self.port)
+ self.gridLayout.addWidget(self.buttonBox)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
def accept(self):
- self.done(1);
+ self.done(1)
def reject(self):
- self.done(0);
+ self.done(0)
class UpdaterWindow(Qt.QDialog):
def __init__(self, key, radio, parent):
Qt.QDialog.__init__(self, parent)
- self.key = key;
+ self.key = key
self.radio = radio
self.resize(300,200)
@@ -594,16 +597,15 @@ class UpdaterWindow(Qt.QDialog):
class MForm(Qt.QWidget):
def update(self):
- # TODO: revisit this try-except block, figure out what it's doing, and if we need to keep it. at very lease makes debugging dificult
try:
- st = time.time();
+ st = time.time()
knobs = self.radioclient.getKnobs([])
- ft = time.time();
- latency = ft-st;
+ ft = time.time()
+ latency = ft-st
self.parent.statusBar().showMessage("Current GNU Radio Control Port Query Latency: %f ms"%(latency*1000))
except Exception as e:
- sys.stderr.write("ctrlport-monitor: radio.get threw exception ({0}).\n".format(e))
+ sys.stderr.write("ctrlport-monitor: lost connection ({0}).\n".format(e))
if(type(self.parent) is MAINWindow):
# Find window of connection
remove = []
@@ -614,12 +616,12 @@ class MForm(Qt.QWidget):
# Find any subplot windows of connection
for p in self.parent.mdiArea.subWindowList():
for plot in self.parent.plots[self.uid]:
- if plot.qwidget() == p.widget():
+ if plot == p.widget():
remove.append(p)
# Clean up local references to these
- self.parent.conns.remove(self.parent.conns[self.uid])
- self.parent.plots.remove(self.parent.plots[self.uid])
+ self.parent.conns[self.uid] = []
+ self.parent.plots[self.uid] = []
# Remove subwindows for connection and plots
for r in remove:
@@ -640,20 +642,24 @@ class MForm(Qt.QWidget):
self.parent.update(knobs, self.uid)
- def __init__(self, radioclient, uid=0, updateRate=2000, parent=None, dialogprompt = False):
+ def __init__(self, radioclient, uid=0, updateRate=2000, parent=None):
super(MForm, self).__init__()
- self.radioclient = radioclient
- if(dialogprompt or radioclient.getHost() is None or radioclient.getPort() is None):
- askinfo = ConInfoDialog(self);
+
+ self.radioclient = None
+ if radioclient is None:
+ askinfo = ConInfoDialog(self)
if askinfo.exec_():
- host = str(askinfo.host.text());
- port = str(askinfo.port.text());
- self.radioclient = self.radioclient.newConnection(host, port)
- if self.radioclient is None:
- print("Cannot connect to %s:%s" % (host, port))
- else:
+ host = str(askinfo.host.text())
+ port = str(askinfo.port.text())
+
+ try:
+ self.radioclient = GNURadioControlPortClient(host, port, 'thrift').client
print("Connected to %s:%s" % (host, port))
+ except:
+ print("Cannot connect to %s:%s" % (host, port))
+ else:
+ self.radioclient = radioclient
if self.radioclient is None:
return
@@ -684,7 +690,7 @@ class MForm(Qt.QWidget):
# set up timer
self.timer.timeout.connect(self.update)
- self.updateRate = updateRate;
+ self.updateRate = updateRate
self.timer.start(self.updateRate)
# set up context menu ..
@@ -737,8 +743,17 @@ def get_minmax(p):
class MyApp(object):
def __init__(self, args):
- from gnuradio.ctrlport.GNURadioControlPortClient import GNURadioControlPortClient
- GNURadioControlPortClient(args, 'thrift', self.run, Qt.QApplication(sys.argv).exec_)
+
+ parser = ArgumentParser(description="GNU Radio Control Port Monitor")
+ parser.add_argument("host", nargs="?", default="localhost", help="host name or IP")
+ parser.add_argument("port", help="port")
+ args = parser.parse_args()
+
+ try:
+ GNURadioControlPortClient(args.host, args.port, 'thrift', self.run, Qt.QApplication(sys.argv).exec_)
+ except:
+ print("Control Port failed to connect.")
+ sys.exit(1)
def run(self, client):
MAINWindow(client).show()
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/monitor.py b/gnuradio-runtime/python/gnuradio/ctrlport/monitor.py
index 3215fa5b26..f8e5882e59 100644
--- a/gnuradio-runtime/python/gnuradio/ctrlport/monitor.py
+++ b/gnuradio-runtime/python/gnuradio/ctrlport/monitor.py
@@ -34,15 +34,11 @@ class monitor(object):
atexit.register(self.shutdown)
# setup export prefs
- gr.prefs().singleton().set_bool("ControlPort","on",True);
+ gr.prefs().singleton().set_bool("ControlPort","on",True)
if(tool == "gr-perf-monitorx"):
- gr.prefs().singleton().set_bool("ControlPort","edges_list",True);
- gr.prefs().singleton().set_bool("PerfCounters","on",True);
- gr.prefs().singleton().set_bool("PerfCounters","export",True);
-
- def __del__(self):
- if(self.started):
- self.stop()
+ gr.prefs().singleton().set_bool("ControlPort","edges_list",True)
+ gr.prefs().singleton().set_bool("PerfCounters","on",True)
+ gr.prefs().singleton().set_bool("PerfCounters","export",True)
def start(self):
print("monitor::endpoints() = %s" % (gr.rpcmanager_get().endpoints()))
@@ -50,7 +46,7 @@ class monitor(object):
ep = gr.rpcmanager_get().endpoints()[0]
cmd = [self.tool, re.search(r"-h (\S+|\d+\.\d+\.\d+\.\d+)", ep).group(1), re.search(r"-p (\d+)", ep).group(1)]
print("running: %s"%(str(cmd)))
- self.proc = subprocess.Popen(cmd);
+ self.proc = subprocess.Popen(cmd)
self.started = True
except (ValueError, OSError):
self.proc = None
@@ -65,6 +61,6 @@ class monitor(object):
print("\tno proc to shut down, exiting")
def shutdown(self):
- print("ctrlport.monitor received shutdown signal")
+ print("ctrlport monitor received shutdown signal")
if(self.started):
self.stop()