+ sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == -1) {
+ perror("socket");
+ exit(1);
+ }
+
+ int one = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
+ perror("setsockopt");
+ exit(1);
+ }
+
+ memset(&saddr6, 0, sizeof(saddr6));
+ saddr6.sin6_family = AF_INET6;
+ if (argc >= 2) {
+ if (inet_pton(AF_INET6, argv[1], &saddr6.sin6_addr) != 1) {
+ fprintf(stderr, "Invalid address '%s'\n", argv[1]);
+ exit(1);
+ }
+ } else {
+ inet_pton(AF_INET6, "::1", &saddr6.sin6_addr);
+ }
+
+ int port = 6000;
+ if (argc >= 3) {
+ port = atoi(argv[2]);
+ }
+ saddr6.sin6_port = htons(port);
+
+ const char *serialpath = "/dev/ttyUSB0";
+ if (argc >= 4) {
+ serialpath = argv[3];
+ }
+ int serialfd = open(serialpath, O_RDWR);
+ if (serialfd == -1) {
+ perror(serialpath);
+ exit(1);
+ }
+
+ struct termios options;
+ memset(&options, 0, sizeof(options));
+ options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
+ options.c_iflag = IGNBRK | IGNPAR;
+ options.c_lflag = 0;
+ options.c_cc[VMIN] = 1; // Blocking read, minimum one byte.
+ tcsetattr(serialfd, TCSANOW, &options);