/* (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.
 *
 */

/* 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 running 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 *server_host;
	int server_port;
	int client_id;
	int client_slot;
	int it_sock_fd;
};

/* enqueue a msgb (containing '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_card_remove(struct bankd_client *bc)
{
	return 0;
}

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

int frontend_request_sim_local(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, int idx, size_t max_env)
{
	return idx;
}

/***********************************************************************
 * 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;
	char hostname[256];
	int rc;

	if (gethostname(hostname, sizeof(hostname)) < 0)
		OSMO_STRLCPY_ARRAY(hostname, "unknown");

	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, hostname, "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);
	rc = osmo_fd_register(&ct->it_ofd);
	OSMO_ASSERT(rc == 0);

	/* 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 = {
		.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);
}
