/* (C) 2020 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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.
 *
 */

/* This is a remsim-client that provides an IFD_Handler (reader driver)
 * towards the PC/SC services.  This effectively allows any local PC/SC client
 * application to use a remote smartcard via osmo-remsim.
 *
 * In order to use this, you will need an /etc/reader.conf.d/osmo-remsim-client
 * file with the following content:
 *
 * 	FRIENDLYNAME "osmo-remsim-client"
 * 	DEVICENAME   0:0:192.168.11.10:9998
 *	LIBPATH      /usr/lib/pcsc/drivers/serial/libifd_remsim_client.so
 *
 * Where  DEVICENAME has the following format:
 * 	[ClientID:[SlotNr:[ServerIp:[ServerPort]]]]
 *
 */

#include <errno.h>
#include <unistd.h>
#include <pthread.h>

#include <osmocom/core/select.h>
#include <osmocom/core/application.h>
extern int osmo_ctx_init(const char *id);

#include "client.h"

/* ensure this current thread has an osmo_ctx and hence can use OTC_GLOBAL and friends */
static void ensure_osmo_ctx(void)
{
	if (!osmo_ctx)
		osmo_ctx_init("");
}

/* inter-thread messages between IFD thread and remsim-client thread */
enum itmsg_type {
	ITMSG_TYPE_NONE,

	/* card present? */
	ITMSG_TYPE_CARD_PRES_REQ,
	ITMSG_TYPE_CARD_PRES_RESP,

	/* obtain ATR */
	ITMSG_TYPE_ATR_REQ,
	ITMSG_TYPE_ATR_RESP,

	/* transceive APDU: Send C-APDU, receive R-APDU */
	ITMSG_TYPE_C_APDU_REQ,
	ITMSG_TYPE_R_APDU_IND,

	/* power off the card */
	ITMSG_TYPE_POWER_OFF_REQ,
	ITMSG_TYPE_POWER_OFF_RESP,

	/* power on the card */
	ITMSG_TYPE_POWER_ON_REQ,
	ITMSG_TYPE_POWER_ON_RESP,

	/* reset the card */
	ITMSG_TYPE_RESET_REQ,
	ITMSG_TYPE_RESET_RESP,
};

struct itmsg {
	enum itmsg_type type;
	uint16_t status;	/* 0 == success */
	uint16_t len;		/* length of 'data' */
	uint8_t data[0];
};

/* allocate + initialize msgb-wrapped inter-thread message (struct itmsg) */
struct msgb *itmsg_alloc(enum itmsg_type type, uint16_t status, const uint8_t *data, uint16_t len)
{
	struct msgb *msg = msgb_alloc_c(OTC_GLOBAL, sizeof(struct itmsg)+len, "Tx itmsg");
	struct itmsg *im;

	if (!msg)
		return NULL;

	im = (struct itmsg *) msgb_put(msg, sizeof(struct itmsg) + len);
	im->type = type;
	im->status = status;
	im->len = len;
	if (len)
		memcpy(im->data, data, len);

	return msg;
}

/***********************************************************************
 * remsim_client thread
 ***********************************************************************/

void __thread *talloc_asn1_ctx;

struct client_thread {
	/* bankd client runningi inside this thread */
	struct bankd_client *bc;

	/* inter-thread osmo-fd; communication with IFD/PCSC thread */
	struct osmo_fd it_ofd;
	struct llist_head it_msgq;

	/* ATR as received from remsim-bankd */
	uint8_t atr[ATR_SIZE_MAX];
	uint8_t atr_len;
};

/* configuration of client thread; passed in from IFD thread */
struct client_thread_cfg {
	const char *name;
	const char *server_host;
	int server_port;
	int client_id;
	int client_slot;
	int it_sock_fd;
};

/* enqueue a msgb (containg 'struct itmsg') towards the IFD-handler thread */
static void enqueue_to_ifd(struct client_thread *ct, struct msgb *msg)
{
	if (!msg)
		return;

	msgb_enqueue(&ct->it_msgq, msg);
	ct->it_ofd.when |= OSMO_FD_WRITE;
}

/***********************************************************************
 * frontend to remsim-client main FSM code
 ***********************************************************************/

