Attempt to implement working simcard emulator

The BUFLEN is fixed 5 bytes now, which has to be increased.
A timeout has to be implemented, which is smaller than max_waittime.
If the timeout is triggered, the data received in the buffer so far
should be sent to the host computer which is responsible for generating
a response. Without the timeout the max_waittime of the phone would
expire and it would repeat sending the command, so that we do not
have atomary messages anymore.
This commit is contained in:
Christina Quast
2015-03-18 18:41:19 +01:00
parent 69734e9ad9
commit ce296b9def
3 changed files with 84 additions and 37 deletions

View File

@@ -107,13 +107,19 @@ static const Pin pinPhoneRST = ISO7816_PHONE_RST;
/** Flip flop for send and receive char */
#define USART_SEND 0
#define USART_RCV 1
#define NONE 9
#define RST_RCVD 10
#define WAIT_CMD_PHONE 11
#define WAIT_CMD_PC 12
#define WAIT_ATR 13
/*-----------------------------------------------------------------------------
* Internal variables
*-----------------------------------------------------------------------------*/
/** Variable for state of send and receive froom USART */
static uint8_t StateUsartGlobal = USART_RCV;
extern uint32_t char_stat;
static uint32_t state;
extern uint8_t rcvdChar;
/*-----------------------------------------------------------------------------
@@ -122,11 +128,12 @@ extern uint8_t rcvdChar;
#define RESET 'R'
static void ISR_PhoneRST( const Pin *pPin)
{
int msg = RESET;
printf("+++ Int!!\n\r");
USBD_Write( INT, &msg, 1, 0, 0 );
if (state == NONE) {
state = RST_RCVD;
}
// FIXME: What to do on reset?
// FIXME: It seems like the phone is constantly sending a lot of these RSTs
// PIO_DisableIt( &pinPhoneRST ) ;
}
@@ -245,7 +252,7 @@ void Phone_Master_Init( void ) {
/* Configure ISO7816 driver */
// FIXME: PIO_Configure(pPwr, PIO_LISTSIZE( pPwr ));
state = NONE;
// FIXME: Or do I need to call VBUS_CONFIGURE() here instead, which will call USBD_Connect() later?
@@ -267,53 +274,93 @@ void Phone_Master_Init( void ) {
}
void send_ATR(uint8_t *ATR, uint8_t len)
void send_ATR(uint8_t *ATR, uint8_t status, uint32_t transferred, uint32_t remaining)
{
int i;
TRACE_INFO("Send %x %x %x", ATR[0], ATR[1], ATR[2]);
for ( i = 0; i < len; i++ ) {
TRACE_INFO("Send %x %x %x.. %x", ATR[0], ATR[1], ATR[2], ATR[transferred-1]);
for ( i = 0; i < transferred; i++ ) {
_ISO7816_SendChar(*(ATR++));
}
state = WAIT_CMD_PHONE;
}
void HandleIncommingData( void *pArg, uint8_t status, uint32_t transferred, uint32_t remaining)
void sendResponse( uint8_t *pArg, uint8_t status, uint32_t transferred, uint32_t remaining)
{
TRACE_INFO("HandleIncommingData ,stat: %X, transf: %x, remain: %x", status, transferred, remaining);
int i;
TRACE_INFO("sendResponse, stat: %X, transf: %x, remain: %x", status, transferred, remaining);
TRACE_INFO("Resp: %x %x %x .. %x", pArg[0], pArg[1], pArg[2], pArg[transferred-1]);
uint8_t ans[MAX_ANSWER_SIZE];
if (status == USBD_STATUS_SUCCESS) {
if (((uint8_t *)pArg)[0] == 0x3B) {
send_ATR(pArg, transferred);
return;
} else {
ISO7816_XfrBlockTPDU_T0(pArg, ans, transferred);
}
for ( i = 0; i < transferred; i++ ) {
_ISO7816_SendChar(*(pArg++));
}
TRACE_INFO("Ans: %x %x %x", ans[0], ans[1], ans[2]);
state = WAIT_CMD_PHONE;
}
#define PR TRACE_INFO
extern ring_buffer buf;
#define MAX_MSG_LEN 64
#define PR printf
void wait_for_response(uint8_t pBuffer[]) {
int ret = 0;
// uint8_t msg[] = {0xa0, 0xa4, 0x0, 0x0, 0x2};
if (rcvdChar != 0) {
printf(" rr ");
/* DATA_IN for host side is data_out for simtrace side */
/* FIXME: Performancewise sending a USB packet for every byte is a disaster */
PR("b:%x %x %x %x %x.\n\r", buf.buf[0], buf.buf[1],buf.buf[2], buf.buf[3], buf.buf[4]);
USBD_Write( DATAIN, buf.buf, BUFLEN, 0, 0 );
//USBD_Write( DATAIN, msg, BUFLEN, 0, 0 );
rcvdChar = 0;
if ((ret = USBD_Read(DATAOUT, pBuffer, MAX_MSG_LEN, (TransferCallback)&sendResponse, pBuffer)) == USBD_STATUS_SUCCESS) {
TRACE_INFO("Reading started sucessfully (wait_resp)");
state = WAIT_CMD_PC;
} else {
TRACE_INFO("USB Error: %X", ret);
}
}
}
// Sniffed Phone to SIM card communication:
// phone > sim : RST
// phone < sim : ATR
// phone > sim : A0 A4 00 00 02 (Select File)
// phone < sim : A4 (INS repeated)
// phone > sim : 7F 02 (= ??)
// phone < sim : 9F 16 (9F: success, can deliver 0x16 (=22) byte)
// phone > sim : ?? (A0 C0 00 00 16)
// phone < sim : C0 (INS repeated)
// phone < sim : 00 00 00 00 7F 20 02 00 00 00 00 00 09 91 00 17 04 00 83 8A (data of length 22 -2)
// phone <? sim : 90 00 (OK, everything went fine)
// phone ? sim : 00 (??)
void Phone_run( void )
{
int ret;
uint8_t pBuffer[MAX_MSG_LEN];
int msg = RESET;
// FIXME: remove:
// uint8_t ATR[] = {0x3B, 0x9A, 0x94, 0x00, 0x92, 0x02, 0x75, 0x93, 0x11, 0x00, 0x01, 0x02, 0x02, 0x19};
// send_ATR(ATR, (sizeof(ATR)/sizeof(ATR[0])));
if (rcvdChar != 0) {
/* DATA_IN for host side is data_out for simtrace side */
/* FIXME: Performancewise sending a USB packet for every byte is a disaster */
PR("----- %x %x %x ..\n\r", buf.buf[0], buf.buf[1],buf.buf[2] );
USBD_Write( DATAIN, buf.buf, BUFLEN, 0, 0 );
rcvdChar = 0;
}
if ((ret = USBD_Read(DATAOUT, pBuffer, MAX_MSG_LEN, (TransferCallback)&HandleIncommingData, pBuffer)) == USBD_STATUS_SUCCESS) {
TRACE_INFO("Reading started sucessfully");
TRACE_INFO("Recvd: %X %X %X %X %X", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3], pBuffer[4]);
} else {
// TRACE_INFO("USB Error: %X", ret);
switch (state) {
case RST_RCVD:
USBD_Write( INT, &msg, 1, 0, 0 );
// send_ATR sets state to WAIT_CMD
if ((ret = USBD_Read(DATAOUT, pBuffer, MAX_MSG_LEN, (TransferCallback)&send_ATR, pBuffer)) == USBD_STATUS_SUCCESS) {
TRACE_INFO("Reading started sucessfully (ATR)");
state = WAIT_ATR;
} else {
TRACE_INFO("USB Error: %X", ret);
//FIXME: state = ERR;
}
break;
case WAIT_CMD_PHONE:
wait_for_response(pBuffer);
break;
default:
break;
}
// FIXME: Function Phone_run not implemented yet

View File

@@ -6,7 +6,7 @@
#define DATAIN 2
#define INT 3
#define BUFLEN 64
#define BUFLEN 5
typedef struct ring_buffer
{
uint8_t buf[BUFLEN*2]; // data buffer

View File

@@ -53,9 +53,9 @@ ring_buffer buf = { {0}, 0 };
void buf_push(uint8_t item)
{
buf.buf[buf.idx % (BUFLEN*2)] = item;
buf.buf[buf.idx % (BUFLEN)] = item;
PR("----- Push: %x %x\n\r", buf.idx, buf.buf[buf.idx]);
buf.idx = (buf.idx+1) % (BUFLEN*2);
buf.idx = (buf.idx+1) % (BUFLEN);
}
uint8_t get_buf_start(uint8_t *buf_start)
@@ -144,7 +144,7 @@ void USART1_IrqHandler( void )
PR("%x\n\r", (USART_PHONE->US_RHR) & 0xFF);
} /* else: error occured */
if ((buf.idx % BUFLEN) == 0) {
if ((buf.idx % BUFLEN) == BUFLEN-1) {
rcvdChar = 1;
}