FreeCalypso > hg > fc-sim-sniff
comparison sw/sniff-dec/dispatch.c @ 41:118a12e9483b
simtrace3-sniff-dec started
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 31 Aug 2023 08:46:23 +0000 |
| parents | |
| children | 74330513121e |
comparison
equal
deleted
inserted
replaced
| 40:510bef2b2000 | 41:118a12e9483b |
|---|---|
| 1 /* | |
| 2 * Dispatching received FPGA words based on the current state. | |
| 3 */ | |
| 4 | |
| 5 #include <sys/types.h> | |
| 6 #include <stdio.h> | |
| 7 #include <stdlib.h> | |
| 8 #include "state.h" | |
| 9 | |
| 10 extern char linebuf[]; | |
| 11 extern int lineno; | |
| 12 extern unsigned fpga_word; | |
| 13 | |
| 14 extern u_char parity_table[256]; | |
| 15 extern u_char inverse_coding_table[256]; | |
| 16 | |
| 17 int state; | |
| 18 int inverse_conv; | |
| 19 unsigned rx_byte; | |
| 20 | |
| 21 #define PREFIX "%s line %d: " | |
| 22 | |
| 23 static void | |
| 24 handle_rst_change() | |
| 25 { | |
| 26 if (fpga_word & 0x4000) { | |
| 27 printf(PREFIX "RST high, card session begin\n", | |
| 28 linebuf, lineno); | |
| 29 state = STATE_ATR_TS; | |
| 30 atr_begin(); | |
| 31 } else { | |
| 32 printf(PREFIX "RST low, card session end\n", linebuf, lineno); | |
| 33 state = STATE_RSTLOW; | |
| 34 } | |
| 35 } | |
| 36 | |
| 37 static int | |
| 38 byte_prelim_checks() | |
| 39 { | |
| 40 if (!(fpga_word & 0x4000)) { | |
| 41 printf(PREFIX "ERROR: char Rx with RST low\n", linebuf, lineno); | |
| 42 return 1; | |
| 43 } | |
| 44 if (fpga_word & 0x0200) { | |
| 45 printf(PREFIX "ERROR: start bit midpoint sampled high\n", | |
| 46 linebuf, lineno); | |
| 47 return 1; | |
| 48 } | |
| 49 if (fpga_word & 0x0400) { | |
| 50 printf(PREFIX "ISO 7816-3 section 7.3 error signal\n", | |
| 51 linebuf, lineno); | |
| 52 return 1; | |
| 53 } | |
| 54 return 0; | |
| 55 } | |
| 56 | |
| 57 static int | |
| 58 check_parity() | |
| 59 { | |
| 60 unsigned expect_par; | |
| 61 | |
| 62 expect_par = (parity_table[fpga_word & 0xFF] ^ inverse_conv) << 8; | |
| 63 if ((fpga_word & 0x100) != expect_par) { | |
| 64 printf(PREFIX "ERROR: bad character parity\n", linebuf, lineno); | |
| 65 state = STATE_ERROR; | |
| 66 return 1; | |
| 67 } | |
| 68 return 0; | |
| 69 } | |
| 70 | |
| 71 static void | |
| 72 extract_rx_byte() | |
| 73 { | |
| 74 if (inverse_conv) | |
| 75 rx_byte = inverse_coding_table[fpga_word & 0xFF]; | |
| 76 else | |
| 77 rx_byte = fpga_word & 0xFF; | |
| 78 } | |
| 79 | |
| 80 void | |
| 81 process_fpga_word() | |
| 82 { | |
| 83 if (fpga_word & 0x8000) { | |
| 84 handle_rst_change(); | |
| 85 return; | |
| 86 } | |
| 87 if (state == STATE_ERROR) | |
| 88 return; | |
| 89 if (byte_prelim_checks()) { | |
| 90 state = STATE_ERROR; | |
| 91 return; | |
| 92 } | |
| 93 switch (state) { | |
| 94 case STATE_UNDEF: | |
| 95 printf(PREFIX "ERROR: char Rx without preceding RST high\n", | |
| 96 linebuf, lineno); | |
| 97 state = STATE_ERROR; | |
| 98 return; | |
| 99 case STATE_RSTLOW: | |
| 100 printf(PREFIX "ERROR: char Rx after RST low\n", | |
| 101 linebuf, lineno); | |
| 102 state = STATE_ERROR; | |
| 103 return; | |
| 104 case STATE_ATR_TS: | |
| 105 if ((fpga_word & 0x1FF) == 0x13B) { | |
| 106 printf(PREFIX "TS sets direct coding convention\n", | |
| 107 linebuf, lineno); | |
| 108 inverse_conv = 0; | |
| 109 rx_byte = 0x3B; | |
| 110 atr_byte_in(); | |
| 111 state = STATE_ATR_CONT; | |
| 112 } else if ((fpga_word & 0x1FF) == 0x103) { | |
| 113 printf(PREFIX "TS sets inverse coding convention\n", | |
| 114 linebuf, lineno); | |
| 115 inverse_conv = 1; | |
| 116 rx_byte = 0x3F; | |
| 117 atr_byte_in(); | |
| 118 state = STATE_ATR_CONT; | |
| 119 } else { | |
| 120 printf(PREFIX "ERROR: invalid char after RST high\n", | |
| 121 linebuf, lineno); | |
| 122 state = STATE_ERROR; | |
| 123 } | |
| 124 return; | |
| 125 case STATE_ATR_CONT: | |
| 126 if (check_parity()) | |
| 127 return; | |
| 128 extract_rx_byte(); | |
| 129 atr_byte_in(); | |
| 130 return; | |
| 131 case STATE_READY_FOR_CMD: | |
| 132 if (check_parity()) | |
| 133 return; | |
| 134 extract_rx_byte(); | |
| 135 if (rx_byte == 0xFF) | |
| 136 start_pps_msg(); | |
| 137 else | |
| 138 start_cmd_header(); | |
| 139 return; | |
| 140 case STATE_PPS_MSG: | |
| 141 if (check_parity()) | |
| 142 return; | |
| 143 extract_rx_byte(); | |
| 144 pps_byte_in(); | |
| 145 return; | |
| 146 default: | |
| 147 fprintf(stderr, "BUG in top state machine: invalid state\n"); | |
| 148 abort(); | |
| 149 } | |
| 150 } |