int frontend_request_card_insert(struct bankd_client *bc)
{
	return 0;
}

int frontend_request_sim_remote(struct bankd_client *bc)
{
	return 0;
}

int frontend_request_modem_reset(struct bankd_client *bc)
{
	return 0;
}

int frontend_handle_card2modem(struct bankd_client *bc, const uint8_t *data, size_t len)
{
	struct client_thread *ct = bc->data;
	struct msgb *msg;

	OSMO_ASSERT(data);

	DEBUGP(DMAIN, "R-APDU: %s\n", osmo_hexdump(data, len));
	/* enqueue towards IFD thread */
	msg = itmsg_alloc(ITMSG_TYPE_R_APDU_IND, 0, data, len);
	OSMO_ASSERT(msg);
	enqueue_to_ifd(ct, msg);

	return 0;
}

int frontend_handle_set_atr(struct bankd_client *bc, const uint8_t *data, size_t len)
{
	struct client_thread *ct = bc->data;
	unsigned int atr_len;

	OSMO_ASSERT(data);

	DEBUGP(DMAIN, "SET_ATR: %s\n", osmo_hexdump(data, len));

	/* store ATR in local data structure until somebody needs it */
	atr_len = len;
	if (atr_len > sizeof(ct->atr))
		atr_len = sizeof(ct->atr);
	memcpy(ct->atr, data, atr_len);
	ct->atr_len = atr_len;

	return 0;
}

int frontend_handle_slot_status(struct bankd_client *bc, const SlotPhysStatus_t *sts)
{
	return 0;
}

int frontend_append_script_env(struct bankd_client *bc, char **env, size_t max_env)
{
	return 0;
}

/***********************************************************************
 * Incoming command from the user application
 ***********************************************************************/

/* handle a single msgb-wrapped 'struct itmsg' from the IFD-handler thread */
static void handle_it_msg(struct client_thread *ct, struct itmsg *itmsg)
{
	struct bankd_client *bc = ct->bc;
	struct msgb *tx = NULL;
	RsproPDU_t *pdu;
	BankSlot_t bslot;

	bank_slot2rspro(&bslot, &ct->bc->bankd_slot);

	switch (itmsg->type) {
	case ITMSG_TYPE_CARD_PRES_REQ:
		if (bc->bankd_conn.fi->state == 2 /*SRVC_ST_CONNECTED*/)
			tx = itmsg_alloc(ITMSG_TYPE_CARD_PRES_RESP, 0, NULL, 0);
		else
			tx = itmsg_alloc(ITMSG_TYPE_CARD_PRES_RESP, 0xffff, NULL, 0);
		OSMO_ASSERT(tx);
		break;

	case ITMSG_TYPE_ATR_REQ:
		/* respond to IFD */
		tx = itmsg_alloc(ITMSG_TYPE_ATR_RESP, 0, ct->atr, ct->atr_len);
		OSMO_ASSERT(tx);
		break;

	case ITMSG_TYPE_POWER_OFF_REQ:
		pdu = rspro_gen_ClientSlotStatusInd(bc->srv_conn.clslot, &bslot,
						    true, false, false, true);
		server_conn_send_rspro(&bc->bankd_conn, pdu);
		/* respond to IFD */
		tx = itmsg_alloc(ITMSG_TYPE_POWER_OFF_RESP, 0, NULL, 0);
		OSMO_ASSERT(tx);
		break;

	case ITMSG_TYPE_POWER_ON_REQ:
		pdu = rspro_gen_ClientSlotStatusInd(bc->srv_conn.clslot, &bslot,
						    false, true, true, true);
		server_conn_send_rspro(&bc->bankd_conn, pdu);
		/* respond to IFD */
		tx = itmsg_alloc(ITMSG_TYPE_POWER_ON_RESP, 0, NULL, 0);
		OSMO_ASSERT(tx);
		break;

	case ITMSG_TYPE_RESET_REQ:
		/* reset the [remote] card */
		pdu = rspro_gen_ClientSlotStatusInd(bc->srv_conn.clslot, &bslot,
						    true, true, true, true);
		server_conn_send_rspro(&bc->bankd_conn, pdu);
		/* and take it out of reset again */
		pdu = rspro_gen_ClientSlotStatusInd(bc->srv_conn.clslot, &bslot,
						    false, true, true, true);
		server_conn_send_rspro(&bc->bankd_conn, pdu);
		/* respond to IFD */
		tx = itmsg_alloc(ITMSG_TYPE_RESET_RESP, 0, NULL, 0);
		OSMO_ASSERT(tx);
		break;
	case ITMSG_TYPE_C_APDU_REQ:
		if (!bc->srv_conn.clslot) {
			LOGP(DMAIN, LOGL_ERROR, "Cannot send command; no client slot\n");
			/* FIXME: Response? */
			return;
		}

		/* Send CMD APDU to [remote] card */
		pdu = rspro_gen_TpduModem2Card(bc->srv_conn.clslot, &bslot, itmsg->data, itmsg->len);
		server_conn_send_rspro(&bc->bankd_conn, pdu);
		/* response will come in asynchronously */
		break;
	default:
		LOGP(DMAIN, LOGL_ERROR, "Unknown inter-thread msg type %u\n", itmsg->type);
		break;
	}

	if (tx)
		enqueue_to_ifd(ct, tx);

}

