#ifndef DK_CHANNEL_H
#define DK_CHANNEL_H

#include <stdio.h>

#include "dk_apdu.h"
#include "dk_common.h"
#include "sec_apdu.h"
#include "sec_EseStatus.h"

/**
 * Simple channel structure containing destination applet 
 * and channel id.
 */
typedef struct channel {
    uint8_t id;
    byte    aid[MAX_AID_SIZE];
    size_t  aid_len;
    byte    is_open;
} __attribute__ ((packed)) channel_t;

/**
 * Opens a communication channel to an eSE applet
 * 
 * @param channel A structure that holds the channel information
 * @param buflen length of buf.
 * @param rpdu rpdu to which eSE response will be written to.
 * @param c channel over which transmission takes place.
 * 
 * @return DK_SUCCESS on success; different values on error.
 */
DK_Result open_channel(channel_t *channel, secEse_7816_rpdu_t *rpdu);

/**
 * Transmit a buffer of bytes to an eSE thought an previously opened channel.
 * 
 * @param buf cpdu byte array to be sent.
 * @param buflen length of buf.
 * @param rpdu rpdu to which eSE response will be written to.
 * @param c channel over which transmission takes place.
 * 
 * @return DK_SUCCESS on success; different values on error.
 */
DK_Result transmit(
    byte* buf,
    size_t buflen,
    secEse_7816_rpdu_t* rpdu,
    channel_t* channel);

DK_Result close_channel(channel_t *channel);

#ifdef DK_DEBUG
extern DK_Result (*test_close_channel)(channel_t *channel);
extern DK_Result (*test_open_channel)(channel_t *channel, secEse_7816_rpdu_t *rpdu);
extern DK_Result (*test_transmit)(byte* buf, size_t buflen, secEse_7816_rpdu_t* rpdu, channel_t* channel);
DK_Result mock_open_channel(channel_t *channel, secEse_7816_rpdu_t *rpdu);
DK_Result mock_close_channel(channel_t *channel);
DK_Result mock_transmit_send_apdu(byte* buf, size_t buflen, secEse_7816_rpdu_t* rpdu, channel_t* channel);
DK_Result mock_transmit_open_secure_channel(byte* buf, size_t buflen, secEse_7816_rpdu_t* rpdu, channel_t* channel);
DK_Result mock_transmit_full(byte* buf, size_t buflen, secEse_7816_rpdu_t* rpdu, channel_t* channel);
DK_Result dump_channel(channel_t *channel);
#endif

#endif