DVX_GUI/proxy/sockShim.c

99 lines
2.2 KiB
C

// Socket shim — rs232-compatible API over TCP sockets
#include "sockShim.h"
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
// ========================================================================
// Internal state
// ========================================================================
#define MAX_PORTS 4
static int sFds[MAX_PORTS] = { -1, -1, -1, -1 };
static bool sOpen[MAX_PORTS] = { false, false, false, false };
// ========================================================================
// Public functions (alphabetical)
// ========================================================================
int rs232Close(int com) {
if (com < 0 || com >= MAX_PORTS) {
return RS232_ERR_INVALID_PORT;
}
sOpen[com] = false;
// Socket lifecycle is managed by the caller, not the shim
return RS232_SUCCESS;
}
int rs232Open(int com, int32_t bps, int dataBits, char parity, int stopBits, int handshake) {
(void)bps;
(void)dataBits;
(void)parity;
(void)stopBits;
(void)handshake;
if (com < 0 || com >= MAX_PORTS) {
return RS232_ERR_INVALID_PORT;
}
if (sFds[com] < 0) {
return RS232_ERR_NOT_OPEN;
}
sOpen[com] = true;
return RS232_SUCCESS;
}
int rs232Read(int com, char *data, int len) {
if (com < 0 || com >= MAX_PORTS || sFds[com] < 0) {
return 0;
}
ssize_t n = recv(sFds[com], data, len, MSG_DONTWAIT);
if (n <= 0) {
return 0;
}
return (int)n;
}
int rs232Write(int com, const char *data, int len) {
if (com < 0 || com >= MAX_PORTS || sFds[com] < 0) {
return RS232_ERR_NOT_OPEN;
}
int sent = 0;
while (sent < len) {
ssize_t n = send(sFds[com], data + sent, len - sent, MSG_NOSIGNAL);
if (n < 0) {
if (errno == EINTR) {
continue;
}
return RS232_ERR_NOT_OPEN;
}
sent += (int)n;
}
return RS232_SUCCESS;
}
void sockShimSetFd(int com, int fd) {
if (com < 0 || com >= MAX_PORTS) {
return;
}
sFds[com] = fd;
// Set non-blocking so rs232Read returns immediately when empty
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}