/* call-back function for inter-thread socket */
static int it_sock_fd_cb(struct osmo_fd *ofd, unsigned int what)
{
	struct client_thread *ct = ofd->data;
	int rc;

	if (what & OSMO_FD_READ) {
		struct msgb *msg = msgb_alloc_c(OTC_GLOBAL, 1024, "Rx it_fd");
		struct itmsg *itmsg;

		OSMO_ASSERT(msg);
		rc = read(ofd->fd, msg->tail, msgb_tailroom(msg));
		if (rc <= 0) {
			LOGP(DMAIN, LOGL_ERROR, "Error reading from inter-thread fd: %d\n", rc);
			pthread_exit(NULL);
		}
		msgb_put(msg, rc);
		itmsg = (struct itmsg *) msgb_data(msg);
		if (msgb_length(msg) < sizeof(*itmsg) ||
		    msgb_length(msg) < sizeof(*itmsg) + itmsg->len) {
			LOGP(DMAIN, LOGL_ERROR, "Dropping short inter-thread message\n");
		} else {
			handle_it_msg(ct, itmsg);
		}
		msgb_free(msg);
	}

	if (what & OSMO_FD_WRITE) {
		struct msgb *msg = msgb_dequeue(&ct->it_msgq);
		if (!msg) {
			/* last message: disable write events */
			ofd->when &= ~OSMO_FD_WRITE;
		} else {
			unsigned int len = msgb_length(msg);
			rc = write(ofd->fd, msgb_data(msg), len);
			msgb_free(msg);
			if (rc < len) {
				LOGP(DMAIN, LOGL_ERROR, "Short write on inter-thread fd: %d < %d\n",
				     rc, len);
			}
		}
	}


	return 0;
}

/* release all resources allocated by thread */
static void client_pthread_cleanup(void *arg)
{
	struct client_thread *ct = arg;

	LOGP(DMAIN, LOGL_INFO, "Cleaning up remsim-client thread\n");
	//FIXME remsim_client_destroy(ct->bc);
	ct->bc = NULL;
	msgb_queue_free(&ct->it_msgq);
	osmo_fd_unregister(&ct->it_ofd);
	close(ct->it_ofd.fd);
	ct->it_ofd.fd = -1;
	talloc_free(ct);
}

