arduino-audio-tools
Loading...
Searching...
No Matches
URLStreamESP32.h
Go to the documentation of this file.
1#pragma once
2
7#include "esp_http_client.h"
8#include "esp_idf_version.h"
9#include "esp_system.h"
10#include "esp_wifi.h"
11#include "nvs_flash.h"
12
13namespace audio_tools {
14
22class WiFiESP32 {
23 public:
24 bool begin(const char* ssid, const char* password) {
25 TRACEI();
26 if (is_open) return true;
27 if (!setupWIFI(ssid, password)) {
28 LOGE("setupWIFI failed");
29 return false;
30 }
31
32 return true;
33 }
34
35 void end() {
36 TRACED();
37 if (is_open) {
38 TRACEI();
41 }
42 is_open = false;
43 }
44
46
47 bool isConnected() { return is_open; }
48
49 protected:
50 volatile bool is_open = false;
53
54 bool setupWIFI(const char* ssid, const char* password) {
55 assert(ssid != nullptr);
56 assert(password != nullptr);
57 LOGI("setupWIFI: %s", ssid);
59 if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
62 ret = nvs_flash_init();
63 }
64
65 if (esp_netif_init() != ESP_OK) {
66 LOGE("esp_netif_init");
67 return false;
68 };
69
71 LOGE("esp_event_loop_create_default");
72 return false;
73 };
74
76 if (itf == nullptr) {
77 LOGE("esp_netif_create_default_wifi_sta");
78 return false;
79 };
80
86 if (esp_wifi_init(&cfg) != ESP_OK) {
87 LOGE("esp_wifi_init");
88 return false;
89 }
90
93
95 memset(&sta_config, 0, sizeof(wifi_config_t));
96 strncpy((char*)sta_config.sta.ssid, ssid, 32);
97 strncpy((char*)sta_config.sta.password, password, 32);
98 sta_config.sta.threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK;
100
101 // start wifi
102 bool rc = esp_wifi_start() == ESP_OK;
103 if (!rc) {
104 LOGE("esp_wifi_start");
105 }
106 return rc;
107 }
108
110 int32_t event_id, void* event_data) {
111 WiFiESP32* self = (WiFiESP32*)arg;
112
113 if (event_base == WIFI_EVENT) {
114 switch (event_id) {
116 LOGI("WIFI_EVENT_STA_START");
118 break;
120 LOGI("WIFI_EVENT_STA_DISCONNECTED");
122 break;
123 }
124 } else if (event_base == IP_EVENT) {
125 switch (event_id) {
126 case IP_EVENT_STA_GOT_IP: {
128 self->ip = event->ip_info.ip;
129 self->is_open = true;
130 LOGI("==> Station connected with IP: " IPSTR ", GW: " IPSTR
131 ", Mask: " IPSTR ".",
132 IP2STR(&event->ip_info.ip), IP2STR(&event->ip_info.gw),
133 IP2STR(&event->ip_info.netmask));
134 break;
135 }
136 }
137 }
138 }
139
140} static IDF_WIFI;
141
142class URLStreamESP32;
144
164 public:
165 URLStreamESP32(const char* ssid, const char* pwd) {
166 setSSID(ssid);
169 }
172 // executes the URL request
173 virtual bool begin(const char* urlStr, const char* acceptMime = "",
174 MethodID action = GET, const char* reqMime = "",
175 const char* reqData = "") {
176 TRACED();
177 if (client_handle != nullptr) {
178 end();
179 }
180 total_read = 0;
181 url_str = urlStr;
182 content_length = 0;
183 // start wifi if necessary and possible
184 if (ssid != nullptr) {
185 if (!IDF_WIFI.begin(ssid, password)) {
186 LOGE("Wifi failed");
187 return false;
188 }
189 if (!IDF_WIFI.isConnected()) {
190 // wait for connection
191 Serial.print("Waiting for connection ");
192 while (!IDF_WIFI.isConnected()) {
193 delay(200);
194 Serial.print(".");
195 }
196 Serial.println();
197 }
198 }
199
200 // for headers
202
203 // determine wifi country
205 memset(&cntry, 0, sizeof(wifi_country_t));
207 char text[4] = {0};
208 strncpy(text, cntry.cc, 3);
209 LOGI("wifi country: %s", text);
210
211 // fill http_config
213 memset(&http_config, 0, sizeof(http_config));
214 http_config.url = urlStr;
215 http_config.user_agent = DEFAULT_AGENT;
216 http_config.event_handler = http_event_handler;
217 http_config.buffer_size = buffer_size;
218 http_config.timeout_ms = _timeout;
219 http_config.user_data = this;
220 // for SSL certificate
221 if (pem_cert != nullptr) {
222 http_config.cert_pem = (const char*)pem_cert;
223 http_config.cert_len = pem_cert_len;
224 }
225 // for SSL (use of a bundle for certificate verification)
226 if (crt_bundle_attach != nullptr) {
227 http_config.crt_bundle_attach = crt_bundle_attach;
228 }
229
230 switch (action) {
231 case GET:
233 break;
234 case POST:
236 break;
237 case PUT:
239 break;
240 case DELETE:
242 break;
243 default:
244 LOGE("Unsupported action: %d", action);
245 break;
246 }
247
248 // Init only the first time
249 if (client_handle == nullptr) {
251 }
252
253 // process header parameters
257 for (auto it = lines.begin(); it != lines.end(); ++it) {
258 if ((*it)->active) {
259 esp_http_client_set_header(client_handle, (*it)->key.c_str(),
260 (*it)->value.c_str());
261 }
262 }
263
264 // Open http
266 LOGE("esp_http_client_open");
267 return false;
268 }
269
270 // Determine the result
273 LOGI("status_code: %d / content_length: %d", status_code, content_length);
274
275 // Process post/put data
276 StrView data(reqData);
277 if (!data.isEmpty()) {
278 write((const uint8_t*)reqData, data.length());
279 }
280
281 return status_code == 200;
282 }
283 // ends the request
284 virtual void end() override {
285 if (client_handle == nullptr) return;
288 client_handle = nullptr;
289 }
290
292 int availableForWrite() override { return 1024; }
293
295 virtual void setSSID(const char* ssid) { this->ssid = ssid; }
296
298 virtual void setPassword(const char* password) { this->password = password; }
299
304
305 size_t write(const uint8_t* data, size_t len) override {
306 TRACED();
307 int written = esp_http_client_write(client_handle, (const char*)data, len);
308 if (written < 0) {
309 LOGE("esp_http_client_write: %d", written);
310 return 0;
311 }
312 return written;
313 }
314
315 size_t readBytes(uint8_t* data, size_t len) override {
316 TRACED();
317 int read = esp_http_client_read(client_handle, (char*)data, len);
318 if (read < 0) {
319 LOGE("esp_http_client_read: %d", read);
320 return 0;
321 }
322 total_read += read;
323 return read;
324 }
325
327 void addRequestHeader(const char* key, const char* value) override {
328 TRACED();
329 request.addRequestHeader(key, value);
330 }
332 const char* getReplyHeader(const char* key) override {
333 return request.getReplyHeader(key);
334 }
335
338 void setCACert(const char* cert) override {
339 int len = strlen(cert);
340 setCACert((const uint8_t*)cert, len + 1);
341 }
342
345 void setCACert(esp_err_t (*cb)(void* conf)) { crt_bundle_attach = cb; }
346
348 void setReadBufferSize(int size) { buffer_size = size; }
349
351 HttpRequest& httpRequest() override { return request; }
352
354 void setClient(Client& client) override {}
355
357 const char* urlStr() override { return (char*)url_str; }
358
360 size_t totalRead() override { return total_read; }
361
363 int contentLength() override { return content_length; }
364
366 virtual bool waitForData(int timeout) override{ return false; }
368 void setConnectionClose(bool flag) override {}
369
370 protected:
371 int id = 0;
374 bool is_power_save = false;
375 const char* ssid = nullptr;
376 const char* password = nullptr;
378 const uint8_t* pem_cert = nullptr;
380 esp_err_t (*crt_bundle_attach)(void* conf) = nullptr;
381 size_t total_read = 0;
382 const char* url_str = nullptr;
384
387 void setCACert(const uint8_t* cert, int len) {
388 pem_cert_len = len;
389 pem_cert = cert;
390 // certificate must end with traling null
391 assert(cert[len - 1] == 0);
392 }
393
395 switch (evt->event_id) {
396 case HTTP_EVENT_ERROR:
397 LOGI("HTTP_EVENT_ERROR");
398 break;
400 LOGD("HTTP_EVENT_ON_CONNECTED");
401 break;
403 LOGD("HTTP_EVENT_HEADER_SENT");
404 break;
406 LOGI("HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key,
407 evt->header_value);
408 // store reply headers
410 evt->header_value);
411 break;
413 LOGD("HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
414 break;
416 LOGI("HTTP_EVENT_ON_FINISH");
417 break;
419 LOGI("HTTP_EVENT_DISCONNECTED");
420 break;
421#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 7)
423 LOGI("HTTP_EVENT_REDIRECT");
424 break;
425#endif
426 }
427 return ESP_OK;
428 }
429};
430
433#if defined(USE_CONCURRENCY)
438#endif
439
441#if !defined(ARDUINO)
448#endif
449
450} // namespace audio_tools
#define TRACEI()
Definition AudioLoggerIDF.h:32
#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
Abstract Base class for all URLStream implementations.
Definition AbstractURLStream.h:17
Definition NoArduino.h:169
List< HttpHeaderLine * > & getHeaderLines()
Provides the http parameter lines.
Definition HttpHeader.h:317
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:165
void addRequestHeader(const char *key, const char *value)
Adds/Updates a request header.
Definition HttpRequest.h:199
virtual HttpRequestHeader & header()
provides access to the request header
Definition HttpRequest.h:168
const char * getReplyHeader(const char *key)
Definition HttpRequest.h:202
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
int _timeout
Definition NoArduino.h:139
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:383
virtual bool isEmpty()
checks if the string is empty
Definition StrView.h:386
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:163
size_t totalRead() override
Total amout of data that was consumed so far.
Definition URLStreamESP32.h:360
size_t total_read
Definition URLStreamESP32.h:381
virtual void setPowerSave(bool ps)
Sets the power save mode (default false)!
Definition URLStreamESP32.h:301
URLStreamESP32()
Definition URLStreamESP32.h:170
URLStreamESP32(const char *ssid, const char *pwd)
Definition URLStreamESP32.h:165
HttpRequest request
Definition URLStreamESP32.h:372
~URLStreamESP32()
Definition URLStreamESP32.h:171
void setCACert(esp_err_t(*cb)(void *conf))
Definition URLStreamESP32.h:345
esp_http_client_handle_t client_handle
Definition URLStreamESP32.h:373
size_t readBytes(uint8_t *data, size_t len) override
Definition URLStreamESP32.h:315
virtual void setSSID(const char *ssid)
Sets the ssid that will be used for logging in (when calling begin)
Definition URLStreamESP32.h:295
const char * ssid
Definition URLStreamESP32.h:375
virtual void setPassword(const char *password)
Sets the password that will be used for logging in (when calling begin)
Definition URLStreamESP32.h:298
int pem_cert_len
Definition URLStreamESP32.h:379
esp_err_t(* crt_bundle_attach)(void *conf)
Definition URLStreamESP32.h:380
virtual bool begin(const char *urlStr, const char *acceptMime="", MethodID action=GET, const char *reqMime="", const char *reqData="")
Definition URLStreamESP32.h:173
int content_length
Definition URLStreamESP32.h:383
virtual bool waitForData(int timeout) override
Not used.
Definition URLStreamESP32.h:366
HttpRequest & httpRequest() override
Used for request and reply header parameters.
Definition URLStreamESP32.h:351
size_t write(const uint8_t *data, size_t len) override
Definition URLStreamESP32.h:305
static esp_err_t http_event_handler(esp_http_client_event_t *evt)
Definition URLStreamESP32.h:394
void setCACert(const uint8_t *cert, int len)
Definition URLStreamESP32.h:387
int availableForWrite() override
Writes are not supported.
Definition URLStreamESP32.h:292
const char * url_str
Definition URLStreamESP32.h:382
void addRequestHeader(const char *key, const char *value) override
Adds/Updates a request header.
Definition URLStreamESP32.h:327
const char * password
Definition URLStreamESP32.h:376
const char * urlStr() override
Provides the url as string.
Definition URLStreamESP32.h:357
void setConnectionClose(bool flag) override
Not used.
Definition URLStreamESP32.h:368
void setCACert(const char *cert) override
Definition URLStreamESP32.h:338
int contentLength() override
Provides the reported data size from the http reply.
Definition URLStreamESP32.h:363
void setClient(Client &client) override
Does nothing.
Definition URLStreamESP32.h:354
const uint8_t * pem_cert
Definition URLStreamESP32.h:378
virtual void end() override
Definition URLStreamESP32.h:284
void setReadBufferSize(int size)
Defines the read buffer size.
Definition URLStreamESP32.h:348
int buffer_size
Definition URLStreamESP32.h:377
bool is_power_save
Definition URLStreamESP32.h:374
const char * getReplyHeader(const char *key) override
Provides a header entry.
Definition URLStreamESP32.h:332
Represents the content of a URL as Stream. We use the WiFi.h API. If you run into performance issues,...
Definition URLStream.h:26
Login to Wifi using the ESP32 IDF functionality. This can be accessed with the global object IDF_WIFI...
Definition URLStreamESP32.h:22
esp_ip4_addr_t ip
Definition URLStreamESP32.h:51
bool begin(const char *ssid, const char *password)
Definition URLStreamESP32.h:24
volatile bool is_open
Definition URLStreamESP32.h:50
void setPowerSave(wifi_ps_type_t powerSave)
Definition URLStreamESP32.h:45
bool isConnected()
Definition URLStreamESP32.h:47
static void wifi_sta_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
Definition URLStreamESP32.h:109
bool setupWIFI(const char *ssid, const char *password)
Definition URLStreamESP32.h:54
void end()
Definition URLStreamESP32.h:35
wifi_ps_type_t power_save
Definition URLStreamESP32.h:52
#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 AudioCodecsBase.h:10
static const char * DEFAULT_AGENT
Definition HttpHeader.h:27
URLStreamBufferedT< URLStreamESP32 > URLStreamBufferedESP32
Buffered URLStream for ESP32 platform.
Definition URLStreamESP32.h:435
void delay(unsigned long ms)
Definition Time.h:23
static HardwareSerial Serial
Definition NoArduino.h:186
static URLStreamESP32 * actualURLStreamESP32
Definition URLStreamESP32.h:143
static const char * CONTENT_TYPE
Definition HttpHeader.h:16
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
URLStreamBufferedT< ICYStreamESP32 > ICYStreamBufferedESP32
Buffered ICYStream for ESP32 platform.
Definition URLStreamESP32.h:437
static const char * ACCEPT
Definition HttpHeader.h:23