rllib  1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
rlserial.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rlserial.cpp - description
3  -------------------
4  begin : Sat Dec 21 2002
5  copyright : (C) 2002 by R. Lehrig
6  email : lehrig@t-online.de
7 
8  RMOS implementation:
9  Copyright : (C) 2004 Zertrox GbR
10  Written by : Alexander Feller
11  Email : feller@zertrox.de
12  ***************************************************************************/
13 
14 /***************************************************************************
15  * *
16  * This library is free software; you can redistribute it and/or modify *
17  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
18  * published by the Free Software Foundation *
19  * *
20  ***************************************************************************/
21 #include "rlserial.h"
22 
23 #ifdef RLUNIX
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <termios.h>
29 #include <unistd.h>
30 #include <signal.h>
31 #endif
32 
33 #ifdef __VMS
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <starlet.h>
38 #include <descrip.h>
39 #include <lib$routines.h>
40 #include <ssdef.h>
41 #include <iodef.h>
42 typedef struct
43 {
44  short iostat;
45  unsigned short msg_len;
46  int reader_pid;
47 }IOSB;
48 #endif
49 
50 #ifdef RLWIN32
51 #include <windows.h>
52 #include <stdio.h>
53 #endif
54 
55 #ifdef RM3
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <rmcomp.h>
59 #include <rmapi.h>
60 #include <rio.h>
61 #include <drvspec.h>
62 #include <rm3cav.h>
63 //#include <clean.h>
64 #include <rcinc.h>
65 #define RTS_TIME_WAIT 0x008 /* Verzoerungszeit fuer RTS - Signal */
66 #endif
67 
68 #include "rlthread.h"
69 
70 /*
71 static void sighandler(int sig)
72 {
73  if(sig == SIGINT)
74  {
75  closeDevice();
76  closeDatabase();
77  }
78 }
79 */
80 
82 {
83  ttysavefd = -1;
84  ttystate = RESET;
85  fd = -1;
86  trace = 0;
87 }
88 
90 {
91  closeDevice();
92 }
93 
94 void rlSerial::setTrace(int on)
95 {
96  if(on == 1) trace = 1;
97  else trace = 0;
98 }
99 
100 int rlSerial::openDevice(const char *devicename, int speed, int block, int rtscts, int bits, int stopbits, int parity)
101 {
102 #ifdef RLUNIX
103  struct termios buf;
104 
105  if(fd != -1) return -1;
106  fd = open(devicename, O_RDWR | O_NOCTTY | O_NDELAY);
107  if(fd < 0) { return -1; }
108 
109  //signal(SIGINT, sighandler);
110 
111  if(tcgetattr(fd, &save_termios) < 0) { return -1; }
112  buf = save_termios;
113  buf.c_cflag = speed | CLOCAL | CREAD;
114  if(rtscts == 1) buf.c_cflag |= CRTSCTS;
115  if(bits == 7) buf.c_cflag |= CS7;
116  else buf.c_cflag |= CS8;
117  if(stopbits == 2) buf.c_cflag |= CSTOPB;
118  if(parity == rlSerial::ODD) buf.c_cflag |= (PARENB | PARODD);
119  if(parity == rlSerial::EVEN) buf.c_cflag |= PARENB;
120  buf.c_lflag = IEXTEN; //ICANON;
121  buf.c_oflag = OPOST;
122  buf.c_cc[VMIN] = 1;
123  buf.c_cc[VTIME] = 0;
124 #ifndef PVMAC
125  buf.c_line = 0;
126 #endif
127  buf.c_iflag = IGNBRK | IGNPAR | IXANY;
128  if(tcsetattr(fd, TCSAFLUSH, &buf) < 0) { return -1; }
129  //if(tcsetattr(fd, TCSANOW, &buf) < 0) { return -1; }
130  ttystate = RAW;
131  ttysavefd = fd;
132  if(block == 1) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
133  tcflush(fd,TCIOFLUSH);
134 #endif
135 
136 #ifdef __VMS
137  // Please set com parameters at DCL level
138  struct dsc$descriptor_s dsc;
139  int status;
140 
141  dsc.dsc$w_length = strlen(devicename);
142  dsc.dsc$a_pointer = (char *) devicename;
143  dsc.dsc$b_class = DSC$K_CLASS_S;
144  dsc.dsc$b_dtype = DSC$K_DTYPE_T;
145  status = SYS$ASSIGN(&dsc,&vms_channel,0,0);
146  if(status != SS$_NORMAL) return -1;
147 #endif
148 
149 #ifdef RLWIN32
150  DWORD ccsize;
151  COMMCONFIG cc;
152  int baudrate,ret;
153  char devname[100];
154 
155  if(strlen(devicename) > 80) return -1;
156  sprintf(devname,"\\\\.\\%s",devicename); // Aenderung: allow more than 4 COM ports
157  hdl = CreateFile(
158  devname, // devicename, // pointer to name of the file
159  GENERIC_READ | GENERIC_WRITE, // access (read-write) mode
160  0, // share mode
161  0, // pointer to security attributes
162  OPEN_EXISTING, // how to create
163  0, // not overlapped I/O
164  0 // handle to file with attributes to copy
165  );
166  if(hdl == INVALID_HANDLE_VALUE)
167  {
168  printf("CreateFile(%s) failed\n",devicename);
169  return -1;
170  }
171 
172  baudrate = CBR_9600;
173  if(speed == B50 ) baudrate = 50;
174  if(speed == B75 ) baudrate = 75;
175  if(speed == B110 ) baudrate = CBR_110;
176  if(speed == B134 ) baudrate = 134;
177  if(speed == B150 ) baudrate = 150;
178  if(speed == B200 ) baudrate = 200;
179  if(speed == B300 ) baudrate = CBR_300;
180  if(speed == B600 ) baudrate = CBR_600;
181  if(speed == B1200 ) baudrate = CBR_1200;
182  if(speed == B1800 ) baudrate = 1800;
183  if(speed == B2400 ) baudrate = CBR_2400;
184  if(speed == B4800 ) baudrate = CBR_4800;
185  if(speed == B9600 ) baudrate = CBR_9600;
186  if(speed == B19200 ) baudrate = CBR_19200;
187  if(speed == B38400 ) baudrate = CBR_38400;
188  if(speed == B57600 ) baudrate = CBR_57600;
189  if(speed == B115200 ) baudrate = CBR_115200;
190  if(speed == B230400 ) baudrate = 230400;
191  if(speed == B460800 ) baudrate = 460800;
192  if(speed == B500000 ) baudrate = 500000;
193  if(speed == B576000 ) baudrate = 576000;
194  if(speed == B921600 ) baudrate = 921600;
195  if(speed == B1000000) baudrate = 1000000;
196  if(speed == B1152000) baudrate = 1152000;
197  if(speed == B1500000) baudrate = 1500000;
198  if(speed == B2000000) baudrate = 2000000;
199  if(speed == B2500000) baudrate = 2500000;
200  if(speed == B3000000) baudrate = 3000000;
201  if(speed == B3500000) baudrate = 3500000;
202  if(speed == B4000000) baudrate = 4000000;
203 
204  GetCommConfig(hdl,&cc,&ccsize);
205  //cc.dwSize = sizeof(cc); // size of structure
206  //cc.wVersion = 1; // version of structure
207  //cc.wReserved = 0; // reserved
208  // DCB dcb; // device-control block
209  cc.dcb.DCBlength = sizeof(DCB); // sizeof(DCB)
210  cc.dcb.BaudRate = baudrate; // current baud rate
211  cc.dcb.fBinary = 1; // binary mode, no EOF check
212  cc.dcb.fParity = 1; // enable parity checking
213  cc.dcb.fOutxCtsFlow = 0; // CTS output flow control
214  if(rtscts == 1) cc.dcb.fOutxCtsFlow = 1;
215  cc.dcb.fOutxDsrFlow = 0; // DSR output flow control
216  cc.dcb.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control type
217  cc.dcb.fDsrSensitivity = 0; // DSR sensitivity
218  cc.dcb.fTXContinueOnXoff = 1; // XOFF continues Tx
219  //cc.dcb.fOutX = 0; // XON/XOFF out flow control
220  //cc.dcb.fInX = 0; // XON/XOFF in flow control
221  //cc.dcb.fErrorChar = 0; // enable error replacement
222  cc.dcb.fNull = 0; // enable null stripping
223  cc.dcb.fRtsControl = RTS_CONTROL_DISABLE;
224  if(rtscts == 1) cc.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // RTS flow control
225  cc.dcb.fAbortOnError = 0; // abort reads/writes on error
226  //cc.dcb.fDummy2 = 0; // reserved
227  //cc.dcb.wReserved = 0; // not currently used
228  //cc.dcb.XonLim = 0; // transmit XON threshold
229  //cc.dcb.XoffLim = 0; // transmit XOFF threshold
230  cc.dcb.ByteSize = bits; // number of bits/byte, 4-8
231  cc.dcb.Parity = 0; // 0-4=no,odd,even,mark,space
232  if(parity == rlSerial::ODD) cc.dcb.Parity = 1;
233  if(parity == rlSerial::EVEN) cc.dcb.Parity = 2;
234  cc.dcb.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
235  if(stopbits==2) cc.dcb.StopBits = TWOSTOPBITS;
236  //cc.dcb.XonChar = 0; // Tx and Rx XON character
237  //cc.dcb.XoffChar = 0; // Tx and Rx XOFF character
238  //cc.dcb.ErrorChar = 0; // error replacement character
239  //cc.dcb.EofChar = 0; // end of input character
240  //cc.dcb.EvtChar = 0; // received event character
241  //cc.dcb.wReserved1 = 0; // reserved; do not use
242  cc.dwProviderSubType = PST_RS232; // type of provider-specific data
243  //cc.dwProviderOffset = 0; // offset of provider-specific data
244  //cc.dwProviderSize = 0; // size of provider-specific data
245  //cc.wcProviderData[0] = 0; // provider-specific data
246 
247  ret = SetCommConfig(hdl,&cc,sizeof(cc));
248  if(ret == 0)
249  {
250  printf("SetCommConfig ret=%d devicename=%s LastError=%d\n",ret,devicename,GetLastError());
251  return -1;
252  }
253 #endif
254 
255 #ifdef RM3
256  RmEntryStruct CatEntry; /* Struktur der Deiviceinformationen */
257  int iStatus; /* Rckgabewert */
258  RmIOStatusStruct DrvSts; /* Struktur der Rckgabewerte fr RmIO - Funktion */
259  RmBytParmStruct PBlock; /* Parameterstruktur fr RmIO - Funktion */
260  static UCD_BYT_PORT Ucd_byt_drv; /* Struktur zum Setzen der UCD - Werte */
261  ushort uTimeBd; /* Timing - Wert der �ertragungsgeschwindigkeit */
262  uint uMode; /* Portsteuerungsparameter */
263  unsigned char cByte; /* Byte - Parameter */
264  /* Timing = 748800 / Baudrate; */
265  /**************************************************/
266  char byt_com[32];
267 
268  /* COM1=0x3F8 COM2=0x2F8 - Port Adresse */
269  if (strcmp(devicename,"COM1") == 0)
270  {
271  strcpy(byt_com,"BYT_COM1");
272  com = 0x3f8;
273  }
274  else if(strcmp(devicename,"COM2") == 0)
275  {
276  strcpy(byt_com,"BYT_COM2");
277  com = 0x2f8;
278  }
279  else
280  {
281  printf("Error: devicename=%s unknown\n",devicename);
282  return -1;
283  }
284  //printf("Open COM port - inside\n");
285 
286  /*
287  * Device und Unit - Id auslesen
288  */
289  if( RmGetEntry( RM_WAIT, byt_com, &CatEntry ) != RM_OK ) /* RM_CONTINUE */
290  {
291  printf( "Error: %s device not found\n", byt_com);
292  return -1;
293  }
294 
295  device = (int) ((ushort) CatEntry.ide);
296  unit = (int) CatEntry.id;
297 
298  /*
299  * Ger� reservieren
300  */
301  if( RmIO( BYT_RESERVE, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock ) < 0 )
302  {
303  printf( "Error: Unable to reserve %s device\n", byt_com);
304  return -1;
305  }
306 
307  /*
308  * Baudrate ausrechnen
309  */
310  baudrate = 9600;
311  if(speed == B50 ) baudrate = 50;
312  if(speed == B75 ) baudrate = 75;
313  if(speed == B110 ) baudrate = 110;
314  if(speed == B134 ) baudrate = 134;
315  if(speed == B150 ) baudrate = 150;
316  if(speed == B200 ) baudrate = 200;
317  if(speed == B300 ) baudrate = 300;
318  if(speed == B600 ) baudrate = 600;
319  if(speed == B1200 ) baudrate = 1200;
320  if(speed == B1800 ) baudrate = 1800;
321  if(speed == B2400 ) baudrate = 2400;
322  if(speed == B4800 ) baudrate = 4800;
323  if(speed == B9600 ) baudrate = 9600;
324  if(speed == B19200 ) baudrate = 19200;
325  if(speed == B38400 ) baudrate = 38400;
326  if(speed == B57600 ) baudrate = 57600;
327  if(speed == B115200 ) baudrate = 115200;
328  if(speed == B230400 ) baudrate = 230400;
329  if(speed == B460800 ) baudrate = 460800;
330  if(speed == B500000 ) baudrate = 500000;
331  if(speed == B576000 ) baudrate = 576000;
332  if(speed == B921600 ) baudrate = 921600;
333  if(speed == B1000000) baudrate = 1000000;
334  if(speed == B1152000) baudrate = 1152000;
335  if(speed == B1500000) baudrate = 1500000;
336  if(speed == B2000000) baudrate = 2000000;
337  if(speed == B2500000) baudrate = 2500000;
338  if(speed == B3000000) baudrate = 3000000;
339  if(speed == B3500000) baudrate = 3500000;
340  if(speed == B4000000) baudrate = 4000000;
341  uTimeBd = 748800 / baudrate;
342 
343  /*
344  * Portsteuerungsparameter setzen
345  */
346  uMode = 0x1000 | DATA_8 | STOP_1 | NOPARITY;
347 
348  /*
349  * UCD des seriellen Ports auslesen
350  */
351  PBlock.string = 0;
352  PBlock.strlen = 0;
353  PBlock.buffer = (char *)&Ucd_byt_drv;
354  PBlock.timlen = sizeof(UCD_BYT_PORT);
355  PBlock.status = 0;
356 
357  iStatus = RmIO( BYT_CREATE_NEW, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock );
358 
359  /*
360  * Modus �dern
361  */
362  Ucd_byt_drv.mobyte[5] |= (ushort) (uMode & 0xFFu);
363 
364  /*
365  * Timeout setzen
366  */
367  Ucd_byt_drv.header.timout = timeout;
368 
369  /*
370  * Werte zuweisen
371  */
372  PBlock.string = (char*) &Ucd_byt_drv;
373  PBlock.strlen = sizeof(UCD_BYT_PORT);
374  PBlock.buffer = 0;
375  PBlock.timlen = 0;
376  PBlock.status = 0;
377 
378  iStatus = RmIO( BYT_CREATE_NEW, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock );
379 
380  /*
381  * Register 0 und 1 zum Schreiben freigeben
382  */
383  cByte = inbyte( com + 0x03 );
384  outbyte( com + 0x03, (unsigned char)(cByte | 0x80) );
385 
386  /*
387  * Baudrate setzen
388  */
389  outbyte( com + 0x00, (ushort) LOW (uTimeBd) );
390  outbyte( com + 0x01, (ushort) HIGH (uTimeBd) );
391 
392  /*
393  * Register 0 und 1 sperren
394  */
395  outbyte( com + 0x03, cByte );
396 
397  if( iStatus ) printf( "BYT_CREATE_NEW (set ucb): Error status = %X\n", iStatus );
398 #endif
399 
400  return 0;
401 }
402 
404 {
405 #ifdef RLUNIX
406  int ret;
407  unsigned char buf[2];
408 
409  if(fd == -1) return -1;
410  ret = read(fd,buf,1);
411  if(ret == 1) return buf[0];
412  if(ret == 0) return -2;
413  return -1;
414 #endif
415 
416 #ifdef __VMS
417  unsigned char buf[2];
418 
419  if(readBlock(buf, 1) < 0) return -1;
420  return buf[0];
421 #endif
422 
423 #ifdef RLWIN32
424  BOOL ret;
425  unsigned char buf[2];
426  unsigned long len;
427 
428  ret = ReadFile(
429  hdl, // handle of file to read
430  buf, // pointer to buffer that receives data
431  1, // number of bytes to read
432  &len, // pointer to number of bytes read
433  NULL // pointer to structure for data
434  );
435  if(len > 0)
436  {
437  if(trace == 1) printf("readChar %d\n",(int) buf[0]);
438  return buf[0];
439  }
440  return -1;
441 #endif
442 
443 #ifdef RM3
444  int ret;
445  unsigned char buf[2];
446 
447  ret = readBlock(buf,1);
448  if(ret < 0) return ret;
449  return buf[0];
450 #endif
451 }
452 
453 int rlSerial::writeChar(unsigned char uchar)
454 {
455 #ifdef RLUNIX
456  int ret;
457  if(fd == -1) return -1;
458  if(trace == 1) printf("writeChar %d\n",(int)uchar);
459  ret = write(fd,&uchar,1);
460  if(ret < 0) return -1;
461  //tcflush(fd, TCIOFLUSH);
462  return ret;
463 #endif
464 
465 #ifdef __VMS
466  int status;
467  IOSB iosb;
468 
469  status = SYS$QIOW(0,vms_channel,IO$_WRITEVBLK | IO$M_CANCTRLO | IO$M_NOFORMAT,
470  &iosb,0,0,&uchar,1,0,0,0,0);
471  if(status != SS$_NORMAL) return -1;
472  return 1;
473 #endif
474 
475 #ifdef RLWIN32
476  BOOL ret;
477  unsigned long len;
478 
479  if(trace == 1) printf("writeChar %d\n",(int)uchar);
480  ret = WriteFile(
481  hdl, // handle to file to write to
482  &uchar, // pointer to data to write to file
483  1, // number of bytes to write
484  &len, // pointer to number of bytes written
485  NULL // pointer to structure for overlapped I/O
486  );
487 
488  if(ret) return (int) len;
489  return -1;
490 #endif
491 
492 #ifdef RM3
493  return writeBlock(&uchar, 1);
494 #endif
495 }
496 
497 int rlSerial::readBlock(unsigned char *buf, int len, int timeout)
498 {
499 #ifdef RLUNIX
500  int c, retlen;
501 
502  retlen = 0;
503  for(int i=0; i<len; i++)
504  {
505  if(timeout >= 0)
506  {
507  if(select(timeout) == 0) break; // timeout
508  }
509  c = readChar();
510  if(c < 0) return c;
511  buf[i] = (unsigned char) c;
512  retlen = i+1;
513  }
514  if(retlen <= 0) return -1;
515  return retlen;
516 #endif
517 
518 #ifdef __VMS
519  int status;
520  int _timeout = 1; // second
521  short iosb[4];
522 
523  status = SYS$QIOW(0,vms_channel,
524  IO$_READVBLK | IO$M_NOFILTR | IO$M_NOECHO | IO$M_TIMED,
525  iosb,0,0,buf,len,_timeout,0,0,0);
526  if(status != SS$_NORMAL) return -1;
527  len=iosb[1];
528  if(iosb[2] != 0)
529  {
530  len++;
531  buf[len] = iosb[2];
532  }
533  return len;
534 #endif
535 
536 #ifdef RLWIN32
537  BOOL ret;
538  unsigned long retlen;
539 
540  if(timeout >= 0) select(timeout);
541  ret = ReadFile(
542  hdl, // handle of file to read
543  buf, // pointer to buffer that receives data
544  len, // number of bytes to read
545  &retlen, // pointer to number of bytes read
546  NULL // pointer to structure for data
547  );
548  if(retlen > 0)
549  {
550  if(trace == 1) printf("readBlock retlen=%d\n",retlen);
551  return (int) retlen;
552  }
553  return -1;
554 #endif
555 
556 #ifdef RM3
557  RmBytParmStruct PBlock; /* Parameterstruktur fr RmIO - Funktion */
558  RmIOStatusStruct DrvSts; /* Struktur der Rckgabewerte fr RmIO - Funktion */
559  int iStatus; /* Rckgabewert */
560  int i; /* Schleifenz�ler */
561  /**************************************************/
562 
563  /*
564  * Schreibparameter setzen
565  */
566  PBlock.string = 0;
567  PBlock.strlen = 0;
568  PBlock.buffer = (char*)buf;
569  PBlock.timlen = len;
570  PBlock.status = 0;
571 
572  /*
573  * Lesevorgang einleiten
574  */
575  iStatus = RmIO( BYT_POLL_XBUF_WAIT, (unsigned)device, (unsigned)unit, 0u, 0u, &DrvSts, &PBlock );
576 
577  if( iStatus ) printf( "BYT_POLL_XBUF_WAIT (set ucb): Error status = %X\n", iStatus );
578 
579  if( !iStatus ) return len;
580  return -1;
581 #endif
582 }
583 
584 int rlSerial::writeBlock(const unsigned char *buf, int len)
585 {
586 #ifdef RLUNIX
587  int ret;
588 
589  if(fd == -1) return -1;
590  if(trace == 1)
591  {
592  printf("writeBlock:");
593  for(int i=0; i<len; i++) printf(" %d",(int) buf[i]);
594  printf("\n");
595  }
596  ret = write(fd,buf,len);
597  //tcflush(fd, TCIOFLUSH);
598  return ret;
599 #endif
600 
601 #ifdef __VMS
602  int status;
603  IOSB iosb;
604 
605 
606  status = SYS$QIOW(0,vms_channel,IO$_WRITEVBLK | IO$M_CANCTRLO | IO$M_NOFORMAT,
607  &iosb,0,0,buf,len,0,0,0,0);
608  if(status != SS$_NORMAL) return -1;
609  return len;
610 #endif
611 
612 #ifdef RLWIN32
613  BOOL ret;
614  unsigned long retlen;
615 
616  if(trace == 1)
617  {
618  printf("writeBlock:");
619  for(int i=0; i<len; i++) printf(" %d",(int) buf[i]);
620  printf("\n");
621  }
622  retlen = len;
623  ret = WriteFile(
624  hdl, // handle to file to write to
625  buf, // pointer to data to write to file
626  len, // number of bytes to write
627  &retlen, // pointer to number of bytes written
628  NULL // pointer to structure for overlapped I/O
629  );
630 
631  if(ret) return (int) retlen;
632  return -1;
633 #endif
634 
635 #ifdef RM3
636  RmBytParmStruct PBlock; /* Parameterstruktur fr RmIO - Funktion */
637  RmIOStatusStruct DrvSts; /* Struktur der Rckgabewerte fr RmIO - Funktion */
638  unsigned char cByte; /* Rckgabewert von ibyte - Funktion */
639  int iStatus; /* Rckgabewert */
640  int i; /* Schleifenz�ler */
641  /**************************************************/
642 
643  /*
644  * Schreibparameter setzen
645  */
646  PBlock.string = (char*)buf;
647  PBlock.strlen = len;
648  PBlock.buffer = 0;
649  PBlock.timlen = 0;
650  PBlock.status = 0;
651 
652  /******************************************************
653  * *
654  * Toggle mode wird emuliert indem an dieser Stelle *
655  * RTS-Signal gesetzt und sp�er wieder gel�cht wird *
656  * *
657  ******************************************************/
658 
659  cByte = inbyte( com + 0x04u );
660  outbyte( com + 0x04, (unsigned char)(cByte | 0x02u) );
661 
662  /*
663  * Schreibvorgang einleiten
664  */
665  iStatus = RmIO( BYT_WRITE_WAIT, (unsigned)device, (unsigned)unit, 0u, 0u, &DrvSts, &PBlock );
666 
667  /******************************************************************
668  * *
669  * 8ms warten.Bei der Aenderung der Uebertragungsgeschwindigkeit, *
670  * sollte dieser Wert angepasst werden. Hier fuer 9600 *
671  * *
672  ******************************************************************/
673  RmPauseTask((RTS_TIME_WAIT*9600)/baudrate);
674 
675  /*
676  * RTS-Signal l�chen
677  */
678  outbyte( com + 0x04, (unsigned char)(cByte & 0xFDu) );
679 
680  if( iStatus ) printf( "BYT_WRITE_WAIT (write block): Error status = %X\n", iStatus );
681 
682  if( !iStatus ) return len;
683  return -1;
684 #endif
685 }
686 
687 int rlSerial::readLine(unsigned char *buf, int maxlen, int timeout)
688 {
689  int i,c,ret;
690 
691  if(maxlen <= 1) return -1;
692  ret = 0;
693  buf[maxlen-1] = '\0';
694  for(i=0; i<maxlen-2; i++)
695  {
696  ret = i;
697  if(timeout > 0)
698  {
699  int t = select(timeout);
700  if(t == 0) return -1;
701  }
702  c = readChar();
703  if(c < 0)
704  {
705  buf[i] = '\0';
706  ret = c;
707  break;
708  }
709  buf[i] = (unsigned char) c;
710  if(c < ' ' && c != '\t')
711  {
712  buf[i+1] = '\0';
713  break;
714  }
715  }
716  return ret;
717 }
718 
719 int rlSerial::select(int timeout)
720 {
721 #ifdef RLUNIX
722  struct timeval timout;
723  fd_set wset,rset,eset;
724  int ret,maxfdp1;
725 
726  if(timeout <= 0) return 1;
727  /* setup sockets to read */
728  maxfdp1 = fd+1;
729  FD_ZERO(&rset);
730  FD_SET (fd,&rset);
731  FD_ZERO(&wset);
732  FD_ZERO(&eset);
733  timout.tv_sec = timeout / 1000;
734  timout.tv_usec = (timeout % 1000) * 1000;
735 
736  ret = ::select(maxfdp1,&rset,&wset,&eset,&timout);
737  if(ret == 0) return 0; /* timeout */
738  return 1;
739 #endif
740 
741 #ifdef __VMS
742  return 1;
743 #endif
744 
745 #ifdef RLWIN32
746  COMMTIMEOUTS ctimeout;
747 
748  ctimeout.ReadIntervalTimeout = timeout;
749  ctimeout.ReadTotalTimeoutMultiplier = 1;
750  ctimeout.ReadTotalTimeoutConstant = timeout;
751  ctimeout.WriteTotalTimeoutMultiplier = 1;
752  ctimeout.WriteTotalTimeoutConstant = timeout;
753 
754  SetCommTimeouts(hdl, &ctimeout);
755  return 1;
756 #endif
757 
758 #ifdef RM3
759  return 1;
760 #endif
761 }
762 
764 {
765 #ifdef RLUNIX
766  if(fd == -1) return -1;
767  //if(::tcsetattr(fd,TCSAFLUSH,&save_termios) < 0) return -1;
768  if(::tcsetattr(fd,TCSANOW,&save_termios) < 0) return -1;
769  ::close(fd);
770  ttystate = RESET;
771  fd = -1;
772  return 0;
773 #endif
774 
775 #ifdef __VMS
776  sys$dassgn(vms_channel);
777  return 0;
778 #endif
779 
780 #ifdef RLWIN32
781  CloseHandle(hdl);
782  return 0;
783 #endif
784 
785 #ifdef RM3
786  RmBytParmStruct PBlock; /* Parameterstruktur fr RmIO - Funktion */
787  RmIOStatusStruct DrvSts; /* Struktur der Rckgabewerte fr RmIO - Funktion */
788  /**************************************************/
789  if( RmIO( BYT_RELEASE, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock ) < 0 )
790  {
791  printf( "Error: Unable to release device. device: %i, unit: %i\n",device, unit );
792  return -1;
793  }
794  return 0;
795 #endif
796 }