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 */ /** Flip flop for send and receive char */
#define USART_SEND 0 #define USART_SEND 0
#define USART_RCV 1 #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 * Internal variables
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
/** Variable for state of send and receive froom USART */ /** Variable for state of send and receive froom USART */
static uint8_t StateUsartGlobal = USART_RCV; static uint8_t StateUsartGlobal = USART_RCV;
extern uint32_t char_stat; static uint32_t state;
extern uint8_t rcvdChar; extern uint8_t rcvdChar;
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
@@ -122,11 +128,12 @@ extern uint8_t rcvdChar;
#define RESET 'R' #define RESET 'R'
static void ISR_PhoneRST( const Pin *pPin) static void ISR_PhoneRST( const Pin *pPin)
{ {
int msg = RESET;
printf("+++ Int!!\n\r"); printf("+++ Int!!\n\r");
USBD_Write( INT, &msg, 1, 0, 0 ); if (state == NONE) {
state = RST_RCVD;
}
// FIXME: What to do on reset? // FIXME: What to do on reset?
// FIXME: It seems like the phone is constantly sending a lot of these RSTs
// PIO_DisableIt( &pinPhoneRST ) ; // PIO_DisableIt( &pinPhoneRST ) ;
} }
@@ -245,7 +252,7 @@ void Phone_Master_Init( void ) {
/* Configure ISO7816 driver */ /* Configure ISO7816 driver */
// FIXME: PIO_Configure(pPwr, PIO_LISTSIZE( pPwr )); // 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? // 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; int i;
TRACE_INFO("Send %x %x %x", ATR[0], ATR[1], ATR[2]); TRACE_INFO("Send %x %x %x.. %x", ATR[0], ATR[1], ATR[2], ATR[transferred-1]);
for ( i = 0; i < len; i++ ) { for ( i = 0; i < transferred; i++ ) {
_ISO7816_SendChar(*(ATR++)); _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]; for ( i = 0; i < transferred; i++ ) {
if (status == USBD_STATUS_SUCCESS) { _ISO7816_SendChar(*(pArg++));
if (((uint8_t *)pArg)[0] == 0x3B) {
send_ATR(pArg, transferred);
return;
} else {
ISO7816_XfrBlockTPDU_T0(pArg, ans, transferred);
}
} }
TRACE_INFO("Ans: %x %x %x", ans[0], ans[1], ans[2]); state = WAIT_CMD_PHONE;
} }
#define PR TRACE_INFO
extern ring_buffer buf; extern ring_buffer buf;
#define MAX_MSG_LEN 64 #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 ) void Phone_run( void )
{ {
int ret; int ret;
uint8_t pBuffer[MAX_MSG_LEN]; 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) { switch (state) {
/* DATA_IN for host side is data_out for simtrace side */ case RST_RCVD:
/* FIXME: Performancewise sending a USB packet for every byte is a disaster */ USBD_Write( INT, &msg, 1, 0, 0 );
PR("----- %x %x %x ..\n\r", buf.buf[0], buf.buf[1],buf.buf[2] ); // send_ATR sets state to WAIT_CMD
USBD_Write( DATAIN, buf.buf, BUFLEN, 0, 0 ); if ((ret = USBD_Read(DATAOUT, pBuffer, MAX_MSG_LEN, (TransferCallback)&send_ATR, pBuffer)) == USBD_STATUS_SUCCESS) {
rcvdChar = 0; TRACE_INFO("Reading started sucessfully (ATR)");
} state = WAIT_ATR;
} else {
if ((ret = USBD_Read(DATAOUT, pBuffer, MAX_MSG_LEN, (TransferCallback)&HandleIncommingData, pBuffer)) == USBD_STATUS_SUCCESS) { TRACE_INFO("USB Error: %X", ret);
TRACE_INFO("Reading started sucessfully"); //FIXME: state = ERR;
TRACE_INFO("Recvd: %X %X %X %X %X", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3], pBuffer[4]); }
} else { break;
// TRACE_INFO("USB Error: %X", ret); case WAIT_CMD_PHONE:
wait_for_response(pBuffer);
break;
default:
break;
} }
// FIXME: Function Phone_run not implemented yet // FIXME: Function Phone_run not implemented yet

View File

@@ -6,7 +6,7 @@
#define DATAIN 2 #define DATAIN 2
#define INT 3 #define INT 3
#define BUFLEN 64 #define BUFLEN 5
typedef struct ring_buffer typedef struct ring_buffer
{ {
uint8_t buf[BUFLEN*2]; // data 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) 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]); 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) 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); PR("%x\n\r", (USART_PHONE->US_RHR) & 0xFF);
} /* else: error occured */ } /* else: error occured */
if ((buf.idx % BUFLEN) == 0) { if ((buf.idx % BUFLEN) == BUFLEN-1) {
rcvdChar = 1; rcvdChar = 1;
} }