FreeCalypso > hg > fc-sim-sniff
view sw/sniff-dec/command.c @ 52:cbfcc480d61b
fpga build: migrate to yosys-tee wrapper
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 03 Oct 2023 18:17:58 +0000 |
parents | b0524d1dc6ef |
children | 5268246520de |
line wrap: on
line source
/* * Here we implement decoding of command APDU exchanges. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "state.h" extern char linebuf[]; extern int lineno; extern unsigned rx_byte; extern int state; static char cmd_start_timestamp[18]; static int cmd_start_line; static char data_start_timestamp[18]; static int data_start_line; static char sw1_timestamp[18]; static int sw1_line; static u_char cmd_hdr[5]; static unsigned hdr_byte_count; static unsigned data_total, data_sofar, data_thistime; static u_char data_buf[256], sw1; void start_cmd_header() { strcpy(cmd_start_timestamp, linebuf); cmd_start_line = lineno; cmd_hdr[0] = rx_byte; hdr_byte_count = 1; state = STATE_CMD_HDR; } static void print_cmd_hdr() { unsigned n; printf("%s line %d: CMD", cmd_start_timestamp, cmd_start_line); for (n = 0; n < 5; n++) printf(" %02X", cmd_hdr[n]); putchar('\n'); } void cmd_hdr_byte_in() { cmd_hdr[hdr_byte_count++] = rx_byte; if (hdr_byte_count < 5) return; print_cmd_hdr(); if ((cmd_hdr[1] & 0xF0) == 0x60 || (cmd_hdr[1] & 0xF0) == 0x90) { printf(" ERROR: INS byte is invalid!\n"); state = STATE_ERROR; return; } if (cmd_hdr[4]) data_total = cmd_hdr[4]; else data_total = 256; data_sofar = 0; state = STATE_CMD_PROC; } static void print_data() { unsigned n; printf("%s line %d: DATA\n", data_start_timestamp, data_start_line); for (n = 0; n < data_sofar; n++) { printf(" %02X", data_buf[n]); if ((n & 15) == 15 || n == data_sofar - 1) putchar('\n'); } } static void handle_sw1() { strcpy(sw1_timestamp, linebuf); sw1_line = lineno; sw1 = rx_byte; if (data_sofar) print_data(); state = STATE_CMD_SW; } void handle_ack(single) { if (data_sofar >= data_total) { printf("%s line %d: ERROR: ACK for more data than possible\n", linebuf, lineno); state = STATE_ERROR; return; } if (!data_sofar) { strcpy(data_start_timestamp, linebuf); data_start_line = lineno; } if (single) data_thistime = 1; else data_thistime = data_total - data_sofar; state = STATE_CMD_DATA; } void cmd_proc_byte_in() { if (rx_byte == 0x60) return; if ((rx_byte & 0xF0) == 0x60 || (rx_byte & 0xF0) == 0x90) { handle_sw1(); return; } if (rx_byte == cmd_hdr[1]) { handle_ack(0); return; } if (rx_byte == (cmd_hdr[1] ^ 0xFF)) { handle_ack(1); return; } printf("%s line %d: ERROR: invalid procedure byte\n", linebuf, lineno); state = STATE_ERROR; } void cmd_data_byte_in() { data_buf[data_sofar++] = rx_byte; data_thistime--; if (data_thistime) return; state = STATE_CMD_PROC; } void cmd_sw2_byte_in() { printf("%s line %d: SW %02X %02X\n", sw1_timestamp, sw1_line, sw1, rx_byte); state = STATE_READY_FOR_CMD; }