timer/serial_forwarder.c
2024-06-22 17:51:55 -05:00

184 lines
3.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <errno.h>
#include <stdbool.h>
#include <libserialport.h>
#include "bufsize.h"
#define PORT 4321
#define SERIALPORT "/dev/ttyS0"
int sp_error(const char * s, enum sp_return result)
{
char * error_message;
switch (result) {
case SP_ERR_ARG:
printf("%s: error: Invalid argument.\n", s);
case SP_ERR_FAIL:
error_message = sp_last_error_message();
printf("%s: error: Failed: %s\n", error_message, s);
sp_free_error_message(error_message);
case SP_ERR_SUPP:
printf("%s: error: Not supported.\n", s);
case SP_ERR_MEM:
printf("%s: error: Couldn't allocate memory.\n", s);
case SP_OK: [[fallthrough]];
default:
return result;
}
}
int init_serial(struct sp_port * port)
{
enum sp_return sp_ret;
sp_ret = sp_get_port_by_name(SERIALPORT, &port);
if (sp_ret != SP_OK) {
sp_error("sp_get_port_by_name", sp_ret);
return -1;
}
sp_ret = sp_open(port, SP_MODE_READ_WRITE);
if (sp_ret != SP_OK) {
sp_error("sp_open", sp_ret);
return -1;
}
sp_ret = sp_set_baudrate(port, 1200);
if (sp_ret != SP_OK) {
sp_error("sp_set_baudrate", sp_ret);
return -1;
}
sp_ret = sp_set_bits(port, 8);
if (sp_ret != SP_OK) {
sp_error("sp_set_bits", sp_ret);
return -1;
}
sp_ret = sp_set_parity(port, SP_PARITY_NONE);
if (sp_ret != SP_OK) {
sp_error("sp_set_parity", sp_ret);
return -1;
}
sp_ret = sp_set_stopbits(port, 1);
if (sp_ret != SP_OK) {
sp_error("sp_set_stopbits", sp_ret);
return -1;
}
sp_ret = sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE);
if (sp_ret != SP_OK) {
sp_error("sp_set_flowcontrol", sp_ret);
return -1;
}
}
int handle_sock(int sock)
{
struct sockaddr_in src_addr;
socklen_t addrlen = (sizeof (struct sockaddr_in));
char buf[BUFSIZE];
while (true) {
ssize_t recv_len = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *)&src_addr, &addrlen);
if (recv_len == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
perror("eagain");
return 0;
} else {
perror("recvfrom");
return -1;
}
}
printf("got %ld data\n", recv_len);
printf("Received packet from %s:%d\n", inet_ntoa(src_addr.sin_addr), ntohs(src_addr.sin_port));
buf[recv_len] = 0;
printf("Data: %s\n", buf);
}
}
struct receiver_state {
uint64_t seq;
uint64_t ack_seq;
};
int main(void)
{
int ret;
int sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
if (sock == -1) {
perror("socket");
return -1;
}
struct sockaddr_in sockaddr = {0};
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(PORT);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sock, (struct sockaddr *)&sockaddr, (sizeof (struct sockaddr_in)));
if (ret == -1) {
perror("bind");
return -1;
}
#define MAX_EVENTS 2
struct epoll_event events[MAX_EVENTS];
int epollfd = epoll_create1(0);
if (epollfd == -1) {
perror("epoll_create1");
return -1;
}
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = sock;
ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev);
if (ret == -1) {
perror("epoll_ctl: sock");
return -1;
}
while (1) {
printf("Wait for datagram\n");
int nfds = epoll_wait(epollfd, events, MAX_EVENTS, 1000);
if (nfds == -1) {
perror("epoll_wait");
return -1;
}
for (int n = 0; n < nfds; ++n) {
if (events[n].data.fd == sock) {
ret = handle_sock(sock);
if (ret == -1)
return -1;
}
}
/*
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(1234);
dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = sendto(sock, buf, 3, 0, (struct sockaddr *)&dest_addr, (sizeof (struct sockaddr_in)));
if (ret == -1) {
perror("sendto()");
}
*/
//sleep(2);
}
close(sock);
return 0;
}