276 lines
6.7 KiB
C++
276 lines
6.7 KiB
C++
#include "../stdafx.h"
|
|
|
|
|
|
#include "cmmio_base.h"
|
|
#ifdef _WIN64
|
|
#include "../WAI64bit/WAI64bit.h"
|
|
#endif
|
|
|
|
// added notifying feature to base class CMMIO [7/30/2004] /MP
|
|
// - SetCallback(ptr) to establish the feedback path
|
|
// then AddReceived will notify if such a ptr was set
|
|
// caller receive function is prototyped as function(CString), i.e. Recieved(CString sWhat)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CMMIO::Init()
|
|
{
|
|
m_RXTempPtr = nullptr;
|
|
m_RXHead = nullptr;
|
|
m_RXTail = nullptr;
|
|
m_SXTempPtr = nullptr;
|
|
m_SXHead = nullptr;
|
|
m_SXTail = nullptr;
|
|
CurrentPointer = 0;
|
|
m_iNbMsgWaiting = 0;
|
|
m_terminator = '\0';
|
|
m_usesTerminator = FALSE;
|
|
m_pReceiveNotify = nullptr;
|
|
}
|
|
|
|
void CMMIO::SetCallback(p_fstr ptr)
|
|
{
|
|
m_pReceiveNotify = ptr;
|
|
}
|
|
|
|
DWORD CMMIO::Send(CString buffer, BOOL needsResponse/*=FALSE*/)
|
|
{
|
|
//ZH 12-12-05 EnterCriticalSection(&m_QueueLock); //ZH-122904
|
|
|
|
char LocBuffer[MAX_OUTPUT_BUFFER_SIZE];
|
|
int length = buffer.GetLength();
|
|
if (length > MAX_OUTPUT_BUFFER_SIZE)
|
|
{
|
|
length = MAX_OUTPUT_BUFFER_SIZE;
|
|
}
|
|
|
|
auto ptr = (unsigned short*)buffer.GetBuffer(MAX_OUTPUT_BUFFER_SIZE);
|
|
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
LocBuffer[i] = static_cast<char>(ptr[i] & 0xff);
|
|
}
|
|
DWORD res = Send(LocBuffer, length, needsResponse);
|
|
|
|
//ZH 12-12-05 LeaveCriticalSection( &m_QueueLock ); //ZH-122904
|
|
|
|
return res;
|
|
}
|
|
|
|
// GetNextReceived() : Helper function, rreturns receives messages placed in the queue
|
|
// by LineReceive()
|
|
//
|
|
int CMMIO::GetNextReceived(char* inputBuf)
|
|
{
|
|
struct SerialList* Free;
|
|
int cnt = 0;
|
|
|
|
// If there is a previous block then delete it
|
|
if (nullptr != m_RXTempPtr)
|
|
delete[] m_RXTempPtr;
|
|
m_RXTempPtr = nullptr;
|
|
|
|
// We are messing with pointers so use the CriticalSection
|
|
// EnterCriticalSection(&m_QueueLock);
|
|
|
|
// If there any more to return
|
|
if (m_RXHead)
|
|
{
|
|
Free = m_RXHead;
|
|
m_RXHead = m_RXHead->Next;
|
|
|
|
// Point the temp pointer at the block
|
|
m_RXTempPtr = Free->Buffer;
|
|
cnt = Free->Bytes;
|
|
// delete the list entry
|
|
delete Free;
|
|
--m_iNbMsgWaiting; // mp
|
|
|
|
// move over the data to the user's buffer
|
|
if (nullptr != inputBuf)
|
|
memcpy(inputBuf, m_RXTempPtr, cnt);
|
|
}
|
|
|
|
if (m_RXHead == nullptr)
|
|
m_RXTail = nullptr;
|
|
|
|
// All done so out of the CriticalSection
|
|
// LeaveCriticalSection( &m_QueueLock );
|
|
|
|
return (cnt);
|
|
}
|
|
|
|
int CMMIO::AddReceived(const char* Buffer, DWORD Bytes)
|
|
{
|
|
DWORD index = 0; //primary buffer index
|
|
struct SerialList* Ptr;
|
|
static char Buffer2[MAX_RECIEVE_BUFFER_SIZE]; // result buffer
|
|
static char* pBuffer2 = &Buffer2[0];
|
|
unsigned char c;
|
|
bool bArmed;
|
|
/************************************************************************/
|
|
/* Greg Guilbeau - 2011/08/23 */
|
|
/* The following line(s) have been modified to handle x64 conversion */
|
|
/************************************************************************/
|
|
/* int count; */
|
|
INT_PTR count;
|
|
static int escape = 0;
|
|
static int tilde = 0;
|
|
static int tildeseqcount = 0;
|
|
|
|
bool bDone = false;
|
|
bool bEventRequest = false;
|
|
|
|
//TRACE(_T("AddReceived> pBuffer2 = %x\n"),pBuffer2);
|
|
// TRACE(_T("Content %s\n"),Buffer);
|
|
if (FALSE /*Bytes==0*/)
|
|
{
|
|
TRACE(_T("CMMIO> Exiting , no real input"));
|
|
return TRUE;
|
|
}
|
|
do
|
|
{
|
|
bArmed = false;
|
|
|
|
for (; index < Bytes; index++)
|
|
{
|
|
c = Buffer[index] & 0xff;
|
|
//TRACE(_T("== %02x% ==\n"),c); //copy char one by one
|
|
*(pBuffer2++) = c; //copy char one by one
|
|
|
|
// check for end of packet. ignore if this is the last char anyways
|
|
if (m_usesTerminator && c == m_terminator && (index < Bytes - 1))
|
|
{
|
|
bArmed = TRUE;
|
|
index++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (index == Bytes)
|
|
bArmed = bDone = true;
|
|
|
|
// We are messing with pointers so use the CriticalSection
|
|
if (bArmed)
|
|
{
|
|
// EnterCriticalSection(&m_QueueLock);
|
|
//Allocate a new list and add it in
|
|
count = pBuffer2 - (&Buffer2[0]);
|
|
if (m_pReceiveNotify)
|
|
{
|
|
// send a string to callback or,
|
|
auto pLocalBuffer = new char[count + 1];
|
|
if (pLocalBuffer)
|
|
{
|
|
memcpy(pLocalBuffer, Buffer2, count);
|
|
pLocalBuffer[count] = 0;
|
|
CString LocalStr(pLocalBuffer);
|
|
(*m_pReceiveNotify)(LocalStr);
|
|
delete pLocalBuffer;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// add it as before to received data ....
|
|
Ptr = new struct SerialList;
|
|
Ptr->Buffer = new char[count + 1];
|
|
/************************************************************************/
|
|
/* Greg Guilbeau - 2011/08/23 */
|
|
/* The following line(s) have been modified to handle x64 conversion */
|
|
/************************************************************************/
|
|
/* Ptr->Bytes = count; */
|
|
#ifdef _WIN64
|
|
Ptr->Bytes = WAI64bit::to32bit(count,__FILE__,__LINE__);
|
|
#else
|
|
Ptr->Bytes = count,__FILE__,__LINE__;
|
|
#endif
|
|
Ptr->Next = nullptr;
|
|
memcpy(Ptr->Buffer, Buffer2, count);
|
|
Ptr->Buffer[count] = 0;
|
|
|
|
memcpy(m_sLastMessage, Buffer2, count); //copy to last message
|
|
m_sLastMessage[count] = 0;
|
|
|
|
if (m_RXTail)
|
|
m_RXTail->Next = Ptr;
|
|
else
|
|
m_RXHead = Ptr;
|
|
m_RXTail = Ptr;
|
|
|
|
// All done so out of the CriticalSection
|
|
++m_iNbMsgWaiting;
|
|
}
|
|
// LeaveCriticalSection( &m_QueueLock );
|
|
pBuffer2 = &Buffer2[0]; // reset out buffer
|
|
count = 0;
|
|
bEventRequest = true;
|
|
}
|
|
}
|
|
while (!bDone);
|
|
//TRACE (_T("CMMIO> Done\n"));
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
void CMMIO::LineReceive(char* s, int nbCharAvail, BOOL ignoreDelimiter /*= FALSE*/)
|
|
{
|
|
if (nbCharAvail != -1)
|
|
{
|
|
//TRACE(_T("LineReceive got %d chars \n"),nbCharAvail);
|
|
char c;
|
|
for (int i = 0; i < nbCharAvail; i++)
|
|
{
|
|
c = s[i];
|
|
m_InputBuffer[CurrentPointer++] = c;
|
|
|
|
// only add a packet if we have a delimiter
|
|
if ((!m_usesTerminator && i == nbCharAvail - 1) || (m_usesTerminator && c == m_terminator) ||
|
|
ignoreDelimiter)
|
|
{
|
|
m_InputBuffer[CurrentPointer] = '\0';
|
|
AddReceived(m_InputBuffer, CurrentPointer);
|
|
CurrentPointer = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
DWORD CMMIO::Close()
|
|
{
|
|
struct SerialList* Free;
|
|
|
|
// Delete the contents of the temp rx pointer if any
|
|
delete[] m_RXTempPtr;
|
|
m_RXTempPtr = nullptr;
|
|
|
|
// Clear down all internal lists
|
|
// EnterCriticalSection( &m_QueueLock );
|
|
while (m_RXHead)
|
|
{
|
|
Free = m_RXHead;
|
|
m_RXHead = m_RXHead->Next;
|
|
delete[] Free->Buffer;
|
|
delete Free;
|
|
}
|
|
m_RXHead = nullptr;
|
|
|
|
// for now we are not using the Transmit list
|
|
#if 0
|
|
|
|
while( m_TXHead )
|
|
{
|
|
Free = m_TXHead;
|
|
m_TXHead = m_TXHead->Next;
|
|
delete[] Free->Buffer;
|
|
delete Free;
|
|
}
|
|
m_TXHead = NULL;
|
|
#endif
|
|
// LeaveCriticalSection( &m_QueueLock );
|
|
return (TRUE);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// END OF BASE CLASS CMMIO
|
|
///////////////////////////////////////////////////////////////////////////////
|