Index: xbee.c
===================================================================
--- xbee.c	(revision 1344)
+++ xbee.c	(revision 1345)
@@ -1,3 +1,37 @@
+/**
+ * Copyright (c) 2007 Colony Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ **/
+
+/**
+ * @file xbee.c
+ * @brief XBee Interface
+ *
+ * Implementation of low level communication with the XBee in API mode.
+ *
+ * @author Brian Coltin, Colony Project, CMU Robotics Club
+ **/
+
 #include "xbee.h"
 #include "wl_defs.h"
 
@@ -7,6 +41,7 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <errno.h>
+#include <termios.h>
 
 #else
 
@@ -19,9 +54,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <queue.h>
-
 #define XBEE_FRAME_START 0x7E
+#define XBEE_GET_PACKET_TIMEOUT 1000
 
 /*Frame Types*/
 #define XBEE_FRAME_STATUS 0x8A
@@ -36,53 +70,62 @@
 /*Internal Function Prototypes*/
 
 /*I/O Functions*/
-void xbee_send(char* buf, int size);
-void xbee_send_string(char* c);
+static int xbee_send(char* buf, int size);
+static int xbee_send_string(char* c);
 
 #ifndef ROBOT
-void xbee_read(char* buf, int size);
+static int xbee_read(char* buf, int size);
 #endif
 
 /*Command Mode Functions
  * Called during initialization.
  */
-void xbee_enter_command_mode(void);
-void xbee_exit_command_mode(void);
-void xbee_enter_api_mode(void);
-void xbee_wait_for_string(char* s, int len);
-void xbee_wait_for_ok(void);
+static int xbee_enter_command_mode(void);
+static int xbee_exit_command_mode(void);
+static int xbee_enter_api_mode(void);
+static int xbee_wait_for_string(char* s, int len);
+static int xbee_wait_for_ok(void);
 
 /*API Mode Functions*/
 
-int xbee_handle_packet(char* packet, int len);
-void xbee_handle_at_command_response(char* command, char result,
-	char* extra, int extraLen);
-void xbee_handle_status(char status);
-int xbee_verify_checksum(char* packet, int len);
-char xbee_compute_checksum(char* packet, int len);
-void xbee_send_frame(char* buf, int len);
-void xbee_send_read_at_command(char* command);
-void xbee_send_modify_at_command(char* command, char* value);
+static int xbee_handle_packet(char* packet, int len);
+static void xbee_handle_at_command_response(char* command, char result, char* extra, int extraLen);
+static void xbee_handle_status(char status);
+static int xbee_verify_checksum(char* packet, int len);
+static char xbee_compute_checksum(char* packet, int len);
+static int xbee_send_frame(char* buf, int len);
+static int xbee_send_read_at_command(char* command);
+static int xbee_send_modify_at_command(char* command, char* value);
 
 /*Global Variables*/
 
 #ifndef ROBOT
-int xbee_stream;
-pthread_t* xbee_listen_thread;
+static char* xbee_com_port = XBEE_PORT_DEFAULT;
+static int xbee_stream;
+static pthread_t* xbee_listen_thread;
 #endif
 
-Queue* xbee_queue;
+// TODO: is this a good size?
+#define XBEE_BUFFER_SIZE	128
+#define PACKET_BUFFER_SIZE	108
+// a buffer for data received from the XBee
+char arrival_buf[XBEE_BUFFER_SIZE];
+// location of last unread byte in buffer
+volatile int buffer_last = 0;
+// first unread byte in buffer
+volatile int buffer_first = 0;
 
+
 //used to store packets as they are read
-char xbee_buf[128];
-int currentBufPos = 0;
+static char xbee_buf[PACKET_BUFFER_SIZE];
+static int currentBufPos = 0;
 
 //XBee status
-unsigned int xbee_panID = XBEE_PAN_DEFAULT;
-unsigned int xbee_pending_panID = XBEE_PAN_DEFAULT;
-int xbee_channel = XBEE_CHANNEL_DEFAULT;
-int xbee_pending_channel = XBEE_CHANNEL_DEFAULT;
-unsigned int xbee_address = 0;
+static unsigned int xbee_panID = XBEE_PAN_DEFAULT;
+static unsigned int xbee_pending_panID = XBEE_PAN_DEFAULT;
+static int xbee_channel = XBEE_CHANNEL_DEFAULT;
+static int xbee_pending_channel = XBEE_CHANNEL_DEFAULT;
+static volatile unsigned int xbee_address = 0;
 
 /*Function Implementations*/
 
