multi-serial port communication on windows - c++

I am working on a project which need to operate two serial port as the same time on windows, but whatever I try I can only open one serial port. Unless repeat open and close, I can operate the two ports but it is too slow. I need to write and read first port and formalize it by protocol and sent it to another port, but I can not initial two port. I was using open and close two ports repeatly to do that before but it was toooooooo slow. Anybody know how to open two port in the same time; Thx!!!
here are my code here:
#include <iostream>
#include <iomanip>
#include "udp.h"
#include "Serial.h"
#include "Formalized.h"
using namespace std;
bool sthread = false;
unsigned char status[6] = {};
HANDLE hMutex = NULL;
DWORD WINAPI ULTRAread(LPVOID lpParamter)
{
Cserial ultra;
unsigned char input0[7] = { 0x00,0x01,0x00,0x01,0x01,0xE5,0xAC };
unsigned char input1[7] = { 0x00,0x02,0x00,0x01,0x01,0xE5,0xE8 };
unsigned char input2[7] = { 0x00,0x03,0x00,0x01,0x01,0xE4,0x14 };
unsigned char input3[7] = { 0x00,0x04,0x00,0x01,0x01,0xE5,0x60 };
unsigned char input4[7] = { 0x00,0x05,0x00,0x01,0x01,0xE4,0x9C };
unsigned char input5[7] = { 0x00,0x06,0x00,0x01,0x01,0xE4,0xD8 };
unsigned char* input[6] = { input0,input1,input2,input3,input4,input5 };
unsigned char pool[8] = {};
if (!ultra.Initcom("COM10")) //ultrasonic COM interface
{
cout << "Init ultrasonic failure \n";
getchar();
sthread = false;
}
else
{
sthread = true;
for (;;)
{
WaitForSingleObject(hMutex, INFINITE);
for (int i = 0; i < 6; i++)
{
if (ultra.Write(input[i], 7))
{
ultra.Read(pool, 8);
}
switch (pool[5])
{
case 0x01:
status[i] = 0x01;
break;
case 0x00:
status[i] = 0x00;
break;
}
}
Sleep(5000);
ReleaseMutex(hMutex);
}
}
}
int main()
{
HANDLE uThread = CreateThread(NULL, 0, ULTRAread, NULL, 0, NULL);
hMutex = CreateMutex(NULL, FALSE, "ultrasonics status");
Cserial zigbee;
cUDP UWB;
char buff[300];
char data[256];
if (!UWB.Initial(6685)) //latitude and longitude port
{
cout << "UWB Port connecting failure \n";
getchar();
}
else
{
cout << "UWB Com connecting success \n";
}
if (!zigbee.Initcom("COM7")) //zigbee access port
{
cout << "Zigbee Initial Failure! \n";
getchar();
}
else
{
cout << "Zigbee Initial Success! \n";
}
for (;;)
{
WaitForSingleObject(hMutex, INFINITE);
switch (sthread)
{
case TRUE: //ultrasonics trustful
WaitForSingleObject(hMutex, INFINITE);
cout << "1";
ReleaseMutex(hMutex);
break;
case FALSE:
cout << "2";
break;
}
Sleep(5000);
}
CloseHandle(uThread);
getchar();
return 0;
}
#include"Serial.h"
Cserial::Cserial()
{
hcom = INVALID_HANDLE_VALUE;
}
Cserial::~Cserial()
{
}
bool Cserial::Initcom(LPCSTR Port)
{
hcom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL, 0);
if (hcom == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "fail serial1\n");
return false;
}
SetupComm(hcom, 1024, 1024);
DCB dcb;
GetCommState(hcom, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = 0;
dcb.StopBits = 1;
SetCommState(hcom, &dcb);
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(hcom, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 10;
CommTimeouts.ReadTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier = 1;
CommTimeouts.WriteTotalTimeoutConstant = 10;
if (!SetCommTimeouts(hcom, &CommTimeouts))
{
fprintf(stderr, "fail serial2\n");
return FALSE;
}
return true;
}
void Cserial::Uninitcom()
{
CloseHandle(hcom);
hcom = INVALID_HANDLE_VALUE;
}
bool Cserial::Clearcom()
{
PurgeComm(hcom, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);
return TRUE;
}
bool Cserial::Write(unsigned char* buf, int len)
{
if (hcom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD dwWrittenLen = 0;
if (!WriteFile(hcom, buf, len, &dwWrittenLen, NULL))
{
return FALSE;
}
else
{
return TRUE;
}
}
bool Cserial::Read(unsigned char* buf, int len)
{
DWORD dwReadLen = 0;
if (hcom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (!ReadFile(hcom, buf, len, &dwReadLen, NULL))
{
return FALSE;
}
else
{
return TRUE;
}
}

Related

C++ Serial port with USB hub

I want to connect a seairl port with C++ using USB hub (USB splliter).
I have a code that works perfectly fine with my COM ports, but when I'm trying to use the USB hub, I get an error says the COM port not available (even though I see it in the device manager).
I there a way to connect a USB hub COM port in C++?
I attached my current code if necessary. Thank you!
SerialPort.hpp:
/*
* Author: Manash Kumar Mandal
* Modified Library introduced in Arduino Playground which does not work
* This works perfectly
* LICENSE: MIT
*/
#pragma once
#define ARDUINO_WAIT_TIME 2000
#define MAX_DATA_LENGTH 1024
#include <windows.h>
#include <iostream>
#include <string>
class SerialPort {
private:
std::string readBuffer;
HANDLE handler;
bool connected;
COMSTAT status;
DWORD errors;
public:
explicit SerialPort(const char* portName, DWORD baudRate = CBR_9600);
~SerialPort();
int readSerialPort(const char* buffer, unsigned int buf_size);
int readSerialPortUntil(std::string* payload, std::string until);
bool writeSerialPort(const char* buffer, unsigned int buf_size);
bool writeSerialPort(std::string payload);
bool isConnected();
void closeSerial();
};
SerialPort.cpp:
/*
* Author: Manash Kumar Mandal
* Modified Library introduced in Arduino Playground which does not work
* This works perfectly
* LICENSE: MIT
*/
#include <windows.h>
#include <iostream>
#include <string>
#include "SerialPort.hpp"
SerialPort::SerialPort(const char* portName, DWORD baudRate) {
this->connected = false;
this->handler = CreateFileA(static_cast<LPCSTR>(portName),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (this->handler == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
std::cerr << "ERROR: Handle was not attached.Reason : " << portName << " not available\n";
} else {
std::cerr << "ERROR!!!\n";
}
} else {
DCB dcbSerialParameters = { 0 };
if (!GetCommState(this->handler, &dcbSerialParameters)) {
std::cerr << "ERROR: Failed to get current serial parameters\n";
} else {
dcbSerialParameters.BaudRate = baudRate;
dcbSerialParameters.ByteSize = 8;
dcbSerialParameters.StopBits = ONESTOPBIT;
dcbSerialParameters.Parity = NOPARITY;
dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
if (!SetCommState(handler, &dcbSerialParameters)) {
std::cout << "ALERT: could not set serial port parameters\n";
} else {
this->connected = true;
PurgeComm(this->handler, PURGE_RXCLEAR | PURGE_TXCLEAR);
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
SerialPort::~SerialPort() {
if (this->connected) {
this->connected = false;
CloseHandle(this->handler);
}
}
// Reading bytes from serial port to buffer;
// returns read bytes count, or if error occurs, returns 0
int SerialPort::readSerialPort(const char* buffer, unsigned int buf_size) {
DWORD bytesRead{};
unsigned int toRead = 0;
ClearCommError(this->handler, &this->errors, &this->status);
if (this->status.cbInQue > 0) {
if (this->status.cbInQue > buf_size) {
toRead = buf_size;
} else {
toRead = this->status.cbInQue;
}
}
memset((void*)buffer, 0, buf_size);
if (ReadFile(this->handler, (void*)buffer, toRead, &bytesRead, NULL)) {
return bytesRead;
}
return 0;
}
int SerialPort::readSerialPortUntil(std::string* payload, std::string until) {
int untilLen = until.length(), len;
do {
char buffer[MAX_DATA_LENGTH];
int bytesRead = this->readSerialPort(buffer, MAX_DATA_LENGTH);
if (bytesRead == 0) {
int endIndex = this->readBuffer.find(until);
if (endIndex != -1) {
int index = endIndex + untilLen;
*payload = this->readBuffer.substr(0, index);
this->readBuffer = this->readBuffer.substr(index);
}
return bytesRead;
}
this->readBuffer += std::string(buffer);
len = this->readBuffer.length();
} while (this->readBuffer.find(until) == std::string::npos);
int index = this->readBuffer.find(until) + untilLen;
*payload = this->readBuffer.substr(0, index);
this->readBuffer = this->readBuffer.substr(index);
return index;
}
// Sending provided buffer to serial port;
// returns true if succeed, false if not
bool SerialPort::writeSerialPort(const char* buffer, unsigned int buf_size) {
DWORD bytesSend;
if (!WriteFile(this->handler, (void*)buffer, buf_size, &bytesSend, 0)) {
ClearCommError(this->handler, &this->errors, &this->status);
return false;
}
return true;
}
bool SerialPort::writeSerialPort(std::string payload) {
return this->writeSerialPort(payload.c_str(), payload.length());
}
// Checking if serial port is connected
bool SerialPort::isConnected() {
if (!ClearCommError(this->handler, &this->errors, &this->status)) {
this->connected = false;
}
return this->connected;
}
void SerialPort::closeSerial() {
CloseHandle(this->handler);
}

Some files send on a HLS Server using Http Put request are partially uploaded

I have to upload audio chunks continuously on a HLS Server as a part of my project. I am able to upload chunks sucessfully using HTTP Put method with wininet API in C++ using following code.
bool CHTTP::HttpPut(char *szFile,int fileType)
{
bool bErrorFlag = false;
if(m_hInternet == NULL)
{
int retStatus = OpenHTTPSession();
if(retStatus < 1)
{
return true;
}
}
char szPostURL[256];
INTERNET_BUFFERS BufferIn = {0};
DWORD dwBytesRead;
DWORD dwBytesWritten;
BYTE pBuffer[350000];
BOOL bRead, bRet;
static int flag = 1;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
char szLocalFilePath[256];
if(fileType == AUDIO_CHUNK)
sprintf(szLocalFilePath,"%s/%s",m_strFilePath,szFile);
else
strcpy(szLocalFilePath,szFile);
int iFileSize = 0;
if(fileType == AUDIO_CHUNK)
{
strcpy(szPostURL,m_strPostPath);
strcat(szPostURL,"/");
strcat(szPostURL,szFile);
}
else if(fileType == M3U8)
strcpy(szPostURL,m_szM3U8FileToPost);
else if(fileType == AUTO_M3U8)
strcpy(szPostURL,m_szM3U8AutoPost);
DWORD dwFlags =
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_COOKIES |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_NO_UI |
INTERNET_FLAG_RELOAD |INTERNET_FLAG_SECURE;
m_hRequest = HttpOpenRequest(m_hHttpSession, (const char*)"PUT",szPostURL, "HTTP/1.1",NULL , (const char**)"*/*\0",dwFlags, 1);
if(m_hRequest==NULL)
{
bErrorFlag = true;
CloseHTTPSession();
return bErrorFlag;
}
else
{
bErrorFlag = false;
}
int num_of_try = 0;
while(num_of_try < 3)
{
char logDump[1000];
num_of_try++;
HANDLE hFile = CreateFile (szLocalFilePath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
bErrorFlag = true;
break;
}
else if(!m_bLogFlagCreateErr)
{
m_bLogFlagCreateErr = true;
sprintf(logDump,"CreateFile success %s",szFile);
WriteLog(mLogFile,logDump);
bErrorFlag = false;
}
BufferIn.dwBufferTotal = GetFileSize (hFile, NULL);
iFileSize = BufferIn.dwBufferTotal;
if(!HttpSendRequestEx( m_hRequest, &BufferIn, NULL, HSR_INITIATE, 0))
{
bErrorFlag = true;
m_bLogFlagSend = false;
sprintf(logDump,"Error on HttpSendRequestEx %lu %s",GetLastError(),szFile);
WriteLog(mLogFile,logDump);
break;
}
else
{
bErrorFlag = false;
sprintf(logDump,"HttpSendRequest success %s",szFile);
WriteLog(mLogFile,logDump);
}
DWORD sum = 0;
int size = 0;
do
{
bRead = ReadFile (hFile, pBuffer,iFileSize,
&dwBytesRead, NULL);
if(dwBytesRead != iFileSize)
{
sprintf(logDump,"dwBytesRead %d iFileSize %d %s",dwBytesRead,iFileSize,szFile);
WriteLog(mLogFile,logDump);
}
if(dwBytesRead > 0)
{
bRet=InternetWriteFile( m_hRequest, pBuffer, dwBytesRead,
&dwBytesWritten);
while(dwBytesRead < dwBytesWritten && bRet)
{
sprintf(logDump,"dwBytesRead %d dwBytesWritten %d %s",dwBytesRead,dwBytesWritten,szFile);
WriteLog(mLogFile,logDump);
bRet=InternetWriteFile( m_hRequest, pBuffer+dwBytesWritten, dwBytesRead - dwBytesWritten ,&dwBytesWritten);
}
if(!bRet)
{
int error = GetLastError();
sprintf(logDump,"InternetWriteFile %lu %s",error,szFile);
WriteLog(mLogFile,logDump);
bErrorFlag = true;
break;
}
else
{
sprintf(logDump,"InternetWriteFile buffer success %s",szFile);
WriteLog(mLogFile,logDump);
bErrorFlag = false;
}
}
}
while (dwBytesRead == iFileSize);
CloseHandle (hFile);
if(!HttpEndRequest(m_hRequest, NULL, 0, 0))
{
int error = GetLastError();
if(error != 12032)
{
sprintf(logDump,"HttpEndRequest %lu %s",error,szFile);
WriteLog(mLogFile,logDump)
bErrorFlag = true;
break;
}
else
{
bErrorFlag = true;
continue;
}
}
else
{
sprintf(logDump,"HttpEndRequest success %s",szFile);
WriteLog(mLogFile,logDump);
DWORD dwCode, dwCodeSize;
dwCodeSize = sizeof(DWORD);
if(!HttpQueryInfo(m_hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwCodeSize, NULL))
{
int error = GetLastError();
char tmp[256];
sprintf(tmp,"HttpQueryfails %d %s",error, szFile);
WriteLog(mLogFile,tmp);
}
else
{
if(dwCode != 201 && dwCode != 204)
{
char tmp[256];
sprintf(tmp,"dwcode %d is not 201 or 204 %s",dwCode,szFile);
WriteLog(mLogFile,tmp);
bErrorFlag = true;
break;
}
}
bErrorFlag = false;
break;
}
}
CloseHTTPSession();
return bErrorFlag;
}
Most of the times chunks uploaded are of full size. Randomly chunks uploaded on server are not of full size as shown in following image.
sample image
In such case I am not getting any error messages, even dwBytesWritten returned by InternetWriteFile function is also correct. I am unable to understand what should I do to solve it. Any help in this regard is appreciated.

Is it possible to have 2 WinSock servers on 2 different ports?

i have a quick question, i have 1 tcp proxy server wich helps me redirect data from 1 port to another, ie: 55500 to 55510, now i want to make the server to listen to another port, let`s say 55520, all this at the same time, is it possible?
I have tried examples found here to bind to another port, but maybe i am doing something wrong :(
I have tried to create a IOCP server after i startup the proxy server, but it crashes... any ideas? or maybe a example? Any help would be apreciated!
This is my proxytcp:
#include "ProxyTCP.h"
#include <process.h>
#include "GInclude.h"
using namespace std;
CProxyTCP::CProxyTCP() :
_guid(0),
_started(false),
_hevent_start(NULL),
_hevent_stop(NULL),
_serv_sock(INVALID_SOCKET),
_connect_callback(NULL),
_connect_param(NULL),
_close_callback(NULL),
_close_param(NULL),
_send_callback(NULL),
_send_param(NULL),
_recv_callback(NULL),
_recv_param(NULL)
{
InitializeCriticalSection(&_csect);
InitializeCriticalSection(&_csect_dbg);
}
CProxyTCP::~CProxyTCP()
{
Stop();
DeleteCriticalSection(&_csect);
DeleteCriticalSection(&_csect_dbg);
}
bool CProxyTCP::Start(const char *src_addr, unsigned short src_port, const char *dest_addr, unsigned short dest_port)
{
sockaddr_in addr = {};
int res;
if (_started) {
_DBG_OUTPUT("Error, server already started!");
return false;
}
RemoveAllConnInfo();
_removed_conn.clear();
_hthr_pool.clear();
if (!CreateSockAddr(src_addr, src_port, &addr)) {
_DBG_OUTPUT("Error, incorrect source address");
return false;
}
if (!dest_addr || !CreateSockAddr(dest_addr, dest_port, &_serv_addr)) {
_DBG_OUTPUT("Error, incorrect destination address");
return false;
}
_serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_serv_sock == INVALID_SOCKET) {
_DBG_OUTPUT("Error, socket() failed with code " << WSAGetLastError());
return false;
}
res = bind(_serv_sock, (sockaddr *)&addr, sizeof(addr));
if (res == SOCKET_ERROR) {
_DBG_OUTPUT("Error, bind() failed with code " << WSAGetLastError());
closesocket(_serv_sock);
return false;
}
_hevent_start = CreateEvent(NULL, true, false, NULL);
if (!_hevent_start) {
_DBG_OUTPUT("Error, CreateEvent() failed with code " << GetLastError());
closesocket(_serv_sock);
return false;
}
_hevent_stop = CreateEvent(NULL, true, true, NULL);
if (!_hevent_start) {
_DBG_OUTPUT("Error, CreateEvent() failed with code " << GetLastError());
CloseHandle(_hevent_start);
closesocket(_serv_sock);
return false;
}
_started = true;
_beginthreadex(NULL, 0, proxy_conn_gate, this, 0, NULL);
if (WaitForSingleObject(_hevent_start, 10000) != WAIT_OBJECT_0) {
_DBG_OUTPUT("Error, WaitForSingleObject() failed");
Stop();
return false;
}
return true;
}
void CProxyTCP::Stop()
{
bool retn = false;
HANDLE *pthr_pool;
unsigned int count;
EnterCriticalSection(&_csect);
if (!_started) {
retn = true;
} else {
_started = false;
}
LeaveCriticalSection(&_csect);
if (retn) {
return;
}
if (_serv_sock != INVALID_SOCKET) {
closesocket(_serv_sock);
_serv_sock = INVALID_SOCKET;
}
WaitForSingleObject(_hevent_stop, INFINITE);
EnterCriticalSection(&_csect);
count = _hthr_pool.size() * 2;
if (count != 0) {
try {
pthr_pool = new HANDLE[count];
} catch (...) {
pthr_pool = NULL;
}
map<unsigned int, std::pair<HANDLE, HANDLE>>::iterator it = _hthr_pool.begin();
for (unsigned int i = 0; i < count; i += 2, it++) {
pthr_pool[i] = it->second.first;
pthr_pool[i + 1] = it->second.second;
}
list<PProxy_Client>::iterator it_conn = _conn.begin();
PProxy_Client pelem;
for (unsigned int i = 0; i < _conn.size(); i++, it_conn++) {
pelem = *it_conn;
closesocket(pelem->client);
closesocket(pelem->server);
}
}
LeaveCriticalSection(&_csect);
if (count == 0) {
return;
}
if (pthr_pool == NULL) {
Sleep(2000); //hmm...
} else {
WaitForMultipleObjects(count, pthr_pool, true, 2000);
}
RemoveAllConnInfo();
}
bool CProxyTCP::IsStarted()
{
return _started;
}
void CProxyTCP::RegConnectFilter(tcp_proxy_connect_filter callback, void *param)
{
_connect_callback = callback;
_connect_param = param;
}
void CProxyTCP::UnregConnectFilter()
{
_connect_callback = NULL;
_connect_param = NULL;
}
void CProxyTCP::RegCloseFilter(tcp_proxy_close_filter callback, void *param)
{
_close_callback = callback;
_close_param = param;
}
void CProxyTCP::UnregCloseFilter()
{
_close_callback = NULL;
_close_param = NULL;
}
void CProxyTCP::RegSendFilter(tcp_proxy_traffic_filter callback, void *param)
{
_send_callback = callback;
_send_param = param;
}
void CProxyTCP::UnregSendFilter()
{
_send_callback = NULL;
_send_param = NULL;
}
void CProxyTCP::RegRecvFilter(tcp_proxy_traffic_filter callback, void *param)
{
_recv_callback = callback;
_recv_param = param;
}
void CProxyTCP::UnregRecvFilter()
{
_recv_callback = NULL;
_recv_param = NULL;
}
bool CProxyTCP::CreateSockAddr(const char *addr, unsigned short port, sockaddr_in *psaddr)
{
psaddr->sin_family = AF_INET;
psaddr->sin_port = htons(port);
if (!addr) {
psaddr->sin_addr.s_addr = 0;
} else {
psaddr->sin_addr.s_addr = inet_addr(addr);
if (psaddr->sin_addr.s_addr == INADDR_NONE) {
HOSTENT *host;
host = gethostbyname(addr);
if (!host) {
return false;
}
psaddr->sin_addr.s_addr = host->h_addr[0];
}
}
return true;
}
unsigned int CProxyTCP::AddConnInfo(SOCKET client)
{
PProxy_Client pelem = new Proxy_Client;
EnterCriticalSection(&_csect);
__try {
pelem->id = GenGuid();
pelem->client = client;
pelem->server = INVALID_SOCKET;
pelem->client_init = false;
pelem->server_init = false;
pelem->started = false;
pelem->hevent_init = CreateEvent(NULL, false, false, NULL);
if (!pelem->hevent_init) {
delete pelem;
return INVALID_CONN_ID;
}
pelem->hevent_sync = CreateEvent(NULL, false, false, NULL);
if (!pelem->hevent_sync) {
CloseHandle(pelem->hevent_init);
delete pelem;
return INVALID_CONN_ID;
}
_conn.push_back(pelem);
} __finally {
LeaveCriticalSection(&_csect);
}
return pelem->id;
}
CProxyTCP::PProxy_Client CProxyTCP::GetFreeClientConnInfo()
{
list<PProxy_Client>::iterator it;
PProxy_Client pelem = NULL;
EnterCriticalSection(&_csect);
it = _conn.begin();
while (it != _conn.end()) {
if ((*it)->client_init == false) {
pelem = (*it);
pelem->client_init = true;
break;
}
it++;
}
LeaveCriticalSection(&_csect);
return pelem;
}
CProxyTCP::PProxy_Client CProxyTCP::GetFreeServerConnInfo()
{
list<PProxy_Client>::iterator it;
PProxy_Client pelem = NULL;
EnterCriticalSection(&_csect);
it = _conn.begin();
while (it != _conn.end()) {
if ((*it)->server_init == false) {
pelem = (*it);
pelem->server_init = true;
break;
}
it++;
}
LeaveCriticalSection(&_csect);
return pelem;
}
bool CProxyTCP::RemoveConnInfo(unsigned int conn_id)
{
list<PProxy_Client>::iterator it;
bool res = false;
EnterCriticalSection(&_csect);
it = _conn.begin();
while (it != _conn.end()) {
if ((*it)->id == conn_id) {
(*it)->started = false;
if ((*it)->client) {
closesocket((*it)->client);
}
if ((*it)->server) {
closesocket((*it)->server);
}
if ((*it)->hevent_sync) {
SetEvent((*it)->hevent_sync);
CloseHandle((*it)->hevent_sync);
}
if ((*it)->hevent_init) {
SetEvent((*it)->hevent_init);
CloseHandle((*it)->hevent_init);
}
_conn.erase(it);
res = true;
break;
}
it++;
}
LeaveCriticalSection(&_csect);
return res;
}
void CProxyTCP::RemoveAllConnInfo()
{
list<PProxy_Client>::iterator it;
EnterCriticalSection(&_csect);
it = _conn.begin();
while (it != _conn.end()) {
(*it)->started = false;
if ((*it)->client) {
closesocket((*it)->client);
}
if ((*it)->server) {
closesocket((*it)->server);
}
if ((*it)->hevent_sync) {
SetEvent((*it)->hevent_sync);
CloseHandle((*it)->hevent_sync);
}
if ((*it)->hevent_init) {
SetEvent((*it)->hevent_init);
CloseHandle((*it)->hevent_init);
}
it++;
}
LeaveCriticalSection(&_csect);
}
void CProxyTCP::ClearClosedResources()
{
list<unsigned int>::iterator it;
EnterCriticalSection(&_csect);
it = _removed_conn.begin();
while (it != _removed_conn.end()) {
_hthr_pool.erase(*it);
it++;
}
LeaveCriticalSection(&_csect);
}
void CProxyTCP::ConnectionCtrl()
{
SOCKET client_sock = INVALID_SOCKET;
HANDLE hthr_client, hthr_server;
sockaddr_in saddr;
unsigned int id;
int res;
ResetEvent(_hevent_stop);
SetEvent(_hevent_start);
while (_started) {
res = listen(_serv_sock, SOMAXCONN);
if (res == SOCKET_ERROR) {
_DBG_OUTPUT("Error, ConnectionCtrl::listen() failed with code " << res);
break;
}
client_sock = accept(_serv_sock, (sockaddr *)&saddr, NULL);
if (client_sock == INVALID_SOCKET) {
continue;
}
id = AddConnInfo(client_sock);
if (id == INVALID_CONN_ID) {
_DBG_OUTPUT("Error, ConnectionCtrl::AddConnInfo() failed");
continue;
}
if (_connect_callback) {
if (!_connect_callback(id, &saddr, _connect_param)) {
RemoveConnInfo(id);
closesocket(client_sock);
continue;
}
}
//SOCKADDR_IN client_info = {0};
//int addrsize = sizeof(client_info);
//getpeername(client_sock, &saddr, sizeof(saddr));
// char *ip = inet_ntoa(saddr.sin_addr);
//g_Log.LogAdd(g_Colors.Gold(), "test %s", ip);
//_DBG_OUTPUT(">>>> Client #" << id << " connected");
EnterCriticalSection(&_csect);
hthr_client = (HANDLE)_beginthreadex(NULL, 0, proxy_send_gate, this, 0, NULL);
hthr_server = (HANDLE)_beginthreadex(NULL, 0, proxy_recv_gate, this, 0, NULL);
_hthr_pool.insert(
pair<unsigned int, pair<HANDLE, HANDLE>>(
id, pair<HANDLE, HANDLE>(hthr_client, hthr_server)
)
);
LeaveCriticalSection(&_csect);
ClearClosedResources();
}
SetEvent(_hevent_stop);
}
void CProxyTCP::SendCtrl(PProxy_Client client)
{
enum { MAX_BUF_LEN = 2048 };
char recvbuf[MAX_BUF_LEN];
int res;
res = WaitForSingleObject(client->hevent_sync, 10000);
if (res != WAIT_OBJECT_0) {
_DBG_OUTPUT("Error, SendCtrl::WaitForSingleObject() failed with code " << GetLastError());
return;
}
//init
/*for(ptr = _serv_addr; ptr != NULL; ptr = ptr->ai_next) {
client->server = socket(_serv_addr->ai_family, _serv_addr->ai_socktype, _serv_addr->ai_protocol);
if (client->server == INVALID_SOCKET) {
_DBG_OUTPUT("Error, SendCtrl::socket() failed with code " << WSAGetLastError());
return;
}
res = connect(client->server, ptr->ai_addr, (int)ptr->ai_addrlen);
if (res == SOCKET_ERROR) {
closesocket(client->server);
client->server = INVALID_SOCKET;
continue;
}
break;
}
if (client->server == INVALID_SOCKET) {
return;
}*/
client->server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client->server == INVALID_SOCKET) {
_DBG_OUTPUT("Error, SendCtrl::socket() failed with code " << WSAGetLastError());
return;
}
res = connect(client->server, (sockaddr *)&_serv_addr, sizeof(_serv_addr));
if (res == SOCKET_ERROR) {
_DBG_OUTPUT("Error, SendCtrl::connect() failed with code " << WSAGetLastError());
closesocket(client->server);
client->server = INVALID_SOCKET;
return;
}
client->started = true;
SetEvent(client->hevent_init);
//worked cycle
while (client->started && _started) {
res = recv(client->client, recvbuf, MAX_BUF_LEN, 0);
if (res == 0) {
break;
} else if (res < 0) {
break;
}
if (_send_callback) {
res = _send_callback(client->id, recvbuf, res, MAX_BUF_LEN, _send_param);
if (res == 0) {
break;
} else if (res < 0) {
break;
}
}
res = send(client->server, recvbuf, res, 0);
if (res == SOCKET_ERROR) {
break;
}
}
client->started = false;
closesocket(client->client);
closesocket(client->server);
WaitForSingleObject(client->hevent_sync, 10000);
if (_close_callback) {
_close_callback(client->id, _close_param);
}
EnterCriticalSection(&_csect);
_removed_conn.insert(_removed_conn.begin(), client->id);
LeaveCriticalSection(&_csect);
//_DBG_OUTPUT("<<<< Client #" << client->id << " closed");
}
void CProxyTCP::RecvCtrl(PProxy_Client client)
{
enum { MAX_BUF_LEN = 2048 };
char recvbuf[MAX_BUF_LEN];
int res;
SetEvent(client->hevent_sync);
res = WaitForSingleObject(client->hevent_init, 10000);
if (res != WAIT_OBJECT_0) {
_DBG_OUTPUT("Error, RecvCtrl::WaitForSingleObject() failed with code " << GetLastError());
return;
}
//worked cycle
while (client->started && _started) {
res = recv(client->server, recvbuf, MAX_BUF_LEN, 0);
if (res == 0) {
break;
} else if (res < 0) {
break;
}
if (_recv_callback) {
res = _recv_callback(client->id, recvbuf, res, MAX_BUF_LEN, _recv_param);
if (res == 0) {
break;
} else if (res < 0) {
break;
}
}
res = send(client->client, recvbuf, res, 0);
if (res == SOCKET_ERROR) {
break;
}
}
client->started = false;
SetEvent(client->hevent_sync);
}
unsigned int __stdcall CProxyTCP::proxy_conn_gate(void *param)
{
CProxyTCP *pthis = (CProxyTCP *)param;
pthis->ConnectionCtrl();
pthis->Stop();
_endthreadex(0);
return 0;
}
unsigned int __stdcall CProxyTCP::proxy_send_gate(void *param)
{
CProxyTCP *pthis = (CProxyTCP *)param;
PProxy_Client client;
client = pthis->GetFreeServerConnInfo();
if (!client) {
_endthreadex(1);
return 1;
}
pthis->SendCtrl(client);
pthis->RemoveConnInfo(client->id);
_endthreadex(0);
return 0;
}
unsigned int __stdcall CProxyTCP::proxy_recv_gate(void *param)
{
CProxyTCP *pthis = (CProxyTCP *)param;
PProxy_Client client;
client = pthis->GetFreeClientConnInfo();
if (!client) {
_endthreadex(1);
return 1;
}
pthis->RecvCtrl(client);
_endthreadex(0);
return 0;
}

Issue Sending text to COM Port

I have a PLC connected to one of my laptop's COM Ports and I've trying to send it a default command that returns a default response. Currently WriteFile successfully sends the 20 bit command but ReadFile doesn't read anything though there's no error.
int main(){
HANDLE hCom = CreateFile("\\\\.\\COM4",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hCom == INVALID_HANDLE_VALUE)
{
DWORD err=GetLastError();
std::cout << "Failed\n";
return 0;
}
DCB dcbConfig;
if(GetCommState(hCom, &dcbConfig))
{
dcbConfig.BaudRate = CBR_115200;
dcbConfig.ByteSize = 8;
dcbConfig.Parity = NOPARITY;
dcbConfig.StopBits = ONESTOPBIT;
dcbConfig.fBinary = TRUE;
dcbConfig.fParity = FALSE;
}
if(!SetCommState(hCom, &dcbConfig))
{
CloseHandle(hCom);
return 0;
}
COMMTIMEOUTS commTimeout;
if(GetCommTimeouts(hCom, &commTimeout))
{
commTimeout.ReadIntervalTimeout = 1;
commTimeout.ReadTotalTimeoutConstant = 1;
commTimeout.ReadTotalTimeoutMultiplier = 1;
commTimeout.WriteTotalTimeoutConstant = 1;
commTimeout.WriteTotalTimeoutMultiplier = 1;
}
if(!SetCommTimeouts(hCom, &commTimeout))
//Handle Error Condition
CloseHandle(hCom);
// Write to the COM
static char data[22]="%01#RDD0010000107**\n";
int size = strlen(data);
DWORD dwWritten, dwReading;
int j;
WriteFile(hCom,data,(DWORD)size,&dwWritten,NULL);
DWORD err=GetLastError();
std::cout << err;
char datarecv[22];
ReadFile(hCom,&datarecv,1,&dwReading,NULL);
err = GetLastError();
std::cout << err;
std::cout << datarecv << "\n";
CloseHandle(hCom);
std::cin>>j;
return 0;
}

modem call in c++

I'm trying to make a modem call in one end, and in the other end the program answers the call. It doesn't seem to detect the carrier. Am I doing anything wrong? Am I missing something?
int main(int argc, char** argv)
{
ParseArgs(argc,argv);
SerialPort* port = SerialPort::New();
if(!port)
Error(ErrorNoMemory,"Can't create port");
int error = port->Open(PortNum, SendFlag);
if(error)
Error(error,"Can't open port");
error = port->Initialise(PortBaud);
if(error)
Error(error,"Can't initialise port");
if(ReceiveFlag)
{
port->Listen();
Receive(port); //after the call is stablished I send a file
}
else
{
port->Dial(PhoneNumber);
Send(port);
}
port->Close();
delete port;
return 0;
}
The part of opening the port:
int Open(unsigned port, bool SendFlag)
{
// make name for port...
char name[] = "\\\\.\\com???.???";
char* nameNumber = name+sizeof(name)-8;
char* nameEnd = nameNumber;
if(port>999){
return ErrorInvalidPort;
}
if(port>99)
{
*nameEnd++ = '0'+port/100;
port %= 100;
}
if(port>9)
{
*nameEnd++ = '0'+port/10;
port %= 10;
}
*nameEnd++ = '0'+port;
*nameEnd = 0;
// open port...
hSerial = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(hSerial==INVALID_HANDLE_VALUE)
{
switch(GetLastError())
{
case ERROR_FILE_NOT_FOUND:
return ErrorInvalidPort;
case ERROR_ACCESS_DENIED:
return ErrorPortInUse;
default:
return Error();
}
}
SetupComm( hSerial, 1024, 1024 );
if (!SendFlag)
{
if (!SetCommMask(hSerial, EV_RING |EV_RLSD))
// Error setting communications mask
printf("error mascara");
}
else
{
if (!SetCommMask(hSerial, EV_RLSD))
{
// Error setting communications mask
printf("error mascara");
}
}
return 0;
}
The initialise part:
int Initialise(unsigned baud)
{
// flush port...
if(!FlushFileBuffers(hSerial))
return Error();
if(!PurgeComm(hSerial, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR))
return Error();
// configure port...
DCB dcb ;
if(!GetCommState(hSerial, &dcb))
return Error();
dcb.BaudRate = CBR_115200;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
if(!SetCommState(hSerial, &dcb))
{
if(GetLastError()==ERROR_INVALID_PARAMETER)
return ErrorInvalidSettings;
return Error();
}
// set timeouts to zero so read/writes return immediately...
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier= 0;
if(!SetCommTimeouts(hSerial, &timeouts))
return Error();
// flush port again...
if(!PurgeComm(hSerial, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR))
return Error();
return 0;
}
The dial part:
int Dial(char *telefono)
{
unsigned long int n = 0;
DWORD dwCommEvent;
DWORD bytes;
DWORD dwRead;
char cadena[15];
char chRead;
sprintf(cadena, "ATDT%s\r", telefono);
if (!WriteFile( hSerial, "ATH1\r", strlen("ATH1\r"), (&(n)), 0 ))
{
printf("error");
}
FlushFileBuffers( hSerial );
Sleep(1000);
if (!WriteFile( hSerial, cadena, strlen(cadena), (&(n)), 0))
{
printf("error");
}
FlushFileBuffers( hSerial );
Sleep(10000);
printf("Marcamos");
do
{
printf("Espero eventos");
if(WaitCommEvent(hSerial, &dwCommEvent, NULL))
{
if(dwCommEvent & EV_RLSD)
{
printf("rlsd");
break;
}
else
{
printf("otro");
}
}
printf("fin del bucle");
} while(true);
return 0;
}
The listening part:
int Listen()
{
DWORD dwCommEvent;
unsigned long int n = 0;
do
{
printf("ESpero eventos");
if(WaitCommEvent(hSerial, &dwCommEvent, NULL))
{
if(dwCommEvent & EV_RING)
{
printf("RING");
if (!WriteFile( hSerial, "ATA\r", strlen("ATA\r"), (&(n)), 0 ))
{
printf("error");
}
FlushFileBuffers( hSerial );
break;
}
else if (dwCommEvent & EV_RLSD )
{
break;
}
}
printf("fin del bucle");
} while(true);
return 0;
}
You might have an easier time of it using Microsoft's Telephony API (TAPI) rather than trying to talk to the modem directly.
You may want to try issuing an ATS0=1 on the receiving side and let the modem autoanswer (substitute the number of rings you want instead of 1 if you wish).
You may discover that smart modems don't always pass through the ring (EV_RING) signal.
EDIT: Don't forget to 'ATS0=0' when you don't want the modem to auto-answer any more.
Maybe you need to apply the A0 and / or S0=1 Hayes command on the answering side.