/**************************************************************************** * examples/flowc/flowc_receiver.c * * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name Gregory Nutt nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "flowc.h" /**************************************************************************** * Public Data ****************************************************************************/ static char g_tty_devname[MAX_DEVNAME] = CONFIG_EXAMPLES_FLOWC_RECEVER_DEVNAME; static char g_expected = 0x20; static unsigned int g_nerrors; static unsigned long g_count; /**************************************************************************** * Private Functions ****************************************************************************/ static inline void check_buffer(FAR uint8_t *buf, size_t buflen) { unsigned long count; FAR uint8_t *ptr; size_t i; int ch; /* Verfiy the buffer content */ ch = g_expected; for (i = 0, ptr = buf, count = g_count; i < buflen; i++, ptr++, count++) { if (*ptr != ch) { printf("receiver: ERROR: Expected %c (%02x), found %c (%02x) at count=%lu\n", isprint(ch) ? ch : '.', ch, isprint(*ptr) ? *ptr : '.', *ptr, count); g_nerrors++; ch = *ptr; } if (++ch > 0x7e) { ch = 0x20; } } /* Update globals */ g_expected = ch; if (g_expected > 0x7e) { g_expected = 0x20; } g_count = count; } /**************************************************************************** * flowc_cmdline ****************************************************************************/ static int flowc_cmdline(int argc, char **argv) { /* Currently only a single command line option is supported: The receiver * IP address. */ if (argc == 2) { strncpy(g_tty_devname, argv[1], MAX_DEVNAME); } else if (argc != 1) { fprintf(stderr, "ERROR: Too many arguments\n"); fprintf(stderr, "USAGE: %s []\n", argv[0]); return 1; } return 0; } /**************************************************************************** * Public Functions ****************************************************************************/ int flowc_receiver(int argc, char **argv) { uint8_t inbuf[CONFIG_EXAMPLES_FLOWC_RECEIVER_BUFSIZE]; #ifdef CONFIG_EXAMPLES_FLOWC_INPUT struct termios term; #endif ssize_t nread; int ret; int fd; /* Parse the command line */ ret = flowc_cmdline(argc, argv); if (ret != 0) { return ret; } /* Open the serial device */ fd = open(g_tty_devname, O_RDONLY); if (fd < 0) { printf("sender ERROR: Failed to open %s: %d\n", g_tty_devname, errno); return 1; } #ifdef CONFIG_EXAMPLES_FLOWC_INPUT /* Set input flow control */ tcgetattr(fd, &term); #ifdef CRTS_IFLOW term.c_cflag |= CRTS_IFLOW; #else term.c_cflag |= CRTSCTS; #endif tcsetattr(fd, TCSANOW, &term); #endif /* Then receive until all data has been received correctly (possibly * hanging if data is lost). */ while (g_count < TOTALSIZE) { nread = read(fd, inbuf, CONFIG_EXAMPLES_FLOWC_RECEIVER_BUFSIZE); if (nread < 0) { printf("receiver: %lu. recv failed: %d\n", g_count, errno); close(fd); return 1; } check_buffer(inbuf, nread); if (g_nerrors > 25) { printf("receiver: %lu. Too many errors: %u\n", g_count, g_nerrors); close(fd); return 1; } #if defined(CONFIG_EXAMPLES_FLOWC_RECEIVER_DELAY) && \ CONFIG_EXAMPLES_FLOWC_RECEIVER_DELAY > 0 /* Delay to force flow control */ usleep(1000 * CONFIG_EXAMPLES_FLOWC_RECEIVER_DELAY); #endif #ifdef CONFIG_SYSLOG_INTBUFFER /* Just to force a flush of syslog interrupt buffer. May also provide * a handy indication that the test is still running. */ syslog(LOG_INFO, "."); #endif } close(fd); return 0; }