diff --git a/README.md b/README.md
index 941c341..462155c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,13 @@
 DC29BadgeBot
 ===============
 
-Bot to connect badge to IRC for sharing and validating codes
\ No newline at end of file
+Bot to connect badge to IRC for sharing and validating codes
+
+simply git clone this repo
+
+````
+php bot.php
+
+```
+
+the script will connect to ice.uplinkcorp.net #theSignal and interface with the serial device.
\ No newline at end of file

diff --git a/README.md b/README.md
index 941c341..462155c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,13 @@
 DC29BadgeBot
 ===============
 
-Bot to connect badge to IRC for sharing and validating codes
\ No newline at end of file
+Bot to connect badge to IRC for sharing and validating codes
+
+simply git clone this repo
+
+````
+php bot.php
+
+```
+
+the script will connect to ice.uplinkcorp.net #theSignal and interface with the serial device.
\ No newline at end of file
diff --git a/bot.php b/bot.php
new file mode 100644
index 0000000..6a26a82
--- /dev/null
+++ b/bot.php
@@ -0,0 +1,97 @@
+<?php
+set_time_limit(0);
+include 'php_serial.class.php';
+$badgeInterface = "/dev/ttyACM0";// EDIT THIS TO MATCH YOUR INTERFACE
+$collected = array();
+
+function get_code($code){
+    global $badgeInterface;
+    $result = preg_replace("/[^a-zA-Z0-9]+/", "", strtoupper(substr(trim($code), 0, 32)));
+    $serial = new PhpSerial;
+    $serial->deviceSet($badgeInterface); 
+    $serial->confBaudRate(9600);
+    $serial->deviceOpen('w+');
+    stream_set_timeout($serial->_dHandle, 3);
+    $serial->sendMessage("\r\n\r\n"."5"."$result"."\r\n");
+    $devResponse = $serial->readPort();
+    $serial->deviceClose();
+
+    $toReturn = trim(str_replace("Press ENTER to continue...", "", $devResponse));
+    $toReturn = substr($toReturn, -32);
+    return $toReturn;
+}
+
+function get_own_code(){
+    global $badgeInterface;
+    $serial = new PhpSerial;
+    $serial->deviceSet($badgeInterface); 
+    $serial->confBaudRate(9600);
+    $serial->deviceOpen('w+');
+    stream_set_timeout($serial->_dHandle, 3);
+    $serial->sendMessage("\r\n\r\n4\r\n");
+    $devResponse = $serial->readPort();
+    $serial->deviceClose();
+
+    $toReturn = trim(str_replace("Invalid Input. Please try again:", "", $devResponse));
+    $toReturn = trim(str_replace("Choose an option:", "", $toReturn));
+    //echo $toReturn; // DEBUG
+    $toReturn = substr($toReturn, -32);
+    return $toReturn;
+}
+
+$rand = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil(8/strlen($x)) )),1,8);
+
+$socket = fsockopen("ice.uplinkcorp.net", 6667);
+// Send auth info
+// fputs($socket, "PASS " . $password . "\n");
+fputs($socket, "NICK Badge-" . $rand . "\n");
+fputs($socket, "USER Badge-" . $rand . " 0 * :DC29 Badge Bot\n");
+fputs($socket, "JOIN #theSignal\n"); // Join channel
+
+// announce self to channel
+$myCode = get_own_code();
+fputs($socket, "PRIVMSG #theSignal :!req " . $rand . " " . $myCode . "\n"); 
+
+// Force an endless while
+while (1) {
+    // Continue the rest of the script here
+    while ($data = fgets($socket, 128)) {
+        echo $data;
+        flush();
+        
+        // Separate all data
+        $ex = explode(' ', $data);
+        
+        // Send PONG back to the server
+        if ($ex[0] == "PING") {
+            fputs($socket, "PONG " . $ex[1] . "\n");
+        }
+        
+        // executes chat command
+        if ($ex[0] != 'PING' && ISSET($ex[3])) {
+            $command = str_replace(array(
+                chr(10),
+                chr(13)
+            ), '', $ex[3]);
+            if ($command == ":!req") {
+                // 4 = bot name, 5 = their code
+                if(!in_array($ex[4], $collected)){ // not already added their code
+                    $response = get_code($ex[5]);
+                    if(preg_match("/^[0-9A-Fa-f]{32}/", $response)){ // valid code back
+                        fputs($socket, "PRIVMSG #theSignal :!rsp " . $ex[4] . " " . $response . "\n");
+                        array_push($collected, $ex[4]); // add to replied array
+                        $myCode = get_own_code();
+                        fputs($socket, "PRIVMSG #theSignal :!req " . $rand . " " . $myCode . "\n");
+
+                    }
+                }
+            }
+            if ($command == ":!rsp") {
+                if ($ex[4] == $rand){ // response is for this bot
+                    get_code($ex[5]);
+                }
+            }
+        }
+    }
+}
+?>

diff --git a/README.md b/README.md
index 941c341..462155c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,13 @@
 DC29BadgeBot
 ===============
 
-Bot to connect badge to IRC for sharing and validating codes
\ No newline at end of file
+Bot to connect badge to IRC for sharing and validating codes
+
+simply git clone this repo
+
+````
+php bot.php
+
+```
+
+the script will connect to ice.uplinkcorp.net #theSignal and interface with the serial device.
\ No newline at end of file
diff --git a/bot.php b/bot.php
new file mode 100644
index 0000000..6a26a82
--- /dev/null
+++ b/bot.php
@@ -0,0 +1,97 @@
+<?php
+set_time_limit(0);
+include 'php_serial.class.php';
+$badgeInterface = "/dev/ttyACM0";// EDIT THIS TO MATCH YOUR INTERFACE
+$collected = array();
+
+function get_code($code){
+    global $badgeInterface;
+    $result = preg_replace("/[^a-zA-Z0-9]+/", "", strtoupper(substr(trim($code), 0, 32)));
+    $serial = new PhpSerial;
+    $serial->deviceSet($badgeInterface); 
+    $serial->confBaudRate(9600);
+    $serial->deviceOpen('w+');
+    stream_set_timeout($serial->_dHandle, 3);
+    $serial->sendMessage("\r\n\r\n"."5"."$result"."\r\n");
+    $devResponse = $serial->readPort();
+    $serial->deviceClose();
+
+    $toReturn = trim(str_replace("Press ENTER to continue...", "", $devResponse));
+    $toReturn = substr($toReturn, -32);
+    return $toReturn;
+}
+
+function get_own_code(){
+    global $badgeInterface;
+    $serial = new PhpSerial;
+    $serial->deviceSet($badgeInterface); 
+    $serial->confBaudRate(9600);
+    $serial->deviceOpen('w+');
+    stream_set_timeout($serial->_dHandle, 3);
+    $serial->sendMessage("\r\n\r\n4\r\n");
+    $devResponse = $serial->readPort();
+    $serial->deviceClose();
+
+    $toReturn = trim(str_replace("Invalid Input. Please try again:", "", $devResponse));
+    $toReturn = trim(str_replace("Choose an option:", "", $toReturn));
+    //echo $toReturn; // DEBUG
+    $toReturn = substr($toReturn, -32);
+    return $toReturn;
+}
+
+$rand = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil(8/strlen($x)) )),1,8);
+
+$socket = fsockopen("ice.uplinkcorp.net", 6667);
+// Send auth info
+// fputs($socket, "PASS " . $password . "\n");
+fputs($socket, "NICK Badge-" . $rand . "\n");
+fputs($socket, "USER Badge-" . $rand . " 0 * :DC29 Badge Bot\n");
+fputs($socket, "JOIN #theSignal\n"); // Join channel
+
+// announce self to channel
+$myCode = get_own_code();
+fputs($socket, "PRIVMSG #theSignal :!req " . $rand . " " . $myCode . "\n"); 
+
+// Force an endless while
+while (1) {
+    // Continue the rest of the script here
+    while ($data = fgets($socket, 128)) {
+        echo $data;
+        flush();
+        
+        // Separate all data
+        $ex = explode(' ', $data);
+        
+        // Send PONG back to the server
+        if ($ex[0] == "PING") {
+            fputs($socket, "PONG " . $ex[1] . "\n");
+        }
+        
+        // executes chat command
+        if ($ex[0] != 'PING' && ISSET($ex[3])) {
+            $command = str_replace(array(
+                chr(10),
+                chr(13)
+            ), '', $ex[3]);
+            if ($command == ":!req") {
+                // 4 = bot name, 5 = their code
+                if(!in_array($ex[4], $collected)){ // not already added their code
+                    $response = get_code($ex[5]);
+                    if(preg_match("/^[0-9A-Fa-f]{32}/", $response)){ // valid code back
+                        fputs($socket, "PRIVMSG #theSignal :!rsp " . $ex[4] . " " . $response . "\n");
+                        array_push($collected, $ex[4]); // add to replied array
+                        $myCode = get_own_code();
+                        fputs($socket, "PRIVMSG #theSignal :!req " . $rand . " " . $myCode . "\n");
+
+                    }
+                }
+            }
+            if ($command == ":!rsp") {
+                if ($ex[4] == $rand){ // response is for this bot
+                    get_code($ex[5]);
+                }
+            }
+        }
+    }
+}
+?>
diff --git a/php_serial.class.php b/php_serial.class.php
new file mode 100644
index 0000000..c7ef423
--- /dev/null
+++ b/php_serial.class.php
@@ -0,0 +1,638 @@
+<?php
+define ("SERIAL_DEVICE_NOTSET", 0);
+define ("SERIAL_DEVICE_SET", 1);
+define ("SERIAL_DEVICE_OPENED", 2);
+
+/**
+ * Serial port control class
+ *
+ * THIS PROGRAM COMES WITH ABSOLUTELY NO WARANTIES !
+ * USE IT AT YOUR OWN RISKS !
+ * 
+ * Changes added by Rizwan Kassim <rizwank@uwink.com> for OSX functionality
+ * Further changes for OSX functionality added by Andrew Hutchings <andrew.hutchings@gmail.com>
+ * default serial device for osx devices is /dev/tty.serial for machines with a built in serial device
+ *
+ * @author Rémy Sanchez <thenux@gmail.com>
+ * @thanks Aurélien Derouineau for finding how to open serial ports with windows
+ * @thanks Alec Avedisyan for help and testing with reading
+ * @copyright under GPL 2 licence
+ */
+class phpSerial
+{
+    var $_device = null;
+    var $_windevice = null;
+    var $_dHandle = null;
+    var $_dState = SERIAL_DEVICE_NOTSET;
+    var $_buffer = "";
+    var $_os = "";
+
+    /**
+     * This var says if buffer should be flushed by sendMessage (true) or manualy (false)
+     *
+     * @var bool
+     */
+    var $autoflush = true;
+
+    /**
+     * Constructor. Perform some checks about the OS and setserial
+     *
+     * @return phpSerial
+     */
+    function phpSerial ()
+    {
+        setlocale(LC_ALL, "en_US");
+
+        $sysname = php_uname();
+
+        if (substr($sysname, 0, 5) === "Linux")
+        {
+            $this->_os = "linux";
+
+            if($this->_exec("stty --version") === 0)
+            {
+                register_shutdown_function(array($this, "deviceClose"));
+            }
+            else
+            {
+                trigger_error("No stty availible, unable to run.", E_USER_ERROR);
+            }
+        }
+        elseif (substr($sysname, 0, 6) === "Darwin")
+        {
+            $this->_os = "osx";
+
+            if($this->_exec("stty") === 0)
+            {
+                register_shutdown_function(array($this, "deviceClose"));
+            }
+            else
+            {
+                trigger_error("No stty availible, unable to run.", E_USER_ERROR);
+            }
+
+        }
+        elseif(substr($sysname, 0, 7) === "Windows")
+        {
+            $this->_os = "windows";
+            register_shutdown_function(array($this, "deviceClose"));
+        }
+        else
+        {
+            trigger_error("Host OS is neither osx, linux nor windows, unable to run.", E_USER_ERROR);
+            exit();
+        }
+    }
+
+    //
+    // OPEN/CLOSE DEVICE SECTION -- {START}
+    //
+
+    /**
+     * Device set function : used to set the device name/address.
+     * -> linux : use the device address, like /dev/ttyS0
+     * -> osx : use the device address, like /dev/tty.serial
+     * -> windows : use the COMxx device name, like COM1 (can also be used
+     *     with linux)
+     *
+     * @param string $device the name of the device to be used
+     * @return bool
+     */
+    function deviceSet ($device)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_OPENED)
+        {
+            if ($this->_os === "linux")
+            {
+                if (preg_match("@^COM(\d+):?$@i", $device, $matches))
+                {
+                    $device = "/dev/ttyS" . ($matches[1] - 1);
+                }
+
+                if ($this->_exec("stty -F " . $device) === 0)
+                {
+                    $this->_device = $device;
+                    $this->_dState = SERIAL_DEVICE_SET;
+                    return true;
+                }
+            }
+            elseif ($this->_os === "osx")
+            {
+
+                if (preg_match("@^COM(\d+):?$@i", $device, $matches))
+                {
+                    $device = "/dev/ttyS" . ($matches[1] - 1);
+                }
+
+                if ($this->_exec("stty -f " . $device) === 0)
+                {
+                    $this->_device = $device;
+                    $this->_dState = SERIAL_DEVICE_SET;
+                    return true;
+                }
+            }
+            elseif ($this->_os === "windows")
+            {
+                if (preg_match("@^COM(\d+):?$@i", $device, $matches) and $this->_exec(exec("mode " . $device)) === 0)
+                {
+                    $this->_windevice = "COM" . $matches[1];
+                    $this->_device = "\\.\com" . $matches[1];
+                    $this->_dState = SERIAL_DEVICE_SET;
+                    return true;
+                }
+            }
+
+            trigger_error("Specified serial port is not valid", E_USER_WARNING);
+            return false;
+        }
+        else
+        {
+            trigger_error("You must close your device before to set an other one", E_USER_WARNING);
+            return false;
+        }
+    }
+
+    /**
+     * Opens the device for reading and/or writing.
+     *
+     * @param string $mode Opening mode : same parameter as fopen()
+     * @return bool
+     */
+    function deviceOpen ($mode = "r+b")
+    {
+        if ($this->_dState === SERIAL_DEVICE_OPENED)
+        {
+            trigger_error("The device is already opened", E_USER_NOTICE);
+            return true;
+        }
+
+        if ($this->_dState === SERIAL_DEVICE_NOTSET)
+        {
+            trigger_error("The device must be set before to be open", E_USER_WARNING);
+            return false;
+        }
+
+        if (!preg_match("@^[raw]\+?b?$@", $mode))
+        {
+            trigger_error("Invalid opening mode : ".$mode.". Use fopen() modes.", E_USER_WARNING);
+            return false;
+        }
+
+        $this->_dHandle = @fopen($this->_device, $mode);
+
+        if ($this->_dHandle !== false)
+        {
+            stream_set_blocking($this->_dHandle, 0);
+            $this->_dState = SERIAL_DEVICE_OPENED;
+            return true;
+        }
+
+        $this->_dHandle = null;
+        trigger_error("Unable to open the device", E_USER_WARNING);
+        return false;
+    }
+
+    /**
+     * Closes the device
+     *
+     * @return bool
+     */
+    function deviceClose ()
+    {
+        if ($this->_dState !== SERIAL_DEVICE_OPENED)
+        {
+            return true;
+        }
+
+        if (fclose($this->_dHandle))
+        {
+            $this->_dHandle = null;
+            $this->_dState = SERIAL_DEVICE_SET;
+            return true;
+        }
+
+        trigger_error("Unable to close the device", E_USER_ERROR);
+        return false;
+    }
+
+    //
+    // OPEN/CLOSE DEVICE SECTION -- {STOP}
+    //
+
+    //
+    // CONFIGURE SECTION -- {START}
+    //
+
+    /**
+     * Configure the Baud Rate
+     * Possible rates : 110, 150, 300, 600, 1200, 2400, 4800, 9600, 38400,
+     * 57600 and 115200.
+     *
+     * @param int $rate the rate to set the port in
+     * @return bool
+     */
+    function confBaudRate ($rate)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_SET)
+        {
+            trigger_error("Unable to set the baud rate : the device is either not set or opened", E_USER_WARNING);
+            return false;
+        }
+
+        $validBauds = array (
+            110    => 11,
+            150    => 15,
+            300    => 30,
+            600    => 60,
+            1200   => 12,
+            2400   => 24,
+            4800   => 48,
+            9600   => 96,
+            19200  => 19,
+            38400  => 38400,
+            57600  => 57600,
+            115200 => 115200
+        );
+
+        if (isset($validBauds[$rate]))
+        {
+            if ($this->_os === "linux")
+            {
+                $ret = $this->_exec("stty -F " . $this->_device . " " . (int) $rate, $out);
+            }
+            if ($this->_os === "osx")
+            {
+                $ret = $this->_exec("stty -f " . $this->_device . " " . (int) $rate, $out);
+            }
+            elseif ($this->_os === "windows")
+            {
+                $ret = $this->_exec("mode " . $this->_windevice . " BAUD=" . $validBauds[$rate], $out);
+            }
+            else return false;
+
+            if ($ret !== 0)
+            {
+                trigger_error ("Unable to set baud rate: " . $out[1], E_USER_WARNING);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Configure parity.
+     * Modes : odd, even, none
+     *
+     * @param string $parity one of the modes
+     * @return bool
+     */
+    function confParity ($parity)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_SET)
+        {
+            trigger_error("Unable to set parity : the device is either not set or opened", E_USER_WARNING);
+            return false;
+        }
+
+        $args = array(
+            "none" => "-parenb",
+            "odd"  => "parenb parodd",
+            "even" => "parenb -parodd",
+        );
+
+        if (!isset($args[$parity]))
+        {
+            trigger_error("Parity mode not supported", E_USER_WARNING);
+            return false;
+        }
+
+        if ($this->_os === "linux")
+        {
+            $ret = $this->_exec("stty -F " . $this->_device . " " . $args[$parity], $out);
+        }
+        elseif ($this->_os === "osx")
+        {
+            $ret = $this->_exec("stty -f " . $this->_device . " " . $args[$parity], $out);
+        }
+        else
+        {
+            $ret = $this->_exec("mode " . $this->_windevice . " PARITY=" . $parity{0}, $out);
+        }
+
+        if ($ret === 0)
+        {
+            return true;
+        }
+
+        trigger_error("Unable to set parity : " . $out[1], E_USER_WARNING);
+        return false;
+    }
+
+    /**
+     * Sets the length of a character.
+     *
+     * @param int $int length of a character (5 <= length <= 8)
+     * @return bool
+     */
+    function confCharacterLength ($int)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_SET)
+        {
+            trigger_error("Unable to set length of a character : the device is either not set or opened", E_USER_WARNING);
+            return false;
+        }
+
+        $int = (int) $int;
+        if ($int < 5) $int = 5;
+        elseif ($int > 8) $int = 8;
+
+        if ($this->_os === "linux")
+        {
+            $ret = $this->_exec("stty -F " . $this->_device . " cs" . $int, $out);
+        }
+        elseif ($this->_os === "osx")
+        {
+            $ret = $this->_exec("stty -f " . $this->_device . " cs" . $int, $out);
+        }
+        else
+        {
+            $ret = $this->_exec("mode " . $this->_windevice . " DATA=" . $int, $out);
+        }
+
+        if ($ret === 0)
+        {
+            return true;
+        }
+
+        trigger_error("Unable to set character length : " .$out[1], E_USER_WARNING);
+        return false;
+    }
+
+    /**
+     * Sets the length of stop bits.
+     *
+     * @param float $length the length of a stop bit. It must be either 1,
+     * 1.5 or 2. 1.5 is not supported under linux and on some computers.
+     * @return bool
+     */
+    function confStopBits ($length)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_SET)
+        {
+            trigger_error("Unable to set the length of a stop bit : the device is either not set or opened", E_USER_WARNING);
+            return false;
+        }
+
+        if ($length != 1 and $length != 2 and $length != 1.5 and !($length == 1.5 and $this->_os === "linux"))
+        {
+            trigger_error("Specified stop bit length is invalid", E_USER_WARNING);
+            return false;
+        }
+
+        if ($this->_os === "linux")
+        {
+            $ret = $this->_exec("stty -F " . $this->_device . " " . (($length == 1) ? "-" : "") . "cstopb", $out);
+        } else if ($this->_os === "osx")
+        {
+            $ret = $this->_exec("stty -f " . $this->_device . " " . (($length == 1) ? "-" : "") . "cstopb", $out);
+        }
+        else
+        {
+            $ret = $this->_exec("mode " . $this->_windevice . " STOP=" . $length, $out);
+        }
+
+        if ($ret === 0)
+        {
+            return true;
+        }
+
+        trigger_error("Unable to set stop bit length : " . $out[1], E_USER_WARNING);
+        return false;
+    }
+
+    /**
+     * Configures the flow control
+     *
+     * @param string $mode Set the flow control mode. Availible modes :
+     *     -> "none" : no flow control
+     *     -> "rts/cts" : use RTS/CTS handshaking
+     *     -> "xon/xoff" : use XON/XOFF protocol
+     * @return bool
+     */
+    function confFlowControl ($mode)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_SET)
+        {
+            trigger_error("Unable to set flow control mode : the device is either not set or opened", E_USER_WARNING);
+            return false;
+        }
+
+        $linuxModes = array(
+            "none"     => "clocal -crtscts -ixon -ixoff",
+            "rts/cts"  => "-clocal crtscts -ixon -ixoff",
+            "xon/xoff" => "-clocal -crtscts ixon ixoff"
+        );
+        $windowsModes = array(
+            "none"     => "xon=off octs=off rts=on",
+            "rts/cts"  => "xon=off octs=on rts=hs",
+            "xon/xoff" => "xon=on octs=off rts=on",
+        );
+
+        if ($mode !== "none" and $mode !== "rts/cts" and $mode !== "xon/xoff") {
+            trigger_error("Invalid flow control mode specified", E_USER_ERROR);
+            return false;
+        }
+
+        if ($this->_os === "linux")
+            $ret = $this->_exec("stty -F " . $this->_device . " " . $linuxModes[$mode], $out);
+        elseif ($this->_os === "osx")
+            $ret = $this->_exec("stty -f " . $this->_device . " " . $linuxModes[$mode], $out);
+        else
+            $ret = $this->_exec("mode " . $this->_windevice . " " . $windowsModes[$mode], $out);
+
+        if ($ret === 0) return true;
+        else {
+            trigger_error("Unable to set flow control : " . $out[1], E_USER_ERROR);
+            return false;
+        }
+    }
+
+    /**
+     * Sets a setserial parameter (cf man setserial)
+     * NO MORE USEFUL !
+     *     -> No longer supported
+     *     -> Only use it if you need it
+     *
+     * @param string $param parameter name
+     * @param string $arg parameter value
+     * @return bool
+     */
+    function setSetserialFlag ($param, $arg = "")
+    {
+        if (!$this->_ckOpened()) return false;
+
+        $return = exec ("setserial " . $this->_device . " " . $param . " " . $arg . " 2>&1");
+
+        if ($return{0} === "I")
+        {
+            trigger_error("setserial: Invalid flag", E_USER_WARNING);
+            return false;
+        }
+        elseif ($return{0} === "/")
+        {
+            trigger_error("setserial: Error with device file", E_USER_WARNING);
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    //
+    // CONFIGURE SECTION -- {STOP}
+    //
+
+    //
+    // I/O SECTION -- {START}
+    //
+
+    /**
+     * Sends a string to the device
+     *
+     * @param string $str string to be sent to the device
+     * @param float $waitForReply time to wait for the reply (in seconds)
+     */
+    function sendMessage ($str, $waitForReply = 0.1)
+    {
+        $this->_buffer .= $str;
+
+        if ($this->autoflush === true) $this->serialflush();
+
+        usleep((int) ($waitForReply * 1000000));
+    }
+
+    /**
+     * Reads the port until no new datas are availible, then return the content.
+     *
+     * @pararm int $count number of characters to be read (will stop before
+     *     if less characters are in the buffer)
+     * @return string
+     */
+    function readPort ($count = 0)
+    {
+        if ($this->_dState !== SERIAL_DEVICE_OPENED)
+        {
+            trigger_error("Device must be opened to read it", E_USER_WARNING);
+            return false;
+        }
+
+        if ($this->_os === "linux" || $this->_os === "osx")
+            {
+            // Behavior in OSX isn't to wait for new data to recover, but just grabs what's there!
+            // Doesn't always work perfectly for me in OSX
+            $content = ""; $i = 0;
+
+            if ($count !== 0)
+            {
+                do {
+                    if ($i > $count) $content .= fread($this->_dHandle, ($count - $i));
+                    else $content .= fread($this->_dHandle, 128);
+                } while (($i += 128) === strlen($content));
+            }
+            else
+            {
+                do {
+                    $content .= fread($this->_dHandle, 128);
+                } while (($i += 128) === strlen($content));
+            }
+
+            return $content;
+        }
+        elseif ($this->_os === "windows")
+        {
+            /* Do nothing : not implented yet */
+        }
+
+        trigger_error("Reading serial port is not implemented for Windows", E_USER_WARNING);
+        return false;
+    }
+
+    /**
+     * Flushes the output buffer
+     * Renamed from flush for osx compat. issues
+     *
+     * @return bool
+     */
+    function serialflush ()
+    {
+        if (!$this->_ckOpened()) return false;
+
+        if (fwrite($this->_dHandle, $this->_buffer) !== false)
+        {
+            $this->_buffer = "";
+            return true;
+        }
+        else
+        {
+            $this->_buffer = "";
+            trigger_error("Error while sending message", E_USER_WARNING);
+            return false;
+        }
+    }
+
+    //
+    // I/O SECTION -- {STOP}
+    //
+
+    //
+    // INTERNAL TOOLKIT -- {START}
+    //
+
+    function _ckOpened()
+    {
+        if ($this->_dState !== SERIAL_DEVICE_OPENED)
+        {
+            trigger_error("Device must be opened", E_USER_WARNING);
+            return false;
+        }
+
+        return true;
+    }
+
+    function _ckClosed()
+    {
+        if ($this->_dState !== SERIAL_DEVICE_CLOSED)
+        {
+            trigger_error("Device must be closed", E_USER_WARNING);
+            return false;
+        }
+
+        return true;
+    }
+
+    function _exec($cmd, &$out = null)
+    {
+        $desc = array(
+            1 => array("pipe", "w"),
+            2 => array("pipe", "w")
+        );
+
+        $proc = proc_open($cmd, $desc, $pipes);
+
+        $ret = stream_get_contents($pipes[1]);
+        $err = stream_get_contents($pipes[2]);
+
+        fclose($pipes[1]);
+        fclose($pipes[2]);
+
+        $retVal = proc_close($proc);
+
+        if (func_num_args() == 2) $out = array($ret, $err);
+        return $retVal;
+    }
+
+    //
+    // INTERNAL TOOLKIT -- {STOP}
+    //
+}
+?>
\ No newline at end of file