Raw File
1 #include <sys/file.h>
2 #include <unistd.h>
3 #include <termios.h>
4 #include <stdio.h>
5 #include <fcntl.h>
6 #include <sys/ioctl.h>
7 #include "dce.h"
8 #include "debug.h"
9
10 #include "serial.h"
11
12 int ser_get_bps_const(int speed) {
13 int bps_rate = 0;
14
15 LOG_ENTER();
16
17 LOG(LOG_DEBUG,"Checking speed: %d",speed);
18
19 switch (speed) {
20 #if defined (B921600)
21 case 921600:
22 bps_rate = B921600;
23 break;
24 #endif /* B921600 */
25 #if defined (B460800)
26 case 460800:
27 bps_rate = B460800;
28 break;
29 #endif /* B460800 */
30 #if defined (B230400)
31 case 230400:
32 bps_rate = B230400;
33 break;
34 #endif /* B230400 */
35 #if defined (B115200)
36 case 115200:
37 bps_rate = B115200;
38 break;
39 #endif /* B115200 */
40 #if defined (B57600)
41 case 57600:
42 bps_rate = B57600;
43 break;
44 #endif /* B57600 */
45 #if defined (B38400)
46 case 38400:
47 bps_rate = B38400;
48 break;
49 #endif /* B38400 */
50 #if defined (B19200)
51 case 19200:
52 bps_rate = B19200;
53 break;
54 #endif /* B19200 */
55 #if defined (B9600)
56 case 9600:
57 bps_rate = B9600;
58 break;
59 #endif /* B9600 */
60 #if defined (B4800)
61 case 4800:
62 bps_rate = B4800;
63 break;
64 #endif /* B4800 */
65 #if defined (B2400)
66 case 2400:
67 bps_rate = B2400;
68 break;
69 #endif /* B2400 */
70 #if defined (B1200)
71 case 1200:
72 bps_rate = B1200;
73 break;
74 #endif /* B1200 */
75 #if defined (B600)
76 case 600:
77 bps_rate = B600;
78 break;
79 #endif /* B600 */
80 #if defined (B300)
81 case 300:
82 bps_rate = B300;
83 break;
84 #endif /* B300 */
85 #if defined (B150)
86 case 150:
87 bps_rate = B150;
88 break;
89 #endif /* B150 */
90 #if defined (B134)
91 case 134:
92 bps_rate = B134;
93 break;
94 #endif /* B134 */
95 #if defined (B110)
96 case 110:
97 bps_rate = B110;
98 break;
99 #endif /* B110 */
100 #if defined (B75)
101 case 75:
102 bps_rate = B75;
103 break;
104 #endif /* B75 */
105 #if defined (B50)
106 case 50:
107 bps_rate = B50;
108 break;
109 #endif /* B50 */
110 #if defined (B0)
111 case 0:
112 bps_rate = B0;
113 break;
114 #endif /* B0 */
115 default:
116 ELOG(LOG_FATAL, "Unknown baud rate");
117 bps_rate = -1;
118 }
119 LOG_EXIT();
120 return bps_rate;
121
122 }
123
124 int ser_init_conn(char *tty, int speed) {
125 int fd = -1;
126 struct termios tio;
127 int bps_rate = 0;
128
129 LOG_ENTER();
130
131 bps_rate = ser_get_bps_const(speed);
132
133 if(bps_rate > -1) {
134 /* open the device to be non-blocking (read will return immediatly) */
135 LOG(LOG_INFO, "Opening serial device %s at speed %d", tty, speed);
136
137 fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK);
138
139 if (fd <0) {
140 ELOG(LOG_FATAL, "TTY %s could not be opened", tty);
141 } else {
142 LOG(LOG_INFO, "Opened serial device %s at speed %d as fd %d", tty, speed, fd);
143
144 /* Make the file descriptor asynchronous (the manual page says only
145 O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
146 fcntl(fd, F_SETFL, FASYNC);
147
148 if (0 != tcgetattr(fd, &tio)) {
149 ELOG(LOG_FATAL, "Could not get serial port attributes");
150 return -1;
151 }
152
153 // leave CRTSCTS off when building for Windows on Rapsberry Pi...
154 // https://github.com/driver1998/tcpser
155 #ifdef WIN_RPI
156 tio.c_cflag = CS8 | CLOCAL | CREAD;
157 #else
158 tio.c_cflag = CS8 | CLOCAL | CREAD | CRTSCTS;
159 #endif
160 tio.c_iflag = IGNBRK;
161 tio.c_oflag = 0;
162 tio.c_lflag = 0;
163 cfsetispeed(&tio, bps_rate);
164 cfsetospeed(&tio, bps_rate);
165
166 tio.c_cc[VMIN] = 1;
167 tio.c_cc[VTIME] = 0;
168
169 tcflush(fd, TCIFLUSH);
170 tcsetattr(fd, TCSANOW, &tio);
171 LOG(LOG_INFO, "serial device configured");
172 }
173 }
174
175 LOG_EXIT();
176 return fd;
177 }
178
179 int ser_set_flow_control(int fd, int status) {
180 struct termios tio;
181 if(0 != tcgetattr(fd, &tio)) {
182 ELOG(LOG_FATAL, "Could not get serial port attributes");
183 return -1;
184 }
185 // turn all off.
186 tio.c_cflag &= ~(IXON | IXOFF | CRTSCTS);
187 tio.c_cflag |= status;
188 if(0 != tcsetattr(fd, TCSANOW, &tio)) {
189 ELOG(LOG_FATAL,"Could not set serial port attributes");
190 return -1;
191 }
192 return 0;
193 }
194
195 int ser_get_control_lines(int fd) {
196 int status;
197
198 if(0 > ioctl(fd, TIOCMGET, &status)) {
199 ELOG(LOG_FATAL, "Could not obtain serial port status");
200 return -1;
201 }
202
203 return (DCE_CL_LE // RS232 link is always up.
204 | ((status & TIOCM_DSR) ? DCE_CL_DTR : 0)
205 //| ((status & TIOCM_CTS) ? DCE_CL_RTS : 0)
206 );
207 }
208
209 int ser_set_control_lines(int fd, int state) {
210 int status;
211
212 if(0 > ioctl(fd, TIOCMGET, &status)) {
213 ELOG(LOG_FATAL, "Could not obtain serial port status");
214 return -1;
215 }
216
217 status &= ~(TIOCM_DTR);
218 //status &= ~(TIOCM_RTS | TIOCM_DTR);
219 status |= (state & DCE_CL_DCD ? TIOCM_DTR : 0);
220 //status |= (state & DCE_CL_CTS ? TIOCM_RTS : 0);
221 if(0 > ioctl(fd, TIOCMSET, &status)) {
222 ELOG(LOG_WARN, "Could not set serial port status");
223 }
224 return 0;
225 }
226
227 int ser_write(int fd, unsigned char* data, int len) {
228 log_trace(TRACE_MODEM_OUT, data, len);
229 return write(fd, data, len);
230 }
231
232 int ser_read(int fd, unsigned char* data, int len) {
233 int res;
234
235 res = read(fd, data, len);
236 log_trace(TRACE_MODEM_IN, data, res);
237 return res;
238 }
239
Generated by GNU Enscript 1.6.6, and GophHub 1.3.