diff options
Diffstat (limited to 'mpm/tools')
-rw-r--r-- | mpm/tools/CMakeLists.txt | 21 | ||||
-rwxr-xr-x | mpm/tools/mpm_debug.py | 63 | ||||
-rwxr-xr-x | mpm/tools/rpc_shell.py | 68 |
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())) |