1
9
10
11
12
13
14
15
16
17
18
19
20
21
22
24
25
26
31
35
36
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
61
62
63
64
67
68
69
70
74
75
76
80
81
82
83
84
85
86
90
91
92
93
94
98
99
100
101
106
107
108
109
110
114
115
116
119
120
121
122
123
130
131
132
133
134
135
136
137
138
139
145
146
147
148
149
150
155
156
157
169
170
171
179
180
181
182
183
184
185
186
187
188
189
193
194
195
198
199
201
202
203
205
206
207
208
209
/* ... */
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "protocol_examples_common.h"
#include <esp_http_server.h>10 includes
/* ... */
static const char *TAG = "ws_echo_server";
/* ... */
struct async_resp_arg {
httpd_handle_t hd;
int fd;
}{ ... };
/* ... */
static void ws_async_send(void *arg)
{
static const char * data = "Async data";
struct async_resp_arg *resp_arg = arg;
httpd_handle_t hd = resp_arg->hd;
int fd = resp_arg->fd;
httpd_ws_frame_t ws_pkt;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = (uint8_t*)data;
ws_pkt.len = strlen(data);
ws_pkt.type = HTTPD_WS_TYPE_TEXT;
httpd_ws_send_frame_async(hd, fd, &ws_pkt);
free(resp_arg);
}{ ... }
static esp_err_t trigger_async_send(httpd_handle_t handle, httpd_req_t *req)
{
struct async_resp_arg *resp_arg = malloc(sizeof(struct async_resp_arg));
if (resp_arg == NULL) {
return ESP_ERR_NO_MEM;
}{...}
resp_arg->hd = req->handle;
resp_arg->fd = httpd_req_to_sockfd(req);
esp_err_t ret = httpd_queue_work(handle, ws_async_send, resp_arg);
if (ret != ESP_OK) {
free(resp_arg);
}{...}
return ret;
}{ ... }
/* ... */
static esp_err_t echo_handler(httpd_req_t *req)
{
if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Handshake done, the new connection was opened");
return ESP_OK;
}{...}
httpd_ws_frame_t ws_pkt;
uint8_t *buf = NULL;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.type = HTTPD_WS_TYPE_TEXT;
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_recv_frame failed to get frame len with %d", ret);
return ret;
}{...}
ESP_LOGI(TAG, "frame len is %d", ws_pkt.len);
if (ws_pkt.len) {
buf = calloc(1, ws_pkt.len + 1);
if (buf == NULL) {
ESP_LOGE(TAG, "Failed to calloc memory for buf");
return ESP_ERR_NO_MEM;
}{...}
ws_pkt.payload = buf;
ret = httpd_ws_recv_frame(req, &ws_pkt, ws_pkt.len);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_recv_frame failed with %d", ret);
free(buf);
return ret;
}{...}
ESP_LOGI(TAG, "Got packet with message: %s", ws_pkt.payload);
}{...}
ESP_LOGI(TAG, "Packet type: %d", ws_pkt.type);
if (ws_pkt.type == HTTPD_WS_TYPE_TEXT &&
strcmp((char*)ws_pkt.payload,"Trigger async") == 0) {
free(buf);
return trigger_async_send(req->handle, req);
}{...}
ret = httpd_ws_send_frame(req, &ws_pkt);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_send_frame failed with %d", ret);
}{...}
free(buf);
return ret;
}{ ... }
static const httpd_uri_t ws = {
.uri = "/ws",
.method = HTTP_GET,
.handler = echo_handler,
.user_ctx = NULL,
.is_websocket = true
}{...};
static httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK) {
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &ws);
return server;
}{...}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}{ ... }
static esp_err_t stop_webserver(httpd_handle_t server)
{
return httpd_stop(server);
}{ ... }
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG, "Stopping webserver");
if (stop_webserver(*server) == ESP_OK) {
*server = NULL;
}{...} else {
ESP_LOGE(TAG, "Failed to stop http server");
}{...}
}{...}
}{ ... }
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
ESP_LOGI(TAG, "Starting webserver");
*server = start_webserver();
}{...}
}{ ... }
void app_main(void)
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* ... */
ESP_ERROR_CHECK(example_connect());
/* ... */
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));/* ... */
#endif
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));/* ... */
#endif
server = start_webserver();
}{ ... }