comio_nix.c 5.17 KB
Newer Older
deuce's avatar
deuce committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* comio_nix.c */

/* Synchronet Serial Communications I/O Library Functions for *nix */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
 * Copyright 2007 Rob Swindell - http://www.synchro.net/copyright.html		*
 *																			*
 * This library is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU Lesser General Public License		*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU Lesser General Public License for more details: lgpl.txt or	*
 * http://www.fsf.org/copyleft/lesser.html									*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

deuce's avatar
deuce committed
38
#include <sys/ioctl.h>
deuce's avatar
deuce committed
39
40
41
42
#include <sys/file.h>
#include "comio.h"
#include "genwrap.h"

deuce's avatar
DLL-ify    
deuce committed
43
char* COMIOCALL comVersion(char* str, size_t len)
deuce's avatar
deuce committed
44
45
46
47
48
49
50
51
52
{
	char revision[16];

	sscanf("$Revision$", "%*s %s", revision);

	safe_snprintf(str,len,"Synchronet Communications I/O Library for "PLATFORM_DESC" v%s", revision);
	return str;
}

deuce's avatar
DLL-ify    
deuce committed
53
COM_HANDLE COMIOCALL comOpen(const char* device)
deuce's avatar
deuce committed
54
55
56
57
{
	COM_HANDLE handle;
	struct termios t;

deuce's avatar
deuce committed
58
	if((handle=open(device, O_NONBLOCK|O_RDWR))==COM_HANDLE_INVALID)
deuce's avatar
deuce committed
59
60
61
		return COM_HANDLE_INVALID;

	if(tcgetattr(handle, &t)==-1) {
deuce's avatar
deuce committed
62
		close(handle);
deuce's avatar
deuce committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
		return COM_HANDLE_INVALID;
	}

	t.c_iflag = (
				  IGNBRK   /* ignore BREAK condition */
				| IGNPAR   /* ignore (discard) parity errors */
				);
	t.c_oflag = 0;	/* No output processing */
	t.c_cflag = (
				  CS8         /* 8 bits */
				| CREAD       /* enable receiver */
/*
Fun snippet from the FreeBSD manpage:

     If CREAD is set, the receiver is enabled.  Otherwise, no character is
     received.  Not all hardware supports this bit.  In fact, this flag is
     pretty silly and if it were not part of the termios specification it
     would be omitted.
*/
				| HUPCL       /* hang up on last close */
				| CLOCAL      /* ignore modem status lines */
/* The next two are pretty much never used */
#ifdef CCTX_OFLOW
				| CCTS_OFLOW  /* CTS flow control of output */
#endif
#ifdef CRTSCTS
				| CRTSCTS     /* same as CCTS_OFLOW */
#endif
#ifdef CRTS_IFLOW
				| CRTS_IFLOW  /* RTS flow control of input */
#endif
				);
	t.c_lflag = 0;	/* No local modes */
	if(tcsetattr(handle, TCSANOW, &t)==-1) {
deuce's avatar
deuce committed
97
		close(handle);
deuce's avatar
deuce committed
98
99
100
101
102
103
		return COM_HANDLE_INVALID;
	}
	
	return handle;
}

deuce's avatar
DLL-ify    
deuce committed
104
BOOL COMIOCALL comClose(COM_HANDLE handle)
deuce's avatar
deuce committed
105
106
107
108
{
	return (!close(handle));
}

deuce's avatar
DLL-ify    
deuce committed
109
long COMIOCALL comGetBaudRate(COM_HANDLE handle)
deuce's avatar
deuce committed
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{
	struct termios t;
	speed_t	in;
	speed_t	out;

	if(tcgetattr(handle, &t))
		return COM_ERROR;

	/* 
	 * We actually have TWO speeds available...
	 * return the biggest one
	 */
	in = cfgetispeed(&t);
	out = cfgetospeed(&t);
	return ((long)(in>out?in:out));
}