/* main function of remsim-client pthread */
static void *client_pthread_main(void *arg)
{
	struct client_thread_cfg *cfg = arg;
	struct client_config *ccfg;
	struct client_thread *ct;
	int rc;

	osmo_select_init();
	rc = osmo_ctx_init("client");
	OSMO_ASSERT(rc == 0);

	ct = talloc_zero(OTC_GLOBAL, struct client_thread);
	OSMO_ASSERT(ct);

	ccfg = client_config_init(ct);
	OSMO_ASSERT(ccfg);
	osmo_talloc_replace_string(ccfg, &ccfg->server_host, cfg->server_host);
	if (cfg->server_port >= 0)
		ccfg->server_port = cfg->server_port;
	ccfg->client_id = cfg->client_id;
	ccfg->client_slot = cfg->client_slot;

	if (!talloc_asn1_ctx)
	       talloc_asn1_ctx= talloc_named_const(ct, 0, "asn1");

	ct->bc = remsim_client_create(ct, cfg->name, "remsim_ifdhandler", ccfg);
	OSMO_ASSERT(ct->bc);
	ct->bc->data = ct;

	INIT_LLIST_HEAD(&ct->it_msgq);
	osmo_fd_setup(&ct->it_ofd, cfg->it_sock_fd, OSMO_FD_READ, &it_sock_fd_cb, ct, 0);
	osmo_fd_register(&ct->it_ofd);

	/* ensure we get properly cleaned up if cancelled */
	pthread_cleanup_push(client_pthread_cleanup, ct);

	osmo_fsm_inst_dispatch(ct->bc->srv_conn.fi, SRVC_E_ESTABLISH, NULL);

	while (1) {
		osmo_select_main(0);
	}

	pthread_cleanup_pop(1);
	return NULL;
}

/***********************************************************************
 * PC/SC ifd_handler API functions
 ***********************************************************************/

#include <ifdhandler.h>
#include <debuglog.h>

#include <sys/types.h>
#include <sys/socket.h>

static const struct value_string ifd_status_names[] = {
	OSMO_VALUE_STRING(IFD_SUCCESS),
	OSMO_VALUE_STRING(IFD_ERROR_TAG),
	OSMO_VALUE_STRING(IFD_ERROR_SET_FAILURE),
	OSMO_VALUE_STRING(IFD_ERROR_VALUE_READ_ONLY),
	OSMO_VALUE_STRING(IFD_ERROR_PTS_FAILURE),
	OSMO_VALUE_STRING(IFD_ERROR_NOT_SUPPORTED),
	OSMO_VALUE_STRING(IFD_PROTOCOL_NOT_SUPPORTED),
	OSMO_VALUE_STRING(IFD_ERROR_POWER_ACTION),
	OSMO_VALUE_STRING(IFD_ERROR_SWALLOW),
	OSMO_VALUE_STRING(IFD_ERROR_EJECT),
	OSMO_VALUE_STRING(IFD_ERROR_CONFISCATE),
	OSMO_VALUE_STRING(IFD_COMMUNICATION_ERROR),
	OSMO_VALUE_STRING(IFD_RESPONSE_TIMEOUT),
	OSMO_VALUE_STRING(IFD_NOT_SUPPORTED),
	OSMO_VALUE_STRING(IFD_ICC_PRESENT),
	OSMO_VALUE_STRING(IFD_ICC_NOT_PRESENT),
	OSMO_VALUE_STRING(IFD_NO_SUCH_DEVICE),
	OSMO_VALUE_STRING(IFD_ERROR_INSUFFICIENT_BUFFER),
	{ 0, NULL }
};

static const struct value_string ifd_tag_names[] = {
	OSMO_VALUE_STRING(TAG_IFD_ATR),
	OSMO_VALUE_STRING(TAG_IFD_SLOTNUM),
	OSMO_VALUE_STRING(TAG_IFD_SLOT_THREAD_SAFE),
	OSMO_VALUE_STRING(TAG_IFD_THREAD_SAFE),
	OSMO_VALUE_STRING(TAG_IFD_SLOTS_NUMBER),
	OSMO_VALUE_STRING(TAG_IFD_SIMULTANEOUS_ACCESS),
	OSMO_VALUE_STRING(TAG_IFD_POLLING_THREAD),
	OSMO_VALUE_STRING(TAG_IFD_POLLING_THREAD_KILLABLE),
	OSMO_VALUE_STRING(TAG_IFD_STOP_POLLING_THREAD),
	OSMO_VALUE_STRING(TAG_IFD_POLLING_THREAD_WITH_TIMEOUT),
	{ 0, NULL }
};

#define LOG_EXIT(Lun, r) \
	Log4(r == IFD_SUCCESS || r == IFD_ICC_NOT_PRESENT ? PCSC_LOG_DEBUG : PCSC_LOG_ERROR, \
	     "%s(0x%08lx) => %s\n", __func__, Lun, get_value_string(ifd_status_names, r))

