🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.os.linux.programowanie
Article #72719

tty0tty

#72719
From: Krzysiek
Date: Fri, 12 Dec 2014 10:39
291 lines
7249 bytes
Witam!

Mam potrzebę podglądnąć transmisję po rs232.
Oczywiście pierwsze co zrobiłem to szukałem odpowiednich programów,
ale z mizernym rezultatem.
Znalazłem coś takiego:
http://jpnevulator.snarl.nl/

ale niestety to u mnie nie działa.
Tzn. mam urządzenie podpięte do portu z którym się normalnie dogaduję
z programu na PC i którego transmisję chcę podglądnąć, ale po
uruchomieniu powyższego już transmisja pada i urządzenia się nie
dogadują w ogóle.

Znalazłem jeszcze dwie możliwości tzn. socat i tty0tty,
ale one tworzą dwa wirtualne porty szeregowe, które mogą służyć
do testowania komunikacji pomiędzy dwoma aplikacjami na PC,
ale nie umożliwiają wyświetlania tego co się tam przesyła pomiędzy nimi
i nie umożliwiają podpięcie się pod rzeczywisty fizyczny port
(no, chyba że ja czegoś nie doczytałem).

Poszedłem więc inną drogą (być może błędną) i przerobiłem program
tty0tty, tak aby otwierał jeden rzeczywisty port, a drugi na
pseudoterminalu, a w międzyczasie wypluwał na konsolę to co się tam
pojawia.

Tyle, że coś mi tam jeszcze szwankuję i nie mogę dojść o co chodzi.

Źródła nie są długie, więc je wkleję w całości:

> gcc -Wall -O2 -D_GNU_SOURCE tty0tty.c -o tty0tty

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <errno.h>

#include <termio.h>


#define RED 31
#define GREEN 32
#define YELLOW 33
#define BLUE 34


static unsigned char buffer[1024];


void Reset()
{
	printf ("%c[%d ",0x1B,0); // przywrocenie kolorow na konsoli

}


	int
ptym_open(char *pts_name, char *pts_name_s , int pts_namesz)
{
	char    *ptr;
	int     fdm;

	strncpy(pts_name, "/dev/ptmx", pts_namesz);
	pts_name[pts_namesz - 1] = '\0';

	fdm = posix_openpt(O_RDWR | O_NONBLOCK);
	if (fdm < 0)
		return(-1);
	if (grantpt(fdm) < 0)
	{
		close(fdm);
		return(-2);
	}
	if (unlockpt(fdm) < 0)
	{
		close(fdm);
		return(-3);
	}
	if ((ptr = ptsname(fdm)) == NULL)
	{
		close(fdm);
		return(-4);
	}

	strncpy(pts_name_s, ptr, pts_namesz);
	pts_name[pts_namesz - 1] = '\0';

	return(fdm);
}


	int
conf_ser(int serialDev)
{

	int rc;
	struct termios params;

	// Get terminal atributes
	rc = tcgetattr(serialDev, &params);

	// Modify terminal attributes
	cfmakeraw(&params);

	rc = cfsetispeed(&params, B115200);

	rc = cfsetospeed(&params, B115200);

	// CREAD - Enable port to read data
	// CLOCAL - Ignore modem control lines
	params.c_cflag |= (B115200 |CS8 | CLOCAL | CREAD);

	// Make Read Blocking
	//fcntl(serialDev, F_SETFL, 0);

	// Set serial attributes
	rc = tcsetattr(serialDev, TCSANOW, &params);

	// Flush serial device of both non-transmitted
	// output data and non-read input data....
	tcflush(serialDev, TCIOFLUSH);


	return EXIT_SUCCESS;
}

	void
copydata(int fdfrom, int fdto)
{
	ssize_t br, bw;
	unsigned char *pbuf = buffer;
	unsigned char i;
	br = read(fdfrom, buffer, 1024);
	if (br < 0)
	{
		fprintf(stderr, "BR=%d, errno=%d\n", br, errno);
		if (errno == EAGAIN || errno == EIO)
		{
			br = 0;
		}
		else
		{
			perror("read");
			exit(1);
		}
	}
	if (br > 0)
	{
		fprintf(stderr,"Copydate:%d B\n",br );
		for (i=0; i< br; i++)
		{
			fprintf(stderr, " %02x", buffer[i]);


		}
		putc('\n', stderr);
		do
		{
			do
			{
				bw = write(fdto, pbuf, br);
				if (bw > 0)
				{
					pbuf += bw;
					br -= bw;
				}
			} while (br > 0 && bw > 0);
		} while (bw < 0 && errno == EAGAIN);
		if (bw <= 0)
		{
			// kernel buffer may be full, but we can recover
			fprintf(stderr, "Write error, br=%d bw=%d\n", br, bw);
			usleep(500000);
			// discard input
			while (read(fdfrom, buffer, 1024) > 0)
				;
		}
	}
	else
	{
		usleep(100000);
	}
}

