Guest User

Untitled

a guest
Dec 15th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.39 KB | None | 0 0
  1. #include <termios.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <sys/signal.h>
  6. #include <sys/types.h>
  7. #include <stdlib.h>
  8.  
  9. #define BAUDRATE B9600
  10. #define MODEMDEVICE "/dev/ttyS0"
  11. #define _POSIX_SOURCE 1         /*POSIX compliant source*/
  12. #define FALSE 0
  13. #define TRUE 1
  14.  
  15. volatile int STOP=FALSE;
  16.  
  17. void signal_handler_IO (int status);   /*definition of signal handler*/
  18. int wait_flag=TRUE;                    /*TRUE while no signal received*/
  19. char devicename[80];
  20. long Baud_Rate = 9600;         /*default Baud Rate (110 through 38400)*/
  21. long BAUD;                     /*derived baud rate from command line*/
  22. long DATABITS;
  23. long STOPBITS;
  24. long PARITYON;
  25. long PARITY;
  26. int Data_Bits = 8;              /*Number of data bits*/
  27. int Stop_Bits = 1;              /*Number of stop bits*/
  28. int Parity = 0;                 /*Parity as follows:*/
  29.          /*00 = NONE, 01 = Odd, 02 = Even, 03 = Mark, 04 = Space*/
  30. int Format = 5;
  31. FILE *input;
  32. FILE *output;
  33. int status;
  34.  
  35. int main(int Parm_Count, char *Parms[])
  36. {
  37.    char version[80] = "       POSIX compliant Communications test program version 1.00 4-25-1999\r\n";
  38.    char version1[80] = "          Copyright(C) Mark Zehner/Peter Baumann 1999\r\n";
  39.    char version2[80] = " This code is based on a DOS based test program by Mark Zehner and a Serial\r\n";
  40.    char version3[80] = " Programming POSIX howto by Peter Baumann, integrated by Mark Zehner\r\n";
  41.    char version4[80] = " This program allows you to send characters out the specified port by typing\r\n";
  42.    char version5[80] = " on the keyboard.  Characters typed will be echoed to the console, and \r\n";
  43.    char version6[80] = " characters received will be echoed to the console.\r\n";
  44.    char version7[80] = " The setup parameters for the device name, receive data format, baud rate\r\n";
  45.    char version8[80] = " and other serial port parameters must be entered on the command line \r\n";
  46.    char version9[80] = " To see how to do this, just type the name of this program. \r\n";
  47.    char version10[80] = " This program is free software; you can redistribute it and/or modify it\r\n";
  48.    char version11[80] = " under the terms of the GNU General Public License as published by the \r\n";
  49.    char version12[80] = " Free Software Foundation, version 2.\r\n";
  50.    char version13[80] = " This program comes with ABSOLUTELY NO WARRANTY.\r\n";
  51.    char instr[100] ="\r\nOn the command you must include six items in the following order, they are:\r\n";
  52.    char instr1[80] ="   1.  The device name      Ex: /dev/ttyS0 for com1, ttyS1 for com2, etc\r\n";
  53.    char instr2[80] ="   2.  Baud Rate            Ex: 9600, 19200 38400 .. 115200 \r\n";
  54.    char instr3[80] ="   3.  Number of Data Bits  Ex: 8 \r\n";
  55.    char instr4[80] ="   4.  Number of Stop Bits  Ex: 0 or 1\r\n";
  56.    char instr5[80] ="   5.  Parity               Ex: 0=none, 1=odd, 2=even\r\n";
  57.    char instr6[80] ="   6.  Format of data received:  1=hex, 2=dec, 3=hex/asc, 4=dec/asc, 5=asc\r\n";
  58.    char instr7[80] =" Example command line:  sertest /dev/ttyS0 9600 8 1 0 5\r\n";
  59.    char message[90];
  60.  
  61.    int fd, tty, res, i, error;
  62.    char In1, Key;
  63.    struct termios oldtio, newtio;   /*place for old and new port settings for serial port*/
  64.    struct termios oldkey, newkey;   /*place for old and new port settings for keyboard teletype*/
  65.    struct sigaction saio;           /*definition of signal action*/
  66.    char buf[255];                   /*buffer for where data is put*/
  67.  
  68.    input = fopen("/dev/tty", "r");  /*open the terminal keyboard*/
  69.    output = fopen("/dev/tty", "w"); /*open the terminal screen*/
  70.  
  71.    if (!input || !output)
  72.    {
  73.       fprintf(stderr, "Unable to open /dev/tty\n");
  74.       exit(1);
  75.    }
  76.  
  77.    error=0;
  78.    fputs(version,output);           /*display the program introduction*/
  79.    fputs(version1,output);
  80.    fputs(version2,output);
  81.    fputs(version3,output);
  82.    fputs(version4,output);
  83.    fputs(version5,output);
  84.    fputs(version6,output);
  85.    fputs(version7,output);
  86.    fputs(version8,output);
  87.    fputs(version9,output);
  88.    fputs(version10,output);
  89.    fputs(version11,output);
  90.    fputs(version12,output);
  91.    fputs(version13,output);
  92.    /*read the parameters from the command line*/
  93.    if (Parm_Count==7)  /*if there are the right number of parameters on the command line*/
  94.    {
  95.       i=sscanf(Parms[1],"%s",devicename);
  96.       if (i != 1) error=1;
  97.       i=sscanf(Parms[2],"%li",&Baud_Rate);
  98.       if (i != 1) error=1;
  99.       i=sscanf(Parms[3],"%i",&Data_Bits);
  100.       if (i != 1) error=1;
  101.       i=sscanf(Parms[4],"%i",&Stop_Bits);
  102.       if (i != 1) error=1;
  103.       i=sscanf(Parms[5],"%i",&Parity);
  104.       if (i != 1) error=1;
  105.       i=sscanf(Parms[6],"%i",&Format);
  106.       if (i != 1) error=1;
  107.       sprintf(message,"Device=%s, Baud=%li\r\n",devicename, Baud_Rate);
  108. /*output the received setup parameters*/
  109.       fputs(message,output);
  110.       sprintf(message,"Data Bits=%i  Stop Bits=%i  Parity=%i  Format=%i\r\n",Data_Bits, Stop_Bits, Parity, Format);
  111.       fputs(message,output);
  112.    }  /*end of if param_count==7*/
  113.    if ((Parm_Count==7) && (error==0))  /*if the command line entries were correct*/
  114.    {                                   /*run the program*/
  115.       tty = open("/dev/tty", O_RDWR | O_NOCTTY | O_NONBLOCK);
  116.       /*set the user console port up*/
  117.       tcgetattr(tty,&oldkey);
  118.       /* save current port settings so commands are interpreted right for this program*/
  119.       /* set new port settings for non-canonical input processing*/
  120.       /* must be NOCTTY*/
  121.       newkey.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  122.       newkey.c_iflag = IGNPAR;
  123.       newkey.c_oflag = 0;
  124.       newkey.c_lflag = 0;       /*ICANON;*/
  125.       newkey.c_cc[VMIN]=1;
  126.       newkey.c_cc[VTIME]=0;
  127.       tcflush(tty, TCIFLUSH);
  128.       tcsetattr(tty,TCSANOW,&newkey);
  129.  
  130.       switch (Baud_Rate)
  131.       {
  132.          case 38400:
  133.          default:
  134.             BAUD  = B38400;
  135.             break;
  136.          case 19200:
  137.             BAUD  = B19200;
  138.             break;
  139.          case 9600:
  140.             BAUD  = B9600;
  141.             break;
  142.          case 4800:
  143.             BAUD  = B4800;
  144.             break;
  145.          case 2400:
  146.             BAUD  = B2400;
  147.             break;
  148.          case 1800:
  149.             BAUD  = B1800;
  150.             break;
  151.          case 1200:
  152.             BAUD  = B1200;
  153.             break;
  154.          case 600:
  155.             BAUD  = B600;
  156.             break;
  157.          case 300:
  158.             BAUD  = B300;
  159.             break;
  160.          case 200:
  161.             BAUD  = B200;
  162.             break;
  163.          case 150:
  164.             BAUD  = B150;
  165.             break;
  166.          case 134:
  167.             BAUD  = B134;
  168.             break;
  169.          case 110:
  170.             BAUD  = B110;
  171.             break;
  172.          case 75:
  173.             BAUD  = B75;
  174.             break;
  175.          case 50:
  176.             BAUD  = B50;
  177.             break;
  178.       }  /*end of switch baud_rate*/
  179.       switch (Data_Bits)
  180.       {
  181.          case 8:
  182.          default:
  183.             DATABITS = CS8;
  184.             break;
  185.          case 7:
  186.             DATABITS = CS7;
  187.             break;
  188.          case 6:
  189.             DATABITS = CS6;
  190.             break;
  191.          case 5:
  192.             DATABITS = CS5;
  193.             break;
  194.       }  /*end of switch data_bits*/
  195.       switch (Stop_Bits)
  196.       {
  197.          case 1:
  198.          default:
  199.             STOPBITS = 0;
  200.             break;
  201.          case 2:
  202.             STOPBITS = CSTOPB;
  203.             break;
  204.       }  /*end of switch stop bits*/
  205.       switch (Parity)
  206.       {
  207.          case 0:
  208.          default:                       /*none*/
  209.             PARITYON = 0;
  210.             PARITY = 0;
  211.             break;
  212.          case 1:                        /*odd*/
  213.             PARITYON = PARENB;
  214.             PARITY = PARODD;
  215.             break;
  216.          case 2:                        /*even*/
  217.             PARITYON = PARENB;
  218.             PARITY = 0;
  219.             break;
  220.       }  /*end of switch parity*/
  221.  
  222.       /*open the device(com port) to be non-blocking (read will return immediately)*/
  223.       fd = open(devicename, O_RDWR | O_NOCTTY | O_NONBLOCK);
  224.       if (fd < 0)
  225.       {
  226.          perror(devicename);
  227.          exit(-1);
  228.       }
  229.  
  230.       /*install the serial handler before making the device asynchronous*/
  231.       saio.sa_handler = signal_handler_IO;
  232.       sigemptyset(&saio.sa_mask);   /*saio.sa_mask = 0;*/
  233.       saio.sa_flags = 0;
  234.       saio.sa_restorer = NULL;
  235.       sigaction(SIGIO,&saio,NULL);
  236.  
  237.       /* allow the process to receive SIGIO*/
  238.       fcntl(fd, F_SETOWN, getpid());
  239.       /* Make the file descriptor asynchronous (the manual page says only*/
  240.       /* O_APPEND and O_NONBLOCK, will work with F_SETFL...)*/
  241.       fcntl(fd, F_SETFL, FASYNC);
  242.  
  243.       tcgetattr(fd,&oldtio); /* save current port settings */
  244.       /* set new port settings for canonical input processing */
  245.       newtio.c_cflag = BAUD | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
  246.       newtio.c_iflag = IGNPAR;
  247.       newtio.c_oflag = 0;
  248.       newtio.c_lflag = 0;       /*ICANON;*/
  249.       newtio.c_cc[VMIN]=1;
  250.       newtio.c_cc[VTIME]=0;
  251.       tcflush(fd, TCIFLUSH);
  252.       tcsetattr(fd,TCSANOW,&newtio);
  253.  
  254.       /* loop while waiting for input. normally we would do something useful here*/
  255.       while (STOP==FALSE)
  256.       {
  257.          status = fread(&Key,1,1,input);
  258.          if (status==1)   /*if a key was hit*/
  259.          {
  260.             switch (Key)
  261.             { /* branch to appropiate key handler */
  262.                case 0x1b: /* Esc */
  263.                   STOP=TRUE;
  264.                   write(fd,&Key,1);
  265.                   break;
  266.                default:
  267.                   fputc((int) Key,output);
  268. /*                  sprintf(message,"%x ",Key);  *debug*/
  269. /*                  fputs(message,output); */
  270.                   write(fd,&Key,1);
  271.                   /*write 1 byte to the port*/
  272.                   break;
  273.             }  /*end of switch key*/
  274.          }  /*end if a key was hit*/
  275.          /* after receiving SIGIO, wait_flag = FALSE*/
  276.          /* input is available and can be read*/
  277.          if (wait_flag==FALSE)  /*if input is available*/
  278.          {
  279.             res = read(fd,buf,255);
  280.             if (res)
  281.             {
  282.                for (i=0; i<res; i++)  /*for all chars in string*/
  283.                {
  284.                   In1 = buf[i];
  285.                   switch (Format)
  286.                   {
  287.                      case 1:         /*hex*/
  288.                         sprintf(message,"%x ",In1);
  289.                         fputs(message,output);
  290.                         break;
  291.                      case 2:         /*decimal*/
  292.                         sprintf(message,"%d ",In1);
  293.                         fputs(message,output);
  294.                         break;
  295.                      case 3:         /*hex and asc*/
  296.                         if ((In1) || (In1))
  297.                         {
  298.                            sprintf(message,"%x",In1);
  299.                            fputs(message,output);
  300.                         }
  301.                         else fputc ((int) In1, output);
  302.                         break;
  303.                      case 4:         /*decimal and asc*/
  304.                      default:
  305.                         if ((In1) || (In1))
  306.                         {
  307.                            sprintf(message,"%d",In1);
  308.                            fputs(message,output);
  309.                         }
  310.                         else fputc ((int) In1, output);
  311.                         break;
  312.                      case 5:         /*asc*/
  313.                         fputc ((int) In1, output);
  314.                         break;
  315.                   }  /*end of switch format*/
  316.                }  /*end of for all chars in string*/
  317.             }  /*end if res?*/
  318. /*            buf[res]=0;*/
  319. /*            printf(":%s:%d\n", buf, res);*/
  320. /*            if (res==1) STOP=TRUE;*/
  321. /* stop loop if only a CR was input */
  322.             wait_flag = TRUE;      /* wait for new input */
  323.          }  /*end if wait flag == FALSE*/
  324.  
  325.       }  /*while stop==FALSE*/
  326.       /* restore old port settings*/
  327.       tcsetattr(fd,TCSANOW,&oldtio);
  328.       tcsetattr(tty,TCSANOW,&oldkey);
  329.       close(tty);
  330.       close(fd);        /*close the com port*/
  331.    }  /*end if command line entrys were correct*/
  332.    else  /*give instructions on how to use the command line*/
  333.    {
  334.       fputs(instr,output);
  335.       fputs(instr1,output);
  336.       fputs(instr2,output);
  337.       fputs(instr3,output);
  338.       fputs(instr4,output);
  339.       fputs(instr5,output);
  340.       fputs(instr6,output);
  341.       fputs(instr7,output);
  342.    }
  343.    fclose(input);
  344.    fclose(output);
  345.    return 0;
  346. }  /*end of main*/
  347.  
  348. /***************************************************************************
  349. * signal handler. sets wait_flag to FALSE, to indicate above loop that     *
  350. * characters have been received.                                           *
  351. ***************************************************************************/
  352.  
  353. void signal_handler_IO (int status)
  354. {
  355. /*    printf("received SIGIO signal.\n");*/
  356.    wait_flag = FALSE;
  357. }
  358.  
  359.  
  360. /*An example invocation of this program
  361.  
  362. //This program will allow a user to communicate from one computer to another using two serial lines. It is intended only as a test for the serial connection allowing any possible serial setting. This program is named com when compiled. To use it, the following is an example command line:
  363.  
  364. //com /dev/ttyS0 9600 8 1 0 5
  365.  
  366. //This line works for com1 at 9600 baud, 8 data bits. I make it a file,
  367. call it "fcom1" and put it in my system path and invoke it as a script
  368. program.*/
Add Comment
Please, Sign In to add comment