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 } |