⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpftserial.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				// flush the pending wait and continue
				SetCommMask(mPortHandle, EV_RXCHAR);
				ResetEvent(handleArray[2]);
				continue;
			}

			// figure out how long to wait.  if we are waiting for a ring,
			//	then only fall asleep until the latest time the next ring
			//	could come in.
			if(mState == _cs_calldetected)
			{
				if(mLastRingTime + 8*1000 < (now = pgp_getticks()))
				{
					SetState(_cs_listening);
					continue;
				}
				timeout = mLastRingTime + 8*1000 - now;
			}
			else
				timeout = INFINITE;

WAIT_AGAIN:			// wait for the first event that gets triggered.
			result = WaitForMultipleObjects(3, handleArray, FALSE, timeout);
			if(result == WAIT_TIMEOUT)
			{
				// resume listening and flush the pending wait
				SetState(_cs_listening);
				SetCommMask(mPortHandle, EV_RXCHAR);
			}
			else if(result == WAIT_OBJECT_0)
				break;						// we have to abort
			else if(result == (WAIT_OBJECT_0+1))
			{
				//ResetEvent(mAnswerEvent);
				break;						// the phone has been answered
			}
			else if(result != (WAIT_OBJECT_0+2))
			{
				int error = GetLastError();
				if(error ==  ERROR_INVALID_HANDLE && handle_error_count++ < 50)
					goto WAIT_AGAIN;

				MODEM_ERROR("unknown error waiting on event", error);
				response = _pge_InternalAbort;
				break;
			}
			ResetEvent(handleArray[2]);		// must have gotten data
		}
	}

	// flush any pending calls to WaitCommEvent
	SetCommMask(mPortHandle, EV_RXCHAR);
	return response;
}

PGErr
CPFTSerial::Listen(Boolean answer)
{
	short	result = 0, reply = _cr_NoReply;

	mTMutex->Wait();
	if(answer)
		mAnswer = TRUE;
	else
		SetState(_cs_listening);
	while (!mAbort)
	{
		if((mAnswer || (WaitForRing() == _cr_Ring)) && !mAbort)
		{
			if(mAnswer)
			{
				SetState(_cs_connecting);
				Write("ATA\r");		/* answer the call, universal AT command */
				reply = GetModemResult(1000*60);
				if(reply == _cr_Connect)
				{
					SetState(_cs_connected);
					break;
				}
				else
					Write("\r");	/* abort the modem connecting */
			}
			else
			{
				if(mState != _cs_calldetected)
					SetState(_cs_calldetected);
				mLastRingTime = pgp_getticks();
				mPFWindow->GetStatusPane()->AddStatus(0, "...Ring...");
				if(gPGFOpts.popt.playRing)
					PlaySound("RING.WAV",NULL,SND_FILENAME+SND_SYNC);
			}
		}
		Sleep(0);
	}
	if(!mAnswer && mAbort)
		result = _pge_InternalAbort;
	mAnswer = FALSE;
	mTMutex->Signal();
	return result;
}

short
CPFTSerial::Reset()
{
	short	result=0;
	short	reply, inx;
	DCB		dcb;

	mTMutex->Wait();
	mAbort = FALSE;
	ResetEvent(mAbortEvent);

	// get the current settings for the port
	if(! GetCommState(mPortHandle, &dcb))
	{
		MODEM_ERROR("error getting modem settings", GetLastError());
		mTMutex->Signal();
		return -1;
	}

	// set the baud rate and other hardware parameters
	dcb.BaudRate        = mSerOpts.baud;
	dcb.fBinary         = 1;
	dcb.fParity         = 0;
	dcb.fOutxCtsFlow    = 1;
	dcb.fOutxDsrFlow    = 0;
	dcb.fDtrControl     = DTR_CONTROL_ENABLE;
	dcb.fDsrSensitivity = 0;
	dcb.fOutX           = 0;
	dcb.fInX            = 0;
	dcb.fErrorChar      = 0;
	dcb.fNull           = 0;
	dcb.fRtsControl     = RTS_CONTROL_ENABLE;
	dcb.fAbortOnError   = 0;
	dcb.ByteSize        = 8;
	dcb.Parity          = NOPARITY;
	dcb.StopBits        = ONESTOPBIT;
	if(! SetCommState(mPortHandle, &dcb))
	{
		MODEM_ERROR("error setting modem settings", GetLastError());
		mTMutex->Signal();
		return -2;
	}

	SetState(_cs_initializing);
	Sleep(1000);	// sleep for a second to let the modem catch-up

	// setup a mask so we know when a character comes in
	if(! SetCommMask(mPortHandle, EV_RXCHAR))
	{
		MODEM_ERROR("error setting up comm mask", GetLastError());
		return -3;
	}

	mTMutex->Signal();
	reply = _cr_NoReply;
	for(inx = 0; inx < 3 && reply != _cr_OK && !mAbort; inx++)
	{
		if(Write("AT%s\r", gPGFOpts.sopt.modemInit) < 0)
		{
			MODEM_ERROR("error writing to the modem", GetLastError());
			return -4;
		}
		reply = GetModemResult(1000*5);
	}
	if(reply != _cr_OK)
		result = _pge_ModemNotAvail;
	if(mAbort)
		result = _pge_InternalAbort;

	return result;
}

