Help getting ESP32 ota_demo working with OTA update

Hi,
I am trying to learn how to do OTA updates for the ESP32. I have built the ota_demo project:

And have followed the readme, as well as the additional steps here:

I have the project loaded onto an ESP32 device, and it is direct connected to SmartThings server. On the SmartThings app, when I go to the device’s menu (the three vertical dots on the top right of the screen) and select “Information”, there is an enabled button that says “Firmware update”. When I click it, it says the latest firmware will be installed. On the device, I get the following serial messages (after clicking the “Firmware update” button on the SmartThings app):

 Starting OTA...
_update_device
E (50859) esp-tls: Failed to connnect to host (errno 113)
E (50859) esp-tls: Failed to open new connection
E (50859) TRANS_SSL: Failed to open a new connection
E (50859) HTTP_CLIENT: Connection failed, sock < 0
Failed to open HTTP connection: 28674
E (59359) esp-tls: Failed to connnect to host (errno 113)
E (59359) esp-tls: Failed to open new connection
E (59359) TRANS_SSL: Failed to open a new connection
E (59359) HTTP_CLIENT: Connection failed, sock < 0
Failed to open HTTP connection: 28674
Firmware Upgrades Failed (-1)

So the device definitely gets the command from the SmartThings server to try to OTA update, but then it is unable to connect.

It seems like this might be an issue with how I created the certificate for HTTPS, but I’m not 100% sure. There are a couple of steps in the process where I had questions, so I’ll outline them here in case I did something wrong.

The first question is when creating the scrip for the certificates. There are two domain names:

ROOT_DOMAIN_NAME=yourRootDomain
SERVER_DOMAIN_NAME=yourServerDomain

For SERVER_DOMAIN_NAME, I used the IP address of the computer I’m running the webserver. So I think that one is probably correct. But what do I put for ROOT_DOMAIN_NAME? I left it as “yourRootDomain” assuming it was for the ESP32, and it would use whatever IP address that it obtained when it connects to my WiFi? But maybe I’m supposed to explicitly set it?

The next question was when I created firmware_sign.py, I got an error when I tried to do the following:

    # write signature's header
    fd.write("\xFF\xFF\xFF\xFF\x00\x00")

So I changed it to:

    # write signature's header
    fd.write(binascii.unhexlify('FFFFFFFF0000'))

And same modification with the # write footer. I’m not sure if this is an acceptable change, but it allowed me to run the file without error.

Also in firmware_sign.py, there were a lot of spots that it had print without the () after, so I added those parenthesis, and the errors I were getting for that went away as well. I assume this has no bearing on the outcome.

Last, I wasn’t sure if the location of the webserver directory matters. I assume it doesn’t, but the example had it located in the ota_demo folder.

If anyone has any insight to the errors I am getting, or to any of the steps I have questions on, please let me know. Any help is appreciated.

BTW I’m using esp-idf v3.3, as recommended by @jody.albritton from his “How to Build Direct Connected Devices” post. Also, I’m tagging @nayelyz to make sure she sees this.

1 Like

Hi, @Bobby!

Please, allow me some time to check this issue with the engineering team. I’ll let you know their feedback.

OK, thank you. I look forward to hearing back.

Hi @nayelyz, do you have any update from the engineering team? This is an urgent issue that I need to solve soon.

Sorry for the delay, @Bobby
The team mentioned ROOT_DOMAIN_NAME is CN(common name).
So, you can insert the domain name there, for example, they made the following sample:

SERVER_DOMAIN_NAME=ota.demo

Can you let us know if this was helpful, please?

@nayelyz, I’m not sure what common name means. But I’m asking about the ROOT_DOMAIN_NAME, not the SERVER_DOMAIN_NAME. For the SERVER_DOMAIN_NAME, I used the IP address of the computer I’m running the webserver on.

Can you please ask what the ROOT_DOMAIN_NAME should be? Is it referring to the ESP32 device’s IP address? If so, how would I know what that will be?

Ah, sorry about that. I already asked the team again.

@nayelyz, thank you. I just tried manually putting the ESP32’s ip address as the ROOT_DOMAIN_NAME, and that didn’t fix the problem. So I’m at a loss for what ROOT_DOMAIN_NAME is referring to.

Hi, @Bobby.

The team mentioned that the ROOT_DOMAIN_NAME(CN) value is used to make the SSL certificate.
Also, they mentioned here’s more information about what Common Name is, which is basically the domain name:

@nayelyz, OK but both the SERVER_DOMAIN_NAME and the ROOT_DOMAIN_NAME are Common Name. I understand they can both either be an IP address or a domain name.

I’m pretty sure the SERVER_DOMAIN_NAME is the IP or domain name of the computer running the web server. But what is the ROOT_DOMAIN_NAME referring to? I know it’s a domain name. But the domain name (or IP address) of what?

ok, the team mentioned that we need an SSL certificate to make the OTA firmware update.
Root_domain_name and server_domain_name values follow the openSSL specification, so it depends on what you configured:

ROOT_DOMAIN_NAME => it means the root.csr’s CN.
SERVER_DOMAIN_NAME => it imeans the server.csr’s CN.

CSR: Certificate Signing Request

The team shared these commands as an example:

openssl req -new -nodes -text -out root.csr -keyout root.key -subj "/CN=$ROOT_DOMAIN_NAME"
openssl req -new -nodes -text -out server.csr -keyout server.key -subj "/CN=$SERVER_DOMAIN_NAME"

I used the command assigning test_rootname and, when I get the content of the file root.csr, I see this value in CN:
image

openssl req -new -nodes -text -out root.csr -keyout root.key -subj "/CN=test_rootname"

@nayelyz,
Yes I understand how to set the ROOT_DOMAIN_NAME and SERVER_DOMAIN_NAME. It was described here:

Which shows exactly the lines of code you shared:

openssl req -new -nodes -text -out root.csr -keyout root.key -subj “/CN=$ROOT_DOMAIN_NAME”
openssl req -new -nodes -text -out server.csr -keyout server.key -subj “/CN=$SERVER_DOMAIN_NAME”

So I have no problem setting the common names. The problem I have is I don’t know what to set them to. The link I pasted above says that the SERVER_DOMAIN_NAME should be the IP address, which I assume is the server IP address. But it says nothing of what the ROOT_DOMAIN_NAME should be set to.

Can you please ask the team what I should set the ROOT_DOMAIN_NAME to? Also confirm that the SERVER_DOMAIN_NAME is the IP address (or domain name) of the computer running the webserver for the OTA update?

Please let me know if something is not clear. I feel like we are going in circles here.

@nayelyz would it be possible for me to talk to the team directly? I’m so close to getting this working, that I think if I walked them through what I’m doing, I think they would be able to identify the mistake pretty quickly.

@nayelyz is there really no one that can help me? There must be someone who has done this before. I am stuck in this project until I can get past this.

please consider Matter

https://docs.espressif.com/projects/esp-matter/en/main/esp32/production.html

and Get started with Matter  |  Google Home

I have no specific experience of this area but I would suggest that your server domain is the domain name or IP address of the OTA server. The root domain will be whatever you choose it to be as you are creating self-signed certificates. You are the root certificate authority in this case.

1 Like

Sorry, I haven’t had the opportunity to make the test myself, but the team mentioned that the provided information in the tutorial and in the previous posts should be enough for you to integrate the device.
I agree with @orangebucket. It will depend on what you have configured for your server.

Maybe, @TAustin that also worked with the Direct-Connected integration has done this before. If so, could you share some tips about it, please, Todd?

@orangebucket thank you for the response. Unfortunately I’ve been doing exactly as you mentioned, using the IP address of the OTA server as the server domain. Does not work for me.

@nayelyz I’ve spent another 8 hours on this and I’m still getting the following errors from the esp32 device that is trying to connect to the webserver:

E (59359) esp-tls: Failed to connnect to host (errno 113)
E (59359) esp-tls: Failed to open new connection
E (59359) TRANS_SSL: Failed to open a new connection
E (59359) HTTP_CLIENT: Connection failed, sock < 0
Failed to open HTTP connection: 28674
Firmware Upgrades Failed (-1)

I am able to connect to the OTA webserver using the following curl command from Ubuntu:
curl --cacert ./root.crt “https://192.168.86.68:4443

So it seems I have the OTA webserver setup properly. It’s something to do with how I have the esp32 program setup.

The tutorial probably has all of the information needed to get this going, but I am not understanding something, so I am not able to get this to work. I cannot afford to waste more time on this (I’ve spent well over a 40 hours debugging). Can you please connect me with someone on your support team to help me? If I can walk someone through what I’ve done, it will likely take 5 minutes for them to spot the error.

@TAustin directly messaged me and was able to solve the issue:

  • In the file ota_util.c, you updated line 47 to be:
    #define CONFIG_OTA_SERVER_URL “https://192.168.86.68:4443/”
    I didn’t find in the docs where it said to do this, so if you missed this one, then that would definitely prevent your device app from being able to connect to your OTA server!!

He was right that I didn’t realize I needed to modify the file ota_util.c. @nayelyz, can you relay this information to your team so the docs get update?

Now that I have it working, my next issue is that after the firmware is ota updated onto the esp32, the SmartThings app still shows that there is new firmware available (even though I confirmed that the latest firmware is installed on the esp32). @nayelyz have you seen this?