author | zautrix <zautrix> | 2004-10-25 08:56:23 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-10-25 08:56:23 (UTC) |
commit | 62e92aa86b6281b4e4c2a2bdb57f3ceb5a87f4e3 (patch) (unidiff) | |
tree | c2b7a41b0c8fffdc0786b84ff86724ea8f08d6a1 /gammu/emb/common/device | |
parent | feff0930372dd51af24dc3b46697e70838277ea5 (diff) | |
download | kdepimpi-62e92aa86b6281b4e4c2a2bdb57f3ceb5a87f4e3.zip kdepimpi-62e92aa86b6281b4e4c2a2bdb57f3ceb5a87f4e3.tar.gz kdepimpi-62e92aa86b6281b4e4c2a2bdb57f3ceb5a87f4e3.tar.bz2 |
gammu updates
-rw-r--r-- | gammu/emb/common/device/serial/ser_djg.c | 399 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_djg.h | 37 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_unx.c | 27 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_w32.c | 9 |
4 files changed, 447 insertions, 25 deletions
diff --git a/gammu/emb/common/device/serial/ser_djg.c b/gammu/emb/common/device/serial/ser_djg.c index 2524187..609deb8 100644 --- a/gammu/emb/common/device/serial/ser_djg.c +++ b/gammu/emb/common/device/serial/ser_djg.c | |||
@@ -1,72 +1,441 @@ | |||
1 | /* Some sources from SVAsync (c) 1996, 1997, Samuel Vincent | ||
2 | * 7337 Carioca Ct, Rohnert Park, Ca 94928 | ||
3 | * "you may freely use it in your programs without paying me anything" | ||
4 | */ | ||
5 | /* Some sources from DZCOMM */ | ||
1 | 6 | ||
2 | #include "../../gsmstate.h" | 7 | #include "../../gsmstate.h" |
3 | 8 | ||
4 | #ifdef GSM_ENABLE_SERIALDEVICE | 9 | #ifdef GSM_ENABLE_SERIALDEVICE |
5 | #ifdef DJGPP | 10 | #ifdef DJGPP |
6 | 11 | ||
7 | #include "../../gsmcomon.h" | 12 | #include "../../gsmcomon.h" |
13 | #include "../../misc/coding/coding.h" | ||
8 | #include "ser_djg.h" | 14 | #include "ser_djg.h" |
9 | 15 | ||
16 | #include <stdlib.h> | ||
17 | #include <stdio.h> | ||
18 | #include <string.h> | ||
19 | #include <dos.h> | ||
20 | #include <dpmi.h> | ||
21 | #include <pc.h> | ||
22 | #include <go32.h> | ||
23 | #include <sys/farptr.h> | ||
24 | #include <sys/movedata.h> | ||
25 | #include <conio.h> | ||
26 | |||
27 | extern unsigned short __djgpp_ds_alias; | ||
28 | extern void SVAsyncProtISR(void); | ||
29 | |||
30 | static unsigned char SVAsyncStatus=0; | ||
31 | |||
32 | static void lock_interrupt_memory(void); | ||
33 | static void unlock_interrupt_memory(void); | ||
34 | |||
35 | #define Ctrl8259_0 0x020 /* 8259 port */ | ||
36 | #define Ctrl8259_1 0x021 /* 8259 port (Masks) */ | ||
37 | #define BufSize 32768 /* Buffer Size */ | ||
38 | |||
39 | static unsigned char VectorNum; /* Vector Number */ | ||
40 | static unsigned char EnableIRQ; /* Mask to enable 8259 IRQ */ | ||
41 | static unsigned char DisableIRQ; /* Mask to disable 8259 IRQ */ | ||
42 | static _go32_dpmi_seginfo ProtVector; /* Old Protmode Vector */ | ||
43 | static _go32_dpmi_seginfo info; /* New Protmode Vector */ | ||
44 | |||
45 | /* Register Addresses for the UART */ | ||
46 | static unsigned short Port; /* Port Base Address */ | ||
47 | unsigned short THR; /* Transmitter Holding Register */ | ||
48 | unsigned short RDR; /* Reciever Data Register */ | ||
49 | unsigned short BRDL; /* Baud Rate Divisor, Low byte */ | ||
50 | unsigned short BRDH; /* Baud Rate Divisor, High Byte */ | ||
51 | unsigned short IER; /* Interupt Enable Register */ | ||
52 | unsigned short IIR; /* Interupt Identification Register */ | ||
53 | unsigned short FCR; /* FIFO Control Register */ | ||
54 | unsigned short LCR; /* Line Control Register */ | ||
55 | unsigned short MCR; /* Modem Control Register */ | ||
56 | unsigned short LSR; /* Line Status Register */ | ||
57 | unsigned short MSR; /* Modem Status Register */ | ||
58 | unsigned short SCR; /* SCR Register */ | ||
59 | |||
60 | /* Data Buffer */ | ||
61 | unsigned volatile char RecBuffer[BufSize] = { 0 }; | ||
62 | unsigned volatile int RecHead, RecTail; | ||
63 | |||
64 | /* This uninstalls the ISR and resets the serial port. */ | ||
65 | static void SVAsyncStop(void) | ||
66 | { | ||
67 | if(!SVAsyncStatus) return; | ||
68 | SVAsyncStatus = 0; | ||
69 | |||
70 | /***** Mask (disable) 8259 IRQ Interrupt */ | ||
71 | outportb(Ctrl8259_1, (inportb(Ctrl8259_1) | DisableIRQ)); | ||
72 | |||
73 | /***** Disable 8250 interrupt */ | ||
74 | outportb(LCR, (inportb(LCR) & 0x7F)); | ||
75 | outportb(IER, 0); | ||
76 | |||
77 | /***** Set bit 3 in MCR to 0 */ | ||
78 | outportb(MCR, (inportb(MCR) & 0xF7)); | ||
79 | |||
80 | /***** Interrupts are disabled. Restore saved interrupt vector. */ | ||
81 | _go32_dpmi_set_protected_mode_interrupt_vector(VectorNum, &ProtVector); | ||
82 | } | ||
83 | |||
84 | /* This will empty the receive buffer */ | ||
85 | static void SVAsyncClear(void) | ||
86 | { | ||
87 | disable(); | ||
88 | RecHead = 0; | ||
89 | RecTail = 0; | ||
90 | enable(); | ||
91 | } | ||
92 | |||
93 | |||
94 | /* Sets communication parameters | ||
95 | * Baud = 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 28800, 38400, 57600 | ||
96 | * Control = The value to place in the LCR | ||
97 | */ | ||
98 | void SVAsyncSet(unsigned int Baud, unsigned int Control) | ||
99 | { | ||
100 | int divisor; | ||
101 | unsigned char divlow, divhigh; | ||
102 | |||
103 | if (!Baud) return; | ||
104 | |||
105 | divisor = 115200 / Baud; | ||
106 | |||
107 | disable(); | ||
108 | |||
109 | outportb(LCR, Control | 0x80); /* Set Port Toggle to BRDL/BRDH registers */ | ||
110 | divlow = divisor & 0x000000ff; | ||
111 | divhigh = (divisor >> 8) & 0x000000ff; | ||
112 | outportb(BRDL, divlow); /* Set Baud Rate */ | ||
113 | outportb(BRDH, divhigh); | ||
114 | |||
115 | outportb(LCR, Control & 0x007F); /* Set LCR and Port Toggle */ | ||
116 | |||
117 | enable(); | ||
118 | } | ||
119 | |||
120 | /* Sets various handshaking lines */ | ||
121 | void SVAsyncHand(unsigned int Hand) | ||
122 | { | ||
123 | outportb(MCR, Hand | 0x08); /* Keep interrupt enable ON */ | ||
124 | } | ||
125 | |||
126 | static void lock_interrupt_memory(void) | ||
127 | { | ||
128 | int errval; | ||
129 | __dpmi_meminfo info; | ||
130 | unsigned long address; | ||
131 | |||
132 | __dpmi_get_segment_base_address(_my_ds(), &address); | ||
133 | |||
134 | info.address = (int) address + (int) &RDR; | ||
135 | info.size = sizeof(RDR); | ||
136 | errval = __dpmi_lock_linear_region(&info); | ||
137 | if(errval == -1) printf("Error in locking memory\n!"); | ||
138 | |||
139 | info.address = (int) address + (int) &LSR; | ||
140 | info.size = sizeof(LSR); | ||
141 | errval = __dpmi_lock_linear_region(&info); | ||
142 | if(errval == -1) printf("Error in locking memory\n!"); | ||
143 | |||
144 | info.address = (int) address + (int) &RecHead; | ||
145 | info.size = sizeof(RecHead); | ||
146 | errval = __dpmi_lock_linear_region(&info); | ||
147 | if(errval == -1) printf("Error in locking memory\n!"); | ||
148 | |||
149 | info.address = (int) address + (int) &RecBuffer; | ||
150 | info.size = sizeof(RecBuffer); | ||
151 | errval = __dpmi_lock_linear_region(&info); | ||
152 | if(errval == -1) printf("Error in locking memory\n!"); | ||
153 | |||
154 | info.address = (int) address + (int) RecBuffer; | ||
155 | info.size = BufSize; | ||
156 | errval = __dpmi_lock_linear_region(&info); | ||
157 | if(errval == -1) printf("Error in locking memory\n!"); | ||
158 | |||
159 | __dpmi_get_segment_base_address(_my_cs(), &address); | ||
160 | |||
161 | info.address = (int) address + (int) SVAsyncProtISR; | ||
162 | info.size = 4096; /* 4096 bytes is probably overkill. */ | ||
163 | errval = __dpmi_lock_linear_region(&info); | ||
164 | if(errval == -1) printf("Error in locking memory\n!"); | ||
165 | } | ||
166 | |||
167 | static void unlock_interrupt_memory(void) | ||
168 | { | ||
169 | __dpmi_meminfo info; | ||
170 | unsigned long address; | ||
171 | |||
172 | __dpmi_get_segment_base_address(_my_ds(), &address); | ||
173 | info.address = (int) address + (int) &RDR; | ||
174 | info.size = sizeof(RDR); | ||
175 | __dpmi_unlock_linear_region(&info); | ||
176 | info.address = (int) address + (int) &LSR; | ||
177 | info.size = sizeof(LSR); | ||
178 | __dpmi_unlock_linear_region(&info); | ||
179 | info.address = (int) address + (int) &RecHead; | ||
180 | info.size = sizeof(RecHead); | ||
181 | __dpmi_unlock_linear_region(&info); | ||
182 | info.address = (int) address + (int) &RecBuffer; | ||
183 | info.size = sizeof(RecBuffer); | ||
184 | __dpmi_unlock_linear_region(&info); | ||
185 | info.address = (int) address + (int) RecBuffer; | ||
186 | info.size = BufSize; | ||
187 | __dpmi_unlock_linear_region(&info); | ||
188 | |||
189 | __dpmi_get_segment_base_address(_my_cs(), &address); | ||
190 | |||
191 | info.address = (int) address + (int) SVAsyncProtISR; | ||
192 | info.size = 4096; /* probably overkill */ | ||
193 | __dpmi_unlock_linear_region(&info); | ||
194 | } | ||
195 | |||
10 | static GSM_Error serial_close(GSM_StateMachine *s) | 196 | static GSM_Error serial_close(GSM_StateMachine *s) |
11 | { | 197 | { |
12 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 198 | SVAsyncStop(); |
13 | 199 | ||
14 | return ERR_NOTIMPLEMENTED; | 200 | return ERR_NONE; |
15 | } | 201 | } |
16 | 202 | ||
17 | static GSM_Error serial_open (GSM_StateMachine *s) | 203 | static GSM_Error serial_open (GSM_StateMachine *s) |
18 | { | 204 | { |
19 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 205 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
20 | 206 | unsigned char temp; | |
21 | return ERR_NOTIMPLEMENTED; | 207 | int i; |
208 | |||
209 | /**** Set various things according to com port number */ | ||
210 | if (mystrncasecmp(s->CurrentConfig->Device,"com1:",0)) { | ||
211 | Port = 0x03F8; | ||
212 | VectorNum = 0x0C; | ||
213 | EnableIRQ = 0xEF; | ||
214 | DisableIRQ = 0x10; | ||
215 | } else if (mystrncasecmp(s->CurrentConfig->Device,"com2:",0)) { | ||
216 | Port = 0x02F8; | ||
217 | VectorNum = 0x0B; | ||
218 | EnableIRQ = 0xF7; | ||
219 | DisableIRQ = 0x08; | ||
220 | } else if (mystrncasecmp(s->CurrentConfig->Device,"com3:",0)) { | ||
221 | Port = 0x03E8; | ||
222 | VectorNum = 0x0C; | ||
223 | EnableIRQ = 0xEF; | ||
224 | DisableIRQ = 0x10; | ||
225 | } else if (mystrncasecmp(s->CurrentConfig->Device,"com4:",0)) { | ||
226 | Port = 0x02E8; | ||
227 | VectorNum = 0x0B; | ||
228 | EnableIRQ = 0xF7; | ||
229 | DisableIRQ = 0x08; | ||
230 | } else return ERR_NOTSUPPORTED; | ||
231 | |||
232 | /**** Compute Register locations */ | ||
233 | THR = Port; | ||
234 | RDR = Port; | ||
235 | BRDL = Port; | ||
236 | BRDH = 1 + Port; | ||
237 | IER = 1 + Port; | ||
238 | IIR = 2 + Port; | ||
239 | FCR = 2 + Port; | ||
240 | LCR = 3 + Port; | ||
241 | MCR = 4 + Port; | ||
242 | LSR = 5 + Port; | ||
243 | MSR = 6 + Port; | ||
244 | SCR = 7 + Port; | ||
245 | |||
246 | /***** Initalize Buffer */ | ||
247 | SVAsyncClear(); | ||
248 | |||
249 | lock_interrupt_memory(); | ||
250 | atexit(unlock_interrupt_memory); | ||
251 | /***** Set bit 3 in MCR to 0 */ | ||
252 | outportb(MCR, (inportb(MCR) & 0xF7)); | ||
253 | |||
254 | /*** Save and reassign interrupt vectors */ | ||
255 | |||
256 | _go32_dpmi_get_protected_mode_interrupt_vector(VectorNum, &ProtVector); | ||
257 | |||
258 | info.pm_offset = (int) SVAsyncProtISR; | ||
259 | info.pm_selector = _my_cs(); | ||
260 | _go32_dpmi_set_protected_mode_interrupt_vector(VectorNum, &info); | ||
261 | |||
262 | atexit(SVAsyncStop); | ||
263 | |||
264 | /***** Enable 8259 interrupt (IRQ) line for this async adapter */ | ||
265 | outportb(Ctrl8259_1, (inportb(Ctrl8259_1) & EnableIRQ)); | ||
266 | |||
267 | /***** Enable 8250 Interrupt-on-data-ready */ | ||
268 | outportb(LCR, (inportb(LCR) & 0x7F)); | ||
269 | |||
270 | outportb(IER, 0); | ||
271 | if (inportb(IER)) { | ||
272 | SVAsyncStatus = 0; | ||
273 | return ERR_UNKNOWN; | ||
274 | } | ||
275 | outportb(IER, 0x01); | ||
276 | |||
277 | /***** Clear 8250 Status and data registers */ | ||
278 | do { | ||
279 | temp=inportb(RDR); | ||
280 | temp=inportb(LSR); | ||
281 | temp=inportb(MSR); | ||
282 | temp=inportb(IIR); | ||
283 | } while(!(temp & 1)); | ||
284 | |||
285 | /***** Set Bit 3 of MCR -- Enable interupts */ | ||
286 | outportb(MCR, (inportb(MCR) | 0x08)); | ||
287 | |||
288 | SVAsyncStatus = 1; | ||
289 | /***** Clear Buffer Just in case */ | ||
290 | SVAsyncClear(); | ||
291 | |||
292 | /* Code based on stuff from SVAsync lib. | ||
293 | * Clear UART Status and data registers | ||
294 | * setting up FIFO if possible | ||
295 | */ | ||
296 | outportb(SCR, 0x55); | ||
297 | if (inportb(SCR) == 0x55) { | ||
298 | /* On the off chance that SCR is actually hardwired to 0x55, | ||
299 | * do the same check with a different value. | ||
300 | */ | ||
301 | outportb(SCR, 0xAA); | ||
302 | if (inportb(SCR) == 0xAA) { | ||
303 | /* The chip is better than an 8250 - it has a scratch pad */ | ||
304 | outportb(SCR, i); /* Set SCR back to what it was before */ | ||
305 | inportb(SCR); /* Give slow motherboards a chance */ | ||
306 | |||
307 | /* Is there a FIFO ? - go through twice for slow motherboards */ | ||
308 | outportb(FCR, 0x01); | ||
309 | i = inportb(FCR); | ||
310 | outportb(FCR, 0x01); | ||
311 | i = inportb(FCR); | ||
312 | |||
313 | /* Some old stuff relies on this (no idea why) */ | ||
314 | outportb(FCR, 0x00); | ||
315 | inportb(FCR); /* Give slow motherboards a chance */ | ||
316 | |||
317 | if ((i&0x80) == 0) { | ||
318 | smprintf(s,"UART 16450 or UART 8250 with scratch pad\n"); | ||
319 | } else if ((i&0x40) == 0) { | ||
320 | smprintf(s,"UART 16550 - broken FIFO\n"); | ||
321 | } else { | ||
322 | /* It's a 16450A series : try and start the FIFO. | ||
323 | * It appears that some chips need a two call protocol, but | ||
324 | * those that don't seem to work even if you do start it | ||
325 | * twice. The first call is simply to start it, the second | ||
326 | * starts it and sets an 8 byte FIFO trigger level. | ||
327 | */ | ||
328 | outportb(FCR, 0x01); | ||
329 | inportb(FCR); /* Give slow motherboards a chance */ | ||
330 | outportb(FCR, 0x87); | ||
331 | inportb(FCR); /* Give slow motherboards a chance */ | ||
332 | |||
333 | /* Check that the FIFO initialised */ | ||
334 | if ((inportb(IIR) & 0xc0) != 0xc0) { | ||
335 | /* | ||
336 | * It didn't so we assume it isn't there but disable it to | ||
337 | * be on the safe side. | ||
338 | */ | ||
339 | outportb(IIR, 0xfe); | ||
340 | inportb(IIR); /* Give slow motherboards a chance */ | ||
341 | smprintf(s,"UART 16450A - FIFO disabled\n"); | ||
342 | } else { | ||
343 | smprintf(s,"UART 16450A - FIFO enabled\n"); | ||
344 | } | ||
345 | } | ||
346 | } else { | ||
347 | smprintf(s,"UART 8250\n"); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | d->Control = BITS_8 | STOP_1; | ||
352 | d->Parity = false; | ||
353 | d->Speed = 9600; | ||
354 | SVAsyncSet(d->Speed,d->Control | NO_PARITY); | ||
355 | |||
356 | return ERR_NONE; | ||
22 | } | 357 | } |
23 | 358 | ||
24 | static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) | 359 | static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) |
25 | { | 360 | { |
26 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 361 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
27 | 362 | ||
28 | return ERR_NOTIMPLEMENTED; | 363 | d->Parity = parity; |
364 | |||
365 | if (parity) { | ||
366 | SVAsyncSet(d->Speed, d->Control | ODD_PARITY); | ||
367 | } else { | ||
368 | SVAsyncSet(d->Speed, d->Control | NO_PARITY); | ||
369 | } | ||
370 | |||
371 | return ERR_NONE; | ||
29 | } | 372 | } |
30 | 373 | ||
31 | static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) | 374 | static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) |
32 | { | 375 | { |
33 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 376 | if (dtr && rts) { |
377 | SVAsyncHand(DTR | RTS); | ||
378 | } else if (dtr) { | ||
379 | SVAsyncHand(DTR); | ||
380 | } else if (rts) { | ||
381 | SVAsyncHand(RTS); | ||
382 | } else { | ||
383 | SVAsyncHand(0); | ||
384 | } | ||
34 | 385 | ||
35 | return ERR_NOTIMPLEMENTED; | 386 | return ERR_NONE; |
36 | } | 387 | } |
37 | 388 | ||
38 | static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) | 389 | static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) |
39 | { | 390 | { |
40 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 391 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
41 | 392 | ||
42 | return ERR_NOTIMPLEMENTED; | 393 | d->Speed = speed; |
394 | |||
395 | if (d->Parity) { | ||
396 | SVAsyncSet(d->Speed, d->Control | ODD_PARITY); | ||
397 | } else { | ||
398 | SVAsyncSet(d->Speed, d->Control | NO_PARITY); | ||
399 | } | ||
400 | |||
401 | return ERR_NONE; | ||
43 | } | 402 | } |
44 | 403 | ||
45 | static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) | 404 | static int serial_read(GSM_StateMachine *s, char *buf, size_t nbytes) |
46 | { | 405 | { |
47 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 406 | if(RecTail == RecHead) return 0; |
407 | |||
408 | disable(); | ||
409 | buf[0] = RecBuffer[RecTail++]; | ||
410 | if(RecTail >= BufSize) RecTail = 0; | ||
411 | enable(); | ||
48 | 412 | ||
49 | return 0; | 413 | return 1; |
50 | } | 414 | } |
51 | 415 | ||
52 | static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) | 416 | static int serial_write(GSM_StateMachine *s, char *buf, size_t nbytes) |
53 | { | 417 | { |
54 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 418 | int i; |
419 | |||
420 | for (i=0;i<nbytes;i++) { | ||
421 | while(~inportb(LSR) & 0x20); | ||
422 | outportb(THR, buf[i]); | ||
423 | } | ||
55 | 424 | ||
56 | return 0; | 425 | return i; |
57 | } | 426 | } |
58 | 427 | ||
59 | GSM_Device_Functions SerialDevice = { | 428 | GSM_Device_Functions SerialDevice = { |
60 | serial_open, | 429 | serial_open, |
61 | serial_close, | 430 | serial_close, |
62 | serial_setparity, | 431 | serial_setparity, |
63 | serial_setdtrrts, | 432 | serial_setdtrrts, |
64 | serial_setspeed, | 433 | serial_setspeed, |
65 | serial_read, | 434 | serial_read, |
66 | serial_write | 435 | serial_write |
67 | }; | 436 | }; |
68 | 437 | ||
69 | #endif | 438 | #endif |
70 | #endif | 439 | #endif |
71 | 440 | ||
72 | /* How should editor hadle tabs in this file? Add editor commands here. | 441 | /* How should editor hadle tabs in this file? Add editor commands here. |
diff --git a/gammu/emb/common/device/serial/ser_djg.h b/gammu/emb/common/device/serial/ser_djg.h index b35b282..3bb2a5b 100644 --- a/gammu/emb/common/device/serial/ser_djg.h +++ b/gammu/emb/common/device/serial/ser_djg.h | |||
@@ -1,15 +1,50 @@ | |||
1 | /* Some sources from SVAsync (c) 1996, 1997, Samuel Vincent | ||
2 | * 7337 Carioca Ct, Rohnert Park, Ca 94928 | ||
3 | * "you may freely use it in your programs without paying me anything" | ||
4 | */ | ||
1 | 5 | ||
2 | #ifdef DJGPP | 6 | #ifdef DJGPP |
3 | #ifndef djgppserial_h | 7 | #ifndef djgppserial_h |
4 | #define djgppserial_h | 8 | #define djgppserial_h |
5 | 9 | ||
6 | typedef struct { | 10 | typedef struct { |
7 | int hPhone; | 11 | int hPhone; |
12 | int Speed; | ||
13 | unsigned int Control; | ||
14 | bool Parity; | ||
8 | } GSM_Device_SerialData; | 15 | } GSM_Device_SerialData; |
9 | 16 | ||
17 | /* Defines for Com Port Paramaters, the second paramater to SVAsyncSet() */ | ||
18 | #define BITS_8 0x03 | ||
19 | #define BITS_7 0x02 | ||
20 | #define STOP_1 0x00 | ||
21 | #define STOP_2 0x04 | ||
22 | #define EVEN_PARITY 0x18 | ||
23 | #define ODD_PARITY 0x08 | ||
24 | #define NO_PARITY 0x00 | ||
25 | |||
26 | /* Defines for SVAsyncHand() */ | ||
27 | #define DTR 0x01 | ||
28 | #define RTS 0x02 | ||
29 | #define USER 0x04 | ||
30 | #define LOOPBACK 0x10 | ||
31 | |||
32 | /* Defines for SVAsyncStat() */ | ||
33 | #define D_CTS 0x0100 | ||
34 | #define D_DSR 0x0200 | ||
35 | #define D_RI 0x0400 | ||
36 | #define D_DCD 0x0800 | ||
37 | #define CTS 0x1000 | ||
38 | #define DSR 0x2000 | ||
39 | #define RI 0x4000 | ||
40 | #define DCD 0x8000 | ||
41 | #define PARITY 0x0004 | ||
42 | #define THREMPTY 0x0020 | ||
43 | #define BREAKDET 0x1000 | ||
44 | |||
10 | #endif | 45 | #endif |
11 | #endif | 46 | #endif |
12 | 47 | ||
13 | /* How should editor hadle tabs in this file? Add editor commands here. | 48 | /* How should editor hadle tabs in this file? Add editor commands here. |
14 | * vim: noexpandtab sw=8 ts=8 sts=8: | 49 | * vim: noexpandtab sw=8 ts=8 sts=8: |
15 | */ | 50 | */ |
diff --git a/gammu/emb/common/device/serial/ser_unx.c b/gammu/emb/common/device/serial/ser_unx.c index 69c7515..18b5f6f 100644 --- a/gammu/emb/common/device/serial/ser_unx.c +++ b/gammu/emb/common/device/serial/ser_unx.c | |||
@@ -1,22 +1,31 @@ | |||
1 | /* (c) 2002-2004 by Marcin Wiacek */ | 1 | /* (c) 2002-2004 by Marcin Wiacek */ |
2 | /* locking device and settings all speeds by Michal Cihar */ | 2 | /* locking device and settings all speeds by Michal Cihar */ |
3 | /* based on some work from Gnokii (www.gnokii.org) | 3 | /* based on some work from Gnokii (www.gnokii.org) |
4 | * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot | 4 | * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot |
5 | * GNU GPL version 2 or later | 5 | * GNU GPL version 2 or later |
6 | */ | 6 | */ |
7 | /* Due to a problem in the source code management, the names of some of | ||
8 | * the authors have unfortunately been lost. We do not mean to belittle | ||
9 | * their efforts and hope they will contact us to see their names | ||
10 | * properly added to the Copyright notice above. | ||
11 | * Having published their contributions under the terms of the GNU | ||
12 | * General Public License (GPL) [version 2], the Copyright of these | ||
13 | * authors will remain respected by adhering to the license they chose | ||
14 | * to publish their code under. | ||
15 | */ | ||
7 | 16 | ||
8 | #include "../../gsmstate.h" | 17 | #include "../../gsmstate.h" |
9 | 18 | ||
10 | #ifdef GSM_ENABLE_SERIALDEVICE | 19 | #ifdef GSM_ENABLE_SERIALDEVICE |
11 | #ifndef WIN32 | 20 | #ifndef WIN32 |
12 | #ifndef DJGPP | 21 | #ifndef DJGPP |
13 | 22 | ||
14 | #include <sys/file.h> | 23 | #include <sys/file.h> |
15 | #include <sys/time.h> | 24 | #include <sys/time.h> |
16 | #include <string.h> | 25 | #include <string.h> |
17 | #include <termios.h> | 26 | #include <termios.h> |
18 | #include <errno.h> | 27 | #include <errno.h> |
19 | 28 | ||
20 | #include "../../gsmcomon.h" | 29 | #include "../../gsmcomon.h" |
21 | #include "ser_unx.h" | 30 | #include "ser_unx.h" |
22 | 31 | ||
@@ -47,34 +56,34 @@ | |||
47 | static GSM_Error serial_close(GSM_StateMachine *s) | 56 | static GSM_Error serial_close(GSM_StateMachine *s) |
48 | { | 57 | { |
49 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 58 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
50 | 59 | ||
51 | /* Restores old settings */ | 60 | /* Restores old settings */ |
52 | tcsetattr(d->hPhone, TCSANOW, &d->old_settings); | 61 | tcsetattr(d->hPhone, TCSANOW, &d->old_settings); |
53 | 62 | ||
54 | /* Closes device */ | 63 | /* Closes device */ |
55 | close(d->hPhone); | 64 | close(d->hPhone); |
56 | 65 | ||
57 | return ERR_NONE; | 66 | return ERR_NONE; |
58 | } | 67 | } |
59 | 68 | ||
60 | static GSM_Error serial_open (GSM_StateMachine *s) | 69 | static GSM_Error serial_open (GSM_StateMachine *s) |
61 | { | 70 | { |
62 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 71 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
63 | struct termios t; | 72 | struct termios t; |
64 | int i; | 73 | int i; |
65 | 74 | ||
66 | /* O_NONBLOCK MUST is required to avoid waiting for DCD */ | 75 | /* O_NONBLOCK MUST is required to avoid waiting for DCD */ |
67 | d->hPhone = open(s->CurrentConfig->Device, O_RDWR | O_NOCTTY | O_NONBLOCK); | 76 | d->hPhone = open(s->CurrentConfig->Device, O_RDWR | O_NOCTTY | O_NONBLOCK); |
68 | if (d->hPhone < 0) { | 77 | if (d->hPhone < 0) { |
69 | i = errno; | 78 | i = errno; |
70 | GSM_OSErrorInfo(s,"open in serial_open"); | 79 | GSM_OSErrorInfo(s,"open in serial_open"); |
71 | if (i == 2) return ERR_DEVICENOTEXIST; //no such file or directory | 80 | if (i == 2) return ERR_DEVICENOTEXIST; //no such file or directory |
72 | if (i == 13) return ERR_DEVICENOPERMISSION;//permission denied | 81 | if (i == 13) return ERR_DEVICENOPERMISSION;//permission denied |
73 | return ERR_DEVICEOPENERROR; | 82 | return ERR_DEVICEOPENERROR; |
74 | } | 83 | } |
75 | 84 | ||
76 | #ifdef TIOCEXCL | 85 | #ifdef TIOCEXCL |
77 | /* open() calls from other applications shall fail now */ | 86 | /* open() calls from other applications shall fail now */ |
78 | ioctl(d->hPhone, TIOCEXCL, (char *) 0); | 87 | ioctl(d->hPhone, TIOCEXCL, (char *) 0); |
79 | #endif | 88 | #endif |
80 | 89 | ||
@@ -111,60 +120,60 @@ static GSM_Error serial_open (GSM_StateMachine *s) | |||
111 | return ERR_DEVICEOPENERROR; | 120 | return ERR_DEVICEOPENERROR; |
112 | } | 121 | } |
113 | 122 | ||
114 | /* Making file descriptor asynchronous. */ | 123 | /* Making file descriptor asynchronous. */ |
115 | if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) { | 124 | if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) { |
116 | serial_close(s); | 125 | serial_close(s); |
117 | GSM_OSErrorInfo(s,"fcntl in serial_open"); | 126 | GSM_OSErrorInfo(s,"fcntl in serial_open"); |
118 | return ERR_DEVICEOPENERROR; | 127 | return ERR_DEVICEOPENERROR; |
119 | } | 128 | } |
120 | 129 | ||
121 | return ERR_NONE; | 130 | return ERR_NONE; |
122 | } | 131 | } |
123 | 132 | ||
124 | static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) | 133 | static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) |
125 | { | 134 | { |
126 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 135 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
127 | struct termios t; | 136 | struct termios t; |
128 | 137 | ||
129 | if (tcgetattr(d->hPhone, &t)) { | 138 | if (tcgetattr(d->hPhone, &t)) { |
130 | GSM_OSErrorInfo(s,"tcgetattr in serial_setparity"); | 139 | GSM_OSErrorInfo(s,"tcgetattr in serial_setparity"); |
131 | return ERR_DEVICEREADERROR; | 140 | return ERR_DEVICEREADERROR; |
132 | } | 141 | } |
133 | 142 | ||
134 | if (parity) { | 143 | if (parity) { |
135 | t.c_cflag |= (PARENB | PARODD); | 144 | t.c_cflag |= (PARENB | PARODD); |
136 | t.c_iflag = 0; | 145 | t.c_iflag = 0; |
137 | } else { | 146 | } else { |
138 | t.c_iflag = IGNPAR; | 147 | t.c_iflag = IGNPAR; |
139 | } | 148 | } |
140 | 149 | ||
141 | if (tcsetattr(d->hPhone, TCSANOW, &t) == -1){ | 150 | if (tcsetattr(d->hPhone, TCSANOW, &t) == -1){ |
142 | serial_close(s); | 151 | serial_close(s); |
143 | GSM_OSErrorInfo(s,"tcsetattr in serial_setparity"); | 152 | GSM_OSErrorInfo(s,"tcsetattr in serial_setparity"); |
144 | return ERR_DEVICEPARITYERROR; | 153 | return ERR_DEVICEPARITYERROR; |
145 | } | 154 | } |
146 | 155 | ||
147 | return ERR_NONE; | 156 | return ERR_NONE; |
148 | } | 157 | } |
149 | 158 | ||
150 | static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) | 159 | static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) |
151 | { | 160 | { |
152 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 161 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
153 | struct termios t; | 162 | struct termios t; |
154 | unsigned int flags; | 163 | unsigned int flags; |
155 | 164 | ||
156 | if (tcgetattr(d->hPhone, &t)) { | 165 | if (tcgetattr(d->hPhone, &t)) { |
157 | GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts"); | 166 | GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts"); |
158 | return ERR_DEVICEREADERROR; | 167 | return ERR_DEVICEREADERROR; |
159 | } | 168 | } |
160 | 169 | ||
161 | #ifdef CRTSCTS | 170 | #ifdef CRTSCTS |
162 | /* Disabling hardware flow control */ | 171 | /* Disabling hardware flow control */ |
163 | t.c_cflag &= ~CRTSCTS; | 172 | t.c_cflag &= ~CRTSCTS; |
164 | #endif | 173 | #endif |
165 | 174 | ||
166 | if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) { | 175 | if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) { |
167 | serial_close(s); | 176 | serial_close(s); |
168 | GSM_OSErrorInfo(s,"tcsetattr in serial_setdtrrts"); | 177 | GSM_OSErrorInfo(s,"tcsetattr in serial_setdtrrts"); |
169 | return ERR_DEVICEDTRRTSERROR; | 178 | return ERR_DEVICEDTRRTSERROR; |
170 | } | 179 | } |
@@ -251,53 +260,53 @@ static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) | |||
251 | cfsetispeed(&t, speed2); | 260 | cfsetispeed(&t, speed2); |
252 | cfsetospeed(&t, speed2); | 261 | cfsetospeed(&t, speed2); |
253 | 262 | ||
254 | if (tcsetattr(d->hPhone, TCSADRAIN, &t) == -1) { | 263 | if (tcsetattr(d->hPhone, TCSADRAIN, &t) == -1) { |
255 | serial_close(s); | 264 | serial_close(s); |
256 | GSM_OSErrorInfo(s,"tcsetattr in serial_setspeed"); | 265 | GSM_OSErrorInfo(s,"tcsetattr in serial_setspeed"); |
257 | return ERR_DEVICECHANGESPEEDERROR; | 266 | return ERR_DEVICECHANGESPEEDERROR; |
258 | } | 267 | } |
259 | 268 | ||
260 | return ERR_NONE; | 269 | return ERR_NONE; |
261 | } | 270 | } |
262 | 271 | ||
263 | static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) | 272 | static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) |
264 | { | 273 | { |
265 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 274 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
266 | struct timeval timeout2; | 275 | struct timeval timeout2; |
267 | fd_set readfds; | 276 | fd_set readfds; |
268 | int actual = 0; | 277 | int actual = 0; |
269 | 278 | ||
270 | FD_ZERO(&readfds); | 279 | FD_ZERO(&readfds); |
271 | FD_SET(d->hPhone, &readfds); | 280 | FD_SET(d->hPhone, &readfds); |
272 | 281 | ||
273 | timeout2.tv_sec = 0; | 282 | timeout2.tv_sec = 0; |
274 | timeout2.tv_usec = 1; | 283 | timeout2.tv_usec = 1; |
275 | 284 | ||
276 | if (select(d->hPhone+1, &readfds, NULL, NULL, &timeout2)) { | 285 | if (select(d->hPhone+1, &readfds, NULL, NULL, &timeout2)) { |
277 | actual = read(d->hPhone, buf, nbytes); | 286 | actual = read(d->hPhone, buf, nbytes); |
278 | if (actual == -1) GSM_OSErrorInfo(s,"serial_read"); | 287 | if (actual == -1) GSM_OSErrorInfo(s,"serial_read"); |
279 | } | 288 | } |
280 | return actual; | 289 | return actual; |
281 | } | 290 | } |
282 | 291 | ||
283 | static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) | 292 | static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) |
284 | { | 293 | { |
285 | GSM_Device_SerialData *d = &s->Device.Data.Serial; | 294 | GSM_Device_SerialData *d = &s->Device.Data.Serial; |
286 | int ret; | 295 | int ret; |
287 | size_t actual = 0; | 296 | size_t actual = 0; |
288 | 297 | ||
289 | do { | 298 | do { |
290 | ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual); | 299 | ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual); |
291 | if (ret < 0 && errno == EAGAIN) continue; | 300 | if (ret < 0 && errno == EAGAIN) continue; |
292 | if (ret < 0) { | 301 | if (ret < 0) { |
293 | if (actual != nbytes) GSM_OSErrorInfo(s,"serial_write"); | 302 | if (actual != nbytes) GSM_OSErrorInfo(s,"serial_write"); |
294 | return actual; | 303 | return actual; |
295 | } | 304 | } |
296 | actual += ret; | 305 | actual += ret; |
297 | buf += ret; | 306 | buf += ret; |
298 | if (s->ConnectionType == GCT_FBUS2PL2303) my_sleep(1); | 307 | if (s->ConnectionType == GCT_FBUS2PL2303) my_sleep(1); |
299 | } while (actual < nbytes); | 308 | } while (actual < nbytes); |
300 | return actual; | 309 | return actual; |
301 | } | 310 | } |
302 | 311 | ||
303 | GSM_Device_Functions SerialDevice = { | 312 | GSM_Device_Functions SerialDevice = { |
diff --git a/gammu/emb/common/device/serial/ser_w32.c b/gammu/emb/common/device/serial/ser_w32.c index 7d88fc7..a7919fe 100644 --- a/gammu/emb/common/device/serial/ser_w32.c +++ b/gammu/emb/common/device/serial/ser_w32.c | |||
@@ -1,22 +1,31 @@ | |||
1 | /* (c) 2002-2004 by Marcin Wiacek */ | 1 | /* (c) 2002-2004 by Marcin Wiacek */ |
2 | /* based on some work from MSDN and others */ | 2 | /* based on some work from MSDN and others */ |
3 | /* based on some work from Gnokii (www.gnokii.org) | 3 | /* based on some work from Gnokii (www.gnokii.org) |
4 | * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot | 4 | * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot |
5 | * GNU GPL version 2 or later | 5 | * GNU GPL version 2 or later |
6 | */ | 6 | */ |
7 | /* Due to a problem in the source code management, the names of some of | ||
8 | * the authors have unfortunately been lost. We do not mean to belittle | ||
9 | * their efforts and hope they will contact us to see their names | ||
10 | * properly added to the Copyright notice above. | ||
11 | * Having published their contributions under the terms of the GNU | ||
12 | * General Public License (GPL) [version 2], the Copyright of these | ||
13 | * authors will remain respected by adhering to the license they chose | ||
14 | * to publish their code under. | ||
15 | */ | ||
7 | 16 | ||
8 | #include "../../gsmstate.h" | 17 | #include "../../gsmstate.h" |
9 | 18 | ||
10 | #ifdef GSM_ENABLE_SERIALDEVICE | 19 | #ifdef GSM_ENABLE_SERIALDEVICE |
11 | #ifdef WIN32 | 20 | #ifdef WIN32 |
12 | 21 | ||
13 | #include <windows.h> | 22 | #include <windows.h> |
14 | #include <string.h> | 23 | #include <string.h> |
15 | #include <stdio.h> | 24 | #include <stdio.h> |
16 | #include <io.h> | 25 | #include <io.h> |
17 | #include <memory.h> | 26 | #include <memory.h> |
18 | 27 | ||
19 | #include "../../gsmcomon.h" | 28 | #include "../../gsmcomon.h" |
20 | #include "ser_w32.h" | 29 | #include "ser_w32.h" |
21 | 30 | ||
22 | static GSM_Error serial_close(GSM_StateMachine *s) | 31 | static GSM_Error serial_close(GSM_StateMachine *s) |