CoCalc Public Fileswww / onhand / fton / rupserial.cOpen with one click!
Author: William A. Stein
1
/*
2
* rupserial.c - low level serial routines
3
* Copyright (C) 1998 N.Fukase
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA
19
*/
20
21
#include <stdio.h>
22
#include <string.h>
23
#include <stdlib.h>
24
#include <sys/types.h>
25
#include <sys/stat.h>
26
#include <fcntl.h>
27
#include <termios.h>
28
#include <unistd.h>
29
30
#include "rupcommand.h"
31
#include "rupserial.h"
32
33
/*_____ �ץ饤�١����ѿ� ____________________________________________________*/
34
static struct termios term,
35
saveterm;
36
static int dev;
37
/*----- �Ƽ拾�����ѥޥ��� --------------------------------------------------*/
38
/* Ruputer Rshell �ꥶ��ȥ����� */
39
#define RRESULT_ACK 0x06
40
#define RRESULT_NAK 0x15
41
42
/* CR��LF */
43
#define LF 0x0a
44
#define CR 0x0d
45
46
/* XMODEM�� */
47
#define XMODEM_ACK 0x06
48
#define XMODEM_NAK 0x15
49
#define XMODEM_CAN 0x18
50
#define XMODEM_SOH 0x01
51
#define XMODEM_STX 0x02
52
#define XMODEM_EOT 0x04
53
#define XMODEM_EOF 0x1A
54
#define XMODEM_C 0x43
55
#define XMODEM_SP 0x20
56
#define XMODEM_SYN 0x16
57
#define XMODEM_DLE 0x10
58
#define XMODEM_XOF 0x11
59
#define XMODEM_XON 0x13
60
#define XMODEM_W 0x57
61
/*===== ���֥롼���� ========================================================*/
62
/*----- Ruputer�����ack������å� ------------------------------------------*/
63
int
64
chk_ack(void)
65
{
66
char b;
67
68
read(dev, &b, 1);
69
#ifdef DEBUG
70
printf("%02x\n" , b & 0xff);
71
#endif
72
return (b != RRESULT_ACK) ? -1 : 0;
73
}
74
/*----- Ruputer��ack������ --------------------------------------------------*/
75
void
76
put_ack(void)
77
{
78
char b;
79
b = RRESULT_ACK;
80
write(dev, &b, 1);
81
}
82
/*----- ���ꥢ��ǥХ����ν���� --------------------------------------------*/
83
int
84
init_line(char *line)
85
{
86
long f;
87
88
if((dev = open(line, (O_RDWR | O_NONBLOCK))) < 0) {
89
fprintf(stderr, "Cannot open %s\n", line);
90
exit(-1);
91
}
92
if (tcgetattr(dev, &term) == -1) {
93
fprintf(stderr, "Cannot get attribute %s\n", line);
94
close(dev);
95
exit(-1);
96
}
97
memcpy(&saveterm, &term, sizeof(struct termios));
98
term.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | IXANY |
99
IXON | IXOFF | INPCK | ISTRIP);
100
term.c_iflag |= BRKINT | IGNPAR;
101
term.c_oflag &= ~OPOST;
102
term.c_lflag = ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK);
103
term.c_cflag |= CS8 | CREAD;
104
/* baud = B19200;
105
* baud = B38400;
106
* baud = B57600;
107
*/
108
cfsetospeed(&term, B38400);
109
cfsetispeed(&term, B38400);
110
tcsetattr(dev, TCSANOW, &term);
111
f = fcntl(dev, F_GETFL);
112
tcflush(dev, TCIOFLUSH);
113
f &= ~O_NONBLOCK;
114
fcntl(dev, F_SETFL, f);
115
return 0;
116
}
117
/*_____ ���ꥢ��ǥХ����θ���� _____________________________________*/
118
void restore_line(void)
119
{
120
tcflush(dev, TCIOFLUSH);
121
tcsetattr(dev, TCSANOW, &saveterm);
122
close(dev);
123
}
124
/*_____ Ruputer�Ȥ���³�ͥ������������ _______________________________*/
125
int
126
ruputer_negotiate(void)
127
{
128
char b = 0;
129
130
while(b != CR) {
131
read(dev, &b, 1);
132
printf("%02x\n" , b & 0xff);
133
}
134
while(b != LF) {
135
read(dev, &b, 1);
136
}
137
write(dev, "Erg", 3);
138
read(dev, &b, 1);
139
if(b == XMODEM_ACK)
140
return 0;
141
else
142
return -1;
143
}
144
/*_____ X-MODEM(128SUM)�ˤ�륢�åץ����� __________________________________*/
145
int
146
xmodem_up(LENDAT *data)
147
{
148
unsigned char buf[132], *ptr, bn, sum, ret;
149
int len, i;
150
151
while((read(dev, &ret, 1) != 1) && (ret != XMODEM_NAK)) {
152
printf("%02x\n", ret);
153
}
154
fprintf(stderr, ".");
155
len = data->length;
156
ptr = data->data;
157
buf[0] = XMODEM_SOH;
158
for (bn = 1; len > 0; bn++) {
159
buf[1] = bn; buf[2] = ~bn;
160
memcpy(buf + 3, ptr, (len > 128)? 128 : len);
161
len -= 128;
162
ptr += 128;
163
/* �Ĥ�ǡ�����128��꾮������� */
164
if (len < 0)
165
memset(buf + 3 + (128 + len), XMODEM_EOF, -len);
166
sum = 0;
167
for (i = 3; i < 128 + 3; i++)
168
sum += buf[i];
169
buf[131] = sum;
170
for (ret = XMODEM_NAK; ret == XMODEM_NAK;) {
171
write(dev, buf, 132);
172
while(read(dev, &ret, 1) != 1)
173
;
174
switch (ret){
175
case XMODEM_ACK:
176
fprintf(stderr, ".");
177
break;
178
case XMODEM_NAK:
179
fprintf(stderr, "x");
180
break;
181
case XMODEM_CAN:
182
fprintf(stderr, "\nTransfer cannceled by onHand\n");
183
return -1;
184
default:
185
fprintf(stderr, "\nInvalid result code from onHand\n");
186
return -1;
187
}
188
}
189
if(ret != XMODEM_ACK) {
190
printf("\nXMODEM: Bad Result Code\n");
191
return -1;
192
}
193
}
194
buf[0] = XMODEM_EOT;
195
do {
196
write(dev, buf, 1);
197
while(read(dev, &ret, 1) != 1)
198
;
199
printf("\n");
200
} while (ret == XMODEM_NAK);
201
if(ret != XMODEM_ACK) {
202
fprintf(stderr, "XMODEM: Bad Result Code %02x\n", ret & 0xff);
203
return -1;
204
}
205
return 0;
206
}
207
/*_____ X-MODEM(128SUM)�ˤ������������ ___________________________________*/
208
int
209
xmodem_down(LENDAT *data)
210
{
211
unsigned char buf[132], *ptr, bn, sum, ret;
212
int len, i, c;
213
214
/* ���� */
215
buf[0] = XMODEM_NAK;
216
for (;;) {
217
write(dev, buf, 1);
218
while(read(dev, &ret, 1) != 1)
219
;
220
if (ret == XMODEM_SOH)
221
break;
222
sleep(10);
223
}
224
/* ž�� */
225
fprintf(stderr, ".");
226
len = data->length;
227
ptr = data->data;
228
for (bn = 1; len > 0; ) {
229
if(ret != XMODEM_SOH) {
230
/* �ǡ�������������? */
231
buf[0] = XMODEM_CAN;
232
write(dev, buf, 1);
233
fprintf(stderr, "\nTransfer failed\n");
234
return -1;
235
}
236
for (c = 0; c < 131;) {
237
c += read(dev, buf + c, 131 - c);
238
}
239
if((buf[0] != bn) || (buf[1] != (~bn & 0xff))) {
240
buf[0] = XMODEM_NAK;
241
fprintf(stderr, "X");
242
write(dev, buf, 1);
243
while(read(dev, &ret, 1) != 1)
244
;
245
continue;
246
}
247
/* SUM �����å� */
248
sum = 0;
249
for (i = 2; i < 128 + 2; i++)
250
sum += buf[i];
251
if (buf[130] != sum) {
252
buf[0] = XMODEM_NAK;
253
fprintf(stderr, "x");
254
write(dev, buf, 1);
255
while(read(dev, &ret, 1) != 1)
256
;
257
continue;
258
}
259
memcpy(ptr, buf + 2, (len > 128)? 128 : len);
260
buf[0] = XMODEM_ACK;
261
write(dev, buf, 1);
262
fprintf(stderr, ".");
263
len -= 128;
264
ptr += 128;
265
while(read(dev, &ret, 1) != 1)
266
;
267
bn++;
268
}
269
printf("\n");
270
if (ret == XMODEM_EOT) {
271
buf[0] = XMODEM_ACK;
272
write(dev, buf, 1);
273
return 0;
274
} else {
275
buf[0] = XMODEM_CAN;
276
write(dev, buf, 1);
277
fprintf(stderr, "At last, transfer failed\n");
278
return -1;
279
}
280
}
281
/*_____ Ruputer�ؤΥ��ޥ��ȯ�� _____________________________________________*/
282
int
283
ruputer_command(int command, int sub, int length, char *data)
284
{
285
int i, sum;
286
char *buf;
287
288
if((buf = (char *)malloc(length + 1)) == NULL) {
289
fprintf(stderr, "Cannot allocate memory!\n");
290
return -1;
291
}
292
buf[0] = (command & 0xff);
293
buf[1] = (sub & 0xff);
294
WORD2(buf + 2, length);
295
if (length > 4) {
296
memcpy(buf + 4, data, (length - 4));
297
}
298
sum = 0;
299
for(i = 0; i < length; ++i) {
300
sum += (buf[i] & 0xff);
301
}
302
buf[length] = ((~sum) & 0xff);
303
write(dev, buf, length + 1);
304
free(buf);
305
return 0;
306
}
307
/*_____ Ruputer����Υ쥹�ݥ󥹤�����å� ___________________________________*/
308
int
309
ruputer_response(int res, int sub, LENDAT *dat)
310
{
311
char b[4];
312
int c, length, sum, i;
313
314
dat->data = NULL;
315
/* get header */
316
for (c = 0; c < 4;) {
317
c += read(dev, b + c, 4 - c);
318
}
319
/* check header */
320
if ((b[0] != res) || (b[1] != sub))
321
return -1;
322
length = WORD(b + 2);
323
/* make return structure */
324
if (length > 4) {
325
length -= 4;
326
dat->length = length;
327
if((dat->data = (char *)malloc(length)) == NULL) {
328
fprintf(stderr, "Cannot allocate memory\n" );
329
return -1;
330
}
331
/* get data */
332
for (c = 0; c < length;) {
333
c += read(dev, dat->data + c, length - c);
334
}
335
}
336
/* sum check */
337
sum = (b[0] & 0xff) + (b[1] & 0xff) + (b[2] & 0xff) + (b[3] & 0xff);
338
for(i = 0; i < length; ++i) {
339
sum += (dat->data[i] & 0xff);
340
}
341
while(read(dev, b, 1) < 1)
342
;
343
if (((~sum) & 0xff) == (*b & 0xff))
344
return 0;
345
if (dat) {
346
free(dat->data);
347
}
348
return -1;
349
}
350