deuce's avatar
DLL-ify    
deuce committed
127
BOOL COMIOCALL comSetBaudRate(COM_HANDLE handle, unsigned long rate)
deuce's avatar
deuce committed
128
129
130
131
132
133
{
	struct termios t;

	if(tcgetattr(handle, &t))
		return FALSE;

deuce's avatar
deuce committed
134
135
	cfsetispeed(&t, rate);
	cfsetospeed(&t, rate);
deuce's avatar
deuce committed
136
137
138
139
140
141
	if(tcsetattr(handle, TCSANOW, &t)==-1)
		return FALSE;

	return TRUE;
}

deuce's avatar
DLL-ify    
deuce committed
142
int COMIOCALL comGetModemStatus(COM_HANDLE handle)
deuce's avatar
deuce committed
143
144
145
146
147
148
149
150
151
{
	int status;

	if(ioctl(handle, TIOCMGET, &status)==-1)
		return COM_ERROR;

	return status;
}

deuce's avatar
DLL-ify    
deuce committed
152
BOOL COMIOCALL comRaiseDTR(COM_HANDLE handle)
deuce's avatar
deuce committed
153
{
154
	int flags = TIOCM_DTR;
deuce's avatar
deuce committed
155
	return(ioctl(handle, TIOCMBIS, &flags)==0);
deuce's avatar
deuce committed
156
157
}

deuce's avatar
DLL-ify    
deuce committed
158
BOOL COMIOCALL comLowerDTR(COM_HANDLE handle)
deuce's avatar
deuce committed
159
{
160
	int flags = TIOCM_DTR;
deuce's avatar
deuce committed
161
	return(ioctl(handle, TIOCMBIC, &flags)==0);
deuce's avatar
deuce committed
162
163
}

deuce's avatar
DLL-ify    
deuce committed
164
BOOL COMIOCALL comWriteByte(COM_HANDLE handle, BYTE ch)
deuce's avatar
deuce committed
165
166
167
168
{
	return(write(handle, &ch, 1)==1);
}

deuce's avatar
DLL-ify    
deuce committed
169
int COMIOCALL comWriteBuf(COM_HANDLE handle, const BYTE* buf, size_t buflen)
deuce's avatar
deuce committed
170
{
deuce's avatar
deuce committed
171
	return write(handle, buf, buflen);
deuce's avatar
deuce committed
172
173
174
175
176
}

/*
 * TODO: This seem kinda dangerous for short writes...
 */
deuce's avatar
DLL-ify    
deuce committed
177
int COMIOCALL comWriteString(COM_HANDLE handle, const char* str)
deuce's avatar
deuce committed
178
{
deuce's avatar
deuce committed
179
	return comWriteBuf(handle, (BYTE*)str, strlen(str));
deuce's avatar
deuce committed
180
181
}

deuce's avatar
DLL-ify    
deuce committed
182
BOOL COMIOCALL comReadByte(COM_HANDLE handle, BYTE* ch)
deuce's avatar
deuce committed
183
184
185
186
{
	return(read(handle, ch, 1)==1);
}

deuce's avatar
DLL-ify    
deuce committed
187
BOOL COMIOCALL comPurgeInput(COM_HANDLE handle)
deuce's avatar
deuce committed
188
{
deuce's avatar
deuce committed
189
	return(tcflush(handle, TCIFLUSH)==0);
deuce's avatar
deuce committed
190
191
}

deuce's avatar
DLL-ify    
deuce committed
192
BOOL COMIOCALL comPurgeOutput(COM_HANDLE handle)
deuce's avatar
deuce committed
193
{
deuce's avatar
deuce committed
194
	return(tcflush(handle, TCOFLUSH)==0);
deuce's avatar
deuce committed
195
196
}

deuce's avatar
DLL-ify    
deuce committed
197
BOOL COMIOCALL comDrainOutput(COM_HANDLE handle)
198
199
200
{
	return(tcdrain(handle)==0);
}