#!/usr/bin/env python2
# -*- coding: utf-8 -*-

# GR-GSM based transceiver
#
# (C) 2016-2018 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 gnuradio import eng_notation

from grgsm.trx import ctrl_if_bb
from grgsm.trx import radio_if
from grgsm.trx import fake_pm

COPYRIGHT = \
	"Copyright (C) 2016-2018 by Vadim Yanitskiy <axilirator@gmail.com>\n" \
	"Copyright (C) 2017 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:
	# Application variables
	remote_addr = "127.0.0.1"
	bind_addr = "0.0.0.0"
	base_port = 6700

	# PHY specific
	phy_sample_rate = 4 * 1625000 / 6
	phy_freq_offset_hz = None
	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.bind_addr, self.remote_addr,
			self.base_port)

		# Optional frequency offset
		if self.phy_freq_offset_hz is not None:
			self.radio.freq_offset_hz = self.phy_freq_offset_hz

		# 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.bind_addr, 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.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 %s)\n" \
			 "  -b --bind-addr    Set bind address (default %s)\n" \
			 "  -p --base-port    Set base port number (default %d)\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 %d)\n" \
			 "  -G --tx-gain      Set TX gain (default %d)\n" \
			 "     --rx-antenna   Set RX antenna (default %s)\n" \
			 "     --tx-antenna   Set TX antenna (default %s)\n" \
			 "     --freq-offset  Shift baseband freq. (e.g. -500M)\n" \
			 "     --ppm          Set frequency correction (default %d)\n"

		print(s % (
			self.remote_addr,
			self.bind_addr,
			self.base_port,
			self.phy_rx_gain,
			self.phy_tx_gain,
			self.phy_rx_antenna,
			self.phy_tx_antenna,
			self.phy_ppm))

	def parse_argv(self):
		try:
			opts, args = getopt.getopt(sys.argv[1:],
				"i:b:p:a:s:g:G:h",
				["help", "remote-addr=", "bind-addr=", "base-port=",
				"device-args=", "sample-rate=", "rx-gain=", "tx-gain=",
				"ppm=", "rx-antenna=", "tx-antenna=", "freq-offset="])
		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 ("-b", "--bind-addr"):
				self.bind_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)
			elif o in ("--freq-offset"):
				# Convert /\d+(\.\d+)?(M|k)?/ to Hz
				offset_hz = eng_notation.str_to_num(v)
				self.phy_freq_offset_hz = offset_hz

	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()
