Mercurial > hg > index.cgi
annotate src/lwwire.c @ 9:a11b330771e0
Fix buffer pointer handling when logging received bytes
Actually save the read buffer pointer so we can log the actual protocol
bytes read in all cases correctly instead of displaying out of bounds memory
in the case where the packet arrives in multiple pieces.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sat, 30 Jul 2016 10:35:14 -0600 |
parents | cf915ece9e48 |
children | 36c4cda4b6c4 |
rev | line source |
---|---|
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
1 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
2 This program implements the lwwire protocol. It expects STDIN and STDOUT |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
3 to be connected to an appropriately configured communication channel. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
4 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
5 The following timeouts are specified by the protocol and are listed here |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
6 for convenience: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
7 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
8 Between bytes in a request: 10 milliseconds |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
9 Between bytes reading a response (client): 10ms <= timeout <= 1000ms |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
10 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
11 Server receiving bad request: >= 1100 milliseconds |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
12 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
13 Implementation notes: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
14 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
15 This implementation uses low level I/O calls (read()/write()) on STDIN |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
16 and STDOUT because we MUST have fully unbuffered I/O for the protocol |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
17 to function properly and we really do not want the stdio overhead for |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
18 that. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
19 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
20 The complexity of the lwwire_readdata() and lwwire_writedata() functions |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
21 is required to handle some possible corner cases that would otherwise |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
22 completely bollix everything up. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
23 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
24 Command line options: |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
25 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
26 drive=N,PATH |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
27 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
28 Specify that drive #N should reference the file at PATH. Note that the |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
29 file at PATH will be created if it doesn't exist, but only if it is actually |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
30 accessed. N is a decimal number from 0 to 255. If N is prefixed with "C", |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
31 the drive is treated as read-only. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
32 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
33 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
34 By default, no drives are associated with files. Also, it is unspecified |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
35 what happens if multiple protocol instances access the same drive. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
36 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
37 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
38 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
39 // for nanosleep |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
40 #define _POSIX_C_SOURCE 199309L |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
41 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
42 #include <errno.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
43 #include <fcntl.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
44 #include <stdio.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
45 #include <stdlib.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
46 #include <string.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
47 #include <sys/select.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
48 #include <time.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
49 #include <unistd.h> |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
50 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
51 #define LWERR_NONE 0 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
52 #define LWERR_CHECKSUM 0xF3 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
53 #define LWERR_READ 0xF4 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
54 #define LWERR_WRITE 0xF5 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
55 #define LWERR_NOTREADY 0xF6 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
56 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
57 struct lwwire_driveinfo |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
58 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
59 char *path; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
60 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
61 int isconst; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
62 }; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
63 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
64 struct lwwire_driveinfo drivedata[256]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
65 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
66 void lwwire_protoerror(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
67 int lwwire_readdata(void *, int, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
68 int lwwire_writedata(void *, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
69 void lwwire_write(void *, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
70 int lwwire_read(void *, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
71 int lwwire_read2(void *, int, int); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
72 void lwwire_reset(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
73 int lwwire_fetch_sector(int dn, int lsn, void *); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
74 int lwwire_save_sector(int dn, int lsn, void *); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
75 int nonblock(int); |
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
76 int lwwire_drive_readononly(int dn); |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
77 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
78 void lwwire_proto_read(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
79 void lwwire_proto_write(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
80 void lwwire_proto_readex(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
81 void lwwire_proto_requestextension(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
82 void lwwire_proto_disableextension(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
83 void lwwire_proto_extensionop(void); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
84 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
85 int main(int argc, char **argv) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
86 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
87 unsigned char buf[32]; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
88 time_t curtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
89 struct tm *tmval; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
90 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
91 int i; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
92 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
93 // make stdin and stdout non-blocking |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
94 if (nonblock(0) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
95 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
96 fprintf(stderr, "Cannot make stdin non-blocking: %s\n", strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
97 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
98 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
99 if (nonblock(1) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
100 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
101 fprintf(stderr, "Cannot make stdout non-blocking: %s\n", strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
102 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
103 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
104 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
105 memset(&drivedata, 0, sizeof(drivedata)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
106 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
107 for (i = 1; i < argc; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
108 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
109 if (strncmp("drive=", argv[i], 6) == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
110 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
111 int dn=0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
112 int isconst = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
113 char *ptr; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
114 ptr = argv[i] + 6; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
115 if (*ptr == 'C') |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
116 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
117 isconst = 1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
118 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
119 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
120 while (*ptr >= '0' && *ptr <= '9') |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
121 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
122 dn = dn * 10 + (*ptr - '0'); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
123 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
124 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
125 if (*ptr != ',' || dn > 255) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
126 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
127 fprintf(stderr, "Ignoring invalid drive specification: %s\n", argv[i]); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
128 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
129 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
130 ptr++; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
131 drivedata[dn].path = ptr; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
132 drivedata[dn].isconst = isconst; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
133 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
134 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
135 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
136 fprintf(stderr, "Running with the following disk images:\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
137 for (i = 0; i < 256; i++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
138 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
139 if (drivedata[i].path) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
140 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
141 fprintf(stderr, "[%d%s] %s\n", i, drivedata[i].isconst ? "C" : "", drivedata[i].path); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
142 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
143 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
144 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
145 // main loop reading operations and dispatching |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
146 for (;;) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
147 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
148 rv = lwwire_readdata(buf, 1, 0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
149 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
150 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
151 fprintf(stderr, "Error or timeout reading operation code.\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
152 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
153 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
154 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
155 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
156 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
157 fprintf(stderr, "EOF on comm channel. Exiting.\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
158 exit(0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
159 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
160 fprintf(stderr, "Handling opcode %02X\n", buf[0]); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
161 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
162 // we have an opcode here |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
163 switch (buf[0]) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
164 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
165 case 0x00: // NOOP |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
166 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
167 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
168 case 0x23: // TIME |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
169 curtime = time(NULL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
170 tmval = localtime(&curtime); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
171 buf[0] = tmval -> tm_year; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
172 buf[1] = tmval -> tm_mon; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
173 buf[2] = tmval -> tm_mday; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
174 buf[3] = tmval -> tm_hour; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
175 buf[4] = tmval -> tm_min; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
176 buf[5] = tmval -> tm_sec; |
8
cf915ece9e48
Remove "week day" from the TIME response
William Astle <lost@l-w.ca>
parents:
5
diff
changeset
|
177 lwwire_write(buf, 6); |
0
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 |
4
56f53e48ab50
Fix off by one bug in protocol extension negotiation.
William Astle <lost@l-w.ca>
parents:
3
diff
changeset
|
338 buf[0] = 0x55; |
0
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 |
4
56f53e48ab50
Fix off by one bug in protocol extension negotiation.
William Astle <lost@l-w.ca>
parents:
3
diff
changeset
|
349 buf[0] = 0x42; |
0
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 |
5
422f5e8fff85
Extend base read timeout to 100ms in spec and implementation.
William Astle <lost@l-w.ca>
parents:
4
diff
changeset
|
376 100 ms, return error. |
0
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 { |
9
a11b330771e0
Fix buffer pointer handling when logging received bytes
William Astle <lost@l-w.ca>
parents:
8
diff
changeset
|
388 char *obuf = buf; |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
389 int toread = len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
390 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
391 fd_set fdset; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
392 struct timeval timeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
393 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
394 if (itimeout == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
395 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
396 for (;;) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
397 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
398 // now wait for the descriptor to be readable |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
399 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
400 FD_SET(0, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
401 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
402 rv = select(1, &fdset, NULL, NULL, NULL); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
403 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
404 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
405 // this is a last ditch effort to not break completely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
406 // in the face of a signal; it should occur only rarely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
407 // and it is not clear what the correct behaviour should |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
408 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
409 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
410 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
411 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
412 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
413 // if we actually have something to read, move on |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
414 if (rv > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
415 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
416 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
417 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
418 while (toread > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
419 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
420 rv = read(0, buf, toread); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
421 if (rv == toread) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
422 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
423 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
424 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
425 // flag EOF so the caller knows to bail |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
426 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
427 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
428 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
429 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
430 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
431 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
432 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
433 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
434 rv = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
435 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
436 // now rv is the number of bytes read |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
437 buf += rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
438 toread -= rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
439 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
440 // now wait for the descriptor to be readable |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
441 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
442 FD_SET(0, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
443 timeout.tv_sec = 0; |
5
422f5e8fff85
Extend base read timeout to 100ms in spec and implementation.
William Astle <lost@l-w.ca>
parents:
4
diff
changeset
|
444 timeout.tv_usec = 100000 * itimeout; |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
445 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
446 rv = select(1, &fdset, NULL, NULL, &timeout); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
447 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
448 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
449 // this is a last ditch effort to not break completely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
450 // in the face of a signal; it should occur only rarely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
451 // and it is not clear what the correct behaviour should |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
452 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
453 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
454 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
455 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
456 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
457 // timeout condition |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
458 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
459 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
460 errno = ETIMEDOUT; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
461 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
462 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
463 // anything else here means we have more bytes to read |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
464 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
465 fprintf(stderr, "Protocol bytes read (%d):", len); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
466 for (rv = 0; rv < len; rv++) |
9
a11b330771e0
Fix buffer pointer handling when logging received bytes
William Astle <lost@l-w.ca>
parents:
8
diff
changeset
|
467 fprintf(stderr, " %02X ", (obuf[rv]) & 0xff); |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
468 fprintf(stderr, "\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
469 return len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
470 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
471 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
472 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
473 Write data to the output. This will time out after 10 seconds. The timeout |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
474 is only there in case the underlying communication channel goes out to lunch. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
475 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
476 It returns -1 on error or len on success. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
477 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
478 The timeout requires the file descriptor to be non-blocking. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
479 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
480 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
481 int lwwire_writedata(void *buf, int len) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
482 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
483 int towrite = len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
484 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
485 fd_set fdset; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
486 struct timeval timeout; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
487 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
488 while (towrite > 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
489 { |
3
e94940ca17e7
Write to *stdout* not stdin. Duh!
William Astle <lost@l-w.ca>
parents:
2
diff
changeset
|
490 rv = write(1, buf, towrite); |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
491 if (rv == towrite) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
492 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
493 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
494 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
495 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
496 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
497 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
498 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
499 rv = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
500 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
501 // now rv is the number of bytes read |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
502 buf += rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
503 towrite -= rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
504 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
505 // now wait for the descriptor to be writable |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
506 FD_ZERO(&fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
507 FD_SET(1, &fdset); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
508 timeout.tv_sec = 10; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
509 timeout.tv_usec = 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
510 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
511 rv = select(2, NULL, &fdset, NULL, &timeout); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
512 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
513 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
514 // this is a last ditch effort to not break completely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
515 // in the face of a signal; it should occur only rarely |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
516 // and it is not clear what the correct behaviour should |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
517 // be. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
518 if (errno == EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
519 continue; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
520 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
521 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
522 // timeout condition |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
523 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
524 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
525 errno = ETIMEDOUT; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
526 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
527 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
528 // anything else here means we have more bytes to write |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
529 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
530 fprintf(stderr, "Protocol bytes written (%d):", len); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
531 for (rv = 0; rv < len; rv++) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
532 fprintf(stderr, " %02X ", ((char *)(buf))[rv] & 0xff); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
533 fprintf(stderr, "\n"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
534 return len; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
535 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
536 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
537 // like lwwire_writedata() except it bails the program on error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
538 void lwwire_write(void *buf, int len) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
539 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
540 if (lwwire_writedata(buf, len) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
541 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
542 fprintf(stderr, "Error writing %d bytes to client: %s\n", len, strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
543 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
544 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
545 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
546 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
547 // like lwwire_readdata() except it bails on EOF and bounces to |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
548 // error state on errors, and always does the timeout for initial |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
549 // bytes. It returns -1 on a timeout. It does not return on EOF. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
550 // It does not return on random errors. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
551 int lwwire_read2(void *buf, int len, int toscale) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
552 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
553 int rv; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
554 rv = lwwire_readdata(buf, len, toscale); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
555 if (rv < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
556 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
557 if (errno == ETIMEDOUT) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
558 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
559 lwwire_protoerror(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
560 return -1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
561 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
562 fprintf(stderr, "Error reading %d bytes from client: %s\n", len, strerror(errno)); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
563 exit(1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
564 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
565 if (rv == 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
566 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
567 fprintf(stderr, "EOF reading %d bytes from client.", len); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
568 exit(0); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
569 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
570 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
571 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
572 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
573 int lwwire_read(void *buf, int len) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
574 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
575 return lwwire_read2(buf, len, 1); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
576 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
577 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
578 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
579 Handle a protocol error by maintaining radio silence for |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
580 at least 1100 ms. The pause must be *at least* 1100ms so |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
581 it's no problem if the messing about takes longer. Do a |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
582 state reset after the error. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
583 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
584 void lwwire_protoerror(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
585 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
586 struct timespec sltime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
587 struct timespec rtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
588 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
589 sltime.tv_sec = 1; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
590 sltime.tv_nsec = 100000000; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
591 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
592 while (nanosleep(&sltime, &rtime) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
593 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
594 // anything other than EINTR indicates something seriously messed up |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
595 if (errno != EINTR) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
596 break; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
597 sltime = rtime; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
598 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
599 lwwire_reset(); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
600 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
601 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
602 /* fetch a file pointer for the specified drive number */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
603 FILE *lwwire_fetch_drive_fp(int dn) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
604 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
605 if (drivedata[dn].path == NULL) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
606 return NULL; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
607 if (drivedata[dn].fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
608 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
609 if (ferror(drivedata[dn].fp)) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
610 fclose(drivedata[dn].fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
611 else |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
612 return drivedata[dn].fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
613 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
614 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
615 drivedata[dn].fp = fopen(drivedata[dn].path, "r+"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
616 if (!drivedata[dn].fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
617 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
618 if (errno == ENOENT && !drivedata[dn].isconst) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
619 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
620 drivedata[dn].fp = fopen(drivedata[dn].path, "w+"); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
621 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
622 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
623 return drivedata[dn].fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
624 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
625 |
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
626 int lwwire_drive_readonly(int dn) |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
627 { |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
628 return drivedata[dn].isconst; |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
629 } |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
630 |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
631 |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
632 /* read a sector from a disk image */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
633 int lwwire_fetch_sector(int dn, int lsn, void *buf) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
634 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
635 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
636 int rc; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
637 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
638 fp = lwwire_fetch_drive_fp(dn); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
639 if (!fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
640 return LWERR_NOTREADY; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
641 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
642 if (fseek(fp, lsn * 256, SEEK_SET) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
643 return LWERR_READ; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
644 rc = fread(buf, 1, 256, fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
645 if (rc < 256) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
646 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
647 memset(buf + rc, 0, 256 - rc); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
648 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
649 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
650 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
651 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
652 int lwwire_save_sector(int dn, int lsn, void *buf) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
653 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
654 FILE *fp; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
655 int rc; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
656 |
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
657 if (lwwire_drive_readonly(dn)) |
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@l-w.ca>
parents:
0
diff
changeset
|
658 return LWERR_WRITE; |
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
659 fp = lwwire_fetch_drive_fp(dn); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
660 if (!fp) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
661 return LWERR_NOTREADY; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
662 if (drivedata[dn].isconst) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
663 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
664 if (fseek(fp, lsn * 256, SEEK_SET) < 0) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
665 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
666 rc = fwrite(buf, 1, 256, fp); |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
667 if (rc < 256) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
668 return LWERR_WRITE; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
669 return 0; |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
670 } |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
671 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
672 |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
673 /* |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
674 Reset the protocol state to "base protocol" mode. |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
675 */ |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
676 void lwwire_reset(void) |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
677 { |
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
678 } |