105 lines
2.4 KiB
C
105 lines
2.4 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 -1;
|
|
}
|
|
|
|
ssize_t n = recv(sFds[com], data, len, MSG_DONTWAIT);
|
|
if (n < 0) {
|
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
if (n == 0) {
|
|
return -1;
|
|
}
|
|
|
|
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);
|
|
}
|