244 lines
5.3 KiB
C
244 lines
5.3 KiB
C
|
|
#include "main.h"
|
||
|
|
|
||
|
|
|
||
|
|
#include "esp_at.h"
|
||
|
|
#include "wifi_portal.h"
|
||
|
|
#include <string.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
|
||
|
|
#define ESP_RX_BUF_SIZE 1024
|
||
|
|
|
||
|
|
static char esp_rx_buf[ESP_RX_BUF_SIZE];
|
||
|
|
static volatile uint16_t esp_rx_idx = 0;
|
||
|
|
|
||
|
|
|
||
|
|
extern UART_HandleTypeDef huart1; // ESP
|
||
|
|
extern UART_HandleTypeDef huart3; // DEBUG
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
static void dbg(const char *s)
|
||
|
|
{
|
||
|
|
HAL_UART_Transmit(&huart3, (uint8_t *)s, strlen(s), HAL_MAX_DELAY);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
void ESP_RxByte(uint8_t byte)
|
||
|
|
{
|
||
|
|
if (esp_rx_idx < ESP_RX_BUF_SIZE - 1)
|
||
|
|
{
|
||
|
|
esp_rx_buf[esp_rx_idx++] = byte;
|
||
|
|
esp_rx_buf[esp_rx_idx] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
char* ESP_GetBuffer(void)
|
||
|
|
{
|
||
|
|
return esp_rx_buf;
|
||
|
|
}
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
void ESP_ClearBuffer(void)
|
||
|
|
{
|
||
|
|
esp_rx_idx = 0;
|
||
|
|
esp_rx_buf[0] = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
static bool ESP_WaitFor(const char *expect, uint32_t timeout)
|
||
|
|
{
|
||
|
|
uint32_t start = HAL_GetTick();
|
||
|
|
|
||
|
|
while ((HAL_GetTick() - start) < timeout)
|
||
|
|
{
|
||
|
|
if (strstr(esp_rx_buf, expect))
|
||
|
|
return true;
|
||
|
|
|
||
|
|
if (strstr(esp_rx_buf, "ERROR"))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
if (strstr(esp_rx_buf, "busy"))
|
||
|
|
{
|
||
|
|
HAL_Delay(100); // 🔥 ESP ocupado → espera
|
||
|
|
ESP_ClearBuffer();
|
||
|
|
start = HAL_GetTick();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
bool ESP_SendCmd(const char *cmd, const char *expect, uint32_t timeout)
|
||
|
|
{
|
||
|
|
ESP_ClearBuffer();
|
||
|
|
|
||
|
|
HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY);
|
||
|
|
HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY);
|
||
|
|
|
||
|
|
dbg(">> ");
|
||
|
|
dbg(cmd);
|
||
|
|
dbg("\r\n");
|
||
|
|
|
||
|
|
bool ok = ESP_WaitFor(expect, timeout);
|
||
|
|
|
||
|
|
dbg("<< ");
|
||
|
|
dbg(esp_rx_buf);
|
||
|
|
dbg("\r\n");
|
||
|
|
HAL_Delay(50); // 🔥 estabiliza ESP
|
||
|
|
return ok;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
bool ESP_EnableMultiConn(void)
|
||
|
|
{
|
||
|
|
return ESP_SendCmd("AT+CIPMUX=1", "OK", 3000);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool ESP_StartSoftAP(const char *ssid, const char *pass)
|
||
|
|
{
|
||
|
|
char cmd[160];
|
||
|
|
|
||
|
|
if (!ESP_SendCmd("AT+CWMODE=2", "OK", 3000))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
snprintf(cmd, sizeof(cmd),
|
||
|
|
"AT+CWSAP=\"%s\",\"%s\",1,3,4",
|
||
|
|
ssid, pass);
|
||
|
|
|
||
|
|
return ESP_SendCmd(cmd, "OK", 5000);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool ESP_StartServer(uint16_t port)
|
||
|
|
{
|
||
|
|
char cmd[64];
|
||
|
|
snprintf(cmd, sizeof(cmd), "AT+CIPSERVER=1,%u", port);
|
||
|
|
return ESP_SendCmd(cmd, "OK", 5000);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
bool ESP_SendLinkData(int link_id, const char *data)
|
||
|
|
{
|
||
|
|
char cmd[64];
|
||
|
|
size_t len = strlen(data);
|
||
|
|
|
||
|
|
ESP_ClearBuffer();
|
||
|
|
|
||
|
|
snprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d,%u", link_id, (unsigned)len);
|
||
|
|
|
||
|
|
HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY);
|
||
|
|
HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY);
|
||
|
|
|
||
|
|
if (!ESP_WaitFor(">", 3000))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
HAL_UART_Transmit(&huart1, (uint8_t *)data, len, HAL_MAX_DELAY);
|
||
|
|
|
||
|
|
return ESP_WaitFor("SEND OK", 5000);
|
||
|
|
}
|
||
|
|
|
||
|
|
int ESP_HasIPD(void)
|
||
|
|
{
|
||
|
|
if (strstr(ESP_GetBuffer(), "+IPD"))
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void ESP_SendData(const char *data)
|
||
|
|
{
|
||
|
|
HAL_UART_Transmit(&huart1, (uint8_t*)data, strlen(data), 1000);
|
||
|
|
}
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
bool ESP_CloseLink(int link_id)
|
||
|
|
{
|
||
|
|
char cmd[32];
|
||
|
|
snprintf(cmd, sizeof(cmd), "AT+CIPCLOSE=%d", link_id);
|
||
|
|
return ESP_SendCmd(cmd, "OK", 3000);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
|
||
|
|
void ESP_Init(void)
|
||
|
|
{
|
||
|
|
HAL_Delay(1000);
|
||
|
|
ESP_SendCmd("AT", "OK", 2000);
|
||
|
|
ESP_SendCmd("ATE0", "OK", 2000);
|
||
|
|
ESP_SendCmd("AT+CIPDINFO=1", "OK", 2000);
|
||
|
|
ESP_SendCmd("AT+CWMODE=2", "OK", 2000);
|
||
|
|
ESP_SendCmd("AT+CWSAP=\"STM32\",\"12345678\",1,3,4", "OK", 5000);
|
||
|
|
|
||
|
|
HAL_Delay(3000); // 🔥 importante
|
||
|
|
|
||
|
|
ESP_SendCmd("AT+CIPSERVER=0", "OK", 2000); // mata server se existir
|
||
|
|
// ESP_SendCmd("AT+CIPCLOSE=5", "OK", 2000); // fecha tudo (modo multi)
|
||
|
|
HAL_Delay(500);
|
||
|
|
|
||
|
|
|
||
|
|
if (!ESP_SendCmd("AT+CIPMUX=1", "OK", 3000))
|
||
|
|
dbg("CIPMUX FAIL\r\n");
|
||
|
|
|
||
|
|
if (!ESP_SendCmd("AT+CIPSERVER=1,80", "OK", 3000))
|
||
|
|
dbg("CIPSERVER FAIL\r\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
__attribute__((unused))
|
||
|
|
static int parse_ipd_link(const char *p)
|
||
|
|
{
|
||
|
|
int link = -1;
|
||
|
|
sscanf(p, "+IPD,%d,", &link);
|
||
|
|
return link;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*************************************************/
|
||
|
|
void ESP_Task(void)
|
||
|
|
{
|
||
|
|
char *p = strstr(ESP_GetBuffer(), "+IPD,");
|
||
|
|
if (p)
|
||
|
|
{
|
||
|
|
int link_id = -1;
|
||
|
|
int len = 0;
|
||
|
|
|
||
|
|
// extrair link_id e tamanho
|
||
|
|
sscanf(p, "+IPD,%d,%d:", &link_id, &len);
|
||
|
|
|
||
|
|
dbg("IPD DETECTADO\r\n");
|
||
|
|
|
||
|
|
// 🔥 esperar fim do pacote
|
||
|
|
HAL_Delay(50);
|
||
|
|
|
||
|
|
const char *resp =
|
||
|
|
"HTTP/1.1 200 OK\r\n"
|
||
|
|
"Content-Type: text/html\r\n"
|
||
|
|
"Connection: close\r\n"
|
||
|
|
"\r\n"
|
||
|
|
"<h1>PORTAL XUPA FUNCIONA</h1>";
|
||
|
|
|
||
|
|
char cmd[64];
|
||
|
|
|
||
|
|
snprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d,%d", link_id, strlen(resp));
|
||
|
|
|
||
|
|
if (ESP_SendCmd(cmd, ">", 2000))
|
||
|
|
{
|
||
|
|
ESP_SendData(resp);
|
||
|
|
ESP_WaitFor("SEND OK", 3000);
|
||
|
|
}
|
||
|
|
|
||
|
|
snprintf(cmd, sizeof(cmd), "AT+CIPCLOSE=%d", link_id);
|
||
|
|
ESP_SendCmd(cmd, "OK", 2000);
|
||
|
|
|
||
|
|
ESP_ClearBuffer(); // 🔥 só aqui
|
||
|
|
}
|
||
|
|
}
|