slayes
November 9, 2022, 7:41am
1
Hello,
I don't understand why this codes doesn't work as instead
This code is working well :
static const char *url = "https://xxxxx/file_v2_1_0_199.bin ";
HttpsOTA.onHttpEvent(HttpEvent);
HttpsOTA.begin( url, server_certificate );
This code, no
...
#include <ArduinoJson.h>
...
StaticJsonDocument srvActions;
...
DeserializationError error = deserializeJson(srvActions, msg);
if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; }
const char* action = srvActions["action"];
const char* datas = srvActions["value"];
...
appUpdate( String( datas ) );
...
void appUpdate( String fwFileName ) {
Serial.println( fwFileName );
Serial.println( fwFileName.length());
int str_len = fwFileName.length() + 1;
char char_array[ str_len ];
fwFileName.toCharArray(char_array, str_len);
static const char *url = char_array;
HttpsOTA.onHttpEvent(HttpEvent);
Serial.print("url : ");Serial.println( url);
HttpsOTA.begin( url, server_certificate );
See bellow the console result :
08:34:15.852 -> 44
08:34:15.852 -> url : https://xxxxxxxx/file_v2_1_0_199.bin
08:34:15.852 -> E (5217) HTTP_CLIENT: Error parse url e⸮?⸮
Thanks in advance for your help
J-M-L
November 9, 2022, 7:52am
2
Memory issue ?
Try
void appUpdate( String& fwFileName ) {
HttpsOTA.onHttpEvent(HttpEvent);
HttpsOTA.begin( fwFileName.c_str(), server_certificate );
…
There is no reason to allocate all the memory you have…
This supposed you are passing a String to the function.
If you pass something within double quotes then just do
void appUpdate( const char * fwFileName ) {
HttpsOTA.onHttpEvent(HttpEvent);
HttpsOTA.begin( fwFileName, server_certificate );
…
Édit: just seen you call appUpdate( String( datas ) );
Why don’t you just call with the const char* you got ➜ appUpdate( datas ); and use the second version of the function given above ….
So much memory used for nothing:
you have a const char *
you allocate a String with its content
you duplicate that String to call the function
in the function you duplicate it again to have a char array buffer
then you allocate a const char * pointer to point at the start of the buffer (the buffer name would have been good enough)
That’s absurd given you had the const char* to start with…
slayes
November 9, 2022, 8:10am
3
Thanks for you reply.
It was my original code and console result :
void wsPrepare(char * msg){//Coming from WebSocket
DeserializationError error = deserializeJson(srvActions, msg);
if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; }
const char* action = srvActions["action"];
const char* datas = srvActions["value"];
...
appUpdate( datas );
...
void appUpdate( const char * fwFileName ) {
HttpsOTA.onHttpEvent(HttpEvent);
Serial.printf("url : %s\n", fwFileName);
HttpsOTA.begin( fwFileName, server_certificate );
09:03:25.993 -> url : https://xxxxxx/file_v2_1_0_199.bin
09:03:25.993 -> E (5299) HTTP_CLIENT: Error while setting default configurations
09:03:25.993 -> E (5304) esp_https_ota: Failed to initialise HTTP connection
I don't understand/know how to debug this issue. It's working only if the url variable has been declared in the "appUpdate" function like :
static const char *url = "https://xxxxxx/file_v2_1_0_199.bin ";
J-M-L
November 9, 2022, 8:18am
4
Did you try what I proposed?
Don’t print or do anything else in the function
Possibly verify your internet connection is still active
Post full code
slayes
November 9, 2022, 8:37am
5
Need a moment to write a short sample code, my actual project is over 1000 lines.
appUpdate( datas );
09:03:25.993 -> E (5299) HTTP_CLIENT: Error while setting default configurations
09:03:25.993 -> E (5304) esp_https_ota: Failed to initialise HTTP connection
But the code see below is working
static const char *url = "https://xxxxxx/file_v2_1_0_199.bin";
appUpdate( url );
I don't understand because "datas" variable is a pointer of char array :
const char* datas = srvActions["value"];
J-M-L
November 9, 2022, 8:40am
6
That’s an issue you need to dig into
slayes
November 9, 2022, 8:52am
7
May be the problem is linked with the JSON, because
This code doesn't work :
void wsPrepare(char * msg){
if (msg == "") return;
Serial.print("WS >> wsPrepare ");
//Serial.println (msg);
DeserializationError error = deserializeJson(srvActions, msg);
if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; }
const char* action = srvActions["action"];
const char* datas = srvActions["value"];
...
Serial.printf("datas : %s\n", datas);
appUpdate( datas);
09:46:20.005 -> url : https://xxxxxx/file_v2_1_0_199.bin
09:46:20.005 -> E (5299) HTTP_CLIENT: Error while setting default configurations
09:46:20.005 -> E (5304) esp_https_ota: Failed to initialise HTTP connection
And this code is working :
void wsPrepare(char * msg){
if (msg == "") return;
Serial.print("WS >> wsPrepare ");
//Serial.println (msg);
DeserializationError error = deserializeJson(srvActions, msg);
if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; }
const char* action = srvActions["action"];
const char* datas = srvActions["value"];
...
static const char *url = "https://xxxxxx/file_v2_1_0_199.bin ";
Serial.printf("url: %s\n", datas);
appUpdate( url);
09:47:41:214 -> url : https://xxxxxx/file_v2_1_0_199.bin
09:47:41:214 -> App >> Mise à jour : Http Event On Connected
J-M-L
November 9, 2022, 9:04am
8
may be there are invisible characters
try to print
Serial.printf("datas : [%s]\n", datas);
J-M-L
November 9, 2022, 9:29am
10
you might have a buffer overflow somewhere than corrupts the http connection
slayes
November 9, 2022, 9:44am
11
Arf... Is there a way/method to trace this issue ?
J-M-L
November 9, 2022, 9:45am
12
look at the whole code for array allocation
slayes
November 9, 2022, 10:12am
13
I tried to remove all unnecessary code.
#include <Arduino.h>
#include <ArduinoUniqueID.h>
#include <Preferences.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#include "HttpsOTAUpdate.h"
#include <jled.h>
...
WebSocketsClient webSocket;
...
const size_t CAPACITY = JSON_OBJECT_SIZE(4) + JSON_ARRAY_SIZE(3);
StaticJsonDocument<CAPACITY> doc;
JsonArray jsonCmd = doc.to<JsonArray>();
StaticJsonDocument<CAPACITY> srvActions;
...
void setup() {
...
wsInit();
...
ledSetup.Stop();
ledCur.Update();
}
...
void loop() {
...
ledCur.Update();
webSocket.loop();
wsSend();
...
}
...
void wsInit(){
Serial.printf("WS >> Initialisation sur %s:%i\n", wsIP, wsPort);
webSocket.begin( wsIP, wsPort, "/");
webSocket.onEvent(wsEvent);
webSocket.setAuthorization(............);
webSocket.setReconnectInterval(5000);
webSocket.enableHeartbeat(15000, 5000, 2);
}
...
void wsSend(){
if (!wsIsConnected || jsonCmd.size() == 0) return;
String output;
serializeJson(doc, output);
output = "{\"" + (isConfigured ? String("publicKey") : String("uniqueId")) + "\":\"" + (isConfigured ? publicKey : uniqueId) + "\", \"version\": \"" + SKETCH_VERSION + "\", \"actions\": " + output + "}";
Serial.printf("WS >> wsSend : %s\n", output.c_str());
webSocket.sendTXT(output);
jsonCmd.clear();
}
...
void wsEvent(WStype_t type, uint8_t * payload, size_t length) {
Serial.print("WS >> ");
switch(type) {
...
case WStype_TEXT:
Serial.printf("wsReceived : %s\n", payload);
if ( String((char *) payload).startsWith("{") ) wsPrepare((char *) payload);
break;
...
}
}
...
void wsPrepare(char * msg){
if (msg == "") return;
Serial.print("WS >> wsPrepare ");
//Serial.println(msg);
DeserializationError error = deserializeJson(srvActions, msg);
if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; }
const char* action = srvActions["action"];
const char* datas = srvActions["value"];
actions act = actionSwitch( srvActions["action"] );
switch (act){
...
case 4: //UPDATE
Serial.printf(">> Action : %s\n", action);
ledCur.Stop();
ledCur = JLed(PIN_RED).Blink(500, 500).Forever();
Serial.printf("datas length : %s - %i\n", datas, strlen (datas));
Serial.printf("datas : [%s]\n", datas);
appUpdate( datas );
break;
...
}
}
...
static HttpsOTAStatus_t otastatus;
static const char *server_certificate = ..............
void HttpEvent(HttpEvent_t *event) {
Serial.print("App >> Mise à jour : ");
.....
}
void appUpdate( const char * fwFileName ) {
HttpsOTA.onHttpEvent(HttpEvent);
HttpsOTA.begin( fwFileName, server_certificate );
}
J-M-L
November 9, 2022, 10:24am
14
so many missing parts, so hard to say. usually the bug is where you don't expect it...
you can't test a cString like this
if (msg == "") return;
do
if (*msg == '\0') return; // message is empty
also in this function
void wsEvent(WStype_t type, uint8_t * payload, size_t length) {
you are not guaranteed that the payload ends up with a null char, so you can't take for granted you have a cString when you do
if ( String((char *) payload).startsWith("{") ) wsPrepare((char *) payload);
➜ there might be a few non printable bytes at the end that you don't see when you print things out.
do something like
case WStype_TEXT:
Serial.write("wsReceived :");
Serial.write(payload, length);
Serial.println();
if (*payload == '{' ) wsPrepare((char* ) payload, length);
break;
and change the function
void wsPrepare(char * msg, size_t length) {
if (length == 0) return;
DeserializationError error = deserializeJson(srvActions, msg, length);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
const char* action = srvActions["action"];
const char* datas = srvActions["value"];
actions act = actionSwitch( srvActions["action"] );
switch (act) {
...
case 4: //UPDATE
Serial.printf(">> Action : %s\n", action);
ledCur.Stop();
ledCur = JLed(PIN_RED).Blink(500, 500).Forever();
Serial.printf("datas length : %s - %i\n", datas, strlen (datas));
Serial.printf("datas : [%s]\n", datas);
appUpdate( datas );
break;
...
}
}
slayes
November 9, 2022, 11:56am
15
Thanks for your comment
Unfortunally, it's not better.
By any chance, is it possible that «srvActions["value"]» doesn't contain a null terminating ?
I don't succeed to add it manually with strcopy
J-M-L
November 9, 2022, 12:27pm
16
no it will have one set by the ArduinoJSON library. what might happen though is that the library will read the data until it finds a null char, which might not be there at the end of the payload
One way to find out possibly is by looking at the char count
when you do
static const char *url = "https://xxxxxx/file_v2_1_0_199.bin";
➜ how many characters do you have in url ?
then when you go for the JSON, how many characters do you see in
const char* datas = srvActions["value"];
they would need to match
slayes
November 9, 2022, 1:14pm
17
I already checked this part, it's correct :
const char* datas = srvActions["value"];
const char *urlTest = "https://xxxxxx/file_v2_1_0_199.bin "
Serial.printf("datas length : %s - %i\n", datas, strlen (datas));
Serial.printf("urlTest length : %s - %i\n", urlTest, strlen (urlTest));
14:11:09.874 -> datas length : https://xxxxxx/file_v2_1_0_199.bin - 44
14:11:09.874 -> urlTest length : https://xxxxxx/file_v2_1_0_199.bin - 44
J-M-L
November 9, 2022, 1:15pm
18
really weird. Hard to debug without the full system on hand...
I would try to write a small code using the JSON and making the request
slayes
November 9, 2022, 1:59pm
19
I'll write a short project to share with only the feature used for this action.
As I can see both variable have the same length and type. Is there a way to do a loop to display all ASCII codes of all caracters ?
J-M-L
November 9, 2022, 2:11pm
20
sure a simple while loop until you find the null char would do
but that's what print does. if you can count 44 characters on screen for https://xxxxxx/file_v2_1_0_199.bin then you've seen them all
the issue is likely somewhere else. could you print the string and its length as well within the function and not when calling it.