Marc V. schrieb:> Klaus schrieb:>> könnt ihr mir sagen, was diese Befehlszeile zu bedeuten hat ins C?>> LOL.> Das soll Befehlszeile sein ?
Upsss, bei kopieren, was falsch gelaufen :-)
Send response (Action *Var)
uint_8 success = '1';
openDocument();
switch (ab->action) {
case 'a':
LED_High;
_no_operation();
break;
case 'b':
LED_LOW
break;
Das ist der Befehlssatz, den ich nicht verstehe. Nur den unteren Part
verstehe ich, wenn ich a oder b sende.
Ich möchte gerne statt a oder b etwas längeres senden, sobald ich die
zeichen ändern, gib er mir ne Fehlermeldung....Multicharacter character
literal.... Mir geht es aber hauptsächlich um den oberen part.....
Klaus schrieb:> gib er mir ne Fehlermeldung...
Welcher Compiler? Welche Toolchain? Welcher Target?
> Ich möchte gerne statt a oder b etwas längeres senden
Dann solltest du dir ansehen, wie in C aus einzelnen Chars dann
komplette Strings zusammengebaut und iwe dei dann dargestellt und
bearbeitet werden.
> Das ist der Befehlssatz, den ich nicht verstehe.
Das findet sich in jedem x-beliebigen C-Buch ganz weit vorne...
Klaus schrieb:> Send response (Action *Var)> uint_8 success = '1';>> openDocument();>> switch (ab->action) {> case 'a':> LED_High;> _no_operation();> break;>> case 'b':> LED_LOW> break;
Der Code ist so ganz sicher nicht korrekt. Es fehlen geschweifte
Klammern, mindestes ein Semikolon, zwischen Send und response stand
vermutlich ein Unterstrich, ...
Mark B. schrieb:> Klaus schrieb:> Send response (Action *Var)> uint_8 success = '1';> openDocument();> switch (ab->action) {> case 'a':> LED_High;> _no_operation();> break;> case 'b':> LED_LOW> break;>> Der Code ist so ganz sicher nicht korrekt. Es fehlen geschweifte> Klammern, mindestes ein Semikolon, zwischen Send und response stand> vermutlich ein Unterstrich, ...
Der Code funktiert doch, aber eben nur mit einem Zeichen. Semikolon und
geschweifte Klammer ist beim abschreiben vergessen wurden, alles andere
passt,
1. will ich eigentlich nur den Sinn verstehen.
2.
Klaus schrieb:> Semikolon und geschweifte Klammer ist beim abschreiben vergessen wurden,> alles andere passtKlaus schrieb:> 2. eventuell könnt ihr mir Tipps geben, wie ich mehr Zeichen senden kann
Könnten wir. Aber die vergisst Du dann eh. ;-)
Im Ernst: Code schreibt man nicht von Hand ab. Dafür gibt es
Copy-and-Paste.
Klaus schrieb:> alles andere passt,
Ziemlich sicher nicht.
Im Switch-Statement wird ein Pointer "ab" deferenziert, übergeben wird
ein Pointer vom Typ "Action", der "Var" heißt.
Nee. So wird das nichts.
Rufus Τ. F. schrieb:> Ziemlich sicher nicht.>> Im Switch-Statement wird ein Pointer "ab" deferenziert, übergeben wird> ein Pointer vom Typ "Action", der "Var" heißt.>> Nee. So wird das nichts.
Habe oben ein Screenshot eingefügt, wie er läuft.
Klaus schrieb:> 2. eventuell könnt ihr mir Tipps geben, wie ich mehr Zeichen senden kann
Da wird nix gesendet. Der gezeigte Code reagiert auf eine Eingabe
(Tastendruck?), indem er eine LED bei "a" oder "b" jeweils an- oder
abschaltet (oder nix tut, falls was anderes eingegeben wurde).
Zusätzlich wird noch eine Funktion "openDocument()" und
"closeDocument()" aufgerufen, von der wir nur raten können, was sie tut,
weil sie nicht gezeigt wird.
"Wichtige Regeln - erst lesen, dann posten!", hast Du nicht gelesen,
oder?
Markus F. schrieb:> Klaus schrieb:>> 2. eventuell könnt ihr mir Tipps geben, wie ich mehr Zeichen senden kann>> Da wird nix gesendet. Der gezeigte Code reagiert auf eine Eingabe> (Tastendruck?), indem er eine LED bei "a" oder "b" jeweils an- oder> abschaltet (oder nix tut, falls was anderes eingegeben wurde).>> Zusätzlich wird noch eine Funktion "openDocument()" und> "closeDocument()" aufgerufen, von der wir nur raten können, was sie tut,> weil sie nicht gezeigt wird.>> "Wichtige Regeln - erst lesen, dann posten!", hast Du nicht gelesen,> oder?
Also nochmal:
ich habe einen Server und über den Brower sende ich den Befehl:
http://192.168.6.2/a
Sobald ich das in meinen Browser eingebe und sende, leuchtet die LED.
sende ich http://192.168.6.2/b geht die LED aus.
Ich möchte aber http://192.168.6.2/abcd senden also mehr als ein Zeichen
(a oder b),damit die Led angeht. Mit dem oben angegebenen Text werte ich
ja das gesendete aus, als A-> Led an, B-> Led aus, warum kann ich nicht
mehr als ein Zeichen auswerten?
Markus F. schrieb:> Zusätzlich wird noch eine Funktion "openDocument()" und> "closeDocument()" aufgerufen, von der wir nur raten können, was sie tut,> weil sie nicht gezeigt wird.
Anbei die beiden unterprogramme
Markus F. schrieb:> Da wird nix gesendet. Der gezeigte Code reagiert auf eine Eingabe> (Tastendruck?), indem er eine LED bei "a" oder "b" jeweils an- oder> abschaltet (oder nix tut, falls was anderes eingegeben wurde).
??????
Klaus schrieb:> warum kann ich nicht> mehr als ein Zeichen auswerten?
Weil ein 'switch'-Statement nun mal nur mit integralen Datentypen
umgehen kann und nicht mit Zeichenketten (zumindest in C).
Und um nochmal Lothar zu zitieren:
Lothar M. schrieb:> Dann solltest du dir ansehen, wie in C aus einzelnen Chars dann> komplette Strings zusammengebaut und wie die dann dargestellt und> bearbeitet werden.> Das findet sich in jedem x-beliebigen C-Buch ganz weit vorne...
Hallo,
um das zu erweitern, muss einiges umgeschrieben werden. Das Programm
beinhaltet anscheinend einen (Mikro-)Web-Server, der ankommende Requests
auseinander nimmt und dann in einer Action-Struktur speichert. Dabei
wird anscheinend der erste Buchstabe im "action"-Feld gespeichert und
mögliche weitere Parameter (wie auch immer die in die URI hineinkodiert
werden) in den folgenden Feldern der Action-Struktur. Im Anschluss wird
dann sendResponse aufgerufen, in der die Action-Struktur ausgewertet
wird.
Du muss also mindestens die Action-Struktur erweitern (action darf nicht
uint8 sein, sondern muss etwas anderes sein, z.B. eine Zeichenkette),
den URI-Parser des Webservers abändern (damit der die übergebene Adresse
anders auswertet und den gewünschten Teil korrekt in der Action-Struktur
speichert), und erst dann lohnt es sich, über Änderungen an sendResponse
zu reden.
Ausgehend von Deinem scheinbaren Wissensstand könnte das eine steile
Lernkurve für Dich werden, die - so befürchte ich - beim Erlernen der
C-Grundlagen beginnen muss.
Schöne Grüße,
Martin
P.S.: Um Deine Frage auch noch zu beantworten: "void sendResponse
(Action *a) {....}" definiert eine Funktion namens sendResponse, der ein
Parameter vom Typ "Zeiger auf eine Action-Struktur" übergeben werden
muss. Diese Funktion wird irgendwo anders in dem Programm dann mit
"sendResponse(Parameter);" aufgerufen.
Martin L. schrieb:> Du muss also mindestens die Action-Struktur erweitern (action darf nicht> uint8 sein, sondern muss etwas anderes sein, z.B. eine Zeichenkette),> den URI-Parser des Webservers abändern (damit der die übergebene Adresse> anders auswertet und den gewünschten Teil korrekt in der Action-Struktur> speichert), und erst dann lohnt es sich, über Änderungen an sendResponse> zu reden.
Da, ich es für eine Schulaufgabe brauche, könntest du mir ein paar
weitere Tipps geben?
Klaus schrieb:> Da, ich es für eine Schulaufgabe brauche, könntest du mir ein paar> weitere Tipps geben?
Die Informationslage ist dazu nicht Ausreichend. Du musst erst
herausfinden, woher das Action objekt kommt und wo es mit Werten befüllt
wird, dies wurde ja bereits gesagt. Du musst schauen, wo sendResponse
aufgerufen wird. Dort wird ein Parameter übergeben, welcher auch
irgendwoher kommt. Irgendwo wird dann den Objekteigenschaften/membern
ein Wert zugewiesen.
Unter linux kannst du einfach mit grep danach Suchen:
1
grep -rn 'sendResponse' /src/dir/path/
Du wirst dabei vermutlich irgendwo eine Deklaration finden:
1
voidsendResponse(Action*a);
2
//oder
3
voidsendResponse(Action*);
4
//oder
5
voidsendResponse();
Die ist erstmal uninteressant. Du suchst nach soetwasem:
1
sendResponse(beliebigeVariable);
2
// oder
3
sendResponse(&beliebigeVariable);
4
// oder
5
sendResponse(beliebiger->ausdruck);
6
// etc.
Es kann auch sein das dass Action-objekt noch weiteren Funktionen
mitgegeben wird, oder von einer zurückgegeben wird, etc. Dort muss du
dann auch nach der Initialisierung des Members action suchen.
Solltest du soetwas wie folgendes finden, wird es viel komplizierter:
1
irgendwas=&sendResponse;
Irgendwo müsste dann der Member action des Action objekts initialisiert
werden. dies ist eine der stellen, wo etwas geändert werdwn muss:
1
irgendwas->action=irgendwasanderes;
2
//oder
3
irgendwas.action=irgendwasanderes;
4
// oder komplexer
5
uint8_t*x=&irgendwas.action;
6
...
7
*x=irgendwasanderes;
8
//etc.
Wir können nicht hellsehen, wo was im Code steht, es gibt noch unzählige
andere möglichkeiten, wie das Action objekt initialisiert werden könnte
oder sendResponse aufgerufen werden könnte.
Daniel A. schrieb:> Du wirst dabei vermutlich irgendwo eine Deklaration finden:void> sendResponse (Action *a);
Das habe ich gefunden. Aber das bringt mir nicht wirklich viel...
Ich habe es jetzt mal komplett hochgeladen, damit du, wenn du Zeit hast,
mal drüber guckst. Das ist sehr freundlich von dir.
Danke im voraus.
Interresant. Die Funktion sendResponse wird im Code offenbar nirgens
Referenziert, ich gehe davon aus, dass diese von einer Library aus
aufgerufen wird. Das Action objekt scheint auch in der Library
allociiert zu werden. Falls diese Library nicht Open Source sein sollte
kann das struct Action möglicherweise nicht geändert werden, aber dass
kann ich nicht mit absoluter Sicherheit sagen.
Es sieht so aus, als ob "handleAction" jeweils mit einer
nullterminierten URL in "parserBuffer" aufgerufen wird, und
"handleParameter" mit einem GET Parameternamen oder Parameterwert. Dabei
findet keine Urldecodierung statt.
Die Auswertung muss in "handleAction" und "parserBuffer" erfolgen.
Jenachdem was für Adressen man verarbeiten will muss man unterschiedlich
vorgehen.
Ich würde es umsetzen, indem ich eine Liste der Aktionen zu den URLs +
ein Enum pro Aktion erstelle.
Das könnte dann so aussehen: (ungetestet, könnte also noch fehler
beinhalten)
Daniel A. schrieb:> Es sieht so aus, als ob "handleAction" jeweils mit einer> nullterminierten URL in "parserBuffer" aufgerufen wird, und> "handleParameter" mit einem GET Parameternamen oder Parameterwert. Dabei> findet keine Urldecodierung statt.>> Die Auswertung muss in "handleAction" und "parserBuffer" erfolgen.> Jenachdem was für Adressen man verarbeiten will muss man unterschiedlich> vorgehen.
Hallo nochmal,
also den deinen Code habe ich eingebaut, aber der hat mir soviel Fehler
ausgelistet. Waren zuviele, um hier zu posten.
Ich habe nochmal meinen Code durchgestept und mir ist folgendes
aufgefallen:
Wenn ich http://192.168.6.2/a sende, sendet er den Befehl an einen
internen Buffer, dann holt er sich das a über den Befehl *byte =
rxBuffer[readBufferPointer++] in diesem Unterprogramm:
uint8_t getByteFromBuffer(uint8_t *byte) {
if (lastByte == readBufferPointer) { // first time or last byte was
read from the local buffer
if (bytesReceived > RX_MAX_BUF_SIZE) { // received more bytes than
we can fit into our RX buffer
lastByte = RX_MAX_BUF_SIZE;
bytesReceived -= RX_MAX_BUF_SIZE;
} else {
lastByte = bytesReceived; // remaining bytes
}
receive(0, rxBuffer, lastByte); // get more from W5200
readBufferPointer = 0;
}
if (lastByte == 0) { // if there are no more bytes in W5200's RX
memory...
return 0; // we are done, return failure
}
*byte = rxBuffer[readBufferPointer++]; // copy byte
dannach springt er in handleAction(a);
void handleAction(Action *a) {
uint8_t byte = parserBuffer[0]; //hier
a->action = byte;
und holt sich hier wieder das a.
Wenn ich http://192.168.6.2/ab sende, dann macht er genau die selben
Aktionen wie oben, das heist, er speichert auch das b in den Buffer.
Aber bei
void handleAction(Action *a) {
uint8_t byte = parserBuffer[0]; //hier
a->action = byte;
holt er sich hier nur das a statt auch das b.
liegt das am uint8_t byte? wie kann ich es verändern, dass er auch das b
holt?
Klaus schrieb:>> also den deinen Code habe ich eingebaut, aber der hat mir soviel Fehler> ausgelistet. Waren zuviele, um hier zu posten.
Man kann auch Dateien anhängen.
> Wenn ich http://192.168.6.2/ab sende, dann macht er genau die selben> Aktionen wie oben, das heist, er speichert auch das b in den Buffer.> Aber bei>> void handleAction(Action *a) {> uint8_t byte = parserBuffer[0]; //hier> a->action = byte;>> holt er sich hier nur das a statt auch das b.> liegt das am uint8_t byte? wie kann ich es verändern, dass er auch das b> holt?
Wie ich bereits sagte, es befindet sich eine nullterminierten URL in
"parserBuffer". Bei obiger Beispiel URL wären in "parserBuffer" die
Zeichen 'a', 'b' und '\0' vorhanden. Wäre die URL
http://192.168.6.2/ab?bc wären es immernoch 'a', 'b' und '\0'. Ein
C-String ist ein char Array, welches nullterminiert ist. parserBuffer[0]
ist das nullte Element in "parserBuffer", also ein (uint8_t)'a',
parserBuffer[1] wäre ein (uint8_t)'b' und parserBuffer[2] wäre 0.
"uint8_t" ist normalerweise das selbe wie "unsigned char", wärend ein
Zeichen eines c-string den Type "char" mit unbekannter signedness hat.
Der C-String selbst hat dann den Typ "char[n]" oder "char*".
Ein "unsigned char" ist gleichgross wie ein "char" und somit meistens
gleich gross wie ein "uint8_t", hat also nur Platz für 1 Zeichen.
(Nebenbei, ein uint8_t wird normalerweise für Zahlen statt Zeichen
verwendet)
Es ist also nicht möglich mehr als ein Zeichen im Member action des
Objects a zu Speichern. Es kann auch kein Pointer auf den String
gespeichert werden (ausser man kopiert ihn vorher), da dieser in
"parserBuffer" enthalten ist und der Inhalt von "parserBuffer" nach dem
Verlassen der Funktion "handleAction" überschrieben wird. Ausserdem ist
unklar, ob das Strukt Action verändert werden Darf.
Unter diesen Voraussetzungen hatt man eigentlich nicht viel mehr
Möglichkeiten, als den URLs nummern zuzuordnen und die Nummer in
a->action zu speichern. Die URLs kann man mit strcmp in "handleAction"
vergleichen:
1
// Cast von uint8_t Array nach C-String (char array)
2
constchar*location=(constchar*)parserBuffer;
3
if(!strcmp(location,"ab")){
4
a->action=1;// location war ab, setze a->action auf 1
5
}elseif(!strcmp(location,"test")){
6
a->action=2;// location war test, setze a->action auf 2
7
}else{
8
a->action=0;// location entsprach keinem Vergleich, setze a->action auf 0
Daniel A. schrieb:> Wäre die URL> http://192.168.6.2/ab?bc wären es immernoch 'a', 'b' und '\0'.
Die URL kann nach 192.168.6.2/ sein, wie ich eswill. es gibt keine
feste vorgaben, nur das mehr als ein Zeichen gesendet werden soll.
Daniel A. schrieb:> Es kann auch kein Pointer auf den String> gespeichert werden (ausser man kopiert ihn vorher), da dieser in> "parserBuffer" enthalten ist und der Inhalt von "parserBuffer" nach dem> Verlassen der Funktion "handleAction" überschrieben wird. Ausserdem ist> unklar, ob das Strukt Action verändert werden Darf.
Ja, die Structure darf verändert werdeen, ansonsten kopieren wir ihn
vorher.
Daniel A. schrieb:> Wie ich bereits sagte, es befindet sich eine nullterminierten URL in> "parserBuffer".
Kann ich die nicht so verändern, dass sie nicht nullterminiert ist. dann
köönnte man einen geeigneten Datentypen wählen. Ansonsten, könnte man
doch jedes Zeichen in eine Variable speichern und später alle zusammen
auswerten
Klaus schrieb:> Daniel A. schrieb:>> Wäre die URL>> http://192.168.6.2/ab?bc wären es immernoch 'a', 'b' und '\0'.>> Die URL kann nach 192.168.6.2/ sein, wie ich eswill. es gibt keine> feste vorgaben, nur das mehr als ein Zeichen gesendet werden soll.
Darauf wollte ich eigentlich nicht hinaus. Wie dem auch sei, die Zeichen
werden hier doch nur Empfangen und Ausgewertet, aber doch nirgens
gesendet?
> Daniel A. schrieb:>> Es kann auch kein Pointer auf den String>> gespeichert werden (ausser man kopiert ihn vorher), da dieser in>> "parserBuffer" enthalten ist und der Inhalt von "parserBuffer" nach dem>> Verlassen der Funktion "handleAction" überschrieben wird. Ausserdem ist>> unklar, ob das Strukt Action verändert werden Darf.>> Ja, die Structure darf verändert werdeen, ansonsten kopieren wir ihn> vorher.
Gut, wenn du dir da wirklich sicher bist, dann könnte man in
"typedefs.h" aus dem uint8_t action ein uint8_t oder char array machen
"char action[32];". Die Zahl zeigt die Anzahl Elemente im Arrays an,
wobei bei c-strings das Letzte Zeichen den wert 0 haben muss. Somit
haben darin Maximal zahl-1 Zeichen Platz.
> Daniel A. schrieb:>> Wie ich bereits sagte, es befindet sich eine nullterminierten URL in>> "parserBuffer".>> Kann ich die nicht so verändern, dass sie nicht nullterminiert ist. dann> köönnte man einen geeigneten Datentypen wählen.
Das eine hat mit dem Anderen nichts zu tun. Nullterminiert bedeutet nur,
dass das letzte Zeichen den Wert 0 hat. Ein derartiges zeichen nennt man
auch Nullbyte, es unterscheidet sich nicht von den Anderen Zeichen und
wurde der Einfachheit halber zur Markerung des Endes des Strings
verwendet. Dies ist eine Konvention an die bis Heute fast alle C
Programme festhalten. Mit dem Datentyp hat dies nichts zutun.
> Ansonsten, könnte man doch jedes Zeichen in eine> Variable speichern und später alle zusammen auswerten
Das würden zuviele Variablen. Deshalb gibt es Arrays, das sind
eigentlich Listen mit Elementen eines Typs. Wäre a->action ein char oder
uint8_t array, könnte man mit
"strncpy((char*)a->action,(char*)parserBuffer,sizeof(a->action));"
mehrere Zeichen in dieses Array kopieren. Ich glaube aber nicht, dass
dies sinnvoll ist, da schlussendlich ja nur die Auswertung woanders
stattfindet, oder brauchst du wirklich diese Zeichenkette?
Daniel A. schrieb:> Gut, wenn du dir da wirklich sicher bist, dann könnte man in> "typedefs.h" aus dem uint8_t action ein uint8_t oder char array machen> "char action[32];". Die Zahl zeigt die Anzahl Elemente im Arrays an,> wobei bei c-strings das Letzte Zeichen den wert 0 haben muss. Somit> haben darin Maximal zahl-1 Zeichen Platz
Könntest du eventuell den Programmcode Posten, habe es versucht, aber
irgendwie kam nur Mist raus.
Muss das uint8_t byte auch verändert werden, weil in diesem Datentyp
doch auch nur Platz für ein Zeichen ist.