--- viewer.cpp.1	2007-01-12 14:11:05.000000000 +0000
+++ viewer.cpp	2007-01-11 16:43:27.000000000 +0000
@@ -541,6 +541,18 @@
 };
 */
 
+////
+// Arduino
+//
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int gArduino = -1;
+int serialport_init();
+int serialport_write(int fd, const char* str);
+int serialport_read_until(int fd, char* buf, char until);
+
 ///////////////////////
 //
 // Forward declarations
@@ -3966,6 +3978,24 @@
 		gAudiop->idle(max_audio_decode_time);
 	}
 
+        //////
+        // Arduino
+		
+		if(gArduino == -1) {
+		    gArduino = serialport_init();
+			llinfos << "Inited arduino, fd: " << gArduino << llendl;
+			gChatBar->sendChatFromViewer("Arduino is online", CHAT_TYPE_NORMAL, FALSE);
+		} else {
+                    char buf[256] = "/42 ";
+                    int n = read(gArduino, buf+4, 100);
+					if(n > 0) {
+                        buf[n+4] = '\0';
+						llinfos << buf << llendl;
+						gChatBar->sendChatFromViewer(buf, CHAT_TYPE_NORMAL, FALSE);
+                    }
+                }
+        //llinfos << "Im in ur idle loop wasting yr cycles" << llendl;
+
 	// yield some time to the os if we are supposed to.
 	if(gYieldTime)
 	{
@@ -6519,3 +6549,101 @@
 }
 // JC - Please don't put code here.  Find the right file, perhaps
 // llviewermessage.cpp, and put it there.  Thanks!
+
+//////
+// Arduino
+
+int serialport_write(int fd, const char* str)
+{
+    int len = strlen(str);
+    int n = write(fd, str, len);
+    if( n!=len ) 
+        return -1;
+    return 0;
+}
+
+int serialport_read_until(int fd, char* buf, char until)
+{
+    char b[1];
+    int i=0;
+    do { 
+        int n = read(fd, b, 1);  // read a char at a time
+        if( n==-1) return -1;    // couldn't read
+        if( n==0 ) {
+            usleep( 10 * 1000 ); // wait 10 msec try again
+            continue;
+        }
+        buf[i] = b[0]; i++;
+    } while( b[0] != until );
+
+    buf[i] = 0;  // null terminate the string
+    return 0;
+}
+
+// takes the string name of the serial port (e.g. "/dev/tty.usbserial","COM1")
+// and a baud rate (bps) and connects to that port at that speed and 8N1.
+// opens the port in fully raw mode so you can send binary data.
+// returns valid fd, or -1 on error
+int serialport_init()
+{
+    struct termios toptions;
+    int fd;
+    
+    //fprintf(stderr,"init_serialport: opening port %s @ %d bps\n",
+    //        serialport,baud);
+
+    fd = open("/dev/tty.usbserial-A4000QpY", O_RDWR | O_NOCTTY | O_NDELAY);
+    if (fd == -1)  {
+        perror("init_serialport: Unable to open port ");
+        return -1;
+    }
+    
+    if (tcgetattr(fd, &toptions) < 0) {
+        perror("init_serialport: Couldn't get term attributes");
+        return -1;
+    }
+	int baud = 9600;
+    speed_t brate = baud; // let you override switch below if needed
+    switch(baud) {
+    case 4800:   brate=B4800;   break;
+    case 9600:   brate=B9600;   break;
+// if you want these speeds, uncomment these and set #defines if Linux
+//#ifndef OSNAME_LINUX
+//    case 14400:  brate=B14400;  break;
+//#endif
+    case 19200:  brate=B19200;  break;
+//#ifndef OSNAME_LINUX
+//    case 28800:  brate=B28800;  break;
+//#endif
+    case 38400:  brate=B38400;  break;
+    case 57600:  brate=B57600;  break;
+    case 115200: brate=B115200; break;
+    }
+    cfsetispeed(&toptions, brate);
+    cfsetospeed(&toptions, brate);
+
+    // 8N1
+    toptions.c_cflag &= ~PARENB;
+    toptions.c_cflag &= ~CSTOPB;
+    toptions.c_cflag &= ~CSIZE;
+    toptions.c_cflag |= CS8;
+    // no flow control
+    toptions.c_cflag &= ~CRTSCTS;
+
+    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
+    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
+
+    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
+    toptions.c_oflag &= ~OPOST; // make raw
+
+    // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
+    toptions.c_cc[VMIN]  = 0;
+    toptions.c_cc[VTIME] = 20;
+    
+    if( tcsetattr(fd, TCSANOW, &toptions) < 0) {
+        perror("init_serialport: Couldn't set term attributes");
+        return -1;
+    }
+
+    return fd;
+}
