summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device/serial
Unidiff
Diffstat (limited to 'gammu/emb/common/device/serial') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/device/serial/ser_djg.c74
-rw-r--r--gammu/emb/common/device/serial/ser_djg.h15
-rw-r--r--gammu/emb/common/device/serial/ser_unx.c291
-rw-r--r--gammu/emb/common/device/serial/ser_unx.h22
-rw-r--r--gammu/emb/common/device/serial/ser_w32.c340
-rw-r--r--gammu/emb/common/device/serial/ser_w32.h19
6 files changed, 761 insertions, 0 deletions
diff --git a/gammu/emb/common/device/serial/ser_djg.c b/gammu/emb/common/device/serial/ser_djg.c
new file mode 100644
index 0000000..ac9d7c8
--- a/dev/null
+++ b/gammu/emb/common/device/serial/ser_djg.c
@@ -0,0 +1,74 @@
1
2#include "../../gsmstate.h"
3
4#ifdef GSM_ENABLE_SERIALDEVICE
5#ifdef DJGPP
6
7#include "../../gsmcomon.h"
8#include "ser_djg.h"
9
10static GSM_Error serial_close(GSM_StateMachine *s)
11{
12 GSM_Device_SerialData *d = &s->Device.Data.Serial;
13
14 return ERR_NONE;
15}
16
17static GSM_Error serial_open (GSM_StateMachine *s)
18{
19 GSM_Device_SerialData *d = &s->Device.Data.Serial;
20
21 return ERR_NONE;
22}
23
24static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity)
25{
26 GSM_Device_SerialData *d = &s->Device.Data.Serial;
27
28 return ERR_NONE;
29}
30
31static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts)
32{
33 GSM_Device_SerialData *d = &s->Device.Data.Serial;
34
35 return ERR_NONE;
36}
37
38static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed)
39{
40 GSM_Device_SerialData *d = &s->Device.Data.Serial;
41
42 return ERR_NONE;
43}
44
45static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes)
46{
47 GSM_Device_SerialData *d = &s->Device.Data.Serial;
48
49 return 0;
50}
51
52static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes)
53{
54 GSM_Device_SerialData *d = &s->Device.Data.Serial;
55
56 return 0;
57}
58
59GSM_Device_Functions SerialDevice = {
60 serial_open,
61 serial_close,
62 serial_setparity,
63 serial_setdtrrts,
64 serial_setspeed,
65 serial_read,
66 serial_write
67};
68
69#endif
70#endif
71
72/* How should editor hadle tabs in this file? Add editor commands here.
73 * vim: noexpandtab sw=8 ts=8 sts=8:
74 */
diff --git a/gammu/emb/common/device/serial/ser_djg.h b/gammu/emb/common/device/serial/ser_djg.h
new file mode 100644
index 0000000..b35b282
--- a/dev/null
+++ b/gammu/emb/common/device/serial/ser_djg.h
@@ -0,0 +1,15 @@
1
2#ifdef DJGPP
3#ifndef djgppserial_h
4#define djgppserial_h
5
6typedef struct {
7 int hPhone;
8} GSM_Device_SerialData;
9
10#endif
11#endif
12
13/* How should editor hadle tabs in this file? Add editor commands here.
14 * vim: noexpandtab sw=8 ts=8 sts=8:
15 */
diff --git a/gammu/emb/common/device/serial/ser_unx.c b/gammu/emb/common/device/serial/ser_unx.c
new file mode 100644
index 0000000..2a87b11
--- a/dev/null
+++ b/gammu/emb/common/device/serial/ser_unx.c
@@ -0,0 +1,291 @@
1/* (c) 2002-2004 by Marcin Wiacek */
2/* locking device and settings all speeds by Michal Cihar */
3
4#include "../../gsmstate.h"
5
6#ifdef GSM_ENABLE_SERIALDEVICE
7#ifndef WIN32
8#ifndef DJGPP
9
10#include <sys/file.h>
11#include <sys/time.h>
12#include <string.h>
13#include <termios.h>
14#include <errno.h>
15
16#include "../../gsmcomon.h"
17#include "ser_unx.h"
18
19static GSM_Error serial_close(GSM_StateMachine *s)
20{
21 GSM_Device_SerialData *d = &s->Device.Data.Serial;
22
23 /* Restores old settings */
24 tcsetattr(d->hPhone, TCSANOW, &d->old_settings);
25
26 /* Closes device */
27 close(d->hPhone);
28
29 return ERR_NONE;
30}
31
32#ifndef O_NONBLOCK
33# define O_NONBLOCK 0
34#endif
35
36static GSM_Error serial_open (GSM_StateMachine *s)
37{
38 GSM_Device_SerialData *d = &s->Device.Data.Serial;
39 struct termios t;
40 int i;
41
42 /* O_NONBLOCK MUST is required to avoid waiting for DCD */
43 d->hPhone = open(s->CurrentConfig->Device, O_RDWR | O_NOCTTY | O_NONBLOCK);
44 if (d->hPhone < 0) {
45 i = errno;
46 GSM_OSErrorInfo(s,"open in serial_open");
47 if (i == 2) return ERR_DEVICENOTEXIST; //no such file or directory
48 if (i == 13) return ERR_DEVICENOPERMISSION;//permission denied
49 return ERR_DEVICEOPENERROR;
50 }
51
52#ifdef TIOCEXCL
53 /* open() calls from other applications shall fail now */
54 ioctl(d->hPhone, TIOCEXCL, (char *) 0);
55#endif
56
57 if (tcgetattr(d->hPhone, &d->old_settings) == -1) {
58 close(d->hPhone);
59 GSM_OSErrorInfo(s,"tcgetattr in serial_open");
60 return ERR_DEVICEREADERROR;
61 }
62
63 if (tcflush(d->hPhone, TCIOFLUSH) == -1) {
64 serial_close(s);
65 GSM_OSErrorInfo(s,"tcflush in serial_open");
66 return ERR_DEVICEOPENERROR;
67 }
68
69 memcpy(&t, &d->old_settings, sizeof(struct termios));
70
71 /* Opening without parity */
72 t.c_iflag = IGNPAR;
73 t.c_oflag = 0;
74 /* disconnect line, 8 bits, enable receiver,
75 * ignore modem lines,lower modem line after disconnect
76 */
77 t.c_cflag = B0 | CS8 | CREAD | CLOCAL | HUPCL;
78 /* enable hardware (RTS/CTS) flow control (NON POSIX) */
79 /* t.c_cflag |= CRTSCTS; */
80 t.c_lflag = 0;
81 t.c_cc[VMIN] = 1;
82 t.c_cc[VTIME] = 0;
83
84 if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) {
85 serial_close(s);
86 GSM_OSErrorInfo(s,"tcsetattr in serial_open");
87 return ERR_DEVICEOPENERROR;
88 }
89
90 /* Making file descriptor asynchronous. */
91 if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) {
92 serial_close(s);
93 GSM_OSErrorInfo(s,"fcntl in serial_open");
94 return ERR_DEVICEOPENERROR;
95 }
96
97 return ERR_NONE;
98}
99
100static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity)
101{
102 GSM_Device_SerialData *d = &s->Device.Data.Serial;
103 struct termios t;
104
105 if (tcgetattr(d->hPhone, &t)) {
106 GSM_OSErrorInfo(s,"tcgetattr in serial_setparity");
107 return ERR_DEVICEREADERROR;
108 }
109
110 if (parity) {
111 t.c_cflag |= (PARENB | PARODD);
112 t.c_iflag = 0;
113 } else {
114 t.c_iflag = IGNPAR;
115 }
116
117 if (tcsetattr(d->hPhone, TCSANOW, &t) == -1){
118 serial_close(s);
119 GSM_OSErrorInfo(s,"tcsetattr in serial_setparity");
120 return ERR_DEVICEPARITYERROR;
121 }
122
123 return ERR_NONE;
124}
125
126static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts)
127{
128 GSM_Device_SerialData *d = &s->Device.Data.Serial;
129 struct termios t;
130 unsigned int flags;
131
132 if (tcgetattr(d->hPhone, &t)) {
133 GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts");
134 return ERR_DEVICEREADERROR;
135 }
136
137#ifdef CRTSCTS
138 /* Disabling hardware flow control */
139 t.c_cflag &= ~CRTSCTS;
140#endif
141
142 if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) {
143 serial_close(s);
144 GSM_OSErrorInfo(s,"tcsetattr in serial_setdtrrts");
145 return ERR_DEVICEDTRRTSERROR;
146 }
147
148 flags = TIOCM_DTR;
149 if (dtr) {
150 ioctl(d->hPhone, TIOCMBIS, &flags);
151 } else {
152 ioctl(d->hPhone, TIOCMBIC, &flags);
153 }
154
155 flags = TIOCM_RTS;
156 if (rts) {
157 ioctl(d->hPhone, TIOCMBIS, &flags);
158 } else {
159 ioctl(d->hPhone, TIOCMBIC, &flags);
160 }
161
162 flags = 0;
163 ioctl(d->hPhone, TIOCMGET, &flags);
164
165 dbgprintf("Serial device:");
166 dbgprintf(" DTR is %s", flags&TIOCM_DTR?"up":"down");
167 dbgprintf(", RTS is %s", flags&TIOCM_RTS?"up":"down");
168 dbgprintf(", CAR is %s", flags&TIOCM_CAR?"up":"down");
169 dbgprintf(", CTS is %s\n", flags&TIOCM_CTS?"up":"down");
170 if (((flags&TIOCM_DTR)==TIOCM_DTR) != dtr) return ERR_DEVICEDTRRTSERROR;
171 if (((flags&TIOCM_RTS)==TIOCM_RTS) != rts) return ERR_DEVICEDTRRTSERROR;
172
173 return ERR_NONE;
174}
175
176static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed)
177{
178 GSM_Device_SerialData *d = &s->Device.Data.Serial;
179 struct termios t;
180 int speed2 = B19200;
181
182 if (tcgetattr(d->hPhone, &t)) {
183 GSM_OSErrorInfo(s,"tcgetattr in serial_setspeed");
184 return ERR_DEVICEREADERROR;
185 }
186
187 smprintf(s, "Setting speed to %d\n", speed);
188
189 switch (speed) {
190 case 50: speed2 = B50; break;
191 case 75: speed2 = B75; break;
192 case 110: speed2 = B110; break;
193 case 134: speed2 = B134; break;
194 case 150: speed2 = B150; break;
195 case 200: speed2 = B200; break;
196 case 300: speed2 = B300; break;
197 case 600: speed2 = B600; break;
198 case 1200: speed2 = B1200; break;
199 case 1800: speed2 = B1800; break;
200 case 2400: speed2 = B2400; break;
201 case 4800: speed2 = B4800; break;
202 case 9600: speed2 = B9600; break;
203 case 19200: speed2 = B19200;break;
204 case 38400: speed2 = B38400;break;
205 case 57600: speed2 = B57600;break;
206 case 115200: speed2 = B115200;break;
207 case 230400: speed2 = B230400;break;
208 case 460800: speed2 = B460800;break;
209 case 500000: speed2 = B500000;break;
210 case 576000: speed2 = B576000;break;
211 case 921600: speed2 = B921600;break;
212 case 1000000: speed2 = B1000000;break;
213 case 1152000: speed2 = B1152000;break;
214 case 1500000: speed2 = B1500000;break;
215 case 2000000: speed2 = B2000000;break;
216 case 2500000: speed2 = B2500000;break;
217 case 3000000: speed2 = B3000000;break;
218 case 3500000: speed2 = B3500000;break;
219 case 4000000: speed2 = B4000000; break;
220 }
221
222 /* This should work on all systems because it is done according to POSIX */
223 cfsetispeed(&t, speed2);
224 cfsetospeed(&t, speed2);
225
226 if (tcsetattr(d->hPhone, TCSADRAIN, &t) == -1) {
227 serial_close(s);
228 GSM_OSErrorInfo(s,"tcsetattr in serial_setspeed");
229 return ERR_DEVICECHANGESPEEDERROR;
230 }
231
232 return ERR_NONE;
233}
234
235static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes)
236{
237 GSM_Device_SerialData *d = &s->Device.Data.Serial;
238 struct timeval timeout2;
239 fd_set readfds;
240 int actual = 0;
241
242 FD_ZERO(&readfds);
243 FD_SET(d->hPhone, &readfds);
244
245 timeout2.tv_sec = 0;
246 timeout2.tv_usec = 1;
247
248 if (select(d->hPhone+1, &readfds, NULL, NULL, &timeout2)) {
249 actual = read(d->hPhone, buf, nbytes);
250 if (actual == -1) GSM_OSErrorInfo(s,"serial_read");
251 }
252 return actual;
253}
254
255static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes)
256{
257 GSM_Device_SerialData *d = &s->Device.Data.Serial;
258 int ret;
259 size_t actual = 0;
260
261 do {
262 ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual);
263 if (ret < 0 && errno == EAGAIN) continue;
264 if (ret < 0) {
265 if (actual != nbytes) GSM_OSErrorInfo(s,"serial_write");
266 return actual;
267 }
268 actual += ret;
269 buf += ret;
270 if (s->ConnectionType == GCT_FBUS2PL2303) my_sleep(1);
271 } while (actual < nbytes);
272 return actual;
273}
274
275GSM_Device_Functions SerialDevice = {
276 serial_open,
277 serial_close,
278 serial_setparity,
279 serial_setdtrrts,
280 serial_setspeed,
281 serial_read,
282 serial_write
283};
284
285#endif
286#endif
287#endif
288
289/* How should editor hadle tabs in this file? Add editor commands here.
290 * vim: noexpandtab sw=8 ts=8 sts=8:
291 */
diff --git a/gammu/emb/common/device/serial/ser_unx.h b/gammu/emb/common/device/serial/ser_unx.h
new file mode 100644
index 0000000..ca8fe5a
--- a/dev/null
+++ b/gammu/emb/common/device/serial/ser_unx.h
@@ -0,0 +1,22 @@
1
2#ifndef WIN32
3#ifndef DJGPP
4#ifndef unixserial_h
5#define unixserial_h
6
7#include <fcntl.h>
8#include <sys/ioctl.h>
9#include <termios.h>
10
11typedef struct {
12 int hPhone;
13 struct termios old_settings;
14} GSM_Device_SerialData;
15
16#endif
17#endif
18#endif
19
20/* How should editor hadle tabs in this file? Add editor commands here.
21 * vim: noexpandtab sw=8 ts=8 sts=8:
22 */
diff --git a/gammu/emb/common/device/serial/ser_w32.c b/gammu/emb/common/device/serial/ser_w32.c
new file mode 100644
index 0000000..9fa0135
--- a/dev/null
+++ b/gammu/emb/common/device/serial/ser_w32.c
@@ -0,0 +1,340 @@
1/* (c) 2002-2004 by Marcin Wiacek */
2/* based on some work from Gnokii, MSDN and others */
3
4#include "../../gsmstate.h"
5
6#ifdef GSM_ENABLE_SERIALDEVICE
7#ifdef WIN32
8
9#include <windows.h>
10#include <string.h>
11#include <stdio.h>
12#include <io.h>
13#include <memory.h>
14
15#include "../../gsmcomon.h"
16#include "ser_w32.h"
17
18static GSM_Error serial_close(GSM_StateMachine *s)
19{
20 GSM_Device_SerialData *d = &s->Device.Data.Serial;
21
22 /* Disables all monitored events for device */
23 SetCommMask(d->hPhone, 0);
24
25 /* Discards all characters from input/output buffer and terminates
26 * pending read/write operations
27 */
28 PurgeComm(d->hPhone, PURGE_TXABORT | PURGE_RXABORT |
29 PURGE_TXCLEAR | PURGE_RXCLEAR);
30
31 /* Clears the DTR (data-terminal-ready) signal */
32 EscapeCommFunction(d->hPhone, CLRDTR);
33
34 /* Restores old settings */
35 if (SetCommState(d->hPhone, &d->old_settings)==0) {
36 GSM_OSErrorInfo(s, "SetCommState in serial_close");
37 }
38
39 /* Closes device */
40 if (CloseHandle(d->hPhone)==0) {
41 GSM_OSErrorInfo(s, "CloseHandle in serial_close");
42 }
43
44 return ERR_NONE;
45}
46
47static GSM_Error serial_open (GSM_StateMachine *s)
48{
49 GSM_Device_SerialData *d = &s->Device.Data.Serial;
50 DCB dcb;
51 unsigned char DeviceName[80],DeviceName2[80];
52 int i;
53#ifdef GSM_ENABLE_FBUS2DKU5
54 HKEY hKey;
55 DWORD DeviceNameLen, KeyNameLen;
56 unsigned char KeyName[100];
57#endif
58
59 strcpy(DeviceName2,s->CurrentConfig->Device);
60
61#ifdef GSM_ENABLE_FBUS2DKU5
62 if (s->ConnectionType == GCT_FBUS2DKU5) {
63 smprintf(s,"Reading DKU5 device\n");
64 DeviceName2[0] = 0;
65 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) {
66 smprintf(s,"Error opening key\n");
67 return ERR_DEVICENOTWORK;
68 }
69 i = 0;
70 while(1) {
71 DeviceNameLen = 80;
72 KeyNameLen = 100;
73 if (RegEnumValue(hKey,i,KeyName,&KeyNameLen,NULL,NULL,DeviceName2,&DeviceNameLen) != ERROR_SUCCESS) {
74 smprintf(s,"Error reading key value\n");
75 return ERR_DEVICENOTWORK;
76 }
77 // smprintf(s,"Key name is %s, value is %s\n",KeyName,DeviceName2);
78 if (!strncmp(KeyName,"\\Device\\AtmelVirtualPort",24)) break;
79 i++;
80 }
81 RegCloseKey(hKey);
82 if (strlen(DeviceName2) == 0) return ERR_DEVICENOTWORK;
83 smprintf(s,"DKU5 device is \"%s\"\n",DeviceName2);
84 //nodriver
85 }
86#endif
87
88 if ((s->ConnectionType == GCT_FBUS2DKU5) ||
89 (!strncmp(DeviceName2,"com",3) && strlen(DeviceName2)>3)) {
90 sprintf(DeviceName,"\\\\.\\COM%i",atoi(DeviceName2+3));
91 } else {
92 strcpy(DeviceName,DeviceName2);
93 }
94
95 smprintf(s,"Device is %s\n",DeviceName);
96
97 /* Allows for reading/writing, no device sharing */
98 d->hPhone = CreateFile(DeviceName,
99 GENERIC_READ | GENERIC_WRITE,
100 0,
101 0,
102 OPEN_EXISTING,
103 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
104 NULL);
105
106 if (d->hPhone == INVALID_HANDLE_VALUE) {
107 i = GetLastError();
108 GSM_OSErrorInfo(s, "CreateFile in serial_open");
109 if (i == 2) return ERR_DEVICENOTWORK; //can't find specified file
110 if (i == 5) return ERR_DEVICEBUSY; //access denied
111 if (i == 31) return ERR_DEVICENOTWORK; //attached device not working
112 if (i == 123) return ERR_DEVICENOTEXIST;
113 return ERR_DEVICEOPENERROR;
114 }
115
116 d->old_settings.DCBlength = sizeof(DCB);
117 if (GetCommState(d->hPhone, &d->old_settings)==0) {
118 GSM_OSErrorInfo(s, "ReadDevice in serial_open");
119 return ERR_DEVICEREADERROR;
120 }
121
122 /* When char will be received, we will receive notifications */
123 SetCommMask(d->hPhone, EV_RXCHAR);
124
125 /* Sets size for input/output buffer */
126 SetupComm(d->hPhone, 4096, 4096);
127
128 /* Discards all characters from input/output buffer and terminates
129 * pending read/write operations
130 */
131 PurgeComm(d->hPhone, PURGE_TXABORT | PURGE_RXABORT |
132 PURGE_TXCLEAR | PURGE_RXCLEAR);
133
134 memcpy(&dcb, &d->old_settings, sizeof(DCB));
135
136 dcb.ByteSize = 8;
137 dcb.Parity = NOPARITY;
138 dcb.StopBits = ONESTOPBIT;
139
140 /* No Xon/Xof flow control */
141 // dcb.fOutX = false;
142 // dcb.fInX = false;
143
144 /* Hardware flow control */
145 //dcb.fOutxDsrFlow = true;
146 //dcb.fOutxCtsFlow = true;
147 //dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
148 //dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
149
150 /* Initialise the port settings */
151 if (SetCommState(d->hPhone, &dcb)==0) {
152 GSM_OSErrorInfo(s, "WriteDevice in serial_open");
153 return ERR_DEVICEOPENERROR;
154 }
155
156 return ERR_NONE;
157}
158
159static GSM_Error serial_setparity (GSM_StateMachine *s, bool parity)
160{
161 DCB dcb;
162 GSM_Device_SerialData *d = &s->Device.Data.Serial;
163
164 dcb.DCBlength = sizeof(DCB);
165 if (GetCommState(d->hPhone, &dcb)==0) {
166 GSM_OSErrorInfo(s, "ReadDevice in serial_setparity");
167 return ERR_DEVICEREADERROR;
168 }
169
170 if (parity) {
171 dcb.Parity = ODDPARITY;
172 } else {
173 dcb.Parity = NOPARITY;
174 }
175
176 if (SetCommState(d->hPhone, &dcb)==0) {
177 GSM_OSErrorInfo(s, "WriteDevice in serial_setparity");
178 return ERR_DEVICEPARITYERROR;
179 }
180
181 return ERR_NONE;
182}
183
184static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts)
185{
186 DCB dcb;
187 GSM_Device_SerialData *d = &s->Device.Data.Serial;
188
189 dcb.DCBlength = sizeof(DCB);
190 if (GetCommState(d->hPhone, &dcb)==0) {
191 GSM_OSErrorInfo(s, "ReadDevice in serial_setdtrrts");
192 return ERR_DEVICEREADERROR;
193 }
194
195 dcb.fOutxDsrFlow = 0;
196 dcb.fDtrControl = DTR_CONTROL_DISABLE;
197 if (dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE;
198
199 dcb.fOutxCtsFlow = 0;
200 dcb.fRtsControl = RTS_CONTROL_DISABLE;
201 if (rts) dcb.fRtsControl = RTS_CONTROL_ENABLE;
202
203 /* no software (Xon/Xof) flow control */
204 dcb.fInX = dcb.fOutX = 0;
205
206 if (SetCommState(d->hPhone, &dcb)==0) {
207 GSM_OSErrorInfo(s, "WriteDevice in serial_setdtrrts");
208 return ERR_DEVICEDTRRTSERROR;
209 }
210
211 /* the rest of function checks, if setting was really done */
212
213 dcb.DCBlength = sizeof(DCB);
214 GetCommState(d->hPhone, &dcb);
215
216 dbgprintf("Serial device:");
217 dbgprintf(" DTR is ");
218 switch (dcb.fDtrControl) {
219 case DTR_CONTROL_ENABLE : dbgprintf("up"); break;
220 case DTR_CONTROL_DISABLE : dbgprintf("down"); break;
221 case DTR_CONTROL_HANDSHAKE : dbgprintf("handshake"); break;
222 }
223 dbgprintf(", RTS is ");
224 switch (dcb.fRtsControl) {
225 case RTS_CONTROL_ENABLE : dbgprintf("up"); break;
226 case RTS_CONTROL_DISABLE : dbgprintf("down"); break;
227 case RTS_CONTROL_HANDSHAKE : dbgprintf("handshake"); break;
228 case RTS_CONTROL_TOGGLE : dbgprintf("toggle"); break;
229 }
230 dbgprintf("\n");
231 if ( dtr && dcb.fDtrControl != DTR_CONTROL_ENABLE ) return ERR_DEVICEDTRRTSERROR;
232 if (!dtr && dcb.fDtrControl != DTR_CONTROL_DISABLE) return ERR_DEVICEDTRRTSERROR;
233 if ( rts && dcb.fRtsControl != RTS_CONTROL_ENABLE ) return ERR_DEVICEDTRRTSERROR;
234 if (!rts && dcb.fRtsControl != RTS_CONTROL_DISABLE) return ERR_DEVICEDTRRTSERROR;
235
236 return ERR_NONE;
237}
238
239static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed)
240{
241 DCB dcb;
242 GSM_Device_SerialData *d = &s->Device.Data.Serial;
243
244 dcb.DCBlength = sizeof(DCB);
245 if (GetCommState(d->hPhone, &dcb)==0) {
246 GSM_OSErrorInfo(s, "ReadDevice in serial_setspeed");
247 return ERR_DEVICEREADERROR;
248 }
249
250 dcb.BaudRate = speed;
251
252 if (SetCommState(d->hPhone, &dcb)==0) {
253 GSM_OSErrorInfo(s, "WriteDevice in serial_setspeed");
254 return ERR_DEVICECHANGESPEEDERROR;
255 }
256
257 return ERR_NONE;
258}
259
260static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes)
261{
262 COMSTAT ComStat;
263 DWORD ErrorFlags, Length;
264 GSM_Device_SerialData *d = &s->Device.Data.Serial;
265
266 /* Gets information about a communications error and
267 * current status of device
268 */
269 ClearCommError(d->hPhone, &ErrorFlags, &ComStat);
270 Length = ComStat.cbInQue;
271
272 /* Nothing to read */
273 if (Length <= 0) return Length;
274
275 /* Read without problems */
276 if (ReadFile(d->hPhone, buf, Length, &Length, &d->osRead)) return Length;
277
278 if (GetLastError() != ERROR_IO_PENDING) {
279 GSM_OSErrorInfo(s, "serial_read1");
280 Length = 0;
281 ClearCommError(d->hPhone, &ErrorFlags, &ComStat);
282 return Length;
283 }
284
285 while(1) {
286 if (GetOverlappedResult(d->hPhone,&d->osRead, &Length, TRUE)) break;
287 if (GetLastError() != ERROR_IO_INCOMPLETE) {
288 GSM_OSErrorInfo(s, "serial_read2");
289 /* an error occurred, try to recover */
290 ClearCommError(d->hPhone, &ErrorFlags, &ComStat);
291 break;
292 }
293 }
294 return Length;
295}
296
297static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes)
298{
299 DWORD BytesWritten,ErrorFlags,BytesSent=0;
300 COMSTAT ComStat;
301 GSM_Device_SerialData *d = &s->Device.Data.Serial;
302
303 if (WriteFile(d->hPhone, buf, nbytes, &BytesSent, &d->osWrite)) return BytesSent;
304
305 if (GetLastError() != ERROR_IO_PENDING) {
306 GSM_OSErrorInfo(s, "serial_write1");
307 ClearCommError(d->hPhone, &ErrorFlags, &ComStat);
308 return BytesSent;
309 }
310
311 while (1) {
312 if (GetOverlappedResult(d->hPhone, &d->osWrite, &BytesWritten, TRUE)) break;
313 if (GetLastError() != ERROR_IO_INCOMPLETE) {
314 GSM_OSErrorInfo(s, "serial_write2");
315 ClearCommError(d->hPhone, &ErrorFlags, &ComStat);
316 break;
317 }
318 BytesSent += BytesWritten;
319 }
320 BytesSent += BytesWritten;
321
322 return BytesSent;
323}
324
325GSM_Device_Functions SerialDevice = {
326 serial_open,
327 serial_close,
328 serial_setparity,
329 serial_setdtrrts,
330 serial_setspeed,
331 serial_read,
332 serial_write
333};
334
335#endif
336#endif
337
338/* How should editor hadle tabs in this file? Add editor commands here.
339 * vim: noexpandtab sw=8 ts=8 sts=8:
340 */
diff --git a/gammu/emb/common/device/serial/ser_w32.h b/gammu/emb/common/device/serial/ser_w32.h
new file mode 100644
index 0000000..d226f32
--- a/dev/null
+++ b/gammu/emb/common/device/serial/ser_w32.h
@@ -0,0 +1,19 @@
1
2#ifdef WIN32
3#ifndef winserial_h
4#define winserial_h
5
6#include <windows.h>
7
8typedef struct {
9 HANDLE hPhone;
10 DCB old_settings;
11 OVERLAPPED osWrite,osRead;
12} GSM_Device_SerialData;
13
14#endif
15#endif
16
17/* How should editor hadle tabs in this file? Add editor commands here.
18 * vim: noexpandtab sw=8 ts=8 sts=8:
19 */