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