Coder Social home page Coder Social logo

homeaccessorykid / life-cycle-manager Goto Github PK

View Code? Open in Web Editor NEW
60.0 12.0 11.0 6.78 MB

Initial install, WiFi settings and over the air firmware upgrades for any esp-open-rtos repository on GitHub

License: Apache License 2.0

Makefile 2.98% C 97.02%
esp-open-rtos ota over-the-air firmware-update esp8266 wifi-settings secure encrypted

life-cycle-manager's Introduction

Life-Cycle-Manager (LCM)

Initial install, WiFi settings and over the air firmware upgrades for any esp-open-rtos repository on GitHub
(c) 2018-2024 HomeAccessoryKid

Update December 2023

It looks like GitHub has put a 10s timeout on their TLS stack.
When verifying the server certificate, we take >15s and the server finishes the connection.
Version 2.2.6 tries to fix this by using overclock during this phase.

Update season 16 April 2022

After 14 months, version 2.1.2 will get upgraded to version 2.2.5. So be aware your own app update will take extra long.
It would be recommendable to also update devices that do not have an user app update.
Not that 2.1.2 is broken or in danger, but 2.2.5 is more future proof.

Version

Changelog
With version 2.0.0 LCM has arrived to a new stage with its own adaptation of rboot - rboot4lcm - which counts powercycles. These are used to check updates, reset wifi, clear or set LCM_beta or factory reset. It also gives access to the emergency mode.
Setting a value for a led_pin visual feedback is possible. By having introduced the latest-pre-release concept in version 1.0.0, users (and LCM itself) can test new software before exposing it to production devices. See the 'How to use it' section.

https://github.com/HomeACcessoryKid/ota-demo has been upgraded to offer system-parameter editing features which allows for flexible testing of the LCM code.

Scope

This is a program that allows any simple repository based on esp-open-rtos on esp8266 to solve its life cycle tasks.

  • assign a WiFi AccessPoint for internet connectivity
  • specify and install the user app without flashing over cable (once the LCM image is in)
  • assign app specific and device specific parameters
  • update the user app over the air by using releases and versions on GitHub

New features version 2

This new LCM code is able to load/update the bootloader from github.
The new bootloader is able to count the amount of short power cycles (<1.5s)
From the second cycle the cycles must be shorter than 4 seconds. Also a LED is lit if defined.
The boot loader conveys the count to the loaded code using the rtc.temp_rom value
User code is allowed the values from 1-4

  • 1 : this is a normal boot
  • 2-4: users choice in user code (communicate 3 to user or risk a bit and use 2, 3 and 4 separatly)

If count > 4 the bootloader launches LCM otamain.bin in rom[1]

For these values the behaviour is controlled through the sysparam string ota_count_step.
The default value of 3 reduces the chance of user misscounting and triggering something else than intended or playfull children.

Note that with LCM_beta mode and wifi erased you can set any emergency fallback server to collect a new signed version of otaboot.bin. This is to prevent a lockout as witnessed when Github changed their webserver in 2020.
Tested with macOS builtin apache server.
By monitoring the output with the terminal command nc -kulnw0 45678 you have 10 seconds to see which action was chosen before it executes.

If ota_count_step=="3" (default)

  • 5-7: check for new code (communicate 6 to user)
  • 8-10: erase wifi info and clear LCM_beta mode (communicate 9 to user)
  • 11-13: erase wifi info and set LCM_beta mode and gain access to emergency mode (communicate 12 to user)
  • 14-16: factory reset (communicate 15 to user)

If ota_count_step=="2"

  • 5-6: check for new code (communicate 5 to user)
  • 7-8: erase wifi info and clear LCM_beta mode (communicate 7 to user)
  • 9-10: erase wifi info and set LCM_beta mode and gain access to emergency mode (communicate 9 to user)
  • 11-12: factory reset (communicate 11 to user)

If ota_count_step=="1"

  • 5: check for new code (communicate 5 to user)
  • 6: erase wifi info and clear LCM_beta mode (communicate 6 to user)
  • 7: erase wifi info and set LCM_beta mode and gain access to emergency mode (communicate 7 to user)
  • 8: factory reset (communicate 8 to user)

Missing or other ota_count_step values will be interpreted as 3

In version 2.2.5 there are two new features: There is a new possibility for those user apps that need some configuration data to work that is specific to each instantiation. One can set the ota_string parameter which can be parsed by the user app to set e.g. MQTT server, user and password or whatever else you fancy. Since it is up to the user app to parse it, you test whatever works for you within the cgi transfer of parameters. Also, using the 'erase wifi' mode, new settings can be set again when needed.

There also exists the possibility to set the sysparam ota_count to activate the 'erase wifi' etc from the user app as well.

Non-typical solution

The solution is dedicated to a particular set of repositories and devices, which I consider is worth solving.

  • Many ESP8266 devices have only 1Mbyte of flash
  • Many people have no interest in setting up a software (web)server to solve their upgrade needs
  • Many repositories have no ram or flash available to combine the upgrade routines and the user routines
  • For repositories that will be applied by MANY people, a scalable software server is needed
  • be able to setup wifi securly while not depending on an electrical connection whenever wifi needs setup *)

If all of the above would not be an issue, the typical solution would be to

  • combine the usercode and the upgrade code
  • load a full new code image side by side with the old proven image
  • have a checkpoint in the code that 'proofs' that the upgrade worked or else it will fall back to the old code
  • run a server from a home computer at dedicated moments
  • setup the wifi password when electrically connected or send it unencrypted and cross fingers no-one is snooping *)

