📄 port.c
字号:
/******************************************************************** FILE: Port.c** DESCRIPTION: Abstracts the serial port interface for Twiddle** VERSION: 1.0*********************************************************************/#include "Twiddle.h"#include "TwiddleRsc.h"#include "Utils.h"#include "UtilsRsc.h"#include "Port.h"static Boolean fConnected = false;static UInt fSerLibRefNum;static Char fSerialBuffer[mainFormBufferSize];static UInt32 fPortWatchdog = 0;static Char fInfoBuff[256];typedef enum _PortErrorEnum { portCannotOpenError = 0, portOpenError, portOpenBufferSetError } PortErrorEnum;static void SetConnectedPort( Boolean state );/********************************************************* * * FUNCTION: SetConnectedPort * * DESCRIPTION: This routine says whether or not the port is * connected * * PARAMETERS: true if the port is connected * * RETURNED: nothing * *********************************************************/ static void SetConnectedPort( Boolean state // (in) true if connected ) { fConnected = state; } /********************************************************* * * FUNCTION: ConnectedPort * * DESCRIPTION: This routine indicates whether or not the port * is connected * * PARAMETERS: nothing * * RETURNED: true if the port is connected; false otherwise * *********************************************************/Boolean ConnectedPort( void){ return fConnected;}/********************************************************* * * FUNCTION: OpenPort * * DESCRIPTION: This routine opens the selected port. * * PARAMETERS: nothing * * RETURNED: Error code on failure or noErr * *********************************************************/Err OpenPort( // (out) error code on failure void ){ Err anErr; SerSettingsType settings = { 0 }; ErrTry { if ( ConnectedPort() ) ErrThrow(portCannotOpenError ); // If we don't have the serial library, bail anErr = SysLibFind( "Serial Library", &fSerLibRefNum ); if ( anErr != noErr ) {// Are we on a PalmPilot Pro? anErr = SysLibFind( "IrSerial Library", &fSerLibRefNum ); } ErrFatalDisplayIf( anErr != noErr, "No Serial Manager was found" ); if ( anErr != noErr ) ErrThrow( portCannotOpenError );// Open the port anErr = SerOpen( fSerLibRefNum, 0, mainFormBaudRate ); if ( anErr != noErr ) ErrThrow( portCannotOpenError ); // Resize the serial buffer. anErr = SerSetReceiveBuffer( fSerLibRefNum, fSerialBuffer, sizeof( fSerialBuffer ) ); if ( anErr != noErr ) ErrThrow( portOpenError );// Set the serial port's options. settings.baudRate =mainFormBaudRate; settings.flags = srmSettingsFlagBitsPerChar8 | srmSettingsFlagStopBits1;//settings.ctsTimeout = serDefaultCTSTimeout; anErr = SerSetSettings (fSerLibRefNum, &settings); if ( anErr != noErr ) ErrThrow( portOpenBufferSetError ); // we're open! SetConnectedPort( true ); fPortWatchdog = TimGetTicks(); } ErrCatch( e ) { switch ( e ) { case portOpenBufferSetError: // Falls through!! SerSetReceiveBuffer( fSerLibRefNum, 0, 0 ); case portOpenError: SerClose( fSerLibRefNum ); // Falls through! case portCannotOpenError: default: // nothing to do ; } } ErrEndCatch; return anErr;}/********************************************************* * * FUNCTION: ClosePort * * DESCRIPTION: This routine closes the open port. * * PARAMETERS: nothing * * RETURNED: nothing * *********************************************************/Err ClosePort( // (out) error code or noErr on success. void ){ Err anErr = noErr; // we ignore this. ErrTry { if ( !ConnectedPort() ) ErrThrow( serErrNotOpen ); anErr = SerSetReceiveBuffer( fSerLibRefNum, 0, 0 ); if ( anErr != noErr ) { StrPrintF( fInfoBuff, "An error occurred (%d:%d) while releasing the receive fInfoBuffer.", serErrorClass, anErr ); FrmCustomAlert( InfoAlert, fInfoBuff, "", "" ); } anErr = SerClose( fSerLibRefNum ); if ( anErr != noErr ) { StrPrintF( fInfoBuff, "An error occurred (%d:%d) while closing the port.", serErrorClass, anErr ); FrmCustomAlert( InfoAlert, fInfoBuff, "", "" ); } fConnected = false; } ErrCatch( err ) { ErrNonFatalDisplay( "ClosePort called when the port was closed!" ); anErr = (Err)err; } ErrEndCatch; return anErr;}/********************************************************* * * FUNCTION: SendPort * * DESCRIPTION: This routine sends the text string out the open port. * * PARAMETERS: textP -- null terminated string to send. * * RETURNED: noErr on success or error code. * *********************************************************/Err SendPort( // (out) error code on failure or noErr CharPtr textP // (in) pointer to text to send.){ Err anErr = noErr; UInt32 howManyPending, howManySent; howManyPending = StrLen( textP ); while( howManyPending > 0 ) { howManySent = SerSend( fSerLibRefNum, textP, howManyPending, &anErr ); if ( anErr != noErr ) { if ( anErr == serErrTimeOut ) { continue; } else { StrPrintF( fInfoBuff, "An error occurred (%d). Your text was not sent.", anErr ); FrmCustomAlert( InfoAlert, fInfoBuff, "", "" ); } } else if ( howManySent == howManyPending ) { break; } textP += howManySent; howManyPending = StrLen( textP ); } return noErr;}/********************************************************* * * FUNCTION: RecvPort * * DESCRIPTION: This routine receives pending data * * PARAMETERS: handleInputFuncP processes input * * RETURNED: serErrTimeOut - No response from host. * serErrLineErr - No response; max retries reached. Connection * was closed. * *********************************************************/Err RecvPort( PortHandleInputFuncPtr handleInputFuncP // (in) what to do){ Err anErr = noErr; UInt32 howManyPending, howMany; static Char rcvBuff[mainFormBufferSize]; do {// Don't auto-off during comms! EvtResetAutoOffTimer ();// Wait for a bit to see if there's data. anErr = SerReceiveWait( fSerLibRefNum, mainFormRecvWaitBytes, mainFormRecvWaitDelay ); // If there's nothing or an error, so note and return. if ( anErr == serErrTimeOut ) { break; } if ( anErr != noErr ) { StrPrintF( fInfoBuff, "An error occurred (%d). Received data may have been lost.", anErr ); FrmCustomAlert( InfoAlert, fInfoBuff, "", "" ); SerReceiveFlush( fSerLibRefNum, 1 ); break; } // See how many bytes we have to read anErr = SerReceiveCheck (fSerLibRefNum, &howManyPending); if ( anErr == serErrTimeOut ) { break; } if ( anErr != noErr ) { StrPrintF( fInfoBuff, "An error occurred (%d). Received data may have been lost.", anErr ); FrmCustomAlert( InfoAlert, fInfoBuff, "", "" ); SerReceiveFlush( fSerLibRefNum, 1 ); break; } // If we have something, read it. if ( howManyPending ) { if ( howManyPending > sizeof( rcvBuff ) ) { howManyPending = sizeof( rcvBuff ); } howMany = SerReceive( fSerLibRefNum, rcvBuff, howManyPending, 0, &anErr ); if ( anErr == serErrTimeOut ) { break; } if ( anErr != noErr ) { StrPrintF( fInfoBuff, "An error occurred (%d). Received data may have been lost.", anErr ); FrmCustomAlert( InfoAlert, fInfoBuff, "", "" ); SerReceiveFlush( fSerLibRefNum, 1 ); break; } rcvBuff[ howMany ] = '\0'; // See if the data we read is correct. fPortWatchdog = TimGetTicks(); (*handleInputFuncP)( rcvBuff ); break; } } while( !EvtSysEventAvail( false ) ); if ( anErr == serErrTimeOut ) anErr = noErr;// Time out if there's been no response in some time. if ( fConnected && ( TimGetTicks() > fPortWatchdog + mainFormTimeOutIfNoResponse ) ) { fRetryCount++; if ( fRetryCount < mainFormRecvMaxRetry ) {// Ahh, let's try again. anErr = serErrTimeOut; } // We decided to retry else { anErr = serErrLineErr; ClosePort( ); FrmAlert( CommAlert ); } } return anErr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -