#!/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" \
	"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"
	base_port = 6700

	# 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 %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" \
			 "     --ppm          Set frequency correction (default %d)\n"

		print(s % (
			self.remote_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: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()
