OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.24/] [disk/] [diskserv/] [diskserv.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 hellwig
/*
2
 * diskserv.c -- serial line disk server
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <stdarg.h>
10
#include <fcntl.h>
11
#include <unistd.h>
12
#include <termios.h>
13
 
14
 
15
#define SERIAL_PORT     "/dev/tty01"
16
 
17
#define SYN             0x16
18
#define ACK             0x06
19
 
20
#define RESULT_OK       0x00
21
#define RESULT_UNCMD    0x01
22
#define RESULT_TOOBIG   0x02
23
#define RESULT_POSERR   0x03
24
#define RESULT_RDERR    0x04
25
#define RESULT_WRERR    0x05
26
 
27
 
28
static int debugCmds = 1;
29
static int debugData = 0;
30
 
31
static FILE *diskFile = NULL;
32
static unsigned int numSectors;
33
static int sfd = 0;
34
static struct termios origOptions;
35
static struct termios currOptions;
36
 
37
 
38
void serialClose(void);
39
 
40
 
41
void error(char *fmt, ...) {
42
  va_list ap;
43
 
44
  va_start(ap, fmt);
45
  printf("Error: ");
46
  vprintf(fmt, ap);
47
  printf("\n");
48
  va_end(ap);
49
  if (diskFile != NULL) {
50
    fclose(diskFile);
51
    diskFile = NULL;
52
  }
53
  if (sfd != 0) {
54
    serialClose();
55
    sfd = 0;
56
  }
57
  exit(1);
58
}
59
 
60
 
61
void serialOpen(void) {
62
  sfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
63
  if (sfd == -1) {
64
    error("cannot open serial port '%s'", SERIAL_PORT);
65
  }
66
  tcgetattr(sfd, &origOptions);
67
  currOptions = origOptions;
68
  cfsetispeed(&currOptions, B38400);
69
  cfsetospeed(&currOptions, B38400);
70
  currOptions.c_cflag |= (CLOCAL | CREAD);
71
  currOptions.c_cflag &= ~PARENB;
72
  currOptions.c_cflag &= ~CSTOPB;
73
  currOptions.c_cflag &= ~CSIZE;
74
  currOptions.c_cflag |= CS8;
75
  currOptions.c_cflag &= ~CRTSCTS;
76
  currOptions.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN);
77
  currOptions.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK);
78
  currOptions.c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL);
79
  currOptions.c_iflag &= ~(IXON | IXOFF | IXANY);
80
  currOptions.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET);
81
  tcsetattr(sfd, TCSANOW, &currOptions);
82
}
83
 
84
 
85
void serialClose(void) {
86
  tcsetattr(sfd, TCSANOW, &origOptions);
87
  close(sfd);
88
}
89
 
90
 
91
int serialSnd(unsigned char b) {
92
  int n;
93
 
94
  n = write(sfd, &b, 1);
95
  return n == 1;
96
}
97
 
98
 
99
int serialRcv(unsigned char *bp) {
100
  int n;
101
 
102
  n = read(sfd, bp, 1);
103
  return n == 1;
104
}
105
 
106
 
107
void connect(void) {
108
  unsigned char b;
109
 
110
  printf("SYN... ");
111
  fflush(stdout);
112
  while (!serialSnd(ACK)) ;
113
  tcdrain(sfd);
114
  printf("ACK... ");
115
  fflush(stdout);
116
  while (!serialRcv(&b)) ;
117
  if (b != ACK) {
118
    error("cannot synchronize with client");
119
  }
120
  printf("connected\n");
121
}
122
 
123
 
124
void sendResult(unsigned char result) {
125
  while (!serialSnd(result)) ;
126
  tcdrain(sfd);
127
}
128
 
129
 
130
void showData(unsigned char buffer[512]) {
131
  int i, j;
132
  unsigned char c;
133
 
134
  for (i = 0; i < 32; i++) {
135
    printf("%03X   ", i * 16);
136
    for (j = 0; j < 16; j++) {
137
      c = buffer[i * 16 + j];
138
      printf("%02X ", c);
139
    }
140
    printf("  ");
141
    for (j = 0; j < 16; j++) {
142
      c = buffer[i * 16 + j];
143
      if (c >= 0x20 && c < 0x7F) {
144
        printf("%c", c);
145
      } else {
146
        printf(".");
147
      }
148
    }
149
    printf("\n");
150
  }
151
}
152
 
153
 
154
int main(int argc, char *argv[]) {
155
  char *diskName;
156
  int i;
157
  unsigned char b;
158
  unsigned char cmd;
159
  unsigned int sector;
160
  unsigned char buffer[512];
161
 
162
  if (argc != 2) {
163
    printf("Usage: %s <disk image file>\n", argv[0]);
164
    exit(1);
165
  }
166
  diskName = argv[1];
167
  diskFile = fopen(diskName, "r+b");
168
  if (diskFile == NULL) {
169
    error("cannot open disk image file '%s'", diskName);
170
  }
171
  fseek(diskFile, 0, SEEK_END);
172
  numSectors = ftell(diskFile) / 512;
173
  fseek(diskFile, 0, SEEK_SET);
174
  printf("Disk '%s' has 0x%08X sectors.\n", diskName, numSectors);
175
  /* open serial interface */
176
  serialOpen();
177
  /* wait for client to connect */
178
  printf("Waiting for client...\n");
179
  while (1) {
180
    if (serialRcv(&b) && b == SYN) {
181
      break;
182
    }
183
  }
184
  connect();
185
  /* connected, now handle requests */
186
  while (1) {
187
    while (!serialRcv(&cmd)) ;
188
    if (cmd == 'q') {
189
      /* for tests only, a real client would never quit */
190
      if (debugCmds) {
191
        printf("quit\n");
192
      }
193
      break;
194
    }
195
    if (cmd == SYN) {
196
      /* this happens if the client has been reset */
197
      connect();
198
      continue;
199
    }
200
    if (cmd == 'c') {
201
      /* client asks for disk capacity */
202
      sendResult(RESULT_OK);
203
      for (i = 0; i < 4; i++) {
204
        b = (numSectors >> (8 * (3 - i))) & 0xFF;
205
        while (!serialSnd(b)) ;
206
      }
207
      tcdrain(sfd);
208
      if (debugCmds) {
209
        printf("capacity... OK\n");
210
      }
211
      continue;
212
    }
213
    if (cmd != 'r' && cmd != 'w') {
214
      /* unknown command */
215
      sendResult(RESULT_UNCMD);
216
      if (debugCmds) {
217
        printf("unknown... UNCMD\n");
218
      }
219
      continue;
220
    }
221
    /* only read and write requests get here */
222
    sector = 0;
223
    for (i = 0; i < 4; i++) {
224
      while (!serialRcv(&b)) ;
225
      sector = (sector << 8) | b;
226
    }
227
    if (cmd == 'r') {
228
      if (debugCmds) {
229
        printf("reading sector 0x%08X... ", sector);
230
        fflush(stdout);
231
      }
232
      if (sector >= numSectors) {
233
        sendResult(RESULT_TOOBIG);
234
        if (debugCmds) {
235
          printf("TOOBIG\n");
236
        }
237
      } else
238
      if (fseek(diskFile, sector * 512, SEEK_SET) != 0) {
239
        sendResult(RESULT_POSERR);
240
        if (debugCmds) {
241
          printf("POSERR\n");
242
        }
243
      } else
244
      if (fread(buffer, 1, 512, diskFile) != 512) {
245
        sendResult(RESULT_RDERR);
246
        if (debugCmds) {
247
          printf("RDERR\n");
248
        }
249
      } else {
250
        sendResult(RESULT_OK);
251
        for (i = 0; i < 512; i++) {
252
          while (!serialSnd(buffer[i])) ;
253
        }
254
        tcdrain(sfd);
255
        if (debugCmds) {
256
          printf("OK\n");
257
        }
258
        if (debugData) {
259
          showData(buffer);
260
        }
261
      }
262
      continue;
263
    }
264
    if (cmd == 'w') {
265
      if (debugCmds) {
266
        printf("writing sector 0x%08X... ", sector);
267
        fflush(stdout);
268
      }
269
      for (i = 0; i < 512; i++) {
270
        while (!serialRcv(buffer + i)) ;
271
      }
272
      if (sector >= numSectors) {
273
        sendResult(RESULT_TOOBIG);
274
        if (debugCmds) {
275
          printf("TOOBIG\n");
276
        }
277
      } else
278
      if (fseek(diskFile, sector * 512, SEEK_SET) != 0) {
279
        sendResult(RESULT_POSERR);
280
        if (debugCmds) {
281
          printf("POSERR\n");
282
        }
283
      } else
284
      if (fwrite(buffer, 1, 512, diskFile) != 512) {
285
        sendResult(RESULT_WRERR);
286
        if (debugCmds) {
287
          printf("WRERR\n");
288
        }
289
      } else {
290
        sendResult(RESULT_OK);
291
        if (debugCmds) {
292
          printf("OK\n");
293
        }
294
        if (debugData) {
295
          showData(buffer);
296
        }
297
      }
298
      continue;
299
    }
300
  }
301
  if (diskFile != NULL) {
302
    fclose(diskFile);
303
    diskFile = NULL;
304
  }
305
  if (sfd != 0) {
306
    serialClose();
307
    sfd = 0;
308
  }
309
  return 0;
310
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.