@@ -90,36 +133,69 @@
 
 /**
  * Interrupt for the robot. Adds bytes received from the xbee
- * to the queue.
+ * to the buffer.
  **/
 #ifndef FIREFLY
 ISR(USART1_RX_vect)
 {
 	char c = UDR1;
-	queue_add(xbee_queue, (void*)(int)c);
+	arrival_buf[buffer_last] = c;
+	int t = buffer_last + 1;
+	if (t == XBEE_BUFFER_SIZE)
+		t = 0;
+	if (t == buffer_first)
+	{
+		WL_DEBUG_PRINT("\nOut of space in buffer.\n");
+	}
+	buffer_last = t;
 }
 #else
 SIGNAL(SIG_USART0_RECV)
 {
 	char c = UDR0;
-	queue_add(xbee_queue, (void*)(int)c);
+	arrival_buf[buffer_last] = c;
+	int t = buffer_last + 1;
+	if (t == XBEE_BUFFER_SIZE)
+		t = 0;
+	if (t == buffer_first)
+	{
+		WL_DEBUG_PRINT("Out of space in buffer.\n");
+	}
+	buffer_last = t;
 }
 #endif
 
 #else
 
+// Computer code
+
 /**
  * Thread that listens to the xbee.
  **/
-void* listen_to_xbee(void* x)
+static void* listen_to_xbee(void* x)
 {
 	char c;
 	while (1)
 	{
-		xbee_read(&c, 1);
-		queue_add(xbee_queue, (void*)(int)c);
+		if (xbee_read(&c, 1) != 0) {
+			WL_DEBUG_PRINT("xbee_read failed.\n");
+			return NULL;
+		}
+
+		arrival_buf[buffer_last] = c;
+		int t = buffer_last + 1;
+		if (t == XBEE_BUFFER_SIZE)
+			t = 0;
+		if (t == buffer_first)
+		{
+			WL_DEBUG_PRINT("Out of space in buffer.\n");
+		}
+		buffer_last = t;
+
+		usleep(1000);
 	}
-	return 0;
+
+	return NULL;
 }
 
 #endif
@@ -126,52 +202,134 @@
 
 /**
  * Initializes the XBee library so that other functions may be used.
- *
- * @param pan_id the PAN to join initially. Use XBEE_PAN_DEFAULT
- * to leave the PAN as it is initially.
  **/
-void xbee_lib_init(void)
+int xbee_lib_init()
 {
-	xbee_queue = queue_create();
-	
-	#ifdef ROBOT
+	WL_DEBUG_PRINT("in xbee_init\n");
+#ifdef ROBOT
 
 	//enable the receiving interrupt
-	#ifdef FIREFLY
+#ifdef FIREFLY
 	UCSR0B |= _BV(RXCIE) | _BV(RXEN);
-	#else
+#else
+#ifdef BAYBOARD
+	UCSR1B |= _BV(RXCIE1);
+#else
 	UCSR1B |= _BV(RXCIE);
-	#endif
+#endif
+#endif
 	sei();
-	#else
-	xbee_stream = open("/dev/ttyUSB0", O_RDWR);
-	if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
-		xbee_stream = open("/dev/ttyUSB1", O_RDWR);
-	if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
+#else
+	xbee_stream = open(xbee_com_port, O_RDWR);
+	if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/)
 	{
-		printf("Failed to open connection to XBee.\r\n");
-		exit(0);
+		WL_DEBUG_PRINT("Failed to open connection to XBee on port ");
+		WL_DEBUG_PRINT_INT(xbee_com_port);
+		WL_DEBUG_PRINT(".\n");
+		return -1;
+	} else {
+	  WL_DEBUG_PRINT("Successfully opened connection to XBee on port ");
+		WL_DEBUG_PRINT_INT(xbee_com_port);
+		WL_DEBUG_PRINT(".\n");
 	}
