Repository navigation
Expand file tree
/
Copy pathWebClientModule.hpp
More file actions
142 lines (120 loc) · 6.03 KB
/
Copy pathWebClientModule.hpp
File metadata and controls
142 lines (120 loc) · 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef WEBCLIENTMODULE_HPP
#define WEBCLIENTMODULE_HPP
#include <Arduino.h>
#include <functional>
#include <vector>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "PsramUtils.hpp"
// Default User-Agent string (can be overridden by defining DEFAULT_USER_AGENT before including this header)
#ifndef DEFAULT_USER_AGENT
#define DEFAULT_USER_AGENT "ESP32-PanelClock/1.0"
#endif
// Vorwärtsdeklarationen, um Header-Abhängigkeiten zu minimieren
struct DeviceConfig;
extern DeviceConfig* deviceConfig;
class PsramBufferStream : public Stream {
public:
PsramBufferStream();
void begin(char* buffer, size_t capacity);
void reset();
size_t write(uint8_t data) override;
size_t write(const uint8_t *buffer, size_t size) override;
bool hasOverflowed() const;
size_t getCapacity() const;
int available() override;
int read() override;
int peek() override;
void flush() override;
char* getBuffer();
size_t getSize();
private:
char* _buffer = nullptr;
size_t _capacity = 0;
size_t _position = 0;
bool _overflowed = false;
};
struct ManagedResource {
PsramString url;
PsramString customHeaders; // Optional headers for this resource (format: "Header1: Value1\nHeader2: Value2")
uint32_t update_interval_ms;
const char* root_ca_fallback;
PsramString cert_filename;
char* data_buffer = nullptr;
size_t data_size = 0;
time_t last_successful_update = 0;
time_t last_check_attempt = 0;
unsigned long last_check_attempt_ms = 0; // Millisecond-precise timestamp for second-precise intervals
SemaphoreHandle_t mutex;
uint8_t retry_count = 0;
bool is_in_retry_mode = false;
bool is_data_stale = true;
bool is_paused = false; // When true, resource polling is paused
bool has_priority = false; // When true, resource is checked with priority when due
bool use_ms_timing = false; // When true, use millisecond-precise timing
ManagedResource(const PsramString& u, uint32_t interval, const char* ca);
ManagedResource(const PsramString& u, const PsramString& headers, uint32_t interval, const char* ca);
~ManagedResource();
ManagedResource(ManagedResource&& other) noexcept;
};
struct WebJob {
enum JobType { GET, POST };
JobType type;
PsramString url;
PsramString body;
PsramString contentType;
PsramString customHeaders; // Format: "Header1: Value1\nHeader2: Value2"
std::function<void(const char* buffer, size_t size)> callback;
std::function<void(int httpCode, const char* payload, size_t len)> detailed_callback;
};
class WebClientModule {
public:
WebClientModule();
~WebClientModule();
void begin();
void registerResource(const String& url, uint32_t update_interval_minutes, const char* root_ca = nullptr);
void registerResourceWithHeaders(const String& url, const String& customHeaders, uint32_t update_interval_minutes, const char* root_ca = nullptr);
// Second-precise registration (interval in seconds, with priority option, force_new to avoid URL replacement)
void registerResourceSeconds(const String& url, uint32_t update_interval_seconds, bool with_priority = false, bool force_new = false, const char* root_ca = nullptr);
void registerResourceSecondsWithHeaders(const String& url, const String& customHeaders, uint32_t update_interval_seconds, bool with_priority = false, const char* root_ca = nullptr);
void updateResourceUrl(const String& old_url, const String& new_url);
void accessResource(const String& url, std::function<void(const char* data, size_t size, time_t last_update, bool is_stale)> callback);
void accessResource(const String& url, const String& customHeaders, std::function<void(const char* data, size_t size, time_t last_update, bool is_stale)> callback);
void updateResourceCertificateByHost(const String& host, const String& cert_filename);
// Pause/Resume control for resources
void pauseResource(const String& url);
void pauseResourceWithHeaders(const String& url, const String& customHeaders);
void resumeResource(const String& url);
void resumeResourceWithHeaders(const String& url, const String& customHeaders);
void getRequest(const PsramString& url, std::function<void(const char* buffer, size_t size)> callback);
void getRequest(const PsramString& url, std::function<void(int httpCode, const char* payload, size_t len)> detailed_callback);
void getRequest(const PsramString& url, const PsramString& customHeaders, std::function<void(int httpCode, const char* payload, size_t len)> detailed_callback);
void postRequest(const PsramString& url, const PsramString& postBody, const PsramString& contentType, std::function<void(const char* buffer, size_t size)> callback);
// User-Agent configuration
void setUserAgent(const String& userAgent);
String getUserAgent() const;
// Processing-active flag: set true while module processData() runs to prevent
// concurrent downloads and avoid parallel heap allocations causing fragmentation.
void setProcessingActive(bool active) { _processingActive = active; }
private:
char* _downloadBuffer = nullptr;
size_t _bufferCapacity = 0;
PsramBufferStream _downloadStream;
std::vector<ManagedResource, PsramAllocator<ManagedResource>> resources;
TaskHandle_t workerTaskHandle;
QueueHandle_t jobQueue;
// Timing control: start delay and minimum pause between downloads (ms)
unsigned long _startMs = 0;
unsigned long _lastDownloadMs = 0;
// Flag set by the main loop while module processData() is running; prevents
// new downloads starting in parallel to avoid heap fragmentation.
volatile bool _processingActive = false;
// Configurable User-Agent string (initialized with default from define)
PsramString _userAgent = DEFAULT_USER_AGENT;
bool reallocateBuffer(size_t new_size);
void performJob(const WebJob& job);
void performUpdate(ManagedResource& resource);
static void webWorkerTask(void* param);
};
#endif // WEBCLIENTMODULE_HPP