/********************************************************************************* * Copyright: (C) 2021 Guo Wenxue * All rights reserved. * * Filename: comport.c * Description: This file used to do ioctl() on common device or communicate * with serial port/TTY device. * * Version: 1.0.0(5/1/2021~) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "5/1/2021 10:08:05 AM" * ********************************************************************************/ #include #include #include #include "comport.h" unsigned char g_stop = 0; unsigned char g_CtrlZ; void print_version(char *name); void usage(char *name); void signal_handler(int i_sig); void stdin_nonblock(void); int kbhit(void); int main(int argc, char **argv) { int opt = 0; int rv = 0; int i; comport_t comport; int baudrate = 115200; char *settings = "8N1N"; char *dev_name = NULL; char buf[512]; unsigned char disp_mode = 0x00; struct sigaction sigact; struct option long_options[] = { {"device", required_argument, NULL, 'd'}, {"baudrate", required_argument, NULL, 'b'}, {"settings", required_argument, NULL, 's'}, {"hex", no_argument, NULL, 'x'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((opt = getopt_long(argc, argv, "d:b:s:vh", long_options, NULL)) != -1) { switch (opt) { case 'd': dev_name = optarg; break; case 'b': baudrate = atoi(optarg); break; case 's': /* Default settings as 8N1N */ settings = optarg; break; case 'x': /* Display receive data as Hex mode */ disp_mode = 0x01; break; case 'v': /* version */ print_version(argv[0]); return 0; case 'h': /* help */ usage(argv[0]); return 0; default: break; } /* end of "switch(opt)" */ } if (argc < 2) { usage(argv[0]); return 0; } if ( (rv=comport_open(&comport, dev_name, baudrate, settings)) < 0) { printf("Failed to open %s wth baudrate %d, %s. rv=%d\n", dev_name, baudrate, settings, rv); return -1; } stdin_nonblock(); /* Process level signal handler */ sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigact.sa_handler = signal_handler; sigaction(SIGTERM, &sigact, NULL); /* catch terminate signal */ sigaction(SIGINT, &sigact, NULL); /* catch interrupt signal */ sigaction(SIGSEGV, &sigact, NULL); /* catch segmentation faults */ sigaction(SIGTSTP, &sigact, NULL); /* catch ctrl+Z */ sigaction(SIGSTOP, &sigact, NULL); /* catch ctrl+Z */ while ( !g_stop ) { rv = comport_recv(&comport, buf, sizeof(buf) - 1, 10); if ( rv > 0) { for (i=0; i\n"); free(ptr); return; } void usage(char *name) { char *progname = NULL; char *ptr = NULL; ptr = strdup(name); progname = basename(ptr); printf("Usage1: comport -d [-b ][-s ] [-x]\n"); printf(" -d[device ] device name\n"); printf(" -b[baudrate] device baudrate (115200, 57600, 19200, 9600), default is 115200\n"); printf(" -s[settings] device settings as like 8N1N(default setting)\n"); printf(" - data bits: 8, 7\n"); printf(" - parity: N=None, O=Odd, E=Even, S=Space\n"); printf(" - stop bits: 1, 0\n"); printf(" - flow control: N=None, H=Hardware, S=Software, B=Both\n"); printf(" -x[hex ] display received data in hex format\n"); printf(" -v[version ] Display the program version\n"); printf(" -h[help ] Display this help information\n"); print_version(progname); free(ptr); return; } void signal_handler(int signum) { if (SIGTERM == signum || SIGINT == signum) { g_stop = 1; } else if (SIGTSTP == signum) { g_CtrlZ = 1; } } void stdin_nonblock(void) { struct termios ttystate; //get the terminal state tcgetattr(STDIN_FILENO, &ttystate); //turn off canonical mode ttystate.c_lflag &= ~ICANON; //minimum of number input read. ttystate.c_cc[VMIN] = 1; //set the terminal attributes. tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); } int kbhit(void) { struct timeval tv; fd_set fds; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv); return FD_ISSET(STDIN_FILENO, &fds); }