#!/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.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()
