Cygwin support, using SDL.
[btb/d2x.git] / unused / win95 / comm.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: comm.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $";
17 #pragma on (unreferenced)
18
19
20 #define WIN32_LEAN_AND_MEAN
21 #define WIN95
22 #define _WIN32
23 #include <windows.h>
24 #include <mmsystem.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "mono.h"
29 #include "winapp.h"
30 #include "comm.h"
31 #include "error.h"
32
33 #define ASCII_XON       0x11
34 #define ASCII_XOFF      0x13
35
36 #define MODEM_REGISTRY_PATH "System\\CurrentControlSet\\Services\\Class\\Modem"
37
38
39 static long comm_delay_val = 0;
40
41 DWORD FAR PASCAL comm_thread_proc(LPSTR lpdata);
42 int FAR PASCAL comm_idle_function(COMM_OBJ *obj);
43 void comm_dump_info(COMM_OBJ *obj);
44
45
46 //      ---------------------------------------------------------------------
47  
48 int comm_get_modem_info(int modem, COMM_OBJ *obj)
49 {
50         HKEY hKey, hSubKey;
51         char path[256];
52         char buf[32];
53         DWORD len, err, type;
54
55         memset(obj, 0, sizeof(COMM_OBJ));
56         obj->connect = FALSE;
57
58         if (modem < 0) {
59         //      Direct Link
60                 obj->type = 0;
61                 obj->port = (char)(modem * -1);
62                 return 1;
63         }
64         else obj->type = 1;
65         
66         sprintf(buf, "\\%04d", modem);
67
68         strcpy(path, MODEM_REGISTRY_PATH);
69         strcat(path, buf);
70         
71         mprintf((0, "Looking for modem in HKEY_LOCAL_MACHINE\\%s\n", path));
72
73         err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hKey);
74
75         if (err != ERROR_SUCCESS) return 0;
76
77 //      We have a key into the modem 000x
78 //      Retreive all pertinant info.
79         len = sizeof(buf);
80         err = RegQueryValueEx(hKey, "Model", 0, &type, buf, &len);
81         if (err != ERROR_SUCCESS) {
82                 RegCloseKey(hKey);
83                 return 0;
84         }
85
86         strcpy(obj->name, buf);
87
88         len = sizeof(buf);
89         err = RegQueryValueEx(hKey, "PortSubClass", 0, &type, buf, &len);
90         if (err != ERROR_SUCCESS) {
91                 RegCloseKey(hKey);
92                 return 0;
93         }
94         mprintf((0, "COM:%d\n", buf[0]));       
95  
96         obj->port = buf[0];
97
98         len = sizeof(buf);
99         err = RegQueryValueEx(hKey, "Reset", 0, &type, buf, &len);
100         if (err != ERROR_SUCCESS) {
101                 RegCloseKey(hKey);
102                 return 0;
103         }
104
105         strcpy(obj->cmd[COMM_RESET_CMD], buf);
106
107 //      Retreive some settings stuff
108         err =  RegOpenKeyEx(hKey, "Answer", 0, KEY_READ, &hSubKey);
109         if (err !=ERROR_SUCCESS) {
110                 RegCloseKey(hKey);
111                 return 0;
112         }
113         len = sizeof(buf);
114         err = RegQueryValueEx(hSubKey, "1", 0, &type, buf, &len);
115         if (err != ERROR_SUCCESS) {
116                 RegCloseKey(hSubKey);
117                 RegCloseKey(hKey);
118                 return 0;
119         }
120         strcpy(obj->cmd[COMM_ANSWER_CMD], buf);
121         RegCloseKey(hSubKey);
122
123         err =  RegOpenKeyEx(hKey, "Hangup", 0, KEY_READ, &hSubKey);
124         if (err !=ERROR_SUCCESS) {
125                 RegCloseKey(hKey);
126                 return 0;
127         }
128         len = sizeof(buf);
129         err = RegQueryValueEx(hSubKey, "1", 0, &type, buf, &len);
130         if (err != ERROR_SUCCESS) {
131                 RegCloseKey(hSubKey);
132                 RegCloseKey(hKey);
133                 return 0;
134         }
135         strcpy(obj->cmd[COMM_HANGUP_CMD], buf);
136         RegCloseKey(hSubKey);
137
138         err =  RegOpenKeyEx(hKey, "Settings", 0, KEY_READ, &hSubKey);
139         if (err !=ERROR_SUCCESS) {
140                 RegCloseKey(hKey);
141                 return 0;
142         }
143         len = sizeof(buf);
144         err = RegQueryValueEx(hSubKey, "DialPrefix", 0, &type, buf, &len);
145         if (err != ERROR_SUCCESS) {
146                 RegCloseKey(hSubKey);
147                 RegCloseKey(hKey);
148                 return 0;
149         }
150         strcpy(obj->cmd[COMM_DIALPREF_CMD], buf);
151
152         len = sizeof(buf);
153         err = RegQueryValueEx(hSubKey, "Tone", 0, &type, buf, &len);
154         if (err != ERROR_SUCCESS) {
155                 RegCloseKey(hSubKey);
156                 RegCloseKey(hKey);
157                 return 0;
158         }
159         strcat(obj->cmd[COMM_DIALPREF_CMD], buf);
160
161         len = sizeof(buf);
162         err = RegQueryValueEx(hSubKey, "Prefix", 0, &type, buf, &len);
163         if (err != ERROR_SUCCESS) {
164                 RegCloseKey(hSubKey);
165                 RegCloseKey(hKey);
166                 return 0;
167         }
168         strcpy(obj->cmd[COMM_PREFIX_CMD], buf);
169
170         RegCloseKey(hSubKey);
171         RegCloseKey(hKey);
172
173         comm_dump_info(obj);
174
175         return 1;
176 }       
177  
178
179 //      int comm_open_connection(COMM_OBJ *obj);
180 //      ----------------------------------------------------------------------------
181 int comm_open_connection(COMM_OBJ *obj)
182 {
183         char filename[16];
184         COMMTIMEOUTS ctimeouts;
185
186         sprintf(filename, "COM%d", obj->port);
187                                                                                         
188         obj->handle = CreateFile(filename, 
189                                                         GENERIC_READ | GENERIC_WRITE,
190                                                         0,
191                                                         NULL,
192                                                         OPEN_EXISTING, 
193                                                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
194         if (obj->handle == INVALID_HANDLE_VALUE)        
195                 return 0;
196         
197 //       Modem COMport is open.
198         SetCommMask(obj->handle, EV_RXCHAR);
199         SetupComm(obj->handle, 4096, 4096);
200         PurgeComm( obj->handle, 
201                                         PURGE_TXABORT | 
202                                         PURGE_RXABORT |
203                 PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
204
205 //      Timeout after 10 sec.
206         ctimeouts.ReadIntervalTimeout = 0xffffffff;
207         ctimeouts.ReadTotalTimeoutMultiplier = 0;
208         ctimeouts.ReadTotalTimeoutConstant = 10000;
209         ctimeouts.WriteTotalTimeoutMultiplier = 0;
210         ctimeouts.WriteTotalTimeoutConstant = 10000;
211         SetCommTimeouts(obj->handle, &ctimeouts);
212
213         memset(&obj->rov, 0, sizeof(OVERLAPPED));
214         memset(&obj->wov, 0, sizeof(OVERLAPPED));
215
216         obj->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
217         if (obj->rov.hEvent == NULL) {
218                 mprintf((0, "COMM: Unable to create read event.\n"));
219                 CloseHandle(obj->handle);
220                 return 0;
221         }
222         obj->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
223         if (obj->wov.hEvent == NULL) {
224                 mprintf((0, "COMM: Unable to create write event.\n"));
225                 CloseHandle(obj->rov.hEvent);
226                 CloseHandle(obj->handle); 
227                 return 0;
228         }
229
230 //      Setup parameters for Connection
231 //      38400 8N1
232         obj->dcb.DCBlength = sizeof(DCB);
233         GetCommState(obj->handle, &obj->dcb);
234
235         if (obj->baud) 
236                 obj->dcb.BaudRate = obj->baud;
237         else obj->baud = obj->dcb.BaudRate;
238
239         mprintf((0, "COM%d (%d) is opened.\n", obj->port,  obj->baud));
240
241         obj->dcb.fBinary                        = 1;
242         obj->dcb.Parity                         = NOPARITY;
243         obj->dcb.fNull                  = 0;
244    obj->dcb.XonChar                     = ASCII_XON;
245    obj->dcb.XoffChar            = ASCII_XOFF;
246    obj->dcb.XonLim                      = 1024;
247    obj->dcb.XoffLim                     = 1024;
248    obj->dcb.EofChar                     = 0;
249    obj->dcb.EvtChar                     = 0;
250         obj->dcb.fDtrControl            = DTR_CONTROL_ENABLE;// dtr=on
251         obj->dcb.fRtsControl            = RTS_CONTROL_ENABLE;
252
253         obj->dcb.ByteSize               = 8;
254         obj->dcb.StopBits               = ONESTOPBIT;
255         obj->dcb.fParity                        = FALSE;
256
257         obj->dcb.fOutxDsrFlow   = FALSE;
258         obj->dcb.fOutxCtsFlow   = FALSE;                                        // rts/cts off
259
260 // obj->dcb.fInX = obj->dcb.fOutX = 1;                          // Software flow control XON/XOFF
261         
262         if (SetCommState(obj->handle, &obj->dcb) == TRUE) 
263         {
264                 obj->hThread = NULL;
265                 obj->threadID = (DWORD)(-1);
266
267         //      Send DTR
268                 EscapeCommFunction(obj->handle, SETDTR);
269                 obj->connect = TRUE;
270         }
271         else {
272                 mprintf((1, "COMM: Unable to set CommState: (%x)\n", GetLastError()));
273
274                 obj->hThread = NULL;
275                 obj->threadID = (DWORD)(-1);
276                 obj->connect = FALSE;
277 //              CloseHandle(obj->wov.hEvent);
278 //              CloseHandle(obj->rov.hEvent);
279                 CloseHandle(obj->handle);
280
281                 return 0;
282         }
283
284         return 1;
285 }
286
287
288 //      int comm_close_connection(COMM_OBJ *obj);
289 //      ----------------------------------------------------------------------------    
290 int comm_close_connection(COMM_OBJ *obj)
291 {
292         CloseHandle(obj->wov.hEvent);
293         CloseHandle(obj->rov.hEvent);
294
295         SetCommMask(obj->handle, 0);
296         EscapeCommFunction(obj->handle, CLRDTR);
297         PurgeComm( obj->handle, 
298                                         PURGE_TXABORT | 
299                                         PURGE_RXABORT |
300                 PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
301         CloseHandle(obj->handle);
302
303         obj->connect = FALSE;
304         obj->handle = NULL;
305         mprintf((0, "COM%d closed.\n", obj->port));
306         return 1;
307 }               
308
309
310 //      int comm_read_char(COMM_OBJ *obj);
311 //      ----------------------------------------------------------------------------
312
313 #define ROTBUF_SIZE 16
314
315 static char rotbuf[ROTBUF_SIZE];
316 static int rotbuf_cur=0, rotbuf_tail=0;
317
318 int comm_read_char(COMM_OBJ *obj)
319 {
320         DWORD errflags, result;
321         COMSTAT comstat;
322         DWORD length, length_to_read;
323
324         if (!obj->connect) return COMM_BUF_EMPTY;
325
326 //      Do read buffer stuff
327         if (rotbuf_cur < rotbuf_tail) {
328                 return (int)rotbuf[rotbuf_cur++];
329         }
330
331 //      Now if we have a condition of cur = tail, then the buffer is empty
332 //      and we have to refill it.
333
334         ClearCommError(obj->handle, &errflags, &comstat);
335
336         if (comstat.cbInQue > 0) {
337                 if (comstat.cbInQue < ROTBUF_SIZE) 
338                         length_to_read = comstat.cbInQue;
339                 else
340                         length_to_read = ROTBUF_SIZE;
341
342                 result = ReadFile(obj->handle, rotbuf, length_to_read, &length, &obj->rov);
343
344                 if (result == 0) {
345                         if ((errflags = GetLastError()) != ERROR_IO_PENDING) {
346                                 mprintf((1, "CommReadChar err: %X\n", errflags));
347                                 ClearCommError(obj->handle, &errflags, &comstat);
348                         }
349                         else {
350                                 while (!GetOverlappedResult(obj->handle, &obj->rov, &length, TRUE))
351                                 {
352                                         errflags = GetLastError();
353                                         if (errflags == ERROR_IO_INCOMPLETE) {
354                                                 continue;
355                                         }
356                                         else {
357                                                 mprintf((1, "GetOverlappedResult error: %d.\n", errflags));
358                                                 rotbuf_cur = rotbuf_tail;
359                                                 return COMM_BUF_EMPTY;
360                                         }
361                                 }
362                         }
363                 }
364                 rotbuf_cur = 0;
365
366                 Assert(length <= ROTBUF_SIZE);
367                 rotbuf_tail = length;
368                 return (int)rotbuf[rotbuf_cur++];
369         }
370         else return COMM_BUF_EMPTY;
371 }
372
373
374 //      int comm_read_char_timed(COMM_OBJ *obj, int msecs);
375 //      ----------------------------------------------------------------------------
376 int comm_read_char_timed(COMM_OBJ *obj, int msecs)
377 {
378         DWORD err;
379         COMSTAT cstat;
380         int status;
381         long timeout = timeGetTime() + (long)msecs;
382
383         ClearCommError(obj->handle, &err, &cstat);
384         while (cstat.cbInQue == 0)
385         {
386                 status = comm_idle_function(obj);
387                 if (!status) return -1; 
388                 ClearCommError(obj->handle, &err, &cstat);
389                 if (timeout <= timeGetTime()) return -1;
390         }
391         return comm_read_char(obj);
392 }
393         
394
395 //      int comm_write_char(COMM_OBJ *obj, int ch);
396 //      ----------------------------------------------------------------------------
397 int comm_write_char(COMM_OBJ *obj, int ch)
398 {
399         DWORD errflags;
400         DWORD length;
401         COMSTAT comstat;
402         char c;
403
404         if (!obj->connect) return 0;
405
406         c = (char)ch;
407
408 //      mprintf((0, "%c", c));
409
410         if (!WriteFile(obj->handle, &c, 1, &length, &obj->wov)) {
411                 if (GetLastError() == ERROR_IO_PENDING) {
412                         while (!GetOverlappedResult(obj->handle, &obj->wov, &length, TRUE))
413                         {       
414                                 errflags = GetLastError();
415                                 if (errflags == ERROR_IO_INCOMPLETE)
416                                         continue;
417                                 else {
418                                         ClearCommError(obj->handle, &errflags, &comstat);
419                                         mprintf((1, "Comm: Write error!\n"));
420                                         return 0;
421                                 }
422                         }
423                 }
424                 else {
425                         ClearCommError(obj->handle, &errflags, &comstat);
426                         mprintf((1, "Comm: Write error!\n"));
427                         return 0;
428                 }
429         }
430
431 //mprintf((0, "[%c]", c));
432
433         return 1;
434 }
435                         
436
437 //      int comm_get_cd(COMM_OBJ *obj);
438 //      ----------------------------------------------------------------------------
439 int comm_get_cd(COMM_OBJ *obj)
440 {
441         DWORD status;
442
443         if (!obj->connect) return 0;
444
445         GetCommModemStatus(obj->handle, &status);
446         if (status & MS_RLSD_ON) return 1;
447         else return 0;
448 }
449
450
451 //      int comm_get_line_status(COMM_OBJ *obj);
452 //      ----------------------------------------------------------------------------
453 int comm_get_line_status(COMM_OBJ *obj)
454 {
455         COMSTAT comstat;
456         DWORD err;
457         int status=0;
458
459         if (!obj->connect) return 0;
460
461         ClearCommError(obj->handle, &err, &comstat);
462         
463         if (err & CE_BREAK) status |= COMM_STATUS_BREAK;
464         if (err & CE_FRAME) status |= COMM_STATUS_FRAME;
465         if (err & CE_OVERRUN) status |= COMM_STATUS_OVERRUN;
466         if (err & CE_RXPARITY) status |= COMM_STATUS_RXPARITY;
467
468         return status;
469 }
470
471
472 //      void comm_clear_line_status(COMM_OBJ *obj)
473 //      ----------------------------------------------------------------------------
474 void comm_clear_line_status(COMM_OBJ *obj)
475 {
476         
477 }
478
479
480 //      void comm_set_dtr(COMM_OBJ *obj, int flag);
481 //      ----------------------------------------------------------------------------
482 void comm_set_dtr(COMM_OBJ *obj, int flag)
483 {
484         if (!obj->connect) return;
485
486         GetCommState(obj->handle, &obj->dcb);
487         
488         if (flag == 1) obj->dcb.fDtrControl = DTR_CONTROL_ENABLE;
489         else obj->dcb.fDtrControl = DTR_CONTROL_DISABLE;
490         
491         SetCommState(obj->handle, &obj->dcb);
492 }
493                 
494
495 //      void comm_set_rtscts(COMM_OBJ *obj, int flag);
496 //      ----------------------------------------------------------------------------
497 void comm_set_rtscts(COMM_OBJ *obj, int flag)
498 {
499         
500         if (!obj->connect) return;
501
502         GetCommState(obj->handle, &obj->dcb);
503
504         if (flag) {
505                 obj->dcb.fOutxCtsFlow   = TRUE;                         // rts/cts off
506                 obj->dcb.fRtsControl    = RTS_CONTROL_HANDSHAKE;
507         }
508         else {
509                 obj->dcb.fOutxCtsFlow   = FALSE;                                // rts/cts off
510                 obj->dcb.fRtsControl    = RTS_CONTROL_ENABLE;
511         }
512
513         SetCommState(obj->handle, &obj->dcb);
514 }
515
516
517 //      int comm_modem_input_line(COMM_OBJ *obj, int msecs, char *buffer, int chars);
518 //      ----------------------------------------------------------------------------
519 int comm_modem_input_line(COMM_OBJ *obj, int msecs, char *buffer, int chars)
520 {               
521         long timeout;
522         int ch;
523         int retval=1;
524         int i;
525
526         i = 0; 
527
528         timeout = timeGetTime() + msecs;
529
530         if (chars <= 0) return 0;
531
532         while (1)
533         {
534                 ch = comm_read_char(obj);
535                 if (ch >=0) { 
536                         if (ch == '\r') {
537                         //      mprintf((0, "\n"));
538                                 break;
539                         }
540                         if (ch == '\n') continue;
541                         buffer[i++] = (char)ch;
542                         chars--;
543                         if (chars == 0) break;
544                 }
545                 else if (ch == COMM_BUF_EMPTY) {
546                         retval = 0;
547                         break;
548                 }
549                 else {
550                         retval = ch;
551                         break;
552                 }
553                 if (timeout <= timeGetTime()) break;
554         }
555
556         buffer[i] = '\0';
557         if (retval < 0) return retval;
558
559         retval = timeout - timeGetTime();
560         if (retval < 0) retval = 0;
561         return retval;
562 }
563
564
565 //      void comm_set_delay(COMM_OBJ *obj, int msecs)
566 //      ----------------------------------------------------------------------------
567 void comm_set_delay(COMM_OBJ *obj, int msecs)
568 {
569         comm_delay_val = (long)msecs;
570 }
571
572
573 //      void comm_wait(COMM_OBJ *obj, int msecs)
574 //      ----------------------------------------------------------------------------
575 int comm_wait(COMM_OBJ *obj, int msecs)
576 {
577         long delaytime;
578
579         delaytime = timeGetTime() + (long)msecs;
580
581         while (timeGetTime() < delaytime) {
582                 if (!comm_idle_function(obj)) {
583                         mprintf((1, "Comm_wait: THIS IS NOT GOOD!!\n")); 
584                         return 0;
585                 }
586         }       
587         return 1;
588 }
589
590
591 //      int comm_modem_send_string(COMM_OBJ *obj, char *str);
592 //      ----------------------------------------------------------------------------
593 int comm_modem_send_string(COMM_OBJ *obj, char *str)
594 {
595         int retval;
596         long curtime;
597         char buf[64];
598
599         mprintf((0, "Commodem: send %s\n", str));
600         retval = comm_modem_send_string_nowait(obj, str, -2);
601         if (!retval) return 0;
602
603         if (comm_delay_val > 0) {
604                 if (!comm_wait(obj, comm_delay_val)) return 0;
605         }
606
607 //      Checking for OK response
608         curtime = comm_delay_val;
609         while(1) 
610         {
611                 curtime = comm_modem_input_line(obj, curtime, buf, 64);
612                 if (curtime == 0) {
613                         mprintf((1, "CommSendString: Didn't get an OK!\n"));
614                         return 0;
615                 }
616                 if (strcmp("OK", buf) == 0) {
617                         return comm_wait(obj, 500);
618                 }
619         }                       
620
621 }
622
623
624 //      int comm_modem_send_string_nowait(COMM_OBJ *obj, char *str, int term); 
625 //      ----------------------------------------------------------------------------
626 int comm_modem_send_string_nowait(COMM_OBJ *obj, char *str, int term)
627 {
628         int i;
629
630         if (term < -2 || term > 255) return 0;
631
632 //      mprintf((0, "<%s", str));
633         for (i= 0; i < lstrlen(str); i++)
634                 comm_write_char(obj, str[i]);   
635
636 //@@    if (!WriteFile(obj->handle, &str, lstrlen(str), &length, &obj->wov)) {
637 //@@            if (GetLastError() == ERROR_IO_PENDING) {
638 //@@                    mprintf((0,"Comm: SendStringNoWait IO pending...\n"));
639 //@@                    while (!GetOverlappedResult(obj->handle, &obj->wov, &length, TRUE))
640 //@@                    {       
641 //@@                            errflags = GetLastError();
642 //@@                            if (errflags == ERROR_IO_INCOMPLETE)
643 //@@                                    continue;
644 //@@                            else {
645 //@@                                    ClearCommError(obj->handle, &errflags, &comstat);
646 //@@                                    mprintf((1, "Comm: SendStringNoWait error!\n"));
647 //@@                                    return 0;
648 //@@                            }
649 //@@                    }
650 //@@            }
651 //@@            else {
652 //@@                    ClearCommError(obj->handle, &errflags, &comstat);
653 //@@                    mprintf((1, "Comm: SendStringNoWait error!\n"));
654 //@@                    return 0;
655 //@@            }
656 //@@    }
657
658         if (term >=0) 
659                 comm_write_char(obj, term);
660         else if (term == -2) {
661                 comm_write_char(obj, '\r');
662                 comm_write_char(obj, '\n');
663         }
664
665         return 1;
666
667
668
669 //      int comm_modem_reset(COMM_OBJ *obj);
670 //      ----------------------------------------------------------------------------
671 int comm_modem_reset(COMM_OBJ *obj)
672 {
673         return comm_modem_send_string(obj, obj->cmd[COMM_RESET_CMD]);
674 }
675
676
677 //      int comm_modem_dial(COMM_OBJ *obj, char *phonenum);
678 //      ----------------------------------------------------------------------------
679 int comm_modem_dial(COMM_OBJ *obj, char *phonenum)
680 {
681         char str[40];
682         
683         strcpy(str, obj->cmd[COMM_PREFIX_CMD]);
684         strcat(str, obj->cmd[COMM_DIALPREF_CMD]);
685         strcat(str, phonenum);
686         return comm_modem_send_string_nowait(obj, str, '\r');
687 }
688
689
690 //      int comm_modem_answer(COMM_OBJ *obj);
691 //      ----------------------------------------------------------------------------
692 int comm_modem_answer(COMM_OBJ *obj)
693 {
694         return comm_modem_send_string_nowait(obj, obj->cmd[COMM_ANSWER_CMD], '\r');
695 }
696
697
698
699 //@@    DWORD FAR PASCAL comm_thread_proc (LPSTR lpData);
700 //@@    -------------------------------------------------------------------------
701 //@@DWORD FAR PASCAL comm_thread_proc (LPSTR lpData)
702 //@@{
703 //@@    DWORD event_mask;
704 //@@    OVERLAPPED os;
705 //@@    COMM_OBJ *obj = (COMM_OBJ *)lpData;
706 //@@
707 //@@    memset(&os, 0, sizeof(OVERLAPPED));
708 //@@    os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
709 //@@    if (os.hEvent == NULL) {
710 //@@            mprintf((1, "CommThread: unable to create event!\n"));
711 //@@            return FALSE;
712 //@@    }
713 //@@
714 //@@    if (!SetCommMask(obj->handle, EV_RXCHAR)) return FALSE;
715 //@@
716 //@@    while (obj->connected) 
717 //@@    {
718 //@@            event_mask = 0;
719 //@@            WaitCommEvent(obj->handle, &event_mask, NULL);
720 //@@            if ((event_mask & EV_RXCHAR) == EV_RXCHAR) {
721 //@@            }
722 //@@    }
723 //@@}
724
725
726 //      int FAR PASCAL comm_idle_function(COMM_OBJ *obj);
727 //      ----------------------------------------------------------------------------
728 int FAR PASCAL comm_idle_function(COMM_OBJ *obj)
729 {
730         MSG msg;
731         
732         while (PeekMessage(&msg, 0,0,0, PM_REMOVE)) {
733                 TranslateMessage(&msg);
734                 DispatchMessage(&msg);
735         }
736
737         return 1;
738 }
739
740
741 //      Dump Info
742 //      ----------------------------------------------------------------------------
743 void comm_dump_info(COMM_OBJ *obj)
744 {
745         int baud;
746
747         switch (obj->dcb.BaudRate)
748         {
749                 case CBR_9600:  baud = 9600; break;
750                 case CBR_14400: baud = 14400; break;
751                 case CBR_19200: baud = 19200; break;
752                 case CBR_38400: baud = 38400; break;
753                 case CBR_57600: baud = 57600; break;
754                 default:
755                         baud = -1;
756         }
757         mprintf((0, "CommObj %x:\n", obj->handle));
758         mprintf((0, "\tConnect: %d\n\tDevice: %s\n", obj->connect, obj->name));
759         mprintf((0,     "\tPort: COM%d\n", obj->port));
760         mprintf((0, "\tBaud:    %d\n\tDTR:[%d]  RTS/CTS:[%d|%d]\n", baud, obj->dcb.fDtrControl,obj->dcb.fRtsControl,obj->dcb.fOutxCtsFlow));
761         mprintf((0, "\tXON/XOFF [In|Out]:[%d|%d]  XON/OFF thresh:[%d|%d]\n", obj->dcb.fInX, obj->dcb.fOutX, obj->dcb.XonLim, obj->dcb.XoffLim));
762 }
763
764         
765         
766
767
768
769