<?php
/////////////////////////////////////////////////////
// Demo-PHP-Script                                 //
// Es zeigt die Ansteuerung der GPIO-Ports und die //
// Uebergabe von Programmausgaben an die Webseite  //
/////////////////////////////////////////////////////

// Pfad zur GPIO-Schnittstelle, kann waehrend der Entwicklung
// durch einen beliebigen Dateipfad ersetzt werden
define("GPIOPATH","/sys/class/gpio/");


// Passwort-Hash (damit das Passwort "geheim" bleibt
// und nicht im Qelltext auftaucht)
$PW = '906072001efddf3e11e6d2b5782f4777fe038739';

// Fehlerbericht fuer alle Fehler einschalten
// und im Browser ausgeben
// Achtung: In der Produktionsversion die beiden Zeilen loeschen!
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Beginn der HTML-Seite
vorspann();
print '<H2>Demo fuer PHP-Automaten</H2>';

// Formularstatus checken; beim ersten Aufruf der Seite ist
// natuerlich kein Status vorhanden --> $status = "NIX"
$Status = (isset($_POST['STATUS']))? $_POST['STATUS'] : "NIX";

// weiterer Aufruf der Seite: Formular wurde ausgefuellt, 
// ensprechende reagieren
if ($Status == 'Absenden')
  {
  // Formulardaten pruefen
  // Verarbeitung der Text-Felder
  $Passwort = security_filter($_POST['Passwort']);
  $Passwort = trim($Passwort);
  check($Passwort,"Passwort");
  $Passwort = sha1($Passwort);
  // Passwort-Hases vergleichen
  if ($Passwort != $PW)
    {
    print '<h1>Sorry, falsches Passwort!</h1>';
    nachspann();
    exit;
    }
  print "<P><B>Vielen Dank, Ihre Angaben wurden folgenderma&szlig;en bearbeitet:</B><br /><br />\n";
  print '<br />Passwort (SHA1-Hash): ' . $Passwort . ', LEDs ' .
        $_POST['LED1'] . ' ' . $_POST['LED2'] . ' ' . $_POST['LED3'] . ' ' . $_POST['LED4'] .
        '<br /><br /><a href="javascript:history.back();"><B>Zur&uuml;ck</B></a><br />';

  // Hier die Verarbeitung der LEDs
  // ACHTUNG: Vorher muessen die GPIO-Ports initialisiert und das
  //          Zugriffsrecht fuer die Gruppe GPIO gesetzt sein
  //          (siehe RasPi_GPIO.html)
  // Port 17  27  22  23
  // LED   1   2   3   4
  $res = gpio_set_value('17', $_POST['LED1']);
  $res = gpio_set_value('27', $_POST['LED2']);
  $res = gpio_set_value('22', $_POST['LED3']);
  $res = gpio_set_value('23', $_POST['LED4']);

  // Die folgenden Beispiele zeigen wie man Shell-Kommandos
  // aufruft und deren Ausgaben an den Browser durchreicht.
  // Falls Usereingaben (Formulardaten) an diese Funktion weitergereicht werden, 
  // sollten Sie escapeshellarg() oder escapeshellcmd() verwenden.

  print "<pre>\nAusgabe des uname-Kommandos:\n";
  passthru('/bin/uname -a',$err);
  print "Fehlercode: $err</pre>\n";

  // Soll der Programm-Output vor der Ausgabe noch aufbereitet werden,
  // kann man ihn auch in einer Variablen speichern. Die Pufferung
  // der Ausgabe beginnt mit:
  ob_start();

  // Aufruf wie oben, nur landet der Output im "Output Buffer"
  print "<pre>\nAusgabe des uptime-Kommandos:\n";
  passthru('/usr/bin/uptime',$err);
  print "Fehlercode: $err</pre>\n";

  print "<pre>Ausgabe des date-Kommandos:\n";
  passthru('/bin/date  +%d.%m.%Y-%H:%M:%S',$err);
  print "Fehlercode: $err</pre>\n";

  // Nach den Kommandoaufrufen kann deren gepuffertere Output
  // in eine Variable uebernommen werden:
  $inhalte = ob_get_contents();

  // Der Puffer wird nicht mehr gebraucht, also ausleeren:
  ob_end_clean();

  // Kontrollausgabe der Variablen
  print $inhalte;

  // Man kann das Kommando auch, wie in der Shell ueblich, seine Ausgaben
  // in eine Datei, z. B. nach "/tmp/df.txt", umleiten lassen. Das
  // Verzeichnis "/tmp" ist in all solchen Fllen eine gute Wahl:
  system('df -k > /tmp/df.txt');

  print "<pre>Ausgabe des df-Kommandos:\n";

  // Die Datei wird mittels readfile() ausgegeben
  // (readfile() funktioniert wie das Kommando "cat" in der Shell):
  readfile('/tmp/df.txt');

  print "</pre>\n";

  // Die nicht mehr benoetigte Datei loeschen:
  unlink('/tmp/df.txt');
  }
