Mercurial > hg > index.cgi
annotate src/lwwire.c @ 4:56f53e48ab50
Fix off by one bug in protocol extension negotiation.
Arrays are indexed from zero!!!!
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 29 May 2016 21:50:51 -0600 |
parents | e94940ca17e7 |
children | 422f5e8fff85 |
rev | line source |
---|---|
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
1 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
2 This program implements the lwwire protocol. It expects STDIN and STDOUT |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
3 to be connected to an appropriately configured communication channel. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
4 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
5 The following timeouts are specified by the protocol and are listed here |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
6 for convenience: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
7 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
8 Between bytes in a request: 10 milliseconds |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
9 Between bytes reading a response (client): 10ms <= timeout <= 1000ms |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
10 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
11 Server receiving bad request: >= 1100 milliseconds |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
12 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
13 Implementation notes: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
14 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
15 This implementation uses low level I/O calls (read()/write()) on STDIN |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
16 and STDOUT because we MUST have fully unbuffered I/O for the protocol |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
17 to function properly and we really do not want the stdio overhead for |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
18 that. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
19 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
20 The complexity of the lwwire_readdata() and lwwire_writedata() functions |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
21 is required to handle some possible corner cases that would otherwise |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
22 completely bollix everything up. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
23 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
24 Command line options: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
25 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
26 drive=N,PATH |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
27 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
28 Specify that drive #N should reference the file at PATH. Note that the |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
29 file at PATH will be created if it doesn't exist, but only if it is actually |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
30 accessed. N is a decimal number from 0 to 255. If N is prefixed with "C", |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
31 the drive is treated as read-only. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
32 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
33 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
34 By default, no drives are associated with files. Also, it is unspecified |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
35 what happens if multiple protocol instances access the same drive. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
36 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
37 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
38 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
39 // for nanosleep |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
40 #define _POSIX_C_SOURCE 199309L |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
41 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
42 #include <errno.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
43 #include <fcntl.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
44 #include <stdio.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
45 #include <stdlib.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
46 #include <string.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
47 #include <sys/select.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
48 #include <time.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
49 #include <unistd.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
50 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
51 #define LWERR_NONE 0 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
52 #define LWERR_CHECKSUM 0xF3 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
53 #define LWERR_READ 0xF4 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
54 #define LWERR_WRITE 0xF5 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
55 #define LWERR_NOTREADY 0xF6 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
56 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
57 struct lwwire_driveinfo |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
58 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
59 char *path; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
60 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
61 int isconst; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
62 }; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
63 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
64 struct lwwire_driveinfo drivedata[256]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
65 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
66 void lwwire_protoerror(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
67 int lwwire_readdata(void *, int, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
68 int lwwire_writedata(void *, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
69 void lwwire_write(void *, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
70 int lwwire_read(void *, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
71 int lwwire_read2(void *, int, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
72 void lwwire_reset(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
73 int lwwire_fetch_sector(int dn, int lsn, void *); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
74 int lwwire_save_sector(int dn, int lsn, void *); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
75 int nonblock(int); |
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
76 int lwwire_drive_readononly(int dn); |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
77 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
78 void lwwire_proto_read(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
79 void lwwire_proto_write(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
80 void lwwire_proto_readex(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
81 void lwwire_proto_requestextension(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
82 void lwwire_proto_disableextension(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
83 void lwwire_proto_extensionop(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
84 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
85 int main(int argc, char **argv) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
86 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
87 unsigned char buf[32]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
88 time_t curtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
89 struct tm *tmval; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
90 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
91 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
92 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
93 // make stdin and stdout non-blocking |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
94 if (nonblock(0) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
95 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
96 fprintf(stderr, "Cannot make stdin non-blocking: %s\n", strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
97 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
98 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
99 if (nonblock(1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
100 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
101 fprintf(stderr, "Cannot make stdout non-blocking: %s\n", strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
102 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
103 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
104 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
105 memset(&drivedata, 0, sizeof(drivedata)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
106 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
107 for (i = 1; i < argc; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
108 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
109 if (strncmp("drive=", argv[i], 6) == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
110 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
111 int dn=0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
112 int isconst = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
113 char *ptr; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
114 ptr = argv[i] + 6; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
115 if (*ptr == 'C') |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
116 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
117 isconst = 1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
118 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
119 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
120 while (*ptr >= '0' && *ptr <= '9') |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
121 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
122 dn = dn * 10 + (*ptr - '0'); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
123 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
124 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
125 if (*ptr != ',' || dn > 255) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
126 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
127 fprintf(stderr, "Ignoring invalid drive specification: %s\n", argv[i]); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
128 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
129 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
130 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
131 drivedata[dn].path = ptr; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
132 drivedata[dn].isconst = isconst; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
133 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
134 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
135 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
136 fprintf(stderr, "Running with the following disk images:\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
137 for (i = 0; i < 256; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
138 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
139 if (drivedata[i].path) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
140 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
141 fprintf(stderr, "[%d%s] %s\n", i, drivedata[i].isconst ? "C" : "", drivedata[i].path); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
142 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
143 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
144 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
145 // main loop reading operations and dispatching |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
146 for (;;) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
147 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
148 rv = lwwire_readdata(buf, 1, 0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
149 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
150 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
151 fprintf(stderr, "Error or timeout reading operation code.\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
152 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
153 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
154 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
155 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
156 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
157 fprintf(stderr, "EOF on comm channel. Exiting.\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
158 exit(0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
159 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
160 fprintf(stderr, "Handling opcode %02X\n", buf[0]); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
161 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
162 // we have an opcode here |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
163 switch (buf[0]) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
164 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
165 case 0x00: // NOOP |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
166 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
167 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
168 case 0x23: // TIME |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
169 curtime = time(NULL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
170 tmval = localtime(&curtime); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
171 buf[0] = tmval -> tm_year; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
172 buf[1] = tmval -> tm_mon; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
173 buf[2] = tmval -> tm_mday; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
174 buf[3] = tmval -> tm_hour; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
175 buf[4] = tmval -> tm_min; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
176 buf[5] = tmval -> tm_sec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
177 buf[6] = tmval -> tm_wday; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
178 lwwire_write(buf, 7); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
179 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
180 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
181 case 0x46: // PRINTFLUSH |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
182 // no printer is supported by this implemention so NO-OP |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
183 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
184 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
185 case 0x47: // GETSTAT (useless dw3 operation) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
186 case 0x53: // SETSTAT (useless dw3 operation) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
187 // burn two bytes from the client and do nothing |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
188 lwwire_read(buf, 2); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
189 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
190 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
191 case 0x49: // INIT (old style INIT call) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
192 case 0x54: // TERM (old DW3 op treated same as INIT) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
193 case 0xF8: // RESET3 (junk on the line during reset) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
194 case 0xFE: // RESET1 (junk on the line during reset) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
195 case 0xFF: // RESET2 (junk on the line during reset) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
196 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
197 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
198 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
199 case 0x50: // PRINT |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
200 // burn a byte because we don't support any printers |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
201 lwwire_read(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
202 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
203 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
204 case 0x52: // READ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
205 case 0x72: // REREAD (same semantics as READ) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
206 fprintf(stderr, "DWPROTO: read()\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
207 lwwire_proto_read(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
208 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
209 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
210 case 0x57: // WRITE |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
211 case 0x77: // REWRITE (same semantics as WRITE) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
212 fprintf(stderr, "DWPROTO: write()\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
213 lwwire_proto_write(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
214 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
215 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
216 case 0x5A: // DWINIT (new style init) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
217 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
218 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
219 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
220 fprintf(stderr, "DWINIT: client drive code %02X\n", buf[0]); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
221 // tell the client we speak lwwire protocol |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
222 buf[0] = 0x80; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
223 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
224 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
225 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
226 case 0xD2: // READEX (improved reading operation) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
227 case 0xF2: // REREADEX (same semantics as READEX) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
228 fprintf(stderr, "DWPROTO: readex()\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
229 lwwire_proto_readex(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
230 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
231 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
232 case 0xF0: // REQUESTEXTENSION |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
233 lwwire_proto_requestextension(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
234 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
235 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
236 case 0xF1: // DISABLEEXTENSION |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
237 lwwire_proto_disableextension(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
238 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
239 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
240 case 0xF3: // EXTENSIONOP |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
241 lwwire_proto_extensionop(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
242 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
243 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
244 default: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
245 fprintf(stderr, "Unrecognized operation code %02X. Doing error state.\n", buf[0]); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
246 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
247 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
248 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
249 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
250 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
251 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
252 // protocol handling functions |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
253 void lwwire_proto_read(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
254 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
255 unsigned char buf[259]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
256 int ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
257 int lsn; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
258 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
259 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
260 if (lwwire_read(buf, 4) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
261 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
262 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
263 lsn = (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
264 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
265 ec = lwwire_fetch_sector(buf[0], lsn, buf + 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
266 buf[0] = ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
267 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
268 if (ec) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
269 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
270 // all this futzing around here is probably a long enough |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
271 // delay but testing on real hardware is needed here |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
272 ec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
273 for (i = 1; i < 257; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
274 ec += buf[i]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
275 buf[257] = (ec >> 8) & 0xff; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
276 buf[258] = ec & 0xff; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
277 lwwire_write(buf + 1, 258); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
278 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
279 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
280 void lwwire_proto_write(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
281 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
282 unsigned char buf[262]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
283 int lsn; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
284 int ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
285 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
286 if (lwwire_read(buf, 262) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
287 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
288 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
289 lsn = (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
290 for (ec = 0, i = 4; i < 260; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
291 ec += buf[i]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
292 if (ec != ((buf[260] << 8) | buf[261])) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
293 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
294 buf[0] = LWERR_CHECKSUM; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
295 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
296 else |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
297 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
298 ec = lwwire_save_sector(buf[0], lsn, buf + 4); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
299 buf[0] = ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
300 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
301 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
302 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
303 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
304 void lwwire_proto_readex(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
305 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
306 unsigned char buf[256]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
307 int lsn; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
308 int ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
309 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
310 int csum; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
311 if (lwwire_read(buf, 4) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
312 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
313 lsn = (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
314 ec = lwwire_fetch_sector(buf[0], lsn, buf); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
315 if (ec) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
316 memset(buf, 0, 256); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
317 for (i = 0, csum = 0; i < 256; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
318 csum += buf[i]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
319 lwwire_write(buf, 256); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
320 if ((i = lwwire_read2(buf, 2, 5)) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
321 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
322 fprintf(stderr, "Error reading protocol bytes: %d, %s\n", i, strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
323 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
324 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
325 i = (buf[0] << 8) | buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
326 if (i != csum) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
327 ec = LWERR_CHECKSUM; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
328 buf[0] = ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
329 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
330 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
331 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
332 void lwwire_proto_requestextension(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
333 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
334 unsigned char buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
335 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
336 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
337 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
338 // NAK the request |
4
56f53e48ab50
Fix off by one bug in protocol extension negotiation.
William Astle <lost@l-w.ca>
parents:
3
diff
changeset
|
339 buf[0] = 0x55; |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
340 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
341 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
342 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
343 void lwwire_proto_disableextension(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
344 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
345 unsigned char buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
346 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
347 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
348 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
349 // ACK disabling any unsupported extensions |
4
56f53e48ab50
Fix off by one bug in protocol extension negotiation.
William Astle <lost@l-w.ca>
parents:
3
diff
changeset
|
350 buf[0] = 0x42; |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
351 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
352 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
353 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
354 void lwwire_proto_extensionop(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
355 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
356 unsigned char buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
357 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
358 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
359 // we don't currently support any extensions so treat as unknown |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
360 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
361 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
362 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
363 // Various infrastructure things follow here. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
364 int nonblock(int fd) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
365 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
366 int flags; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
367 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
368 flags = fcntl(fd, F_GETFL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
369 if (flags < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
370 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
371 flags |= O_NONBLOCK; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
372 return fcntl(fd, F_SETFL, flags); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
373 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
374 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
375 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
376 Read len bytes from the input. If no bytes are available after |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
377 10 ms, return error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
378 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
379 This *may* allow a timeout longer than 10ms. However, it will |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
380 eventually time out. In the worse case, it is more permissive |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
381 than the specification. It will not time out before 10ms elapses. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
382 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
383 If "itimeout" is 0, then it will wait forever for the first |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
384 byte. Otherwise, it will time out even on the first one. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
385 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
386 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
387 int lwwire_readdata(void *buf, int len, int itimeout) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
388 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
389 int toread = len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
390 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
391 fd_set fdset; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
392 struct timeval timeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
393 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
394 if (itimeout == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
395 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
396 for (;;) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
397 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
398 // now wait for the descriptor to be readable |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
399 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
400 FD_SET(0, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
401 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
402 rv = select(1, &fdset, NULL, NULL, NULL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
403 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
404 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
405 // this is a last ditch effort to not break completely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
406 // in the face of a signal; it should occur only rarely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
407 // and it is not clear what the correct behaviour should |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
408 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
409 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
410 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
411 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
412 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
413 // if we actually have something to read, move on |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
414 if (rv > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
415 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
416 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
417 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
418 while (toread > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
419 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
420 rv = read(0, buf, toread); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
421 if (rv == toread) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
422 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
423 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
424 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
425 // flag EOF so the caller knows to bail |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
426 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
427 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
428 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
429 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
430 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
431 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
432 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
433 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
434 rv = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
435 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
436 // now rv is the number of bytes read |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
437 buf += rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
438 toread -= rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
439 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
440 // now wait for the descriptor to be readable |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
441 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
442 FD_SET(0, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
443 timeout.tv_sec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
444 timeout.tv_usec = 10000 * itimeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
445 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
446 rv = select(1, &fdset, NULL, NULL, &timeout); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
447 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
448 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
449 // this is a last ditch effort to not break completely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
450 // in the face of a signal; it should occur only rarely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
451 // and it is not clear what the correct behaviour should |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
452 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
453 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
454 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
455 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
456 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
457 // timeout condition |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
458 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
459 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
460 errno = ETIMEDOUT; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
461 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
462 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
463 // anything else here means we have more bytes to read |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
464 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
465 fprintf(stderr, "Protocol bytes read (%d):", len); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
466 for (rv = 0; rv < len; rv++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
467 fprintf(stderr, " %02X ", ((char *)(buf))[rv] & 0xff); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
468 fprintf(stderr, "\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
469 return len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
470 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
471 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
472 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
473 Write data to the output. This will time out after 10 seconds. The timeout |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
474 is only there in case the underlying communication channel goes out to lunch. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
475 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
476 It returns -1 on error or len on success. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
477 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
478 The timeout requires the file descriptor to be non-blocking. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
479 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
480 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
481 int lwwire_writedata(void *buf, int len) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
482 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
483 int towrite = len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
484 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
485 fd_set fdset; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
486 struct timeval timeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
487 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
488 while (towrite > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
489 { |
3
e94940ca17e7
Write to *stdout* not stdin. Duh!
William Astle <lost@l-w.ca>
parents:
2
diff
changeset
|
490 rv = write(1, buf, towrite); |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
491 if (rv == towrite) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
492 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
493 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
494 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
495 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
496 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
497 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
498 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
499 rv = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
500 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
501 // now rv is the number of bytes read |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
502 buf += rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
503 towrite -= rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
504 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
505 // now wait for the descriptor to be writable |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
506 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
507 FD_SET(1, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
508 timeout.tv_sec = 10; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
509 timeout.tv_usec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
510 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
511 rv = select(2, NULL, &fdset, NULL, &timeout); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
512 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
513 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
514 // this is a last ditch effort to not break completely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
515 // in the face of a signal; it should occur only rarely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
516 // and it is not clear what the correct behaviour should |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
517 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
518 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
519 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
520 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
521 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
522 // timeout condition |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
523 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
524 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
525 errno = ETIMEDOUT; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
526 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
527 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
528 // anything else here means we have more bytes to write |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
529 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
530 fprintf(stderr, "Protocol bytes written (%d):", len); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
531 for (rv = 0; rv < len; rv++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
532 fprintf(stderr, " %02X ", ((char *)(buf))[rv] & 0xff); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
533 fprintf(stderr, "\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
534 return len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
535 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
536 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
537 // like lwwire_writedata() except it bails the program on error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
538 void lwwire_write(void *buf, int len) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
539 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
540 if (lwwire_writedata(buf, len) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
541 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
542 fprintf(stderr, "Error writing %d bytes to client: %s\n", len, strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
543 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
544 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
545 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
546 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
547 // like lwwire_readdata() except it bails on EOF and bounces to |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
548 // error state on errors, and always does the timeout for initial |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
549 // bytes. It returns -1 on a timeout. It does not return on EOF. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
550 // It does not return on random errors. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
551 int lwwire_read2(void *buf, int len, int toscale) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
552 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
553 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
554 rv = lwwire_readdata(buf, len, toscale); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
555 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
556 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
557 if (errno == ETIMEDOUT) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
558 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
559 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
560 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
561 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
562 fprintf(stderr, "Error reading %d bytes from client: %s\n", len, strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
563 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
564 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
565 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
566 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
567 fprintf(stderr, "EOF reading %d bytes from client.", len); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
568 exit(0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
569 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
570 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
571 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
572 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
573 int lwwire_read(void *buf, int len) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
574 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
575 return lwwire_read2(buf, len, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
576 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
577 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
578 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
579 Handle a protocol error by maintaining radio silence for |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
580 at least 1100 ms. The pause must be *at least* 1100ms so |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
581 it's no problem if the messing about takes longer. Do a |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
582 state reset after the error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
583 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
584 void lwwire_protoerror(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
585 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
586 struct timespec sltime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
587 struct timespec rtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
588 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
589 sltime.tv_sec = 1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
590 sltime.tv_nsec = 100000000; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
591 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
592 while (nanosleep(&sltime, &rtime) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
593 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
594 // anything other than EINTR indicates something seriously messed up |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
595 if (errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
596 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
597 sltime = rtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
598 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
599 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
600 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
601 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
602 /* fetch a file pointer for the specified drive number */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
603 FILE *lwwire_fetch_drive_fp(int dn) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
604 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
605 if (drivedata[dn].path == NULL) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
606 return NULL; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
607 if (drivedata[dn].fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
608 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
609 if (ferror(drivedata[dn].fp)) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
610 fclose(drivedata[dn].fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
611 else |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
612 return drivedata[dn].fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
613 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
614 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
615 drivedata[dn].fp = fopen(drivedata[dn].path, "r+"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
616 if (!drivedata[dn].fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
617 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
618 if (errno == ENOENT && !drivedata[dn].isconst) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
619 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
620 drivedata[dn].fp = fopen(drivedata[dn].path, "w+"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
621 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
622 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
623 return drivedata[dn].fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
624 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
625 |
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
626 int lwwire_drive_readonly(int dn) |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
627 { |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
628 return drivedata[dn].isconst; |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
629 } |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
630 |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
631 |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
632 /* read a sector from a disk image */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
633 int lwwire_fetch_sector(int dn, int lsn, void *buf) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
634 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
635 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
636 int rc; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
637 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
638 fp = lwwire_fetch_drive_fp(dn); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
639 if (!fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
640 return LWERR_NOTREADY; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
641 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
642 if (fseek(fp, lsn * 256, SEEK_SET) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
643 return LWERR_READ; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
644 rc = fread(buf, 1, 256, fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
645 if (rc < 256) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
646 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
647 memset(buf + rc, 0, 256 - rc); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
648 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
649 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
650 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
651 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
652 int lwwire_save_sector(int dn, int lsn, void *buf) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
653 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
654 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
655 int rc; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
656 |
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
657 if (lwwire_drive_readonly(dn)) |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
658 return LWERR_WRITE; |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
659 fp = lwwire_fetch_drive_fp(dn); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
660 if (!fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
661 return LWERR_NOTREADY; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
662 if (drivedata[dn].isconst) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
663 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
664 if (fseek(fp, lsn * 256, SEEK_SET) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
665 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
666 rc = fwrite(buf, 1, 256, fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
667 if (rc < 256) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
668 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
669 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
670 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
671 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
672 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
673 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
674 Reset the protocol state to "base protocol" mode. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
675 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
676 void lwwire_reset(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
677 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
678 } |