In my opinion, for the target group, the typical solution doesn't work and so LCM will handle it. Also it turns out that there are no out-of-the-box solutions of the typical case out there so if you are fine with the limitations of LCM, just enjoy it... or roll your own.
(PS. the balance is much less black and white but you get the gist)
*) This feature is not yet implemented (it is quite hard), so 'cross your fingers'.

Benefits

  • Having over the air firmware updates is very important to be able to close security holes and prevent others to introduce malicious code
  • The user app only requires a few simple lines of code so no increase in RAM usage or complexity and an overall smaller flash footprint
  • Through the use of cryptography throughout the life cycle manager, it is not possible for any outside party to squeeze in any malicious code nor to snoop the password of the WiFi AccessPoint *)
  • The fact that it is hosted on GitHub means your code is protected by the https certificates from GitHub and that no matter how many devices are out there, it will scale
  • The code is publicly visible and can be audited at all times so that security is at its best
  • The user could add their own DigitalSignature (ecDSA) although it is not essential. (feature on todolist)
  • The producer of hardware could preinstall the LCM code on hardware thereby allowing the final user to select any relevant repository.
  • Many off-the-shelf hardware devices have OTA code that can be highjacked and replaced with LCM so no solder iron or mechanical hacks needed (feature on todolist)

Can I trust you?

If you feel you need 100% control, you can fork this repository, create your own private key and do the life cycle of the LCM yourself. But since the code of LCM is public, by audit it is unlikely that malicious events will happen. It is up to you. And if you have ideas how to improve on this subject, please share your ideas in the issue #1 that is open for this reason.

How to use it

User code preparation part

  • in an appropriate part of your code, add these two function calls which will trigger an update if you want to:
  • rboot_set_temp_rom(1); //select the OTA main routine
  • sdk_system_restart(); //#include <rboot-api.h>
  • there is a bug in the esp SDK such that if you do not power cycle the chip after flashing, restart is unreliable
  • compile your own code and create a signature (see below)
  • in the shell, echo -n x.y.z > latest-pre-release
  • commit this to Git and sync it with GitHub
  • Start a release from this commit and take care the version is in x.y.z format
  • Attach/Upload the binary and the signature and create the release as a pre-release **)
  • Now go to the current 'latest release', ie the non-pre-release one you’re about to improve upon, edit its list of assets and either add or remove and replace the latest-pre-release file so that we now have a pointer to the pre-release we created above
    **) except the very first time, you must set it as latest release

Now test your new code by using a device that you enroll to the pre-release versions (a checkbox in the wifi-setup page).

  • If fatal errors are found, just start a new version and leave this one as a pre-release.
  • Once a version is approved you can mark it as 'latest release'.
  • If a 'latest release' is also the latest release overall, a latest-pre-release is not needed, it points to itself.

User device setup part

  • clone or fork the LCM repository (or download just the otaboot.bin file)
  • wipe out the entire flash (not essential, but cleaner)
  • upload these three files making sure to specify a 1MByte flash size:
esptool.py write_flash -fs 1MB
0x0    <path_to>/esp-open-rtos/bootloader/firmware_prebuilt/rboot.bin
0x1000 <path_to>/esp-open-rtos/bootloader/firmware_prebuilt/blank_config.bin
0x2000 <release>/otaboot.bin
  • (or otabootbeta.bin if enrolling in the LCM pre-release testing)
  • start the code and either use serial input menu or wait till the Wifi AP starts.
  • set the repository you want to use in your device: yourname/repository and name of binary
  • then select your Wifi AP and insert your password
  • once selected, it will take up to 5 minutes for the system to download the ota-main software in the second bootsector and the user code in the 1st boot sector
  • you can follow progress on the serial port or use the UDPlogger using the terminal command nc -kulnw0 45678

Creating a user app DigitalSignature

from the directory where make is run execute:

openssl sha384 -binary -out firmware/main.bin.sig firmware/main.bin
printf "%08x" `cat firmware/main.bin | wc -c`| xxd -r -p >>firmware/main.bin.sig

How it works

This design serves to read through the code base. The actual entry point of the process is the self-updater which is called ota-boot and which is flashed by serial cable.

Concepts

User app(0)
v.X triggers

The usercode Main app is running in bootslot 0 at version x. It can trigger a switch to bootslot 1.
Also the tuned bootloader rBoot4LCM can switch to bootslot 1.

powercycles select:

Based on the number of cycles, we will check for new versions, reset the wifi parameters or with lcmbeta allow the setting of an emergency server. Choosing factory reset will erase all the usercode and parameters so no sensitive data stays behind. After this the normal update cycle starts, except if an emergency server is defined

use http://not.github.com/somewhere/

After resetting wifi and selecting lcmbeta mode (12 power cycles) the user can specify another base location where the files otaboot.bin.sig and otaboot.bin will be collected. This enters emergency mode. If the signature is valid against the public key of LCM then it will replace the bootslot 0 and continue to update otamain etc.

(t)

This represents an exponential hold-off to prevent excesive hammering on the github servers. It resets at a power-cycle.

download certificate signature
certificate update?
Download Certificates

