From 65d551e4f113d07a76c3eda3434c6fea84f0ad19 Mon Sep 17 00:00:00 2001 From: Grigory Kletsko Date: Sun, 4 Jun 2017 01:01:17 +0300 Subject: [support] Add netevent utility --- .../netevent/0001-fix-endian-for-cross-arch.patch | 113 ++++ .../netevent/netevent/0002-fix-cross-compile.patch | 70 +++ .../0003-use-socket-instead-of-stdout.patch | 653 +++++++++++++++++++++ ...-keep-alive-to-handle-peer-death-properly.patch | 162 +++++ .../recipes-support/netevent/netevent_git.bb | 29 + 5 files changed, 1027 insertions(+) create mode 100644 meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch create mode 100644 meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch create mode 100644 meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch create mode 100644 meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch create mode 100644 meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch new file mode 100644 index 0000000..e984447 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch @@ -0,0 +1,113 @@ +From d9e02e86cacb6771381c4cde45f6badd71ec01cf Mon Sep 17 00:00:00 2001 +From: Andrey Gusakov +Date: Tue, 13 Sep 2016 15:51:33 +0300 +Subject: [PATCH 1/2] fix endian for cross-arch + + +Signed-off-by: Andrey Gusakov +--- + reader.cpp | 21 +++++++++++++++------ + write.cpp | 21 ++++++++++++++++----- + 2 files changed, 31 insertions(+), 11 deletions(-) + +diff --git a/reader.cpp b/reader.cpp +index ab047bd..651967a 100644 +--- a/reader.cpp ++++ b/reader.cpp +@@ -3,9 +3,18 @@ + #include + #include + #include ++#include + #include + #include + ++int64_t htonll(int64_t value){ ++ int num = 42; ++ if(*(char *)&num == 42) //test big/little endian ++ return (((int64_t)htonl(value)) << 32) + htonl(value >> 32); ++ else ++ return value; ++} ++ + static bool running = true; + bool on = true; + static int fd = 0; +@@ -159,7 +168,7 @@ int read_device(const char *devfile) + + // First thing to write is the size of the structures as a 16 bit uint! + uint16_t strsz; +- strsz = sizeof(dev); ++ strsz = htons(sizeof(dev)); + if (!cout.write((const char*)&strsz, sizeof(strsz))) + exit(1); + if (cout.eof()) +@@ -272,11 +281,11 @@ int read_device(const char *devfile) + } + else if (on) { + input_event_t et; +- et.tv_sec = ev.time.tv_sec; +- et.tv_usec = ev.time.tv_usec; +- et.type = ev.type; +- et.code = ev.code; +- et.value = ev.value; ++ et.tv_sec = htonll(ev.time.tv_sec); ++ et.tv_usec = htonl(ev.time.tv_usec); ++ et.type = htons(ev.type); ++ et.code = htons(ev.code); ++ et.value = htonl(ev.value); + if (!cout.write((const char*)&et, sizeof(et))) + exit(1); + if (cout.eof()) +diff --git a/write.cpp b/write.cpp +index 7d58bf6..91c956c 100644 +--- a/write.cpp ++++ b/write.cpp +@@ -1,9 +1,18 @@ + #include "main.h" + #include + #include ++#include + #include + #include + ++int64_t ntohll(int64_t value){ ++ int num = 42; ++ if(*(char *)&num == 42) //test big/little endian ++ return value; ++ else ++ return (((int64_t)ntohl(value)) << 32) + ntohl(value >> 32); ++} ++ + static const char *uinput_file[] = { + "/dev/uinput", + "/dev/input/uinput", +@@ -35,6 +44,7 @@ int spawn_device() + struct input_event ev; + + cin.read((char*)&strsz, sizeof(strsz)); ++ strsz = ntohs(strsz); + if (strsz != sizeof(uinput_user_dev)) { + cerr << "Device information field sizes do not match. Sorry." << endl; + return 1; +@@ -126,11 +136,12 @@ int spawn_device() + cerr << "End of data" << endl; + break; + } +- ev.time.tv_sec = et.tv_sec; +- ev.time.tv_usec = et.tv_usec; +- ev.type = et.type; +- ev.code = et.code; +- ev.value = et.value; ++ ev.time.tv_sec = ntohll(et.tv_sec); ++ ev.time.tv_usec = ntohl(et.tv_usec); ++ ev.type = ntohs(et.type); ++ ev.code = ntohs(et.code); ++ ev.value = ntohl(et.value); ++ //cErr << "EV " << ev.time.tv_sec << "." << ev.time.tv_usec << ": type " << ev.type << ", code " << ev.code << ", value " << ev.value << endl; + if (hotkey_hook(ev.type, ev.code, ev.value)) + continue; + if (write(fd, &ev, sizeof(ev)) < (ssize_t)sizeof(ev)) { +-- +1.7.10.4 + diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch new file mode 100644 index 0000000..cca70ba --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch @@ -0,0 +1,70 @@ +From 7b30e567552535d9546e34d4fc38337095347224 Mon Sep 17 00:00:00 2001 +From: Andrey Gusakov +Date: Tue, 13 Sep 2016 15:51:55 +0300 +Subject: [PATCH 2/2] fix cross-compile + + +Signed-off-by: Andrey Gusakov +--- + Makefile | 19 ++++++++++--------- + reader.cpp | 1 + + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/Makefile b/Makefile +index 02d25c7..9bbe82e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,14 +1,15 @@ +-prefix = /usr/local +-bindir = $(prefix)/bin +-CXX = g++ +-CC = gcc +-CFLAGS = -Wall -pthread +-LDFLAGS = -g -pthread ++PREFIX ?= /usr ++SBINDIR ?= $(PREFIX)/bin ++CXX ?= g++ ++CC ?= gcc ++CFLAGS += -Wall -pthread ++LDFLAGS += -g ++LIBS = -lpthread + + SOURCES = main.cpp reader.cpp write.cpp showev.cpp + + ifneq ($(inotify),no) +- CFLAGS += -DWITH_INOTIFY ++ GCC_FLAGS += -DWITH_INOTIFY + endif + + all: build netevent devname +@@ -23,13 +24,13 @@ build/%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $*.c -MMD -MF build/$*.d -MT $@ + + netevent: $(patsubst %.cpp,build/%.o,$(SOURCES)) +- $(CXX) $(LDFLAGS) -o $@ $^ ++ $(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) + + devname: build/devname.o + $(CC) -o $@ $^ + + install: all +- install -m 755 -p -t "$(DESTDIR)$(bindir)" netevent devname ++ install -m 755 -p -t "$(DESTDIR)$(SBINDIR)" netevent devname + + clean: + -rm -rf build +diff --git a/reader.cpp b/reader.cpp +index 651967a..07fa64a 100644 +--- a/reader.cpp ++++ b/reader.cpp +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + int64_t htonll(int64_t value){ + int num = 42; +-- +1.7.10.4 + diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch new file mode 100644 index 0000000..4fb3039 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch @@ -0,0 +1,653 @@ +From 68944103c94f4957c2dbc0d246bf1360d28bd5b4 Mon Sep 17 00:00:00 2001 +From: Andrey Gusakov +Date: Wed, 14 Sep 2016 18:16:47 +0300 +Subject: [PATCH] use socket instead of stdout + +--- + main.cpp | 16 +++--- + reader.cpp | 181 +++++++++++++++++++++++++++++++++++++------------------------ + write.cpp | 139 ++++++++++++++++++++++++++++++++++++----------- + 3 files changed, 226 insertions(+), 110 deletions(-) + +diff --git a/main.cpp b/main.cpp +index da512b0..e695328 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -9,15 +9,15 @@ bool no_grab = false; + bool count_syn = false; + bool be_quiet = false; + +-int read_device(const char *devname); +-int spawn_device(); ++int read_device(const char *devname, const char *hostname, int port); ++int spawn_device(int port); + int show_events(int count, const char *devname); + + static void usage(const char *arg0) + { + size_t len = strlen(arg0); +- cerr << "usage: " << arg0 << " [options] -read " << endl; +- cerr << " " << std::string(len, ' ') << " -write" << endl; ++ cerr << "usage: " << arg0 << " [options] -read " << endl; ++ cerr << " " << std::string(len, ' ') << " -write " << endl; + cerr << " " << std::string(len, ' ') << " [options] -showevents " << endl; + cerr << "options are:" << endl; + cerr << " -ontoggle Command to execute when grabbing is toggled." << endl; +@@ -53,12 +53,14 @@ int main(int argc, char **argv) + usage(arg0); + } + else if (command == "-read") { +- if (argc < 3) ++ if (argc < 5) + usage(arg0); +- return read_device(argv[2]); ++ return read_device(argv[2], argv[3], atoi(argv[4])); + } + else if (command == "-write") { +- return spawn_device(); ++ if (argc < 3) ++ usage(arg0); ++ return spawn_device(atoi(argv[2])); + } + else if (command == "-toggler") { + if (argc < 3) +diff --git a/reader.cpp b/reader.cpp +index 07fa64a..0b6de20 100644 +--- a/reader.cpp ++++ b/reader.cpp +@@ -3,10 +3,14 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include ++#include ++#include + + int64_t htonll(int64_t value){ + int num = 42; +@@ -50,26 +54,26 @@ static void *tog_func(void *ign) + #if !defined( WITH_INOTIFY ) + struct stat st; + if (lstat(toggle_file, &st) != 0) { +- cErr << "stat failed on " << toggle_file << ": " << err << endl; ++ fprintf(stderr, "stat failed on %s, %d\n", toggle_file, errno); + tog_on = false; + } + else + { + if (!S_ISFIFO(st.st_mode)) { +- cerr << "The toggle file is not a fifo, and inotify support has not been compiled in." << endl; +- cerr << "This is evil, please compile with inotify support." << endl; ++ fprintf(stderr, "The toggle file is not a fifo, and inotify support has not been compiled in.\n"); ++ fprintf(stderr, "This is evil, please compile with inotify support.\n"); + tog_on = false; + } + } + #else + inf_fd = inotify_init(); + if (inf_fd == -1) { +- cErr << "inotify_init failed: " << err << endl; ++ fprintf(stderr, "inotify_init failed: %d\n"); + tog_on = false; + } else { + watch_fd = inotify_add_watch(inf_fd, toggle_file, IN_CLOSE_WRITE | IN_CREATE); + if (watch_fd == -1) { +- cErr << "inotify_add_watch failed: " << err << endl; ++ fprintf(stderr, "inotify_add_watch failed: %d\n", err); + tog_on = false; + } + } +@@ -79,17 +83,17 @@ static void *tog_func(void *ign) + #if defined( WITH_INOTIFY ) + inotify_event iev; + if (read(inf_fd, &iev, sizeof(iev)) != (ssize_t)sizeof(iev)) { +- cErr << "Failed to read from inotify watch: " << err << endl; ++ fprintf(stderr, "Failed to read from inotify watch: %d\n", err); + break; + } + if (iev.wd != watch_fd) { +- cerr << "Inotify sent is bogus information..." << endl; ++ fprintf(stderr, "Inotify sent is bogus information...\n"); + continue; + } + #endif + tfd = open(toggle_file, O_RDONLY); + if (tfd < 0) { +- cErr << "Failed to open '" << toggle_file << "': " << err << endl; ++ fprintf(stderr, "Failed to open '%s', %d\n", toggle_file, errno); + break; + } + memset(dat, 0, sizeof(dat)); +@@ -110,22 +114,58 @@ static void *tog_func(void *ign) + static void toggle_hook() + { + if (ioctl(fd, EVIOCGRAB, (on ? (void*)1 : (void*)0)) == -1) { +- cErr << "Grab failed: " << err << endl; ++ fprintf(stderr, "Grab failed: %d\n", errno); + } + setenv("GRAB", (on ? "1" : "0"), -1); +- if (toggle_cmd) { ++ if (toggle_cmd) { + if (!fork()) { + execlp("sh", "sh", "-c", toggle_cmd, NULL); +- cErr << "Failed to run command: " << err << endl; +- exit(1); ++ fprintf(stderr, "Failed to run command: %d\n", errno); ++ exit(1); + } + +- } ++ } ++} ++ ++int socket_open(const char *hostname, int port) ++{ ++ int ret; ++ int sockfd; ++ struct sockaddr_in serv_addr; ++ struct hostent *server; ++ ++ printf("connecting to %s:%d\n", hostname, port); ++ ++ sockfd = socket(AF_INET, SOCK_STREAM, 0); ++ if (sockfd < 0) { ++ fprintf(stderr, "ERROR opening socket\n"); ++ return sockfd; ++ } ++ ++ server = gethostbyname(hostname); ++ if (server == NULL) { ++ fprintf(stderr, "ERROR, no such host\n"); ++ return -1; ++ } ++ ++ bzero((char *) &serv_addr, sizeof(serv_addr)); ++ serv_addr.sin_family = AF_INET; ++ bcopy((char *)server->h_addr, ++ (char *)&serv_addr.sin_addr.s_addr, ++ server->h_length); ++ serv_addr.sin_port = htons(port); ++ ret = connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR connecting %d, %d\n", ret, errno); ++ return ret; ++ } ++ return sockfd; + } + +-int read_device(const char *devfile) ++int read_device_new(const char *devfile, const char *hostname, int port) + { + struct input_event ev; ++ int sock_fd; + size_t i; + ssize_t s; + //int e = 0; +@@ -136,14 +176,13 @@ int read_device(const char *devfile) + + if (fd < 0) { + std::string err(strerror(errno)); +- cerr << "Failed to open device '" << devfile << "': " << err << endl; ++ fprintf(stderr, "Failed to open device '%s', %d\n", devfile, errno); + return 1; + } + + if (on) { + if (ioctl(fd, EVIOCGRAB, (void*)1) == -1) { +- std::string err(strerror(errno)); +- cerr << "Failed to grab device: " << err << endl; ++ fprintf(stderr, "Failed to grab device: %d\n", errno); + } + setenv("GRAB", "1", -1); + } +@@ -154,59 +193,54 @@ int read_device(const char *devfile) + memset(&dev, 0, sizeof(dev)); + + if (ioctl(fd, EVIOCGNAME(sizeof(dev.name)), dev.name) == -1) { +- cErr << "Failed to get device name: " << err << endl; ++ fprintf(stderr, "Failed to get device name: %d\n", errno); + goto error; + } + + if (ioctl(fd, EVIOCGID, &dev.id) == -1) { +- cErr << "Failed to get device id: " << err << endl; ++ fprintf(stderr, "Failed to get device id: %d\n", errno); + goto error; + } + +- cerr << " Device: " << dev.name << endl; +- cerr << " Id: " << dev.id.version << endl; +- cerr << "BusType: " << dev.id.bustype << endl; ++ fprintf(stderr, " Device: %s\n", dev.name); ++ fprintf(stderr, " Id: %d\n", dev.id.version); ++ fprintf(stderr, "BusType: %d\n", dev.id.bustype); ++ ++ sock_fd = socket_open(hostname, port); ++ if (sock_fd < 0) ++ goto error; + + // First thing to write is the size of the structures as a 16 bit uint! + uint16_t strsz; + strsz = htons(sizeof(dev)); +- if (!cout.write((const char*)&strsz, sizeof(strsz))) +- exit(1); +- if (cout.eof()) +- exit(0); +- +- if (!cout.write(dev.name, sizeof(dev.name))) +- exit(1); +- if (cout.eof()) +- exit(0); +- if (!cout.write((const char*)&dev.id, sizeof(dev.id))) +- exit(1); +- if (cout.eof()) +- exit(0); +- +- cerr << "Getting input bits." << endl; ++ if (!write(sock_fd, (const char*)&strsz, sizeof(strsz))) ++ goto err_close; ++ ++ if (!write(sock_fd, dev.name, sizeof(dev.name))) ++ goto err_close; ++ ++ if (!write(sock_fd, (const char*)&dev.id, sizeof(dev.id))) ++ goto err_close; ++ ++ fprintf(stderr, "Getting input bits.\n"); + if (ioctl(fd, EVIOCGBIT(0, sizeof(input_bits)), &input_bits) == -1) { +- cErr << "Failed to get input-event bits: " << err << endl; ++ fprintf(stderr, "Failed to get input-event bits: %d\n", errno); + goto error; + } +- if (!cout.write((const char*)input_bits, sizeof(input_bits))) +- exit(1); +- if (cout.eof()) +- exit(0); ++ if (!write(sock_fd, (const char*)input_bits, sizeof(input_bits))) ++ goto err_close; + + #define TransferBitsFor(REL, rel, REL_MAX) \ + do { \ + if (testbit(input_bits, EV_##REL)) { \ + unsigned char bits##rel[1+REL_MAX/8]; \ +- cerr << "Getting " #rel "-bits." << endl; \ ++ fprintf(stderr, "Getting " #rel "-bits.\n"); \ + if (ioctl(fd, EVIOCGBIT(EV_##REL, sizeof(bits##rel)), bits##rel) == -1) { \ +- cErr << "Failed to get " #rel " bits: " << err << endl; \ ++ fprintf(stderr, "Failed to get " #rel " bits: %d\n", errno); \ + goto error; \ + } \ +- if (!cout.write((const char*)&bits##rel, sizeof(bits##rel))) \ +- exit(1); \ +- if (cout.eof()) \ +- exit(0); \ ++ if (!write(sock_fd, (const char*)&bits##rel, sizeof(bits##rel))) \ ++ goto err_close; \ + } \ + } while(0) + +@@ -220,16 +254,14 @@ int read_device(const char *devfile) + #define TransferDataFor(KEY, key, KEY_MAX) \ + do { \ + if (testbit(input_bits, EV_##KEY)) { \ +- cerr << "Getting " #key "-state." << endl; \ ++ fprintf(stderr, "Getting " #key "-state.\n"); \ + unsigned char bits##key[1+KEY_MAX/8]; \ + if (ioctl(fd, EVIOCG##KEY(sizeof(bits##key)), bits##key) == -1) { \ +- cErr << "Failed to get " #key " state: " << err << endl; \ ++ fprintf(stderr, "Failed to get " #key " state: %d\n", errno); \ + goto error; \ + } \ +- if (!cout.write((const char*)bits##key, sizeof(bits##key))) \ +- exit(1); \ +- if (cout.eof()) \ +- exit(0); \ ++ if (!write(sock_fd, (const char*)bits##key, sizeof(bits##key))) \ ++ goto err_close; \ + } \ + } while(0) + +@@ -239,39 +271,35 @@ int read_device(const char *devfile) + + if (testbit(input_bits, EV_ABS)) { + struct input_absinfo ai; +- cerr << "Getting abs-info." << endl; ++ fprintf(stderr, "Getting abs-info.\n"); + for (i = 0; i < ABS_MAX; ++i) { + if (ioctl(fd, EVIOCGABS(i), &ai) == -1) { +- cErr << "Failed to get device id: " << err << endl; ++ fprintf(stderr, "Failed to get device id: %d\n", errno); + goto error; + } +- if (!cout.write((const char*)&ai, sizeof(ai))) +- exit(1); +- if (cout.eof()) +- exit(0); ++ if (!write(sock_fd, (const char*)&ai, sizeof(ai))) ++ goto err_close; + } + } + +- cout.flush(); +- + if (toggle_file) { + if (pthread_create(&tog_thread, 0, &tog_func, 0) != 0) { +- cErr << "Failed to create toggling-thread: " << err << endl; ++ fprintf(stderr, "Failed to create toggling-thread: %d\n", errno); + goto error; + } + } + +- cerr << "Transferring input events." << endl; ++ fprintf(stderr, "Transferring input events.\n"); + while (running) { + int dummy; + waitpid(0, &dummy, WNOHANG); + s = read(fd, &ev, sizeof(ev)); + if (!s) { +- cerr << "EOF" << endl; ++ fprintf(stderr, "EOF\n"); + break; + } + else if (s < 0) { +- cErr << "When reading from device: " << err << endl; ++ fprintf(stderr, "When reading from device: %d\n", errno); + goto error; + } + +@@ -282,20 +310,22 @@ int read_device(const char *devfile) + } + else if (on) { + input_event_t et; ++ ++ //fprintf(stderr, "EV %d.%06d: type %d, code %d, value %d\n", ++ // (int)ev.time.tv_sec, (int)ev.time.tv_usec, (int)ev.type, ev.code, ev.value); + et.tv_sec = htonll(ev.time.tv_sec); + et.tv_usec = htonl(ev.time.tv_usec); + et.type = htons(ev.type); + et.code = htons(ev.code); + et.value = htonl(ev.value); +- if (!cout.write((const char*)&et, sizeof(et))) +- exit(1); +- if (cout.eof()) +- exit(0); +- cout.flush(); ++ if (!write(sock_fd, (const char*)&et, sizeof(et))) ++ goto err_close; + } + } + + goto end; ++err_close: ++ close(sock_fd); + error: + //e = 1; + end: +@@ -306,3 +336,12 @@ end: + + return 0; + } ++ ++int read_device(const char *devfile, const char *hostname, int port) ++{ ++ while (1) { ++ read_device_new(devfile, hostname, port); ++ sleep(1); ++ } ++ return 0; ++} +\ No newline at end of file +diff --git a/write.cpp b/write.cpp +index 91c956c..dc6c3bc 100644 +--- a/write.cpp ++++ b/write.cpp +@@ -1,9 +1,13 @@ + #include "main.h" + #include + #include ++#include + #include + #include ++#include + #include ++#include ++#include + + int64_t ntohll(int64_t value){ + int num = 42; +@@ -22,12 +26,55 @@ static const size_t uinput_cnt = sizeof(uinput_file) / sizeof(uinput_file[0]); + + static uint16_t strsz; + +-int spawn_device() ++int socket_start_listen(int port) ++{ ++ int ret; ++ int sockfd; ++ struct sockaddr_in serv_addr; ++ ++ printf("starting on port %d\n", port); ++ ++ sockfd = socket(AF_INET, SOCK_STREAM, 0); ++ if (sockfd < 0) { ++ fprintf(stderr, "ERROR opening socket %d", sockfd); ++ return sockfd; ++ } ++ bzero((char *) &serv_addr, sizeof(serv_addr)); ++ serv_addr.sin_family = AF_INET; ++ serv_addr.sin_addr.s_addr = INADDR_ANY; ++ serv_addr.sin_port = htons(port); ++ ret = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on binding %d", ret); ++ return ret; ++ } ++ listen(sockfd, 1); ++ return sockfd; ++} ++ ++int socket_wait_connection(int sockfd) ++{ ++ int newsockfd; ++ struct sockaddr_in cli_addr; ++ socklen_t clilen; ++ ++ clilen = sizeof(cli_addr); ++ newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); ++ if (newsockfd < 0) { ++ fprintf(stderr, "ERROR on accept %d", newsockfd); ++ return newsockfd; ++ } ++ return newsockfd; ++} ++ ++int spawn_device_new(int sock_con) + { + int e; + int fd; +- size_t i; ++ int i; + ssize_t si; ++ struct uinput_user_dev dev; ++ struct input_event ev; + + for (i = 0; i < uinput_cnt; ++i) { + fd = open(uinput_file[i], O_WRONLY | O_NDELAY); +@@ -36,30 +83,28 @@ int spawn_device() + } + + if (i >= uinput_cnt) { +- cerr << "Failed to open uinput device file. Please specify." << endl; ++ fprintf(stderr, "Failed to open uinput device file. Please specify.\n"); + return 1; + } + +- struct uinput_user_dev dev; +- struct input_event ev; +- +- cin.read((char*)&strsz, sizeof(strsz)); ++ read(sock_con, (char*)&strsz, sizeof(strsz)); + strsz = ntohs(strsz); + if (strsz != sizeof(uinput_user_dev)) { +- cerr << "Device information field sizes do not match. Sorry." << endl; +- return 1; ++ fprintf(stderr, "Device information field sizes do not match (%d != %d). Sorry.\n", ++ strsz, (int)sizeof(uinput_user_dev)); ++ goto err_close; + } + + memset(&dev, 0, sizeof(dev)); +- cin.read((char*)dev.name, sizeof(dev.name)); +- cin.read((char*)&dev.id, sizeof(dev.id)); ++ read(sock_con, dev.name, sizeof(dev.name)); ++ read(sock_con, &dev.id, sizeof(dev.id)); + +- cin.read((char*)input_bits, sizeof(input_bits)); ++ read(sock_con, input_bits, sizeof(input_bits)); + for (i = 0; i < EV_MAX; ++i) { + if (!testbit(input_bits, i)) + continue; + if (ioctl(fd, UI_SET_EVBIT, i) == -1) { +- cErr << "Failed to set evbit " << i << ": " << err << endl; ++ fprintf(stderr, "Failed to set evbit %d, %d\n", i, errno); + goto error; + } + } +@@ -68,13 +113,13 @@ int spawn_device() + do { \ + if (testbit(input_bits, EV_##REL)) { \ + unsigned char bits##rel[1+REL_MAX/8]; \ +- cerr << "Reading " #rel "-bits" << endl; \ +- cin.read((char*)bits##rel, sizeof(bits##rel)); \ ++ fprintf(stderr, "Reading " #rel "-bits\n"); \ ++ read(sock_con, (char*)bits##rel, sizeof(bits##rel)); \ + for (i = 0; i < REL_MAX; ++i) { \ + if (!testbit(bits##rel, i)) continue; \ + if (ioctl(fd, UI_SET_##RELBIT, i) == -1) { \ +- cErr << "Failed to set " #rel "-bit: " << i << ": " << err << endl; \ +- goto error; \ ++ fprintf(stderr, "Failed to set " #rel "-bit: %d, %d\n", i, errno); \ ++ goto err_close; \ + } \ + } \ + } \ +@@ -91,13 +136,13 @@ int spawn_device() + do { \ + if (testbit(input_bits, EV_##KEY)) { \ + unsigned char bits##key[1+KEY_MAX/8]; \ +- cerr << "Reading " #key "-data" << endl; \ +- cin.read((char*)bits##key, sizeof(bits##key)); \ ++ fprintf(stderr, "Reading " #key "-data\n"); \ ++ read(sock_con, (char*)bits##key, sizeof(bits##key)); \ + for (i = 0; i < KEY_MAX; ++i) { \ + if (!testbit(bits##key, i)) continue; \ + if (ioctl(fd, UI_SET_##KEYBIT, i) == -1) { \ +- cErr << "Failed to activate " #key "-bit: " << i << ": " << err << endl; \ +- goto error; \ ++ fprintf(stderr, "Failed to activate " #key "-bit: %d, %d\n", i, errno); \ ++ goto err_close; \ + } \ + } \ + } \ +@@ -110,7 +155,7 @@ int spawn_device() + if (testbit(input_bits, EV_ABS)) { + struct input_absinfo ai; + for (i = 0; i < ABS_MAX; ++i) { +- cin.read((char*)&ai, sizeof(ai)); ++ read(sock_con, (char*)&ai, sizeof(ai)); + dev.absmin[i] = ai.minimum; + dev.absmax[i] = ai.maximum; + } +@@ -118,22 +163,22 @@ int spawn_device() + + si = write(fd, &dev, sizeof(dev)); + if (si < (ssize_t)sizeof(dev)) { +- cErr << "Failed to write initial data to device: " << err << endl; +- goto error; ++ fprintf(stderr, "Failed to write initial data to device: %d\n", errno); ++ goto err_close; + } + + if (ioctl(fd, UI_DEV_CREATE) == -1) { +- cErr << "Failed to create device: " << err << endl; +- goto error; ++ fprintf(stderr, "Failed to create device: %d\n", errno); ++ goto err_close; + } + +- cerr << "Transferring input events." << endl; ++ fprintf(stderr, "Transferring input events.\n"); + while (true) { + input_event_t et; + int dummy; + waitpid(0, &dummy, WNOHANG); +- if (!cin.read((char*)&et, sizeof(et))) { +- cerr << "End of data" << endl; ++ if (!read(sock_con, (char*)&et, sizeof(et))) { ++ fprintf(stderr, "End of data\n"); + break; + } + ev.time.tv_sec = ntohll(et.tv_sec); +@@ -141,16 +186,21 @@ int spawn_device() + ev.type = ntohs(et.type); + ev.code = ntohs(et.code); + ev.value = ntohl(et.value); +- //cErr << "EV " << ev.time.tv_sec << "." << ev.time.tv_usec << ": type " << ev.type << ", code " << ev.code << ", value " << ev.value << endl; ++ //fprintf(stderr, "EV %d.%06d: type %d, code %d, value %d\n", ++ // (int)ev.time.tv_sec, (int)ev.time.tv_usec, (int)ev.type, ev.code, ev.value); + if (hotkey_hook(ev.type, ev.code, ev.value)) + continue; + if (write(fd, &ev, sizeof(ev)) < (ssize_t)sizeof(ev)) { +- cErr << "Write error: " << err << endl; +- goto error; ++ fprintf(stderr, "Write error: %d\n", errno); ++ goto err_close; + } + } + + goto end; ++ ++err_close: ++ if (sock_con > 0) ++ close(sock_con); + error: + e = 1; + end: +@@ -159,3 +209,28 @@ end: + + return e; + } ++ ++int spawn_device(int port) ++{ ++ int ret; ++ int sock_listen, sock_con; ++ printf("...%d\n", port); ++ ++ sock_listen = socket_start_listen(port); ++ if (sock_listen < 0) ++ return sock_listen; ++ ++ printf("Got connection on port %d\n", port); ++ while(1) { ++ sock_con = socket_wait_connection(sock_listen); ++ if (sock_con < 0) ++ goto err_close; ++ ret = spawn_device_new(sock_con); ++ printf("connection closed %d\n", ret); ++ sleep(1); ++ } ++ return 0; ++err_close: ++ close(sock_listen); ++ return -1; ++} +\ No newline at end of file +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch new file mode 100644 index 0000000..f84f113 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch @@ -0,0 +1,162 @@ +From 0d797dca82a714688657523a89a14c37ae7767cf Mon Sep 17 00:00:00 2001 +From: Grigory Kletsko +Date: Wed, 5 Oct 2016 22:15:25 +0300 +Subject: [PATCH] Add TCP keep alive to handle peer death properly + +--- + reader.cpp | 32 +++++++++++++++++++++++++++++++- + write.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 75 insertions(+), 3 deletions(-) + +diff --git a/reader.cpp b/reader.cpp +index 0b6de20..e1a26e3 100644 +--- a/reader.cpp ++++ b/reader.cpp +@@ -11,6 +11,8 @@ + #include + #include + #include ++#include ++#include + + int64_t htonll(int64_t value){ + int num = 42; +@@ -131,6 +133,8 @@ int socket_open(const char *hostname, int port) + { + int ret; + int sockfd; ++ int val; ++ + struct sockaddr_in serv_addr; + struct hostent *server; + +@@ -159,6 +163,32 @@ int socket_open(const char *hostname, int port) + fprintf(stderr, "ERROR connecting %d, %d\n", ret, errno); + return ret; + } ++ ++ val = 5; ++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ ++ val = 1; ++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ ++ val = 1; ++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ ++ + return sockfd; + } + +@@ -344,4 +374,4 @@ int read_device(const char *devfile, const char *hostname, int port) + sleep(1); + } + return 0; +-} +\ No newline at end of file ++} +diff --git a/write.cpp b/write.cpp +index dc6c3bc..67ce412 100644 +--- a/write.cpp ++++ b/write.cpp +@@ -8,6 +8,9 @@ + #include + #include + #include ++#include ++#include ++#include + + int64_t ntohll(int64_t value){ + int num = 42; +@@ -30,6 +33,8 @@ int socket_start_listen(int port) + { + int ret; + int sockfd; ++ int val; ++ + struct sockaddr_in serv_addr; + + printf("starting on port %d\n", port); +@@ -48,7 +53,41 @@ int socket_start_listen(int port) + fprintf(stderr, "ERROR on binding %d", ret); + return ret; + } ++ ++ val = 1; ++ ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ ++ val = 5; ++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ ++ val = 1; ++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ ++ val = 1; ++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ fprintf(stderr, "ERROR on setsockopt %d", ret); ++ return ret; ++ } ++ + listen(sockfd, 1); ++ + return sockfd; + } + +@@ -174,10 +213,13 @@ int spawn_device_new(int sock_con) + + fprintf(stderr, "Transferring input events.\n"); + while (true) { ++ int ret; + input_event_t et; + int dummy; + waitpid(0, &dummy, WNOHANG); +- if (!read(sock_con, (char*)&et, sizeof(et))) { ++ ret = read(sock_con, (char*)&et, sizeof(et)); ++ ++ if (ret <= 0) { + fprintf(stderr, "End of data\n"); + break; + } +@@ -233,4 +275,4 @@ int spawn_device(int port) + err_close: + close(sock_listen); + return -1; +-} +\ No newline at end of file ++} +-- +2.7.4 + diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb b/meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb new file mode 100644 index 0000000..7dde8f5 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb @@ -0,0 +1,29 @@ +SUMMARY = "netevent - share input devices over net" +SECTION = "misc" + +LICENSE = "CLOSED" + +PN = "netevent" +PE = "1" +PV = "0.1" +PR = "r1" + +SRC_URI = "git://github.com/Blub/netevent.git \ + file://0001-fix-endian-for-cross-arch.patch \ + file://0002-fix-cross-compile.patch \ + file://0003-use-socket-instead-of-stdout.patch \ + file://0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch \ +" + +SRCREV = "06f1fe545f2063ae882fc8b66dc07f1ced85d1da" + +S = "${WORKDIR}/git" + +B = "${S}" + +do_install() { + install -d ${D}${bindir} + + install -m 0755 netevent ${D}${bindir}/ + install -m 0755 devname ${D}${bindir}/ +} -- cgit 1.2.3-korg