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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [disk/] [diskserv/] [diskserv.c] - Blame information for rev 48

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 SYN             0x16
16
#define ACK             0x06
17
 
18
#define RESULT_OK       0x00
19
#define RESULT_UNCMD    0x01
20
#define RESULT_TOOBIG   0x02
21
#define RESULT_POSERR   0x03
22
#define RESULT_RDERR    0x04
23
#define RESULT_WRERR    0x05
24
 
25
 
26
static int debugCmds = 1;
27
static int debugData = 0;
28
 
29
static FILE *diskFile = NULL;
30
static unsigned int numSectors;
31
static int sfd = 0;
32
static struct termios origOptions;
33
static struct termios currOptions;
34
 
35
 
36
void serialClose(void);
37
 
38
 
39
void error(char *fmt, ...) {
40
  va_list ap;
41
 
42
  va_start(ap, fmt);
43
  printf("Error: ");
44
  vprintf(fmt, ap);
45
  printf("\n");
46
  va_end(ap);
47
  if (diskFile != NULL) {
48
    fclose(diskFile);
49
    diskFile = NULL;
50
  }
51
  if (sfd != 0) {
52
    serialClose();
53
    sfd = 0;
54
  }
55
  exit(1);
56
}
57
 
58
 
59 48 hellwig
void serialOpen(char *serialPort) {
60
  sfd = open(serialPort, O_RDWR | O_NOCTTY | O_NDELAY);
61 17 hellwig
  if (sfd == -1) {
62 48 hellwig
    error("cannot open serial port '%s'", serialPort);
63 17 hellwig
  }
64
  tcgetattr(sfd, &origOptions);
65
  currOptions = origOptions;
66
  cfsetispeed(&currOptions, B38400);
67
  cfsetospeed(&currOptions, B38400);
68
  currOptions.c_cflag |= (CLOCAL | CREAD);
69
  currOptions.c_cflag &= ~PARENB;
70
  currOptions.c_cflag &= ~CSTOPB;
71
  currOptions.c_cflag &= ~CSIZE;
72
  currOptions.c_cflag |= CS8;
73
  currOptions.c_cflag &= ~CRTSCTS;
74
  currOptions.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN);
75
  currOptions.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK);
76
  currOptions.c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL);
77
  currOptions.c_iflag &= ~(IXON | IXOFF | IXANY);
78
  currOptions.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET);
79
  tcsetattr(sfd, TCSANOW, &currOptions);
80
}
81
 
82
 
83
void serialClose(void) {
84
  tcsetattr(sfd, TCSANOW, &origOptions);
85
  close(sfd);
86
}
87
 
88
 
89
int serialSnd(unsigned char b) {
90
  int n;
91
 
92
  n = write(sfd, &b, 1);
93
  return n == 1;
94
}
95
 
96
 
97
int serialRcv(unsigned char *bp) {
98
  int n;
99
 
100
  n = read(sfd, bp, 1);
101
  return n == 1;
102
}
103
 
104
 
105
void connect(void) {
106
  unsigned char b;
107
 
108
  printf("SYN... ");
109
  fflush(stdout);
110
  while (!serialSnd(ACK)) ;
111
  tcdrain(sfd);
112
  printf("ACK... ");
113
  fflush(stdout);
114
  while (!serialRcv(&b)) ;
115
  if (b != ACK) {
116
    error("cannot synchronize with client");
117
  }
118
  printf("connected\n");
119
}
120
 
121
 
122
void sendResult(unsigned char result) {
123
  while (!serialSnd(result)) ;
124
  tcdrain(sfd);
125
}
126
 
127
 
128
void showData(unsigned char buffer[512]) {
129
  int i, j;
130
  unsigned char c;
131
 
132
  for (i = 0; i < 32; i++) {
133
    printf("%03X   ", i * 16);
134
    for (j = 0; j < 16; j++) {
135
      c = buffer[i * 16 + j];
136
      printf("%02X ", c);
137
    }
138
    printf("  ");
139
    for (j = 0; j < 16; j++) {
140
      c = buffer[i * 16 + j];
141
      if (c >= 0x20 && c < 0x7F) {
142
        printf("%c", c);
143
      } else {
144
        printf(".");
145
      }
146
    }
147
    printf("\n");
148
  }
149
}
150
 
151
 
152
int main(int argc, char *argv[]) {
153 48 hellwig
  char *serialPort;
154 17 hellwig
  char *diskName;
155
  int i;
156
  unsigned char b;
157
  unsigned char cmd;
158
  unsigned int sector;
159
  unsigned char buffer[512];
160
 
161 48 hellwig
  if (argc != 3) {
162
    printf("Usage: %s <serial port> <disk image file>\n", argv[0]);
163 17 hellwig
    exit(1);
164
  }
165 48 hellwig
  serialPort = argv[1];
166
  diskName = argv[2];
167 17 hellwig
  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 48 hellwig
  serialOpen(serialPort);
177 17 hellwig
  /* 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.