-	lockf(xbee_stream, F_LOCK, 0);
-	
-	xbee_listen_thread =
-		(pthread_t*)malloc(sizeof(pthread_t));
-	
-	int ret = pthread_create(xbee_listen_thread, NULL, 
-		listen_to_xbee, NULL);
+
+	// set baud rate, etc. correctly
+	struct termios options;
+
+	tcgetattr(xbee_stream, &options);
+	cfsetispeed(&options, B9600);
+	cfsetospeed(&options, B9600);
+	options.c_iflag &= ~ICRNL;
+	options.c_oflag &= ~OCRNL;
+	options.c_cflag |= (CLOCAL | CREAD);
+	options.c_cflag &= ~PARENB;
+	options.c_cflag &= ~CSTOPB;
+	options.c_cflag &= ~CSIZE;
+	options.c_cflag |= CS8;
+	options.c_lflag &= ~ICANON;
+	options.c_cc[VMIN] = 1;
+	options.c_cc[VTIME] = 50;
+
+	if (tcsetattr(xbee_stream, TCSANOW, &options))
+	{
+		WL_DEBUG_PRINT("Error setting attributes.\n");
+		return -1;
+	}
+
+	xbee_listen_thread = (pthread_t*)malloc(sizeof(pthread_t));
+	if (xbee_listen_thread == NULL)
+	{
+		WL_DEBUG_PRINT("Malloc failed.\n");
+		return -1;
+	}
+
+	int ret = pthread_create(xbee_listen_thread, NULL, listen_to_xbee, NULL);
 	if (ret)
 	{
-		printf("Failed to create listener thread.\r\n");
-		exit(0);
+		WL_DEBUG_PRINT("Failed to create listener thread.\n");
+		return -1;
 	}
-	#endif
-	xbee_enter_command_mode();
-	xbee_enter_api_mode();
-	xbee_exit_command_mode();
-	xbee_send_read_at_command("MY");
+#endif
+
+	WL_DEBUG_PRINT("Entering command mode.\n");
+
+	if (xbee_enter_command_mode() != 0) {
+		return -1;
+	}
+
+	WL_DEBUG_PRINT("Entered command mode.\n");
+
+	if (xbee_enter_api_mode() != 0) {
+		return -1;
+	}
+
+	WL_DEBUG_PRINT("Entered api mode.\n");
+
+	if (xbee_exit_command_mode() != 0) {
+	     return -1;
+	}
 	
+	WL_DEBUG_PRINT("Left command mode.\n");
+
+	if (xbee_send_read_at_command("MY")) {
+		return -1;
+	}
+	WL_DEBUG_PRINT("Getting ATMY address.\n");
+
+#ifndef ROBOT
+	int i;
+	for (i = 0; xbee_address == 0 && i < XBEE_GET_PACKET_TIMEOUT; i++) {
+	  ret = xbee_get_packet(NULL);
+
+	  usleep(1000);
+	  
+/* 	  if (ret == -1) { */
+/* 	    WL_DEBUG_PRINT("xbee_get_packet(NULL) failed.\n"); */
+/* 	    return -1; */
+/* 	  } */
+	}
+#else
 	//wait to return until the address is set
-	while (xbee_address == 0) xbee_get_packet(NULL);
+  //TODO: this shouldn't wait indefinitely.  There should be some sort of reasonable timeout
+  // so if the address is never set right, an error can be returned instead of having the
+  // robot hang forever
+	while (xbee_address == 0) {
+	  xbee_get_packet(NULL);
+	}
+#endif
+	WL_DEBUG_PRINT("Got ATMY address.\n");
+
+#ifndef ROBOT
+	if (i == XBEE_GET_PACKET_TIMEOUT) { // We timed-out.
+
+	  WL_DEBUG_PRINT("xbee_get_packet timed out.\n");
+	  return -1;
+	} else {
+	  return 0;
+	}
+#else
+	return 0;
+#endif
 }
 
 /**
@@ -186,26 +344,30 @@
 	lockf(xbee_stream, F_ULOCK, 0);
 	close(xbee_stream);
 	#endif
-	queue_destroy(xbee_queue);
 }
 
 /**
  * Send a buffer buf of size bytes to the XBee.
- * 
+ *
  * @param buf the buffer of data to send
  * @param size the number of bytes to send
  **/
-void xbee_send(char* buf, int size)
+static int xbee_send(char* buf, int size)
 {
-	#ifdef ROBOT
+#ifdef ROBOT
 	int i;
-	for (i = 0; i < size; i++)
+	for (i = 0; i < size; i++) {
 		xbee_putc(buf[i]);
-	#else
+	}
+
+	return 0;
+
+#else
+
 	int ret = write(xbee_stream, buf, size);
 	//success
 	if (ret == size)
-		return;
+		return 0;
 	if (ret == -1)
 	{
 		//interrupted by system signal, probably timer interrupt.
@@ -212,16 +374,15 @@
 		//just try again
 		if (errno == 4)
 		{
-			xbee_send(buf, size);
-			return;
+			return xbee_send(buf, size);
 		}
-		printf("Failed to write to xbee, error %i.\r\n", errno);
-		return;
+		WL_DEBUG_PRINT("Failed to write to xbee\r\n");
+		return -1;
 	}
 
 	//write was interrupted after writing ret bytes
-	xbee_send(buf + ret, size - ret);
-	#endif
+	return xbee_send(buf + ret, size - ret);
+#endif
 }
 
 /**
@@ -229,16 +390,22 @@
  *
  * @param c the string to send to the XBEE
  **/
-void xbee_send_string(char* c)
+//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
+// it reduces code size or not should be done to be sure.
+static int xbee_send_string(char* c)
 {
-	xbee_send(c, strlen(c));
+	return xbee_send(c, strlen(c));
 }
 
 #ifndef ROBOT
-void xbee_read(char* buf, int size)
+static int xbee_read(char* buf, int size)
 {
-	if (read(xbee_stream, buf, size) == -1)
-		printf("Failed to read from xbee.\r\n");
+	if (read(xbee_stream, buf, size) == -1) {
+		WL_DEBUG_PRINT("Failed to read from xbee.\r\n");
+		return -1;
+	}
+
+	return 0;
 }
 #endif
 
@@ -245,36 +412,53 @@
 /**
  * Enter into command mode.
  **/
-void xbee_enter_command_mode()
+static int xbee_enter_command_mode()
 {
-	xbee_send_string("+++");
-	xbee_wait_for_ok();
+	if (xbee_send_string("+++") != 0) {
+		return -1;
+	}
+
+	if (xbee_wait_for_ok() != 0) {
+	  return -1;
+	}
+	  return 0;
 }
 
 /**
  * Exit from command mode.
  **/
-void xbee_exit_command_mode()
+static int xbee_exit_command_mode()
 {
-	xbee_send_string("ATCN\r");
+	if (xbee_send_string("ATCN\r") != 0) {
+		return -1;
+	}
+
 	xbee_wait_for_ok();
+
+	return 0;
 }
 
 /**
  * Enter API mode.
  **/
-void xbee_enter_api_mode()
+static int xbee_enter_api_mode()
 {
-	xbee_send_string("ATAP 1\r");
+	if (xbee_send_string("ATAP 1\r") != 0) {
+		return -1;
+	}
 	xbee_wait_for_ok();
+
+	return 0;
 }
 
 /**
  * Wait until the string "OK\r" is received from the XBee.
  **/
-void xbee_wait_for_ok()
+//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
+// it reduces code size or not should be done to be sure.
+static int xbee_wait_for_ok()
 {
-	xbee_wait_for_string("OK\r", 3);
+	return xbee_wait_for_string("OK\r", 3);
 }
 
 /**
@@ -284,19 +468,35 @@
  * @param s the string to receive
  * @param len the length of the string
  **/
