source: trunk/src/kernel32/hmcomm.cpp@ 4310

Last change on this file since 4310 was 4285, checked in by hugh, 25 years ago

Implemented Serial APIs

File size: 28.3 KB
Line 
1/* $Id: hmcomm.cpp,v 1.5 2000-09-20 21:32:51 hugh Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 COM device access class
7 *
8 * 1999 Achim Hasenmueller <achimha@innotek.de>
9 *
10 */
11
12
13
14#include <os2win.h>
15#include <string.h>
16#include "handlemanager.h"
17#include "hmdevice.h"
18#include "hmcomm.h"
19#include "oslibdos.h"
20
21#define DBG_LOCALLOG DBG_hmcomm
22#include "dbglocal.h"
23
24#define MAGIC_COM 0x12abcd34
25
26#define IOCTL_ASYNC 0x01
27#define ASYNC_GETDCBINFO 0x73
28#define ASYNC_SETDCBINFO 0x53
29#define ASYNC_SETLINECTRL 0x42
30#define ASYNC_GETCOMMEVENT 0x72
31#define ASYNC_EXTGETBAUDRATE 0x63
32#define ASYNC_EXTSETBAUDRATE 0x43
33#define ASYNC_GETCOMMERROR 0x6D
34#define ASYNC_GETCOMMSTATUS 0x65
35#define ASYNC_GETINQUECOUNT 0x68
36#define ASYNC_GETOUTQUECOUNT 0x69
37#define ASYNC_GETMODEMINPUT 0x67
38#define ASYNC_TRANSMITIMM 0x44
39#define ASYNC_SETBREAKON 0x4B
40#define ASYNC_SETBREAKOFF 0x45
41#define ASYNC_SETMODEMCTRL 0x46
42#define ASYNC_STARTTRANSMIT 0x48
43#define ASYNC_STOPTRANSMIT 0x47
44
45
46
47#pragma pack(1)
48typedef struct _DCBINFO
49{
50 USHORT usWriteTimeout; /* Time period used for Write Timeout processing. */
51 USHORT usReadTimeout; /* Time period used for Read Timeout processing. */
52 BYTE fbCtlHndShake; /* HandShake Control flag. */
53 BYTE fbFlowReplace; /* Flow Control flag. */
54 BYTE fbTimeOut; /* Timeout flag. */
55 BYTE bErrorReplacementChar; /* Error Replacement Character. */
56 BYTE bBreakReplacementChar; /* Break Replacement Character. */
57 BYTE bXONChar; /* Character XON. */
58 BYTE bXOFFChar; /* Character XOFF. */
59} DCBINFO;
60typedef DCBINFO *PDCBINFO;
61
62
63typedef struct _RXQUEUE
64{
65 USHORT cch; /* Number of characters in the queue. */
66 USHORT cb; /* Size of receive/transmit queue. */
67} RXQUEUE;
68
69typedef RXQUEUE *PRXQUEUE;
70
71
72typedef struct _MODEMSTATUS
73{
74 BYTE fbModemOn; /* Modem Control Signals ON Mask. */
75 BYTE fbModemOff; /* Modem Control Signals OFF Mask. */
76} MODEMSTATUS;
77
78typedef MODEMSTATUS *PMODEMSTATUS;
79
80
81#pragma pack()
82
83
84
85
86
87typedef struct _HMDEVCOMDATA
88{
89 ULONG ulMagic;
90 // Win32 Device Control Block
91 COMMCONFIG CommCfg;
92 COMMTIMEOUTS CommTOuts;
93 DWORD dwInBuffer, dwOutBuffer;
94 DWORD dwEventMask;
95 //OS/2 Device Control Block
96 DCBINFO dcbOS2;
97} HMDEVCOMDATA, *PHMDEVCOMDATA;
98
99VOID * CreateDevData()
100{
101 PHMDEVCOMDATA pData;
102 pData = new HMDEVCOMDATA();
103 if(NULL!=pData)
104 {
105 memset(pData,0,sizeof(HMDEVCOMDATA));
106 pData->ulMagic = MAGIC_COM;
107 pData->CommCfg.dwSize = sizeof(COMMCONFIG);
108 pData->CommCfg.wVersion = 1;
109 pData->CommCfg.dwProviderSubType = PST_RS232;
110 pData->CommCfg.dcb.DCBlength = sizeof(DCB);
111 pData->CommCfg.dcb.BaudRate = CBR_1200;
112 pData->CommCfg.dcb.ByteSize = 8;
113 pData->CommCfg.dcb.Parity = NOPARITY;
114 pData->CommCfg.dcb.StopBits = ONESTOPBIT;
115 pData->dwInBuffer = 16;
116 pData->dwOutBuffer = 16;
117 }
118 return pData;
119}
120
121HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
122{
123 VOID *pData;
124 dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
125 pData = CreateDevData();
126 if(pData!= NULL)
127 HMDeviceRegisterEx("COM1", this, pData);
128 pData = CreateDevData();
129 if(pData!= NULL)
130 HMDeviceRegisterEx("COM2", this, pData);
131 pData = CreateDevData();
132 if(pData!= NULL)
133 HMDeviceRegisterEx("COM3", this, pData);
134 pData = CreateDevData();
135 if(pData!= NULL)
136 HMDeviceRegisterEx("COM4", this, pData);
137 pData = CreateDevData();
138 if(pData!= NULL)
139 HMDeviceRegisterEx("COM5", this, pData);
140 pData = CreateDevData();
141 if(pData!= NULL)
142 HMDeviceRegisterEx("COM6", this, pData);
143 pData = CreateDevData();
144 if(pData!= NULL)
145 HMDeviceRegisterEx("COM7", this, pData);
146 pData = CreateDevData();
147 if(pData!= NULL)
148 HMDeviceRegisterEx("COM8", this, pData);
149}
150
151DWORD HMDeviceCommClass::CreateFile(LPCSTR lpFileName,
152 PHMHANDLEDATA pHMHandleData,
153 PVOID lpSecurityAttributes,
154 PHMHANDLEDATA pHMHandleDataTemplate)
155{
156 dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
157
158 pHMHandleData->hHMHandle = 0;
159
160 //AH: TODO parse Win32 security handles
161 OSLibDosDisableHardError(TRUE);
162 pHMHandleData->hHMHandle = OSLibDosOpen((char*)lpFileName,
163 OSLIB_ACCESS_READWRITE |
164 OSLIB_ACCESS_SHAREDENYREAD |
165 OSLIB_ACCESS_SHAREDENYWRITE);
166 OSLibDosDisableHardError(FALSE);
167 if (pHMHandleData->hHMHandle != 0)
168 {
169 ULONG ulLen;
170 APIRET rc;
171
172 pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
173 // Init The handle instance with the default default device config
174 memcpy( pHMHandleData->lpHandlerData,
175 pHMHandleData->lpDeviceData,
176 sizeof(HMDEVCOMDATA));
177
178 ulLen = sizeof(DCBINFO);
179
180 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
181 IOCTL_ASYNC,
182 ASYNC_GETDCBINFO,
183 0,0,0,
184 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
185
186 if(!rc)
187 {
188 return -1;
189 }
190 return 0;
191 }
192 else
193 return -1;
194}
195
196
197 /* this is a handler method for calls to CloseHandle() */
198DWORD HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
199{
200 dprintf(("HMComm: Serial communication port close request\n"));
201 delete pHMHandleData->lpHandlerData;
202 return OSLibDosClose(pHMHandleData->hHMHandle);
203}
204
205/*****************************************************************************
206 * Name : DWORD HMDeviceHandler::SetupComm
207 * Purpose : set com port parameters (queue)
208 * Variables :
209 * Result :
210 * Remark :
211 * Status :
212 *
213 * Author : Achim Hasenmueller
214 *****************************************************************************/
215
216BOOL HMDeviceCommClass::SetupComm( PHMHANDLEDATA pHMHandleData,
217 DWORD dwInQueue,
218 DWORD dwOutQueue)
219{
220 dprintf(("HMDeviceCommClass::SetupComm "));
221 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
222 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
223 {
224 O32_SetLastError(ERROR_INVALID_HANDLE);
225 return FALSE;
226 }
227 pDevData->dwInBuffer = dwInQueue;
228 pDevData->dwOutBuffer = dwOutQueue;
229
230 return(TRUE);
231}
232
233BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
234 LPDWORD lpfdwEvtMask,
235 LPOVERLAPPED lpo)
236{
237 APIRET rc;
238 ULONG ulLen;
239 USHORT COMEvt;
240 DWORD dwEvent,dwMask;
241
242 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
243
244 dprintf(("HMDeviceCommClass::WaitCommEvent"));
245 ulLen = sizeof(CHAR);
246
247 dwEvent = 0;
248 rc = 0;
249 ulLen = sizeof(COMEvt);
250 dwMask = pDevData->dwEventMask;
251 while( (0==rc) &&
252 !(dwEvent & dwMask) &&
253 (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
254 {
255 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
256 IOCTL_ASYNC,
257 ASYNC_GETCOMMEVENT,
258 0,0,0,
259 &COMEvt,ulLen,&ulLen);
260 if(!rc)
261 {
262 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
263 //dwEvent |= (COMEvt&0x0002)? 0:0;
264 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
265 dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
266 dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
267 //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
268 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
269 dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
270 dwEvent |= (COMEvt&0x0100)? EV_RING:0;
271 }
272 DosSleep(100);
273 }
274 *lpfdwEvtMask = rc==0?dwEvent:0;
275 return(rc==0);
276}
277
278
279#pragma pack(1)
280typedef struct
281{
282 ULONG ulCurrBaud;
283 UCHAR ucCurrFrac;
284 ULONG ulMinBaud;
285 UCHAR ucMinFrac;
286 ULONG ulMaxBaud;
287 UCHAR ucMaxFrac;
288} EXTBAUDGET, *PEXTBAUDGET;
289
290typedef struct
291{
292 ULONG ulBaud;
293 UCHAR ucFrac;
294} EXTBAUDSET, *PEXTBAUDSET;
295#pragma pack()
296
297BAUDTABLEENTRY BaudTable[] =
298{
299 {75,BAUD_075},
300 {110,BAUD_110},
301 {134,BAUD_134_5},
302 {150,BAUD_150},
303 {300,BAUD_300},
304 {600,BAUD_600},
305 {1200,BAUD_1200},
306 {1800,BAUD_1800},
307 {2400,BAUD_2400},
308 {4800,BAUD_4800},
309 {7200,BAUD_7200},
310 {9600,BAUD_9600},
311 {14400,BAUD_14400},
312 {19200,BAUD_19200},
313 {38400,BAUD_38400},
314 {56000,BAUD_56K},
315 {57600,BAUD_57600},
316 {115200,BAUD_115200},
317 {128000,BAUD_128K}
318};
319
320#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
321
322BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
323 LPCOMMPROP lpcmmp)
324{
325 EXTBAUDGET BaudInfo;
326 APIRET rc;
327 ULONG ulLen;
328 USHORT COMErr;
329 int i;
330 dprintf(("HMDeviceCommClass::GetCommProperties"));
331
332 ulLen = sizeof(EXTBAUDGET);
333 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
334 IOCTL_ASYNC,
335 ASYNC_EXTGETBAUDRATE,
336 0,0,0,
337 &BaudInfo,ulLen,&ulLen);
338 memset(lpcmmp,0,sizeof(COMMPROP));
339 lpcmmp->wPacketLength = sizeof(COMMPROP);
340 lpcmmp->wPacketVersion = 1; //???
341 lpcmmp->dwServiceMask = SP_SERIALCOMM;
342 for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
343 lpcmmp->dwMaxBaud = BaudTable[i].dwBaudFlag;
344 lpcmmp->dwProvSubType = PST_RS232;
345 lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
346 PCF_RTSCTS | PCF_SETXCHAR |
347 PCF_XONXOFF;
348 lpcmmp->dwSettableParams = SP_BAUD | SP_DATABITS |
349 SP_HANDSHAKEING | SP_PARITY |
350 SP_PARITY_CHECK | SP_STOPBIT;
351 lpcmmp->dwSettableBaud = 0;
352 for(i=0;i<BaudTableSize;i++)
353 {
354 if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
355 (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
356 lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
357 }
358 lpcmmp->dwSettableBaud |= BAUD_USER;
359 lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
360 lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
361 PARITY_NONE | PARITY_ODD | PARITY_EVEN |
362 PARITY_MARK | PARITY_SPACE;
363 return(rc==0);
364}
365
366BOOL HMDeviceCommClass::GetCommMask( PHMHANDLEDATA pHMHandleData,
367 LPDWORD lpfdwEvtMask)
368{
369 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
370
371 dprintf(("HMDeviceCommClass::GetCommMask"));
372
373 *lpfdwEvtMask = pDevData->dwEventMask;
374 return(TRUE);
375}
376
377BOOL HMDeviceCommClass::SetCommMask( PHMHANDLEDATA pHMHandleData,
378 DWORD fdwEvtMask)
379{
380 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
381 dprintf(("HMDeviceCommClass::SetCommMask"));
382
383 pDevData->dwEventMask = fdwEvtMask & ~(EV_RLSD|EV_RXFLAG); // Clear the 2 not supported Flags.
384 return(TRUE);
385}
386
387BOOL HMDeviceCommClass::PurgeComm( PHMHANDLEDATA pHMHandleData,
388 DWORD fdwAction)
389{
390 dprintf(("HMDeviceCommClass::PurgeComm unimplemented stub!"));
391 // ToDo: find a way to stop the current transmision didn't find
392 // any clue how to in Control Program Guide and reference
393
394 return(TRUE);
395}
396BOOL HMDeviceCommClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
397 LPDWORD lpdwErrors,
398 LPCOMSTAT lpcst)
399{
400 APIRET rc;
401 ULONG ulLen;
402 USHORT COMErr;
403
404 dprintf(("HMDeviceCommClass::ClearCommError"));
405 ulLen = sizeof(USHORT);
406
407 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
408 IOCTL_ASYNC,
409 ASYNC_GETCOMMERROR,
410 0,0,0,
411 &COMErr,2,&ulLen);
412 *lpdwErrors = 0;
413 *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
414 *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
415 *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
416 *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
417
418 if(lpcst)
419 {
420 UCHAR ucStatus;
421 RXQUEUE qInfo;
422 ulLen = 1;
423 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
424 IOCTL_ASYNC,
425 ASYNC_GETCOMMSTATUS,
426 0,0,0,
427 &ucStatus,ulLen,&ulLen);
428 if(!rc)
429 {
430 lpcst->fCtsHold = ((ucStatus & 0x01)>0);
431 lpcst->fDsrHold = ((ucStatus & 0x02)>0);
432 lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
433 lpcst->fXoffHold = ((ucStatus & 0x08)>0);
434 lpcst->fXoffSend = ((ucStatus & 0x10)>0);
435 lpcst->fEof = ((ucStatus & 0x20)>0);// Is break = Eof ??
436 lpcst->fTxim = ((ucStatus & 0x40)>0);
437
438 ulLen = sizeof(qInfo);
439 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
440 IOCTL_ASYNC,
441 ASYNC_GETINQUECOUNT,
442 0,0,0,
443 &qInfo,ulLen,&ulLen);
444 if(!rc)
445 {
446 lpcst->cbInQue = qInfo.cch;
447 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
448 IOCTL_ASYNC,
449 ASYNC_GETOUTQUECOUNT,
450 0,0,0,
451 &qInfo,ulLen,&ulLen);
452 if(!rc)
453 lpcst->cbOutQue = qInfo.cch;
454 }
455 }
456 }
457
458 return(rc==0);
459}
460BOOL HMDeviceCommClass::SetCommState( PHMHANDLEDATA pHMHandleData,
461 LPDCB lpDCB)
462{
463 APIRET rc;
464 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
465 DCB *pCurDCB = &pDevData->CommCfg.dcb;
466 dprintf(("HMDeviceCommClass::SetCommState"));
467
468 rc = 0;
469 if(pCurDCB->BaudRate != lpDCB->BaudRate)
470 rc = SetBaud( pHMHandleData,
471 lpDCB->BaudRate);
472
473 if(!rc)
474 {
475 if( (pCurDCB->ByteSize != lpDCB->ByteSize) ||
476 (pCurDCB->Parity != lpDCB->Parity) ||
477 (pCurDCB->StopBits != lpDCB->StopBits))
478 rc = SetLine( pHMHandleData,
479 lpDCB->ByteSize,
480 lpDCB->Parity,
481 lpDCB->StopBits);
482 }
483
484 if(!rc)
485 {
486 if( (pCurDCB->fOutxCtsFlow != lpDCB->fOutxCtsFlow) ||
487 (pCurDCB->fOutxDsrFlow != lpDCB->fOutxDsrFlow) ||
488 (pCurDCB->fDtrControl != lpDCB->fDtrControl) ||
489 (pCurDCB->fDsrSensitivity != lpDCB->fDsrSensitivity) ||
490 (pCurDCB->fTXContinueOnXoff != lpDCB->fTXContinueOnXoff) ||
491 (pCurDCB->fOutX != lpDCB->fOutX) ||
492 (pCurDCB->fInX != lpDCB->fInX) ||
493 (pCurDCB->fErrorChar != lpDCB->fErrorChar) ||
494 (pCurDCB->fNull != lpDCB->fNull) ||
495 (pCurDCB->fRtsControl != lpDCB->fRtsControl) ||
496 (pCurDCB->fAbortOnError != lpDCB->fAbortOnError) ||
497 (pCurDCB->XonChar != lpDCB->XonChar) ||
498 (pCurDCB->XoffChar != lpDCB->XoffChar) ||
499 (pCurDCB->ErrorChar != lpDCB->ErrorChar))
500 SetOS2DCB( pHMHandleData,
501 lpDCB->fOutxCtsFlow, lpDCB->fOutxDsrFlow,
502 lpDCB->fDtrControl, lpDCB->fDsrSensitivity,
503 lpDCB->fTXContinueOnXoff, lpDCB->fOutX,
504 lpDCB->fInX, lpDCB->fErrorChar,
505 lpDCB->fNull, lpDCB->fRtsControl,
506 lpDCB->fAbortOnError, lpDCB->XonChar,
507 lpDCB->XoffChar,lpDCB->ErrorChar);
508 }
509
510 return(rc==0);
511}
512BOOL HMDeviceCommClass::GetCommState( PHMHANDLEDATA pHMHandleData,
513 LPDCB lpdcb)
514{
515 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
516
517 dprintf(("HMDeviceCommClass::GetCommState"));
518 memcpy(lpdcb,&pDevData->CommCfg.dcb,sizeof(DCB));
519
520 return(TRUE);
521}
522BOOL HMDeviceCommClass::GetCommModemStatus( PHMHANDLEDATA pHMHandleData,
523 LPDWORD lpModemStat )
524{
525 APIRET rc;
526 ULONG ulLen;
527 USHORT COMErr;
528 UCHAR ucStatus;
529
530 dprintf(("HMDeviceCommClass::TransmitCommChar partly implemented"));
531 ulLen = sizeof(CHAR);
532
533 ulLen = 1;
534 *lpModemStat = 0;
535
536 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
537 IOCTL_ASYNC,
538 ASYNC_GETMODEMINPUT,
539 0,0,0,
540 &ucStatus,ulLen,&ulLen);
541 if(!rc)
542 {
543 *lpModemStat |= (ucStatus & 0x10)? MS_CTS_ON:0;
544 *lpModemStat |= (ucStatus & 0x20)? MS_DSR_ON:0;
545 *lpModemStat |= (ucStatus & 0x40)? MS_RING_ON:0;
546 //*lpModemStat |= (ucStatus & 0x80)? MS_RSLD_ON:0;
547 }
548
549 return(rc==0);
550}
551
552BOOL HMDeviceCommClass::GetCommTimeouts( PHMHANDLEDATA pHMHandleData,
553 LPCOMMTIMEOUTS lpctmo)
554{
555 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
556
557 dprintf(("HMDeviceCommClass::GetCommTimeouts stub"));
558 memcpy( lpctmo,
559 &pDevData->CommTOuts,
560 sizeof(COMMTIMEOUTS));
561 return(TRUE);
562}
563BOOL HMDeviceCommClass::SetCommTimeouts( PHMHANDLEDATA pHMHandleData,
564 LPCOMMTIMEOUTS lpctmo)
565{
566 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
567 DCBINFO os2dcb;
568 ULONG ulLen;
569 APIRET rc;
570
571 memcpy( &pDevData->CommTOuts,
572 lpctmo,
573 sizeof(COMMTIMEOUTS));
574
575 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
576
577 os2dcb.fbTimeOut = 0x01;
578 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
579 {
580 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
581 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
582 os2dcb.fbTimeOut = 0x03;
583 else
584 os2dcb.fbTimeOut = 0x02;
585 }
586 else
587 {
588 DWORD dwTimeout;
589 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
590 if(dwTimeout)
591 dwTimeout--; // 0=10 ms unit is 10ms or .01s
592 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
593 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
594 }
595 ulLen = sizeof(DCBINFO);
596 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
597 IOCTL_ASYNC,
598 ASYNC_SETDCBINFO,
599 &os2dcb,ulLen,&ulLen,
600 NULL,0,NULL);
601
602 return(0==rc);
603}
604BOOL HMDeviceCommClass::TransmitCommChar( PHMHANDLEDATA pHMHandleData,
605 CHAR cChar )
606{
607 APIRET rc;
608 ULONG ulLen;
609 USHORT COMErr;
610
611 dprintf(("HMDeviceCommClass::TransmitCommChar"));
612 ulLen = sizeof(CHAR);
613
614 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
615 IOCTL_ASYNC,
616 ASYNC_TRANSMITIMM,
617 &cChar,ulLen,&ulLen,
618 NULL,0,NULL);
619
620 return(rc==0);
621}
622
623BOOL HMDeviceCommClass::SetCommBreak( PHMHANDLEDATA pHMHandleData )
624{
625 APIRET rc;
626 ULONG ulLen;
627 USHORT COMErr;
628
629 dprintf(("HMDeviceCommClass::SetCommBreak"));
630 ulLen = sizeof(USHORT);
631
632 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
633 IOCTL_ASYNC,
634 ASYNC_SETBREAKON,
635 0,0,0,
636 &COMErr,2,&ulLen);
637
638 return(rc==0);
639}
640
641BOOL HMDeviceCommClass::ClearCommBreak( PHMHANDLEDATA pHMHandleData)
642{
643 APIRET rc;
644 ULONG ulLen;
645 USHORT COMErr;
646
647 dprintf(("HMDeviceCommClass::ClearCommBreak"));
648 ulLen = sizeof(USHORT);
649
650 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
651 IOCTL_ASYNC,
652 ASYNC_SETBREAKOFF,
653 0,0,0,
654 &COMErr,2,&ulLen);
655
656 return(rc==0);
657}
658
659BOOL HMDeviceCommClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
660 LPCOMMCONFIG lpCC,
661 DWORD dwSize )
662{
663 dprintf(("HMDeviceCommClass::SetCommConfig"));
664
665
666 return(TRUE);
667}
668
669BOOL HMDeviceCommClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
670 LPCOMMCONFIG lpCC,
671 LPDWORD lpdwSize )
672{
673 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
674
675 dprintf(("HMDeviceCommClass::GetCommConfig"));
676
677 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
678 *lpdwSize< sizeof(COMMCONFIG) )
679 {
680 O32_SetLastError(ERROR_INSUFFICIENT_BUFFER);
681 *lpdwSize= sizeof(COMMCONFIG);
682 return FALSE;
683 }
684
685 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
686 {
687 O32_SetLastError(ERROR_INVALID_HANDLE);
688 return FALSE;
689 }
690
691 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
692 *lpdwSize = sizeof(COMMCONFIG);
693 return(TRUE);
694
695
696 return(TRUE);
697}
698
699BOOL HMDeviceCommClass::EscapeCommFunction( PHMHANDLEDATA pHMHandleData,
700 UINT dwFunc )
701{
702 APIRET rc;
703 ULONG ulDLen,ulPLen;
704 USHORT COMErr;
705 MODEMSTATUS mdm;
706
707 dprintf(("HMDeviceCommClass::EscapeCommFunction"));
708
709 ulDLen = sizeof(USHORT);
710 ulPLen = sizeof(MODEMSTATUS);
711 switch(dwFunc)
712 {
713 case CLRDTR:
714 mdm.fbModemOn = 0x00;
715 mdm.fbModemOff = 0XFE;
716 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
717 IOCTL_ASYNC,
718 ASYNC_SETMODEMCTRL,
719 &mdm,ulPLen,&ulPLen,
720 &COMErr,ulDLen,&ulDLen);
721 break;
722 case CLRRTS:
723 mdm.fbModemOn = 0x00;
724 mdm.fbModemOff = 0XFD;
725 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
726 IOCTL_ASYNC,
727 ASYNC_SETMODEMCTRL,
728 &mdm,ulPLen,&ulPLen,
729 &COMErr,ulDLen,&ulDLen);
730 break;
731 case SETDTR:
732 mdm.fbModemOn = 0x01;
733 mdm.fbModemOff = 0XFF;
734 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
735 IOCTL_ASYNC,
736 ASYNC_SETMODEMCTRL,
737 &mdm,ulPLen,&ulPLen,
738 &COMErr,ulDLen,&ulDLen);
739 break;
740 case SETRTS:
741 mdm.fbModemOn = 0x02;
742 mdm.fbModemOff = 0XFF;
743 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
744 IOCTL_ASYNC,
745 ASYNC_SETMODEMCTRL,
746 &mdm,ulPLen,&ulPLen,
747 &COMErr,ulDLen,&ulDLen);
748 break;
749 case SETXOFF:
750 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
751 IOCTL_ASYNC,
752 ASYNC_STOPTRANSMIT,
753 0,0,0,
754 0,0,0);
755 break;
756 case SETXON:
757 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
758 IOCTL_ASYNC,
759 ASYNC_STARTTRANSMIT,
760 0,0,0,
761 0,0,0);
762 break;
763 default:
764 O32_SetLastError(ERROR_INVALID_PARAMETER);
765 return(FALSE);
766 }
767
768 return(rc==0);
769}
770
771BOOL HMDeviceCommClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
772 LPCOMMCONFIG lpCC,
773 DWORD dwSize)
774{
775 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
776 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
777 {
778 O32_SetLastError(ERROR_INVALID_HANDLE);
779 return FALSE;
780 }
781 memset(&pDevData->CommCfg,0, sizeof(COMMCONFIG));
782 memcpy(&pDevData->CommCfg,lpCC,dwSize>sizeof(COMMCONFIG)?sizeof(COMMCONFIG):dwSize);
783
784 return(TRUE);
785}
786BOOL HMDeviceCommClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
787 LPCOMMCONFIG lpCC,
788 LPDWORD lpdwSize)
789{
790 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
791
792 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
793 *lpdwSize< sizeof(COMMCONFIG) )
794 {
795 O32_SetLastError(ERROR_INSUFFICIENT_BUFFER);
796 *lpdwSize= sizeof(COMMCONFIG);
797 return FALSE;
798 }
799
800 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
801 {
802 O32_SetLastError(ERROR_INVALID_HANDLE);
803 return FALSE;
804 }
805
806 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
807 *lpdwSize = sizeof(COMMCONFIG);
808 return(TRUE);
809}
810APIRET HMDeviceCommClass::SetLine( PHMHANDLEDATA pHMHandleData,
811 UCHAR ucSize,
812 UCHAR ucParity,
813 UCHAR ucStop)
814{
815 APIRET rc;
816 ULONG ulLen;
817 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
818 DCB *pCurDCB = &pDevData->CommCfg.dcb;
819 struct
820 {
821 UCHAR ucSize;
822 UCHAR ucParity;
823 UCHAR ucStop;
824 UCHAR ucPadding;
825 }Param;
826
827 ulLen = 3;
828 Param.ucSize = ucSize;
829 Param.ucParity = ucParity;
830 Param.ucStop = ucStop;
831
832 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
833 IOCTL_ASYNC,
834 ASYNC_SETLINECTRL,
835 &Param,ulLen,&ulLen,
836 NULL,0,NULL);
837
838 if(0==rc)
839 {
840 pCurDCB->ByteSize = ucSize;
841 pCurDCB->Parity = ucParity;
842 pCurDCB->StopBits = ucStop;
843 }
844
845 return rc;
846}
847
848APIRET HMDeviceCommClass::SetOS2DCB( PHMHANDLEDATA pHMHandleData,
849 BOOL fOutxCtsFlow, BOOL fOutxDsrFlow,
850 UCHAR ucDtrControl, BOOL fDsrSensitivity,
851 BOOL fTXContinueOnXoff, BOOL fOutX,
852 BOOL fInX, BOOL fErrorChar,
853 BOOL fNull, UCHAR ucRtsControl,
854 BOOL fAbortOnError, BYTE XonChar,
855 BYTE XoffChar,BYTE ErrorChar)
856{
857 APIRET rc;
858 ULONG ulLen;
859 DCBINFO os2dcb;
860
861 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
862 DCB *pCurDCB = &pDevData->CommCfg.dcb;
863
864 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
865 os2dcb.fbCtlHndShake = (ucDtrControl & 0x03) |
866 (fOutxCtsFlow?0x08:0x00) |
867 (fOutxDsrFlow?0x10:0x00) |
868 // No DCD support in Win32 ?!
869 (fDsrSensitivity?0x40:0x00);
870 os2dcb.fbFlowReplace = (fOutX?0x01:0x00) |
871 (fInX?0x02:0x00) |
872 (fErrorChar?0x04:0x00)|
873 (fNull?0x08:0x00)|
874 (fTXContinueOnXoff?0x02:0x00)| // Not sure if thats the right flag to test
875 (ucRtsControl<<6);
876
877 os2dcb.fbTimeOut = 0x01;
878 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
879 {
880 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
881 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
882 os2dcb.fbTimeOut = 0x03;
883 else
884 os2dcb.fbTimeOut = 0x02;
885 }
886 else
887 {
888 DWORD dwTimeout;
889 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
890 if(dwTimeout)
891 dwTimeout--; // 0=10 ms unit is 10ms or .01s
892 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
893 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
894 }
895 os2dcb.bErrorReplacementChar = ErrorChar;
896 os2dcb.bXONChar = XonChar;
897 os2dcb.bXOFFChar = XoffChar;
898 ulLen = sizeof(DCBINFO);
899 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
900 IOCTL_ASYNC,
901 ASYNC_SETDCBINFO,
902 &os2dcb,ulLen,&ulLen,
903 NULL,0,NULL);
904
905 if(0==rc)
906 {
907 memcpy(&pDevData->dcbOS2,&os2dcb,sizeof(DCBINFO));
908 pCurDCB->fOutxCtsFlow = fOutxCtsFlow;
909 pCurDCB->fOutxDsrFlow = fOutxDsrFlow;
910 pCurDCB->fDtrControl = ucDtrControl;
911 pCurDCB->fDsrSensitivity = fDsrSensitivity;
912 pCurDCB->fTXContinueOnXoff = fTXContinueOnXoff;
913 pCurDCB->fOutX = fOutX;
914 pCurDCB->fInX = fInX;
915 pCurDCB->fErrorChar = fErrorChar;
916 pCurDCB->fNull = fNull;
917 pCurDCB->fRtsControl = ucRtsControl;
918 pCurDCB->fAbortOnError = fAbortOnError;
919 pCurDCB->XonChar = XonChar;
920 pCurDCB->XoffChar = XoffChar;
921 pCurDCB->ErrorChar = ErrorChar;
922 }
923
924 return rc;
925
926}
927
928APIRET HMDeviceCommClass::SetBaud( PHMHANDLEDATA pHMHandleData,
929 DWORD dwNewBaud)
930{
931 APIRET rc;
932 ULONG ulLen;
933 EXTBAUDSET SetBaud;
934 EXTBAUDGET GetBaud;
935 ulLen = sizeof(SetBaud);
936 SetBaud.ulBaud = dwNewBaud;
937 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
938 IOCTL_ASYNC,
939 ASYNC_EXTSETBAUDRATE,
940 &SetBaud,ulLen,&ulLen,
941 NULL,0,NULL);
942 if(0==rc)
943 {
944 ulLen = sizeof(GetBaud);
945 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
946 IOCTL_ASYNC,
947 ASYNC_EXTGETBAUDRATE,
948 NULL,0,NULL,
949 &GetBaud,ulLen,&ulLen);
950 if(0==rc)
951 {
952 if(dwNewBaud !=GetBaud.ulCurrBaud)
953 rc = 1; // ToDo set a proper Errorhandling
954 else
955 {
956 ((PHMDEVCOMDATA)pHMHandleData->lpDeviceData)->CommCfg.dcb.BaudRate = dwNewBaud;
957 ((PHMDEVCOMDATA)pHMHandleData->lpDeviceData)->CommCfg.dcb.BaudRate = dwNewBaud;
958 }
959 }
960 }
961 return rc;
962}
963
Note: See TracBrowser for help on using the repository browser.