Mercurial > hg > index.cgi
annotate src/lwwire.c @ 4:56f53e48ab50
Fix off by one bug in protocol extension negotiation.
Arrays are indexed from zero!!!!
author  William Astle <lost@lw.ca> 

date  Sun, 29 May 2016 21:50:51 0600 
parents  e94940ca17e7 
children  422f5e8fff85 
rev  line source 

0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

1 /* 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.ca>
parents:
diff
changeset

4 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

6 for convenience: 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

7 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

8 Between bytes in a request: 10 milliseconds 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

10 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

11 Server receiving bad request: >= 1100 milliseconds 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

12 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

13 Implementation notes: 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

14 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

18 that. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

19 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.ca>
parents:
diff
changeset

22 completely bollix everything up. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

23 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

24 Command line options: 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

25 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

26 drive=N,PATH 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

27 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

31 the drive is treated as readonly. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

32 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

33 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.ca>
parents:
diff
changeset

36 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

37 */ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

38 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

39 // for nanosleep 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

40 #define _POSIX_C_SOURCE 199309L 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

41 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

42 #include <errno.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

43 #include <fcntl.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

44 #include <stdio.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

45 #include <stdlib.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

46 #include <string.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

47 #include <sys/select.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

48 #include <time.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

49 #include <unistd.h> 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

50 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

51 #define LWERR_NONE 0 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

52 #define LWERR_CHECKSUM 0xF3 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

53 #define LWERR_READ 0xF4 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

54 #define LWERR_WRITE 0xF5 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

55 #define LWERR_NOTREADY 0xF6 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

56 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

57 struct lwwire_driveinfo 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

58 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

59 char *path; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

60 FILE *fp; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

61 int isconst; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

62 }; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

63 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

64 struct lwwire_driveinfo drivedata[256]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

65 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

