# -*- coding: utf-8 -*-

""" pySim: Transport Link for Calypso bases phones
"""

#
# Copyright (C) 2018 Vadim Yanitskiy <axilirator@gmail.com>
#
# 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, see <http://www.gnu.org/licenses/>.
#

import select
import struct
import socket
import os

from pySim.transport import LinkBase
from pySim.exceptions import *
from pySim.utils import h2b, b2h

class L1CTLMessage(object):

	# Every (encoded) L1CTL message has the following structure:
	#  - msg_length (2 bytes, net order)
	#  - l1ctl_hdr (packed structure)
	#    - msg_type
	#    - flags
	#    - padding (2 spare bytes)
	#  - ... payload ...

	def __init__(self, msg_type, flags = 0x00):
		# Init L1CTL message header
		self.data = struct.pack("BBxx", msg_type, flags)

	def gen_msg(self):
		return struct.pack("!H", len(self.data)) + self.data

class L1CTLMessageReset(L1CTLMessage):

	# L1CTL message types
	L1CTL_RESET_REQ		= 0x0d
	L1CTL_RESET_IND		= 0x07
	L1CTL_RESET_CONF	= 0x0e

	# Reset types
	L1CTL_RES_T_BOOT	= 0x00
	L1CTL_RES_T_FULL	= 0x01
	L1CTL_RES_T_SCHED	= 0x02

	def __init__(self, type = L1CTL_RES_T_FULL):
		super(L1CTLMessageReset, self).__init__(self.L1CTL_RESET_REQ)
		self.data += struct.pack("Bxxx", type)

class L1CTLMessageSIM(L1CTLMessage):

	# SIM related message types
	L1CTL_SIM_REQ		= 0x16
	L1CTL_SIM_CONF		= 0x17

	def __init__(self, pdu):
		super(L1CTLMessageSIM, self).__init__(self.L1CTL_SIM_REQ)
		self.data += pdu

class CalypsoSimLink(LinkBase):

	def __init__(self, sock_path = "/tmp/osmocom_l2"):
		# Make sure that a given socket path exists
		if not os.path.exists(sock_path):
			raise ReaderError("There is no such ('%s') UNIX socket" % sock_path)

		print("Connecting to osmocon at '%s'..." % sock_path)

		# Establish a client connection
		self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
		self.sock.connect(sock_path)

	def __del__(self):
		self.sock.close()

	def wait_for_rsp(self, exp_len = 128):
		# Wait for incoming data (timeout is 3 seconds)
		s, _, _ = select.select([self.sock], [], [], 3.0)
		if not s:
			raise ReaderError("Timeout waiting for card response")

		# Receive expected amount of bytes from osmocon
		rsp = self.sock.recv(exp_len)
		return rsp

	def reset_card(self):
		# Request FULL reset
		req_msg = L1CTLMessageReset()
		self.sock.send(req_msg.gen_msg())

		# Wait for confirmation
		rsp = self.wait_for_rsp()
		rsp_msg = struct.unpack_from("!HB", rsp)
		if rsp_msg[1] != L1CTLMessageReset.L1CTL_RESET_CONF:
			raise ReaderError("Failed to reset Calypso PHY")

	def connect(self):
		self.reset_card()

	def disconnect(self):
		pass # Nothing to do really ...

	def wait_for_card(self, timeout = None, newcardonly = False):
		pass # Nothing to do really ...

	def send_apdu_raw(self, pdu):
		"""see LinkBase.send_apdu_raw"""

		# Request FULL reset
		req_msg = L1CTLMessageSIM(h2b(pdu))
		self.sock.send(req_msg.gen_msg())

		# Read message length first
		rsp = self.wait_for_rsp(struct.calcsize("!H"))
		msg_len = struct.unpack_from("!H", rsp)[0]
		if msg_len < struct.calcsize("BBxx"):
			raise ReaderError("Missing L1CTL header for L1CTL_SIM_CONF")

		# Read the whole message then
		rsp = self.sock.recv(msg_len)

		# Verify L1CTL header
		hdr = struct.unpack_from("BBxx", rsp)
		if hdr[0] != L1CTLMessageSIM.L1CTL_SIM_CONF:
			raise ReaderError("Unexpected L1CTL message received")

		# Verify the payload length
		offset = struct.calcsize("BBxx")
		if len(rsp) <= offset:
			raise ProtocolError("Empty response from SIM?!?")

		# Omit L1CTL header
		rsp = rsp[offset:]

		# Unpack data and SW
		data = rsp[:-2]
		sw = rsp[-2:]

		return b2h(data), b2h(sw)
