/* libosmosim test application - currently simply dumps a USIM */
/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
 * 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.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/sim/sim.h>
#include <osmocom/gsm/tlv.h>


/* FIXME: this needs to be moved to card_fs_uicc.c */

/* 11.1.1 */
static struct msgb *_select_file(struct osim_chan_hdl *st, uint8_t p1, uint8_t p2,
			const uint8_t *data, uint8_t data_len)
{
	struct msgb *msg, *resp;
	char *dst;

	msg = osim_new_apdumsg(0x00, 0xA4, p1, p2, data_len, 256);
	dst = msgb_put(msg, data_len);
	memcpy(dst, data, data_len);

	osim_transceive_apdu(st, msg);

	return msg;
}

/* 11.1.1 */
static struct msgb *select_adf(struct osim_chan_hdl *st, const uint8_t *adf, uint8_t adf_len)
{
	int sw;

	return _select_file(st, 0x04, 0x04, adf,adf_len);
}

/* 11.1.1 */
static struct msgb *select_file(struct osim_chan_hdl *st, uint16_t fid)
{
	uint16_t cfid = htons(fid);

	return _select_file(st, 0x00, 0x04, (uint8_t *)&cfid, 2);
}

/* 11.1.9 */
static int verify_pin(struct osim_chan_hdl *st, uint8_t pin_nr, uint8_t *pin)
{
	struct msgb *msg;
	char *pindst;
	int sw;

	if (strlen(pin) > 8)
		return -EINVAL;

	msg = osim_new_apdumsg(0x00, 0x20, 0x00, pin_nr, 8, 0);
	pindst = msgb_put(msg, 8);
	memset(pindst, 0xFF, 8);
	strncpy(pindst, pin, strlen(pin));

	return osim_transceive_apdu(st, msg);
}

/* 11.1.5 */
static struct msgb *read_record_nr(struct osim_chan_hdl *st, uint8_t rec_nr, uint16_t rec_size)
{
	struct msgb *msg;

	msg = osim_new_apdumsg(0x00, 0xB2, rec_nr, 0x04, 0, rec_size);

	osim_transceive_apdu(st, msg);

	return msg;
}

/* 11.1.6 */
static struct msgb *update_record_nr(struct osim_chan_hdl *st, uint8_t rec_nr,
				     const uint8_t *data, uint16_t rec_size)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = osim_new_apdumsg(0x00, 0xDC, rec_nr, 0x04, rec_size, 0);
	cur = msgb_put(msg, rec_size);
	memcpy(cur, data, rec_size);

	osim_transceive_apdu(st, msg);

	return msg;
}

/* 11.1.3 */
static struct msgb *read_binary(struct osim_chan_hdl *st, uint16_t offset, uint16_t len)
{
	struct msgb *msg;

	if (offset > 0x7fff || len > 256)
		return NULL;

	msg = osim_new_apdumsg(0x00, 0xB0, offset >> 8, offset & 0xff, 0, len & 0xff);

	osim_transceive_apdu(st, msg);

	return msg;
}

/* 11.1.4 */
static struct msgb *update_binary(struct osim_chan_hdl *st, uint16_t offset,
				  const uint8_t *data, uint16_t len)
{
	struct msgb *msg;
	uint8_t *cur;

	if (offset > 0x7fff || len > 256)
		return NULL;

	msg = osim_new_apdumsg(0x00, 0xD6, offset >> 8, offset & 0xff, len & 0xff, 0);
	cur = msgb_put(msg, len);
	memcpy(cur, data, len);

	osim_transceive_apdu(st, msg);

	return msg;
}



static int dump_fcp_template(struct tlv_parsed *tp)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(tp->lv); i++) {
		if (TLVP_PRESENT(tp, i))
			printf("Tag 0x%02x (%s): %s\n", i,
				get_value_string(ts102221_fcp_vals, i),
				osmo_hexdump(TLVP_VAL(tp, i), TLVP_LEN(tp, i)));
	}

	return 0;
}