This is a file that contains the checksum of the sector containing three certificates/keys

  • public key of HomeACessoryKid that signs the certificate/key sector
  • root CA used by GitHub
  • root CA used by the DistributedContentProvider (now GitHub's own, Amazon before release 2.1.0)

Once downloaded, the signature is checked against the known public key and the sha384 checksum of the active sector is compared to the checksum in the signature file. If equal, we move on. If not, we download the updated sector file to the standby sector.

signature match?

From the sector containing up to date certificates the sha384 hash has been signed by the private key of LCM. Using the available public key, the validity is verified. From here, the files are intended to be downloaded with server certificate verification activated. If this fails, the server is marked as invalid.

new boot version?

This will download the latest version of rboot4lcm

new OTA version?
download OTA-boot➔0
update OTA-main➔1
sig & checksum OK?

We verify if there is an update of this OTA repo itself? If so, we use ota-boot to self update. After this we have the latest OTA code.

server valid?

If by checking the certificates the server is marked invalid, we return to the main app in boot slot 0 and we report by syslog to a server (to be determinded) so we learn that github has changed its certificate CA provider and HomeACessoryKid can issue a new certificate sector.
Now that the downloading from GitHub has been secured, we can trust whatever we download based on a checksum.

OTA-main(1) updates User app➔0
sig & checksum OK?

Using the baseURL info and the version as stored in sysparam area, the latest binary is found and downloaded if needed. If the checksum does not work out, we return to the OTA app start point considering we cannot run the old code anymore. But normally we boot the new code and the mission is done.

Note that switching from boot=slot1 to boot=slot0 does not require a reflash

AS-IS disclaimer and License

While I pride myself to make this software error free and backward compatible and otherwise perfect, this is the result of a hobby etc. etc. etc. So don't expect me to be responsible for anything...

See the LICENSE file for license information

life-cycle-manager's People

Contributors

homeaccessorykid avatar ravensystem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

life-cycle-manager's Issues

Provisioning wifi and repo using Serial

Use the serial port as input while you setup a new device so there is no need for the wifi AP

Awesome job overall, Thank you! But..

Provisioning via Serial works too straightforward - my experience isn't great:

  1. scandone string interrupts my input every 10 sec. What's for is it?
  2. Result: 'ota_repo'=... If this is not OK, re-flash the device
    I'd love to be able Confirm OR retype again to fix misprints.
  3. Press <enter> to continue
    I did, but nothing happened. Bunch of scandone, but no other activity.

UPD: I had to power cycle my Sonoff Basic for OTA magic to begin.
Is it by design? Then it should be prompted.

Not able to connect to hidden Access Point

Hello,

i flashed HomeAccessory Architect Firmware to a Sonoff TH16 and i wanted to initialy join a hidden Wifi, but sadly there seems not to be a option to join hidden Networks from the Life-cycle-Manager part of HAA.

LCM 2.2.6 - Wolf SSL error downloading user app

Hi HACK and Team,

Noticed a problem with LCM 226 where it seems to freak out when downloading the user app. Tried full erase of flash (on several modules).

Thinking it may have been something wrong with my app / signature files. I tested using the default "HomeACcessoryKid/ota-demo" with the same results.

It appears the fault is coming from a wolfSSL_send error = -188 which then causes the Fatal exception (28)

I'm out of my depth to go any further for a resolution.

Attached is UDPlogger and serial port captures - hopefully these help narrow down the cause.

20240324-LCM226-udplog.txt
20240324-LCM226-serial.txt

freeze in starting a tcp session

in the typical situation, the default gateway requests confirmation of arp from our assigned address ALL the time

in the code we are referring to ota.c near line 278 of release 0.9.10
if (!local_port) {
do {
wc_RNG_GenerateBlock(&rng, initial_port, 2);
local_port=256initial_port[0]+initial_port[1];
printf("%04x,",local_port);
} while (local_port<LOCAL_PORT_START);
}
UDPLGP("%04x ",local_port);
ret = netconn_gethostbyname(host, &target_ip);
while(ret) {
printf("%d",ret);
vTaskDelay(delay);
delay=delay<500?delay
2:500; //exponential hold-off till 5 seconds
ret = netconn_gethostbyname(host, &target_ip);
}

typical:
--- ota_get_version
in UDPlogger
--- ota_get_version
--- ota_connect LocalPort=e847
in printf
--- ota_get_version

this time:

in UDPlogger
--- ota_get_version
--- ota_connect LocalPort=e847
in printf
--- ota_get_version

<some 5 seconds of nothing>

--- ota_connect LocalPort=9e28,5f6d,a4f8,4fa4,a218,2316,0c3a,605c,10ab,3636,cc3e,cc3e Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
Timer Start Failed
Timer Stop Failed
beacon timeout
rm match
-6-1-1-1-1-1Timer Stop Failed
-1Timer Start Failed
beacon timeout
scandone
-1Timer Stop Failed
Timer Start Failed
beacon timeout
scandone
Timer Stop Failed
-1Timer Start Failed
beacon timeout
scandone
Timer Stop Failed
Timer Start Failed
beacon timeout
scandone
Timer Stop Failed
Timer Start Failed
beacon timeout
-1Timer Stop Failed
scandone
Timer Stop Failed
Timer Start Failed
<5 minutes nothing>
-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1

other variation:
UDPlogger:
--- ota_get_version
--- ota_connect LocalPort=f5ca IP:140.82.118.4 local..OK remote..OK SSL..OK set_fd to github.com port 443..
printf:
--- ota_get_version
--- ota_connect LocalPort=ac54,b69b,758d,83a7,f5ca,f5ca IP:140.82.118.4 local..OK remote..OK SSL..OK set_fd to github.com port 4
<1 minute frozen>
43..failed, return [-0x1]
wolfSSL_send error = -308
--- ota_get_file_ex
Fatal exception (28):
epc1=0x402cb12b
epc2=0x00000000
epc3=0x4028e684
excvaddr=0x00000000
depc=0x00000000
excsave1=0x402a3401
Registers:
a0 402a3401 a1 3fff82d0 a2 3fff82d0 a3 00000000
a4 00000000 a5 3fff830b a6 00000000 a7 6f6c6e77
a8 402c4238 a9 60000000 a10 00000000 a11 0000000a
a12 402c459c a13 00000000 SAR 0000001f

Stack: SP=0x3fff82d0
0x3fff82d0: 20544547 6d6f482f 63434165 6f737365
0x3fff82e0: 694b7972 696c2f64 632d6566 656c6379
0x3fff82f0: 6e616d2d 72656761 6c65722f 65736165
0x3fff8300: 6f642f73 6f6c6e77 002f6461 3fff2094
0x3fff8310: 00000190 00000001 00000001 3fff2938
0x3fff8320: 00000000 00000000 00000000 0000001b
0x3fff8330: 00000001 ffffffff 3fff295c 00000000
0x3fff8340: 00000000 00000000 3fff2938 40290114

Free Heap: 30412
_heap_start 0x3fff2560 brk 0x3fff9e98 supervisor sp 0x40000000 sp-brk 24936 bytes
arena (total_size) 31032 fordblks (free_size) 5476 uordblocks (used_size) 25556

compile

Hi there!

Great job on your LCM project. But I have a question. How to compile your code myself?
When I compile I says #error You must set OTAVERSION=x.y.z of the ota code to match github version tag x.y.z is missing on line 17 form main.c witch refers to OTA.h line 6?

Could you help me compile your code myself? I would be great full.
Thanks in advance.

Broken HTTP header and Finally answer from GitHub

The first and a long time the only standardised message from GitHub 'support staff'

Malcolm (GitHub Developer Support)
Feb 29, 5:16 PM UTC

Hello HacK,

Thank you for writing in to GitHub!
We appreciate the feedback, I will go ahead and pass this information over to the right teams.
Please write back if you have any additional questions.

All the best,
GitHub Staff


HacK
Feb 29, 3:02 PM UTC

Since today GitHub has changed their HTTP headers and has chosen to use lowercase
instead of the normal capital first letter.
This results in the header "Location: "(RFC2616:14.30) to have become "location: "
MANY amateur coders have no code in place for case-insensitive parsing because they are not aware!
While I have now found out that the RFC allows for the capitalization to be insensitive,
the reasonable thing to do for GitHub is to stick to the text as presented in the RFC and use "Location: "

In my case there are over 20.000 devices out there in the world that depend on my code to update via OTA
HomeACcessoryKid/life-cycle-manager and they cannot anymore.
Of course the self-update of OTA will become smarter, but for the sake of helping the community I really
really hope that GitHub will fix this back to the old RFC suggested format.
It doesn't hurt them and helps amateurs around the world.

Thanks,
HacK

PS. this has also been posted to the forum for API but I feel there it is a bit out of place...
https://github.community/t5/GitHub-API-Development-and/GitHub-changed-the-capitalisation-of-the-HTTP-headers-and-OTA/m-p/48247
PPS. I hope this doesn't happen to AWS as well, but for now it is OK
PPPS. There are still 'normal' headers in the reply, just not the top ones anymore
HTTP/1.1 302 Found
date: Sat, 29 Feb 2020 14:47:10 GMT
content-type: text/html; charset=utf-8
server: GitHub.com
status: 302 Found
vary: X-PJAX, Accept-Encoding, Accept, X-Requested-With
location: https://github.com/HomeACcessoryKid/life-cycle-manager/releases/tag/1.0.0
cache-control: no-cache
Age: 0
Set-Cookie: Set-Cookie: logged_in=no; Path=/; Domain=github.com; Expires=Mon, 01 Mar 2021 14:47:10 GMT; HttpOnly; Secure
Content-Length: 139
X-GitHub-Request-Id: DF95:2F739:3CBF7FE:57D6ABE:5E5A796E

*moved here* HTTP returns 302 for Fatal exception (28)

moved from: maximkulkin/esp-homekit#132 (comment)'

Latest update to continue from:

I had a read of your main page. I saw the 'how to use it' section, but am clueless how to apply it to https://www.studiopieters.nl/esp8266-homekit-light-switch/. In any case, I just ran git clone https://github.com/HomeACcessoryKid/life-cycle-manager.git, then I checked the changelog.md file and it shows information about 1.9.11 so I'd say I'm up-to-date. I then erased and flashed the ESP01.

After booting I still get the wifi config page but after that, same issue (fatal exception 28), over and over.

What would you advise to do at this point? Thank you.

Problem with OTABOOT and sonoff

Hello
Thank you so much for your great work
I have a very strange proble descripted below
RavenSystem/esp-homekit-devices#172

I'm using the OTABOOT.bin updated at last release to download and install ravencore in SONOFF 4ch R2 and Dual R2.

I'm waiting for the SONOFF SV and Shelly where I'll would like to do other test.

Some weeks ago I'd flashed some SONOFF basic without problem and I'm updating them without issue.

Can you forward me ideas about test to do and understanding why OTA procedure doesn't work for me?
Thank you

Support flashing with new Sonoff DIY mode

Hello,

It would be great to add the support by flashing the firmware with the new DIY mode. Tasmota firmware are already compatible with DIY flashing mode.
It is hard to solder pin on the new Sonoff mini so it can be very useful to flash without soldering.

Thank you

Can we trust you...

In this design, all is about trust, where no-one can sneak in the side and setup undesired code.
My design is to sign with my private key the certificates that are being used by GitHub and Amazon, such that they can be updated if needed. My private key is also used so I can update the LCM code itself.

This feels like too much power in the hands of one person.
In theory everyone can fork the LCM but they will then have the burden of the key and code management and that is not the easy-to-use approach I have in mind, this is for everyone.
So, if you have ideas how to improve on this scheme, please share??

PS. At the same time, we trust Apple, Google, Microsoft etc. to do the very same every day...

Error

hey HomeACcessoryKid,

Great job on your LCM 👍 👍

I followed every step, but still get a error:

erasing@0x6a000>0b6500...000000 1c0000...642040 202573...333435 363738...657370 so far collected 430080 bytes
send request......OK
erasing@0x6b000>2d6f70...000041 so far collected 430144 bytes
--- ota_verify_hash
--- ota_hash
error reading flash
error reading flash

can you tell me what this means and how to solve it?

How to programmatically reset the LCM such that it behaves as-if just flashed?

Can I programmatically reset the LCM such that it behaves as-if just flashed?

  1. I currently erase the flash, then program the life-cycle-manager.

  2. Then I configure both WiFi AP and the repository.

  3. After this the application is downloaded and run.

How can I return to 2 programmatically? I.e. I would like to have the possibility to reset to a state where it starts in 2.

I have tried "sysparam_init(SYSPARAMSECTOR, 0);" but that did not work.

Change repo after wifi config

Hi,

I have flashed an Gosund SP111 with tuya-convert to LCM and I connect to the LCM-XXXX wifi network. I set up a wifi network but forgot to set up a repo so there is a standard ota-demo. Device is connected to my network, but i can't open settings panel. If I turn off my wifi network, the device creates its LCM-XXXX network, but after connecting I can only change the wifi settings. How can I change the repository to run a RavenSystem/haa?

Question: Customize UI and code

Hi!
Is it possible to customize the code both for UI and default repo (and LCM- wifi AP name etc)?
It will look for newer LCM version of your code or what i'm compiled?
Basic idea is to simplify the LCM setup on first startup for users to skip the repo name and .bin name setup for easier use 😄
Also i've custom UI for esp-wifi-config and i want to implement it too Its done 😄

Are you planning to make a version with better customization? Like one #define for repo name and for .bin, and for the wifi-config (LCM-), so everybody who want to implement OTA can define the default variables and the (end)user only have to Join wifi network without adding any variables - correctly - on first startup 😄
Other question is, is it possible to change the flash size to 32 for 4mb flash devices?

Question: How to go back to initial state?

Assuming, we installed LCM to a device and then selected a repo of our choice, is there any way that we can return back to original state like when the LCM was first installed?

warning new version

Hello, is it possible that I have a feature with a warning that you have a new version?

wolfSSL_send error = -322

Hi I can't update my ESP8266 board OTA. Can you please help.

--- ota_connect LocalPort=c083 DNS IP:140.82.121.4 local..OK remote..OK SSL..OK set_fd to github.com port 443..OK
sent OK
HTTP/1.1 302 Found
Server: GitHub.com
Date: Tue, 13 Apr 2021 18:33:13 GMT
Content-Type: text/html; charset=utf-8
Vary: X-PJAX, Accept-Encoding, Accept, X-Requested-With
Location: https://github-releases.githubusercontent.com/127610504/8d20b280-6671-11eb-8557-9b13eda4d6c1?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210413%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210413T183313Z&X-Amz-Expires=300&X-Amz-Signature=562436e1bcfb6d2a380026b183c98bf97f4c142a633f9b830e28cc60acabcff8&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=127610504&response-content-disposition=attachment%3B%20filename%3Dotamain.bin.sig&response-content-type=application%2Foctet-stream
Cache-Control: no-cache
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: deny
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Referrer-Policy: no-referrer-when-downgrade
Expect-CT: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors"
Content-Secu
HTTP returns 302
--- ota_connect LocalPort=c084 DNS IP:185.199.111.154 local..OK remote..OK SSL..OK set_fd to github-releases.githubusercontent.com port 443..failed, return [-0x1]
wolfSSL_send error = -322
send request......failed, return [-0x1]
wolfSSL_send error = -322
--- ota_verify_signature
signature valid: 0
--- entering the loop

Firmware size 666k

My firmware size is 666k

erasing@0x8a000>070000...762540 cc7725...79d425 f7dee8...5e0e86 b32a3e...fd9dc3  so far collected 561152 bytes
send request......OK
erasing@0x8b000>1e8d3e...2d8569 662107...ab888d 72b9f8...864886 f70d02...797074  so far collected 565248 bytes
send request......OK
erasing@0x8c000>696f6e...040b00 69642d...000000 605c28...204b45 592d2d...3e3e20  so far collected 569344 bytes
send request......OK

download stops at 569344

No Update over OTA

@HomeACcessoryKid at first great job on this LCM 👍

But unfortunately I have a question about the update when releasing a new versions of my software. let's go step by step;

  1. esptool.py erase_flash
  2. esptool.py -p /dev/cu.usbserial-A50285BI --baud 115200 write_flash -fs 1MB -fm dout -ff 40m 0x0 rboot.bin 0x1000 blank_config.bin 0x2000 otaboot.bin
  3. Then I reset the ESP, hereafter the LCMXXX appears and try to connect, unfortunately the first time it never works? 😯
    4.Reset the ESP again, connect to LCMXXX and now I can add the WIFI Password and the url to my git where the .bin is located. Everything runs well, after installing my bin file, I can connect My homekit device.

Now I have added the code necessary to update the firmware when I release a new one on my git(see code below).

#include <stdio.h>
#include <stdlib.h>
#include <espressif/esp_common.h>
#include "rboot-api.h" //LCM
#include <esp/uart.h>
#include <esp8266.h>
#include <FreeRTOS.h>
#include <task.h>

#include <homekit/homekit.h>
#include <homekit/characteristics.h>
#include <wifi_config.h>

#include "button.h"


// The GPIO pin that is connected to the relay on the Sonoff Basic.
const int relay_gpio = 12;
// The GPIO pin that is connected to the LED on the Sonoff Basic.
const int led_gpio = 2;
// The GPIO pin that is oconnected to the button on the Sonoff Basic.
const int BUTTON_GPIO = 4;

void switch_on_callback(homekit_characteristic_t *_ch, homekit_value_t on, void *context);


void relay_write(bool on) {
        gpio_write(relay_gpio, on ? 1 : 0);
}

void led_write(bool on) {
        gpio_write(led_gpio, on ? 0 : 1);
}

void device_restart_task() {
    vTaskDelay(5500 / portTICK_PERIOD_MS);

        wifi_config_reset();
        printf("Reset Wifi\n");
        vTaskDelay(200 / portTICK_PERIOD_MS);

        rboot_set_temp_rom(1);
        printf("set temp rom\n");
        vTaskDelay(150 / portTICK_PERIOD_MS);

    sdk_system_restart();

    vTaskDelete(NULL);
}

void device_restart() {
    printf("HomeKit Device > Restarting...\n");
    xTaskCreate(device_restart_task, "device_restart_task", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
}

homekit_characteristic_t switch_on = HOMEKIT_CHARACTERISTIC_(
        ON, false, .callback=HOMEKIT_CHARACTERISTIC_CALLBACK(switch_on_callback)
        );

void gpio_init() {
        gpio_enable(led_gpio, GPIO_OUTPUT);
        led_write(false);
        gpio_enable(relay_gpio, GPIO_OUTPUT);
        relay_write(switch_on.value.bool_value);
}

void switch_on_callback(homekit_characteristic_t *_ch, homekit_value_t on, void *context) {
        relay_write(switch_on.value.bool_value);
}

void idle_task(void* arg) {
        while (true) {
                vTaskDelay(1000 / portTICK_PERIOD_MS);
        }

        vTaskDelete(NULL);
}

void button_callback(button_event_t event, void* context) {
        switch (event) {
        case button_event_single_press:
                printf("Toggling relay\n");
                switch_on.value.bool_value = !switch_on.value.bool_value;
                relay_write(switch_on.value.bool_value);
                homekit_characteristic_notify(&switch_on, switch_on.value);
                break;
        case button_event_long_press:
                device_restart();
                break;
        default:
                printf("Unknown button event: %d\n", event);
        }
}

void switch_identify_task(void *_args) {
        // We identify the Sonoff by Flashing it's LED.
        for (int i=0; i<3; i++) {
                for (int j=0; j<2; j++) {
                        led_write(true);
                        vTaskDelay(100 / portTICK_PERIOD_MS);
                        led_write(false);
                        vTaskDelay(100 / portTICK_PERIOD_MS);
                }

                vTaskDelay(250 / portTICK_PERIOD_MS);
        }

        led_write(false);

        vTaskDelete(NULL);
}

void switch_identify(homekit_value_t _value) {
        printf("Switch identify\n");
        xTaskCreate(switch_identify_task, "Switch identify", 128, NULL, 2, NULL);
}

homekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, "Switch");

homekit_accessory_t *accessories[] = {
        HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]){
                HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){
                        &name,
                        HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Nono"),
                        HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "037A2BABF19D"),
                        HOMEKIT_CHARACTERISTIC(MODEL, "Basic Switch"),
                        HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1.6"),
                        HOMEKIT_CHARACTERISTIC(IDENTIFY, switch_identify),
                        NULL
                }),
                HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
                        HOMEKIT_CHARACTERISTIC(NAME, "Switch"),
                        &switch_on,
                        NULL
                }),
                NULL
        }),
        NULL
};

