-
Notifications
You must be signed in to change notification settings - Fork 0
/
xmodem.c
116 lines (98 loc) · 1.52 KB
/
xmodem.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <stdlib.h>
#include "stm32f334x8.h"
#include "system.h"
#include "xmodem.h"
char
xmodem_cancel(struct xmodem_state *s)
{
s->state = XMODEM_STATE_CANCEL;
s->seq = 1;
s->idx = 0;
return 'C';
}
char
xmodem_ingest(struct xmodem_state *s, char c)
{
char ret = 0;
switch (s->idx) {
case 0:
switch (c) {
case 0x1:
// SOH
s->state = XMODEM_STATE_SOH;
s->crc = 0;
s->packetpos = 0;
break;
case 0x4:
// End of Transmission
s->state = XMODEM_STATE_EOT;
goto complete;
break;
case 0x17:
// End of Transmission Block
s->state = XMODEM_STATE_EOB;
goto complete;
break;
case 0x18:
// Cancel
return xmodem_cancel(s);
break;
default:
goto nack;
}
break;
case 1:
s->state = XMODEM_STATE_RECV;
// Sequence
if (c != s->seq) {
goto nack;
}
break;
case 2:
// Sequence Recip
if (c != 0xFF - (s->seq)) {
goto nack;
}
break;
case 131:
// CRC
if (c != ((s->crc >> 8) & 0xFF)) {
goto nack;
}
break;
case 132:
if (c != (s->crc & 0xFF)) {
goto nack;
}
s->seq += 1;
s->state = XMODEM_STATE_EOP;
// XXX - Use the valid packet.
goto ack;
break;
default:
// Payload
s->crc ^= ((int)c) << 8;
for (int i = 0; i < 8; i++) {
if (s->crc & 0x8000) {
s->crc = (s->crc << 1) ^ 0x1021;
} else {
s->crc = s->crc << 1;
}
}
s->packet[s->packetpos] = c;
s->packetpos += 1;
break;
}
s->idx += 1;
return 0;
nack:
ret = 0x15;
goto next;
complete:
s->seq = 1;
ack:
ret = 0x06;
next:
s->idx = 0;
return ret;
}