#define LOG_EXITF(Lun, r, fmt, args...) \
	Log5(r == IFD_SUCCESS ? PCSC_LOG_DEBUG : PCSC_LOG_ERROR, \
	     "%s(0x%08lx) "fmt" => %s\n", __func__, Lun, ## args, get_value_string(ifd_status_names, r))

/* IFD side handle for a remsim-client [thread] */
struct ifd_client {
	/* the client pthread itself */
	pthread_t pthread;
	/* socket to talk to thread */
	int it_fd;
	/* configuration passed into the thread */
	struct client_thread_cfg cfg;
};

static struct msgb *ifd_xceive_client(struct ifd_client *ic, struct msgb *tx)
{
	struct msgb *rx = msgb_alloc_c(OTC_GLOBAL, 1024, "ifd_rx itmsg");
	struct itmsg *rx_it;
	int rc;

	rc = write(ic->it_fd, msgb_data(tx), msgb_length(tx));
	msgb_free(tx);
	if (rc < msgb_length(tx)) {
		Log2(PCSC_LOG_ERROR, "Short write IFD->client thread: %d\n", rc);
		msgb_free(rx);
		return NULL;
	}
	rc = read(ic->it_fd, rx->tail, msgb_tailroom(rx));
	if (rc <= 0) {
		Log2(PCSC_LOG_ERROR, "Short read IFD<-client thread: %d\n", rc);
		msgb_free(rx);
		return NULL;
	}
	msgb_put(rx, rc);
	rx_it = (struct itmsg *) msgb_data(rx);
	if (msgb_length(rx) < sizeof(*rx_it) + rx_it->len) {
		Log2(PCSC_LOG_ERROR, "Short itmsg IFD<-client thread: %d\n", msgb_length(rx));
		msgb_free(rx);
		return NULL;
	}
	return rx;
}

/* function called on IFD side to create socketpair + start remsim-client thread */
static struct ifd_client *create_ifd_client(const struct client_thread_cfg *cfg)
{
	struct ifd_client *ic = talloc_zero(OTC_GLOBAL, struct ifd_client);
	int sp[2];
	int rc;

	/* copy over configuration */
	ic->cfg = *cfg;

	/* create socket pair for communication between threads */
	rc = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sp);
	if (rc != 0) {
		talloc_free(ic);
		return NULL;
	}

	ic->it_fd = sp[0];
	ic->cfg.it_sock_fd = sp[1];

	/* start the thread */
	rc = pthread_create(&ic->pthread, NULL, client_pthread_main, &ic->cfg);
	if (rc != 0) {
		Log1(PCSC_LOG_ERROR, "Error creating remsim-client pthread\n");
		close(sp[0]);
		close(sp[1]);
		talloc_free(ic);
		return NULL;
	}

	return ic;
}

/* function called on IFD side to destroy (terminate) remsim-client thread */
static void destroy_ifd_client(struct ifd_client *ic)
{
	if (!ic)
		return;

	pthread_cancel(ic->pthread);
	pthread_join(ic->pthread, NULL);
}

#define MAX_SLOTS	256
static struct ifd_client *ifd_client[MAX_SLOTS];

#define LUN2SLOT(lun) ((lun) & 0xffff)
#define LUN2RDR(lun) ((lun) >> 16)


RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel)
{
	return IFD_COMMUNICATION_ERROR;
}

RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR DeviceName)
{
	struct ifd_client *ic;
	struct client_thread_cfg cfg = {
		.name = "fixme-name",
		.server_host = "127.0.0.1",
		.server_port = -1,
		.client_id = 0,
		.client_slot = 0,
	};
	char *r, *client_id, *slot_nr, *host, *port;

	if (LUN2RDR(Lun) != 0)
		return IFD_NO_SUCH_DEVICE;

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client))
		return IFD_NO_SUCH_DEVICE;

	ensure_osmo_ctx();

	client_id = strtok_r(DeviceName, ":", &r);
	if (!client_id)
		goto end_parse;
	cfg.client_id = atoi(client_id);

	slot_nr = strtok_r(NULL, ":", &r);
	if (!slot_nr)
		goto end_parse;
	cfg.client_slot = atoi(slot_nr);

	host = strtok_r(NULL, ":", &r);
	if (!host)
		goto end_parse;
	cfg.server_host = strdup(host);

	port = strtok_r(NULL, ":", &r);
	cfg.server_port = atoi(port);


