Raw File
1 #include <termios.h>
2 #include <sys/ioctl.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5
6 #include "debug.h"
7 #include "serial.h"
8 #include "modem_core.h"
9 #include "ip232.h" // needs modem_core.h
10 #include "dce.h"
11
12 void dce_init_config(dce_config *cfg) {
13 cfg->parity = -1; // parity not yet checked.
14 }
15
16 int detect_parity (int charA, int charT) {
17 int parity, eobits;
18
19 parity = ((charA >> 6) & 2) | (charT >> 7);
20 eobits = gen_parity(charA & 0x7f) << 1 | gen_parity(charT & 0x7f);
21
22 if((parity == 1) || (parity == 2)) {
23 if(parity == eobits)
24 return PARITY_EVEN;
25 else
26 return PARITY_ODD;
27 } else
28 return parity;
29 }
30
31 int dce_connect(dce_config *cfg) {
32 int rc;
33
34 LOG_ENTER();
35 if (cfg->is_ip232) {
36 rc = ip232_init_conn(cfg);
37 } else {
38 rc = ser_init_conn(cfg->tty, cfg->port_speed);
39 if(-1 < rc) {
40 cfg->is_connected = TRUE;
41 cfg->ofd = rc;
42 cfg->ifd = rc;
43 }
44 }
45
46 LOG_EXIT();
47 return rc;
48 }
49
50 int dce_set_flow_control(dce_config *cfg, int opts) {
51 int status = 0;
52 int rc = 0;
53
54 LOG_ENTER();
55 if(opts == 0) {
56 LOG(LOG_ALL, "Setting NONE flow control");
57 } else {
58 if((opts & MDM_FC_RTS) != 0) {
59 LOG(LOG_ALL, "Setting RTSCTS flow control");
60 status |= CRTSCTS;
61 }
62 if((opts & MDM_FC_XON) != 0) {
63 status |= (IXON | IXOFF);
64 LOG(LOG_ALL, "Setting XON/XOFF flow control");
65 }
66 }
67
68 if (cfg->is_ip232) {
69 rc = ip232_set_flow_control(cfg, status);
70 } else {
71 rc = ser_set_flow_control(cfg->ofd, status);
72 }
73
74 LOG_EXIT()
75 return rc;
76 }
77
78 int dce_set_control_lines(dce_config *cfg, int state) {
79 int rc;
80
81 LOG_ENTER();
82 // if((state & DCE_CL_CTS) != 0) {
83 // LOG(LOG_ALL, "Setting CTS pin high");
84 // } else {
85 // LOG(LOG_ALL, "Setting CTS pin low");
86 // }
87 if((state & DCE_CL_DCD) != 0) {
88 LOG(LOG_ALL, "Setting DCD pin high");
89 } else {
90 LOG(LOG_ALL, "Setting DCD pin low");
91 }
92
93 if((state & DCE_CL_RI) != 0) {
94 LOG(LOG_ALL, "Setting RI pin high");
95 } else {
96 LOG(LOG_ALL, "Setting RI pin low");
97 }
98
99 if (cfg->is_ip232) {
100 rc = ip232_set_control_lines(cfg, state);
101 } else {
102 rc = ser_set_control_lines(cfg->ofd, state);
103 }
104
105 LOG_EXIT();
106 return rc;
107 }
108
109 int dce_get_control_lines(dce_config *cfg) {
110 int state;
111
112 if (cfg->is_ip232) {
113 state = ip232_get_control_lines(cfg);
114 } else {
115 state = ser_get_control_lines(cfg->ifd);
116 }
117 return state;
118 }
119
120 int dce_check_control_lines(dce_config *cfg) {
121 int state = 0;
122 int new_state = 0;
123
124 LOG_ENTER();
125 state = dce_get_control_lines(cfg);
126 new_state = state;
127 while(new_state > -1 && state == new_state) {
128 usleep(100000);
129 new_state = dce_get_control_lines(cfg);
130 }
131
132 LOG_EXIT();
133 return new_state;
134 }
135
136 int dce_write(dce_config *cfg, unsigned char data[], int len) {
137 unsigned char *buf;
138 int rc;
139 int i;
140
141 log_trace(TRACE_SERIAL_OUT, data, len);
142 if (cfg->is_ip232) {
143 return ip232_write(cfg, data, len);
144 } else if(cfg->parity) {
145 buf = malloc(len); // TODO what if malloc fails?
146 memcpy(buf, data, len);
147
148 if(0 < cfg->parity) {
149 for (i = 0; i < len; i++) {
150 buf[i] = apply_parity(data[i], cfg->parity);
151 }
152 }
153 } else {
154 buf = data;
155 }
156 rc = ser_write(cfg->ofd, buf, len);
157 if(cfg->parity)
158 free(buf);
159 return rc;
160 }
161
162 int dce_write_char_raw(dce_config *cfg, unsigned char data) {
163 int rc;
164
165 log_trace(TRACE_SERIAL_OUT, &data, 1);
166 if (cfg->is_ip232) {
167 rc = ip232_write(cfg, &data, 1);
168 } else {
169 rc = ser_write(cfg->ofd, &data, 1);
170 }
171 return rc;
172 }
173
174 int dce_read(dce_config *cfg, unsigned char data[], int len) {
175 int res;
176 int i;
177
178 if (cfg->is_ip232) {
179 res = ip232_read(cfg, data, len);
180 } else {
181 res = ser_read(cfg->ifd, data, len);
182 }
183 if(0 < res) {
184 LOG(LOG_DEBUG, "Read %d bytes from serial port", res);
185 if(0 < cfg->parity) {
186 for (i = 0; i < res; i++) {
187 data[i] &= 0x7f; // strip parity from returned data
188 }
189 }
190 log_trace(TRACE_SERIAL_IN, data, res);
191 }
192 return res;
193 }
194
195 int dce_read_char_raw(dce_config *cfg) {
196 int res;
197 unsigned char data[1];
198
199 if (cfg->is_ip232) {
200 res = ip232_read(cfg, data, 1);
201 } else {
202 res = ser_read(cfg->ifd, data, 1);
203 }
204 if(0 < res) {
205 res = data[0];
206 LOG(LOG_DEBUG, "Read 1 raw byte from serial port");
207 log_trace(TRACE_SERIAL_IN, data, 1);
208 }
209 return res;
210 }
211
212 void dce_detect_parity(dce_config *cfg, unsigned char a, unsigned char t) {
213 cfg->parity = detect_parity(a, t);
214 }
215
216 int dce_strip_parity(dce_config *cfg, unsigned char data) {
217 return (cfg->parity ? data & 0x7f : data);
218 }
219
220 int dce_get_parity(dce_config *cfg) {
221 return cfg->parity;
222 }
223
224
Generated by GNU Enscript 1.6.6, and GophHub 1.3.