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 }