homekit_server_config_t config = {
        .accessories = accessories,
        .password = "558-98-144",
        .setupId="7SW9",
};

void on_wifi_ready() {
        homekit_server_init(&config);
}

void create_accessory_name() {
        uint8_t macaddr[6];
        sdk_wifi_get_macaddr(STATION_IF, macaddr);

        int name_len = snprintf(NULL, 0, "Switch-%02X%02X%02X",
                                macaddr[3], macaddr[4], macaddr[5]);
        char *name_value = malloc(name_len+1);
        snprintf(name_value, name_len+1, "Switch-%02X%02X%02X",
                 macaddr[3], macaddr[4], macaddr[5]);

        name.value = HOMEKIT_STRING(name_value);
}

void user_init(void) {
        uart_set_baud(0, 115200);

        create_accessory_name();

        wifi_config_init("switch", NULL, on_wifi_ready);
        gpio_init();

        button_config_t button_config = BUTTON_CONFIG(
                .active_level=button_active_low,
                );

        int r = button_create(BUTTON_GPIO, button_config, button_callback, NULL);
        if (r) {
                printf("Failed to initalize button (code %d)\n", r);
        }

        printf("Button example\n");

        xTaskCreate(idle_task, "Idle task", 256, NULL, tskIDLE_PRIORITY, NULL);
}

