Forum: Mikrocontroller und Digitale Elektronik LWIP CGI Rückgabe wert


von heiko (Gast)


Lesenswert?

Ich arbeite mit dem LWIP WEBSERVER Beispiel von ST.

Ich wollte nun gern wenn ich ein Button auf der HTML Seite drücke mir 
ein gif Bild angezeigt wird.

Es wird aber nun kei Bild angezeigt.

Vielleicht könnte mir wer weiterhelfen.

Anbei mal soweit ich das bis jetzt habe.





Hier die HTML
1
            
2
            <box_10_img>       
3
                <img id="kinoa"  src="/E_off.gif"  width="64" height="64" alt="layer">          
4
                  </box_10_img>
5
          
6
                <input type=button class="box_10_but1" value="UP" onClick="Kino_1a(1)">


Hier die JSON
1
          var xmlhttp;
2
          var text;
3
          var count;
4
5
          function loadXMLDoc(url,cfunc)
6
          {
7
            if (window.XMLHttpRequest)
8
            {
9
              xmlhttp=new XMLHttpRequest();
10
            }
11
            
12
            else
13
            {
14
              xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
15
            }
16
           xmlhttp.onreadystatechange=cfunc;
17
           xmlhttp.open("GET",url,true);
18
           xmlhttp.send();
19
          }
20
21
22
          function toQueryString( p )
23
          {
24
           var ret = "";
25
            for( var k in p )
26
              ret += ( ret=='' ? '?' : '&' ) + encodeURIComponent(k) + '=' + encodeURIComponent(p[k]);
27
            return ret;
28
          }
29
30
          //_Statusabfrage
31
                    function get( url, onload, onerror )
32
          {
33
                        var xhr = new XMLHttpRequest();
34
            xhr.onload = function(){
35
            
36
              if( this.status != 200 )
37
              {
38
                if(onerror)
39
                  onerror( "Error " + this.status );
40
                
41
                }else{
42
                  var mime = this.getResponseHeader("Content-Type");
43
                  var text = this.responseText;
44
                  
45
                    if( onload )
46
                      onload( mime, text );
47
                  }
48
                 };
49
  
50
                      xhr.onerror = function(){
51
                        var error = this.error || this;
52
    
53
                          if( onerror )
54
                                onerror( error.message );
55
                            };
56
                       
57
              xhr.open( "GET", url );
58
                        xhr.send();
59
                    }
60
          
61
          function getFormFields(form){
62
            var e = form.querySelectorAll("input,select");
63
            var res = {};
64
            for( var i=0, n=e.length; i<n; i++ ){
65
              if( !e[i].name )
66
                continue;
67
              res[e[i].name] = e[i].value;
68
            }
69
            return res;
70
          }
71
72
73
74
          function Kino_1a( event)
75
          {
76
            loadXMLDoc("/l_kinoa.cgi" + toQueryString({kinoa: event,t: Math.random()}),
77
  
78
              function()
79
              {
80
                if( xmlhttp.readyState==4 && xmlhttp.status==200 )
81
                {
82
                  document.getElementById("kinoa").src = xmlhttp.responseText;
83
                }
84
              }
85
            );
86
            }



Hier die CGI
1
 char *KINO_1_CGIHandler( int iIndex, int iNumParams, char *pcParam[], char *pcValue[] )
2
{
3
  uint32_t i=0;
4
  int  index;
5
 
6
  
7
  
8
  /* We have only one SSI handler iIndex = 0 */
9
  index = FindCGIParameter ( "kinoa", pcParam, iNumParams );
10
  //clear_response_bufer(data_response_buf);     
11
12
  if(index != -1)
13
  {
14
    /* Check cgi parameter : example GET  */
15
    for (i=0; i<iNumParams; i++)
16
    {
17
      /* check parameter "kinoa" */
18
      if (strcmp(pcParam[i] , "kinoa")==0)   
19
      {
20
        /* switch + */
21
        if(strcmp(pcValue[i], "1") ==0) 
22
        {
23
          if (licht[0] < 100)                     // 
24
           {
25
             licht[0] +=25;        
26
27
           }          
28
        }  
29
        
30
        /* switch -*/
31
        else if(strcmp(pcValue[i], "2") ==0) 
32
        {  
33
          if (licht[0] > 0)                     // 
34
           {
35
             licht[0] -=25;
36
37
);
38
           } 
39
        }
40
        
41
       if (licht[0]  == 0) 
42
       {  
43
        strcat((char *)(data_response_buf),"/E_off.gif");
44
        //Lamp_off(); 
45
       }    
46
47
       else if (licht[0]  == 25) 
48
       {  
49
        strcat((char *)(data_response_buf),"/F_25.gif");
50
        //Lamp_25(); 
51
       }              
52
53
       else if (licht[0]  == 50) 
54
       {  
55
        strcat((char *)(data_response_buf),"/F_50.gif");  
56
        //Lamp_50(); 
57
       }    
58
59
       else if (licht[0]  == 75) 
60
       {  
61
        strcat((char *)(data_response_buf),"/F_75.gif");  
62
        //Lamp_75(); 
63
       }  
64
65
       else if (licht[0]  == 100) 
66
       {  
67
        strcat((char *)(data_response_buf),"/F_100.gif");
68
        //Lamp_100(); 
69
       }             
70
      }
71
    }    
72
  }
