diff options
Diffstat (limited to 'firmware/src/simtrace')
| -rw-r--r-- | firmware/src/simtrace/iso7816_uart.c | 33 | ||||
| -rw-r--r-- | firmware/src/simtrace/iso7816_uart.h | 2 | ||||
| -rw-r--r-- | firmware/src/simtrace/main_simtrace.c | 25 | 
3 files changed, 58 insertions, 2 deletions
diff --git a/firmware/src/simtrace/iso7816_uart.c b/firmware/src/simtrace/iso7816_uart.c index 09a7aa0..4169ab9 100644 --- a/firmware/src/simtrace/iso7816_uart.c +++ b/firmware/src/simtrace/iso7816_uart.c @@ -106,6 +106,8 @@ struct iso7816_3_handle {  	int rctx_must_be_sent;  	struct req_ctx *rctx; + +	struct simtrace_stats stats;  };  struct iso7816_3_handle isoh; @@ -123,6 +125,20 @@ static const u_int8_t di_table[] = {  	12, 20, 2, 4, 8, 16, 32, 64,  }; +void iso_uart_stats_dump(void) +{ +	DEBUGPCRF("no_rctx: %u, rctx_sent: %u, rst: %u, pps: %u, bytes: %u, " +		"parity_err: %u, frame_err: %u, overrun:%u", +		isoh.stats.no_rctx, isoh.stats.rctx_sent, isoh.stats.rst, +		isoh.stats.pps, isoh.stats.bytes, isoh.stats.parity_err, +		isoh.stats.frame_err, isoh.stats.overrun); +} + +struct simtrace_stats *iso_uart_stats_get(void) +{ +	return &isoh.stats; +} +  /* compute the F/D ratio based on Fi and Di values */  static int compute_fidi_ratio(u_int8_t fi, u_int8_t di)  { @@ -186,6 +202,8 @@ static void send_rctx(struct iso7816_3_handle *ih)  	memset(&ih->sh, 0, sizeof(ih->sh));  	ih->rctx = NULL; + +	ih->stats.rctx_sent++;  } @@ -476,6 +494,8 @@ static void process_byte(struct iso7816_3_handle *ih, u_int8_t byte)  	int new_state = -1;  	struct req_ctx *rctx; +	ih->stats.bytes++; +  	if (!ih->rctx)  		refill_rctx(ih); @@ -489,6 +509,7 @@ static void process_byte(struct iso7816_3_handle *ih, u_int8_t byte)  	case ISO7816_S_WAIT_APDU:  		if (byte == 0xff) {  			new_state = process_byte_pts(ih, byte); +			ih->stats.pps++;  			goto out_silent;  		}  	case ISO7816_S_IN_APDU: @@ -506,7 +527,8 @@ static void process_byte(struct iso7816_3_handle *ih, u_int8_t byte)  	rctx = ih->rctx;  	if (!rctx) { -		DEBUGPCR("==> Lost byte, missing rctx"); +		//DEBUGPCR("==> Lost byte, missing rctx"); +		ih->stats.no_rctx++;  		return;  	} @@ -562,6 +584,13 @@ static __ramfunc void usart_irq(void)  		//DEBUGP("NER=%02x ", nb_err);  		/* clear the status */  		usart->US_CR |= AT91C_US_RSTSTA; + +		if (csr & AT91C_US_PARE) +			isoh.stats.parity_err++; +		if (csr & AT91C_US_FRAME) +			isoh.stats.frame_err++; +		if (csr & AT91C_US_OVRE) +			isoh.stats.overrun++;  	}  	if (csr & AT91C_US_INACK) { @@ -579,6 +608,7 @@ static void reset_pin_irq(u_int32_t pio)  	} else {  		DEBUGPCR("RST");  		set_state(&isoh, ISO7816_S_WAIT_ATR); +		isoh.stats.rst++;  	}  } @@ -647,6 +677,7 @@ void iso_uart_init(void)  	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, SIMTRACE_PIO_IO, SIMTRACE_PIO_CLK);  	AT91F_PIO_CfgInput(AT91C_BASE_PIOA, SIMTRACE_PIO_nRST); +	/* Configure Interrupt */  	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US0,  			      OPENPCD_IRQ_PRIO_USART,  			      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &usart_irq); diff --git a/firmware/src/simtrace/iso7816_uart.h b/firmware/src/simtrace/iso7816_uart.h index ed1c898..beb0b23 100644 --- a/firmware/src/simtrace/iso7816_uart.h +++ b/firmware/src/simtrace/iso7816_uart.h @@ -1,4 +1,6 @@ +struct simtrace_stats *iso_uart_stats_get(void); +void iso_uart_stats_dump(void);  void iso_uart_dump(void);  void iso_uart_rst(unsigned int state);  void iso_uart_rx_mode(void); diff --git a/firmware/src/simtrace/main_simtrace.c b/firmware/src/simtrace/main_simtrace.c index 0f2bfc5..6f82d96 100644 --- a/firmware/src/simtrace/main_simtrace.c +++ b/firmware/src/simtrace/main_simtrace.c @@ -33,6 +33,7 @@  #include <simtrace/tc_etu.h>  #include <simtrace/iso7816_uart.h>  #include <simtrace/sim_switch.h> +#include <simtrace_usb.h>  enum simtrace_md {  	SIMTRACE_MD_OFF, @@ -117,6 +118,24 @@ static void simtrace_set_mode(enum simtrace_md mode)  	}  } +static int simtrace_usb_in(struct req_ctx *rctx) +{ +	struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->data[0]; +	struct simtrace_stats *stats_in; +	struct simtrace_stats *stats = (struct simtrace_stats *) poh->data; + +	switch (poh->cmd) { +	case SIMTRACE_MSGT_STATS: +		stats_in = iso_uart_stats_get(); +		memcpy(stats, stats_in, sizeof(*stats)); +		req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING); +		break; +	default: +		req_ctx_set_state(rctx, RCTX_STATE_FREE); +		break; +	} +} +  void _init_func(void)  {  	/* low-level hardware initialization */ @@ -126,6 +145,7 @@ void _init_func(void)  	sim_switch_init();  	usbtest_init(); +	usb_hdlr_register(&simtrace_usb_in, OPENPCD_CMD_CLS_ADC);  	/* high-level protocol */  	//opicc_usbapi_init(); @@ -150,7 +170,7 @@ static void help(void)  		 "l: set nRST to low (active)\r\n"  		 "h: set nRST to high (inactive)\r\n"  		 "o: set nRST to input\r\n" -		 "r: set Rx mode for UART\r\n" +		 "t: ISO UART statistics\r\n"  		 "s: disconnect SIM bus switch\r\n"  		 "S: connect SIM bus switch\r\n");  } @@ -167,6 +187,9 @@ int _main_dbgu(char key)  	case 'S':  		simtrace_set_mode(SIMTRACE_MD_SNIFFER);  		break; +	case 't': +		iso_uart_stats_dump(); +		break;  	case 'r':  		iso_uart_rx_mode();  		break;  | 