The reset of the Wifi is going as it should. I can access LCMXXX to select my Wifi and add the Password. (monitor output: see below )

HomeKit Device > Restarting...
Reset Wifi
set temp rom
rm match
del if0
usl
sul 0 0
Task stack overflow (high water mark=0 name="device_restart_")
!!! HomeKit: [Client 6] Error reading data from socket (code 113). Disconnecting
!!! HomeKit: [Client 4] Error reading data from socket (code 113). Disconnecting
!!! HomeKit: [Client 5] Error reading data from socket (code 113). Disconnecting
>>> HomeKit: [Client 6] Closing client connection
>>> HomeKit: [Client 4] Closing client connection
>>> HomeKit: [Client 5] Closing client connection

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 2292, room 16 
tail 4
chksum 0x57
load 0x3ffe8000, len 772, room 4 
tail 0
chksum 0x0b
csum 0x0b

rBoot v1.4.0 - [email protected]
Flash Size:   8 Mbit
Flash Mode:   DOUT
Flash Speed:  40 MHz
rBoot Option: Big flash
rBoot Option: RTC data

Booting temp rom.
Booting rom 1.
WA���l⸮⸮l⸮⸮��⸮n⸮n⸮�⸮<⸮n⸮�⸮#⸮n⸮⸮!�⸮8�n⸮⸮⸮�⸮|⸮r⸮⸮�⸮⸮�⸮;r⸮��r⸮�bl�r��pp_task_hdl : 3ffefac8, prio:14, stack:512
pm_task_hdl : 3ffef530, prio:1, stack:176
frc2_timer_task_hdl:0x3fff4780, prio:12, stack:200