end_parse:
	LOGP(DMAIN, LOGL_NOTICE, "remsim-client C%d:%d bankd=%s:%d\n",
		cfg.client_id, cfg.client_slot, cfg.server_host, cfg.server_port);

	ic = create_ifd_client(&cfg);
	if (ic) {
		ifd_client[LUN2SLOT(Lun)] = ic;
		return IFD_SUCCESS;
	} else
		return IFD_COMMUNICATION_ERROR;
}

RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, PUCHAR TxBuffer, DWORD TxLength,
			 PUCHAR RxBuffer, DWORD RxLength, LPDWORD pdwBytesReturned)
{
	RESPONSECODE r = IFD_COMMUNICATION_ERROR;

	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client)) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (pdwBytesReturned)
		*pdwBytesReturned = 0;

	r = IFD_ERROR_NOT_SUPPORTED;
err:
	LOG_EXIT(Lun, r);
	return r;
}

RESPONSECODE IFDHCloseChannel(DWORD Lun)
{
	RESPONSECODE r = IFD_COMMUNICATION_ERROR;

	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client)) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	destroy_ifd_client(ifd_client[LUN2SLOT(Lun)]);
	ifd_client[LUN2SLOT(Lun)] = NULL;

	r = IFD_SUCCESS;
err:
	LOG_EXIT(Lun, r);
	return r;
}

RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag, PDWORD Length, PUCHAR Value)
{
	RESPONSECODE r = IFD_COMMUNICATION_ERROR;
	struct ifd_client *ic;
	struct msgb *rx, *tx;
	struct itmsg *rx_it;

	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client)) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	ic = ifd_client[LUN2SLOT(Lun)];
	if (!ic) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (!Length || !Value)
		goto err;

	switch (Tag) {
	case TAG_IFD_ATR:
		/* Return the ATR and its size */
		tx = itmsg_alloc(ITMSG_TYPE_ATR_REQ, 0, NULL, 0);
		OSMO_ASSERT(tx);
		rx = ifd_xceive_client(ic, tx);
		if (!rx) {
			r = IFD_NO_SUCH_DEVICE;
			goto err;
		}
		rx_it = (struct itmsg *)msgb_data(rx);
		if (*Length > rx_it->len)
			*Length = rx_it->len;
		memcpy(Value, rx_it->data, *Length);
		msgb_free(rx);
		break;
	case TAG_IFD_SIMULTANEOUS_ACCESS:
		/* Return the number of sessions (readers) the driver
		 * can handle in Value[0]. This is used for multiple
		 * readers sharing the same driver. */
		if (*Length < 1)
			goto err;
		*Value = 1;
		*Length = 1;
		break;
	case TAG_IFD_SLOTS_NUMBER:
		/* Return the number of slots in this reader in Value[0] */
		if (*Length < 1)
			goto err;
		*Value = 1;
		*Length = 1;
		break;
	case TAG_IFD_THREAD_SAFE:
		/* If the driver supports more than one reader (see
		 * TAG_IFD_SIMULTANEOUS_ACCESS above) this tag indicates
		 * if the driver supports access to multiple readers at
		 * the same time.  */
		if (*Length < 1)
			goto err;
		*Value = 0;
		*Length = 1;
		break;
	case TAG_IFD_SLOT_THREAD_SAFE:
		/* If the reader has more than one slot (see
		 * TAG_IFD_SLOTS_NUMBER above) this tag indicates if the
		 * driver supports access to multiple slots of the same
		 * reader at the same time. */
		if (*Length < 1)
			goto err;
		*Value = 0;
		*Length = 1;
		break;
	default:
		r = IFD_ERROR_TAG;
		goto err;
	}

	r = IFD_SUCCESS;

err:
	if (r != IFD_SUCCESS && Length)
		*Length = 0;

	LOG_EXITF(Lun, r, "%s", get_value_string(ifd_tag_names, Tag));
	return r;
}

RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag, DWORD Length, PUCHAR Value)
{
	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0)
		return IFD_NO_SUCH_DEVICE;

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client))
		return IFD_NO_SUCH_DEVICE;


	LOG_EXIT(Lun, IFD_NOT_SUPPORTED);
	return IFD_NOT_SUPPORTED;
}

RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol, UCHAR Flags, UCHAR PTS1,
					UCHAR PTS2, UCHAR PTS3)
{
	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0)
		return IFD_NO_SUCH_DEVICE;

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client))
		return IFD_NO_SUCH_DEVICE;

	LOG_EXIT(Lun, IFD_SUCCESS);
	return IFD_SUCCESS;
}

RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action, PUCHAR Atr, PDWORD AtrLength)
{
	RESPONSECODE r = IFD_COMMUNICATION_ERROR;
	struct ifd_client *ic;
	struct msgb *rx, *tx;

	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client)) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	ic = ifd_client[LUN2SLOT(Lun)];
	if (!ic) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	switch (Action) {
	case IFD_POWER_DOWN:
		tx = itmsg_alloc(ITMSG_TYPE_POWER_OFF_REQ, 0, NULL, 0);
		break;
	case IFD_POWER_UP:
		tx = itmsg_alloc(ITMSG_TYPE_POWER_ON_REQ, 0, NULL, 0);
		break;
	case IFD_RESET:
		tx = itmsg_alloc(ITMSG_TYPE_RESET_REQ, 0, NULL, 0);
		break;
	default:
		r = IFD_NOT_SUPPORTED;
		goto err;
	}

	rx = ifd_xceive_client(ic, tx);
	if (!rx) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	r = IFD_SUCCESS;
	msgb_free(rx);

err:
	if (r != IFD_SUCCESS && AtrLength)
		*AtrLength = 0;
	else
		r = IFDHGetCapabilities(Lun, TAG_IFD_ATR, AtrLength, Atr);

	LOG_EXIT(Lun, r);
	return r;
}

RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci, PUCHAR TxBuffer,
			       DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength,
			       PSCARD_IO_HEADER RecvPci)
{
	RESPONSECODE r = IFD_COMMUNICATION_ERROR;
	struct ifd_client *ic;
	struct msgb *rx, *tx;
	struct itmsg *rx_it;

	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client)) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	ic = ifd_client[LUN2SLOT(Lun)];
	if (!ic) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	tx = itmsg_alloc(ITMSG_TYPE_C_APDU_REQ, 0, TxBuffer, TxLength);
	OSMO_ASSERT(tx);
	/* transmit C-APDU to remote reader + blocking wait for response from peer */
	rx = ifd_xceive_client(ic, tx);
	if (!rx) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}
	rx_it = (struct itmsg *) msgb_data(rx);
	if (*RxLength > rx_it->len)
		*RxLength = rx_it->len;
	memcpy(RxBuffer, rx_it->data, *RxLength);
	msgb_free(rx);

	r = IFD_SUCCESS;
err:
	if (r != IFD_SUCCESS && RxLength)
		*RxLength = 0;

	LOG_EXIT(Lun, r);
	return r;
}

RESPONSECODE IFDHICCPresence(DWORD Lun)
{
	RESPONSECODE r = IFD_COMMUNICATION_ERROR;
	struct ifd_client *ic;
	struct msgb *rx, *tx;
	struct itmsg *rx_it;

	ensure_osmo_ctx();

	if (LUN2RDR(Lun) != 0) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	if (LUN2SLOT(Lun) >= ARRAY_SIZE(ifd_client)) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	ic = ifd_client[LUN2SLOT(Lun)];
	if (!ic) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}

	tx = itmsg_alloc(ITMSG_TYPE_CARD_PRES_REQ, 0, NULL, 0);
	OSMO_ASSERT(tx);
	rx = ifd_xceive_client(ic, tx);
	if (!rx) {
		r = IFD_NO_SUCH_DEVICE;
		goto err;
	}
	rx_it = (struct itmsg *) msgb_data(rx);
	if (rx_it->status == 0)
		r = IFD_SUCCESS;
	else
		r = IFD_ICC_NOT_PRESENT;

err:
	LOG_EXIT(Lun, r);
	return r;
}

static __attribute__((constructor)) void on_dso_load_ifd(void)
{
	void *g_tall_ctx = NULL;
	ensure_osmo_ctx();
	osmo_init_logging2(g_tall_ctx, &log_info);
}
