184 lines
3.9 KiB
C
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;
|
|
}
|