ESP-Open-SDK ver: 0.0.1 compiled @ Jan  5 2019 17:14:12
phy ver: 273, pp ver: 8.3








user-init-start
>>> wifi_config: Initializing WiFi config
>>> wifi_config: wifi_config_station_connect: No configuration found
user-init-done
mode : sta(5c:cf:7f:b8:d6:1d)
add if0

LifeCycleManager version 1.0.0
Will start Wifi AP for config if no input in 5 seconds
Press <enter> to begin
Too Late, Typo? Just restart
scandone
add 0
aid 3
cnt 

connected with AirPort Network, channel 1
dhcp client start...
ip:192.168.178.27,mask:255.255.255.0,gw:192.168.178.1
>>> wifi_config: wifi_config_station_connect: No configuration found
>>> wifi_config: Starting AP mode
mode : sta(5c:cf:7f:b8:d6:1d) + softAP(5e:cf:7f:b8:d6:1d)
add if1
bcn 100
Function called without core lock
>>> wifi_config: wifi_config_softap_start: Starting AP SSID=LCM-B8D61D
bcn 0
del if1
add if1
bcn 100
>>> wifi_config: Starting WiFi scan
>>> wifi_config: Starting DHCP server
>>> wifi_config: Starting DNS server
>>> wifi_config: Starting HTTP server

