-
Notifications
You must be signed in to change notification settings - Fork 1
/
Websocket-Server-GET-POST.c
179 lines (158 loc) · 5.77 KB
/
Websocket-Server-GET-POST.c
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Websocket Server responsive to GET and POST request on the same URL
#include <stdio.h>
#include <sys/param.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/event_groups.h"
#include <esp_http_server.h>
#include "my_data.h"
static const char *TAG = "Websocket Server: ";
static void wifi_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
switch (event_id)
{
case WIFI_EVENT_STA_START:
printf("WiFi connecting ... \n");
break;
case WIFI_EVENT_STA_CONNECTED:
printf("WiFi connected ... \n");
break;
case WIFI_EVENT_STA_DISCONNECTED:
printf("WiFi lost connection ... \n");
break;
case IP_EVENT_STA_GOT_IP:
printf("WiFi got IP ... \n\n");
break;
default:
break;
}
}
void wifi_connection()
{
nvs_flash_init();
// 1 - Wi-Fi/LwIP Init Phase
esp_netif_init(); // TCP/IP initiation s1.1
esp_event_loop_create_default(); // event loop s1.2
esp_netif_create_default_wifi_sta(); // WiFi station s1.3
wifi_init_config_t wifi_initiation = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_initiation); // s1.4
// 2 - Wi-Fi Configuration Phase
esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL);
wifi_config_t wifi_configuration = {
.sta = {
.ssid = SSID,
.password = PASS}};
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_configuration);
// 3 - Wi-Fi Start Phase
esp_wifi_start();
// 4- Wi-Fi Connect Phase
esp_wifi_connect();
}
// Asynchronous response data structure
struct async_resp_arg
{
httpd_handle_t hd; // Server instance
int fd; // Session socket file descriptor for cilent
};
// The asynchronous response GET
static void generate_async_resp_get(void *arg)
{
// Data format to be sent from the server as a response to the client
char http_string[250];
char *data_string = "GET response from ESP32 websocket server ...";
sprintf(http_string, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n", strlen(data_string));
// Initialize asynchronous response data structure
struct async_resp_arg *resp_arg = (struct async_resp_arg *)arg;
httpd_handle_t hd = resp_arg->hd;
int fd = resp_arg->fd;
// Send data to the client
ESP_LOGI(TAG, "Executing queued work GET fd : %d", fd);
httpd_socket_send(hd, fd, http_string, strlen(http_string), 0);
httpd_socket_send(hd, fd, data_string, strlen(data_string), 0);
free(arg);
}
// The asynchronous response POST
static void generate_async_resp_post(void *arg)
{
// Data format to be sent from the server as a response to the client
char http_string[250];
char *data_string = "POST response from ESP32 websocket server ...";
sprintf(http_string, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n", strlen(data_string));
// Initialize asynchronous response data structure
struct async_resp_arg *resp_arg = (struct async_resp_arg *)arg;
httpd_handle_t hd = resp_arg->hd;
int fd = resp_arg->fd;
// Send data to the client
ESP_LOGI(TAG, "Executing queued work POST fd : %d", fd);
httpd_socket_send(hd, fd, http_string, strlen(http_string), 0);
httpd_socket_send(hd, fd, data_string, strlen(data_string), 0);
free(arg);
}
// Initialize a queue for asynchronous communication for GET
static esp_err_t async_get_handler(httpd_req_t *req)
{
struct async_resp_arg *resp_arg = malloc(sizeof(struct async_resp_arg));
resp_arg->hd = req->handle;
resp_arg->fd = httpd_req_to_sockfd(req);
ESP_LOGI(TAG, "Queuing work GET fd : %d", resp_arg->fd);
httpd_queue_work(req->handle, generate_async_resp_get, resp_arg);
return ESP_OK;
}
// Initialize a queue for asynchronous communication for POST
esp_err_t async_post_handler(httpd_req_t *req)
{
// Read data send by the client
char content[100];
size_t recv_size = MIN(req->content_len, sizeof(content));
httpd_req_recv(req, content, recv_size);
printf("Data send by the client: %.*s\n", recv_size, content);
// Generate server response queue
struct async_resp_arg *resp_arg = malloc(sizeof(struct async_resp_arg));
resp_arg->hd = req->handle;
resp_arg->fd = httpd_req_to_sockfd(req);
ESP_LOGI(TAG, "Queuing work POST fd : %d", resp_arg->fd);
httpd_queue_work(req->handle, generate_async_resp_post, resp_arg);
return ESP_OK;
}
// Create URI (Uniform Resource Identifier) handler structure for GET
// for the server which is added to default gateway
static const httpd_uri_t uri_get = {
.uri = "/ws", // URL added to WiFi's default gateway
.method = HTTP_GET,
.handler = async_get_handler,
.user_ctx = NULL,
};
// URI handler structure for POST
httpd_uri_t uri_post = {
.uri = "/ws",
.method = HTTP_POST,
.handler = async_post_handler,
.user_ctx = NULL
};
static void websocket_app_start(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK)
{
// Registering the uri_handler
ESP_LOGI(TAG, "Registering URI handler");
httpd_register_uri_handler(server, &uri_get);
httpd_register_uri_handler(server, &uri_post);
}
}
void app_main(void)
{
wifi_connection();
vTaskDelay(1500 / portTICK_RATE_MS);
websocket_app_start();
}