arduino-audio-tools
Loading...
Searching...
No Matches
URLStreamESP32.h
Go to the documentation of this file.
1#pragma once
2
8#include "esp_http_client.h"
9#include "esp_idf_version.h"
10#include "esp_system.h"
11#include "esp_wifi.h"
12#include "nvs_flash.h"
13
14namespace audio_tools {
15
16class URLStreamESP32;
18
38 public:
39 URLStreamESP32(const char* ssid, const char* pwd) {
41 setPassword(pwd);
43 }
44 URLStreamESP32() : URLStreamESP32(nullptr, nullptr) {}
46 // executes the URL request
47 virtual bool begin(const char* urlStr, const char* acceptMime = "",
48 MethodID action = GET, const char* reqMime = "",
49 const char* reqData = "") {
50 TRACED();
51 if (client_handle != nullptr) {
52 end();
53 }
54 total_read = 0;
57 // start wifi if necessary and possible
58 if (ssid != nullptr) {
59 if (!IDF_WIFI.begin(ssid, password)) {
60 LOGE("Wifi failed");
61 return false;
62 }
63 if (!IDF_WIFI.isConnected()) {
64 // wait for connection
65 Serial.print("Waiting for connection ");
66 while (!IDF_WIFI.isConnected()) {
67 delay(200);
68 Serial.print(".");
69 }
70 Serial.println();
71 }
72 }
73
74 // for headers
76
77 // determine wifi country
78 wifi_country_t cntry;
79 memset(&cntry, 0, sizeof(wifi_country_t));
80 esp_wifi_get_country(&cntry);
81 char text[4] = {0};
82 strncpy(text, cntry.cc, 3);
83 LOGI("wifi country: %s", text);
84
85 // fill http_config
86 esp_http_client_config_t http_config;
87 memset(&http_config, 0, sizeof(http_config));
88 http_config.url = urlStr;
89 http_config.user_agent = DEFAULT_AGENT;
90 http_config.event_handler = http_event_handler;
91 http_config.buffer_size = buffer_size;
92 http_config.timeout_ms = _timeout;
93 http_config.user_data = this;
94 // for SSL certificate
95 if (pem_cert != nullptr) {
96 http_config.cert_pem = (const char*)pem_cert;
97 http_config.cert_len = pem_cert_len;
98 }
99 // for SSL (use of a bundle for certificate verification)
100 if (crt_bundle_attach != nullptr) {
101 http_config.crt_bundle_attach = crt_bundle_attach;
102 }
103
104 switch (action) {
105 case GET:
106 http_config.method = HTTP_METHOD_GET;
107 break;
108 case POST:
109 http_config.method = HTTP_METHOD_POST;
110 break;
111 case PUT:
112 http_config.method = HTTP_METHOD_PUT;
113 break;
114 case DELETE:
115 http_config.method = HTTP_METHOD_DELETE;
116 break;
117 default:
118 LOGE("Unsupported action: %d", action);
119 break;
120 }
121
122 // Init only the first time
123 if (client_handle == nullptr) {
124 client_handle = esp_http_client_init(&http_config);
125 }
126
127 // process header parameters
128 if (!StrView(acceptMime).isEmpty()) addRequestHeader(ACCEPT, acceptMime);
129 if (!StrView(reqMime).isEmpty()) addRequestHeader(CONTENT_TYPE, reqMime);
131 for (auto it = lines.begin(); it != lines.end(); ++it) {
132 if ((*it)->active) {
133 esp_http_client_set_header(client_handle, (*it)->key.c_str(),
134 (*it)->value.c_str());
135 }
136 }
137
138 // Open http
139 if (esp_http_client_open(client_handle, 0) != ESP_OK) {
140 LOGE("esp_http_client_open");
141 return false;
142 }
143
144 // Determine the result
145 content_length = esp_http_client_fetch_headers(client_handle);
146 int status_code = esp_http_client_get_status_code(client_handle);
147 LOGI("status_code: %d / content_length: %d", status_code, content_length);
148
149 // Process post/put data
150 StrView data(reqData);
151 if (!data.isEmpty()) {
152 write((const uint8_t*)reqData, data.length());
153 }
154
155 return status_code == 200;
156 }
157 // ends the request
158 virtual void end() override {
159 if (client_handle == nullptr) return;
160 esp_http_client_close(client_handle);
161 esp_http_client_cleanup(client_handle);
162 client_handle = nullptr;
163 }
164
166 int availableForWrite() override { return 1024; }
167
169 virtual void setSSID(const char* ssid) { this->ssid = ssid; }
170
172 virtual void setPassword(const char* password) { this->password = password; }
173
175 virtual void setPowerSave(bool ps) {
176 IDF_WIFI.setPowerSave(ps ? WIFI_PS_MAX_MODEM : WIFI_PS_NONE);
177 }
178
179 size_t write(const uint8_t* data, size_t len) override {
180 TRACED();
181 int written = esp_http_client_write(client_handle, (const char*)data, len);
182 if (written < 0) {
183 LOGE("esp_http_client_write: %d", written);
184 return 0;
185 }
186 return written;
187 }
188
189 size_t readBytes(uint8_t* data, size_t len) override {
190 TRACED();
191 int read = esp_http_client_read(client_handle, (char*)data, len);
192 if (read < 0) {
193 LOGE("esp_http_client_read: %d", read);
194 return 0;
195 }
196 total_read += read;
197 return read;
198 }
199
201 void addRequestHeader(const char* key, const char* value) override {
202 TRACED();
203 request.addRequestHeader(key, value);
204 }
206 const char* getReplyHeader(const char* key) override {
207 return request.getReplyHeader(key);
208 }
209
212 void setCACert(const char* cert) override {
213 int len = strlen(cert);
214 setCACert((const uint8_t*)cert, len + 1);
215 }
216
219 void setCACert(esp_err_t (*cb)(void* conf)) { crt_bundle_attach = cb; }
220
222 void setReadBufferSize(int size) { buffer_size = size; }
223
225 HttpRequest& httpRequest() override { return request; }
226
228 void setClient(Client& client) override {}
229
231 const char* urlStr() override { return (char*)url_str; }
232
234 size_t totalRead() override { return total_read; }
235
237 int contentLength() override { return content_length; }
238
240 virtual bool waitForData(int timeout) override{ return false; }
242 void setConnectionClose(bool flag) override {}
243
244 protected:
245 int id = 0;
247 esp_http_client_handle_t client_handle = nullptr;
248 bool is_power_save = false;
249 const char* ssid = nullptr;
250 const char* password = nullptr;
252 const uint8_t* pem_cert = nullptr;
254 esp_err_t (*crt_bundle_attach)(void* conf) = nullptr;
255 size_t total_read = 0;
256 const char* url_str = nullptr;
258
261 void setCACert(const uint8_t* cert, int len) {
262 pem_cert_len = len;
263 pem_cert = cert;
264 // certificate must end with traling null
265 assert(cert[len - 1] == 0);
266 }
267
268 static esp_err_t http_event_handler(esp_http_client_event_t* evt) {
269 switch (evt->event_id) {
270 case HTTP_EVENT_ERROR:
271 LOGI("HTTP_EVENT_ERROR");
272 break;
273 case HTTP_EVENT_ON_CONNECTED:
274 LOGD("HTTP_EVENT_ON_CONNECTED");
275 break;
276 case HTTP_EVENT_HEADER_SENT:
277 LOGD("HTTP_EVENT_HEADER_SENT");
278 break;
279 case HTTP_EVENT_ON_HEADER:
280 LOGI("HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key,
281 evt->header_value);
282 // store reply headers
283 actualURLStreamESP32->request.reply().put(evt->header_key,
284 evt->header_value);
285 break;
286 case HTTP_EVENT_ON_DATA:
287 LOGD("HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
288 break;
289 case HTTP_EVENT_ON_FINISH:
290 LOGI("HTTP_EVENT_ON_FINISH");
291 break;
292 case HTTP_EVENT_DISCONNECTED:
293 LOGI("HTTP_EVENT_DISCONNECTED");
294 break;
295#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 7)
296 case HTTP_EVENT_REDIRECT:
297 LOGI("HTTP_EVENT_REDIRECT");
298 break;
299#endif
300 }
301 return ESP_OK;
302 }
303};
304
307#if defined(USE_CONCURRENCY)
312#endif
313
315#if !defined(ARDUINO)
322#endif
323
324} // namespace audio_tools
static HardwareSerial Serial
Definition Arduino.h:179
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
MethodID
supported http methods
Definition HttpTypes.h:3
@ GET
Definition HttpTypes.h:5
@ POST
Definition HttpTypes.h:7
@ DELETE
Definition HttpTypes.h:9
@ PUT
Definition HttpTypes.h:8
#define DEFAULT_BUFFER_SIZE
Definition avr.h:20
#define assert(T)
Definition avr.h:10
Definition Arduino.h:162
int _timeout
Definition Arduino.h:133
Abstract Base class for all URLStream implementations.
Definition AbstractURLStream.h:17
List< HttpHeaderLine * > & getHeaderLines()
Provides the http parameter lines.
Definition HttpHeader.h:323
HttpHeader & put(const char *key, const char *value)
Definition HttpHeader.h:86
Simple API to process get, put, post, del http requests I tried to use Arduino HttpClient,...
Definition HttpRequest.h:25
virtual HttpReplyHeader & reply()
Definition HttpRequest.h:163
void addRequestHeader(const char *key, const char *value)
Adds/Updates a request header.
Definition HttpRequest.h:197
virtual HttpRequestHeader & header()
provides access to the request header
Definition HttpRequest.h:166
const char * getReplyHeader(const char *key)
Definition HttpRequest.h:200
Buffered ICYStream with metadata callback support.
Definition ICYStream.h:18
Icecast/Shoutcast audio stream that separates ICY metadata from audio bytes.
Definition ICYStreamT.h:42
Double linked list.
Definition List.h:18
Iterator begin()
Definition List.h:273
Iterator end()
Definition List.h:278
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
virtual int length()
Definition StrView.h:384
virtual bool isEmpty()
checks if the string is empty
Definition StrView.h:387
URLStream implementation for the ESP32 based on a separate FreeRTOS task: the.
Definition URLStreamBufferedT.h:162
URLStream using the ESP32 IDF API.
Definition URLStreamESP32.h:37
size_t totalRead() override
Total amout of data that was consumed so far.
Definition URLStreamESP32.h:234
size_t total_read
Definition URLStreamESP32.h:255
virtual void setPowerSave(bool ps)
Sets the power save mode (default false)!
Definition URLStreamESP32.h:175
URLStreamESP32()
Definition URLStreamESP32.h:44
URLStreamESP32(const char *ssid, const char *pwd)
Definition URLStreamESP32.h:39
HttpRequest request
Definition URLStreamESP32.h:246
~URLStreamESP32()
Definition URLStreamESP32.h:45
void setCACert(esp_err_t(*cb)(void *conf))
Definition URLStreamESP32.h:219
esp_http_client_handle_t client_handle
Definition URLStreamESP32.h:247
size_t readBytes(uint8_t *data, size_t len) override
Definition URLStreamESP32.h:189
virtual void setSSID(const char *ssid)
Sets the ssid that will be used for logging in (when calling begin)
Definition URLStreamESP32.h:169
const char * ssid
Definition URLStreamESP32.h:249
virtual void setPassword(const char *password)
Sets the password that will be used for logging in (when calling begin)
Definition URLStreamESP32.h:172
int pem_cert_len
Definition URLStreamESP32.h:253
esp_err_t(* crt_bundle_attach)(void *conf)
Definition URLStreamESP32.h:254
virtual bool begin(const char *urlStr, const char *acceptMime="", MethodID action=GET, const char *reqMime="", const char *reqData="")
Definition URLStreamESP32.h:47
int content_length
Definition URLStreamESP32.h:257
virtual bool waitForData(int timeout) override
Not used.
Definition URLStreamESP32.h:240
HttpRequest & httpRequest() override
Used for request and reply header parameters.
Definition URLStreamESP32.h:225
size_t write(const uint8_t *data, size_t len) override
Definition URLStreamESP32.h:179
static esp_err_t http_event_handler(esp_http_client_event_t *evt)
Definition URLStreamESP32.h:268
void setCACert(const uint8_t *cert, int len)
Definition URLStreamESP32.h:261
int availableForWrite() override
Writes are not supported.
Definition URLStreamESP32.h:166
const char * url_str
Definition URLStreamESP32.h:256
void addRequestHeader(const char *key, const char *value) override
Adds/Updates a request header.
Definition URLStreamESP32.h:201
const char * password
Definition URLStreamESP32.h:250
const char * urlStr() override
Provides the url as string.
Definition URLStreamESP32.h:231
void setConnectionClose(bool flag) override
Not used.
Definition URLStreamESP32.h:242
void setCACert(const char *cert) override
Definition URLStreamESP32.h:212
int contentLength() override
Provides the reported data size from the http reply.
Definition URLStreamESP32.h:237
void setClient(Client &client) override
Does nothing.
Definition URLStreamESP32.h:228
const uint8_t * pem_cert
Definition URLStreamESP32.h:252
virtual void end() override
Definition URLStreamESP32.h:158
void setReadBufferSize(int size)
Defines the read buffer size.
Definition URLStreamESP32.h:222
int buffer_size
Definition URLStreamESP32.h:251
bool is_power_save
Definition URLStreamESP32.h:248
const char * getReplyHeader(const char *key) override
Provides a header entry.
Definition URLStreamESP32.h:206
Represents the content of a URL as Stream. We use the WiFi.h API. If you run into performance issues,...
Definition URLStream.h:26
bool begin(const char *ssid, const char *password)
Definition WiFiESP32.h:20
void setPowerSave(wifi_ps_type_t powerSave)
Definition WiFiESP32.h:41
bool isConnected()
Definition WiFiESP32.h:43
#define URL_CLIENT_TIMEOUT
Definition esp8266.h:23
class audio_tools::WiFiESP32 IDF_WIFI
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
static const char * DEFAULT_AGENT
Definition HttpHeader.h:27
URLStreamBufferedT< URLStreamESP32 > URLStreamBufferedESP32
Buffered URLStream for ESP32 platform.
Definition URLStreamESP32.h:309
void delay(uint32_t ms)
Definition Arduino.h:255
static URLStreamESP32 * actualURLStreamESP32
Definition URLStreamESP32.h:17
static const char * CONTENT_TYPE
Definition HttpHeader.h:16
URLStreamBufferedT< ICYStreamESP32 > ICYStreamBufferedESP32
Buffered ICYStream for ESP32 platform.
Definition URLStreamESP32.h:311
static const char * ACCEPT
Definition HttpHeader.h:23