Uploading program over the air ESP32 using the HTTP webserver

Thread Starter

zazas321

Joined Nov 29, 2015
936
Hello. I have a raspberry PI running as a server (have apache2, php installed). I also have multiple nodes of ESP32 connected to the same network using WiFi.

I am trying to do OTA (over the air update) on my ESP32 devices from my Raspberry PI. Could someone give me some advice/tips?
I have been reading this article:
https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#http-server

If you go down to HTTP SERVER OTA update, there is a snippet of code :
ESPhttpUpdate.update("192.168.0.2", 80, "/arduino.bin");


Each ESP32 node will have its own program so I need to store multiple .bin files in my webserver and I would like to somehow initiate the firmware update from the user interface that I have set up(NODE-RED). My questions are:


1. Can I store multiple .bin files on my raspberry pi PHP webserver and access them from my remote nodes ( they are connected to the same network)

2. I could initiate a firmware update by subscribing to the topic and waiting for user input as such;

if(user_button_pressed){ // if button pressed - initiate firwmare update
ESPhttpUpdate.update("192.168.0.2", 80, "/arduino.bin");
}

Would that work?
 

geekoftheweek

Joined Oct 6, 2013
1,213
Didn't realize this was possible. Thanks for asking as it is something I want to incorporate into a project.

As for your questions... you can store all you want on the server provided you make the filenames different. Just skimming over the page makes me think the button idea will work.

One thing that jumped out right away is you have to have enough flash memory for both your current running sketch and the new sketch.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
Cant figure out how do I upload files to my PHP server on raspberry PI. There are so many examples online but none of them are working. The closest and simplest example I found is :
https://stackoverflow.com/questions/28872167/upload-file-binary-data-into-variable

I have created index.php which is just a form that is waiting for me to select the file:

Code:
<form enctype="multipart/form-data" action="upload.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="512000" />
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>
and I have upload.php which is supposed to handle the uploading the files

Code:
<?php

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo "<p>";

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
  echo "File is valid, and was successfully uploaded.\n";
} else {
   echo "Upload failed";
}

echo "</p>";
echo '<pre>';
echo 'Here is some more debugging info:';
print_r($_FILES);
print "</pre>";

?>
However Im just getting error trying to upload any file:

Code:
Upload failed

Here is some more debugging info:Array
(
           [userfile] => Array
                 (
                           [name] => dev1.bin
                           [type] => application/x-sega-cd-rom
                           [tmp_name] => /tmp/phpvaZ7eg
                           [error] => 0
                           [size] => 283904
                 )
)

First of all I would like to ask what should be my upload directory:
$uploaddir = '/var/www/uploads/';
Does that mean that I need to hold my .bin files in that directory or what?
 

geekoftheweek

Joined Oct 6, 2013
1,213
First of all I would like to ask what should be my upload directory:
$uploaddir = '/var/www/uploads/';
Does that mean that I need to hold my .bin files in that directory or what?
I've never tried uploading to a server myself, but can say your files should end up in /var/www/uploads. The one thing I can think of off the top of my head is how are the permissions for the directory set? Usually the web server runs as something along the lines of httpd for a user and so your upload directory will either need to have it's owner changed or the permissions to allow the server to write to it. Other than that I'm not too sure.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
You are right. I have permission problems.

I have checked what user is my apache2 running as - it is "www-data" user. The owner of /var/www is "root" user. Does that mean that I need to change the owner of /var/www to www-data?
 

geekoftheweek

Joined Oct 6, 2013
1,213
You could do it that way and for home use it would probably be the most convenient. Ideally you would want to do individual directories for a production type server though.
 

geekoftheweek

Joined Oct 6, 2013
1,213
Actually just realized I was wrong. You will need to change your upload directory itself. If you change /var/www permissions it won't extend to /var/www/uploads.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
I have found a thread and someone suggested:
"
Hi,
Its is simple.
On normal situation, http daemon run as some user and group, www-data on debian (raspbian).
Standard html files are stored on /var/www/, owned by root:root, with permissive permission, all can read, but only root can write.
To ordinary user write to /var/www need to takeover it. Supposed the use is pi.
sudo chown -R pi:www-data /var/www
Also, need to set user and group permission:
sudo chmod u+rxw,g+rx-w,o-rwx /var/www
Now, /var/www can be read,write and chdir by user pi, group www-data can chdir and read. Other not have access.
sudo chmod g+s /var/www
Any new file created on /var/www belong to group www-data.
If have files on /var/www, change user and group, and allow to group www-data read.
For file chmod u+rw,g+r-xw,o-rwx
For directory chmod u+rwx,g+rx-w,o-rxw
Now, user pi can manipulate files on /var/www and httpd can read, but not write.
"

So I have followed these steps:
1. sudo chown -R pi:www-data /var/www - changed the owner of www-data to pi user
2. sudo chmod u+rxw,g+rx-w,o-rwx /var/www - changed permissions
3. sudo chmod g+s /var/www - I dont understand what this command does??

The last few steps I cant really understand - would you be able to help here?

Any new file created on /var/www belong to group www-data.
If have files on /var/www, change user and group, and allow to group www-data read.
For file chmod u+rw,g+r-xw,o-rwx
For directory chmod u+rwx,g+rx-w,o-rxw
Now, user pi can manipulate files on /var/www and httpd can read, but not write.
 

geekoftheweek

Joined Oct 6, 2013
1,213
So I have followed these steps:
1. sudo chown -R pi:www-data /var/www - changed the owner of www-data to pi user
2. sudo chmod u+rxw,g+rx-w,o-rwx /var/www - changed permissions
3. sudo chmod g+s /var/www - I dont understand what this command does??
The "+s" has something to do with the sticky bit I believe which I really don't understand myself.
The first line should have changed the owner of /var/www and all items in it to www-data which by itself should have made uploads work.

Really as long as /var/www/uploads is owned by www-data and has permissions that the owner can write to it everything should work.

What does ls -l /var/www print out?
 

geekoftheweek

Joined Oct 6, 2013
1,213
Once again I realized I was wrong.
The first line would change /var/www to user pi and group www-data.

Personally I would just "chown www-data /var/www/uploads".
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
The first line if I understand correctly assings the user of /var/www to pi and group www-data. Becuase we write pi:www-data so pi is the owner right?

permissions for the /var/www folder are:

Code:
drwxr-x---  4 pi   www-data      4096 Jul 14 09:46 www
ls -l /var/www prints out:
Code:
drwxrwx--- 2 pi www-data 4096 Jul 14 09:45 html
drwxr-xr-x 2 pi www-data 4096 Jul 14 09:38 uploads
Note that I have manually created the uploads folder with default permissions. Even if I use
For file chmod u+rw,g+r-xw,o-rwx /var/www/uploads
or
For directory chmod u+rwx,g+rx-w,o-rxw /var/www/uploads

it wont let me write anything because group does not have write permission - only owner have write permissions. Is my owner supposed to be www-data?
 

geekoftheweek

Joined Oct 6, 2013
1,213
Awesome!!
If I were doing it myself I can do it without thinking, but to write it down for someone else it takes a second to get my thoughts right.

Hope the rest goes without much more trouble. Good luck!
 

geekoftheweek

Joined Oct 6, 2013
1,213
Note that I have manually created the uploads folder with default permissions. Even if I use
For file chmod u+rw,g+r-xw,o-rwx /var/www/uploads
or
For directory chmod u+rwx,g+rx-w,o-rxw /var/www/uploads
The issue was chmod u+rwx,g+rx-w,o-rxw /var/www/uploads removes write permission for the group. Good for normal http stuff, but bad for uploading.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
Yes that is cool! Now the second problem I need to solve is how do I access this bin file using my esp8266.

From what I know, the function takes in URL parameter which is my webserver where i store .bin file.
Im not sure how do I build this URL ?
ESPhttpUpdate.update( );
 

geekoftheweek

Joined Oct 6, 2013
1,213
Something I didn't catch before... can you in a normal browser do something like
Code:
http://your-pi-address/downloads/filename.bin
or does it give an error?

It's been a while (10 years) since I've played with apache, but it is normally set up to serve from the html directory and may not be able to access the downloads directory depending on how it is set up. Sounds wrong considering you can upload, but there are security settings for every action and maybe there's a simple way.

Edit -- should have said
Code:
http://your-pi-address/uploads/filename.bin
 
Last edited:

geekoftheweek

Joined Oct 6, 2013
1,213
Looked over things again and thinking:
ESPhttpUpdate.update("192.168.0.2", 80, "uploads/arduino.bin"); should be what you want.

If it doesn't work maybe try:
Code:
mv /var/www/uploads /var/www/html
ln -s /var/www/html/uploads /var/www/uploads
That will move the uploads directory where apache will have access and still be able to upload the same way using what you have already working.
 

Thread Starter

zazas321

Joined Nov 29, 2015
936
I can tell that I am getting somewhere. I have used those commands that you suggested and now I have dev1.bin file in /var/www/html/uploads, however when I call:
ESPhttpUpdate.update("192.168.100.158", 80, "uploads/dev1.bin"); Arduino returns me an error message:
HTTP_UPDATE_FAILD Error (-104): Wrong HTTP code
 

geekoftheweek

Joined Oct 6, 2013
1,213
Im a bit confused of whats the point of using php script to uploading files to /var/www/uploads if I can just copy and paste whatever files and put them there manually
I was kind of wondering that myself, but thought maybe it was for someone developing on a separate computer that can't copy and paste.

Unfortunately a 104 error code means the server didn't recognize something as far as I can tell and dropped the connection. I'm not going to be much more help at this point. I can say to have a look in /var/log/apache2/error.log and see if anything makes sense there.
 
Top