home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
pmtermsr.lzh
/
async.c
next >
Wrap
C/C++ Source or Header
|
1995-10-13
|
6KB
|
233 lines
/*
* This file contains helper functions that are specific to programming
* the serial port (OpenPort, SetRate, etc)
*/
#include "pmterm.h"
#ifndef ASYNC_EXTSETBAUDRATE
#define ASYNC_EXTSETBAUDRATE 0x0043
#define ASYNC_EXTGETBAUDRATE 0X0063
#endif
HFILE OpenPort(char *name)
{
HFILE hf;
APIRET rc;
ULONG ulAction;
rc = DosOpen(name, /* pointer to filename */
&hf, /* pointer to variable for file handle */
&ulAction, /* pointer to variable for action taken */
0L, /* file size if file is created or truncated */
FILE_NORMAL, /* file attribute */
OPEN_ACTION_OPEN_IF_EXISTS, /* action if file exists/does not exist */
OPEN_ACCESS_READWRITE |
OPEN_SHARE_DENYREADWRITE, /* open mode of file */
NULL); /* pointer to structure for extended attributes */
if(rc){
printf( "sys%04u: error from dosopen(%s)\n", rc, name);
return 0xffff;
}
return hf;
}
int SetRate(HFILE hf, USHORT rate) // returns 0 on success
{
APIRET rc;
ULONG ulPinout, ulDinout;
ulPinout = sizeof(rate);
ulDinout = 0;
rc = DosDevIOCtl(hf,
IOCTL_ASYNC,
ASYNC_SETBAUDRATE,
&rate, sizeof(rate), &ulPinout, /* parms */
NULL, 0, &ulDinout); /* data */
if(rc)
printf("sys%04u: SetRate() error\n", rc);
return (int)rc;
}
typedef struct _esrp
{
ULONG ulBitRate;
BYTE bFraction;
} EXTSETRATEPARMS;
int SetRate2(HFILE hf, ULONG rate) // returns 0 on success
{
EXTSETRATEPARMS esr;
APIRET rc;
ULONG ulPinout, ulDinout;
ulPinout = sizeof(esr);
ulDinout = 0;
esr.ulBitRate = rate;
esr.bFraction = 0;
rc = DosDevIOCtl(hf,
IOCTL_ASYNC,
ASYNC_EXTSETBAUDRATE,
&esr, sizeof(esr), &ulPinout, /* parms */
NULL, 0, &ulDinout); /* data */
if(rc)
printf("sys%04u: SetRate2() error\n", rc);
return (int)rc;
}
#pragma pack(1)
typedef struct _eqrd
{
ULONG ulBitRate;
BYTE bFraction;
ULONG ulMinBitRate;
BYTE bMinFraction;
ULONG ulMaxBitRate;
BYTE bMaxFraction;
} EXTQUERYRATEDATA;
#pragma pack()
ULONG QueryMaxRate(HFILE hf)
{
APIRET rc;
ULONG ulPinout, ulDinout;
EXTQUERYRATEDATA qbr;
ulPinout = 0;
ulDinout = sizeof(qbr);
rc = DosDevIOCtl(hf,
IOCTL_ASYNC,
ASYNC_EXTGETBAUDRATE,
NULL, 0, &ulPinout,
&qbr, sizeof(qbr), &ulDinout); /* parms */
if(rc){
printf("SYS%04u: Couldn't query baud rate\n", rc);
if(rc == ERROR_BAD_COMMAND)
printf("(may require a newer version of com*.sys or OS/2 to run this program)\n");
return 0;
}
printf("Current Rate = %ld\n", qbr.ulBitRate);
printf("Min Rate = %ld\n", qbr.ulMinBitRate);
printf("Max Rate = %ld\n", qbr.ulMaxBitRate);
return qbr.ulMaxBitRate;
}
/*
* SetMode(): Set the desired READ MODE (Wait For Something)
* and WRITE MODE (near infinite)
*/
int SetMode(PDATA *pdata)
{
DCBINFO dcb;
APIRET rc;
ULONG ulPinout, ulDinout;
LINECONTROL lc;
HFILE hf = pdata->hf;
ulPinout = 0;
ulDinout = sizeof(dcb);
if(0 != (rc = DosDevIOCtl(hf, IOCTL_ASYNC, ASYNC_GETDCBINFO,
NULL, 0, &ulPinout, &dcb, sizeof(dcb), &ulDinout)))
return rc;
/* normal (not-infinite) write timeout processing */
dcb.fbTimeout &= ~MODE_NO_WRITE_TIMEOUT;
/* make sure these bits are off */
dcb.fbTimeout &= ~(MODE_READ_TIMEOUT | MODE_NOWAIT_READ_TIMEOUT);
/* set to "wait for something" read timeout processing */
dcb.fbTimeout |= MODE_WAIT_READ_TIMEOUT;
dcb.usReadTimeout = 100 * 5;
dcb.usWriteTimeout = 100 * 10; /* ten second write timeout */
dcb.fbCtlHndShake |= MODE_DTR_CONTROL;
if(pdata->ini.CtsRts){
dcb.fbCtlHndShake |= MODE_CTS_HANDSHAKE;
dcb.fbFlowReplace |= MODE_RTS_HANDSHAKE;
dcb.fbFlowReplace &= ~MODE_RTS_CONTROL;
}
else{
dcb.fbCtlHndShake &= ~MODE_CTS_HANDSHAKE;
dcb.fbFlowReplace &= ~MODE_RTS_HANDSHAKE;
}
if(pdata->ini.XonXoff)
dcb.fbFlowReplace |= (MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
else
dcb.fbFlowReplace &= ~(MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE);
if(dcb.fbTimeout & EHB_MASK){
dcb.fbTimeout &= ~(EHB_MASK | EHB_RTL_14 | EHB_TBLC_16);
if(pdata->ini.ExtBuf){
dcb.fbTimeout |= EHB_ENABLE | EHB_RTL_8 | EHB_TBLC_16;
}
else
dcb.fbTimeout |= EHB_DISABLE;
}
else if(pdata->ini.ExtBuf){
ErrMesg(pdata, "%s does not support extended hardware buffering.",
pdata->ini.DevName);
}
ulPinout = sizeof(dcb);
ulDinout = 0;
if(0 != (rc = DosDevIOCtl(hf, IOCTL_ASYNC, ASYNC_SETDCBINFO,
&dcb, sizeof(dcb), &ulPinout, NULL, 0, &ulDinout))){
return(rc);
}
lc.bDataBits = pdata->ini.databits;
lc.bParity = pdata->ini.parity ;
lc.bStopBits = pdata->ini.stopbits;
ulPinout = sizeof(lc);
ulDinout = 0;
if(0 != (rc = DosDevIOCtl(hf, IOCTL_ASYNC, ASYNC_SETLINECTRL,
&lc, sizeof(lc), &ulPinout, NULL, 0, &ulDinout))){
ErrMesg(pdata, "Error %d setting Databits, Parity, Stopbits", rc);
return(rc);
}
return 0;
}
int SetupPort(PDATA *pdata)
{
HFILE hf;
int rc;
ULONG htype, hflag, ul;
if(pdata->tidReadThread){
DosClose(pdata->hf); // this will cause an error in the read thread
DosWaitThread(&pdata->tidReadThread, 0);
pdata->tidReadThread= 0;
}
pdata->hf = hf = OpenPort(pdata->ini.DevName);
if(pdata->hf == 0xffff){
ErrMesg(pdata, "Couldn't open '%s'", pdata->ini.DevName);
return FALSE;
}
DosQueryHType(hf, &htype, &hflag);
if(htype != HANDTYPE_FILE){
if(rc=SetMode(pdata)){
ErrMesg(pdata, "SetMode() error %d\n", rc);
}
if(rc=SetRate2(hf, pdata->ini.bps)){
ErrMesg(pdata, "SetRate() error %d\n", rc);
}
DosWrite(hf, pdata->ini.InitString, strlen(pdata->ini.InitString), &ul);
DosWrite(hf, "\r", 1, &ul);
}
pdata->tidReadThread = _beginthread(AsyncReadThread, NULL, 0x2000, pdata);
return TRUE;
}