Files
BCIgui/Masterarbeit/openvibe/sdk-master/modules/socket/src/IConnectionParallel.cpp
T
2021-10-14 13:47:35 +02:00

262 lines
6.1 KiB
C++

#include "IConnectionParallel.h"
#if defined TARGET_OS_Windows
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
#include <sys/ioctl.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/errno.h>
#else
#error "Unsupported platform"
#endif
#if defined TARGET_OS_Linux && !defined TARGET_OS_Android
#include <linux/ppdev.h>
#include <linux/parport.h>
#endif
#include <assert.h>
namespace Socket {
class CConnectionParallel final : public IConnectionParallel
{
protected:
unsigned short m_portNumber;
std::string m_lastError;
public:
CConnectionParallel()
#if defined TARGET_OS_Linux || defined TARGET_OS_MacOS
:m_file(0)
#endif
{
#if defined TARGET_OS_Windows
m_portNumber = 0;
m_port = LoadLibrary(TEXT("TVicPort.dll"));
if (m_port != nullptr)
{
m_isDriverOpened = port_is_driver_opened_t(GetProcAddress(m_port, "IsDriverOpened"));
m_portOpen = port_open_t(GetProcAddress(m_port, "OpenTVicPort"));
m_portClose = port_close_t(GetProcAddress(m_port, "CloseTVicPort"));
m_portWrite = port_write_t(GetProcAddress(m_port, "WritePort"));
if (!m_isDriverOpened || !m_portOpen || !m_portClose || !m_portWrite)
{
m_lastError = "Cannot load function from TVicPort.dll: " + this->getLastErrorFormated();
this->release();
}
}
else { m_lastError = "Cannot found or open TVicPort.dll: " + this->getLastErrorFormated(); }
#endif
}
bool open() override
{
// Should never be used
return false;
}
bool close() override
{
#if defined TARGET_OS_Windows
if (m_port != nullptr)
{
if (m_isDriverOpened())
{
m_portNumber = 0;
m_portClose();
return true;
}
m_lastError = "Cannot close the TVicPort library because it is not opened.";
return false;
}
return false;
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
return false;
/*if (ioctl(fd, PPRELEASE) < 0) { return false; }
if (close(m_file) < 0) { return false; }
else
{
m_file = -1;
}*/
#endif
}
bool isReadyToSend(const size_t /*timeOut*/ = 0) const override { return this->isConnected(); }
bool isReadyToReceive(const size_t /*timeOut*/ = 0) const override { return this->isConnected(); }
size_t getPendingByteCount() const { return (this->isConnected() ? 0 : 1); }
size_t sendBuffer(const void* buffer, const size_t size = 8) override
{
if (!this->isConnected()) { return 0; }
#if defined TARGET_OS_Windows
const uint8_t value = *(static_cast<const uint8_t*>(buffer));
m_portWrite(m_portNumber, value);
return size;
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
return 0;
/*if (ioctl(m_file, PPWDATA, &value) < 0) { return size; }*/
#endif
}
size_t receiveBuffer(void* /*buffer*/, const size_t /*size*/ = 8) override
{
if (!this->isConnected()) { return 0; }
#if defined TARGET_OS_Windows
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
/*
unsigned char valin;
int dirin=1;
int dirout=0;
if (ioctl (fd, PPDATADIR, &dirin) < 0) { return 0; }
if (ioctl(fd, PPRDATA, &valin) < 0) { return 0; }
int res = ::read(m_file, buffer, size);
if(res < 0)
{
this->close();
return 0;
}
return res;
*/
#endif
return 0;
}
bool sendBufferBlocking(const void* buffer, const size_t size) override
{
const char* p = reinterpret_cast<const char*>(buffer);
size_t bytesLeft = size;
while (bytesLeft != 0 && this->isConnected()) { bytesLeft -= this->sendBuffer(p + size - bytesLeft, bytesLeft); }
return this->isConnected();
}
bool receiveBufferBlocking(void* buffer, const size_t size) override
{
char* p = reinterpret_cast<char*>(buffer);
size_t bytesLeft = size;
while (bytesLeft != 0 && this->isConnected()) { bytesLeft -= this->receiveBuffer(p + size - bytesLeft, bytesLeft); }
return this->isConnected();
}
#if defined TARGET_OS_Windows
bool isConnected() const override { return m_portNumber != 0; }
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
bool isConnected() const override { return m_file != 0; }
#endif
void release() override
{
#if defined TARGET_OS_Windows
if (m_port != nullptr && !FreeLibrary(m_port)) { m_lastError = getLastErrorFormated(); }
#endif
delete this;
}
bool connect(const unsigned short portNumber) override
{
if (this->isConnected()) { return false; }
#if defined TARGET_OS_Windows
if (m_port != nullptr)
{
if (m_portOpen())
{
m_lastError = "No error";
m_portNumber = portNumber;
return true;
}
m_lastError = "Cannot open the TVic library";
m_portNumber = 0;
return false;
}
m_lastError = "TVicPort library is not loaded.";
return false;
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
return false;
/*
std::string url = "/dev/parport" + std::to_string(portNumber);
if ((m_file = open(url.c_str() , O_RDWR)) < 0)
{
this->close();
return false;
}
else
{
if (ioctl(m_file, PPCLAIM) < 0)
{
this->close();
return false;
}
}
*/
#endif
}
std::string getLastError() override { return m_lastError; }
std::string getLastErrorFormated()
{
#if defined TARGET_OS_Windows
LPTSTR errorText;
const DWORD error = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM // use system message tables to retrieve error text
| FORMAT_MESSAGE_ALLOCATE_BUFFER // allocate buffer on local heap for error text
| FORMAT_MESSAGE_IGNORE_INSERTS, // Important! will fail otherwise, since we're not (and CANNOT) pass insertion parameters
nullptr, // unused with FORMAT_MESSAGE_FROM_SYSTEM
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
LPTSTR(&errorText), // output
0, // minimum size for output buffer
nullptr); // arguments - see note
return errorText + std::to_string(static_cast<uint64_t>(error));
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
return "Not implemented.";
#endif
}
#if defined TARGET_OS_Linux || defined TARGET_OS_MacOS
int m_file;
#endif
};
IConnectionParallel* createConnectionParallel() { return new CConnectionParallel(); }
} // namespace Socket