else
  {
  // Keine Formulardaten vorhanden? Dann Formular ausgeben
  print '
   <P>
   <B>Bitte geben Sie das Passwort ein:</B>
   </P><P>
   <form action="'.$_SERVER['PHP_SELF'].'" method="POST">
   <table border="0" cellspacing="1" cellpadding="2">
     <tr>
      <td bgcolor="#eeeeee">Passwort</td>
      <td><input type="text" name="Passwort" value="" size="40"></td>
     </tr>
     <tr>
      <td bgcolor="#eeeeee">LED 1</td>
      <td><input type="radio" name="LED1" value="0" checked="checked">AUS
          <input type="radio" name="LED1" value="1">EIN</td>
     </tr>
     <tr>
      <td bgcolor="#eeeeee">LED 2</td>
      <td><input type="radio" name="LED2" value="0" checked="checked">AUS
          <input type="radio" name="LED2" value="1">EIN</td>
     </tr>
     <tr>
      <td bgcolor="#eeeeee">LED 3</td>
      <td><input type="radio" name="LED3" value="0" checked="checked">AUS
          <input type="radio" name="LED3" value="1">EIN</td>
     </tr>
     <tr>
      <td bgcolor="#eeeeee">LED 4</td>
      <td><input type="radio" name="LED4" value="0" checked="checked">AUS
          <input type="radio" name="LED4" value="1">EIN</td>
     </tr>
    <tr><td><br /><br /><input type="submit" name="STATUS" value="Absenden"></td>
     <td>&nbsp;</td></tr>
    </table>
    </form>
   </P>
  ';
  // Anstelle der Submit-Variablen fuer den Status kann auch ein Eingabetag
  // vom Typ "hidden" verwendet werden. Dann kann man beliebige Werte fuer
  // den Status verwenden und muss nicht das nehmen, was auch auf dem Button steht.
  }

nachspann();

// ================================== Funktionen =================================

// Check auf leeren String, ggf. Fehlermeldung und EXIT
function check($TVar, $Description)
  {
  if(empty($TVar))
    {
    print '<b><font color="#CC0000">
           Formular unvollst&auml;ndig ausgef&uuml;llt - bitte ' . $Description .
          ' angeben/korrigieren.<br />Nichts gespeichert!</b></font><br /><br />' .
          '<a href="javascript:history.back();"><B>Zur&uuml;ck</B></a><br />'."\n";
    nachspann();
    exit;
    }
  }

// HTML-Vorspann am Anfang
function vorspann()
{
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<link href="http://info.ee.hm.edu/favicon.ico" rel="shortcut icon" />
<link rel="stylesheet" type="text/css" href="http://info.ee.hm.edu/css/standard.css" title="standardstyle">
<META HTTP-EQUIV="content-type" CONTENT="text/html; CHARSET=iso-8859-1">
<META NAME="keywords" CONTENT="Elektrotechnik,Informationstechnik,FH,Hochschule Mnchen">
<title>Demoprogramm Projektpraktikum</title>
</head>
<body text="#000000" bgcolor="#ffffff" link="#000000" vlink="#000000" alink="#000000">
';
}

// HTML-Nachspann am Ende
function nachspann()
{
print '<BR /><BR /><BR />
<table align="center" bgcolor="#CCCCCC" width="90%" border="0" cellpadding="0" cellspacing="0">
  <tr>
   <td align="center">
     Bei Fragen wenden Sie sich an den Adminstrator, bla bla bla ...
   </td>
  </tr>
</table>
</body>
</html>
';
}


// Entfernt aus einem gequoteten String alle Quotes
function my_remove_slashes($st)
  {
  if (get_magic_quotes_gpc()) { return stripslashes($st); }
  else { return $st; }
  }


// Filtert "boese" Dinge
function security_filter($st)
  {
  $attribs = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|'.
             'onmousemove|onmouseout|onkeypress|onkeydown|onkeyup';

  $st = my_remove_slashes($st);
  $st = stripslashes(preg_replace("/$attribs/i", 'forbidden', $st));
  $st = strip_tags($st);
  $st = preg_replace('/;/',',',$st);
  return $st;
  }


//////////// Die folgenden Funktionen wurden auf der Seite "RasPi_GPIO_C.html" ////////////
//////////// beschrieben und sind hier nur einkopiert worden                   ////////////

// gibt den augenblicklichen Wert (0/1) des Pins zurueck
// oder einen leeren String im Fehlerfall
function gpio_get_value($pin)
  {
  $Val = '';
  if (gpio_is_exported($pin) && gpio_get_direction($pin) == 'in')
    { $Val = trim(file_get_contents(GPIOPATH.'gpio'.$pin.'/value')); }
  return $Val;
  }


// gibt den Wert in $value (0/1) auf dem Pin aus
function gpio_set_value($pin, $value)
  {
  if (gpio_is_exported($pin)
       && gpio_get_direction($pin) == 'out'
        && ($value == '0' || $value == '1'))
    {
    file_put_contents(GPIOPATH.'gpio'.$pin.'/value', $value);
    return true;
    }
  else
    { return false; }
  }


// prueft, ob der Pin exportiert ist
function gpio_is_exported($pin)
  {
  return file_exists(GPIOPATH.'gpio'.$pin.'');
  }


// gibt die eingestellte Richtung zurueck
function gpio_get_direction($pin)
  {
  $dir = '';
  if (gpio_is_exported($pin))
    { $dir = trim(file_get_contents(GPIOPATH.'gpio'.$pin.'/direction')); }
  return $dir;
  }


// Stellt die Richtung ein ($direction: 'in' oder 'out')
function gpio_set_direction($pin, $direction)
  {
  if (gpio_is_exported($pin)
       && ($direction == 'in' || $direction == 'out'))
    {
    file_put_contents(GPIOPATH.'gpio'.$pin.'/direction', $direction);
    return true;
    }
  else
    { return false; }
  }

?>
