#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(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 ///////////////////////////////////////////////////////////////////////////////