Mercurial > hg > index.cgi
annotate src/lwwire.c @ 0:bef2801ac83e
Initial checkin with reference implementation of core protocol
Initial checkin. Has the initial version of the protocol documentation along
with a reference implementation of the core protocol.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 08 May 2016 12:56:39 -0600 |
parents | |
children | 2f2cbd2d2561 |
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); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
76 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
77 void lwwire_proto_read(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
78 void lwwire_proto_write(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
79 void lwwire_proto_readex(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
80 void lwwire_proto_requestextension(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
81 void lwwire_proto_disableextension(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
82 void lwwire_proto_extensionop(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
83 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
84 int main(int argc, char **argv) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
85 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
86 unsigned char buf[32]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
87 time_t curtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
88 struct tm *tmval; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
89 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
90 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
91 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
92 // make stdin and stdout non-blocking |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
93 if (nonblock(0) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
94 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
95 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
|
96 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
97 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
98 if (nonblock(1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
99 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
100 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
|
101 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
102 } |
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 memset(&drivedata, 0, sizeof(drivedata)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
105 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
106 for (i = 1; i < argc; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
107 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
108 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
|
109 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
110 int dn=0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
111 int isconst = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
112 char *ptr; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
113 ptr = argv[i] + 6; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
114 if (*ptr == 'C') |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
115 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
116 isconst = 1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
117 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
118 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
119 while (*ptr >= '0' && *ptr <= '9') |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
120 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
121 dn = dn * 10 + (*ptr - '0'); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
122 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
123 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
124 if (*ptr != ',' || dn > 255) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
125 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
126 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
|
127 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
128 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
129 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
130 drivedata[dn].path = ptr; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
131 drivedata[dn].isconst = isconst; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
132 } |
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 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
|
136 for (i = 0; i < 256; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
137 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
138 if (drivedata[i].path) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
139 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
140 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
|
141 } |
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 // main loop reading operations and dispatching |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
145 for (;;) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
146 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
147 rv = lwwire_readdata(buf, 1, 0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
148 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
149 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
150 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
|
151 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
152 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
153 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
154 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
155 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
156 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
|
157 exit(0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
158 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
159 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
|
160 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
161 // we have an opcode here |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
162 switch (buf[0]) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
163 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
164 case 0x00: // NOOP |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
165 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
166 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
167 case 0x23: // TIME |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
168 curtime = time(NULL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
169 tmval = localtime(&curtime); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
170 buf[0] = tmval -> tm_year; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
171 buf[1] = tmval -> tm_mon; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
172 buf[2] = tmval -> tm_mday; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
173 buf[3] = tmval -> tm_hour; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
174 buf[4] = tmval -> tm_min; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
175 buf[5] = tmval -> tm_sec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
176 buf[6] = tmval -> tm_wday; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
177 lwwire_write(buf, 7); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
178 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
179 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
180 case 0x46: // PRINTFLUSH |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
181 // 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
|
182 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
183 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
184 case 0x47: // GETSTAT (useless dw3 operation) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
185 case 0x53: // SETSTAT (useless dw3 operation) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
186 // 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
|
187 lwwire_read(buf, 2); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
188 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
189 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
190 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
|
191 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
|
192 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
|
193 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
|
194 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
|
195 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
196 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
197 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
198 case 0x50: // PRINT |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
199 // 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
|
200 lwwire_read(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
201 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
202 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
203 case 0x52: // READ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
204 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
|
205 fprintf(stderr, "DWPROTO: read()\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
206 lwwire_proto_read(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
207 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
208 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
209 case 0x57: // WRITE |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
210 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
|
211 fprintf(stderr, "DWPROTO: write()\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
212 lwwire_proto_write(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
213 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
214 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
215 case 0x5A: // DWINIT (new style init) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
216 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
217 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
218 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
219 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
|
220 // 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
|
221 buf[0] = 0x80; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
222 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
223 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
224 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
225 case 0xD2: // READEX (improved reading operation) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
226 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
|
227 fprintf(stderr, "DWPROTO: readex()\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
228 lwwire_proto_readex(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
229 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
230 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
231 case 0xF0: // REQUESTEXTENSION |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
232 lwwire_proto_requestextension(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
233 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
234 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
235 case 0xF1: // DISABLEEXTENSION |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
236 lwwire_proto_disableextension(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
237 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
238 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
239 case 0xF3: // EXTENSIONOP |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
240 lwwire_proto_extensionop(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
241 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
242 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
243 default: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
244 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
|
245 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
246 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
247 } |
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 // protocol handling functions |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
252 void lwwire_proto_read(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
253 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
254 unsigned char buf[259]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
255 int ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
256 int lsn; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
257 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
258 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
259 if (lwwire_read(buf, 4) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
260 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
261 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
262 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
|
263 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
264 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
|
265 buf[0] = ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
266 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
267 if (ec) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
268 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
269 // 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
|
270 // 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
|
271 ec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
272 for (i = 1; i < 257; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
273 ec += buf[i]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
274 buf[257] = (ec >> 8) & 0xff; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
275 buf[258] = ec & 0xff; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
276 lwwire_write(buf + 1, 258); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
277 } |
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 void lwwire_proto_write(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
280 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
281 unsigned char buf[262]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
282 int lsn; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
283 int ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
284 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
285 if (lwwire_read(buf, 262) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
286 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
287 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
288 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
|
289 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
|
290 ec += buf[i]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
291 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
|
292 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
293 buf[0] = LWERR_CHECKSUM; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
294 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
295 else |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
296 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
297 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
|
298 buf[0] = ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
299 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
300 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
301 } |
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 void lwwire_proto_readex(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
304 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
305 unsigned char buf[256]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
306 int lsn; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
307 int ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
308 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
309 int csum; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
310 if (lwwire_read(buf, 4) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
311 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
312 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
|
313 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
|
314 if (ec) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
315 memset(buf, 0, 256); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
316 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
|
317 csum += buf[i]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
318 lwwire_write(buf, 256); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
319 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
|
320 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
321 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
|
322 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
323 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
324 i = (buf[0] << 8) | buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
325 if (i != csum) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
326 ec = LWERR_CHECKSUM; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
327 buf[0] = ec; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
328 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
329 } |
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 void lwwire_proto_requestextension(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
332 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
333 unsigned char buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
334 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
335 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
336 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
337 // NAK the request |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
338 buf[1] = 0x55; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
339 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
340 } |
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 void lwwire_proto_disableextension(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
343 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
344 unsigned char buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
345 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
346 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
347 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
348 // ACK disabling any unsupported extensions |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
349 buf[1] = 0x42; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
350 lwwire_write(buf, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
351 } |
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 void lwwire_proto_extensionop(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
354 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
355 unsigned char buf[1]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
356 if (lwwire_read(buf, 1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
357 return; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
358 // 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
|
359 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
360 } |
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 // Various infrastructure things follow here. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
363 int nonblock(int fd) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
364 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
365 int flags; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
366 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
367 flags = fcntl(fd, F_GETFL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
368 if (flags < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
369 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
370 flags |= O_NONBLOCK; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
371 return fcntl(fd, F_SETFL, flags); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
372 } |
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 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
|
376 10 ms, return error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
377 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
378 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
|
379 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
|
380 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
|
381 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
382 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
|
383 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
|
384 |
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 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
|
387 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
388 int toread = len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
389 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
390 fd_set fdset; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
391 struct timeval timeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
392 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
393 if (itimeout == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
394 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
395 for (;;) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
396 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
397 // 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
|
398 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
399 FD_SET(0, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
400 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
401 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
|
402 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
403 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
404 // 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
|
405 // 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
|
406 // 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
|
407 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
408 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
409 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
410 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
411 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
412 // 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
|
413 if (rv > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
414 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
415 } |
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 while (toread > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
418 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
419 rv = read(0, buf, toread); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
420 if (rv == toread) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
421 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
422 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
423 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
424 // 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
|
425 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
426 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
427 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
428 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
429 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
|
430 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
431 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
432 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
433 rv = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
434 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
435 // 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
|
436 buf += rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
437 toread -= rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
438 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
439 // 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
|
440 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
441 FD_SET(0, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
442 timeout.tv_sec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
443 timeout.tv_usec = 10000 * itimeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
444 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
445 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
|
446 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
447 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
448 // 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
|
449 // 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
|
450 // 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
|
451 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
452 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
453 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
454 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
455 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
456 // timeout condition |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
457 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
458 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
459 errno = ETIMEDOUT; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
460 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
461 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
462 // 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
|
463 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
464 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
|
465 for (rv = 0; rv < len; rv++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
466 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
|
467 fprintf(stderr, "\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
468 return len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
469 } |
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 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
|
473 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
|
474 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
475 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
|
476 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
477 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
|
478 |
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 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
|
481 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
482 int towrite = len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
483 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
484 fd_set fdset; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
485 struct timeval timeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
486 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
487 while (towrite > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
488 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
489 rv = write(0, buf, towrite); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
490 if (rv == towrite) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
491 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
492 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
493 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
494 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
|
495 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
496 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
497 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
498 rv = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
499 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
500 // 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
|
501 buf += rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
502 towrite -= rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
503 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
504 // 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
|
505 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
506 FD_SET(1, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
507 timeout.tv_sec = 10; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
508 timeout.tv_usec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
509 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
510 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
|
511 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
512 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
513 // 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
|
514 // 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
|
515 // 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
|
516 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
517 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
518 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
519 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
520 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
521 // timeout condition |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
522 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
523 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
524 errno = ETIMEDOUT; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
525 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
526 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
527 // 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
|
528 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
529 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
|
530 for (rv = 0; rv < len; rv++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
531 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
|
532 fprintf(stderr, "\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
533 return len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
534 } |
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 // 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
|
537 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
|
538 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
539 if (lwwire_writedata(buf, len) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
540 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
541 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
|
542 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
543 } |
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 // 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
|
547 // 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
|
548 // 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
|
549 // 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
|
550 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
|
551 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
552 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
553 rv = lwwire_readdata(buf, len, toscale); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
554 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
555 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
556 if (errno == ETIMEDOUT) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
557 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
558 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
559 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
560 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
561 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
|
562 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
563 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
564 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
565 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
566 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
|
567 exit(0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
568 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
569 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
570 } |
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 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
|
573 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
574 return lwwire_read2(buf, len, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
575 } |
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 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
|
579 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
|
580 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
|
581 state reset after the error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
582 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
583 void lwwire_protoerror(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
584 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
585 struct timespec sltime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
586 struct timespec rtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
587 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
588 sltime.tv_sec = 1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
589 sltime.tv_nsec = 100000000; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
590 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
591 while (nanosleep(&sltime, &rtime) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
592 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
593 // 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
|
594 if (errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
595 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
596 sltime = rtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
597 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
598 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
599 } |
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 /* 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
|
602 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
|
603 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
604 if (drivedata[dn].path == NULL) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
605 return NULL; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
606 if (drivedata[dn].fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
607 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
608 if (ferror(drivedata[dn].fp)) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
609 fclose(drivedata[dn].fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
610 else |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
611 return drivedata[dn].fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
612 } |
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 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
|
615 if (!drivedata[dn].fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
616 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
617 if (errno == ENOENT && !drivedata[dn].isconst) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
618 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
619 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
|
620 } |
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 return drivedata[dn].fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
623 } |
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 /* 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
|
626 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
|
627 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
628 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
629 int rc; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
630 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
631 fp = lwwire_fetch_drive_fp(dn); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
632 if (!fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
633 return LWERR_NOTREADY; |
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 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
|
636 return LWERR_READ; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
637 rc = fread(buf, 1, 256, fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
638 if (rc < 256) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
639 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
640 memset(buf + rc, 0, 256 - rc); |
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 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
643 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
644 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
645 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
|
646 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
647 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
648 int rc; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
649 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
650 fp = lwwire_fetch_drive_fp(dn); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
651 if (!fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
652 return LWERR_NOTREADY; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
653 if (drivedata[dn].isconst) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
654 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
655 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
|
656 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
657 rc = fwrite(buf, 1, 256, fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
658 if (rc < 256) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
659 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
660 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
661 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
662 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
663 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
664 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
665 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
|
666 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
667 void lwwire_reset(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
668 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
669 } |