22 define (
"SERIAL_DEVICE_NOTSET", 0);
23 define (
"SERIAL_DEVICE_SET", 1);
24 define (
"SERIAL_DEVICE_OPENED", 2);
64 setlocale(LC_ALL,
"en_US");
66 $sysname = php_uname();
68 if (substr($sysname, 0, 5) ===
"Linux")
72 if($this->
_exec(
"stty --version") === 0)
74 register_shutdown_function(array($this,
"deviceClose"));
78 trigger_error(
"No stty availible, unable to run.", E_USER_ERROR);
81 elseif (substr($sysname, 0, 6) ===
"Darwin")
90 register_shutdown_function(array($this,
"deviceClose"));
97 elseif(substr($sysname, 0, 7) ===
"Windows")
99 $this->_os =
"windows";
100 register_shutdown_function(array($this,
"deviceClose"));
104 trigger_error(
"Host OS is neither osx, linux nor windows, unable to run.", E_USER_ERROR);
127 if ($this->_os ===
"linux")
129 if (preg_match(
"@^COM(\d+):?$@i", $device, $matches))
131 $device =
"/dev/ttyS" . ($matches[1] - 1);
134 if ($this->
_exec(
"stty -F " . $device) === 0)
136 $this->_device = $device;
141 elseif ($this->_os ===
"osx")
143 if ($this->
_exec(
"stty -f " . $device) === 0)
145 $this->_device = $device;
150 elseif ($this->_os ===
"windows")
152 if (preg_match(
"@^COM(\d+):?$@i", $device, $matches) and $this->
_exec(exec(
"mode " . $device .
" xon=on BAUD=9600")) === 0)
154 $this->_windevice =
"COM" . $matches[1];
155 $this->_device =
"\\.\com" . $matches[1];
161 trigger_error(
"Specified serial port is not valid", E_USER_WARNING);
166 trigger_error(
"You must close your device before to set an other one", E_USER_WARNING);
181 trigger_error(
"The device is already opened", E_USER_NOTICE);
187 trigger_error(
"The device must be set before to be open", E_USER_WARNING);
191 if (!preg_match(
"@^[raw]\+?b?$@", $mode))
193 trigger_error(
"Invalid opening mode : ".$mode.
". Use fopen() modes.", E_USER_WARNING);
197 $this->_dHandle = @fopen($this->_device, $mode);
199 if ($this->_dHandle !==
false)
201 stream_set_blocking($this->_dHandle, 0);
206 $this->_dHandle = null;
207 trigger_error(
"Unable to open the device", E_USER_WARNING);
223 if (fclose($this->_dHandle))
225 $this->_dHandle = null;
230 trigger_error(
"Unable to close the device", E_USER_ERROR);
254 trigger_error(
"Unable to set the baud rate : the device is either not set or opened", E_USER_WARNING);
258 $validBauds = array (
273 if (isset($validBauds[$rate]))
275 if ($this->_os ===
"linux")
279 $ret = $this->
_exec(
"stty -F " . $this->_device .
" raw speed -echo " . (
int) $rate, $out);
281 if ($this->_os ===
"osx")
283 $ret = $this->
_exec(
"stty -f " . $this->_device .
" " . (
int) $rate, $out);
285 elseif ($this->_os ===
"windows")
287 $ret = $this->
_exec(
"mode " . $this->_windevice .
" BAUD=" . $validBauds[$rate], $out);
293 trigger_error (
"Unable to set baud rate: " . $out[1], E_USER_WARNING);
310 trigger_error(
"Unable to set parity : the device is either not set or opened", E_USER_WARNING);
316 "odd" =>
"parenb parodd",
317 "even" =>
"parenb -parodd",
320 if (!isset($args[$parity]))
322 trigger_error(
"Parity mode not supported", E_USER_WARNING);
326 if ($this->_os ===
"linux")
328 $ret = $this->
_exec(
"stty -F " . $this->_device .
" " . $args[$parity], $out);
330 elseif ($this->_os ===
"osx")
332 $ret = $this->
_exec(
"stty -f " . $this->_device .
" " . $args[$parity], $out);
336 $ret = $this->
_exec(
"mode " . $this->_windevice .
" PARITY=" . $parity{0}, $out);
344 trigger_error(
"Unable to set parity : " . $out[1], E_USER_WARNING);
358 trigger_error(
"Unable to set length of a character : the device is either not set or opened", E_USER_WARNING);
363 if ($int < 5) $int = 5;
364 elseif ($int > 8) $int = 8;
366 if ($this->_os ===
"linux")
368 $ret = $this->
_exec(
"stty -F " . $this->_device .
" cs" . $int, $out);
370 elseif ($this->_os ===
"osx")
372 $ret = $this->
_exec(
"stty -f " . $this->_device .
" cs" . $int, $out);
376 $ret = $this->
_exec(
"mode " . $this->_windevice .
" DATA=" . $int, $out);
384 trigger_error(
"Unable to set character length : " .$out[1], E_USER_WARNING);
399 trigger_error(
"Unable to set the length of a stop bit : the device is either not set or opened", E_USER_WARNING);
403 if ($length != 1 and $length != 2 and $length != 1.5 and !($length == 1.5 and $this->_os ===
"linux"))
405 trigger_error(
"Specified stop bit length is invalid", E_USER_WARNING);
409 if ($this->_os ===
"linux")
411 $ret = $this->
_exec(
"stty -F " . $this->_device .
" " . (($length == 1) ?
"-" :
"") .
"cstopb", $out);
413 elseif ($this->_os ===
"osx")
415 $ret = $this->
_exec(
"stty -f " . $this->_device .
" " . (($length == 1) ?
"-" :
"") .
"cstopb", $out);
419 $ret = $this->
_exec(
"mode " . $this->_windevice .
" STOP=" . $length, $out);
427 trigger_error(
"Unable to set stop bit length : " . $out[1], E_USER_WARNING);
444 trigger_error(
"Unable to set flow control mode : the device is either not set or opened", E_USER_WARNING);
449 "none" =>
"clocal -crtscts -ixon -ixoff",
450 "rts/cts" =>
"-clocal crtscts -ixon -ixoff",
451 "xon/xoff" =>
"-clocal -crtscts ixon ixoff"
453 $windowsModes = array(
454 "none" =>
"xon=off octs=off rts=on",
455 "rts/cts" =>
"xon=off octs=on rts=hs",
456 "xon/xoff" =>
"xon=on octs=off rts=on",
459 if ($mode !==
"none" and $mode !==
"rts/cts" and $mode !==
"xon/xoff") {
460 trigger_error(
"Invalid flow control mode specified", E_USER_ERROR);
464 if ($this->_os ===
"linux")
465 $ret = $this->
_exec(
"stty -F " . $this->_device .
" " . $linuxModes[$mode], $out);
466 elseif ($this->_os ===
"osx")
467 $ret = $this->
_exec(
"stty -f " . $this->_device .
" " . $linuxModes[$mode], $out);
469 $ret = $this->
_exec(
"mode " . $this->_windevice .
" " . $windowsModes[$mode], $out);
471 if ($ret === 0)
return true;
473 trigger_error(
"Unable to set flow control : " . $out[1], E_USER_ERROR);
492 $return = exec (
"setserial " . $this->_device .
" " . $param .
" " . $arg .
" 2>&1");
494 if ($return{0} ===
"I")
496 trigger_error(
"setserial: Invalid flag", E_USER_WARNING);
499 elseif ($return{0} ===
"/")
501 trigger_error(
"setserial: Error with device file", E_USER_WARNING);
526 $this->_buffer .= $str;
528 if ($this->autoflush ===
true) $this->
serialflush();
530 usleep((
int) ($waitForReply * 1000000));
544 trigger_error(
"Device must be opened to read it", E_USER_WARNING);
548 if ($this->_os ===
"linux" || $this->_os ===
"osx")
552 $content =
""; $i = 0;
557 if ($i >
$count) $content .= fread($this->_dHandle, (
$count - $i));
558 else $content .= fread($this->_dHandle, 128);
559 }
while (($i += 128) === strlen($content));
564 $content .= fread($this->_dHandle, 128);
565 }
while (($i += 128) === strlen($content));
569 elseif ($this->_os ===
"windows")
572 $content =
""; $i = 0;
577 if ($i >
$count) $content .= fread($this->_dHandle, (
$count - $i));
578 else $content .= fread($this->_dHandle, 128);
579 }
while (($i += 128) === strlen($content));
584 $content .= fread($this->_dHandle, 128);
585 }
while (($i += 128) === strlen($content));
604 if (fwrite($this->_dHandle, $this->_buffer) !==
false)
612 trigger_error(
"Error while sending message", E_USER_WARNING);
629 trigger_error(
"Device must be opened", E_USER_WARNING);
638 if ($this->_dState !== SERIAL_DEVICE_CLOSED)
640 trigger_error(
"Device must be closed", E_USER_WARNING);
650 1 => array(
"pipe",
"w"),
651 2 => array(
"pipe",
"w")
654 $proc = proc_open($cmd, $desc, $pipes);
656 $ret = stream_get_contents($pipes[1]);
657 $err = stream_get_contents($pipes[2]);
662 $retVal = proc_close($proc);
664 if (func_num_args() == 2) $out = array($ret, $err);
sendMessage($str, $waitForReply=0.1)
const SERIAL_DEVICE_NOTSET
const SERIAL_DEVICE_OPENED
setSetserialFlag($param, $arg="")
confCharacterLength($int)