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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }