From 52c94e2c0d854886b3bbd76f31f3d3372c2425b2 Mon Sep 17 00:00:00 2001
From: Jon Langseth <jon.langseth@lilug.no>
Date: Sat, 4 Dec 2010 16:24:23 +0100
Subject: [PATCH] Added some C-files

---
 door_works.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++
 main.c       | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 341 insertions(+)
 create mode 100644 door_works.c
 create mode 100644 main.c

diff --git a/door_works.c b/door_works.c
new file mode 100644
index 0000000..2ceacb8
--- /dev/null
+++ b/door_works.c
@@ -0,0 +1,169 @@
+#include <termios.h> /* Terminal I/O support */
+#include <errno.h>   /* Error number definitions */
+#include <string.h>  /* String function definitions */
+#include <stdio.h>   /* Standard I/O */
+#include <fcntl.h>   /* File descriptor manipulation */
+
+#define DEVICE "/dev/ttyUSB0"
+
+int open_port ( char* device )
+{
+	int f;
+	struct termios tio;
+
+	f = open ( DEVICE, O_RDWR | O_NOCTTY ); // Not using O_NDELAY, that caused ERR11: temp unavail.
+	if ( f < 0 )
+	{
+		perror(DEVICE); 
+		return(-1);
+	}
+
+	// Fixed settings: 9600bps, 8 bits, 
+	// no parity, no flow-control,
+	// local mode, read enabled
+	tio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
+	tio.c_cflag &= ~CRTSCTS;
+        tio.c_iflag = IGNPAR;
+        tio.c_oflag = 0;
+        tio.c_lflag = 0; // Non-canonical read, no other options.
+	tio.c_cc[VMIN] = 3; // Expect 3 characters, always.
+       	tio.c_cc[VTIME] = 60; // Wait for a max of 6 seconds
+
+        tcsetattr(f,TCSANOW,&tio); // Apply this now.
+
+	return f;
+}
+
+int send_cmd ( int fd, char cmd )
+{
+	int res;
+	char buf[7];
+	char status;
+
+	tcflush(fd, TCIFLUSH); // Flush the serial input buffer.
+
+	res = write( fd, &cmd , 1 ); 	// Send the command to the device
+	if ( res < 0 ) return -1;	// and return on failure.
+
+	res = read( fd, buf, 5 );
+	if ( res < 0 )
+	{
+		printf("SERIAL read error %d: %s\n", errno, strerror(errno));
+		return -1;
+	}
+	if ( res == 0 ) 
+	{ 
+		printf ("Null read\n"); 
+		return -1; 
+	}
+
+	buf[res] = 0x00;
+
+	// A response is supposed to be precisely three characters.
+	if ( res != 3 ) {
+		return -1;
+	}
+	
+	// And the first is supposed to be an echo of the given command.
+	if ( buf[0] != cmd )
+	{
+		printf("Error: echoed command not correct\n");
+		return -1;
+	}
+
+	// The second is (a ':' is ignored, and the third is checked.
+	// The only valid responses are Locked, Open and Moving.
+	status = buf[2];
+
+	if ( (status == 'O') || (status == 'L') || (status == 'M') )
+		return status;
+	else return -1;
+}
+
+int get_state ( int fd )
+{
+	return send_cmd( fd, 's'); // Yashure. KISS
+}
+
+int set_state ( int fd, int state )
+{
+	int res;
+	switch ( state )
+	{
+		case 0:
+			res = send_cmd ( fd, 'o');
+			break;
+		case 1:
+			res = send_cmd ( fd, 'l');
+			break;
+	}
+	if ( (res != 'L') && ( res != 'O' ) ) return -1; // FAIL
+	// And, yes, I will call a status "Moving" a failed state-change attempt
+	return 0;
+}
+
+
+int main ( int argc, char** argv )
+{
+	int fd;
+	int res;
+	int c;
+	char buf[255];
+
+	fd = open_port( DEVICE );
+	if ( fd < 0 )
+	{
+		perror(DEVICE); 
+		return(-1);
+	}
+
+	printf("Enter command character, followed by enter/return\n");
+	printf("Valid commands are:\n l - Lock\n o - Open \n s - Status\n i - Invalid simulation\n");
+	printf("ESC Enter exits");
+	printf("rdy>");
+	for(;;)
+	{
+		res = getchar();
+		if ( res == 10 ) continue;
+
+		if ( res == 27 ) return 1; 
+		switch( res )
+		{
+			case 'l':
+				printf("Locking...\n");
+				if ( set_state( fd, 1 ) ) printf ( "set_state() failed\n");
+				break;
+			case 'o':
+				printf("Opening...\n");
+				if ( set_state( fd, 0 ) ) printf ( "set_state() failed\n");
+				break;
+			case 's':
+				printf("Requesting status...\n");
+				res = get_state( fd );
+				switch ( res )
+				{
+					case 'O':
+						printf("Open\n");
+						break;
+					case 'L':
+						printf("Locked\n");
+						break;
+					case 'M':
+						printf("Moving\n");
+						break;
+					default:
+						printf("Unknown status %d\n", res);
+				}
+				break;
+			case 'i':
+				printf("Sending invalid command...\n");
+				res = send_cmd( fd, (char)res );
+				printf("Back from attempt. Got %d back\n", res);
+			default:
+				break;
+		}
+		printf("rdy>");
+	}
+}
+
+
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..26a9e37
--- /dev/null
+++ b/main.c
@@ -0,0 +1,172 @@
+#include <termios.h>
+#include <errno.h>   /* Error number definitions */
+#include <string.h>  /* String function definitions */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#define DEVICE "/dev/ttyUSB0"
+#define BAUDRATE B9600
+
+int open_port ( char* device )
+{
+	int f;
+	struct termios tio;
+
+	f = open ( DEVICE, O_RDWR | O_NOCTTY ); // Not using O_NDELAY, that caused ERR11: temp unavail.
+	if ( f < 0 )
+	{
+		perror(DEVICE); 
+		return(-1);
+	}
+
+	// Fixed settings: 9600bps, 8 bits, 
+	// no parity, no flow-control,
+	// local mode, read enabled
+	tio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
+	tio.c_cflag &= ~CRTSCTS;
+        tio.c_iflag = IGNPAR;
+        tio.c_oflag = 0;
+        tio.c_lflag = 0; // Non-canonical read, no other options.
+	tio.c_cc[VMIN] = 3; // Expect 3 characters, always.
+       	tio.c_cc[VTIME] = 60; // Wait for a max of 6 seconds
+
+        tcsetattr(f,TCSANOW,&tio); // Apply this now.
+
+	return f;
+}
+
+int send_cmd ( int fd, char cmd )
+{
+	int res;
+	char buf[7];
+	char status;
+
+	tcflush(fd, TCIFLUSH); // Flush the serial input buffer.
+
+	res = write( fd, &cmd , 1 ); 	// Send the command to the device
+	if ( res < 0 ) return -1;	// and return on failure.
+
+	res = read( fd, buf, 5 );
+	if ( res < 0 )
+	{
+		printf("SERIAL read error %d: %s\n", errno, strerror(errno));
+		return -1;
+	}
+	if ( res == 0 ) 
+	{ 
+		printf ("Null read\n"); 
+		return -1; 
+	}
+
+	buf[res] = 0x00;
+
+	// A response is supposed to be precisely three characters.
+	if ( res != 3 ) {
+		return -1;
+	}
+	
+	// And the first is supposed to be an echo of the given command.
+	if ( buf[0] != cmd )
+	{
+		printf("Error: echoed command not correct\n");
+		return -1;
+	}
+
+	// The second is (a ':' is ignored, and the third is checked.
+	// The only valid responses are Locked, Open and Moving.
+	status = buf[2];
+
+	if ( (status == 'O') || (status == 'L') || (status == 'M') )
+		return status;
+	else return -1;
+}
+
+int get_state ( int fd )
+{
+	return send_cmd( fd, 's'); // Yashure. KISS
+}
+
+int set_state ( int fd, int state )
+{
+	int res;
+	switch ( state )
+	{
+		case 0:
+			res = send_cmd ( fd, 'o');
+			break;
+		case 1:
+			res = send_cmd ( fd, 'l');
+			break;
+	}
+	if ( (res != 'L') && ( res != 'O' ) ) return -1; // FAIL
+	// And, yes, I will call a status "Moving" a failed state-change attempt
+	return 0;
+}
+
+
+int main ( int argc, char** argv )
+{
+	int fd;
+	int res;
+	int c;
+	char buf[255];
+
+	fd = open_port( DEVICE );
+	if ( fd < 0 )
+	{
+		perror(DEVICE); 
+		return(-1);
+	}
+
+	printf("Enter command character, followed by enter/return\n");
+	printf("Valid commands are:\n l - Lock\n o - Open \n s - Status\n i - Invalid simulation\n");
+	printf("ESC Enter exits");
+	printf("rdy>");
+	for(;;)
+	{
+		res = getchar();
+		if ( res == 10 ) continue;
+
+		if ( res == 27 ) return 1; 
+		switch( res )
+		{
+			case 'l':
+				printf("Locking...\n");
+				if ( set_state( fd, 1 ) ) printf ( "set_state() failed\n");
+				break;
+			case 'o':
+				printf("Opening...\n");
+				if ( set_state( fd, 0 ) ) printf ( "set_state() failed\n");
+				break;
+			case 's':
+				printf("Requesting status...\n");
+				res = get_state( fd );
+				switch ( res )
+				{
+					case 'O':
+						printf("Open\n");
+						break;
+					case 'L':
+						printf("Locked\n");
+						break;
+					case 'M':
+						printf("Moving\n");
+						break;
+					default:
+						printf("Unknown status %d\n", res);
+				}
+				break;
+			case 'i':
+				printf("Sending invalid command...\n");
+				res = send_cmd( fd, (char)res );
+				printf("Back from attempt. Got %d back\n", res);
+			default:
+				break;
+		}
+		printf("rdy>");
+	}
+}
+
+
-- 
2.39.2