init
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user