static int dump_fcp_template_msg(struct msgb *msg)
{
	struct tlv_parsed tp;
	int rc;

	rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-4, 0, 0);
	if (rc < 0)
		return rc;

	return dump_fcp_template(&tp);
}

struct osim_fcp_fd_decoded {
	enum osim_file_type type;
	enum osim_ef_type ef_type;
	uint16_t rec_len;
	uint8_t num_rec;
};

static const enum osim_file_type iso2ftype[8] = {
	[0] = TYPE_EF,
	[1] = TYPE_EF_INT,
	[7] = TYPE_DF,
};

static const enum osim_ef_type iso2eftype[8] = {
	[1] = EF_TYPE_TRANSP,
	[2] = EF_TYPE_RECORD_FIXED,
	[6] = EF_TYPE_RECORD_CYCLIC,
};

static int osim_fcp_fd_decode(struct osim_fcp_fd_decoded *ofd, const uint8_t *fcp, int fcp_len)
{
	memset(ofd, 0, sizeof(*ofd));

	if (fcp_len != 2 && fcp_len != 5)
		return -EINVAL;

	ofd->type = iso2ftype[(fcp[0] >> 3) & 7];
	if (ofd->type != TYPE_DF)
		ofd->ef_type = iso2eftype[fcp[0] & 7];

	if (fcp[1] != 0x21)
		return -EINVAL;

	if (fcp_len >= 5) {
		ofd->rec_len = ntohs(*(uint16_t *)(fcp+2));
		ofd->num_rec = fcp[4];
	}

	return 0;
}

extern struct osim_card_profile *osim_cprof_usim(void *ctx);

static struct msgb *try_select_adf_usim(struct osim_chan_hdl *st)
{
	struct tlv_parsed tp;
	struct osim_fcp_fd_decoded ofd;
	struct msgb *msg, *msg2;
	uint8_t *cur;
	int rc, i;

	msg = select_file(st, 0x2f00);
	rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-4, 0, 0);
	if (rc < 0)
		return NULL;

	dump_fcp_template(&tp);

	if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_DESC) ||
	    TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC) < 5) {
		msgb_free(msg);
		return NULL;
	}

	rc = osim_fcp_fd_decode(&ofd, TLVP_VAL(&tp, UICC_FCP_T_FILE_DESC),
				TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC));
	if (rc < 0) {
		msgb_free(msg);
		return NULL;
	}

	if (ofd.type != TYPE_EF || ofd.ef_type != EF_TYPE_RECORD_FIXED) {
		msgb_free(msg);
		return NULL;
	}

	msgb_free(msg);

	printf("ofd rec_len = %u, num_rec = %u\n", ofd.rec_len, ofd.num_rec);

	for (i = 0; i < ofd.num_rec; i++) {
		msg = read_record_nr(st, i+1, ofd.rec_len);
		if (!msg)
			return NULL;

		cur = msgb_apdu_de(msg);
		if (msgb_apdu_le(msg) < 5) {
			msgb_free(msg);
			return NULL;
		}

		if (cur[0] != 0x61 || cur[1] < 0x03 || cur[1] > 0x7f ||
		    cur[2] != 0x4F || cur[3] < 0x01 || cur[3] > 0x10) {
			msgb_free(msg);
			return NULL;
		}

		/* FIXME: actually check if it is an AID that we support, or
		 * iterate until we find one that we support */

		msg2 = select_adf(st, cur+4, cur[3]);

		/* attach the USIM profile, FIXME: do this based on AID match */
		st->card->prof = osim_cprof_usim(st->card);
		st->cwd = osim_file_find_name(st->card->prof->mf, "ADF.USIM");

		msgb_free(msg);

		return msg2;
	}

	return NULL;
}

