Das Beispiel funktioniert einwandfrei.
Aber ich möchte ein uint8_t [] array decodieren und am liebsten auch ein
array zurückbekommen.
Aber mein Controller rebootet sobald ich es mit einem Array als input
versuche
in "input".
1) enthält das wirklich einen base64-String?
2) was passiert wirklich wenn nicht (decoded == NULL)? Vermutlich
Serial.printf(..., NULL).
3) welches System? Welcher Compiler? Aus welcher library stammt
base64_decode()?
4) Was sagt das Manual zum Parameter wo die Variable "test" (aber mit
Konstantem Wert 40) übergeben wird?
Nikolaus S. schrieb:> in "input".> 1) enthält das wirklich einen base64-String?> 2) was passiert wirklich wenn nicht (decoded == NULL)? Vermutlich> Serial.printf(..., NULL).> 3) welches System? Welcher Compiler? Aus welcher library stammt> base64_decode()?> 4) Was sagt das Manual zum Parameter wo die Variable "test" (aber mit> Konstantem Wert 40) übergeben wird?
1) Ja,
1
uint8_t*toDecode=&ble_rx[0];
2
Serial.printf("%.*s",ble_rx_counter,toDecode);
Ausgabewert: AAECAwQFBgcICQoLDA0ODx
2) Length of decoded message: 2148463512
-> Also viel zu lang
-> direkt danach stürzt der controller ab
3) ESP32 mit der Aktuellen Arduino Library
4) Das original beispiel nimmt strlen()
Ich habe es schon auf eine variable geändert und es funktioniert damit.
Das Array mit der Base64 kodierung kommt per BLE. Ich erhalte ein
uint8_t array und einen uint16 counter wieviele Bytes per BLE empfangen
wurden
blub schrieb:> angenommen "input" enthält tatsächlich einen base64 String, dann sollte> das auch so gehen:> unsigned char * decoded = base64_decode(input, test, &outputLength);
selbes verhalten:
Length of decoded message: 2148463512
und reboot
Hallo Stefan,
hier die Hex Werte des Strings:
Data (23) is written to Device Status Service: 41 41 45 43 41 77 51 46
42 67 63 49 43 51 6F 4C 44 41 30 4F 44 78 0
der ble_rx_counter ist 23 und das letzte Byte ist 0
Vermutlich solltest du ble_rx_counter - 1 als Längeninformation an
base64_decode übergeben. Sicher kann ich das aber auch nicht sagen,
weil ich nicht weiß, wo ble_rx und ble_rx_counter herkommen.
foobar schrieb:> Der zweite Parameter von base64_decode ist die Länge des Eingabebuffers.>> char * toDecode = &input[0];>> uint16_t test = 40;>> ...>> ... base64_decode((const unsigned char *)toDecode, test, &outputLength);>> Wenn das input-Array nicht mindestens 40 Zeichen lang ist, kann es> knallen, ja.
danke foobar
hier leigt anscheinend der fehler. Ich habe die Länge mal fest auf 20
gesetzt (23 Bytes kriege ich ja) und es geht.
jetzt muss ich mir mal das array von decoded ausgeben lassen
> Data (23) is written to Device Status Service: 41 41 45 43 41 77 51 46> 42 67 63 49 43 51 6F 4C 44 41 30 4F 44 78 0
Wenn hinten immer eine 0 hängt, sollte der Code so sein:
komisch
mit 20 gehts
mit 21,22,23 geht's nicht
Aber die Ausgabe sah auf den ersten Blick gut aus.
Vielleucht liegt's daran:
die .bin Datei wird von der App gelsen und komplett in Base64 kodiert.
Das ganze wird dann in BLE Packete geteilt. jedes BLE paket endet mit
0x00
Morgen werde ich weiter testen
Schonmal vielen Dank an euch
anfänger schrieb:> mit 20 gehts> mit 21,22,23 geht's nicht
Base64 macht aus 3 Byte (zu 8 Bit) 4 Byte (mit 6 Bit)
Demnach sollte die Länge des Base64-String auch ohne Rest durch 4
teilbar sein.
anfänger schrieb:> mit 20 gehts> mit 21,22,23 geht's nicht
Dann liegt es daran, dass das Padding fehlt. Dazu musst du die Länge des
Base64-kodierten Strings am Ende mit 0 bis 2 '='-Zeichen auffüllen, so
dass die Gesamtlänge ein Vielfaches von 4 wird.
Probier also mal
AAECAwQFBgcICQoLDA0ODx== (Länge 24 durch 4 teilbar)
statt
AAECAwQFBgcICQoLDA0ODx (Länge 22)
zu dekodieren. Das dekodierte Ergebnis sollten 16 Bytes mit den Werten
0, 1, 2, ... 15 sein.
PS: Normalerweise sollte der Kodierer das Padding vornehmen. Umgekehrt
gibt es auch tolerante Dekodierer, die ohne das Padding auskommen. In
deinem Fall haben wir es wohl einen laxen Kodierer und einen peniblen
Dekodierer zu tun :)
PS2: Da fehlt nicht nur das Padding, der Eingabestring scheint auch
sonst unvollständig zu sein. Würde nur das Padding fehlen, wären die
letzten 4 Bits alle 0, d.h. das letzte Zeichen wäre kein 'x', sondern
ein 'w'.
Du kannst nicht einfach Teile eines Base64-kodierten Datenstrom
häppchenweise in den Dekoder schicken. Wie dirkb2 schrieb, müssen es
immer ein mehrfaches von 4-Byte-Paketen sein (pro 4 Byte rein kommen 3
Byte raus). Kürzere Bröckchen mit "=" auffüllen klappt nur am Ende des
gesamten Datenstroms (das macht der Encoder normalerweise von selbst) -
wenn man das mittendrin macht, kommen fehlerhafte Daten raus.
Ohne die Funktion base64_decode zu kennen ist das nur ein Rätsel raten.
Die Funktion soll ein Array zurückliefern, aber wo wird es gespeichert?
Liefert sie gleichviel oder weniger Bytes zurück, könnte das der
Eingabestring sein. Dann braucht man aber auch den Rückgabewert nirgends
zuzuweisen.
Ist der Eingabestring von der Kommandozeile des OS, dann wird er
read-only sein, d.h. Schreiben ergibt eine Exception.
Yalu X. schrieb:> PS: Normalerweise sollte der Kodierer das Padding vornehmen.
Wird er auch machen, aber das segmentieren bei der Übertragung macht da
wohl Ärger.
Da wäre es besser nur 20 Byte zu übertragen.
Peter D. schrieb:> Die Funktion soll ein Array zurückliefern, aber wo wird es gespeichert?
auf dem Heap, da ja danach ein free() nötig ist.
> Liefert sie gleichviel oder weniger Bytes zurück,
Dafür gibt es ja den 3. Parameter in der Funktion.
anfänger schrieb:> 2) Length of decoded message: 2148463512> -> Also viel zu lang
Vor allem länger als uint16_t. Da stimmt also schon das Anzeigeformat
nicht.
Kannst Du nicht mal den Quelltext des geheimen base64_decode verlinken?
Vermutlich stimmen die Aufrufparameter nicht.
Hast Du überhaupt genug Heap-Speicher übrig? Vielleicht hängt es einfach
daran.
Seltsame Funktion. Bin kein Freund von Funktionen, die
Speicherallokierung verbergen.
Vielen Dank nochmal an alle
die Hinweise zu den 4 Bytes waren Goldrichtig
Ich habe die App angepasst und teile nun den Base64 String (insgesamt
349 Bytes) in 20 Byte Stücke
jetzt funktioniert auch das dekodieren ohne Reboot
P.s. im ESP32 Gitter wurde empfohlen eine andere Base64 decode funktion
zu nutzen.