Forum: Mikrocontroller und Digitale Elektronik AVR Net IO Daten direkt in MYSQL hochladen


von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Hallo geschätztes Forum,

vielleicht hat das der eine oder andere schonmal gemacht.

Ich habe ein Net IO (Atmega644) mit Robue's Firmware drauf. Ich sammle 
ein paar Wetterdaten und verwende momentan einen Cronjob, um meine 
gesammelten Daten auf die Datenbank (MYSQL) zu schieben.

Gibt es ne Möglichkeit oder anders gefragt, weiss jemand, wie ich mit 
meinem Net IO meine gesammelten Daten direkt auf die Datenbank lade, 
ohne einen Cronjob verwenden zu müssen?

Jetz schreiben sicherlich welche, die da ein paar Sicherheitsbedenken 
haben....aber für mich sind das "nur" Wetterdaten.......


Gruss Stefan

: Bearbeitet durch User
von net-io (Gast)


Lesenswert?

schaue dir mal das Ethersex-Projekt an: http://www.ethersex.de/

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn auf dem Zielserver (dem mit MySQL) auch PHP läuft, kannst du die 
Daten ans PHP POSTen - das geht mit einem Receiverskript. Hier ist was, 
das ein XML von einem Gameserver empfängt und in die Datenbank XWW2 
einträgt:
1
<?php
2
$pass = 'unique';
3
/*  parsestats parses the XML file sent by the gameserver and feeds the database from  it*/
4
/* comment the next 4 lines for offline testing, these are for online catchin' the XML file from the gameserver */ 
5
$mypost = file_get_contents("php://input");
6
// lets write what we got into 'tmp.xml'
7
$fp = fopen ("/tmp/tmp.xml","w");
8
fputs($fp,$mypost);
9
fclose($fp);
10
// from now on we process the XML file 
11
$xml = simplexml_load_file("/tmp/tmp.xml") or die ("what stuff is this ? rejected ");
12
// dann als Beispiel ein Eintrag in die Datenbank
13
foreach ($xml->xpath('//round') as $round) {
14
  $mname = $round['map'];  
15
  if ( $round['pcode'] != $pass ) die ("authorization failed, do not try that again !");
16
  $link = mysql_connect ("localhost","XWW2 ",$round['pcode']) or die ("Could not connect to mySQL ");  
17
  mysql_select_db("xww2") or die ( "database xww2 not found");
18
  $mplayers = 0;
19
  foreach ($xml->xpath('//playerdata') as $playerdata) {
20
    $pname = $playerdata['pname'];
21
    $pscore = $playerdata['pscore'];
22
// check if we have that pname already or add it
23
    $sqlab = "SELECT * FROM xww2_playerdata WHERE pname = \"$pname\"";
24
    $querie = mysql_db_query("xww2",$sqlab,$link) or die ("query invalid");
25
// theres more but truncated for clarity
26
                $numrows = mysql_num_rows($querie);     
27
// create a new entry when no entry found 
28
                if ($numrows < 1) { 
29
                  mysql_select_db("xww2") or die ( "database not found");
30
//                  echo 'creating new player entry' , '<br />';
31
                $insert = mysql_db_query("xww2","INSERT INTO xww2_playerdata (pname) values ('$pname') " ) or die ("insert did not work"); ;
32
                }             
33
// we now have a valid entry for that player                  
34
//    $querie = mysql_db_query("xww2","SELECT * from xww2_playerdata WHERE pname LIKE \"$pname\"",$link) or die ("query invalid");
35
    $sqlab = "UPDATE xww2_playerdata SET pco = \"$pco\", pid =\"$pid\" WHERE pname = \"$pname\" ";
36
    $querie = mysql_db_query("xww2",$sqlab , $link ) or die ("update fail");
37
// accumulate global scores 
38
    $sqlab = "UPDATE xww2_playerdata SET pscore = pscore + \"$pscore\", ";
39
// write into database
40
    $querie = mysql_db_query("xww2",$sqlab, $link ) or die ("global update fail " );
41
  mysql_close ($link);
42
}
43
?>
Da ist jetzt ne Menge weggelassen, aber das Prinzip bleibt das gleiche. 
Die Hauptarbeit ist es hier, aus dem empfangenen XML die Daten 
rauszufummeln und in die MySQL DB mundgerecht zu posten.

: Bearbeitet durch User
von Daniel (Gast)


Lesenswert?

Das PHP-Beispiel geht aber einfacher:
1
<?php
2
3
mysql_connect(...);
4
mysql_query($_GET["query"]);
5
mysql_close();
6
7
?>

und jetzt die supersichere Variante:
1
<?php
2
3
mysql_connect(...);
4
if( (false === strpos($_GET["query"], array("delete", "drop", "truncate")) && $_GET["password"] == "geheim") )
5
{
6
    mysql_query($_GET["query"]);
7
}
8
mysql_close();
9
10
?>

Mal im Ernst, im Prinzip geht es so, das Skript muss aber verhindern, 
dass ungewollte Anfragen an die DB gestellt werden können. D.h. das 
"INSERT INTO $tablename" sollte im PHP-Skript hartcodiert stehen und 
nicht vom Endgerät per GET/POST kommen.

von Axel S. (a-za-z0-9)


Lesenswert?

Daniel schrieb:
> Das PHP-Beispiel geht aber einfacher:

(schnipp)

> und jetzt die supersichere Variante:

(schnapp)

Aua. AUA. AUA!

1. man nimmt nie einen Querystring aus einem HTTP Parameter. Man nimmt 
nur Werte und fügt die nachdem man sie validiert und wenn es Strings 
waren, korrekt gequotet hat in eine vorgegebene Query ein.

2. ein Passwort in einem HTTP GET Parameter unzubringen ist ungefähr so 
sinnvoll, wie es auf ein Post-It zu schreiben und ans schwarze Brett zu 
kleben.

3. dein "Validator" für Queries ist ... suboptimal. Es gibt SQL 
Kommentare. Groß/Kleinschreibung. Verschiedene Encodings. Und evtl. 
möchte man ja auch sowas wie INSERT INTO foo VALUES ("der drops ist 
gelutscht") machen können.

Ich kann nur hoffen, daß kein PHP Code von dir auf öffentlich 
zugänglichen Webservern liegt.


XL

von Klaus (Gast)


Lesenswert?

Ob das Passwort nun im Query- oder POST-String steht ist doch piepegal, 
ist ja nicht so dass der Atmega den Aufruf im Internet Explorer macht 
und jemand in die URL-Leiste schauen könnte .. :D

von Stefan B. (sibbl) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hi @all,

erstmal danke für die Infos/Antworten. Ich habe es mir ein bißchen 
anders vorgestellt. Das, was ich bis jetz herausfinden konnte ist, dass 
in der Robue's Firmware bzw. in Radigs's Firmware ein http-get Befehl 
existiert. Nur weiss ich nicht, wie man das am einfachsten "codet".
Und zwar möchte ich gerne auf php verzichten, damit meine ich, dass der 
Befehl, der die Daten in die Datenbank schreibt, direkt vom Net IO 
ausgeführt wird.....mal jetz sämtliche Sicherheitsaspekte 
herausgenommen...wie gesagt, es sind Wetterdaten und der Aspekt 
"Sicherheit" ist für mich momentan sekundär.

Ich habe das Problem, dass das Net IO nicht auf jeden vom Cronjob 
ausgeführten Updatebefehl antwortet. Ich hätte gerne alle 5 Minuten ein 
Update, doch dazu muss ich minimum 3 mal den Net IO kontaktieren, bevor 
der mir ein einziges mal Daten ausspuckt.(siehe den Log)



Eine andere Lösung wäre noch, dass man dem PHP-Script beibringt, wenn 
ein Cronjob ausgeführt wird (upload.php):

------schnipp------

wenn das Net IO nicht beim ersten mal antwortet, solange einen 
Updatebefehl ausführen, bis die geforderten Daten übertragen 
sind......und das dann alle 5 Minuten.....usw usw usw......


------schnapp------

Aber da habe ich ebenfalls keinen blassen Dunst, wie sowas zu 
realisieren wäre.

Mein PHP hefte ich ebenfalls mal mit ran, vielleicht gibts ne Idee 
dazu....


Gruss

von Daniel (Gast)


Lesenswert?

Axel Schwenke schrieb:
>> und jetzt die supersichere Variante:
>
> (schnapp)
>
> Aua. AUA. AUA!

Irre, wie das hier immer funktioniert. Pawlows Hund ist nichts dagegen. 
Muss gleich noch mal einen Thread eröffnen, in dem ich Widerstand mit 
"ie" schreibe und ein großes Foto im .png-Format anhänge. ;-)

Tja, jetzt bin ich auf den mySQL-Client gespannt, der auf dem NetIO 
läuft, das Passwort verschlüsselt überträgt und verhindert, dass der 
Server beliebige mySQL-Kommandos ausführt, statt nur die gewünschten.

Stefan, wenn Du nicht herausfinden kannst, warum das NetIO nicht 
antwortet, müsstest Du es eben so oft probieren, bis etwas gültiges 
kommt, etwa so:
1
function getAVRNetIOValue($id) {
2
   $value = NULL;
3
   $avr_net_io = false;
4
   $retries = 0;
5
   error_reporting(0);
6
7
   while( (false === $avr_net_io) && ($retries < 10) )
8
   {
9
      $retries++;
10
      $avr_net_io = fopen("http://meine_URL_zum_NETIO", "r");
11
12
      if ($avr_net_io !== false) {
13
         [...(Dein Code)...]
14
         fclose($avr_net_io);
15
      }
16
   }
17
   return $value;
18
}

Oder doch den Spieß umdrehen und das NetIO zyklisch die Anfrage an den 
Server stellen lassen, wozu Du das herausfinden müsstest:
> Das, was ich bis jetz herausfinden konnte ist, dass
> in der Robue's Firmware bzw. in Radigs's Firmware ein http-get Befehl
> existiert. Nur weiss ich nicht, wie man das am einfachsten "codet".

Ich kenn das NetIO nicht, deshalb kann ich hier nicht helfen.

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

@Daniel:
Ist zwar schon ne Weile her......

Ich habe bis jetzt nicht rausfinden können, warum sich das NetIO 
sporadisch weigert, Daten für die Datenbank preis zu geben.

Ich habe aus diesem Grund den oben genannten Code eingebaut. Sieht jetzt 
besser aus. Danke nochmal dafür.....

Gruss Stefan

von mmmm (Gast)


Lesenswert?

Hi,

Bei mir hat geholfen dass fopen nur einmal in der update php aufzurufen 
anstatt über die Funktion einmal pro Wert.

Damit muss das NetIo nicht zig mal die Daten.htm erstellen.

Gruss micha

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Hi Micha,

ich habe leider nicht viel Plan von PHP. Ich weiss nicht, wie ich das 
anders schreiben kann.

Gruss Stefan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.