1+ #include " BitFlash_Client.h"
2+
3+ BitFlash_Client::BitFlash_Client (const Config& config)
4+ : _config(config), _lastCheck(0 ), _updateInProgress(false ) {
5+ }
6+
7+ void BitFlash_Client::begin () {
8+ if (_config.autoConnect ) {
9+ connectWiFi ();
10+ }
11+ }
12+
13+ void BitFlash_Client::handle () {
14+ if (!_updateInProgress && millis () - _lastCheck >= _config.checkInterval ) {
15+ checkForUpdate ();
16+ _lastCheck = millis ();
17+ }
18+ }
19+
20+ void BitFlash_Client::checkForUpdate () {
21+ if (!isWiFiConnected () && !connectWiFi ()) {
22+ notifyCallback (" WiFi connection failed" );
23+ return ;
24+ }
25+
26+ if (checkVersion ()) {
27+ notifyCallback (" Update available" );
28+ }
29+ }
30+
31+ bool BitFlash_Client::checkVersion () {
32+ WiFiClientSecure client;
33+ client.setInsecure ();
34+
35+ HTTPClient https;
36+ https.begin (client, _config.jsonEndpoint );
37+
38+ int httpCode = https.GET ();
39+ if (httpCode != HTTP_CODE_OK) {
40+ notifyCallback (" Failed to fetch version info" );
41+ https.end ();
42+ return false ;
43+ }
44+
45+ StaticJsonDocument<512 > doc;
46+ DeserializationError error = deserializeJson (doc, https.getString ());
47+ https.end ();
48+
49+ if (error) {
50+ notifyCallback (" Failed to parse version info" );
51+ return false ;
52+ }
53+
54+ const char * latestVersion = doc[" version" ];
55+ const char * firmwareUrl = doc[" firmware_url" ];
56+
57+ if (strcmp (latestVersion, _config.currentVersion ) > 0 ) {
58+ _updateInProgress = true ;
59+ performUpdate (firmwareUrl);
60+ return true ;
61+ }
62+
63+ return false ;
64+ }
65+
66+ void BitFlash_Client::performUpdate (const char * firmwareUrl) {
67+ WiFiClientSecure *client = new WiFiClientSecure;
68+ client->setInsecure ();
69+
70+ HTTPClient https;
71+ https.begin (*client, firmwareUrl);
72+
73+ int httpCode = https.GET ();
74+ if (httpCode == HTTP_CODE_OK) {
75+ int contentLength = https.getSize ();
76+ if (contentLength > 0 && Update.begin (contentLength)) {
77+ WiFiClient * stream = https.getStreamPtr ();
78+ size_t written = 0 ;
79+ uint8_t buff[1024 ] = { 0 };
80+
81+ while (https.connected () && (written < contentLength)) {
82+ size_t size = stream->available ();
83+ if (size) {
84+ int c = stream->readBytes (buff, ((size > sizeof (buff)) ? sizeof (buff) : size));
85+ written += Update.write (buff, c);
86+ int progress = (written * 100 ) / contentLength;
87+ notifyCallback (" Downloading update" , progress);
88+ }
89+ yield ();
90+ }
91+
92+ if (written == contentLength && Update.end ()) {
93+ notifyCallback (" Update complete, restarting..." );
94+ ESP.restart ();
95+ } else {
96+ notifyCallback (" Update failed" );
97+ }
98+ }
99+ }
100+
101+ https.end ();
102+ delete client;
103+ _updateInProgress = false ;
104+ }
105+
106+ bool BitFlash_Client::connectWiFi () {
107+ if (isWiFiConnected ()) return true ;
108+
109+ WiFi.begin (_config.ssid , _config.password );
110+
111+ int attempts = 0 ;
112+ while (WiFi.status () != WL_CONNECTED && attempts < 20 ) {
113+ delay (500 );
114+ attempts++;
115+ }
116+
117+ if (isWiFiConnected ()) {
118+ setClock ();
119+ return true ;
120+ }
121+
122+ return false ;
123+ }
124+
125+ void BitFlash_Client::disconnectWiFi () {
126+ WiFi.disconnect ();
127+ }
128+
129+ bool BitFlash_Client::isWiFiConnected () {
130+ return WiFi.status () == WL_CONNECTED;
131+ }
132+
133+ void BitFlash_Client::setClock () {
134+ configTime (0 , 0 , " pool.ntp.org" );
135+ time_t now = time (nullptr );
136+ while (now < 8 * 3600 * 2 ) {
137+ delay (500 );
138+ now = time (nullptr );
139+ }
140+ }
141+
142+ void BitFlash_Client::setCheckInterval (uint32_t interval) {
143+ _config.checkInterval = interval;
144+ }
145+
146+ void BitFlash_Client::setCallback (std::function<void (const char * status, int progress)> callback) {
147+ _callback = callback;
148+ }
149+
150+ void BitFlash_Client::notifyCallback (const char * status, int progress) {
151+ if (_callback) {
152+ _callback (status, progress);
153+ }
154+ }
0 commit comments