-void xbee_wait_for_string(char* s, int len)
+static int xbee_wait_for_string(char* s, int len)
 {
 	char* curr = s;
-	while (curr - s < len)
-	{
-		if (queue_is_empty(xbee_queue))
-			continue;
-		char c = (char)(int)queue_remove(xbee_queue);
-		if (c == *curr)
-			curr++;
-		else
-			curr = s;
+	while (curr - s < len) {
+		// check if buffer is empty
+		if (buffer_last != buffer_first) {
+			char c = arrival_buf[buffer_first++];
+			if (buffer_first == XBEE_BUFFER_SIZE) {
+				buffer_first = 0;
+			}
+
+			if (c == *curr) {
+				curr++;
+			} else {
+#ifndef ROBOT
+			  //return -1; // Computer is less forgiving.
+			  curr = s;
+#else
+			  curr = s;
+#endif
+			}
+		} // else buffer is empty.
+
+#ifndef ROBOT
+		usleep(100);
+#endif
 	}
+
+	return 0;
 }
 
 /**
@@ -348,7 +548,7 @@
  * @param len the size in bytes of the packet data
  *
  **/
-void xbee_send_frame(char* buf, int len)
+static int xbee_send_frame(char* buf, int len)
 {
 	char prefix[3];
 	prefix[0] = XBEE_FRAME_START;
@@ -355,9 +555,20 @@
 	prefix[1] = (len & 0xFF00) >> 8;
 	prefix[2] = len & 0xFF;
 	char checksum = xbee_compute_checksum(buf, len);
-	xbee_send(prefix, 3);
-	xbee_send(buf, len);
-	xbee_send(&checksum, 1);
+
+	if (xbee_send(prefix, 3) != 0) {
+		return -1;
+	}
+
+	if (xbee_send(buf, len) != 0) {
+		return -1;
+	}
+
+	if (xbee_send(&checksum, 1) != 0) {
+		return -1;
+	}
+
+	return 0;
 }
 
 /**
@@ -367,9 +578,11 @@
  * use ID to read the PAN ID and MY to return the XBee ID.
  * See the XBee reference guide for a complete listing.
  **/
-void xbee_send_read_at_command(char* command)
+//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
+// it reduces code size or not should be done to be sure.
+static int xbee_send_read_at_command(char* command)
 {
-	xbee_send_modify_at_command(command, NULL);
+	return xbee_send_modify_at_command(command, NULL);
 }
 
 /**
@@ -379,11 +592,11 @@
  * @param value the value to pass as a parameter
  * (or NULL if there is no parameter)
  **/
-void xbee_send_modify_at_command(char* command, char* value)
+static int xbee_send_modify_at_command(char* command, char* value)
 {
 	char buf[16];
 	int i;
-	
+
 	buf[0] = XBEE_FRAME_AT_COMMAND;
 	buf[1] = 1;
 	buf[2] = command[0];
@@ -395,26 +608,29 @@
 		if (valueLen > 8)
 		{
 			WL_DEBUG_PRINT("AT Command too large.\r\n");
-			return;
+			return -1;
 		}
-		for (i = 0; i < valueLen; i++)
+
+		for (i = 0; i < valueLen; i++) {
 			buf[4 + i] = value[i];
+		}
 	}
-	xbee_send_frame(buf, 4 + valueLen);
+
+	return xbee_send_frame(buf, 4 + valueLen);
 }
 
 /**
  * Send the specified packet.
- * 
+ *
  * @param packet the packet data to send
  * @param len the number of bytes in the packet
- * 
+ *
  * @param dest the ID of the XBee to send the packet to,
  * or XBEE_BROADCAST to send the message to all robots
  * in the PAN.
- * 
+ *
  * @param options a combination of the flags
- * XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and 
+ * XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and
  * XBEE_OPTIONS_BROADCAST_ALL_PANS
  *
  * @param frame the frame number to associate this packet
@@ -422,8 +638,7 @@
  * the XBee alerts us as to whether or not our message
  * was received.
  **/
