| #!/usr/bin/env python2 |
| # -*- coding: utf-8 -*- |
| |
| # GR-GSM based transceiver |
| # |
| # (C) 2016-2017 by Vadim Yanitskiy <axilirator@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 getopt |
| import sys |
| |
| from grgsm.trx import ctrl_if_bb |
| from grgsm.trx import radio_if |
| from grgsm.trx import fake_pm |
| |
| COPYRIGHT = \ |
| "Copyright (C) 2016-2017 by Vadim Yanitskiy <axilirator@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: |
| # Application variables |
| remote_addr = "127.0.0.1" |
| base_port = 5700 |
| |
| # PHY specific |
| phy_sample_rate = 4 * 1625000 / 6 |
| phy_tx_antenna = "TX/RX" |
| phy_rx_antenna = "RX2" |
| phy_rx_gain = 30 |
| phy_tx_gain = 10 |
| phy_args = "" |
| phy_ppm = 0 |
| |
| def __init__(self): |
| self.print_copyright() |
| self.parse_argv() |
| |
| # Set up signal handlers |
| signal.signal(signal.SIGINT, self.sig_handler) |
| |
| def run(self): |
| # Init Radio interface |
| self.radio = radio_if(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.remote_addr, self.base_port) |
| |
| # Power measurement emulation |
| # Noise: -120 .. -105 |
| # BTS: -75 .. -50 |
| self.pm = fake_pm(-120, -105, -75, -50) |
| |
| # Init TRX CTRL interface |
| self.server = ctrl_if_bb(self.remote_addr, |
| self.base_port + 101, self.base_port + 1, |
| self.radio, self.pm) |
| |
| print("[i] Init complete") |
| |
| # Enter main loop |
| while True: |
| self.server.loop() |
| |
| def shutdown(self): |
| print("[i] Shutting down...") |
| self.server.shutdown() |
| self.radio.shutdown() |
| |
| def print_copyright(self): |
| print(COPYRIGHT) |
| |
| def print_help(self): |
| s = " Usage: " + sys.argv[0] + " [options]\n\n" \ |
| " Some help...\n" \ |
| " -h --help this text\n\n" |
| |
| # TRX specific |
| s += " TRX interface specific\n" \ |
| " -i --remote-addr Set remote address (default 127.0.0.1)\n" \ |
| " -p --base-port Set base port number (default 5700)\n\n" |
| |
| # PHY specific |
| s += " Radio interface specific\n" \ |
| " -a --device-args Set device arguments\n" \ |
| " -s --sample-rate Set sample rate\n" \ |
| " -g --rx-gain Set RX gain (default 30)\n" \ |
| " -G --tx-gain Set TX gain (default 10)\n" \ |
| " --rx-antenna Set RX antenna (default RX2)\n" \ |
| " --tx-antenna Set TX antenna (default TX/RX)\n" \ |
| " --ppm Set frequency correction (default 0)\n" |
| |
| print(s) |
| |
| def parse_argv(self): |
| try: |
| opts, args = getopt.getopt(sys.argv[1:], |
| "i:p:a:s:g:G:h", |
| ["help", "remote-addr=", "base-port=", "device-args=", |
| "sample-rate=", "rx-gain=", "tx-gain=", "ppm=", |
| "rx-antenna=", "tx-antenna="]) |
| except getopt.GetoptError as err: |
| # Print(help and exit) |
| self.print_help() |
| print("[!] " + str(err)) |
| sys.exit(2) |
| |
| for o, v in opts: |
| if o in ("-h", "--help"): |
| self.print_help() |
| sys.exit(2) |
| |
| # TRX specific |
| elif o in ("-i", "--remote-addr"): |
| self.remote_addr = v |
| elif o in ("-p", "--base-port"): |
| if int(v) >= 0 and int(v) <= 65535: |
| self.base_port = int(v) |
| else: |
| print("[!] The port number should be in range [0-65536]") |
| sys.exit(2) |
| |
| # PHY specific |
| elif o in ("-a", "--device-args"): |
| self.phy_args = v |
| elif o in ("-s", "--sample-rate"): |
| self.phy_sample_rate = int(v) |
| elif o in ("-g", "--rx-gain"): |
| self.phy_rx_gain = int(v) |
| elif o in ("-G", "--tx-gain"): |
| self.phy_tx_gain = int(v) |
| elif o in ("--rx-antenna"): |
| self.phy_rx_antenna = v |
| elif o in ("--tx-antenna"): |
| self.phy_tx_antenna = v |
| elif o in ("--ppm"): |
| self.phy_ppm = int(v) |
| |
| def sig_handler(self, signum, frame): |
| print("Signal %d received" % signum) |
| if signum is signal.SIGINT: |
| self.shutdown() |
| sys.exit(0) |
| |
| if __name__ == '__main__': |
| app = Application() |
| app.run() |