aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/tools
diff options
context:
space:
mode:
authorAndrej Rode <andrej.rode@ettus.com>2017-03-27 17:07:44 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:44 -0800
commit8ac9014d5c30836665378d2d088b5c602162f8ac (patch)
tree21708ce88f72da4818e73afe054b89e7f1589fdd /mpm/tools
parent6d332e5ca4a7311406ac285f827c31c9e5b94280 (diff)
downloaduhd-8ac9014d5c30836665378d2d088b5c602162f8ac.tar.gz
uhd-8ac9014d5c30836665378d2d088b5c602162f8ac.tar.bz2
uhd-8ac9014d5c30836665378d2d088b5c602162f8ac.zip
mpm: CMake cleanup, Python code enhancements
- Send user defined data in ping - Improve rpc_shell, add mpm_debug.py, fix tracebacks in multiprocessing
Diffstat (limited to 'mpm/tools')
-rw-r--r--mpm/tools/CMakeLists.txt21
-rwxr-xr-xmpm/tools/mpm_debug.py63
-rwxr-xr-xmpm/tools/rpc_shell.py68
3 files changed, 128 insertions, 24 deletions
diff --git a/mpm/tools/CMakeLists.txt b/mpm/tools/CMakeLists.txt
new file mode 100644
index 000000000..107aedeae
--- /dev/null
+++ b/mpm/tools/CMakeLists.txt
@@ -0,0 +1,21 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+INSTALL(PROGRAMS
+ rpc_shell.py
+ mpm_debug.py
+ DESTINATION ${RUNTIME_DIR})
diff --git a/mpm/tools/mpm_debug.py b/mpm/tools/mpm_debug.py
new file mode 100755
index 000000000..1a97a103c
--- /dev/null
+++ b/mpm/tools/mpm_debug.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+import socket
+from mprpc import RPCClient
+import usrp_mpm as mpm
+import argparse
+
+
+def parse_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-a", "--address", default="0.0.0.0", type=str, help="Destination address")
+ parser.add_argument("-p", "--port", default=0, type=int, help="Destination port")
+ sub_parsers = parser.add_subparsers(dest="command")
+
+ rpc_parser = sub_parsers.add_parser("rpc", help="Issue RPC")
+ rpc_parser.add_argument("-c", "--call", required=True, help="command to issue")
+ rpc_parser.add_argument("arguments", nargs="*")
+
+ disc_parser = sub_parsers.add_parser("disc", help="Issue discovery")
+ return parser.parse_args()
+
+
+def rpc(address, port, command, *args):
+ if not port:
+ port = mpm.types.MPM_RPC_PORT
+ client = RPCClient(address, port)
+ if args:
+ result = client.call(command, *args)
+ else:
+ result = client.call(command)
+ return result
+
+
+def discovery(address, port):
+ if not port:
+ port = mpm.types.MPM_DISCOVERY_PORT
+ sock = socket.socket(
+ socket.AF_INET,
+ socket.SOCK_DGRAM)
+ sock.sendto(mpm.types.MPM_DISCOVERY_MESSAGE, (address, port))
+ sock.settimeout(1.0) # wait max 1 second
+ while True:
+ try:
+ data, sender = sock.recvfrom(4096)
+ print("Received respons from: {}".format(sender[0]))
+ print("Dicovery data: {}".format(data))
+ except:
+ break
+
+
+def main():
+ args = parse_args()
+ if args.command == "rpc":
+ if args.arguments:
+ result = rpc(args.address, args.port, args.call, *args.arguments)
+ else:
+ result = rpc(args.address, args.port, args.call)
+ print(result)
+ elif args.command == "disc":
+ discovery(args.address, args.port)
+
+
+if __name__ == "__main__":
+ exit(not(main()))
diff --git a/mpm/tools/rpc_shell.py b/mpm/tools/rpc_shell.py
index ef3c73614..36c16880a 100755
--- a/mpm/tools/rpc_shell.py
+++ b/mpm/tools/rpc_shell.py
@@ -22,35 +22,49 @@ RPC shell to debug USRP MPM capable devices
import sys
import cmd
import types
-from functools import partial
from mprpc import RPCClient
from mprpc.exceptions import RPCError
from usrp_mpm import types
+from importlib import import_module
-def rpc_template(obj, command, args):
- try:
- if args:
- response = obj.client.call(command, args)
- else:
- response = obj.client.call(command)
- except RPCError as e:
- print("RPC Command failed!")
- print("Error: {}".format(e))
- return
- if isinstance(response, bool):
- if response:
- print("Commend executed successfully!")
- return
- print("Command failed!")
- return
- print(response)
class RPCShell(cmd.Cmd):
- prompt="MPM> "
+ prompt = "MPM> "
client = None
remote_methods = []
+ def rpc_template(self, command, args=None):
+ """Template function to create new RPC shell commands"""
+ eval_preamble = "="
+ try:
+ if args:
+ if isinstance(args, list):
+ parsed_args = [
+ eval(a.lstrip(eval_preamble))
+ if a.startswith(eval_preamble) else a for a in args
+ ]
+ response = self.client.call(command, parsed_args)
+ else:
+ response = self.client.call(
+ command,
+ eval(args.lstrip(eval_preamble))
+ if args.startswith(eval_preamble) else args)
+ else:
+ response = self.client.call(command)
+ except RPCError as e:
+ print("RPC Command failed!")
+ print("Error: {}".format(e))
+ return
+ if isinstance(response, bool):
+ if response:
+ print("Commend executed successfully!")
+ return
+ print("Command failed!")
+ return
+ print(response)
+
def do_connect(self, host, port=types.MPM_RPC_PORT):
+ """connect to a remote RPC serverconnect <host> (port=MPM_RPC_PORT)"""
try:
self.client = RPCClient(host, port)
except:
@@ -61,6 +75,7 @@ class RPCShell(cmd.Cmd):
self.add_command(*method)
def do_disconnect(self, args):
+ """disconnect from the RPC server"""
if self.client:
try:
self.client.close()
@@ -68,15 +83,21 @@ class RPCShell(cmd.Cmd):
print("Error while closing the connection")
print("Error: {}".format(e))
for method in self.remote_methods:
- delattr(self, "do_"+method)
+ delattr(self, "do_" + method)
self.remote_methods = []
self.client = None
+ def do_import(self, args):
+ """import a python module into the global namespace"""
+ globals()[args] = import_module(args)
+
+ def do_EOF(self, args):
+ exit(0)
def add_command(self, command, docs):
- new_command = partial(rpc_template, self, str(command))
+ def new_command(args): self.rpc_template(str(command), args)
new_command.__doc__ = docs
- setattr(self, "do_"+command, new_command)
+ setattr(self, "do_" + command, new_command)
self.remote_methods.append(command)
def run(self):
@@ -92,5 +113,4 @@ class RPCShell(cmd.Cmd):
if __name__ == "__main__":
my_shell = RPCShell()
- exit(not(my_shell.run()))
-
+ exit(not (my_shell.run()))