New file |
| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2021 Guo Wenxue <guowenxue@gmail.com> |
| | | * 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 <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "5/1/2021 10:08:05 AM" |
| | | * |
| | | ********************************************************************************/ |
| | | #include <getopt.h> |
| | | #include <libgen.h> |
| | | #include <sys/ioctl.h> |
| | | |
| | | #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<rv ; i++) |
| | | { |
| | | if (0 == disp_mode) |
| | | printf("%c", buf[i]); |
| | | else |
| | | printf("%02X ", buf[i]); |
| | | } |
| | | fflush(stdout); |
| | | } |
| | | if (0 != kbhit()) |
| | | { |
| | | rv = fgetc(stdin); |
| | | |
| | | if (0x0A == rv) |
| | | { |
| | | buf[0] = 0x0D; /* 13 == 0x0D */ |
| | | } |
| | | else |
| | | { |
| | | buf[0] = rv; |
| | | } |
| | | |
| | | comport_send(&comport, buf, 1); |
| | | } |
| | | else if (0x00 != g_CtrlZ) |
| | | { |
| | | g_CtrlZ = 0x00; |
| | | buf[0] = 0x1A; |
| | | comport_send(&comport, buf, 1); |
| | | } |
| | | } |
| | | |
| | | comport_close(&comport); |
| | | return 0; |
| | | } /* ----- End of main() ----- */ |
| | | |
| | | |
| | | void print_version(char *name) |
| | | { |
| | | char *progname = NULL; |
| | | char *ptr = NULL; |
| | | |
| | | ptr = strdup(name); |
| | | progname = basename(ptr); |
| | | |
| | | printf("%s v1.0.0 Build on %s\n", progname, __DATE__); |
| | | printf("Copyright (C) 2021 guowenxue <guowenxue@gmail.com>\n"); |
| | | |
| | | free(ptr); |
| | | return; |
| | | } |
| | | |
| | | void usage(char *name) |
| | | { |
| | | char *progname = NULL; |
| | | char *ptr = NULL; |
| | | |
| | | ptr = strdup(name); |
| | | progname = basename(ptr); |
| | | printf("Usage1: comport -d <device> [-b <baudrate>][-s <settings>] [-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); |
| | | } |
| | | |
| | | |