Wieder mal ein Problem mit const char

Hi,

die C-Strings werden wohl nie meine Freunde. Mir wurde hier im Board schon so toll geholfen. Aber aktuell hakts wieder mal bei mir. Momentan geht es darum mittels der Ethercard-lib ein "Telegramm" abzusenden. Dazu nutze ich den Befehl Ether.browseUrl. Im Demosketch wird dazu der Hostname verwendet. 1.) Das hier funktioniert:

const char website[] PROGMEM = "file-server";
ether.browseUrl(startphp, phpstring, website, my_callback);

2.) Wenn ich anstelle des Hostnames die IP-Adresse eingeben will, dann klappt es nicht:

const char website[] PROGMEM = "192.168.1.2";
ether.browseUrl(startphp, phpstring, website, my_callback);

3.) Schreibe ich die IP-Adresse aber direkt in den Befehl, dann funktioniert es auch wieder:

ether.browseUrl(startphp, phpstring, "192.168.1.2", my_callback);

Wo ist jetzt aber der Unterschied zwischen 2 und 3 ?

Versuchs mal mit KOMMA const char website[] PROGMEM = "192,168,1,2";

Nope, mit Komma gehts nicht. Kein Telegramm in Wireshark

Eine vernünftige und ausführliche Doku von browseUrl() wäre da nicht schlecht.

Der Unterschied zwischen 2 und 3 ist das der eine String im Flash steht und der andere im RAM. Wegen dem PROGMEM modifier. Das erklärt aber nicht wieso 1 geht.

Serenifly: Eine vernünftige und ausführliche Doku von browseUrl() wäre da nicht schlecht.

Ja, zu der Lib find ich im Inet keine Referenz o.ä. Evtl. das? http://jeelabs.net/pub/docs/ethercard/index.html Und reverse-engineering der library ist über meinen Fähigkeiten. Hilft das weiter:

    /**   @brief  Prepare HTTP request
    *     @param  urlbuf Pointer to c-string URL folder
    *     @param  urlbuf_varpart Pointer to c-string URL file
    *     @param  hoststr Pointer to c-string hostname
    *     @param  callback Pointer to callback function to handle response
    *     @note   Request sent in main packetloop
    */
    static void browseUrl (const char *urlbuf, const char *urlbuf_varpart,
                           const char *hoststr,
                           void (*callback)(uint8_t,uint16_t,uint16_t));

Edit: Selbst wenn ich die IP aus dem Flash ins RAM nehme (also ohne PROGMEM deklariere), funzt es nicht.

So, Kommando zurück. Kein Problem mit dem String, sondern durch das Wechseln auf die feste IP, hab ich den DNSlookup rausgenommen. Aber der liefert als Ergebnis eine ether.hisip und die ist anscheinend notwendig für das Senden. @Serenifly. Hast schon recht, mit der Frage nach vernünftiger Doku. So wirds jetzt was:

 const char website[] PROGMEM = "192.168.1.2";
//  if (!ether.dnsLookup(website))
//    Serial.println(F("DNS failed"));
//    ether.printIp("SRV: ", ether.hisip);
ether.hisip[0] = 192;
ether.hisip[1] = 168;
ether.hisip[2] = 1;
ether.hisip[3] = 2;

   ether.browseUrl(startphp, phpstring, website, my_callback);

Wie könnte ich jetzt die ether.hisip dynamisch aus meiner website[] füttern? Das klappt nämlich nicht:

ether.hisip[0] = website[0];

Edit: Oh mann wie doof. Kann ja auch nicht, das Eine sind Zahlen, das andere ASCII-Zeichen...

Das wäre wohl der hölzerne Weg??

ether.hisip[0] = (website[0]-48)*100 + (website[1]-48)*10 + (website[2]-48);

Das ist wieder mal ein Job für atoi() und strcpy_P()

const char website[] PROGMEM = "192.168.001.002";      //führende Nullen sind hier wichtig damit die Indizes immer passen!!
char buf[4];
buf[3] = '\0';     //strncpy() macht leider keine Null-Terminierung. Allerdings stört sich atoi() auch nicht daran

ether.hisip[0] = atoi(strncpy_P(buf, website, 3));
ether.hisip[1] = atoi(strncpy_P(buf, website + 4, 3));
ether.hisip[2] = atoi(strncpy_P(buf, website + 8, 3));
ether.hisip[3] = atoi(strncpy_P(buf, website + 12, 3));

oder:

char buf[16];

strcpy_P(buf, website);
ether.hisip[0] = atoi(buf);
ether.hisip[1] = atoi(buf + 4);
ether.hisip[2] = atoi(buf + 8);
ether.hisip[3] = atoi(buf + 12);

Oder verzichte hier generell auf das PROGMEM. Dann kannst du dir auch str(n)cpy_P() sparen und es reicht atoi() :)

Hi,
danke. Hast mir mal wieder den eleganteren Weg gezeigt :slight_smile:

Wäre auch schön gewesen, wenn das ether.dnsLookup() nicht nur mit dem Hostnamen, sondern auch mit der IP-Adresse arbeiten würde. Dann hätte alles von selber gepasst.