73
  /* uri to send after cgi call*/
74
 return RESPONSE_PAGE_SET_CGI_RSP_URL;
75
 
76
}

von Stefan F. (Gast)


Lesenswert?

> Es wird aber nun kei Bild angezeigt.

Das ist zu wenig Fehlerbeschreibung.

Benutze den Debugger im Browser (F12). Im Console Tab wird er Fehler 
melden und im Netzwerk Tab kannst du analysieren, was zwischen Browser 
und Server übertragen wurde.

Momentan ist mir noch nicht klar, was du da genau machen willst. Ich 
rate mal, bitte antworte, ob das so richtig ist:

Deine HTML Datei enthält ein Image mit der id "kinoa". Das Javascript 
sendet irgendwelche Formuarfelder an den Server, der anschließen mit 
neuen einem Dateinamen für das Bild antworten soll. Anschließend tauscht 
das Javascript den Dateinamen von dem HTML Element aus.

Ist das so richtig?

Prüfe, ob diese einzelnen Schritte tatsächlich stattfinden. Dein 
Javascript kann dazu hilfreiche Debug Meldungen ins Konsole Fenster 
schreiben, du musst sie nur einfügen. Außerdem kannst du prüfen, ob es 
den Dateinamen wirklich erfolgreich ausgewechselt hat.

Wo ich mir unsicher bin: Wird die Webseite eigentlich automatisch neu 
gerendert, wenn man den Dateinamen ändert? Prüfe das (es sei denn du 
bist Dir da bereits sehr sicher, dass es geht), und zwar unabhängig vom 
Mikrocontroller. Dein Javascript könnte per Timer getriggert werden und 
dann mal ein anderes Bild einsetzen. Wird das dann sichtbar?

Ich habe diese Aufgabe bisher immer anders gelöst, mit zwei 
unterschiedlichen Methoden:

a) Der Server liefert nach jedem Submit eine komplette HTML Seite 
zurück, wo der Name des Bildes (schon vom Server) ausgetauscht ist. Aus 
Sicht des Browsers ist das also eine ganz simple normale HTML Seite, 
gerne ohne Javascript.

b) Die Seite enthält von Anfang an alle Bilder aber mit 
style="display:none", danach kann das Javascript entscheiden, welches 
dieser Bilder sichtbar werden soll.

Das alles löst dein Problem nicht direkt, aber soll Dir helfen, es 
weiter zu analysieren.

von heiko (Gast)


Lesenswert?

Hallo,

wenn ich die Seite im Browser aufrufe wird diese auch korrekt angezeigt 
auch mit dem Image <img id="kinoa"  src="/E_off.gif"  width="64" 
height="64" alt="layer"> also die Lampe aus wird so richtig angezeigt.


wenn ich nun auf den Button drücke soll der Wert von Licht erhöht werden 
und je nach diesem wert das entsprechende IMG angezeigt werden.
Wenn ich zb. im Browser 192.168.2.149/F_75.gif eingebe wird mir auch das 
Bild angezeigt.

Das CGI wird auch durchlaufen und jenachdem wie oft der Button gedrückt 
wurde erhöht sich auch der Wert von licht[0].


Wenn ich dann F12 drücke im Browser und dann den Button up bekomme ich 
als Fehler :: HTTP404: NICHT GEFUNDEN: Der Server hat keine 
Übereinstimmungen für den angeforderten URI


1
#define RESPONSE_BUF_SIZE 1490   //
2
unsigned char data_response_ssi[RESPONSE_BUF_SIZE+14] =
3
{
4
  /* /response.ssi */
5
  0x2F, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 
6
  0x65, 0x2E, 0x73, 0x73, 0x69, 0x00, 
7
};

von Stefan F. (Gast)


Lesenswert?

Ich kann dein Problem nicht nachvollziehen. Die folgende Seite 
funktioniert bei mir tadellos, daher vermute ich, dass dein Javascript 
Ok ist:
1
<html>
2
    <script>
3
        function timeout()
4
        {
5
            document.getElementById("bild").src = "/gruen.png";
6
        }
7
    </script>
8
9
    <body onload="window.setTimeout(timeout,2000);">
10
        <img id="bild" src="/rot.png">
11
    </body>
12
</html>

Test: http://stefanfrings.de/test.html

Wegen dem Error 404 würde ich mal überprüfen, welche URL der Browser vom 
Server anfordert und was der Server damit anstellt.

Tritt der HTTP Error 404 beim Aufrufen des CGI oder beim Laden des 
Bildes auf?

von heiko (Gast)


Lesenswert?

Stefanus F. schrieb:
> Ich kann dein Problem nicht nachvollziehen.
>
Wenn ich die Seite aufrufe wird mir auch das Bild korrekt angezeigt.

wenn ich den button auf der Seite drücke ändert sich das Bild nicht, 
also der Rückgabe wert vom CGI passt auch nicht vermutlich.




> Wegen dem Error 404 würde ich mal überprüfen, welche URL der Browser vom
> Server anfordert und was der Server damit anstellt.
>
> Tritt der HTTP Error 404 beim Aufrufen des CGI oder beim Laden des
> Bildes auf?

Der Tritt erst auf beim Aufruf des CGI

HTTP404: NICHT GEFUNDEN: Der Server hat keine Übereinstimmungen für den 
angeforderten URI (Uniform Resource Identifier) gefunden.
GET - http://192.168.2.149/GIF89a@

von Stefan F. (Gast)


Lesenswert?

heiko schrieb:
> wenn ich den button auf der Seite drücke ändert sich das Bild nicht,
> also der Rückgabe wert vom CGI passt auch nicht vermutlich.

Das kannst du ja im Debugger prüfen. Schau Dir an, was das CGI zurück 
liefert und wie der Seitenquelltext danach aussieht. Du kannst sogar 
Unterbrechungspunkte ins Javascript setzen und es Zeile für Zeile 
ausführen.

> GET - http://192.168.2.149/GIF89a@

Das ist sicher nicht die erwartete URL. Also sendet der Browser eine 
falsche URL an den Server, dieser ruft das CGI daher nicht auf.

Andererseits schriebst du:

> Das CGI wird auch durchlaufen und jenachdem wie oft der Button
> gedrückt wurde erhöht sich auch der Wert von licht[0].

Das passt nicht zusammen.

von heiko (Gast)


Lesenswert?

Ich lasse mir ja den Wert licht[0] per

printf(" %d\r\n", licht[0]);

ausgeben daran sehe ich ja wenn ich den Button drücke dann ändert sich 
auch der Wert von daher wird das cgi ja auch aufgerufen.

Bloss der Rückgabe wert vom CGI wie mache ich das

1
 char *KINO_1_CGIHandler( int iIndex, int iNumParams, char *pcParam[], char *pcValue[] )
2
{
3
  uint32_t i=0;
4
  int  index;
5
 
6
  
7
  
8
  /* We have only one SSI handler iIndex = 0 */
9
  index = FindCGIParameter ( "kinoa", pcParam, iNumParams );
10
  clear_response_bufer(data_response_buf);     
11
12
             licht[0] +=25;        
13
printf("%d\r\n", licht[0]);
14
15
  /* uri to send after cgi call*/
16
// return RESPONSE_PAGE_SET_CGI_RSP_URL;
17
  return  "/F_100.Gif";  
18
}

von Stefan F. (Gast)


Lesenswert?

Ich versuche es nochmal anders: Welche bedeutung hat in deiner Anwendung 
"GIF89a@"?

Ich weiß zufällig auswendig, dass jede GIF Datei mit dieser Zeichenfolge 
beginnt. Sicher macht es keinen Sinn für den CGI, den Inhalt einer GIF 
Datei zu übermitteln.

Da liegt der Hase im Pfeffer.

von Sascha W. (sascha-w)


Lesenswert?

GIF89a ist der Inhalt der gif-Datei!
Die Funktion des JavaScripts kann ich nicht ganz nachvollziehen, scheint 
irgendwie die Datei selbst schon zu laden und das Ergebnis dann der 
img.src zuzuordnen.

Sascha

von heiko (Gast)


Lesenswert?

Stefanus F. schrieb:
> Ich versuche es nochmal anders: Welche bedeutung hat in deiner Anwendung
> "GIF89a@"?
>
der Inhalt der GIF Datei oder irre ich mich


> Ich weiß zufällig auswendig, dass jede GIF Datei mit dieser Zeichenfolge
> beginnt. Sicher macht es keinen Sinn für den CGI, den Inhalt einer GIF
> Datei zu übermitteln.
>
> Da liegt der Hase im Pfeffer.

ich hatte ja schon geschrieben was das cgi machen soll , je nach dem was 
licht[0] für ein Wert hat soll mir das auf der html seite angezeigt 
werden.

von Stefan F. (Gast)


Lesenswert?

heiko schrieb:
> ich hatte ja schon geschrieben was das cgi machen soll , je nach dem was
> licht[0] für ein Wert hat soll mir das auf der html seite angezeigt
> werden.

Das CGI soll den Namen einer GIF Datei liefern, damit das Javascript 
diesen in die Seite einfügt, damit der Browser diese Datei lädt.

Tatsächlich liefert es aber offensichtlich den Inhalt der GIF Datei.

Man beachte die Kommentare:
1
  /* uri to send after cgi call*/
2
  // return RESPONSE_PAGE_SET_CGI_RSP_URL;
3
  return  "/F_100.Gif";

Offensichtlich ist hier vorgesehen, dass du mit "return" bestimmst, 
welche Datei serverseitig geladen werden soll, deren Inhalt an den 
Browser geliefert wird.

Du willst aber nicht den Inhalt der Datei liefern, sondern einfach nur 
den String "/F_100.Gif". Finde heraus, wie das geht.

von Stefan F. (Gast)


Lesenswert?

Wenn du uns verraten würdest, wie die von dir verwendete Bibliothek 
heißt und wo sie dokumentiert ist, könnten wir gezielter helfen.

lwip ist es jedenfalls nicht, das ist höchstens der IP Stack, der deinem 
ganzen Konstrukt zugrunde liegt.

von heiko (Gast)


Angehängte Dateien:

Lesenswert?

Stefanus F. schrieb:
> Wenn du uns verraten würdest, wie die von dir verwendete
> Bibliothek
> heißt und wo sie dokumentiert ist, könnten wir gezielter helfen.
>
> lwip ist es jedenfalls nicht, das ist höchstens der IP Stack, der deinem
> ganzen Konstrukt zugrunde liegt.

Doch das ist LWIP.
Im Anhang mal relevante Teile vom Projekt welches auch Funkktioniert.

von Stefan F. (Gast)


Lesenswert?

heiko schrieb:
> Doch das ist LWIP.

Da muss noch mehr hinter stecken, denn "FindCGIParameter" gibt es nicht 
in der Doku von lwip.

Das ZIP File reicht nicht, daran kann ich weder erkennen, wie die return 
Werte der CGI Handler weiter verarbeitet werden, noch kann ich daraus 
ableiten, welches Framework dahinter steckt um dessen Doku zu finden.

Jedenfalls hat dein Problem nichts mit lwip zu tun, sondern damit, dass 
du nicht weißt, wie diese CGI Handler auszusehen haben.

von heiko (Gast)


Angehängte Dateien:

Lesenswert?

Stefanus F. schrieb:
> heiko schrieb:
>> Doch das ist LWIP.
>
> Da muss noch mehr hinter stecken, denn "FindCGIParameter" gibt es nicht
> in der Doku von lwip.
>
> Das ZIP File reicht nicht, daran kann ich weder erkennen, wie die return
> Werte der CGI Handler weiter verarbeitet werden, noch kann ich daraus
> ableiten, welches Framework dahinter steckt um dessen Doku zu finden.
>

hier nochmal die fehlenden Dateien

> Jedenfalls hat dein Problem nichts mit lwip zu tun, sondern damit, dass
> du nicht weißt, wie diese CGI Handler auszusehen haben.

von Stefan F. (Gast)


Lesenswert?

Dein CGI Handler wird von http_find_file() in httpd.c aufgerufen. Sie 
muss einen Dateinamen zurück liefern, deren Inhalt wird an den Browser 
geliefert. Was du machen willst geht so nicht mit diesem Framework. Du 
müsstest es ändern.

Ich würde hier eher den Weg über Server Side Includes (SSI, shtml File) 
gehen. Das ist der vorgesehene Weg variablen Content vom Server an den 
Browser zu liefern.

Siehe 
https://www.st.com/content/ccc/resource/technical/document/user_manual/65/e8/20/db/16/36/45/f7/DM00103685.pdf/files/DM00103685.pdf/jcr:content/translations/en.DM00103685.pdf 
Kapitel 6.2.1

In diesem Kapitel steht auch ein Kommentar drin, der erklärt, warum es 
mit CGI nicht geht:

"The CGI is a standard web technique used to
execute a request coming from a client on the
server side and then to return a response to the client."

Bis dahin ist noch alles gut, aber dann kommt das:

"In LwIP, the CGI offered works only with GET method requests and can 
handle up to 16 parameters encoded in the URI. The CGI handler function 
executed on the server side returns a HTML file that the HTTP server 
sends to the client."

Du willst aber kein HTML File zurückliefern, sondern nur einen nackten 
String. Den könntest du in eine ansonsten leere *.shtml Seite einbetten.

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.