<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Serial Comm Handle Problem]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>I wrote a code to do serial communication with an equipament.<br />
When i use the code outside of threaded class it seens work properly,<br />
but when i put inside a class and execute a thread in the first seconds the<br />
communication is ok, later i receive read/write error.<br />
I´ve been in MSDN site and there i discover that the read/write error is a<br />
INVALID_HANDLE problem. But why??? I just create the serial communication<br />
file and use it.<br />
Anyone can help me?</p>
<p>Here is the code</p>
<p>/* cut <em>/<br />
/</em>--------------------------------------------------------------------*/<br />
/* Main Class */</p>
<p>#ifndef _IGERENCIADOREQUIPAMENTO_H<br />
#define _IGERENCIADOREQUIPAMENTO_H</p>
<p>#include &lt;stdio.h&gt;<br />
#include &lt;windows.h&gt;</p>
<p>#define SERIAL_PARITY_NONE 0<br />
#define SERIAL_PARITY_ODD 1<br />
#define SERIAL_PARITY_EVEN 2</p>
<p>#define SERIAL_MAX_RX 256 // Input buffer max size<br />
#define SERIAL_MAX_TX 256 // output buffer max size</p>
<p>#define SERIAL_CONNECTED 0<br />
#define SERIAL_DISCONNECTED 1<br />
#define SERIAL_DATA_SENT 2<br />
#define SERIAL_DATA_ARRIVAL 3<br />
#define SERIAL_RING 4<br />
#define SERIAL_CD_ON 5<br />
#define SERIAL_CD_OFF 6<br />
#define SERIAL_DATA_RECV 7</p>
<p>#define SERIAL_SIGNAL_NBR 7</p>
<p>class IGerenciadorEquipamento;</p>
<p>typedef struct<br />
{<br />
HANDLE serialFD;<br />
IGerenciadorEquipamento* pIGE;<br />
}_SERIALCOM_IONICS;</p>
<p>class IGerenciadorEquipamento: public IThread<br />
{</p>
<p>private:<br />
HANDLE hSerial;<br />
char *cPortaSerial;<br />
DWORD dwBaudRate;<br />
BYTE byByteSize;<br />
BYTE byTipoParidade;<br />
bool conectado;<br />
bool bRX_In_Progress; // BOOL indicating if a<br />
ReadFile is<br />
// in progress<br />
bool bTX_In_Progress; // BOOL indicating if a<br />
WriteFile is<br />
// in progress</p>
<p>unsigned char pacoteIN[256];<br />
unsigned char pacoteOUT[256];</p>
<p>bool bConectado;</p>
<p>int ConfigTimeouts(COMMTIMEOUTS mCommtimeout);<br />
int ConfigDCB(DCB mDCB);</p>
<p>public:<br />
IGerenciadorEquipamento(char *mcPortaSerial, DWORD mdwBaudRate,<br />
BYTE mbyByteSize, BYTE mbyiTipoParidade);<br />
~IGerenciadorEquipamento();</p>
<p>int AtivaEquipamento(BOOL mbIniciaThread = true);<br />
int DesativaEquipamento(BOOL mbFinalizaThread = true);<br />
int EscreveMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int<br />
miTamanho);<br />
int LeMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int<br />
miTamanho);<br />
void PurgeSerial(void);<br />
bool VerificaEstado(void);<br />
int Run(void);<br />
HANDLE GetSerialHND(void);<br />
void OnSendRecv(void);<br />
unsigned char *GetDadosRecebidos(void);<br />
unsigned char *GetDadosEnviados(void);</p>
<p>int EnviaPOLLING(HANDLE hSerialCOM);<br />
int ConcedePrivilegio(HANDLE hSerialCOM, BYTE byEndereco);<br />
void TraduzMens(unsigned char *ucPacote, DWORD miTamanho);<br />
DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char <em>ucPacoteIN,<br />
DWORD dStartpos,<br />
DWORD dQtdebytes,<br />
unsigned char</em> ucPacoteOUT);</p>
<p>};</p>
<p>//DWORD WINAPI ComSendRecv(LPVOID p);<br />
int ComSendRecv(LPVOID p);</p>
<p>#endif</p>
<p>/<em>--------------------------------------------------------------------</em>/<br />
/* until here */</p>
<p>/* cut <em>/<br />
/</em>--------------------------------------------------------------------*/<br />
/* Main Class Code */</p>
<p>//#define STRICT<br />
#include &lt;cstdlib&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;process.h&gt;<br />
#include &lt;conio.h&gt;<br />
#include &lt;windows.h&gt;<br />
#include &lt;iostream&gt;<br />
#include &lt;math.h&gt;<br />
#include &quot;IGerenciadorEquipamento.hpp&quot;<br />
#include &quot;StringMethods.hpp&quot;<br />
#include &quot;Consts.hpp&quot;<br />
#include &quot;TipoProtocolo.hpp&quot;</p>
<p>#define SIG_POWER_DOWN 0<br />
#define SIG_READER 1<br />
#define SIG_READ_DONE 2 // data received has been read<br />
#define SIG_WRITER 3<br />
#define SIG_DATA_TO_TX 4 // data waiting to be sent<br />
#define SIG_MODEM_EVENTS 5<br />
#define SIG_MODEM_CHECKED 6</p>
<p>using namespace std;</p>
<p>typedef struct<br />
{<br />
BYTE controladora;<br />
BYTE tentativas;<br />
bool detectaprot;<br />
}STRU_CONFCONTROL;</p>
<p>STRU_CONFCONTROL ConfControl;</p>
<p>unsigned char *IGerenciadorEquipamento::GetDadosRecebidos(void)<br />
{<br />
return pacoteOUT;<br />
}</p>
<p>unsigned char *IGerenciadorEquipamento::GetDadosEnviados(void)<br />
{<br />
return pacoteIN;<br />
}</p>
<p>int IGerenciadorEquipamento::EnviaPOLLING(HANDLE hSerialCOM)<br />
{<br />
unsigned char ucPacoteIN[256];<br />
unsigned char ucPacoteOUT[256];<br />
int iTotalLido;</p>
<p>ZeroMemory(ucPacoteIN,3);</p>
<p>ucPacoteIN[0] = SYN;<br />
ucPacoteIN[1] = '1';<br />
ucPacoteIN[2] = 0x55;</p>
<p>EscreveMensagem(hSerialCOM ,ucPacoteIN,3);<br />
iTotalLido=LeMensagem(hSerialCOM ,ucPacoteOUT,30);<br />
if (iTotalLido)<br />
{<br />
if ((ucPacoteOUT[0] == SYN) &amp;&amp; (ucPacoteOUT[1] == '1') &amp;&amp;<br />
(ucPacoteOUT[2] == 0xAA))<br />
ConfControl.detectaprot = false;<br />
}<br />
return iTotalLido;<br />
}</p>
<p>int IGerenciadorEquipamento::ConcedePrivilegio(HANDLE hSerialCOM, BYTE<br />
byEndereco)<br />
{<br />
unsigned char ucPacoteIN[256];<br />
int iTotalEscrito;</p>
<p>ZeroMemory(ucPacoteIN,3);</p>
<p>// privilegio<br />
ucPacoteIN[0] = SYN;<br />
ucPacoteIN[1] = byEndereco+48;<br />
ucPacoteIN[2] = ACK;</p>
<p>iTotalEscrito=EscreveMensagem(hSerialCOM ,ucPacoteIN,3);<br />
return iTotalEscrito;<br />
}</p>
<p>void IGerenciadorEquipamento::TraduzMens(unsigned char *ucPacote, DWORD<br />
miTamanho)<br />
{<br />
int iCanal;<br />
double dLitros;<br />
char cPulsos[8];<br />
double dPulsos;<br />
char parcelaPacote;<br />
char cInd;<br />
int iInd;<br />
int k;</p>
<p>dLitros = 0;</p>
<p>iCanal = ((((BYTE)ucPacote[1])-49)*8);<br />
iInd = ucPacote[3] &amp; 0x0F;</p>
<p>switch(iInd)<br />
{<br />
case 0:<br />
iCanal += ((((BYTE)ucPacote[4])-47)+100);<br />
printf(&quot;Bomba %i ligada\n&quot;,iCanal-100);<br />
break;<br />
case 1:<br />
iCanal += ((((BYTE)ucPacote[4])-47)+100);<br />
printf(&quot;Bomba %i desligada\n&quot;,iCanal-100);</p>
<p>dPulsos = 0;<br />
k=0;<br />
ZeroMemory(cPulsos,8);<br />
for (int i=5;i&lt;13;i++)<br />
{<br />
cPulsos[k] = ucPacote[i];<br />
k++;<br />
}<br />
dPulsos = atof(cPulsos);</p>
<p>dLitros = round(dPulsos/1*100)/100;</p>
<p>if ((iCanal &gt; 100) &amp;&amp; (iCanal &lt; 133))<br />
{<br />
printf(&quot;Bomba %i abasteceu %4.2f litros \n&quot;,iCanal-100, dLitros);<br />
}<br />
else<br />
printf(&quot;Bomba %i abasteceu %4.2f litros \n&quot;,iCanal-100, 0.00);</p>
<p>break;<br />
case 7:<br />
printf(&quot;APM Reenergizado\n&quot;);<br />
break;<br />
}</p>
<p>}</p>
<p>DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char <em>ucPacoteIN,<br />
DWORD dStartpos,<br />
DWORD dQtdebytes,<br />
unsigned char</em> ucPacoteOUT)<br />
{<br />
int i;<br />
DWORD dPosETX = 0;<br />
DWORD dPosSTX = 0;<br />
DWORD dPosDC2 = 0;<br />
bool bOneMoreSYN;<br />
bool bMensTexto;<br />
bool bContinuar = true;<br />
DWORD dBytesToSYN;<br />
int iTotalBytes;</p>
<p>iTotalBytes = 0;<br />
dBytesToSYN = 0;<br />
bMensTexto = false;<br />
bOneMoreSYN = true;<br />
dPosETX = 0;<br />
dPosSTX = 0;<br />
dPosDC2 = 0;</p>
<p>for(i=dQtdebytes-1;(i&gt;=0);i--)<br />
{</p>
<p>if (bOneMoreSYN)<br />
dBytesToSYN++;</p>
<p>switch(ucPacoteIN[i])<br />
{<br />
case SYN:<br />
if ((dPosETX) &amp;&amp; (dPosSTX) &amp;&amp; ((dPosSTX-i) == 2) &amp;&amp; (dQtdebytes<br />
&gt; dPosETX))<br />
{<br />
bMensTexto = true;<br />
bContinuar = false;<br />
break;<br />
}<br />
else<br />
{<br />
if ((dPosDC2) &amp;&amp; (dPosDC2-i) == 2)<br />
{<br />
if ((!bOneMoreSYN) &amp;&amp; (dBytesToSYN &gt; 0))<br />
{<br />
return iTotalBytes;<br />
}<br />
else<br />
{<br />
bContinuar = false;<br />
break;<br />
}<br />
}<br />
else<br />
{<br />
if (!bOneMoreSYN) { return 0; }<br />
bOneMoreSYN = false;<br />
dPosDC2 = 0;<br />
dPosETX = 0;<br />
dPosSTX = 0;<br />
}</p>
<p>}<br />
break;</p>
<p>case DC2: dPosDC2 = i; break;<br />
case STX: dPosSTX = i; break;<br />
case ETX: dPosETX = i; break;<br />
}<br />
if (!bContinuar) break;</p>
<p>}</p>
<p>if ((i != 0xFFFF) &amp;&amp; (ucPacoteIN[i] == SYN))<br />
{<br />
if (bMensTexto)<br />
dPosETX++;<br />
else<br />
dPosETX = dPosDC2;</p>
<p>for(int j=i;j&lt;=dPosETX;j++)<br />
{<br />
ucPacoteOUT[iTotalBytes] = ucPacoteIN[j];<br />
iTotalBytes++;<br />
}<br />
}<br />
return iTotalBytes;<br />
}</p>
<p>IGerenciadorEquipamento::IGerenciadorEquipamento(char *mcPortaSerial,<br />
DWORD mdwBaudRate,<br />
BYTE mbyByteSize,<br />
BYTE mbyTipoParidade)<br />
{<br />
cPortaSerial = mcPortaSerial;<br />
dwBaudRate = mdwBaudRate;<br />
mbyTipoParidade = mbyTipoParidade;<br />
mbyByteSize = mbyByteSize;<br />
hSerial = INVALID_HANDLE_VALUE;<br />
conectado = false;<br />
bRX_In_Progress = false;<br />
bTX_In_Progress = false;<br />
ConfControl.detectaprot = true;<br />
ConfControl.tentativas = 0;<br />
ConfControl.controladora = 0;</p>
<p>}</p>
<p>IGerenciadorEquipamento::~IGerenciadorEquipamento()<br />
{<br />
conectado = false;<br />
cPortaSerial = &quot;&quot;;<br />
dwBaudRate = 0;<br />
byTipoParidade = SERIAL_PARITY_NONE;<br />
byByteSize = 0;</p>
<p>if (GetThreadHND()!=0)<br />
WaitForSingleObject(GetThreadHND(), 2000);</p>
<p>bRX_In_Progress = false;<br />
bTX_In_Progress = false;</p>
<p>if (hSerial != INVALID_HANDLE_VALUE)<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;<br />
}</p>
<p>int IGerenciadorEquipamento::ConfigTimeouts(COMMTIMEOUTS mCommtimeout)<br />
{</p>
<p>// configura os timeouts da Porta Serial<br />
mCommtimeout.ReadIntervalTimeout = 20;<br />
mCommtimeout.ReadTotalTimeoutMultiplier = 1;<br />
mCommtimeout.ReadTotalTimeoutConstant = 20;<br />
mCommtimeout.WriteTotalTimeoutMultiplier = 5;<br />
mCommtimeout.WriteTotalTimeoutConstant = 5;</p>
<p>return SetCommTimeouts(hSerial,&amp;mCommtimeout);<br />
}</p>
<p>int IGerenciadorEquipamento::ConfigDCB(DCB mDCB)<br />
{<br />
// recupera as informações do DCB<br />
if (!GetCommState(hSerial,&amp;mDCB))<br />
{<br />
CloseHandle(hSerial);<br />
return ERROR_INVALID_HANDLE;<br />
}</p>
<p>// set DCB to configure the serial port<br />
mDCB.DCBlength = sizeof(mDCB);</p>
<p>/* ---------- Serial Port Config ------- */<br />
mDCB.BaudRate = dwBaudRate;</p>
<p>switch(byTipoParidade)<br />
{<br />
case SERIAL_PARITY_NONE:<br />
mDCB.Parity = NOPARITY;<br />
mDCB.fParity = 0;<br />
break;<br />
case SERIAL_PARITY_EVEN:<br />
mDCB.Parity = EVENPARITY;<br />
mDCB.fParity = 1;<br />
break;<br />
case SERIAL_PARITY_ODD:<br />
mDCB.Parity = ODDPARITY;<br />
mDCB.fParity = 1;<br />
break;<br />
}</p>
<p>mDCB.StopBits = ONESTOPBIT;<br />
mDCB.ByteSize = 8;<br />
mDCB.fBinary = 0;<br />
mDCB.fAbortOnError = 0;<br />
mDCB.wReserved = 0;<br />
mDCB.XonLim = 100;<br />
mDCB.XoffLim = 100;<br />
mDCB.XonChar = 0x0D;<br />
mDCB.XoffChar = 0x0A;<br />
mDCB.ErrorChar = 0;<br />
mDCB.EofChar = 0;<br />
mDCB.EvtChar = 0;<br />
mDCB.wReserved1 = 0;</p>
<p>return SetCommState(hSerial,&amp;mDCB);</p>
<p>}</p>
<p>int IGerenciadorEquipamento::AtivaEquipamento(BOOL mbIniciaThread)<br />
{<br />
int iErro;<br />
DCB dcb;<br />
int i;</p>
<p>COMMTIMEOUTS cto;</p>
<p>if (hSerial != INVALID_HANDLE_VALUE)<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;</p>
<p>if (cPortaSerial != &quot;&quot;)<br />
{<br />
iErro = 0;</p>
<p>hSerial = CreateFile(cPortaSerial, // filename<br />
GENERIC_READ | GENERIC_WRITE, // acesso<br />
desejado<br />
0, // modo de<br />
compartilhamento<br />
NULL, // atributos<br />
de segurança<br />
OPEN_EXISTING, // disposição<br />
da criação do arquivo<br />
FILE_FLAG_NO_BUFFERING,<br />
// flag de criação<br />
NULL); // indica se<br />
pode ou não copiar os<br />
// atributos do<br />
arquivo atual para outro<br />
// arquivo<br />
if (hSerial != INVALID_HANDLE_VALUE)<br />
{<br />
bConectado = true;</p>
<p>// aplica os timeous<br />
if (!ConfigTimeouts(cto))<br />
iErro = 2;</p>
<p>// aplica o DCB<br />
if (!ConfigDCB(dcb))<br />
iErro = 4;</p>
<p>}<br />
}<br />
else<br />
iErro = -2;</p>
<p>/* --------------------------------------------- */<br />
if (iErro &gt; 0)<br />
{<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;<br />
}<br />
else<br />
{</p>
<p>HANDLE hThread1;<br />
DWORD dThreadID1;<br />
if(mbIniciaThread)<br />
{<br />
printf(&quot;Connected ! \n&quot;);</p>
<p>hThread1 = CreateThread(NULL, // default<br />
security attributes<br />
0, // use default<br />
stack size<br />
(DWORD (_stdcall *)(void <em>))ComSendRecv,<br />
// thread function<br />
(void</em>)this, // argument to thread<br />
function<br />
0, // use default<br />
creation flags<br />
&amp;dThreadID1); // returns the<br />
thread identifier</p>
<p>*/</p>
<p>}<br />
}</p>
<p>/* --------------------------------------------- */<br />
return iErro;</p>
<p>}</p>
<p>int IGerenciadorEquipamento::DesativaEquipamento(BOOL mbFinalizaThread)<br />
{<br />
conectado = false;</p>
<p>if(mbFinalizaThread)<br />
{</p>
<p>}<br />
if (hSerial != INVALID_HANDLE_VALUE)<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;</p>
<p>if (this-&gt;GetThreadHND())<br />
{<br />
if (WaitForSingleObject (this-&gt;GetThreadHND(), 2000) == WAIT_TIMEOUT)<br />
{<br />
TerminateThread (this-&gt;GetThreadHND(), 1);<br />
CloseHandle (this-&gt;GetThreadHND());<br />
}<br />
else CloseHandle (this-&gt;GetThreadHND());<br />
}<br />
CloseHandle(this-&gt;GetThreadHND());</p>
<p>printf(&quot;Disconnected ! \n&quot;);</p>
<p>}</p>
<p>int IGerenciadorEquipamento::EscreveMensagem(HANDLE hSerialCOM,unsigned<br />
char* mcMensagem, int miTamanho)</p>
<p>{<br />
char cTXBuffer[SERIAL_MAX_RX];<br />
DWORD iQtdebytesEscritos;<br />
int iTamanhoBuffer = 0;<br />
int iSuccess = 0;<br />
int Error = 0;<br />
HANDLE hCom;</p>
<p>if (!bTX_In_Progress)<br />
{<br />
PurgeComm(hSerialCOM,PURGE_TXCLEAR | PURGE_RXCLEAR);<br />
//hCom = hSerialCOM;</p>
<p>iSuccess = WriteFile(hSerialCOM,<br />
mcMensagem,<br />
miTamanho,<br />
&amp;iQtdebytesEscritos,<br />
NULL);</p>
<p>if (!iSuccess)<br />
{<br />
// failure<br />
if((Error = GetLastError()) != ERROR_IO_PENDING )<br />
printf(&quot;erro: %i , qtde: %i =&gt; WriteFile error (not pending)\<br />
n&quot;, Error,iQtdebytesEscritos &amp; 0xFFFF);<br />
}</p>
<p>bTX_In_Progress = false;</p>
<p>}</p>
<p>return iQtdebytesEscritos;<br />
}</p>
<p>int IGerenciadorEquipamento::LeMensagem(HANDLE hSerialCOM,unsigned char*<br />
mcMensagem, int miTamanho)<br />
{<br />
DWORD iQtdebytesLidos;<br />
DWORD iLenMensagem = 0;<br />
int iSuccess = 0;<br />
int Error = 0;<br />
HANDLE hCom;</p>
<p>ZeroMemory(mcMensagem,SERIAL_MAX_RX);</p>
<p>if (!bRX_In_Progress)<br />
{<br />
// locking reading<br />
bRX_In_Progress = true;<br />
//hCom = hSerialCOM;</p>
<p>// starting a new read<br />
iSuccess = ReadFile(hSerialCOM, // handle do arquivo<br />
mcMensagem, // buffer de leitura<br />
miTamanho, // número de bytes a serem lidos<br />
&amp;iQtdebytesLidos, // número de bytes realmente<br />
lidos<br />
NULL); // usado para leitura<br />
concorrente<br />
// da serial</p>
<p>if (!iSuccess)<br />
{<br />
// failure<br />
if((Error = GetLastError()) != ERROR_IO_PENDING)<br />
{<br />
printf(&quot;erro: %i , qtde: %i =&gt; Readfile error (not pending)\<br />
n&quot;, Error,iQtdebytesLidos &amp; 0xFFFF);<br />
}<br />
}<br />
bRX_In_Progress = false;<br />
}</p>
<p>return iQtdebytesLidos;<br />
}</p>
<p>void IGerenciadorEquipamento::PurgeSerial(void)<br />
{<br />
PurgeComm(hSerial,PURGE_TXCLEAR | PURGE_RXCLEAR);<br />
}</p>
<p>bool IGerenciadorEquipamento::VerificaEstado(void)<br />
{<br />
// return (bRX_In_Progress || bTX_In_Progress);<br />
}</p>
<p>int ComSendRecv(LPVOID p)<br />
{<br />
IGerenciadorEquipamento* pIGE;</p>
<p>pIGE = (IGerenciadorEquipamento*)p;</p>
<p>if (pIGE !=0)<br />
return pIGE-&gt;Run();</p>
<p>}</p>
<p>BYTE CalculaCRC(unsigned char *msg, int qtdeBytes)<br />
{<br />
BYTE valor_crc = 0;</p>
<p>for (int i=0; i&lt;=qtdeBytes-1;i++)<br />
{<br />
valor_crc += msg[i];<br />
}<br />
return valor_crc;<br />
}</p>
<p>int IGerenciadorEquipamento::Run(void)<br />
{<br />
bool bDone;<br />
unsigned char ucPacoteIN[256];<br />
unsigned char ucPacoteOUT[256];<br />
unsigned char ucPacoteCMD[256];<br />
int iRetry;<br />
BYTE byPacoteCRC, byPacoteCalcCRC;<br />
// char *lista[3];</p>
<p>int iTotalLido = 0;<br />
int iTamPacoteCMD = 0;</p>
<p>bDone = false;<br />
bRX_In_Progress = false;<br />
bTX_In_Progress = false;</p>
<p>GetLastError(); // just to clear any pending error</p>
<p>HANDLE hComm = hSerial;</p>
<p>char cmd[5];</p>
<p>while(!bDone)<br />
{</p>
<p>Sleep(1000);</p>
<p>if (ConfControl.detectaprot)<br />
EnviaPOLLING(hSerial);</p>
<p>if (ConfControl.controladora)<br />
{<br />
iTotalLido = LeMensagem(hSerial ,pacoteOUT,30);<br />
if (iTotalLido)<br />
{<br />
ConcedePrivilegio(hSerial,ConfControl.controladora);<br />
ConfControl.tentativas = 5;<br />
}<br />
ConfControl.tentativas--;<br />
if (ConfControl.tentativas &lt;= 0)<br />
{<br />
ConfControl.tentativas = 0;<br />
ConfControl.controladora = 0;<br />
}<br />
}</p>
<p>ConcedePrivilegio(hSerial,0);</p>
<p>iRetry = 1;</p>
<p>while (iRetry &gt;0)<br />
{</p>
<p>iRetry--;</p>
<p>iTotalLido = LeMensagem(hSerial,ucPacoteOUT,30);<br />
if (iTotalLido)<br />
{<br />
ZeroMemory(ucPacoteCMD,SERIAL_MAX_RX);</p>
<p>iTamPacoteCMD = ExtraiCMD<br />
(ucPacoteOUT,1,iTotalLido,ucPacoteCMD);<br />
if (iTamPacoteCMD &gt; 0)<br />
{</p>
<p>ZeroMemory(ucPacoteIN,SERIAL_MAX_RX);</p>
<p>switch(ucPacoteCMD[2])<br />
{<br />
case DC2:<br />
if (isdigit(ucPacoteCMD[1]))<br />
{<br />
iRetry = 1;<br />
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD[1]<br />
-48));<br />
}<br />
break;</p>
<p>case STX:<br />
byPacoteCalcCRC = CalculaCRC<br />
(ucPacoteCMD,iTamPacoteCMD-1);<br />
byPacoteCRC = (BYTE)ucPacoteCMD[iTamPacoteCMD-1];<br />
if (byPacoteCRC == byPacoteCalcCRC)<br />
{<br />
iRetry = 0;<br />
if (isdigit(ucPacoteCMD[1]))<br />
{</p>
<p>ConfControl.controladora = (BYTE)(<br />
(ucPacoteCMD[1])- 48);<br />
ConfControl.tentativas = 5;<br />
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD<br />
[1]-48));<br />
PurgeComm(hSerial, PURGE_RXCLEAR);<br />
}<br />
TraduzMens(ucPacoteCMD,iTamPacoteCMD);</p>
<p>/* teste do comando pede abastecimento<br />
if (gets(cmd) != NULL)<br />
{<br />
y = dividePorCaractere(cmd,&quot; &quot;,lista);</p>
<p>if (y &gt; 1)<br />
{<br />
if (strcmp(lista[0],&quot;abast&quot;) == 0)<br />
{<br />
PedeAbastecimentoManual(atoi(lista[1])<br />
+100);<br />
}<br />
}<br />
if (strcmp(cmd,&quot;quit&quot;) == 0)<br />
{<br />
break;<br />
}<br />
}<br />
*/<br />
}<br />
break;<br />
}<br />
}<br />
}</p>
<p>}</p>
<p>}<br />
DesativaEquipamento(true);<br />
}</p>
<p>/<em>--------------------------------------------------------------------</em>/<br />
/* until here */</p>
<p>/* cut <em>/<br />
/</em>--------------------------------------------------------------------*/<br />
/* Main Exec Code */</p>
<p>/***********************************************************************<br />
main.cpp - The main() routine for all the &quot;Basic Winsock&quot; suite of<br />
programs from the Winsock Programmer's FAQ. This function parses<br />
the command line, starts up Winsock, and calls an external function<br />
called DoWinsock to do the actual work.</p>
<p>This program is hereby released into the public domain. There is<br />
ABSOLUTELY NO WARRANTY WHATSOEVER for this product. Caveat hacker.<br />
***********************************************************************/</p>
<p>#include &quot;IThreadConnect.hpp&quot;<br />
#include &quot;IGerenciadorEquipamento.hpp&quot;<br />
#include &lt;windows.h&gt;<br />
#include &lt;vector&gt;<br />
#include &lt;algorithm&gt;</p>
<p>using namespace std;</p>
<p>BOOL CtrlHandler(DWORD fdwCtrlType)<br />
{<br />
switch( fdwCtrlType )<br />
{<br />
// Handle the CTRL+C signal.<br />
case CTRL_C_EVENT:<br />
//printf( &quot;Ctrl-C event\n\n&quot; );<br />
Beep( 750, 300 );<br />
return( TRUE );</p>
<p>// CTRL+CLOSE: confirm that the user wants to exit.<br />
case CTRL_CLOSE_EVENT:<br />
Beep( 600, 200 );<br />
//printf( &quot;Ctrl-Close event\n\n&quot; );<br />
return( TRUE );</p>
<p>// Pass other signals to the next handler.<br />
case CTRL_BREAK_EVENT:<br />
Beep( 900, 200 );<br />
//printf( &quot;Ctrl-Break event\n\n&quot; );<br />
return FALSE;</p>
<p>case CTRL_LOGOFF_EVENT:<br />
Beep( 1000, 200 );<br />
//printf( &quot;Ctrl-Logoff event\n\n&quot; );<br />
return FALSE;</p>
<p>case CTRL_SHUTDOWN_EVENT:<br />
Beep( 750, 500 );<br />
//printf( &quot;Ctrl-Shutdown event\n\n&quot; );<br />
return FALSE;</p>
<p>default:<br />
return FALSE;<br />
}<br />
system(&quot;PAUSE&quot;);<br />
}</p>
<p>//// main //////////////////////////////////////////////////////////////<br />
int main(int argc, char* argv[])<br />
{<br />
IThreadConnect threadConnect(0);<br />
IGerenciadorEquipamento gerente1(&quot;COM1&quot;, 9600, 8, SERIAL_PARITY_NONE);<br />
// IGerenciadorEquipamento gerente2(&quot;COM3&quot;, 9600, 8, SERIAL_PARITY_NONE);<br />
// IGerenciadorEquipamento gerente3(&quot;COM3&quot;, 9600, 8, SERIAL_PARITY_NONE);</p>
<p>vector&lt;IGerenciadorEquipamento&gt; vEquipamento;</p>
<p>if( SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE))<br />
{</p>
<p>gerente1.AtivaEquipamento();<br />
printf(&quot;1 - Connected ! \n&quot;);</p>
<p>}<br />
else<br />
printf( &quot;\nERROR: Could not set control handler&quot;);<br />
//system(&quot;PAUSE&quot;);</p>
<p>// exit(1);<br />
}</p>
<p>/<em>--------------------------------------------------------------------</em>/<br />
/* until here */</p>
<p>villen Dank,<br />
Berti</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/106664/serial-comm-handle-problem</link><generator>RSS for Node</generator><lastBuildDate>Mon, 29 Jun 2026 20:12:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/106664.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 12 Apr 2005 12:51:10 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Serial Comm Handle Problem on Tue, 12 Apr 2005 12:51:10 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>I wrote a code to do serial communication with an equipament.<br />
When i use the code outside of threaded class it seens work properly,<br />
but when i put inside a class and execute a thread in the first seconds the<br />
communication is ok, later i receive read/write error.<br />
I´ve been in MSDN site and there i discover that the read/write error is a<br />
INVALID_HANDLE problem. But why??? I just create the serial communication<br />
file and use it.<br />
Anyone can help me?</p>
<p>Here is the code</p>
<p>/* cut <em>/<br />
/</em>--------------------------------------------------------------------*/<br />
/* Main Class */</p>
<p>#ifndef _IGERENCIADOREQUIPAMENTO_H<br />
#define _IGERENCIADOREQUIPAMENTO_H</p>
<p>#include &lt;stdio.h&gt;<br />
#include &lt;windows.h&gt;</p>
<p>#define SERIAL_PARITY_NONE 0<br />
#define SERIAL_PARITY_ODD 1<br />
#define SERIAL_PARITY_EVEN 2</p>
<p>#define SERIAL_MAX_RX 256 // Input buffer max size<br />
#define SERIAL_MAX_TX 256 // output buffer max size</p>
<p>#define SERIAL_CONNECTED 0<br />
#define SERIAL_DISCONNECTED 1<br />
#define SERIAL_DATA_SENT 2<br />
#define SERIAL_DATA_ARRIVAL 3<br />
#define SERIAL_RING 4<br />
#define SERIAL_CD_ON 5<br />
#define SERIAL_CD_OFF 6<br />
#define SERIAL_DATA_RECV 7</p>
<p>#define SERIAL_SIGNAL_NBR 7</p>
<p>class IGerenciadorEquipamento;</p>
<p>typedef struct<br />
{<br />
HANDLE serialFD;<br />
IGerenciadorEquipamento* pIGE;<br />
}_SERIALCOM_IONICS;</p>
<p>class IGerenciadorEquipamento: public IThread<br />
{</p>
<p>private:<br />
HANDLE hSerial;<br />
char *cPortaSerial;<br />
DWORD dwBaudRate;<br />
BYTE byByteSize;<br />
BYTE byTipoParidade;<br />
bool conectado;<br />
bool bRX_In_Progress; // BOOL indicating if a<br />
ReadFile is<br />
// in progress<br />
bool bTX_In_Progress; // BOOL indicating if a<br />
WriteFile is<br />
// in progress</p>
<p>unsigned char pacoteIN[256];<br />
unsigned char pacoteOUT[256];</p>
<p>bool bConectado;</p>
<p>int ConfigTimeouts(COMMTIMEOUTS mCommtimeout);<br />
int ConfigDCB(DCB mDCB);</p>
<p>public:<br />
IGerenciadorEquipamento(char *mcPortaSerial, DWORD mdwBaudRate,<br />
BYTE mbyByteSize, BYTE mbyiTipoParidade);<br />
~IGerenciadorEquipamento();</p>
<p>int AtivaEquipamento(BOOL mbIniciaThread = true);<br />
int DesativaEquipamento(BOOL mbFinalizaThread = true);<br />
int EscreveMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int<br />
miTamanho);<br />
int LeMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int<br />
miTamanho);<br />
void PurgeSerial(void);<br />
bool VerificaEstado(void);<br />
int Run(void);<br />
HANDLE GetSerialHND(void);<br />
void OnSendRecv(void);<br />
unsigned char *GetDadosRecebidos(void);<br />
unsigned char *GetDadosEnviados(void);</p>
<p>int EnviaPOLLING(HANDLE hSerialCOM);<br />
int ConcedePrivilegio(HANDLE hSerialCOM, BYTE byEndereco);<br />
void TraduzMens(unsigned char *ucPacote, DWORD miTamanho);<br />
DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char <em>ucPacoteIN,<br />
DWORD dStartpos,<br />
DWORD dQtdebytes,<br />
unsigned char</em> ucPacoteOUT);</p>
<p>};</p>
<p>//DWORD WINAPI ComSendRecv(LPVOID p);<br />
int ComSendRecv(LPVOID p);</p>
<p>#endif</p>
<p>/<em>--------------------------------------------------------------------</em>/<br />
/* until here */</p>
<p>/* cut <em>/<br />
/</em>--------------------------------------------------------------------*/<br />
/* Main Class Code */</p>
<p>//#define STRICT<br />
#include &lt;cstdlib&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;process.h&gt;<br />
#include &lt;conio.h&gt;<br />
#include &lt;windows.h&gt;<br />
#include &lt;iostream&gt;<br />
#include &lt;math.h&gt;<br />
#include &quot;IGerenciadorEquipamento.hpp&quot;<br />
#include &quot;StringMethods.hpp&quot;<br />
#include &quot;Consts.hpp&quot;<br />
#include &quot;TipoProtocolo.hpp&quot;</p>
<p>#define SIG_POWER_DOWN 0<br />
#define SIG_READER 1<br />
#define SIG_READ_DONE 2 // data received has been read<br />
#define SIG_WRITER 3<br />
#define SIG_DATA_TO_TX 4 // data waiting to be sent<br />
#define SIG_MODEM_EVENTS 5<br />
#define SIG_MODEM_CHECKED 6</p>
<p>using namespace std;</p>
<p>typedef struct<br />
{<br />
BYTE controladora;<br />
BYTE tentativas;<br />
bool detectaprot;<br />
}STRU_CONFCONTROL;</p>
<p>STRU_CONFCONTROL ConfControl;</p>
<p>unsigned char *IGerenciadorEquipamento::GetDadosRecebidos(void)<br />
{<br />
return pacoteOUT;<br />
}</p>
<p>unsigned char *IGerenciadorEquipamento::GetDadosEnviados(void)<br />
{<br />
return pacoteIN;<br />
}</p>
<p>int IGerenciadorEquipamento::EnviaPOLLING(HANDLE hSerialCOM)<br />
{<br />
unsigned char ucPacoteIN[256];<br />
unsigned char ucPacoteOUT[256];<br />
int iTotalLido;</p>
<p>ZeroMemory(ucPacoteIN,3);</p>
<p>ucPacoteIN[0] = SYN;<br />
ucPacoteIN[1] = '1';<br />
ucPacoteIN[2] = 0x55;</p>
<p>EscreveMensagem(hSerialCOM ,ucPacoteIN,3);<br />
iTotalLido=LeMensagem(hSerialCOM ,ucPacoteOUT,30);<br />
if (iTotalLido)<br />
{<br />
if ((ucPacoteOUT[0] == SYN) &amp;&amp; (ucPacoteOUT[1] == '1') &amp;&amp;<br />
(ucPacoteOUT[2] == 0xAA))<br />
ConfControl.detectaprot = false;<br />
}<br />
return iTotalLido;<br />
}</p>
<p>int IGerenciadorEquipamento::ConcedePrivilegio(HANDLE hSerialCOM, BYTE<br />
byEndereco)<br />
{<br />
unsigned char ucPacoteIN[256];<br />
int iTotalEscrito;</p>
<p>ZeroMemory(ucPacoteIN,3);</p>
<p>// privilegio<br />
ucPacoteIN[0] = SYN;<br />
ucPacoteIN[1] = byEndereco+48;<br />
ucPacoteIN[2] = ACK;</p>
<p>iTotalEscrito=EscreveMensagem(hSerialCOM ,ucPacoteIN,3);<br />
return iTotalEscrito;<br />
}</p>
<p>void IGerenciadorEquipamento::TraduzMens(unsigned char *ucPacote, DWORD<br />
miTamanho)<br />
{<br />
int iCanal;<br />
double dLitros;<br />
char cPulsos[8];<br />
double dPulsos;<br />
char parcelaPacote;<br />
char cInd;<br />
int iInd;<br />
int k;</p>
<p>dLitros = 0;</p>
<p>iCanal = ((((BYTE)ucPacote[1])-49)*8);<br />
iInd = ucPacote[3] &amp; 0x0F;</p>
<p>switch(iInd)<br />
{<br />
case 0:<br />
iCanal += ((((BYTE)ucPacote[4])-47)+100);<br />
printf(&quot;Bomba %i ligada\n&quot;,iCanal-100);<br />
break;<br />
case 1:<br />
iCanal += ((((BYTE)ucPacote[4])-47)+100);<br />
printf(&quot;Bomba %i desligada\n&quot;,iCanal-100);</p>
<p>dPulsos = 0;<br />
k=0;<br />
ZeroMemory(cPulsos,8);<br />
for (int i=5;i&lt;13;i++)<br />
{<br />
cPulsos[k] = ucPacote[i];<br />
k++;<br />
}<br />
dPulsos = atof(cPulsos);</p>
<p>dLitros = round(dPulsos/1*100)/100;</p>
<p>if ((iCanal &gt; 100) &amp;&amp; (iCanal &lt; 133))<br />
{<br />
printf(&quot;Bomba %i abasteceu %4.2f litros \n&quot;,iCanal-100, dLitros);<br />
}<br />
else<br />
printf(&quot;Bomba %i abasteceu %4.2f litros \n&quot;,iCanal-100, 0.00);</p>
<p>break;<br />
case 7:<br />
printf(&quot;APM Reenergizado\n&quot;);<br />
break;<br />
}</p>
<p>}</p>
<p>DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char <em>ucPacoteIN,<br />
DWORD dStartpos,<br />
DWORD dQtdebytes,<br />
unsigned char</em> ucPacoteOUT)<br />
{<br />
int i;<br />
DWORD dPosETX = 0;<br />
DWORD dPosSTX = 0;<br />
DWORD dPosDC2 = 0;<br />
bool bOneMoreSYN;<br />
bool bMensTexto;<br />
bool bContinuar = true;<br />
DWORD dBytesToSYN;<br />
int iTotalBytes;</p>
<p>iTotalBytes = 0;<br />
dBytesToSYN = 0;<br />
bMensTexto = false;<br />
bOneMoreSYN = true;<br />
dPosETX = 0;<br />
dPosSTX = 0;<br />
dPosDC2 = 0;</p>
<p>for(i=dQtdebytes-1;(i&gt;=0);i--)<br />
{</p>
<p>if (bOneMoreSYN)<br />
dBytesToSYN++;</p>
<p>switch(ucPacoteIN[i])<br />
{<br />
case SYN:<br />
if ((dPosETX) &amp;&amp; (dPosSTX) &amp;&amp; ((dPosSTX-i) == 2) &amp;&amp; (dQtdebytes<br />
&gt; dPosETX))<br />
{<br />
bMensTexto = true;<br />
bContinuar = false;<br />
break;<br />
}<br />
else<br />
{<br />
if ((dPosDC2) &amp;&amp; (dPosDC2-i) == 2)<br />
{<br />
if ((!bOneMoreSYN) &amp;&amp; (dBytesToSYN &gt; 0))<br />
{<br />
return iTotalBytes;<br />
}<br />
else<br />
{<br />
bContinuar = false;<br />
break;<br />
}<br />
}<br />
else<br />
{<br />
if (!bOneMoreSYN) { return 0; }<br />
bOneMoreSYN = false;<br />
dPosDC2 = 0;<br />
dPosETX = 0;<br />
dPosSTX = 0;<br />
}</p>
<p>}<br />
break;</p>
<p>case DC2: dPosDC2 = i; break;<br />
case STX: dPosSTX = i; break;<br />
case ETX: dPosETX = i; break;<br />
}<br />
if (!bContinuar) break;</p>
<p>}</p>
<p>if ((i != 0xFFFF) &amp;&amp; (ucPacoteIN[i] == SYN))<br />
{<br />
if (bMensTexto)<br />
dPosETX++;<br />
else<br />
dPosETX = dPosDC2;</p>
<p>for(int j=i;j&lt;=dPosETX;j++)<br />
{<br />
ucPacoteOUT[iTotalBytes] = ucPacoteIN[j];<br />
iTotalBytes++;<br />
}<br />
}<br />
return iTotalBytes;<br />
}</p>
<p>IGerenciadorEquipamento::IGerenciadorEquipamento(char *mcPortaSerial,<br />
DWORD mdwBaudRate,<br />
BYTE mbyByteSize,<br />
BYTE mbyTipoParidade)<br />
{<br />
cPortaSerial = mcPortaSerial;<br />
dwBaudRate = mdwBaudRate;<br />
mbyTipoParidade = mbyTipoParidade;<br />
mbyByteSize = mbyByteSize;<br />
hSerial = INVALID_HANDLE_VALUE;<br />
conectado = false;<br />
bRX_In_Progress = false;<br />
bTX_In_Progress = false;<br />
ConfControl.detectaprot = true;<br />
ConfControl.tentativas = 0;<br />
ConfControl.controladora = 0;</p>
<p>}</p>
<p>IGerenciadorEquipamento::~IGerenciadorEquipamento()<br />
{<br />
conectado = false;<br />
cPortaSerial = &quot;&quot;;<br />
dwBaudRate = 0;<br />
byTipoParidade = SERIAL_PARITY_NONE;<br />
byByteSize = 0;</p>
<p>if (GetThreadHND()!=0)<br />
WaitForSingleObject(GetThreadHND(), 2000);</p>
<p>bRX_In_Progress = false;<br />
bTX_In_Progress = false;</p>
<p>if (hSerial != INVALID_HANDLE_VALUE)<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;<br />
}</p>
<p>int IGerenciadorEquipamento::ConfigTimeouts(COMMTIMEOUTS mCommtimeout)<br />
{</p>
<p>// configura os timeouts da Porta Serial<br />
mCommtimeout.ReadIntervalTimeout = 20;<br />
mCommtimeout.ReadTotalTimeoutMultiplier = 1;<br />
mCommtimeout.ReadTotalTimeoutConstant = 20;<br />
mCommtimeout.WriteTotalTimeoutMultiplier = 5;<br />
mCommtimeout.WriteTotalTimeoutConstant = 5;</p>
<p>return SetCommTimeouts(hSerial,&amp;mCommtimeout);<br />
}</p>
<p>int IGerenciadorEquipamento::ConfigDCB(DCB mDCB)<br />
{<br />
// recupera as informações do DCB<br />
if (!GetCommState(hSerial,&amp;mDCB))<br />
{<br />
CloseHandle(hSerial);<br />
return ERROR_INVALID_HANDLE;<br />
}</p>
<p>// set DCB to configure the serial port<br />
mDCB.DCBlength = sizeof(mDCB);</p>
<p>/* ---------- Serial Port Config ------- */<br />
mDCB.BaudRate = dwBaudRate;</p>
<p>switch(byTipoParidade)<br />
{<br />
case SERIAL_PARITY_NONE:<br />
mDCB.Parity = NOPARITY;<br />
mDCB.fParity = 0;<br />
break;<br />
case SERIAL_PARITY_EVEN:<br />
mDCB.Parity = EVENPARITY;<br />
mDCB.fParity = 1;<br />
break;<br />
case SERIAL_PARITY_ODD:<br />
mDCB.Parity = ODDPARITY;<br />
mDCB.fParity = 1;<br />
break;<br />
}</p>
<p>mDCB.StopBits = ONESTOPBIT;<br />
mDCB.ByteSize = 8;<br />
mDCB.fBinary = 0;<br />
mDCB.fAbortOnError = 0;<br />
mDCB.wReserved = 0;<br />
mDCB.XonLim = 100;<br />
mDCB.XoffLim = 100;<br />
mDCB.XonChar = 0x0D;<br />
mDCB.XoffChar = 0x0A;<br />
mDCB.ErrorChar = 0;<br />
mDCB.EofChar = 0;<br />
mDCB.EvtChar = 0;<br />
mDCB.wReserved1 = 0;</p>
<p>return SetCommState(hSerial,&amp;mDCB);</p>
<p>}</p>
<p>int IGerenciadorEquipamento::AtivaEquipamento(BOOL mbIniciaThread)<br />
{<br />
int iErro;<br />
DCB dcb;<br />
int i;</p>
<p>COMMTIMEOUTS cto;</p>
<p>if (hSerial != INVALID_HANDLE_VALUE)<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;</p>
<p>if (cPortaSerial != &quot;&quot;)<br />
{<br />
iErro = 0;</p>
<p>hSerial = CreateFile(cPortaSerial, // filename<br />
GENERIC_READ | GENERIC_WRITE, // acesso<br />
desejado<br />
0, // modo de<br />
compartilhamento<br />
NULL, // atributos<br />
de segurança<br />
OPEN_EXISTING, // disposição<br />
da criação do arquivo<br />
FILE_FLAG_NO_BUFFERING,<br />
// flag de criação<br />
NULL); // indica se<br />
pode ou não copiar os<br />
// atributos do<br />
arquivo atual para outro<br />
// arquivo<br />
if (hSerial != INVALID_HANDLE_VALUE)<br />
{<br />
bConectado = true;</p>
<p>// aplica os timeous<br />
if (!ConfigTimeouts(cto))<br />
iErro = 2;</p>
<p>// aplica o DCB<br />
if (!ConfigDCB(dcb))<br />
iErro = 4;</p>
<p>}<br />
}<br />
else<br />
iErro = -2;</p>
<p>/* --------------------------------------------- */<br />
if (iErro &gt; 0)<br />
{<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;<br />
}<br />
else<br />
{</p>
<p>HANDLE hThread1;<br />
DWORD dThreadID1;<br />
if(mbIniciaThread)<br />
{<br />
printf(&quot;Connected ! \n&quot;);</p>
<p>hThread1 = CreateThread(NULL, // default<br />
security attributes<br />
0, // use default<br />
stack size<br />
(DWORD (_stdcall *)(void <em>))ComSendRecv,<br />
// thread function<br />
(void</em>)this, // argument to thread<br />
function<br />
0, // use default<br />
creation flags<br />
&amp;dThreadID1); // returns the<br />
thread identifier</p>
<p>*/</p>
<p>}<br />
}</p>
<p>/* --------------------------------------------- */<br />
return iErro;</p>
<p>}</p>
<p>int IGerenciadorEquipamento::DesativaEquipamento(BOOL mbFinalizaThread)<br />
{<br />
conectado = false;</p>
<p>if(mbFinalizaThread)<br />
{</p>
<p>}<br />
if (hSerial != INVALID_HANDLE_VALUE)<br />
CloseHandle(hSerial);<br />
hSerial = INVALID_HANDLE_VALUE;</p>
<p>if (this-&gt;GetThreadHND())<br />
{<br />
if (WaitForSingleObject (this-&gt;GetThreadHND(), 2000) == WAIT_TIMEOUT)<br />
{<br />
TerminateThread (this-&gt;GetThreadHND(), 1);<br />
CloseHandle (this-&gt;GetThreadHND());<br />
}<br />
else CloseHandle (this-&gt;GetThreadHND());<br />
}<br />
CloseHandle(this-&gt;GetThreadHND());</p>
<p>printf(&quot;Disconnected ! \n&quot;);</p>
<p>}</p>
<p>int IGerenciadorEquipamento::EscreveMensagem(HANDLE hSerialCOM,unsigned<br />
char* mcMensagem, int miTamanho)</p>
<p>{<br />
char cTXBuffer[SERIAL_MAX_RX];<br />
DWORD iQtdebytesEscritos;<br />
int iTamanhoBuffer = 0;<br />
int iSuccess = 0;<br />
int Error = 0;<br />
HANDLE hCom;</p>
<p>if (!bTX_In_Progress)<br />
{<br />
PurgeComm(hSerialCOM,PURGE_TXCLEAR | PURGE_RXCLEAR);<br />
//hCom = hSerialCOM;</p>
<p>iSuccess = WriteFile(hSerialCOM,<br />
mcMensagem,<br />
miTamanho,<br />
&amp;iQtdebytesEscritos,<br />
NULL);</p>
<p>if (!iSuccess)<br />
{<br />
// failure<br />
if((Error = GetLastError()) != ERROR_IO_PENDING )<br />
printf(&quot;erro: %i , qtde: %i =&gt; WriteFile error (not pending)\<br />
n&quot;, Error,iQtdebytesEscritos &amp; 0xFFFF);<br />
}</p>
<p>bTX_In_Progress = false;</p>
<p>}</p>
<p>return iQtdebytesEscritos;<br />
}</p>
<p>int IGerenciadorEquipamento::LeMensagem(HANDLE hSerialCOM,unsigned char*<br />
mcMensagem, int miTamanho)<br />
{<br />
DWORD iQtdebytesLidos;<br />
DWORD iLenMensagem = 0;<br />
int iSuccess = 0;<br />
int Error = 0;<br />
HANDLE hCom;</p>
<p>ZeroMemory(mcMensagem,SERIAL_MAX_RX);</p>
<p>if (!bRX_In_Progress)<br />
{<br />
// locking reading<br />
bRX_In_Progress = true;<br />
//hCom = hSerialCOM;</p>
<p>// starting a new read<br />
iSuccess = ReadFile(hSerialCOM, // handle do arquivo<br />
mcMensagem, // buffer de leitura<br />
miTamanho, // número de bytes a serem lidos<br />
&amp;iQtdebytesLidos, // número de bytes realmente<br />
lidos<br />
NULL); // usado para leitura<br />
concorrente<br />
// da serial</p>
<p>if (!iSuccess)<br />
{<br />
// failure<br />
if((Error = GetLastError()) != ERROR_IO_PENDING)<br />
{<br />
printf(&quot;erro: %i , qtde: %i =&gt; Readfile error (not pending)\<br />
n&quot;, Error,iQtdebytesLidos &amp; 0xFFFF);<br />
}<br />
}<br />
bRX_In_Progress = false;<br />
}</p>
<p>return iQtdebytesLidos;<br />
}</p>
<p>void IGerenciadorEquipamento::PurgeSerial(void)<br />
{<br />
PurgeComm(hSerial,PURGE_TXCLEAR | PURGE_RXCLEAR);<br />
}</p>
<p>bool IGerenciadorEquipamento::VerificaEstado(void)<br />
{<br />
// return (bRX_In_Progress || bTX_In_Progress);<br />
}</p>
<p>int ComSendRecv(LPVOID p)<br />
{<br />
IGerenciadorEquipamento* pIGE;</p>
<p>pIGE = (IGerenciadorEquipamento*)p;</p>
<p>if (pIGE !=0)<br />
return pIGE-&gt;Run();</p>
<p>}</p>
<p>BYTE CalculaCRC(unsigned char *msg, int qtdeBytes)<br />
{<br />
BYTE valor_crc = 0;</p>
<p>for (int i=0; i&lt;=qtdeBytes-1;i++)<br />
{<br />
valor_crc += msg[i];<br />
}<br />
return valor_crc;<br />
}</p>
<p>int IGerenciadorEquipamento::Run(void)<br />
{<br />
bool bDone;<br />
unsigned char ucPacoteIN[256];<br />
unsigned char ucPacoteOUT[256];<br />
unsigned char ucPacoteCMD[256];<br />
int iRetry;<br />
BYTE byPacoteCRC, byPacoteCalcCRC;<br />
// char *lista[3];</p>
<p>int iTotalLido = 0;<br />
int iTamPacoteCMD = 0;</p>
<p>bDone = false;<br />
bRX_In_Progress = false;<br />
bTX_In_Progress = false;</p>
<p>GetLastError(); // just to clear any pending error</p>
<p>HANDLE hComm = hSerial;</p>
<p>char cmd[5];</p>
<p>while(!bDone)<br />
{</p>
<p>Sleep(1000);</p>
<p>if (ConfControl.detectaprot)<br />
EnviaPOLLING(hSerial);</p>
<p>if (ConfControl.controladora)<br />
{<br />
iTotalLido = LeMensagem(hSerial ,pacoteOUT,30);<br />
if (iTotalLido)<br />
{<br />
ConcedePrivilegio(hSerial,ConfControl.controladora);<br />
ConfControl.tentativas = 5;<br />
}<br />
ConfControl.tentativas--;<br />
if (ConfControl.tentativas &lt;= 0)<br />
{<br />
ConfControl.tentativas = 0;<br />
ConfControl.controladora = 0;<br />
}<br />
}</p>
<p>ConcedePrivilegio(hSerial,0);</p>
<p>iRetry = 1;</p>
<p>while (iRetry &gt;0)<br />
{</p>
<p>iRetry--;</p>
<p>iTotalLido = LeMensagem(hSerial,ucPacoteOUT,30);<br />
if (iTotalLido)<br />
{<br />
ZeroMemory(ucPacoteCMD,SERIAL_MAX_RX);</p>
<p>iTamPacoteCMD = ExtraiCMD<br />
(ucPacoteOUT,1,iTotalLido,ucPacoteCMD);<br />
if (iTamPacoteCMD &gt; 0)<br />
{</p>
<p>ZeroMemory(ucPacoteIN,SERIAL_MAX_RX);</p>
<p>switch(ucPacoteCMD[2])<br />
{<br />
case DC2:<br />
if (isdigit(ucPacoteCMD[1]))<br />
{<br />
iRetry = 1;<br />
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD[1]<br />
-48));<br />
}<br />
break;</p>
<p>case STX:<br />
byPacoteCalcCRC = CalculaCRC<br />
(ucPacoteCMD,iTamPacoteCMD-1);<br />
byPacoteCRC = (BYTE)ucPacoteCMD[iTamPacoteCMD-1];<br />
if (byPacoteCRC == byPacoteCalcCRC)<br />
{<br />
iRetry = 0;<br />
if (isdigit(ucPacoteCMD[1]))<br />
{</p>
<p>ConfControl.controladora = (BYTE)(<br />
(ucPacoteCMD[1])- 48);<br />
ConfControl.tentativas = 5;<br />
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD<br />
[1]-48));<br />
PurgeComm(hSerial, PURGE_RXCLEAR);<br />
}<br />
TraduzMens(ucPacoteCMD,iTamPacoteCMD);</p>
<p>/* teste do comando pede abastecimento<br />
if (gets(cmd) != NULL)<br />
{<br />
y = dividePorCaractere(cmd,&quot; &quot;,lista);</p>
<p>if (y &gt; 1)<br />
{<br />
if (strcmp(lista[0],&quot;abast&quot;) == 0)<br />
{<br />
PedeAbastecimentoManual(atoi(lista[1])<br />
+100);<br />
}<br />
}<br />
if (strcmp(cmd,&quot;quit&quot;) == 0)<br />
{<br />
break;<br />
}<br />
}<br />
*/<br />
}<br />
break;<br />
}<br />
}<br />
}</p>
<p>}</p>
<p>}<br />
DesativaEquipamento(true);<br />
}</p>
<p>/<em>--------------------------------------------------------------------</em>/<br />
/* until here */</p>
<p>/* cut <em>/<br />
/</em>--------------------------------------------------------------------*/<br />
/* Main Exec Code */</p>
<p>/***********************************************************************<br />
main.cpp - The main() routine for all the &quot;Basic Winsock&quot; suite of<br />
programs from the Winsock Programmer's FAQ. This function parses<br />
the command line, starts up Winsock, and calls an external function<br />
called DoWinsock to do the actual work.</p>
<p>This program is hereby released into the public domain. There is<br />
ABSOLUTELY NO WARRANTY WHATSOEVER for this product. Caveat hacker.<br />
***********************************************************************/</p>
<p>#include &quot;IThreadConnect.hpp&quot;<br />
#include &quot;IGerenciadorEquipamento.hpp&quot;<br />
#include &lt;windows.h&gt;<br />
#include &lt;vector&gt;<br />
#include &lt;algorithm&gt;</p>
<p>using namespace std;</p>
<p>BOOL CtrlHandler(DWORD fdwCtrlType)<br />
{<br />
switch( fdwCtrlType )<br />
{<br />
// Handle the CTRL+C signal.<br />
case CTRL_C_EVENT:<br />
//printf( &quot;Ctrl-C event\n\n&quot; );<br />
Beep( 750, 300 );<br />
return( TRUE );</p>
<p>// CTRL+CLOSE: confirm that the user wants to exit.<br />
case CTRL_CLOSE_EVENT:<br />
Beep( 600, 200 );<br />
//printf( &quot;Ctrl-Close event\n\n&quot; );<br />
return( TRUE );</p>
<p>// Pass other signals to the next handler.<br />
case CTRL_BREAK_EVENT:<br />
Beep( 900, 200 );<br />
//printf( &quot;Ctrl-Break event\n\n&quot; );<br />
return FALSE;</p>
<p>case CTRL_LOGOFF_EVENT:<br />
Beep( 1000, 200 );<br />
//printf( &quot;Ctrl-Logoff event\n\n&quot; );<br />
return FALSE;</p>
<p>case CTRL_SHUTDOWN_EVENT:<br />
Beep( 750, 500 );<br />
//printf( &quot;Ctrl-Shutdown event\n\n&quot; );<br />
return FALSE;</p>
<p>default:<br />
return FALSE;<br />
}<br />
system(&quot;PAUSE&quot;);<br />
}</p>
<p>//// main //////////////////////////////////////////////////////////////<br />
int main(int argc, char* argv[])<br />
{<br />
IThreadConnect threadConnect(0);<br />
IGerenciadorEquipamento gerente1(&quot;COM1&quot;, 9600, 8, SERIAL_PARITY_NONE);<br />
// IGerenciadorEquipamento gerente2(&quot;COM3&quot;, 9600, 8, SERIAL_PARITY_NONE);<br />
// IGerenciadorEquipamento gerente3(&quot;COM3&quot;, 9600, 8, SERIAL_PARITY_NONE);</p>
<p>vector&lt;IGerenciadorEquipamento&gt; vEquipamento;</p>
<p>if( SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE))<br />
{</p>
<p>gerente1.AtivaEquipamento();<br />
printf(&quot;1 - Connected ! \n&quot;);</p>
<p>}<br />
else<br />
printf( &quot;\nERROR: Could not set control handler&quot;);<br />
//system(&quot;PAUSE&quot;);</p>
<p>// exit(1);<br />
}</p>
<p>/<em>--------------------------------------------------------------------</em>/<br />
/* until here */</p>
<p>villen Dank,<br />
Berti</p>
]]></description><link>https://www.c-plusplus.net/forum/post/764812</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/764812</guid><dc:creator><![CDATA[berti]]></dc:creator><pubDate>Tue, 12 Apr 2005 12:51:10 GMT</pubDate></item></channel></rss>