📄 itkplcdlg.cpp
字号:
break;
}
//
// Reponse commands that the driver will send when the ITKPLC sends
// an unsolicited message. We should never get a READ_RESPONSE_CMD
// because the ITKPLC does not issue read requests to the driver.
//
case READ_RESPONSE_CMD:
case BIT_WRITE_RESPONSE_CMD:
case WRITE_RESPONSE_CMD:
SendDLE(ACK);
break;
default:
break;
}
}
else
{
SendDLE(NAK);
}
break;
default:
rcv_state = DLE1;
}
}
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | AnswerRead |
//
// This function builds a responce to a read message containing the data
// requested.
//
void CItkPlcDlg::AnswerRead(unsigned short int nDest, unsigned short int nSource,
unsigned short int nStart, unsigned short int nLength,
unsigned short int nCmd, unsigned short int nTransNum,
SOCKET ClientSocket,
LPSOCKADDR ClientSockAddr)
{
int index;
short int nSendBcc = 0;
unsigned short int nValue;
PutSend(DLE);
PutSend(STX);
// Put in the source ID
PutSendBcc((unsigned char)nSource, &nSendBcc); // put the source (us)
// Put in the destination ID, if enabled
if (this->m_bSourceStn)
{
PutSendBcc((unsigned char)nDest, &nSendBcc); // put the destination (ITK)
}
// Put in the command.
// Switch on the command issued and respond with the correct command
switch(nCmd)
{
case READ_CMD:
PutSendBcc((unsigned char)READ_RESPONSE_CMD, &nSendBcc);
break;
case WRITE_CMD:
PutSendBcc((unsigned char)WRITE_RESPONSE_CMD, &nSendBcc);
break;
case BIT_WRITE_CMD:
PutSendBcc((unsigned char)BIT_WRITE_RESPONSE_CMD, &nSendBcc);
break;
default:
break;
}
if (this->m_bTransNum)
{
// Put the transaction number
PutSendBcc((unsigned char)(nTransNum >> 8), &nSendBcc); // hi-byte
PutSendBcc((unsigned char)nTransNum, &nSendBcc); // lo-byte
}
// Put the data
for ( index = 0; index < (nLength >> 1); index++ )
{
nValue = PlcMemory[nStart + index];
PutSendBcc((unsigned char)( nValue & 0xff), &nSendBcc);
PutSendBcc((unsigned char)(( nValue >> 8 ) & 0xff), &nSendBcc);
}
// Put the trailing stuff
PutSend(DLE);
PutSend(ETX);
// Put in the checksum
PutSend((unsigned char)((-nSendBcc) & 0xff));
__try
{
EnterCriticalSection(&this->m_Lock);
switch (this->m_dwProtocol)
{
case TCPIP_PROTOCOL:
this->m_pTcp->Send(ClientSocket, this->m_nTransmitBuffer,
this->m_dwTransmitIndex);
break;
case UDPIP_PROTOCOL:
if (ClientSockAddr != NULL)
{
this->m_pTcp->Send(*ClientSockAddr, this->m_nTransmitBuffer,
this->m_dwTransmitIndex);
}
break;
case SERIAL_PROTOCOL:
default:
this->m_pIo->Send(this->m_nTransmitBuffer,
this->m_dwTransmitIndex);
break;
}
}
__finally
{
LeaveCriticalSection(&this->m_Lock);
}
this->m_dwTransmitIndex = 0;
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | PutSend |
//
//
void CItkPlcDlg::PutSend( unsigned char nValue )
{
this->m_nTransmitBuffer[this->m_dwTransmitIndex++] = nValue;
if (this->m_dwTransmitIndex >= TRANSMIT_BUFFER_SIZE)
{
this->m_dwTransmitIndex = 0;
}
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | PutSendBcc |
//
//
void CItkPlcDlg::PutSendBcc( unsigned char nValue, short int *nBcc )
{
this->m_nTransmitBuffer[this->m_dwTransmitIndex++] = nValue;
if (this->m_dwTransmitIndex >= TRANSMIT_BUFFER_SIZE)
{
this->m_dwTransmitIndex = 0;
}
*nBcc += nValue;
if ( nValue == DLE )
{
this->m_nTransmitBuffer[this->m_dwTransmitIndex++] = DLE;
if (this->m_dwTransmitIndex >= TRANSMIT_BUFFER_SIZE)
{
this->m_dwTransmitIndex = 0;
}
}
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | SendDLE |
//
// Sends a DLE to the I/O Driver
//
void CItkPlcDlg::SendDLE(unsigned char acknak, SOCKET ClientSocket)
{
PutSend(DLE);
PutSend((unsigned char)acknak);
__try
{
EnterCriticalSection(&this->m_Lock);
switch (this->m_dwProtocol)
{
case TCPIP_PROTOCOL:
// Nothing to send for TCP protocol.
break;
case UDPIP_PROTOCOL:
// Nothing to send for UDP protocol.
break;
case SERIAL_PROTOCOL:
default:
this->m_pIo->Send(this->m_nTransmitBuffer, this->m_dwTransmitIndex);
break;
}
}
__finally
{
LeaveCriticalSection(&this->m_Lock);
}
//
// Increment the correct count
//
switch (acknak)
{
case NAK:
this->m_pdlgCommStats->m_dwNakSentCount++;
break;
case ACK:
this->m_pdlgCommStats->m_dwAckSentCount++;
break;
}
this->m_dwTransmitIndex = 0;
return;
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | GetBCCMask |
//
// Sets and returns the BCC mask for the parse routine. This mask is dependant
// on the data bits.
//
unsigned short int CItkPlcDlg::GetBCCMask()
{
unsigned short int nDataBits = this->GetDataBits();
nDataBits = this->GetDataBits();
switch(nDataBits)
{
case 5:
this->m_cBCCMask = 0x1f;
break;
case 6:
this->m_cBCCMask = 0x3f;
break;
case 7:
this->m_cBCCMask = 0x7f;
break;
case 8:
default:
this->m_cBCCMask = 0xff;
break;
}
return (this->m_cBCCMask);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | GetDataBits |
//
// Returns the data bits for the given port params.
//
unsigned short int CItkPlcDlg::GetDataBits()
{
char cDataBits[2];
if (this->m_szPortMode.IsEmpty())
{
return 0;
}
//
// The nPortParams will be in the format of "9600,n,8,1",
// so the data bits will be the second to last parameter,
// which is the third from last character
//
*cDataBits = this->m_szPortMode[(this->m_szPortMode.GetLength() - 3)];
*(cDataBits+1) = NULL;
return ((unsigned short int)atoi(cDataBits));
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | UnsolIoHandler |
//
// Handler for the Unsolicitied Messaging thread (if enabled).
//
UINT CItkPlcDlg::UnsolIoHandler(LPVOID ptr)
{
CItkPlcDlg *pThis = (CItkPlcDlg *)ptr;
DWORD dwStatus = IO_SUCCESS,
dwIndex = 0,
dwSize,
dwStartRegisters[10] = {0, 50, 100, 150, 200,
250, 300, 350, 400, 450 };
unsigned char buffer[4096];
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
while (!pThis->m_bShutdown)
{
dwSize = pThis->BuildWriteMsg(dwStartRegisters[dwIndex],(unsigned char *)&buffer);
__try
{
EnterCriticalSection(&pThis->m_Lock);
switch (pThis->m_dwProtocol)
{
case TCPIP_PROTOCOL:
// Currently not implemented for TCP protocol.
break;
case UDPIP_PROTOCOL:
// Currently not implemented for UDP protocol.
break;
case SERIAL_PROTOCOL:
default:
pThis->m_pIo->Send(buffer, dwSize);
break;
}
}
__finally
{
LeaveCriticalSection(&pThis->m_Lock);
}
pThis->m_pdlgCommStats->m_dwUnsolicitedSentCount++;
if (++dwIndex >= 10)
{
dwIndex = 0;
}
Sleep(pThis->m_dwUnsolFrequency);
}
return(1);
}
//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | BuildWriteMsg |
//
// Builds a write message for unsolicitied messaging
//
DWORD CItkPlcDlg::BuildWriteMsg(DWORD dwStart, unsigned char *buffer)
{
unsigned char *pXmit,
chBCC = 0;
DWORD dwLength = 0;
pXmit = buffer;
// put on the message header
*pXmit++ = DLE;
dwLength++;
*pXmit++ = STX;
dwLength++;
// Who it came from
if (this->m_bSourceStn)
{
*pXmit = (unsigned char)this->m_dwLocalStation;
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
}
// Who to send to
*pXmit = (unsigned char)this->m_dwRemoteStation;
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
*pXmit = (unsigned char)WRITE_CMD; // Word Write
chBCC = (unsigned char)(chBCC + *pXmit);
pXmit++;
dwLength++;
// Transaction number
if (this->m_bTransNum)
{
//
// Get a random number for the transaction number
//
this->m_nTransactionNumber = (unsigned short int)rand();
// hi byte
*pXmit = (unsigned char)((this->m_nTransactionNumber >> 8) & 0xFF);
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
// lo byte
*pXmit = (unsigned char)(this->m_nTransactionNumber & 0xFF);
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
}
// Word address low byte
*pXmit = (unsigned char)(dwStart & 0xFF);
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
// Word Address high byte
*pXmit = (unsigned char)(dwStart >> 8);
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
//
// Write 10 words.
//
for (int nOffset = 0; nOffset < 10; nOffset++)
{
// Data low
*pXmit = (unsigned char)(this->PlcMemory[dwStart + nOffset] & 0xFF);
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
// Data High
*pXmit = (unsigned char)(this->PlcMemory[dwStart + nOffset] >> 8);
chBCC = (unsigned char)(chBCC + *pXmit);
dwLength++;
// if a DLE, add another (DLE escaping)
if (*pXmit++ == (unsigned char)DLE)
{
*pXmit++ = (unsigned char)DLE;
dwLength++;
}
}
// put on the message trailer
*pXmit++ = (unsigned char)DLE; // DLE
dwLength++;
*pXmit++ = (unsigned char)ETX; // ETX
dwLength++;
*pXmit = (unsigned char)-chBCC;
dwLength++;
return(dwLength);
}
//
// CALLBACK Function TcpSrvCallback() for the Server Receive Message
//
void EXPORT32 CALLBACK TcpSrvCallback(LPVOID ptr, SOCKET ClientSocket, DWORD dwTransferred )
{
CItkPlcDlg *pThis = (CItkPlcDlg *)ptr;
pThis->ParseTcpMsg(ClientSocket, dwTransferred);
}
void CItkPlcDlg::ParseTcpMsg(SOCKET ClientSocket, DWORD dwSize)
{
__try
{
EnterCriticalSection(&this->m_Lock);
DWORD dwLoop;
unsigned char Value;
unsigned short int rcv_state = DLE1,
calc_bcc = 0,
dest = 0, // destination (our station)
src = 0, // source (from who)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -