home *** CD-ROM | disk | FTP | other *** search
- /* modem.c */
- /*---------------------------------------------------------------------------*/
- /* This file is part of PSFax/2. */
- /* */
- /* Written By: Gary L. Hennigan */
- /* */
- /* This code can modified as much as you like provided you follow the */
- /* guidelines as described in the file install.doc which you should have */
- /* received with this file. If you did not please notify the author for a */
- /* copy of this file via Internet email. The address is: */
- /* ghenniga@NMSU.Edu */
- /*---------------------------------------------------------------------------*/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-
- #include "psfax2.h"
-
- #define DevIOCtl DosDevIOCtl32
-
- /**Global variables defined in psfax2.c **/
- extern char cGlobResp[];
-
- ULONG ulTemp; /* Used by various functions in modem.c */
- USHORT usTemp;
-
- void vFlushIO( HFILE );
- unsigned char swap_bits( unsigned char );
- USHORT usSetTTYTime( HFILE, DCBINFO *, int );
- int iGetResp( HFILE, DCBINFO *, char *, int, int, char * );
-
- /****************************************************************************/
- /*************************Used for simplifying*******************************/
- /*************************IOCtl function calls*******************************/
- /****************************************************************************/
- USHORT DosDevIOCtl32(PVOID pData, USHORT cbData, PVOID pParms, USHORT cbParms,
- USHORT usFunction, USHORT usCategory, HFILE hDevice)
- {
- ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData;
- return (USHORT)DosDevIOCtl(hDevice, usCategory, usFunction,
- pParms, cbParms, &ulParmLengthInOut,
- pData, cbData, &ulDataLengthInOut);
- }
- /****************************************************************************/
- /***************************Open the COM Port********************************/
- /****************************************************************************/
- ULONG ulOpenPort(char *cPort, HFILE *hTTY)
- {
-
- return DosOpen(cPort, hTTY, &ulTemp, 0L, 0, FILE_OPEN,
- OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE |
- OPEN_FLAGS_FAIL_ON_ERROR, 0L);
- }
- /****************************************************************************/
- /**********************Get the current port settings*************************/
- /****************************************************************************/
- int iPortGetSet(HFILE hTTY, DCBINFO *dcbCom)
- {
- usTemp = DevIOCtl(dcbCom,sizeof(*dcbCom),NULL,0,
- ASYNC_GETDCBINFO, IOCTL_ASYNC, hTTY);
-
- if(usTemp != 0)
- return 1;
-
- return 0;
- }
- /****************************************************************************/
- /**************************Initialize the Port*******************************/
- /****************************************************************************/
- int iPortInit(HFILE hTTY, DCBINFO *dcbCom)
- {
- MODEMSTATUS ms;
- UINT data;
- /*-------------------------------End Declarations---------------------------*/
-
- /**Set XON/XOFF flow control. **/
- dcbCom->fbCtlHndShake = MODE_DTR_CONTROL;
- dcbCom->fbFlowReplace &= ~(MODE_AUTO_RECEIVE | MODE_AUTO_TRANSMIT |
- MODE_RTS_CONTROL | MODE_RTS_HANDSHAKE);
- dcbCom->fbFlowReplace |= (MODE_AUTO_RECEIVE | MODE_AUTO_TRANSMIT |
- MODE_RTS_CONTROL);
- ms.fbModemOn = RTS_ON;
- ms.fbModemOff = 255;
-
- usTemp = DevIOCtl(NULL,0,dcbCom,sizeof(*dcbCom),ASYNC_SETDCBINFO,
- IOCTL_ASYNC, hTTY);
- if(usTemp != 0)
- return -1;
-
- usTemp = DevIOCtl(&data,sizeof(data),&ms,sizeof(ms),
- ASYNC_SETMODEMCTRL,IOCTL_ASYNC,hTTY);
- if(usTemp != 0)
- return -1;
-
- return 0;
- }
- /****************************************************************************/
- /**************************Initialize the Modem******************************/
- /****************************************************************************/
- int iModemInit(HFILE hTTY, DCBINFO *dcbCom)
- {
- char cBuff[256];
- int iCnt=0;
- /*-------------------------------End Declarations---------------------------*/
-
- strcpy(cBuff,"ATZ\r"); /* Use the default profile of the modem. */
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp);
- if(iGetResp(hTTY, dcbCom, cBuff, 10*sizeof(char), 3, NULL) <= 0 ||
- !strstr(cBuff,"OK\r") )
- return 1;
-
- strcpy(cBuff,"AT&K4V0Q0E0L2M1W2S0=0S2=255S12=255 +FCLASS=2\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp);
- if(iGetResp(hTTY, dcbCom, cBuff, strlen(cBuff)+2*sizeof(char),
- 2, NULL) <= 0 || !strstr(cBuff,"0\r"))
- return 1;
-
- strcpy(cBuff,"ATS7=120 +FCR=1\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp); sleep(1);
- if(iGetResp(hTTY, dcbCom, cBuff, 2*sizeof(char), 2, NULL) <= 0 ||
- !strstr(cBuff,"0\r"))
- return 1;
-
- strcpy(cBuff,"AT+FDCC=1,3\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp); sleep(1);
- if(iGetResp(hTTY, dcbCom, cBuff, 2*sizeof(char), 2, NULL) <= 0 ||
- !strstr(cBuff,"0\r"))
- return 1;
-
- strcpy(cBuff,"AT+FBOR=0\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp); sleep(1);
- if(iGetResp(hTTY, dcbCom, cBuff, 2*sizeof(char), 2, NULL) <= 0 ||
- !strstr(cBuff,"0\r"))
- return 1;
-
- /**Flush all the I/O, set the timeout for reads, and see if the modem **/
- /**is responding properly. **/
- vFlushIO(hTTY);
- usSetTTYTime(hTTY, dcbCom, 2);
-
- strcpy(cBuff, "AT\r");
- do
- {
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp);
- iCnt++;
- DosRead(hTTY, cBuff, 2, &ulTemp);
- }
- while(ulTemp == 0 && iCnt <= MAXTIMEOUTS);
-
- if(ulTemp == 0 && iCnt >= MAXTIMEOUTS)return 1;
-
- if(strncmp(cBuff,"0\r",2) != 0)
- {
- printf("Bad modem response while attempting to sync!\n");
- return 1;
- }
-
- return 0;
- }
- /****************************************************************************/
- /****************************Dial the Phone**********************************/
- /****************************************************************************/
- int iModemDial( HFILE hTTY, char *cPhoneNum, DCBINFO *dcbCom, int iWait )
- {
- int iRedial;
- char cBuff[256];
- /*-------------------------------End Declarations---------------------------*/
-
- strcpy(cBuff,"ATD");
- strcat(cBuff,cPhoneNum);
- strcat(cBuff,"\r");
-
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp); sleep(1);
- if(iGetResp(hTTY, dcbCom, cBuff, 2, iWait, NULL) <= 0)
- {
- cBuff[0] = 0x1b;
- cBuff[1] = 0x00;
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp); sleep(2);
- vFlushIO(hTTY);
- return DIAL_NOANSWER;
- }
-
- if( cBuff[0] )
- {
- switch(cBuff[0])
- {
- case '3':
- iRedial = DIAL_NOCARRIER;
- vFlushIO(hTTY);
- return iRedial;
-
- case '6':
- iRedial = DIAL_NODIALTONE;
- vFlushIO(hTTY);
- return iRedial;
-
- case '7':
- iRedial = DIAL_BUSY;
- vFlushIO(hTTY);
- return iRedial;
-
- case '8':
- iRedial = DIAL_NOANSWER;
- vFlushIO(hTTY);
- return iRedial;
-
- default:
- iRedial = 0;
- break;
- }
- }
- else
- {
- vFlushIO(hTTY);
- return DIAL_NOANSWER;
- }
-
- /**Make sure the remote responds with a connection indication. **/
- if(iGetResp(hTTY, dcbCom, &cBuff[2], 8, -20, "+FCON\r") <= 0)
- {
- printf("Incorrect response \"%s\" received...\n",cBuff);
- vFlushIO(hTTY);
- return DIAL_UNKNOWN;
- }
- else
- strcpy(cGlobResp,cBuff);
-
- puts("Fax connection established!");
- return iRedial;
- }
- /****************************************************************************/
- /*******************Initialize the fax-fax connection************************/
- /****************************************************************************/
- int iFaxInit(HFILE hTTY, DCBINFO *dcbCom, int df, int vr, int wd, int ln)
- {
- char cBuff[256];
- /*-------------------------------End Declarations---------------------------*/
-
- /**Make sure the remote responded correctly. **/
- if(iGetResp(hTTY, dcbCom, cBuff, 50, -15, "0\r") <= 0)
- {
- puts("Remote fax is not responding....");
- return 1;
- }
-
- /**Set transmission parameters. **/
- sprintf(cBuff,"AT+FDT=%d,%d,%d,%d\r", df, vr, wd, ln);
- vFlushIO(hTTY);
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp); sleep(1);
-
- /**Make sure the remote responds with a CONNECT. **/
- if(iGetResp(hTTY, dcbCom, cBuff, 50, -15, "1\r") <= 0)
- {
- puts("Remote fax is not responding....");
- return 1;
- }
- vFlushIO(hTTY);
-
- return 0;
- }
- /****************************************************************************/
- /*********************Send a page via the Fax/Modem**************************/
- /****************************************************************************/
- int iFaxSendPage(HFILE hTTY, DCBINFO *dcbCom, FILE *fStream, int iLast)
- {
- unsigned char cBuff[SENDCHUNK], cBuff2[2*SENDCHUNK];
- int iNumRead, iNumWrite, i1, iPPRCode;
- /*-------------------------------End Declarations---------------------------*/
-
- iNumRead = fread(cBuff, sizeof(char), SENDCHUNK, fStream);
- usSetTTYTime(hTTY, dcbCom, -15);
-
- while(iNumRead > 0)
- {
- iNumWrite = 0;
-
- /** Swap the bits and pad DLE characters. **/
- for(i1=0; i1 < iNumRead; i1++)
- {
- cBuff2[iNumWrite] = swap_bits(cBuff[i1]);
- if(cBuff2[iNumWrite++] == DLE)
- cBuff2[iNumWrite++] = DLE;
- }
-
- /** Write the stuff out to the modem. **/
- DosWrite(hTTY, cBuff2, iNumWrite, &ulTemp);
-
- /** Check for a response, if any, from the modem. **/
- DosRead(hTTY, cBuff, sizeof(cBuff), &ulTemp);
- if(ulTemp != 0)
- {
- for(i1=0; i1 < ulTemp; i1++)
- {
- if((cBuff[i1] & 0x7f) == CAN)
- {
- printf("Remote has canceled transmission!\n");
- sprintf(cBuff,"%c%c",DLE,ETX);
- DosWrite(hTTY, cBuff, 2*sizeof(char), &ulTemp);
- return -1;
- }
- }
- }
-
- iNumRead = fread(cBuff, sizeof(char), SENDCHUNK, fStream);
- }
- sprintf(cBuff,"%c%c",DLE,ETX);
- DosWrite(hTTY, cBuff, 2*sizeof(char), &ulTemp);
- i1 = iGetResp(hTTY, dcbCom, cBuff, 2, -15, "0\r");
- if(i1 <= 0)
- {
- puts("Incorrect response from remote to end-of-page message!\n");
- return -1;
- }
-
- switch(iLast)
- {
- case PEND_ANOTHER:
- strcpy(cBuff,"AT+FET=0\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp);
- break;
- case PEND_ENDTRAN:
- strcpy(cBuff,"AT+FET=2\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp);
- break;
- }
-
- /**Get the post-page response. **/
- if(iGetResp(hTTY, dcbCom, cBuff, 20, -10, "0\r") <= 0)
- {
- puts("No post-page response from remote!");
- return -1;
- }
- if(iLast == PEND_ANOTHER)
- DosWrite(hTTY, "AT+FDT\r", sizeof("AT+FDT\r"), &ulTemp);
-
- strtok(&cBuff[8],"\r");
- i1 = sscanf(&cBuff[8], "%d", &iPPRCode);
- if(i1 <= 0)
- {
- puts("Incorrect post-page response from remote!");
- return -1;
- }
- if(iLast == PEND_ANOTHER)
- {
- if(iGetResp(hTTY, dcbCom, cBuff, 2, -10, "1\r") <= 0)
- {
- puts("Unable to continue transmission!");
- return -1;
- }
- }
- else
- {
- if(iGetResp(hTTY, dcbCom, cBuff, 2, -15, "0\r") <= 0)
- {
- puts("Failed to properly end transmission!");
- return -1;
- }
- }
-
- return iPPRCode;
- }
- /****************************************************************************/
- /************Tell the remote to intterrupt the transmission******************/
- /****************************************************************************/
- int iFaxInterrupt(HFILE hTTY, DCBINFO *dcbCom)
- {
- char cBuff[20];
- /*-------------------------------End Declarations---------------------------*/
-
- strcpy(cBuff,"AT+FK\r");
- DosWrite(hTTY, cBuff, strlen(cBuff), &ulTemp);
-
- return 0;
- }
- /****************************************************************************/
- /**************************Close the COM Port********************************/
- /****************************************************************************/
- ULONG ulClosePort(HFILE hTTY)
- {
- return DosClose(hTTY);
- }
- /****************************************************************************/
- /********************Read the response from the modem************************/
- /****************************************************************************/
- int iGetResp( HFILE hTTY, DCBINFO *dcbCom, char *cBuff, int iExpSize,
- int iTimeout, char *cSearch )
- {
- int iStart=0, iCnt=0;
-
- /**Initialize the buffer. **/
- cBuff[0] = '\000';
-
- /**Set the desired timeout for this read. **/
- usSetTTYTime(hTTY, dcbCom, iTimeout);
-
- /**Read the response. **/
- if(!cSearch)
- {
- DosRead(hTTY, cBuff, iExpSize, &ulTemp);
- cBuff[ulTemp] = '\000'; /* For string manipulation functions. */
- iStart = ulTemp;
- }
- else
- {
- do
- {
- DosRead(hTTY, &cBuff[iStart], iExpSize, &ulTemp);
- iStart += ulTemp;
- cBuff[iStart] = '\000';
- iCnt++;
- }
- while(!strstr(cBuff,cSearch) && iCnt <= MAXTIMEOUTS);
- }
-
- if(iCnt > MAXTIMEOUTS)
- return -1;
-
- return iStart;
- }
- /****************************************************************************/
- /***********************Set the read timeout on******************************/
- /******************************the COM port**********************************/
- /****************************************************************************/
- USHORT usSetTTYTime(HFILE hTTY, DCBINFO *dcbCom, int iTime)
- {
- if(iTime >= 0)
- iTime *= 100;
- else
- iTime *= -1;
-
- dcbCom->usReadTimeout = iTime;
- return (DevIOCtl(NULL,0,dcbCom,sizeof(*dcbCom),ASYNC_SETDCBINFO,
- IOCTL_ASYNC, hTTY));
- }
- /****************************************************************************/
- /*************************Flush all pending I/O******************************/
- /****************************************************************************/
- void vFlushIO(HFILE hTTY)
- {
- UINT data;
- char parm=0;
- /*-------------------------------End Declarations---------------------------*/
-
- DevIOCtl(&data,sizeof(data),&parm,sizeof(parm),
- DEV_FLUSHINPUT, IOCTL_GENERAL, hTTY);
- DevIOCtl(&data,sizeof(data),&parm,sizeof(parm),
- DEV_FLUSHOUTPUT, IOCTL_GENERAL, hTTY);
-
- }
- /****************************************************************************/
- /************************Builds table to swap the****************************/
- /******************low order 4 bits with the high order**********************/
- /****************************************************************************/
- static void init_swaptable(unsigned char *swaptable)
- {
- int i, j;
- /*-------------------------------End Declarations---------------------------*/
-
- for (i = 0; i < 256; i++) {
- j = ( ((i & 0x01) << 7) |
- ((i & 0x02) << 5) |
- ((i & 0x04) << 3) |
- ((i & 0x08) << 1) |
- ((i & 0x10) >> 1) |
- ((i & 0x20) >> 3) |
- ((i & 0x40) >> 5) |
- ((i & 0x80) >> 7) );
- swaptable[i] = j;
- }
- }
-
- /****************************************************************************/
- /********************Reverses the low order 4 bits of a byte*****************/
- /****************************************************************************/
- unsigned char swap_bits(unsigned char c)
- {
- static unsigned char swaptable[256];
- static int swaptable_init = FALSE;
- /*-------------------------------End Declarations---------------------------*/
-
- if (!swaptable_init) {
- init_swaptable(swaptable);
- swaptable_init = TRUE;
- }
-
- return(swaptable[c]);
- }
-