blob: b91171902a814eba87c3b4331569fcb6d4385b30 [file] [log] [blame]
Piotr Krysik902f4eb2017-09-19 08:04:33 +02001#!/usr/bin/env python2
2# -*- coding: utf-8 -*-
3
4# GR-GSM based transceiver
5#
Vadim Yanitskiy3e6bfe72019-01-19 09:02:12 +07006# (C) 2016-2019 by Vadim Yanitskiy <axilirator@gmail.com>
Piotr Krysik262bda12018-09-07 18:36:13 +07007# (C) 2017-2018 by Piotr Krysik <ptrkrysik@gmail.com>
Piotr Krysik902f4eb2017-09-19 08:04:33 +02008#
9# All Rights Reserved
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License along
22# with this program; if not, write to the Free Software Foundation, Inc.,
23# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25import signal
Piotr Krysik902f4eb2017-09-19 08:04:33 +020026import sys
27
Piotr Krysik262bda12018-09-07 18:36:13 +070028from argparse import ArgumentParser
29from argparse import ArgumentTypeError
Vadim Yanitskiy3f9abbd2018-08-10 05:29:23 +070030from gnuradio import eng_notation
31
Vadim Yanitskiy6ee957f2019-01-19 11:55:01 +070032from grgsm.trx import RadioInterfaceUHD
Vadim Yanitskiy44d8c1e2018-12-20 09:49:56 +070033from grgsm.trx import RadioInterface
Vadim Yanitskiy2cbc3b52019-01-19 10:22:59 +070034from grgsm.trx import Transceiver
Piotr Krysik902f4eb2017-09-19 08:04:33 +020035
36COPYRIGHT = \
Vadim Yanitskiy21655842018-08-10 00:20:03 +070037 "Copyright (C) 2016-2018 by Vadim Yanitskiy <axilirator@gmail.com>\n" \
Piotr Krysik262bda12018-09-07 18:36:13 +070038 "Copyright (C) 2017-2018 by Piotr Krysik <ptrkrysik@gmail.com>\n" \
Piotr Krysik902f4eb2017-09-19 08:04:33 +020039 "License GPLv2+: GNU GPL version 2 or later " \
40 "<http://gnu.org/licenses/gpl.html>\n" \
41 "This is free software: you are free to change and redistribute it.\n" \
42 "There is NO WARRANTY, to the extent permitted by law.\n"
43
Piotr Krysikba6fd0e2018-09-06 19:57:57 +020044class Application:
Piotr Krysik262bda12018-09-07 18:36:13 +070045 def __init__(self, argv):
46 self.remote_addr = argv.remote_addr
47 self.bind_addr = argv.bind_addr
48 self.base_port = argv.base_port
49 self.phy_args = argv.args
50 self.phy_sample_rate = argv.sample_rate
51 self.phy_rx_gain = argv.rx_gain
52 self.phy_tx_gain = argv.tx_gain
53 self.phy_rx_antenna = argv.rx_antenna
54 self.phy_tx_antenna = argv.tx_antenna
Piotr Krysikdb658832018-09-13 15:42:55 +020055 self.phy_freq_offset = argv.freq_offset
Piotr Krysik262bda12018-09-07 18:36:13 +070056 self.phy_ppm = argv.ppm
Piotr Krysik902f4eb2017-09-19 08:04:33 +020057
58 # Set up signal handlers
59 signal.signal(signal.SIGINT, self.sig_handler)
60
Piotr Krysik902f4eb2017-09-19 08:04:33 +020061 # Init Radio interface
Vadim Yanitskiy6ee957f2019-01-19 11:55:01 +070062 self.radio = RadioInterfaceUHD(self.phy_args, self.phy_sample_rate,
Vadim Yanitskiy790b6f02017-10-17 11:47:36 +070063 self.phy_rx_gain, self.phy_tx_gain, self.phy_ppm,
Piotr Krysikba6fd0e2018-09-06 19:57:57 +020064 self.phy_rx_antenna, self.phy_tx_antenna,
Piotr Krysikdb658832018-09-13 15:42:55 +020065 self.phy_freq_offset, self.bind_addr,
Piotr Krysik11583ad2018-09-13 14:41:06 +020066 self.remote_addr, self.base_port)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020067
Vadim Yanitskiy2cbc3b52019-01-19 10:22:59 +070068 # Init Transceiver
69 self.trx = Transceiver(self.bind_addr,
70 self.remote_addr, self.base_port,
71 radio_if = self.radio)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020072
73 print("[i] Init complete")
74
Vadim Yanitskiy3e6bfe72019-01-19 09:02:12 +070075 def run(self):
Piotr Krysik902f4eb2017-09-19 08:04:33 +020076 # Enter main loop
77 while True:
Vadim Yanitskiy2cbc3b52019-01-19 10:22:59 +070078 self.trx.ctrl_if.loop()
Piotr Krysik902f4eb2017-09-19 08:04:33 +020079
80 def shutdown(self):
81 print("[i] Shutting down...")
Piotr Krysik902f4eb2017-09-19 08:04:33 +020082 self.radio.shutdown()
83
Piotr Krysik902f4eb2017-09-19 08:04:33 +020084 def sig_handler(self, signum, frame):
85 print("Signal %d received" % signum)
86 if signum is signal.SIGINT:
87 self.shutdown()
88 sys.exit(0)
89
Piotr Krysik262bda12018-09-07 18:36:13 +070090def eng_float(value):
91 try:
92 return eng_notation.str_to_num(value)
93 except:
94 raise ArgumentTypeError("invalid engineering notation "
95 "value: {0}".format(value))
96
97def parse_argv():
98 parser = ArgumentParser(prog = "grgsm_trx")
99
100 # TRX interface specific
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700101 trx_group = parser.add_argument_group("TRX interface")
102 trx_group.add_argument("-i", "--remote-addr",
Piotr Krysik262bda12018-09-07 18:36:13 +0700103 dest = "remote_addr", type = str, default = "127.0.0.1",
104 help = "Set remote address (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700105 trx_group.add_argument("-b", "--bind-addr",
Piotr Krysik262bda12018-09-07 18:36:13 +0700106 dest = "bind_addr", type = str, default = "0.0.0.0",
107 help = "Set bind address (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700108 trx_group.add_argument("-p", "--base_port",
Piotr Krysik262bda12018-09-07 18:36:13 +0700109 dest = "base_port", type = int, default = 6700,
110 help = "Set base port number (default %(default)s)")
111
112 # PHY specific
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700113 phy_group = parser.add_argument_group("PHY parameters")
114 phy_group.add_argument("-a", "--args",
Piotr Krysik262bda12018-09-07 18:36:13 +0700115 dest = "args", type = str, default = "",
116 help = "Set device arguments")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700117 phy_group.add_argument("-s", "--sample-rate",
Piotr Krysik262bda12018-09-07 18:36:13 +0700118 dest = "sample_rate", type = eng_float,
Vadim Yanitskiy44d8c1e2018-12-20 09:49:56 +0700119 default = RadioInterface.SAMPLE_RATE,
Piotr Krysik262bda12018-09-07 18:36:13 +0700120 help = "Set samp_rate (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700121 phy_group.add_argument("-g", "--rx-gain",
Piotr Krysik262bda12018-09-07 18:36:13 +0700122 dest = "rx_gain", type = float, default = 30,
123 help = "Set RX gain (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700124 phy_group.add_argument("-G", "--tx-gain",
Piotr Krysik262bda12018-09-07 18:36:13 +0700125 dest = "tx_gain", type = float, default = 10,
126 help = "Set TX gain (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700127 phy_group.add_argument("--rx-antenna",
Piotr Krysik262bda12018-09-07 18:36:13 +0700128 dest = "rx_antenna", type = str, default = "RX2",
129 help = "Set RX antenna (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700130 phy_group.add_argument("--tx-antenna",
Piotr Krysik262bda12018-09-07 18:36:13 +0700131 dest = "tx_antenna", type = str, default = "TX/RX",
132 help = "Set TX antenna (default %(default)s)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700133 phy_group.add_argument("--freq-offset",
Piotr Krysik262bda12018-09-07 18:36:13 +0700134 dest = "freq_offset", type = eng_float, default = 0,
135 help = "Shift baseband freq. (e.g. -500M)")
Vadim Yanitskiyef933822018-09-21 14:52:53 +0700136 phy_group.add_argument("--ppm",
Piotr Krysik262bda12018-09-07 18:36:13 +0700137 dest = "ppm", type = float, default = 0,
138 help = "Set frequency correction (default %(default)s)")
139
140 return parser.parse_args()
141
Piotr Krysikfcb64a82018-09-05 21:36:34 +0200142if __name__ == '__main__':
Piotr Krysik262bda12018-09-07 18:36:13 +0700143 print(COPYRIGHT)
144 argv = parse_argv()
145 app = Application(argv)
Piotr Krysikba6fd0e2018-09-06 19:57:57 +0200146 app.run()