long
CPFTSerial::Read(void *data, long len, short *channel)
{
	static OVERLAPPED	overlapped;
	ulong	read = 0;
	long	extra = 0;
	uchar	*buffer = (uchar*)data, l = 0, amount;
	DWORD	error;

	// setup an overlapped structure for reading
	overlapped.Offset = overlapped.OffsetHigh = 0;
	overlapped.hEvent = mRXevent;
	ResetEvent(mRXevent);

	// check to see if the caller just wants to know whether we have
	//  any data waiting.
	if(buffer && len)
	{
		// in an earlier check for waiting data, we may have read an
		//  extra character.  if so, then include it in the data we
		//  send back.
		if(mInFront != mInBack)
		{
			// check to see if we have enough data in our internal buffer
			if(len > (uchar)(mInFront - mInBack))
			{
				if(mInFront > mInBack)
				{
					pgp_memcpy(buffer, mInBuffer + mInBack, l = mInFront - mInBack);
					buffer += l;
					len    -= l;
				}
				else
				{
					pgp_memcpy(buffer, mInBuffer + mInBack, l = (uchar)(-mInBack));
					buffer += l;
					len    -= l;
					pgp_memcpy(buffer, mInBuffer, mInFront);
					buffer += mInFront;
					len    -= mInFront;
					l      += mInFront;
				}
				mInBack = mInFront = 0;
			}
			else
			{
				if((uchar)(-mInBack) > len)
				{
					pgp_memcpy(buffer, mInBuffer + mInBack, len);
					mInBack += (uchar)len;
					return len;
				}
				else
				{
					pgp_memcpy(buffer, mInBuffer + mInBack, l = (uchar)(-mInBack));
					mInBack += (uchar)len;
					buffer += l;
					len    -= l;
					pgp_memcpy(buffer, mInBuffer, len);
					return len + l;
				}
			}
		}

		// try and read the data from the modem.
		if(! ReadFile(mPortHandle, buffer, len, &read, &overlapped) &&
			(error = GetLastError()) != ERROR_IO_PENDING)
		{
			MODEM_ERROR("error reading from modem", error);
			return -2;
		}

		// wait for the read to complete
		GetOverlappedResult(mPortHandle, &overlapped, &read, TRUE);

		return l + read;
	}
	else if(buffer)
		// if they don't want any data we succeed automatically.
		return 0;
	else
	{
		// if we have any data in our internal buffer from an earlier read
		//  then return the amount of data in our internal buffer
		//  immediately.  otherwise, try to read some data into our
		//  internal buffer and return the number of bytes that we
		//  succeeded in reading.

		if(mInFront != mInBack)
			return (uchar)(mInFront - mInBack);

		mInFront = mInBack = 0;
		amount = 255;

		if(! ReadFile(mPortHandle, mInBuffer, amount, &read, &overlapped) &&
			(error = GetLastError()) != ERROR_IO_PENDING)
		{
			MODEM_ERROR("error reading from modem", error);
			return -1;
		}

		// wait for the read to complete.
		if(! GetOverlappedResult(mPortHandle, &overlapped, &read, TRUE))
		{
			MODEM_ERROR("error getting read result", GetLastError());
			return -2;
		}

		mInFront = (uchar)read;
		return read;
	}
}