-void xbee_send_packet(char* packet, int len, int dest,
-	char options, char frame)
+int xbee_send_packet(char* packet, int len, int dest, char options, char frame)
 {
 	char buf[5];
 	char prefix[3];
@@ -433,7 +648,7 @@
 	if (len > 100)
 	{
 		WL_DEBUG_PRINT("Packet is too large.\r\n");
-		return;
+		return -1;
 	}
 
 	//data for sending request
@@ -453,10 +668,24 @@
 	for (i = 0; i < len; i++)
 		checksum += (unsigned char)packet[i];
 	checksum = 0xFF - checksum;
-	xbee_send(prefix, 3);
-	xbee_send(buf, 5);
-	xbee_send(packet, len);
-	xbee_send((char*)&checksum, 1);
+
+	if (xbee_send(prefix, 3) != 0) {
+		return -1;
+	}
+
+	if (xbee_send(buf, 5) != 0) {
+		return -1;
+	}
+
+	if (xbee_send(packet, len) != 0) {
+		return -1;
+	}
+
+	if (xbee_send((char*)&checksum, 1) != 0) {
+		return -1;
+	}
+
+	return 0;
 }
 
 /**
@@ -471,7 +700,7 @@
  *
  * The first byte of the packet will be either
  * XBEE_TX_STATUS or XBEE_RX to indicated
- * a response to a sent message or a received message, 
+ * a response to a sent message or a received message,
  * respectively.<br><br>
  *
  * For a status response packet:<br>
@@ -478,7 +707,7 @@
  * The first byte will be XBEE_TX_STATUS.<br>
  * The second byte will be the frame number.<br>
  * The third byte will be the result. 0 indicates success,
- * and nonzero indicates that an error ocurred in 
+ * and nonzero indicates that an error ocurred in
  * transmitting the packet.<br><br>
  *
  * For a received packet:<br>
@@ -488,7 +717,7 @@
  * The fourth byte is the signal strength.<br>
  * The fifth byte is 1 if the packet were sent to
  * a specific address, and 2 if it is a broadcast packet.<br><br>
- * 
+ *
  * @param dest set to the packet data
  * @return the length of the packet, or -1 if no packet
  * is available
@@ -495,33 +724,58 @@
  **/
 int xbee_get_packet(unsigned char* dest)
 {
+     int ret;
 	//start reading a packet with XBEE_FRAME_START
 	if (currentBufPos == 0)
 	{
 		do
-			if (queue_is_empty(xbee_queue))
+		{
+			if (buffer_first == XBEE_BUFFER_SIZE)
+				buffer_first = 0;
+			// check if buffer is empty
+			if (buffer_first == buffer_last) {
 				return -1;
-		while ((char)(int)queue_remove(xbee_queue) != XBEE_FRAME_START);
+			}
+		} while (arrival_buf[buffer_first++] != XBEE_FRAME_START);
+
+		if (buffer_first == XBEE_BUFFER_SIZE) {
+			buffer_first = 0;
+		}
 		xbee_buf[0] = XBEE_FRAME_START;
 		currentBufPos++;
 	}
 
 	int len = -1;
-	if (currentBufPos >= 3)
+	if (currentBufPos >= 3) {
 		len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8);
-		
+	}
+
 	while (len == -1 //packet length has not been read yet
-			|| currentBufPos < len + 4)
+		|| currentBufPos < len + 4)
 	{
 		if (currentBufPos == 3)
+		{
 			len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8);
-		if (queue_is_empty(xbee_queue))
+			if (len > 120)
+			{
+				WL_DEBUG_PRINT("Packet too large. Probably error in XBee transmission.\n");
+				currentBufPos = 0;
+				return -1;
+			}
+		}
+
+		// check if buffer is empty
+		if (buffer_first == buffer_last) {
 			return -1;
-		xbee_buf[currentBufPos++] = (char)(int)queue_remove(xbee_queue);
+		}
+		xbee_buf[currentBufPos++] = arrival_buf[buffer_first++];
+		if (buffer_first == XBEE_BUFFER_SIZE) {
+			buffer_first = 0;
+		}
 	}
-	
+
 	currentBufPos = 0;
-	
+
 	if (!xbee_verify_checksum(xbee_buf, len + 4))
 	{
 		WL_DEBUG_PRINT("XBee checksum failed.\r\n");
@@ -529,15 +783,20 @@
 	}
 
 	//we will take care of the packet
-	if (xbee_handle_packet(xbee_buf + 3, len))
-		return -1;
 	
-	if (dest == NULL)
+	ret = xbee_handle_packet(xbee_buf+3, len);
+	if (ret == 1) {
+		return 3;
+	}
+	
+	if (dest == NULL) {
 		return -1;
-	
+	}
+
 	int i;
-	for (i = 3; i < len + 3; i++)
+	for (i = 3; i < len + 3; i++) {
 		dest[i - 3] = xbee_buf[i];
+	}
 	return len;
 }
 
@@ -581,8 +840,7 @@
  * @param extra the hex value of the requested register
  * @param extraLen the length in bytes of extra
  **/
