/* apdu_dispatch - State machine to determine Rx/Tx phases of APDU
 *
 * (C) 2016 by Harald Welte <hwelte@hmw-consulting.de>
 *
 * 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.
 */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <errno.h>

#include <osmocom/core/utils.h>
#include <osmocom/sim/sim.h>
#include <osmocom/sim/class_tables.h>

#include <osmocom/simtrace2/apdu_dispatch.h>

/*! \brief Has the command-data phase been completed yet? */
static inline bool is_dc_complete(struct osmo_apdu_context *ac)
{
	return (ac->lc.tot == ac->lc.cur);
}

/*! \brief Has the expected-data phase been completed yet? */
static inline bool is_de_complete(struct osmo_apdu_context *ac)
{
	return (ac->le.tot == ac->le.cur);
}

static const char *dump_apdu_hdr(const struct osim_apdu_cmd_hdr *h)
{
	static char buf[256];
	sprintf(buf, "CLA=%02x INS=%02x P1=%02x P2=%02x P3=%02x",
		h->cla, h->ins, h->p1, h->p2, h->p3);

	return buf;
}

static void dump_apdu_ctx(const struct osmo_apdu_context *ac)
{
	printf("%s; case=%d, lc=%d(%d), le=%d(%d)\n",
		dump_apdu_hdr(&ac->hdr), ac->apdu_case,
		ac->lc.tot, ac->lc.cur,
		ac->le.tot, ac->le.cur);
}

/*! \brief input function for APDU segmentation
 *  \param ac APDU context accross successive calls
 *  \param[in] apdu_buf APDU inpud data buffer
 *  \param[in] apdu_len Length of apdu_buf
 *  \param[in] new_apdu Is this the beginning of a new APDU?
 *
 *  The function returns APDU_ACT_TX_CAPDU_TO_CARD once there is
 *  sufficient data of the APDU received to transmit the command-APDU to
 *  the actual card.
 *
 *  The function retunrs APDU_ACT_RX_MORE_CAPDU_FROM_READER when there
 *  is more data to be received from the card reader (GSM Phone).
 */
int osmo_apdu_segment_in(struct osmo_apdu_context *ac, const uint8_t *apdu_buf,
			 unsigned int apdu_len, bool new_apdu)
{
	int rc = 0;

	if (new_apdu) {
		/* initialize the apdu context structure */
		memset(ac, 0, sizeof(*ac));
		/* copy APDU header over */
		memcpy(&ac->hdr, apdu_buf, sizeof(ac->hdr));
		ac->apdu_case = osim_determine_apdu_case(&osim_uicc_sim_cic_profile, apdu_buf);
		switch (ac->apdu_case) {
		case 1: /* P3 == 0, No Lc/Le */
			ac->le.tot = ac->lc.tot = 0;
			break;
		case 2: /* P3 == Le */
			ac->le.tot = ac->hdr.p3;
			break;
		case 3: /* P3 = Lc */
			ac->lc.tot = ac->hdr.p3;
			/* copy Dc */
			ac->lc.cur = apdu_len - sizeof(ac->hdr);
			memcpy(ac->dc, apdu_buf + sizeof(ac->hdr),
				ac->lc.cur);
			break;
		case 4: /* P3 = Lc; SW with Le */
			ac->lc.tot = ac->hdr.p3;
			/* copy Dc */
			ac->lc.cur = apdu_len - sizeof(ac->hdr);
			memcpy(ac->dc, apdu_buf + sizeof(ac->hdr),
				ac->lc.cur);
			break;
		case 0:
		default:
			fprintf(stderr, "Unknown APDU case %d\n", ac->apdu_case);
			return -1;
		}
	} else {
		/* copy more data, if available */
		int cpy_len;
		switch (ac->apdu_case) {
		case 1:
		case 2:
			break;
		case 3:
		case 4:
			cpy_len = ac->lc.tot - ac->lc.cur;
			if (cpy_len > apdu_len)
				cpy_len = apdu_len;
			memcpy(ac->dc+ac->lc.cur, apdu_buf, cpy_len);
			ac->lc.cur += cpy_len;
			break;
		default:
			fprintf(stderr, "Unknown APDU case %d\n", ac->apdu_case);
			break;
		}
	}

	/* take some decisions... */
	switch (ac->apdu_case) {
	case 1: /* P3 == 0, No Lc/Le */
		/* send C-APDU to card */
		/* receive SW from card, forward to reader */
		rc |= APDU_ACT_TX_CAPDU_TO_CARD;
		break;
	case 2: /* P3 == Le */
		/* send C-APDU to card */
		/* receive Le bytes + SW from card, forward to reader */
		rc |= APDU_ACT_TX_CAPDU_TO_CARD;
		break;
	case 3: /* P3 = Lc */
		if (!is_dc_complete(ac)) {
			/* send PB + read further Lc bytes from reader */
			rc |= APDU_ACT_RX_MORE_CAPDU_FROM_READER;
		} else {
			/* send C-APDU to card */
			/* receive SW from card, forward to reader */
			rc |= APDU_ACT_TX_CAPDU_TO_CARD;
		}
		break;
	case 4: /* P3 = Lc; SW with Le */
		if (!is_dc_complete(ac)) {
			/* send PB + read further Lc bytes from reader */
			rc |= APDU_ACT_RX_MORE_CAPDU_FROM_READER;
		} else {
			/* send C-APDU to card */
			/* receive SW from card, forward to reader */
			rc |= APDU_ACT_TX_CAPDU_TO_CARD;
		}
		break;
	case 0:
	default:
		fprintf(stderr, "Unknown APDU case %d\n", ac->apdu_case);
		break;
	}

	dump_apdu_ctx(ac);

	return rc;
}
