<?php
/**
 * Zugriff auf GPIO Ports des Beagleboards
 * 
 * @author Thomas Eimers <notdefine@gmx.de>
*/
class InterfaceGpio {

	/** Port auf 1,8 Volt */
	const level_up='high';
	/** Port auf 0 Volt */
	const level_down='low';

	/** Debbuging ein/aus */
	const debug=false;

	private $auto_release=false;
	
	/**
	 * Verfügbare Portadressen und Alias
	*/
	public $output_ports=array(
		'orange'=>'159',
 		'red'=>'161',
 		'green'=>'158'
	);

	/**
	 * Alle Verfügbaren Ausgänge auf "1"
	*/
	public function allOn() {
		foreach ($this->output_ports AS $color => $port) {
			$this->setPort($color, true);
		}
	}

	/**
	 * Alle Verfügbaren Ausgänge auf "0"
	*/
	public function allOff() {
		foreach ($this->output_ports AS $color => $port) {
			$this->setPort($color, false);
		}
	}

	
	/**
	 * Einzelnen Port auf "1" oder "0" setzen
	 * 
	 * @param $portname Alias für die Portbezeichnung siehe $output_ports
	 * @param $status	 (bool) neuer Port status
	 */
	public function setPort($portname, $status) {
	
		if (!is_bool($status)) {
			throw new BadMethodCallException('Portstatus not valid');
		}
		
		if (empty($this->output_ports[$portname])) {
			throw new BadMethodCallException('Unknown Port alias: '.$portname);
		}
		
		if ($status) {
			$cmd='echo "'.InterfaceGpio::level_up.'" > /sys/class/gpio/gpio'.$this->output_ports[$portname].'/direction';
		} else {
			$cmd='echo "'.InterfaceGpio::level_down.'" > /sys/class/gpio/gpio'.$this->output_ports[$portname].'/direction';
		}
		return $this->passthru($cmd);
	}
	
	/**
	 * Shell Befehl per 'sudo' ausführen
	 * 
	 * @param $cmd Befehl
	 * @param $sudo	(bool) als Root ausführen
	 * @return $result
	 */
	public function passthru($cmd, $sudo=false) {
		if ($sudo) {
			$cmd="sudo su root -c '".$cmd."'";
		}
		if (self::debug) {
			echo $cmd.PHP_EOL;
		}
		passthru ($cmd, $return_var);
		return $return_var;
	}
	
	
	public function __construct($auto_release=false) {
		// Nach Skript die Ports zurücksetzen?
		$this->auto_release=$auto_release;
		$this->bindAllPorts();
	}

	public function __destruct() {
		$this->releaseAllPorts();
	}

	/**
	 * Alle Ports verfügbar machen
	*/
	public function bindAllPorts() {
		echo "Bind ports...".PHP_EOL;
		foreach ($this->output_ports AS $color => $port) {
			$cmd="echo ".$port." > /sys/class/gpio/export";
			if ($this->passthru($cmd, true)===false) {
				echo "Could not bind Port".$color.'/'.$port.PHP_EOL;
			}
		}
		
		// Durch ein Chown gehören die Ports dem Apache, und der Zugriff auf diese Ports
		// benötigt dann kein sudo mehr, das ist dann wesentlich performanter
		echo "chown of Ports".PHP_EOL;
		foreach ($this->output_ports AS $color => $port) {
			$cmd='chown www-data /sys/devices/virtual/gpio/gpio'.$port.'/*';
			if ($this->passthru($cmd, true)===false) {
				echo "Could not chown Port".$color.'/'.$port.PHP_EOL;
			}
		}
	}

	/**
	 * Alle verwendeten Ports freigeben
	*/
	public function releaseAllPorts() {
		if (!$this->auto_release) {
			return;
		}
		echo "Release ports...\n".PHP_EOL;
		foreach ($this->output_ports AS $color => $port) {
			$cmd="echo ".$port." > /sys/class/gpio/unexport";
			if ($this->passthru($cmd, true)===false) {
				echo "Could not bind Port".$color.'/'.$port.PHP_EOL;
			}
		}
		
	}
}
?>