66 void lwwire_protoerror(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

67 int lwwire_readdata(void *, int, int); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

68 int lwwire_writedata(void *, int); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

69 void lwwire_write(void *, int); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

70 int lwwire_read(void *, int); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

71 int lwwire_read2(void *, int, int); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

72 void lwwire_reset(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.ca>
parents:
diff
changeset

75 int nonblock(int); 
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

77 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

78 void lwwire_proto_read(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

79 void lwwire_proto_write(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

80 void lwwire_proto_readex(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

81 void lwwire_proto_requestextension(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

82 void lwwire_proto_disableextension(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

83 void lwwire_proto_extensionop(void); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

84 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

85 int main(int argc, char **argv) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

86 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

87 unsigned char buf[32]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

88 time_t curtime; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

89 struct tm *tmval; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

90 int rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

91 int i; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

92 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

93 // make stdin and stdout nonblocking 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

94 if (nonblock(0) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

95 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

96 fprintf(stderr, "Cannot make stdin nonblocking: %s\n", strerror(errno)); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

97 exit(1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

98 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

99 if (nonblock(1) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

100 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

101 fprintf(stderr, "Cannot make stdout nonblocking: %s\n", strerror(errno)); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

102 exit(1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

103 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

104 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

105 memset(&drivedata, 0, sizeof(drivedata)); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

106 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

107 for (i = 1; i < argc; i++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

108 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

109 if (strncmp("drive=", argv[i], 6) == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

110 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

111 int dn=0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

112 int isconst = 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

113 char *ptr; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

114 ptr = argv[i] + 6; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

115 if (*ptr == 'C') 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

116 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

117 isconst = 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

118 ptr++; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

119 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

120 while (*ptr >= '0' && *ptr <= '9') 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

121 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

122 dn = dn * 10 + (*ptr  '0'); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

123 ptr++; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

124 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

125 if (*ptr != ','  dn > 255) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

126 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

128 continue; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

129 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

130 ptr++; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

131 drivedata[dn].path = ptr; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

132 drivedata[dn].isconst = isconst; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

133 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

134 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

135 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

137 for (i = 0; i < 256; i++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

138 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

139 if (drivedata[i].path) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

140 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

142 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

143 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

144 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

145 // main loop reading operations and dispatching 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

146 for (;;) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

147 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

148 rv = lwwire_readdata(buf, 1, 0); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

149 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

150 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

152 lwwire_protoerror(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

153 continue; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

154 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

155 if (rv == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

156 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

158 exit(0); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

159 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

161 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

162 // we have an opcode here 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

163 switch (buf[0]) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

164 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

165 case 0x00: // NOOP 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

166 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

167 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

168 case 0x23: // TIME 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

169 curtime = time(NULL); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

170 tmval = localtime(&curtime); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

171 buf[0] = tmval > tm_year; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

172 buf[1] = tmval > tm_mon; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

173 buf[2] = tmval > tm_mday; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

174 buf[3] = tmval > tm_hour; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

175 buf[4] = tmval > tm_min; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

176 buf[5] = tmval > tm_sec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

177 buf[6] = tmval > tm_wday; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

178 lwwire_write(buf, 7); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

179 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

180 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

181 case 0x46: // PRINTFLUSH 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

182 // no printer is supported by this implemention so NOOP 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

183 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

184 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

185 case 0x47: // GETSTAT (useless dw3 operation) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

186 case 0x53: // SETSTAT (useless dw3 operation) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

187 // burn two bytes from the client and do nothing 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

188 lwwire_read(buf, 2); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

189 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

190 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

191 case 0x49: // INIT (old style INIT call) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

192 case 0x54: // TERM (old DW3 op treated same as INIT) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

193 case 0xF8: // RESET3 (junk on the line during reset) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

194 case 0xFE: // RESET1 (junk on the line during reset) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

195 case 0xFF: // RESET2 (junk on the line during reset) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

196 lwwire_reset(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

197 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

198 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

199 case 0x50: // PRINT 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

200 // burn a byte because we don't support any printers 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

201 lwwire_read(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

202 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

203 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

204 case 0x52: // READ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

205 case 0x72: // REREAD (same semantics as READ) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

206 fprintf(stderr, "DWPROTO: read()\n"); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

207 lwwire_proto_read(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

208 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

209 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

210 case 0x57: // WRITE 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

211 case 0x77: // REWRITE (same semantics as WRITE) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

212 fprintf(stderr, "DWPROTO: write()\n"); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

213 lwwire_proto_write(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

214 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

215 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

216 case 0x5A: // DWINIT (new style init) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

217 lwwire_reset(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

218 if (lwwire_read(buf, 1) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

219 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

220 fprintf(stderr, "DWINIT: client drive code %02X\n", buf[0]); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

221 // tell the client we speak lwwire protocol 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

222 buf[0] = 0x80; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

223 lwwire_write(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

224 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

225 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

226 case 0xD2: // READEX (improved reading operation) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

227 case 0xF2: // REREADEX (same semantics as READEX) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

228 fprintf(stderr, "DWPROTO: readex()\n"); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

229 lwwire_proto_readex(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

230 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

231 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

232 case 0xF0: // REQUESTEXTENSION 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

233 lwwire_proto_requestextension(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

234 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

235 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

236 case 0xF1: // DISABLEEXTENSION 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

237 lwwire_proto_disableextension(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

238 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

239 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

240 case 0xF3: // EXTENSIONOP 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

241 lwwire_proto_extensionop(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

242 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

243 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

244 default: 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

245 fprintf(stderr, "Unrecognized operation code %02X. Doing error state.\n", buf[0]); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

246 lwwire_protoerror(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

247 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

248 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

249 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

250 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

251 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

252 // protocol handling functions 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

253 void lwwire_proto_read(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

254 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

255 unsigned char buf[259]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

256 int ec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

257 int lsn; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

258 int i; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

259 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

260 if (lwwire_read(buf, 4) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

261 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

262 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

263 lsn = (buf[1] << 16)  (buf[2] << 8)  buf[3]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

264 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

265 ec = lwwire_fetch_sector(buf[0], lsn, buf + 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

266 buf[0] = ec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

267 lwwire_write(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

268 if (ec) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

269 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

270 // all this futzing around here is probably a long enough 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

271 // delay but testing on real hardware is needed here 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

272 ec = 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

273 for (i = 1; i < 257; i++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

274 ec += buf[i]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

275 buf[257] = (ec >> 8) & 0xff; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

276 buf[258] = ec & 0xff; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

277 lwwire_write(buf + 1, 258); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

278 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

279 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

280 void lwwire_proto_write(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

281 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

282 unsigned char buf[262]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

283 int lsn; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

284 int ec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

285 int i; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

286 if (lwwire_read(buf, 262) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

287 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

288 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

289 lsn = (buf[1] << 16)  (buf[2] << 8)  buf[3]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

290 for (ec = 0, i = 4; i < 260; i++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

291 ec += buf[i]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

292 if (ec != ((buf[260] << 8)  buf[261])) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

293 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

294 buf[0] = LWERR_CHECKSUM; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

295 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

296 else 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

297 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

298 ec = lwwire_save_sector(buf[0], lsn, buf + 4); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

299 buf[0] = ec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

300 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

301 lwwire_write(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

302 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

303 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

304 void lwwire_proto_readex(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

305 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

306 unsigned char buf[256]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

307 int lsn; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

308 int ec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

309 int i; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

310 int csum; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

311 if (lwwire_read(buf, 4) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

312 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

313 lsn = (buf[1] << 16)  (buf[2] << 8)  buf[3]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

314 ec = lwwire_fetch_sector(buf[0], lsn, buf); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

315 if (ec) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

316 memset(buf, 0, 256); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

317 for (i = 0, csum = 0; i < 256; i++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

318 csum += buf[i]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

319 lwwire_write(buf, 256); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

320 if ((i = lwwire_read2(buf, 2, 5)) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

321 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

322 fprintf(stderr, "Error reading protocol bytes: %d, %s\n", i, strerror(errno)); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

323 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

324 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

325 i = (buf[0] << 8)  buf[1]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

326 if (i != csum) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

327 ec = LWERR_CHECKSUM; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

328 buf[0] = ec; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

329 lwwire_write(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

330 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

331 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

332 void lwwire_proto_requestextension(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

333 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

334 unsigned char buf[1]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

335 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

336 if (lwwire_read(buf, 1) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

337 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

338 // NAK the request 
4
56f53e48ab50
Fix off by one bug in protocol extension negotiation.
William Astle <lost@lw.ca>
parents:
3
diff
changeset

339 buf[0] = 0x55; 
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

340 lwwire_write(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

341 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

342 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

343 void lwwire_proto_disableextension(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

344 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

345 unsigned char buf[1]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

346 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

347 if (lwwire_read(buf, 1) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

348 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

349 // ACK disabling any unsupported extensions 
4
56f53e48ab50
Fix off by one bug in protocol extension negotiation.
William Astle <lost@lw.ca>
parents:
3
diff
changeset

350 buf[0] = 0x42; 
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

351 lwwire_write(buf, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

352 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

353 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

354 void lwwire_proto_extensionop(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

355 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

356 unsigned char buf[1]; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

357 if (lwwire_read(buf, 1) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

358 return; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

359 // we don't currently support any extensions so treat as unknown 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

360 lwwire_protoerror(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

361 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

362 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

363 // Various infrastructure things follow here. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

364 int nonblock(int fd) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

365 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

366 int flags; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

367 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

368 flags = fcntl(fd, F_GETFL); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

369 if (flags < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

370 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

371 flags = O_NONBLOCK; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

372 return fcntl(fd, F_SETFL, flags); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

373 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

374 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

375 /* 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

376 Read len bytes from the input. If no bytes are available after 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

377 10 ms, return error. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

378 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

379 This *may* allow a timeout longer than 10ms. However, it will 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

380 eventually time out. In the worse case, it is more permissive 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

381 than the specification. It will not time out before 10ms elapses. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

382 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

383 If "itimeout" is 0, then it will wait forever for the first 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

384 byte. Otherwise, it will time out even on the first one. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

385 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

386 */ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

387 int lwwire_readdata(void *buf, int len, int itimeout) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

388 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

389 int toread = len; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

390 int rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

391 fd_set fdset; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

392 struct timeval timeout; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

393 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

394 if (itimeout == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

395 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

396 for (;;) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

397 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

399 FD_ZERO(&fdset); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

400 FD_SET(0, &fdset); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

401 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

402 rv = select(1, &fdset, NULL, NULL, NULL); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

403 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

404 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

408 // be. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

409 if (errno == EINTR) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

410 continue; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

411 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

412 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

414 if (rv > 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

415 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

416 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

417 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

418 while (toread > 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

419 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

420 rv = read(0, buf, toread); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

421 if (rv == toread) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

422 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

423 if (rv == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

424 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

426 return 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

427 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

428 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

429 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

430 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

431 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

432 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

433 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

434 rv = 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

435 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

437 buf += rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

438 toread = rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

439 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

441 FD_ZERO(&fdset); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

442 FD_SET(0, &fdset); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

443 timeout.tv_sec = 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

444 timeout.tv_usec = 10000 * itimeout; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

445 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

446 rv = select(1, &fdset, NULL, NULL, &timeout); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

447 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

448 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

452 // be. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

453 if (errno == EINTR) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

454 continue; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

455 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

456 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

457 // timeout condition 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

458 if (rv == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

459 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

460 errno = ETIMEDOUT; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

461 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

462 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

464 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

465 fprintf(stderr, "Protocol bytes read (%d):", len); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

466 for (rv = 0; rv < len; rv++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

467 fprintf(stderr, " %02X ", ((char *)(buf))[rv] & 0xff); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

468 fprintf(stderr, "\n"); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

469 return len; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

470 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

471 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

472 /* 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.ca>
parents:
diff
changeset

475 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

477 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

478 The timeout requires the file descriptor to be nonblocking. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

479 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

480 */ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

481 int lwwire_writedata(void *buf, int len) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

482 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

483 int towrite = len; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

484 int rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

485 fd_set fdset; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

486 struct timeval timeout; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

487 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

488 while (towrite > 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

489 { 
3
e94940ca17e7
Write to *stdout* not stdin. Duh!
William Astle <lost@lw.ca>
parents:
2
diff
changeset

490 rv = write(1, buf, towrite); 
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

491 if (rv == towrite) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

492 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

493 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

494 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

495 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

496 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

497 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

498 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

499 rv = 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

500 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

502 buf += rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

503 towrite = rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

504 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

506 FD_ZERO(&fdset); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

507 FD_SET(1, &fdset); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

508 timeout.tv_sec = 10; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

509 timeout.tv_usec = 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

510 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

511 rv = select(2, NULL, &fdset, NULL, &timeout); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

512 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

513 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

517 // be. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

518 if (errno == EINTR) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

519 continue; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

520 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

521 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

522 // timeout condition 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

523 if (rv == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

524 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

525 errno = ETIMEDOUT; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

526 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

527 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

529 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

530 fprintf(stderr, "Protocol bytes written (%d):", len); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

531 for (rv = 0; rv < len; rv++) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

532 fprintf(stderr, " %02X ", ((char *)(buf))[rv] & 0xff); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

533 fprintf(stderr, "\n"); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

534 return len; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

535 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

536 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

538 void lwwire_write(void *buf, int len) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

539 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

540 if (lwwire_writedata(buf, len) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

541 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

543 exit(1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

544 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

545 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

546 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

550 // It does not return on random errors. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

552 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

553 int rv; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

554 rv = lwwire_readdata(buf, len, toscale); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

555 if (rv < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

556 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

557 if (errno == ETIMEDOUT) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

558 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

559 lwwire_protoerror(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

560 return 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

561 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

563 exit(1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

564 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

565 if (rv == 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

566 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

568 exit(0); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

569 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

570 return 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

571 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

572 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

573 int lwwire_read(void *buf, int len) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

574 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

575 return lwwire_read2(buf, len, 1); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

576 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

577 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

578 /* 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.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@lw.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@lw.ca>
parents:
diff
changeset

582 state reset after the error. 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

583 */ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

584 void lwwire_protoerror(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

585 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

586 struct timespec sltime; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

587 struct timespec rtime; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

588 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

589 sltime.tv_sec = 1; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

590 sltime.tv_nsec = 100000000; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

591 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

592 while (nanosleep(&sltime, &rtime) < 0) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

593 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

595 if (errno != EINTR) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

596 break; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

597 sltime = rtime; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

598 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

599 lwwire_reset(); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

600 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

601 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

603 FILE *lwwire_fetch_drive_fp(int dn) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

604 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

605 if (drivedata[dn].path == NULL) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

606 return NULL; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

607 if (drivedata[dn].fp) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

608 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

609 if (ferror(drivedata[dn].fp)) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

610 fclose(drivedata[dn].fp); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

611 else 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

612 return drivedata[dn].fp; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

613 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

614 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

616 if (!drivedata[dn].fp) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

617 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

618 if (errno == ENOENT && !drivedata[dn].isconst) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

619 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

621 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

622 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

623 return drivedata[dn].fp; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

624 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

625 
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

626 int lwwire_drive_readonly(int dn) 
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

627 { 
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

628 return drivedata[dn].isconst; 
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

629 } 
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

630 
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

631 
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

632 /* read a sector from a disk image */ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

634 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

635 FILE *fp; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

636 int rc; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

637 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

638 fp = lwwire_fetch_drive_fp(dn); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

639 if (!fp) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

640 return LWERR_NOTREADY; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

641 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

643 return LWERR_READ; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

644 rc = fread(buf, 1, 256, fp); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

645 if (rc < 256) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

646 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

647 memset(buf + rc, 0, 256  rc); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

648 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

649 return 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

650 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

651 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

653 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

654 FILE *fp; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

655 int rc; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

656 
2
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

657 if (lwwire_drive_readonly(dn)) 
2f2cbd2d2561
Theoretically make "C" flag for drive defs work.
William Astle <lost@lw.ca>
parents:
0
diff
changeset

658 return LWERR_WRITE; 
0
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

659 fp = lwwire_fetch_drive_fp(dn); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

660 if (!fp) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

661 return LWERR_NOTREADY; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

662 if (drivedata[dn].isconst) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

663 return LWERR_WRITE; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

665 return LWERR_WRITE; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

666 rc = fwrite(buf, 1, 256, fp); 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

667 if (rc < 256) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

668 return LWERR_WRITE; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

669 return 0; 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

670 } 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

671 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

672 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

673 /* 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.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@lw.ca>
parents:
diff
changeset

675 */ 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

676 void lwwire_reset(void) 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

677 { 
bef2801ac83e
Initial checkin with reference implementation of core protocol
William Astle <lost@lw.ca>
parents:
diff
changeset

678 } 