in my program, I check error value, which netconn_close and netconn_delete return. Netconn_close return ERR_OK, but after it netconn_delete return ERR_VAL(-6). It is normal situation ?
Here is my code:
Code: Select all
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "freertos/portmacro.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "tcpip_adapter.h"
#include "lwip/priv/api_msg.h"
#include "lwip/sockets.h"
#include "lwip/tcp.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/api.h"
#include "lwip/err.h"
#include "lwip/netbuf.h"
#include "lwip/netifapi.h"
#include "lwip/pppapi.h"
#include "string.h"
#include "cJSON.h"
#define MEMP_NUM_NETCONN 20
SemaphoreHandle_t taskSemaphore = NULL;
char* json_unformatted;
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
//static char* TAG = "app_main";
bool sta_is_configured = false;
char* ssid;
char* pwd;
struct netconn conn_array[5];
struct channel
{
char name[80];
char data_str[80];
int data_int;
};
struct channel channel_list[10];
#define delay(ms) (vTaskDelay(ms/portTICK_RATE_MS))
char* json_unformatted;
const static char http_html_hdr[] =
"HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
const static char http_index_hml[] = "<!DOCTYPE html>"
"<html>\n"
"<head>\n"
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
" <style type=\"text/css\">\n"
" html, body, iframe { margin: 0; padding: 0; height: 100%; }\n"
" iframe { display: block; width: 100%; border: none; }\n"
" </style>\n"
"<title>HELLO ESP32</title>\n"
"</head>\n"
"<body>\n"
"<h1>Hello World, from ESP32!</h1>\n"
"</body>\n"
"</html>\n";
char http_index_hml_sta_config[] = "<!DOCTYPE html>"
"<html>\n"
"<head>\n"
"<title>HELLO ESP32</title>\n"
"</head>\n"
"<body>\n"
"<h1>Hello World, from ESP32!</h1>\n"
"<form name=\"myForm\" onsubmit=\"sendForm(); return false;\">\n"
"SSID:<br><input type=\"text\" name=\"ssid\" value=\"\"><br>\n"
"PASS:<br><input type=\"text\" name=\"pass\" value=\"\"><br>\n"
"<input type=\"submit\" value=\"Zapisz\">\n"
"</form><br>\n"
"<script>\n"
"function sendForm() {\n"
"var x = document.forms[\"myForm\"][\"ssid\"].value;\n"
"var y = document.forms[\"myForm\"][\"pass\"].value;\n"
"var xhttp = new XMLHttpRequest();\n"
"xhttp.onreadystatechange = function() {\n"
"if (this.readyState == 4 && this.status == 200) {\n"
"location.reload(true);\n"
"}\n"
"};\n"
"var url = \"?ssid=\"+x+\"&pass=\"+y;\n"
"xhttp.open(\"GET\", url, true);\n"
"xhttp.send();\n"
"document.forms[\"myForm\"].reset()};\n"
"</script>\n"
"</body>\n"
"</html>\n";
char http_index_hml_tmp[] = "<!DOCTYPE html>"
"<html style=\"height: 100%;\">\n"
"<body style=\"color:white; background:linear-gradient(141deg, #0fb8ad 0%, #1fc8db 51%, #2cb5e8 75%);\">\n"
"<title>HELLO ESP32</title>\n"
"</head>\n"
"<body>\n"
"<h1>Hello World, from ESP32!</h1>\n"
"<form name=\"myForm\" onsubmit=\"sendForm(); return false;\">\n"
"Kanal:<br><input type=\"text\" name=\"channel_add\" value=\"\"><br>\n"
"<input type=\"submit\" value=\"Dodaj kanal\">\n"
"</form><br>\n"
"<div style=\"float: left; width: 15%;\">\n"
"Kanal:\n"
"<ul id = \"channel\"> </ul>\n"
"</div>\n"
"<div style=\"float: left; width: 15%;\">\n"
"Pomiary:\n"
"<ul id = \"data\" style=\"list-style: none;\"> </ul>\n"
"</div>\n"
"<script>\n"
"function sendForm() {\n"
"var x = document.forms[\"myForm\"][\"channel_add\"].value;\n"
"var xhttp = new XMLHttpRequest();\n"
"var url = \"?channel_add=\"+x;\n"
"xhttp.open(\"GET\", url, true);\n"
"xhttp.send();\n"
"document.forms[\"myForm\"].reset()};\n"
"setInterval(function(){\n"
"var xhttp = new XMLHttpRequest();\n"
"xhttp.onreadystatechange = function() {\n"
"if (this.readyState == 4 && this.status == 200) {\n"
"obj = JSON.parse(this.responseText);\n"
"var outleft = \"\";\n"
"var outright = \"\";\n"
"var i;\n"
"for(i = 0; i < obj.length; i++) {\n"
"outleft += \"<li>\"+obj[i].Name +\"</li>\";\n"
"outright += \"<li>\"+obj[i].Data +\" \"+\"</li>\";\n"
"}\n"
"document.getElementById(\"channel\").innerHTML = outleft;\n"
"document.getElementById(\"data\").innerHTML = outright;\n }\n };\n"
"xhttp.open(\"GET\", \"&\", true);\n"
"xhttp.send();\n },10000);\n"
"</script>\n </body>\n </html>\n";
int num = 0;
static void generate_json() {
cJSON *root, *d;
root = cJSON_CreateArray();
for(int i = 0;i<10;i++)
{
if(channel_list[i].name[0] != 0)
{
cJSON_AddItemToArray(root, d = cJSON_CreateObject());
cJSON_AddStringToObject(d, "Name", channel_list[i].name);
cJSON_AddStringToObject(d, "Data", channel_list[i].data_str);
}
}
json_unformatted = cJSON_PrintUnformatted(root);
printf("[len = %d] ", strlen(json_unformatted));
printf("%s\n", json_unformatted);
}
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
printf("got ip\n");
printf("ip: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.ip));
printf("netmask: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.netmask));
printf("gw: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.gw));
printf("\n");
fflush(stdout);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );
wifi_config_t ap_config =
{
.ap =
{
.ssid = "czesc",
.password = "12345678",
.authmode = WIFI_AUTH_WPA_WPA2_PSK,
.ssid_len = 0,
.max_connection = 16,
}
};
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &ap_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void
http_server_netconn_serve(struct netconn *conn)
{
printf("%d\n", esp_get_free_heap_size());
struct netbuf *inbuf;
char *buf;
u16_t buflen;
char* buf_temp = malloc(sizeof(char)*80);
char* ChannelToAddMeasure = malloc(sizeof(char)*80);
/* Read the data from the port, blocking if nothing yet there.
We assume the request (the part we care about) is in one netbuf */
netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY);
if (netconn_recv(conn, &inbuf) == ERR_OK) {
err_t err2 = netbuf_data(inbuf,(void**)&buf,&buflen);
printf("EEEEEEE%d\n", err2);
/* Is this an HTTP GET command? (only check the first 5 chars, since
there are other formats for GET, and we're keeping it very simple )*/
printf("buffer = %s \n", buf);
printf("buflen = %d\n", buflen);
if (buflen>=5 && buf[0]=='G' && buf[1]=='E' && buf[2]=='T' && buf[3]==' ' && buf[4]=='/' && buf[5]=='&' )
{
generate_json();
printf("po funkcji\n");
err_t err_write;
err_write = netconn_write(conn, json_unformatted, strlen(json_unformatted), NETCONN_NOCOPY);
printf("%d\n", err_write);
free(json_unformatted);
printf("po write\n");
printf("po free\n");
}
else if (buflen>=5 && buf[0]=='G' && buf[1]=='E' && buf[2]=='T' && buf[3]==' ' && buf[4]=='/' && buf[5]=='!' )
{
int HTTP_pos=6;
int measure_pos=0;
int liczba;
int ChannelToAddMeasurePos=0;
memset(buf_temp,0,sizeof(char)*80);
memset(ChannelToAddMeasure,0,sizeof(char)*80);
printf("tutaj\n");
while(buf[HTTP_pos]!='H')
{
HTTP_pos+=1;
}
printf("tutaj1\n");
strncpy(buf_temp,strstr(buf,"channel_add=")+sizeof(char)*12,sizeof(char)*(HTTP_pos-19));
printf("%s\n", buf_temp);
printf("tutaj2\n");
while(buf_temp[measure_pos]!=':')
{
measure_pos+=1;
}
strncpy(ChannelToAddMeasure,buf_temp,sizeof(char)*measure_pos);
printf("%s\n",ChannelToAddMeasure);
while(strcmp(channel_list[ChannelToAddMeasurePos].name,ChannelToAddMeasure)!=0)
{
ChannelToAddMeasurePos+=1;
if(ChannelToAddMeasurePos>10)
{
break;
}
}
if(ChannelToAddMeasurePos<10)
{
strcpy(ChannelToAddMeasure,buf_temp+measure_pos+1);
printf("%s\n", ChannelToAddMeasure);
liczba = strtol(ChannelToAddMeasure,NULL,10);
printf("liczba= %d\n", liczba-1);
strcpy(channel_list[ChannelToAddMeasurePos].data_str,ChannelToAddMeasure);
}
}
else if (buflen>=5 && buf[0]=='G' && buf[1]=='E' && buf[2]=='T' && buf[3]==' ' && buf[4]=='/' && buf[5]=='?' && sta_is_configured) {
int HTTP_pos=6;
int FemptyPos=0;
memset(buf_temp,0,sizeof(char)*80);
printf("tutaj\n");
while(buf[HTTP_pos] != 'H')
{
HTTP_pos+=1;
}
strncpy(buf_temp,strstr(buf,"channel_add=")+sizeof(char)*12,sizeof(char)*(HTTP_pos-19));
while(channel_list[FemptyPos].name[0] != 0 && strcmp(channel_list[FemptyPos].name,buf_temp) != 0)
{
FemptyPos+=1;
}
printf("slowo = %s\n", buf_temp);
printf("%d\n", FemptyPos);
strcpy(channel_list[FemptyPos].name ,buf_temp);
for(int k = 0;k<=FemptyPos;k++)
{
printf("%s\n",channel_list[k].name );
}
}
else if (buflen>=5 && buf[0]=='G' && buf[1]=='E' && buf[2]=='T' && buf[3]==' ' && buf[4]=='/' && buf[5]=='?' && !sta_is_configured) {
int and_pos=6;
printf("tutaj");
ssid = malloc(sizeof(char)*80);
pwd = malloc(sizeof(char)*80);
memset(ssid,0,sizeof(char)*80);
memset(pwd,0,sizeof(char)*80);
while(buf[and_pos] != '&')
{
and_pos+=1;
}
printf("tutaj1");
strncpy(ssid,strstr(buf,"ssid=")+sizeof(char)*5,sizeof(char)*(and_pos-11));
int HTTP_pos = 0;
while(buf[HTTP_pos] != 'H')
{
HTTP_pos+=1;
}
printf("tutaj2");
strncpy(pwd,strstr(buf,"pass=")+sizeof(char)*5,sizeof(char)*(HTTP_pos-(and_pos+7)));
printf("ssid= %s\n", ssid);
printf("haslo= %s\n",pwd );
free(ssid);
free(pwd);
sta_is_configured = true;
//initialise_wifi();
}
else
{
if(!sta_is_configured) {netconn_write(conn, http_index_hml_sta_config, sizeof(http_index_hml_sta_config)-1, NETCONN_NOCOPY);}
else {netconn_write(conn, http_index_hml_tmp, sizeof(http_index_hml_tmp)-1, NETCONN_NOCOPY);}
}
}
printf("Przed close\n");
err_t err1;
// Close the connection (server closes in HTTP)
err1 = netconn_close(conn);
printf("Po close, err = %d\n",err1);
err1 = netconn_delete(conn);
printf("Po delete, err = %d\n",err1);
/* Delete the buffer (netconn_recv gives us ownership,
so we have to make sure to deallocate the buffer) */
//free(inbuf);
//netbuf_free(inbuf);
netbuf_delete(inbuf);
free(buf_temp);
free(ChannelToAddMeasure);
printf("%d\n", esp_get_free_heap_size());
if (taskSemaphore != NULL && xSemaphoreTake(taskSemaphore, 100 / portTICK_PERIOD_MS) == pdTRUE) // oczekiwanie 1s
{
printf("NUM====%d\n", num);
num=num-1;
xSemaphoreGive(taskSemaphore);
}
vTaskDelete(NULL);
}
static void http_server(void *pvParameters)
{
struct netconn *conn;
taskSemaphore = xSemaphoreCreateMutex();
err_t err;
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, NULL, 80);
netconn_listen(conn);
do {
struct netconn *newconn;
err = netconn_accept(conn,&newconn);
if (err == ERR_OK) {
if (taskSemaphore != NULL && xSemaphoreTake(taskSemaphore, 100 / portTICK_PERIOD_MS) == pdTRUE) // oczekiwanie 1s
{
printf("haslko\n");
newconn->recv_timeout=10;
conn_array[num] = *newconn;
xTaskCreate(&http_server_netconn_serve,"http_server_netconn_serve",4096,&conn_array[num],5,NULL);
num=num+1;
xSemaphoreGive(taskSemaphore);
}
}
//free(newconn);
fflush(stdout);
printf("newconn %d\n",sizeof(newconn));
printf("struct %d\n",sizeof(struct netconn*) );
} while(err == ERR_OK);
netconn_close(conn);
netconn_delete(conn);
vTaskDelete(NULL);
}
int app_main(void)
{
nvs_flash_init();
esp_wifi_restore();
initialise_wifi();
xTaskCreate(&http_server, "http_server", 4096, NULL, 5, NULL);
return 0;
}
Thanks in advance