static int dump_file(struct osim_chan_hdl *chan, uint16_t fid)
{
	struct tlv_parsed tp;
	struct osim_fcp_fd_decoded ffdd;
	struct msgb *msg, *rmsg;
	int rc, i, offset;

	msg = select_file(chan, fid);
	if (!msg) {
		printf("Unable to select file\n");
		return -EIO;
	}
	if (msgb_apdu_sw(msg) != 0x9000) {
		printf("status 0x%04x selecting file\n", msgb_apdu_sw(msg));
		goto out;
	}

	rc = tlv_parse(&tp, &ts102221_fcp_tlv_def, msgb_apdu_de(msg)+2, msgb_apdu_le(msg)-4, 0, 0);
	if (rc < 0) {
		printf("Unable to parse FCP\n");
		goto out;
	}

	if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_DESC) ||
	    TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC) < 2) {
		printf("No file descriptor present ?!?\n");
		goto out;
	}

	rc = osim_fcp_fd_decode(&ffdd, TLVP_VAL(&tp, UICC_FCP_T_FILE_DESC),
				TLVP_LEN(&tp, UICC_FCP_T_FILE_DESC));
	if (rc < 0) {
		printf("Unable to decode File Descriptor\n");
		goto out;
	}

	if (ffdd.type != TYPE_EF) {
		printf("File Type != EF\n");
		goto out;
	}

	printf("EF type: %u\n", ffdd.ef_type);

	switch (ffdd.ef_type) {
	case EF_TYPE_RECORD_FIXED:
		for (i = 0; i < ffdd.num_rec; i++) {
			rmsg = read_record_nr(chan, i+1, ffdd.rec_len);
			if (!msg)
				return -EIO;
			printf("Rec %03u: %s\n", i+1,
				osmo_hexdump(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg)));
		}
		break;
	case EF_TYPE_TRANSP:
		if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_SIZE))
			goto out;
		i = ntohs(*(uint16_t *)TLVP_VAL(&tp, UICC_FCP_T_FILE_SIZE));
		printf("File size: %d bytes\n", i);

		for (offset = 0; offset < i-1; ) {
			uint16_t remain_len = i - offset;
			uint16_t read_len = OSMO_MIN(remain_len, 256);
			rmsg = read_binary(chan, offset, read_len);
			if (!msg)
				return -EIO;
			offset += read_len;
			printf("Content: %s\n",
				osmo_hexdump(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg)));
		}
		break;
	default:
		goto out;
	}

out:
	msgb_free(msg);
	return -EINVAL;
}

int main(int argc, char **argv)
{
	struct osim_reader_hdl *reader;
	struct osim_card_hdl *card;
	struct osim_chan_hdl *chan;
	struct msgb *msg;
	int rc;

	reader = osim_reader_open(0, NULL);
	if (!reader)
		exit(1);
	card = osim_card_open(reader);
	if (!card)
		exit(2);
	chan = llist_entry(card->channels.next, struct osim_chan_hdl, list);
	if (!chan)
		exit(3);

	msg = try_select_adf_usim(chan);
	if (!msg || msgb_apdu_sw(msg) != 0x9000)
		exit(4);
	dump_fcp_template_msg(msg);
	msgb_free(msg);

	msg = select_file(chan, 0x6fc5);
	dump_fcp_template_msg(msg);
	msgb_free(msg);

	verify_pin(chan, 1, "1653");

	msg = select_file(chan, 0x6f06);
	dump_fcp_template_msg(msg);
	msgb_free(msg);

	{
		struct osim_file_desc *ofd;
		llist_for_each_entry(ofd, &chan->cwd->child_list, list) {
			struct msgb *m;
			printf("\n\n================ %s (%s) ==================\n",
				ofd->short_name, ofd->long_name);

			m = select_file(chan, ofd->fid);
			dump_fcp_template_msg(m);
			msgb_free(m);
			dump_file(chan, ofd->fid);
		}
	}

	exit(0);
}