int main(int argc, char* argv[])
{
	char master1[1024];
	char slave1[1024]="/dev/ttyUSB0";
	char master2[1024];
	char slave2[1024];

	int fd1;
	int fd2;

	fd_set rfds;
	int retval;

	//fd1=ptym_open(master1,slave1,1024);
	fd1=open(slave1,O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);

	fd2=ptym_open(master2,slave2,1024);

	if (argc >= 3)
	{
		//unlink(argv[1]);
		unlink(argv[2]);
		/*  if (symlink(slave1, argv[1]) < 0)
		    {
		    fprintf(stderr, "Cannot create: %s\n", argv[1]);
		    return 1;
		    }
		 */

		if (symlink(slave2, argv[2]) < 0) {
			fprintf(stderr, "Cannot create: %s\n", argv[2]);
			return 1;
		}
		printf("(%s) <=> (%s)\n",argv[1],argv[2]);
	}
	else {
		printf("(%s) <=> (%s)\n",slave1,slave2);
	}

	conf_ser(fd1);
	conf_ser(fd2);

	while(1)
	{
		FD_ZERO(&rfds);
		FD_SET(fd1, &rfds);
		FD_SET(fd2, &rfds);

		retval = select(fd2 + 1, &rfds, NULL, NULL, NULL);
		if (retval == -1)
		{
			perror("select");
			return 1;
		}
		if (FD_ISSET(fd1, &rfds))
		{
			fprintf(stderr,"%c[%dm%s -> %s\n",0x1B,RED, slave1, slave2);
			copydata(fd1, fd2);
		}
		if (FD_ISSET(fd2, &rfds))
		{
			fprintf(stderr,"%c[%dm%s -> %s\n", 0x1B,BLUE, slave2, slave1);
			copydata(fd2, fd1);
		}
	}
	Reset();
	close(fd1);
	close(fd2);

	return EXIT_SUCCESS;
}


Otóż jak podepnę swoje urządzenie do /dev/ttyUSB0, a z drugiej strony do
pseudoterminala /dev/pts/2 CuteCom to dogaduję się ze swoim urządzeniem
wysyłanymi komendami. Pierwszy problem zaczyna się w momencie kiedy na
terminalu CuteCom odłączam się od pseudoterminalu za pomocą "Close
device" - czyli zwalniam port.
Wtedy na ekran zaczyna wypluwać mi komunikat, który wynika z treści
mojego przerobionego programu:

/dev/pts/2 -> /dev/ttyUSB0
/dev/pts/2 -> /dev/ttyUSB0
/dev/pts/2 -> /dev/ttyUSB0
/dev/pts/2 -> /dev/ttyUSB0
/dev/pts/2 -> /dev/ttyUSB0
(...) itd całe ekrany

dopiero CTRL-C to kończy.

Nie jestem programistą i nie znam wszystkich niuansów konfiguracji
komunikacji szeregowej stąd ten post.
Dzieje się tak z każdym programem, który podpinam do /dev/pts/2
i przy zamknięciu połączenia zaczyna się zapełnianie ekranu
powyższym komunikatem.

Inna sprawa, że o ile z terminala potrafię się dogadać ze swoim
urządzeniem o tyle jak odpalę dedykowany program (nie moje dzieło)
to też nie mam komunikacji. No, ale nie wszystko na raz.

Gdyby się ktoś coś dopatrzył to byłbym wdzięczny.


Pozdrawiam
Technical Details
Message-ID: <548ac5fd$0$12100$65785112@news.neostrada.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-01.news.neostrada.pl!unt-spo-b-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-01.news.neostrada.pl!unt-spo-b-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail
Date: Fri, 12 Dec 2014 11:39:57 +0100
From: Krzysiek <kris_gor@poczta.onet.pl>
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.6.0
MIME-Version: 1.0
Newsgroups: pl.comp.os.linux.programowanie
Subject: tty0tty
Lines: 298
Message-ID: <548ac5fd$0$12100$65785112@news.neostrada.pl>
Organization: Telekomunikacja Polska
NNTP-Posting-Host: 195.116.182.254
X-Trace: 1418380797 unt-rea-a-02.news.neostrada.pl 12100 195.116.182.254:53975
X-Complaints-To: abuse@news.neostrada.pl
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit