| #!/usr/bin/env python2 |
| # -*- coding: utf-8 -*- |
| |
| # GR-GSM based transceiver |
| # |
| # (C) 2016-2019 by Vadim Yanitskiy <axilirator@gmail.com> |
| # (C) 2017-2018 by Piotr Krysik <ptrkrysik@gmail.com> |
| # |
| # All Rights Reserved |
| # |
| # 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 2 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, write to the Free Software Foundation, Inc., |
| # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| |
| import signal |
| import sys |
| |
| from argparse import ArgumentParser |
| from argparse import ArgumentTypeError |
| from gnuradio import eng_notation |
| |
| from grgsm.trx import RadioInterface |
| from grgsm.trx import Transceiver |
| |
| COPYRIGHT = \ |
| "Copyright (C) 2016-2018 by Vadim Yanitskiy <axilirator@gmail.com>\n" \ |
| "Copyright (C) 2017-2018 by Piotr Krysik <ptrkrysik@gmail.com>\n" \ |
| "License GPLv2+: GNU GPL version 2 or later " \ |
| "<http://gnu.org/licenses/gpl.html>\n" \ |
| "This is free software: you are free to change and redistribute it.\n" \ |
| "There is NO WARRANTY, to the extent permitted by law.\n" |
| |
| class Application: |
| def __init__(self, argv): |
| self.remote_addr = argv.remote_addr |
| self.bind_addr = argv.bind_addr |
| self.base_port = argv.base_port |
| self.phy_args = argv.args |
| self.phy_sample_rate = argv.sample_rate |
| self.phy_rx_gain = argv.rx_gain |
| self.phy_tx_gain = argv.tx_gain |
| self.phy_rx_antenna = argv.rx_antenna |
| self.phy_tx_antenna = argv.tx_antenna |
| self.phy_freq_offset = argv.freq_offset |
| self.phy_ppm = argv.ppm |
| |
| # Set up signal handlers |
| signal.signal(signal.SIGINT, self.sig_handler) |
| |
| if argv.driver == "uhd": |
| from grgsm.trx.radio_if_uhd import RadioInterfaceUHD as Radio |
| elif argv.driver == "lms": |
| from grgsm.trx.radio_if_lms import RadioInterfaceLMS as Radio |
| else: |
| raise ValueError("Unknown RadioInterface driver '%s'" % argv.driver) |
| |
| # Init Radio interface |
| self.radio = Radio(self.phy_args, self.phy_sample_rate, |
| self.phy_rx_gain, self.phy_tx_gain, self.phy_ppm, |
| self.phy_rx_antenna, self.phy_tx_antenna, |
| self.phy_freq_offset, self.bind_addr, |
| self.remote_addr, self.base_port) |
| |
| # Init Transceiver |
| self.trx = Transceiver(self.bind_addr, |
| self.remote_addr, self.base_port, |
| radio_if = self.radio) |
| |
| print("[i] Init complete") |
| |
| def run(self): |
| # Enter main loop |
| while True: |
| self.trx.ctrl_if.loop() |
| |
| def shutdown(self): |
| print("[i] Shutting down...") |
| self.radio.shutdown() |
| |
| def sig_handler(self, signum, frame): |
| print("Signal %d received" % signum) |
| if signum is signal.SIGINT: |
| self.shutdown() |
| sys.exit(0) |
| |
| def eng_float(value): |
| try: |
| return eng_notation.str_to_num(value) |
| except: |
| raise ArgumentTypeError("invalid engineering notation " |
| "value: {0}".format(value)) |
| |
| def parse_argv(): |
| parser = ArgumentParser(prog = "grgsm_trx") |
| |
| # TRX interface specific |
| trx_group = parser.add_argument_group("TRX interface") |
| trx_group.add_argument("-i", "--remote-addr", |
| dest = "remote_addr", type = str, default = "127.0.0.1", |
| help = "Set remote address (default %(default)s)") |
| trx_group.add_argument("-b", "--bind-addr", |
| dest = "bind_addr", type = str, default = "0.0.0.0", |
| help = "Set bind address (default %(default)s)") |
| trx_group.add_argument("-p", "--base_port", |
| dest = "base_port", type = int, default = 6700, |
| help = "Set base port number (default %(default)s)") |
| |
| # PHY specific |
| phy_group = parser.add_argument_group("PHY parameters") |
| phy_group.add_argument("--driver", |
| dest = "driver", type = str, default = "uhd", |
| choices = ["uhd", "lms"], |
| help = "Set device driver (default %(default)s)") |
| phy_group.add_argument("-a", "--args", |
| dest = "args", type = str, default = "", |
| help = "Set device arguments") |
| phy_group.add_argument("-s", "--sample-rate", |
| dest = "sample_rate", type = eng_float, |
| default = RadioInterface.SAMPLE_RATE, |
| help = "Set samp_rate (default %(default)s)") |
| phy_group.add_argument("-g", "--rx-gain", |
| dest = "rx_gain", type = float, default = 30, |
| help = "Set RX gain (default %(default)s)") |
| phy_group.add_argument("-G", "--tx-gain", |
| dest = "tx_gain", type = float, default = 10, |
| help = "Set TX gain (default %(default)s)") |
| phy_group.add_argument("--rx-antenna", |
| dest = "rx_antenna", type = str, default = "RX2", |
| help = "Set RX antenna (default %(default)s)") |
| phy_group.add_argument("--tx-antenna", |
| dest = "tx_antenna", type = str, default = "TX/RX", |
| help = "Set TX antenna (default %(default)s)") |
| phy_group.add_argument("--freq-offset", |
| dest = "freq_offset", type = eng_float, default = 0, |
| help = "Shift baseband freq. (e.g. -500M)") |
| phy_group.add_argument("--ppm", |
| dest = "ppm", type = float, default = 0, |
| help = "Set frequency correction (default %(default)s)") |
| |
| return parser.parse_args() |
| |
| if __name__ == '__main__': |
| print(COPYRIGHT) |
| argv = parse_argv() |
| app = Application(argv) |
| app.run() |