when this is done I can see this in the monitor:

connected with AirPort Network, channel 1
dhcp client start...
ip:192.168.178.27,mask:255.255.255.0,gw:192.168.178.1
>>> wifi_config: wifi_config_sta_connect_timeout_callback: Successfully connected
wifiready-done
--- ota_boot...1
OTAMAIN VERSION: 1.0.0
--- ota_init
userbeta='0' otabeta='0'
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
Function called without core lock
active_sector: 0xfa000
--- ota_set_verify...OFF
--- DNS: done!
active_cert_sector: 0xfa000
--- ota_get_pubkey
 04 94 30 cc 5c 4e 50 29 15 ff 3d 41 da e9 e5 e3 64 27 b3 96 07 61 36 a4 83 28 4d fd f9 05 4f 0d 82 fa 57 26 06 b7 e8 1f 22 2d 2b 8a d2 ff 6e ac 59 73 00 b5 e4 9c 5f 68 ab 31 d3 9f ad bb 3d c8 4f 6d 38 e6 6f b8 b3 f7 22 21 b7 f2 e4 b7 75 ed 09 2c 87 2b 00 56 5b 81 e8 64 5c 2c 84 85 c0 3c 34
ret: 0
--- ota_get_privkey
--- ota_boot...1
--- ota_load_user_app
user_repo='AchimPieters/ESP8266-Update' user_version='V0.0.1' user_file='main.bin'
--- ota_boot...1
--- entering the loop
>>> wifi_config: Stopping DNS server
--- ota_get_pubkey
 04 94 30 cc 5c 4e 50 29 15 ff 3d 41 da e9 e5 e3 64 27 b3 96 07 61 36 a4 83 28 4d fd f9 05 4f 0d 82 fa 57 26 06 b7 e8 1f 22 2d 2b 8a d2 ff 6e ac 59 73 00 b5 e4 9c 5f 68 ab 31 d3 9f ad bb 3d c8 4f 6d 38 e6 6f b8 b3 f7 22 21 b7 f2 e4 b7 75 ed 09 2c 87 2b 00 56 5b 81 e8 64 5c 2c 84 85 c0 3c 34
ret: 0
--- ota_set_verify...OFF
--- ota_get_version
--- ota_connect LocalPort=f603 DNS IP:140.82.118.3 local..OK remote..OK SSL..OK set_fd to github.com port 443..failed, return [-0x1]
wolfSSL_send error = -112
--- ota_boot...1
HomeACcessoryKid/life-cycle-manager@version:"Fatal exception (28): 
epc1=0x402c3940
epc2=0x00000000
epc3=0x4028f080
excvaddr=0x00000000
depc=0x00000000
excsave1=0x4029d921
Registers:
a0 4029d921 a1 3fffdd10 a2  00000000 a3  00000000
a4  ffffffff a5  401065b4 a6  3fffddc0 a7  0000002d
a8  3fffdda3 a9  000000b0 a10 402c4a27 a11 0000000a
a12 00000000 a13 3fff23dc SAR 00000010