short
CPFTSerial::WriteBlock(void *buffer, long *count, short channel)
{
	static OVERLAPPED	overlapped;
	ulong	written;
	DWORD	error;

	mTMutex->Wait();

	// setup the OVERLAPPED structure for writing
	overlapped.Offset = overlapped.OffsetHigh = 0;
	overlapped.hEvent = mTXevent;

	// we use an overlapped structure so that a read can occur at the same
	//  time as a write.
	if(! WriteFile(mPortHandle, buffer, *count, &written, &overlapped) &&
		(error = GetLastError()) != ERROR_IO_PENDING)
	{
		MODEM_ERROR("error writing to modem", error);
		mTMutex->Signal();
		return -1;
	}

	// wait for the write to complete
	if(! GetOverlappedResult(mPortHandle, &overlapped, &written, TRUE))
	{
		MODEM_ERROR("error getting write result", GetLastError());
		mTMutex->Signal();
		return -2;
	}

	*count = written;
	mTMutex->Signal();

	return 0;
}

/*void
CPFTSerial::WaitAsync(AsyncTransport *asyncTrans)
{
	return;

	WaitForSingleObject(asyncTrans->u.overlapped.hEvent, INFINITE);
	return;
}*/

PGErr
CPFTSerial::WriteAsync(long count, short channel, AsyncTransport *async)
{
	return WriteBlock(async->buffer, &count, _pfc_Control);

	BOOL	result;
	DWORD	error;

	async->u.overlapped.Internal = 0;
	async->u.overlapped.InternalHigh = 0;
	async->u.overlapped.Offset = 0;
	async->u.overlapped.OffsetHigh = 0;

	result = WriteFile(mPortHandle, async->buffer, count, &async->written,
		&async->u.overlapped);
	if(!result && (error = GetLastError()) != ERROR_IO_PENDING)
	{
		MODEM_ERROR("error writing to modem", error);
		return _pge_ModemNotAvail;
	}

	return _pge_NoErr;
}

short
CPFTSerial::SleepForData(HANDLE *abortEvent)
{
	OVERLAPPED	overlapped;
	DWORD		eventMask, result, error = 0;
	short retval = 0;
	short handle_error_count = 0;

	HANDLE		handleArray[2] = {*abortEvent, mDataEvent};
	memset (&overlapped,0, sizeof(OVERLAPPED));
	overlapped.hEvent = handleArray[1];

	if(mInFront == mInBack && Read(NIL, 0, NIL) == 0)
	{
		if(! WaitCommEvent(mPortHandle, &eventMask, &overlapped) &&
			(error = GetLastError()) != ERROR_IO_PENDING)
		{
			MODEM_ERROR("error setting up comm event", error);
			retval = -1;
			//goto EXIT_FUNC;
		}

		// make sure that some data didn't come in before WaitCommEvent() was
		//	called
		if(Read(NIL, 0, NIL) > 0)
		{
			// flush the pending wait and return
			SetCommMask(mPortHandle, EV_RXCHAR);
			retval = 0;
			goto CLOSE_EVENT;
		}
		// wait for the first event that gets triggered.
WAIT_AGAIN:	 // Windows 95 returns ERROR_INVALID_HANDLE	sometimes when there is nothing 
			// wrong with the handle. When that happens we ignor the error a few times and see
			// if things don't just work fine anyway.
		result = WaitForMultipleObjects(2, handleArray, FALSE, INFINITE);
		if(result == WAIT_OBJECT_0)
		{
			// flush the pending wait and return
			SetCommMask(mPortHandle, EV_RXCHAR);
			error = 1;
		}
		else if(result != (WAIT_OBJECT_0+1))
		{
			// flush the pending wait, report an error, and return
			DWORD error = GetLastError();
			if(error ==  ERROR_INVALID_HANDLE && handle_error_count++ < 50)
				goto WAIT_AGAIN;

			SetCommMask(mPortHandle, EV_RXCHAR);
			MODEM_ERROR("unknown result waiting on event", error);
			retval = -2;
		}
	}
CLOSE_EVENT:;
	return retval;								// there's data so we're done
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -