esp32-sk6812/scripts/ota_update.py

109 lines
2.2 KiB
Python
Executable file

#!/usr/bin/env python3
import sys
import socket
import struct
import hashlib
import os
import time
from getpass import getpass
# update types
FLASH = 0
SPIFFS = 1
def readMessage(sock):
data = sock.recv(4)
length, = struct.unpack(">I", data)
data = sock.recv(1)
success, = struct.unpack("B", data)
data = sock.recv(length-1)
message = data.decode('utf-8')
return success, message
# read the salt from the config file
with open("../data/etc/auth", "r") as authFile:
lineno = 0
for line in authFile:
if lineno == 1:
SALT = line.strip()
break
lineno += 1
_, host, port, updatetypestr, filename = sys.argv
if updatetypestr == "flash":
updatetype = FLASH
elif updatetypestr == "spiffs":
updatetype = SPIFFS
else:
print(f"Invalid update type {updatetypestr}. Valid types are: flash, spiffs")
exit(1)
# read and store the password from the user
pwd = getpass()
s = socket.create_connection( (host, int(port)) )
data = s.recv(4)
length, = struct.unpack(">I", data)
if length != 4:
print(f"Unexpected challenge length: {length}")
exit(1)
data = s.recv(4)
challenge, = struct.unpack(">I", data)
print(f"Challenge: {challenge}")
# build response string
responsestr = pwd + ":" + str(challenge) + ":" + SALT
m = hashlib.sha256()
m.update(responsestr.encode('utf-8'))
response = m.hexdigest()
print(f"Response: {response}")
data = struct.pack(">I64s", len(response), response.encode('ascii') )
s.send(data)
success, message = readMessage(s)
print(f"Server message: {message}")
if not success:
print("Failed.")
exit(1)
print() # for proper progress display
with open(filename, "rb") as binfile:
filesize = os.stat(filename).st_size
messagesize = filesize + 1 # for type byte
data = struct.pack(">I", messagesize)
s.send(data)
data = struct.pack("B", updatetype)
s.send(data)
sent_bytes = 0
while True:
data = binfile.read(1024)
if not data:
break
s.send(data)
sent_bytes += len(data)
print(f"\rSent {sent_bytes} of {filesize} bytes.")
success, message = readMessage(s)
print(f"Server message: {message}")
if not success:
print("Failed.")
exit(1)