-void xbee_handle_at_command_response(char* command, char result,
-	char* extra, int extraLen)
+static void xbee_handle_at_command_response(char* command, char result, char* extra, int extraLen)
 {
 	if (result == 1)
 	{
@@ -593,7 +851,7 @@
 	WL_DEBUG_PRINT("AT");
 	WL_DEBUG_PRINT(command);
 	WL_DEBUG_PRINT(" command was successful.\r\n");
-		
+
 	if (command[0] == 'I' && command[1] == 'D')
 	{
 		xbee_panID = xbee_pending_panID;
@@ -611,13 +869,14 @@
 		WL_DEBUG_PRINT(".\r\n");
 		return;
 	}
-	
+
 	if (command[0] == 'M' && command[1] == 'Y' && extraLen != 0)
 	{
 		xbee_address = 0;
 		int i;
-		for (i = 0; i < extraLen; i++)
+		for (i = 0; i < extraLen; i++) {
 			xbee_address = (xbee_address << 8) + extra[i];
+		}
 
 		WL_DEBUG_PRINT("XBee address is ");
 		WL_DEBUG_PRINT_INT(xbee_address);
@@ -626,7 +885,9 @@
 		if (xbee_address == 0)
 		{
 			WL_DEBUG_PRINT("XBee 16-bit address must be set using ATMY.\r\n");
+			#ifndef ROBOT
 			exit(0);
+			#endif
 		}
 	}
 }
@@ -640,11 +901,12 @@
  *
  * @param packet the packet to handle
  * @param len the length of the packet
- * 
+ *
  * @return 1 if we have handled the packet, 0 otherwise
  */
-int xbee_handle_packet(char* packet, int len)
+static int xbee_handle_packet(char* packet, int len)
 {
+
 	char command[3] = {1, 2, 3};
 	if (len <= 0) //this should not happend
 	{
@@ -651,7 +913,7 @@
 		WL_DEBUG_PRINT("Non-positive packet length.\r\n");
 		return 0;
 	}
-	
+
 	switch ((unsigned char)packet[0]) //packet type
 	{
 		case XBEE_FRAME_STATUS:
@@ -661,8 +923,7 @@
 			command[0] = packet[2];
 			command[1] = packet[3];
 			command[2] = 0;
-			xbee_handle_at_command_response(command,
-				packet[4], packet + 5, len - 5);
+			xbee_handle_at_command_response(command, packet[4], packet + 5, len - 5);
 			return 1;
 	}
 	return 0;
@@ -673,7 +934,7 @@
  *
  * @param id the new personal area network (PAN) id
  **/
-void xbee_set_pan_id(int id)
+int xbee_set_pan_id(int id)
 {
 	char s[3];
 	s[0] = (id >> 8) & 0xFF;
@@ -680,15 +941,17 @@
 	s[1] = id & 0xFF;
 	s[2] = 0;
 	xbee_pending_panID = id;
-	xbee_send_modify_at_command("ID", s);
+	return xbee_send_modify_at_command("ID", s);
 }
 
 /**
  * Get the PAN ID for the XBee.
- * 
+ *
  * @return the personal area network id, or
  * XBEE_PAN_DEFAULT if it has not yet been set.
  **/
+//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
+// it reduces code size or not should be done to be sure.
 unsigned int xbee_get_pan_id()
 {
 	return xbee_panID;
@@ -697,23 +960,25 @@
 /**
  * Set the channel the XBee is using.
  *
- * @param channel the channel the XBee will not use, 
+ * @param channel the channel the XBee will not use,
  * between 0x0B and 0x1A
  *
  * @see xbee_get_channel
  **/
-void xbee_set_channel(int channel)
+int xbee_set_channel(int channel)
 {
 	if (channel < 0x0B || channel > 0x1A)
 	{
 		WL_DEBUG_PRINT("Channel out of range.\r\n");
-		return;
+		return -1;
 	}
+
 	char s[3];
 	s[0] = channel & 0xFF;
 	s[1] = 0;
 	xbee_pending_channel = channel;
-	xbee_send_modify_at_command("CH", s);
+
+	return xbee_send_modify_at_command("CH", s);
 }
 
 /**
@@ -723,6 +988,8 @@
  *
  * @see xbee_set_channel
  **/
+//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
+// it reduces code size or not should be done to be sure.
 int xbee_get_channel(void)
 {
 	return xbee_channel;
@@ -735,8 +1002,16 @@
  *
  * @return the 16-bit address of the XBee.
  **/
+//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
+// it reduces code size or not should be done to be sure.
 unsigned int xbee_get_address()
 {
 	return xbee_address;
 }
 
+#ifndef ROBOT
+void xbee_set_com_port(char* port)
+{
+	xbee_com_port = port;
+}
+#endif