Stack: SP=0x3fffdd10

Free Heap: 12468
_heap_start 0x3fff2600 brk 0x3fffffc8 supervisor sp 0x40000000 sp-brk 56 bytes
arena (total_size) 55752 fordblks (free_size) 12412 uordblocks (used_size) 43340

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 2292, room 16 
tail 4
chksum 0x57
load 0x3ffe8000, len 772, room 4 
tail 0
chksum 0x0b
csum 0x0b

rBoot v1.4.0 - [email protected]
Flash Size:   8 Mbit
Flash Mode:   DOUT
Flash Speed:  40 MHz
rBoot Option: Big flash
rBoot Option: RTC data

Booting rom 0.
pp_task_hdl : 3ffeff50, prio:14, stack:512
pm_task_hdl : 3ffef840, prio:1, stack:176
frc2_timer_task_hdl:0x3fff3eb0, prio:12, stack:200

ESP-Open-SDK ver: 0.0.1 compiled @ Aug 11 2019 14:49:09
phy ver: 273, pp ver: 8.3

>>> wifi_config: Initializing WiFi config
>>> wifi_config: Found configuration, connecting to AirPort Network
Button example
mode : sta(5c:cf:7f:b8:d6:1d)
add if0
scandone
add 0
aid 3
cnt 

connected with AirPort Network, channel 1
dhcp client start...
ip:192.168.178.27,mask:255.255.255.0,gw:192.168.178.1
>>> wifi_config: wifi_config_sta_connect_timeout_callback: Successfully connected
>>> HomeKit: Starting server
>>> HomeKit: Using existing accessory ID: 28:D8:5F:2F:5A:52
>>> HomeKit: Found admin pairing with D8738893-A2E2-4AA2-8E70-AC3C7ED75F9D, disabling pair setup
>>> HomeKit: Configuring mDNS
mDNS announcement: Name=Switch-B8D61D-28D8 �md=Basic Switch�pv=1.0�id=28:D8:5F:2F:5A:52�c#=1�s#=1�ff=0�sf=0�ci=8�sh=Mpl6YQ== Port=5556 TTL=4500

and I'm back where I started... 😲

I can't figure out what I'm doing wrong, can or would you help solving this puzzle please 🙏

Problem with LCM AP

Hi, uploaded LCM to a former Tasmota device OTA, now its broadcasting an LCM AP but doesn't show the web configuration upon connection, tried on PC, MacOS and iOS to no avail.

GitHub usage of EC based certificates breaks LCM v2.1.2

IT DOES NOT BREAK, a misunderstanding from my side
When updating the root certificate, I forgot to add an old root CA to the file
Fixed 3 April 18:50 CEST

Starting 1 April, people that use LifeCycleManager report that the access to GitHub.com does not work anymore. Analyses shows that GitHub now uses new certificates, and for the first time they use Elliptic Curve (EC) based certificates. Because the clients always worked with RSA based certificates, they are now broken.
Because the clients are embedded and the way they update themselves is through GitHub.com, they are now stuck.
These embedded clients are often deployed in wall sockets and other hard to reach places.

The request to the GitHub team is to provide a grace period in which they use RSA certificates again so the clients can update themselves to support EC. A version that supports EC has been created already, so it confirms the issue can be solved like this.
For the record, it is encouraged to use the same root CA as today, DigiCertGlobalRootCA

This same text is registered in GitHub.com/feedback

flash space coordination so it allows LCM to grow

This issue serves to collect user feedback, so this is your chance to influence what will happen...

The issue: current code (0.9.13) leaves only 1000 bytes between the main routine ending in sector 0xf4000 and the lower_cert_sector at 0xf5000.

I cannot introduce any new code of any value without running into the lower_cert_sector.

GitHub provides until 31 March 2021 to update our LCM to a safe version

UPDATE: It so happens that AWS will update their certificate provider on 23 March.
Please update before this, I will not update the certificate in LCM for that 1 week.
https://forums.aws.amazon.com/ann.jspa?annID=7541

As discussed in #23 GitHub has offered us until 31 March to use the original S3 server.

This issue will provide information about the creation of a new version that will be able to work when the new GitHub owned content delivery network will again be used.

The key obstacle is the use of SNI extension. I will need time to build and TEST that all is in good shape, so for now spread the word and point people to this issue so they stay informed.

I hope to provide new info by the end of this weekend.

Replace LCM with HAA_OTA

Hi @HomeACcessoryKid

I'm, wondering if there is a way to replace LCM with HAA_OTA. As you may be aware of, future versions of HAA require the HAA_OTA boot instead of LCM due to size constraints.

Are you aware of any OTA method to replace LCM with HAA_OTA?

How to adjust the user app

hey, super excited about this project, thanks a lot for your work.
I am currently playing around with it and doing the first OTA worked like a charm. However: how can I do subsequent updates.
In the README.md it says "The user app only requires a few simple lines of code so no increase in RAM usage or complexity and an overall smaller flash footprint".
Do you have an example of those necessary lines? Can't really find any -- or perhaps I am misunderstanding something ... very well possible.

So, currently my device seems to immediately boot into the user app (as it starts blinking really fast), how can I force it to boot into the OTA part again?

Thanks

Question: Going from LCM to other firmwares?

It would be very helpful to know if it is possible to load a different firmware (ie Tasmota / EspHome) and go away from LCM.

This function may be needed from someone who would like to explore different firmwares on devices where wire flashing is very difficult (ie bulbs)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.