/*****************************************************************************\
*   This program is free software; you can redistribute it and/or modify      *
*   it under the terms of the GNU General Public License as published by      *
*   the Free Software Foundation; either version 2 of the License, or         *
*   (at your option) any later version.                                       *
*                                                                             *
*   This program is distributed in the hope that it will be useful,           *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*   GNU General Public License for more details.                              *
*                                                                             *
*   You should have received a copy of the GNU General Public License         *
*   along with this program; if not, write to the Free Software Foundation,   *
*   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.            *
\*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>


int fd = 0;

void SetRTS(int fd)
/* Setzt RTS auf ON */
  {
  int currstat;
  ioctl(fd, TIOCMGET, &currstat);
  currstat |= TIOCM_RTS;
  ioctl(fd, TIOCMSET, &currstat);
  }

void ResetRTS(int fd)
/* Setzt RTS auf OFF */
  {
  int currstat;
  ioctl(fd, TIOCMGET, &currstat);
  currstat &= ~TIOCM_RTS;
  ioctl(fd, TIOCMSET, &currstat);
  }

void SetDTR(int fd)
/* Setzt DTR auf ON */
  {
  int currstat;
  ioctl(fd, TIOCMGET, &currstat);
  currstat |= TIOCM_DTR;
  ioctl(fd, TIOCMSET, &currstat);
  }

void ResetDTR(int fd)
/* Setzt DTR auf OFF */
  {
  int currstat;
  ioctl(fd, TIOCMGET, &currstat);
  currstat &= ~TIOCM_DTR;
  ioctl(fd, TIOCMSET, &currstat);
  }

void ClearSerPins(int fd)
/* Setzt alle Pins der Schnittstelle auf OFF */
  {
  int currstat = 0;
  ioctl(fd, TIOCMSET, &currstat);
  }

int GetRI(int fd)
/* Gibt 1 zurueck, wenn RI gesetzt ist, sonst 0 */
  {
  int  currstat;
  ioctl(fd, TIOCMGET, &currstat);
  return((currstat & TIOCM_RNG)?1:0);
  }

int GetCD(int fd)
/* Gibt 1 zurueck, wenn CD gesetzt ist, sonst 0 */
  {
  int  currstat;
  ioctl(fd, TIOCMGET, &currstat);
  return((currstat & TIOCM_CAR)?1:0);
  }

int GetDSR(int fd)
/* Gibt 1 zurueck, wenn DSR gesetzt ist, sonst 0 */
  {
  int  currstat;
  ioctl(fd, TIOCMGET, &currstat);
  return((currstat & TIOCM_DSR)?1:0);
  }

int GetCTS(int fd)
/* Gibt 1 zurueck, wenn CTS gesetzt ist, sonst 0 */
  {
  int  currstat;
  ioctl(fd, TIOCMGET, &currstat);
  return((currstat & TIOCM_CTS)?1:0);
  }

int GetSerStat(int fd)
/* Gibt den kompletten seriellenStatus zurueck *
 * ggf. RTS und DTR ausblenden:                *
 * currstat &= ~(TIOCM_DTR | TOICM_RTS)        */
  {
  int  currstat;
  ioctl(fd, TIOCMGET, &currstat);
  return(currstat);
  }


int main(int argc, char** argv)
{
  int i, stat;

  /* Parameterprüfung: Das zu verwendende Device muss  */
  /* als erster Parameter angegeben werden.            */
  if(argc != 2)
    {
      printf("Fehler: Ungültige Parameter-Anzahl.\n");
      printf("Aufruf: serpin <device>\n");
      return 1;
    }

  /* Das Device öffnen */
  if((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0)
    {
      printf("Fehler: Device \"%s\" kann nicht geöffnet werden.\n", argv[1]);
      return 2;
    }

  /* alles loeschen */
  ClearSerPins(fd);
  /* mit RTS und DTR blinken */
  for(i=0; i<5; i++)
    {
    usleep(300000);
    SetRTS(fd);
    usleep(300000);
    ResetRTS(fd);
    usleep(300000);
    SetDTR(fd);
    usleep(300000);
    ResetDTR(fd);
    }
/* Status abfragen, bis RI gesetzt wird */
  while(!GetRI(fd))
    {
    stat = GetSerStat(fd);
    printf("%6X  ",stat);
    printf("+%d+ ",GetCTS(fd));
    if (stat & TIOCM_RNG) puts("RI ");
    if (stat & TIOCM_CAR) puts("CD ");
    if (stat & TIOCM_DSR) puts("DSR ");
    if (stat & TIOCM_CTS) puts("CTS ");
    printf("\n");
    sleep(1);
    }
  close(fd);

  return 0;
  }
