| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789 |
- #include "ESP32_WROOM_32D.h"
- #include <stdlib.h>
- #include <stdarg.h>
- extern int Flag3S;
- #define g_uMsgCmdFrameLen (6)
- extern uint8_t Devicenum;
- extern uint8_t g_wifi_rx_buf[WIFI_RX_BUF_SIZE];
- extern volatile uint32_t g_wifi_rx_last;
- extern volatile uint8_t g_wifi_rx_fault;
- extern volatile uint32_t g_wifi_rx_head;
- uint8_t wifi_tx_buf[WIFI_TX_BUF_SIZE];
- uint16_t wifi_tx_len;
- static int wifi_state = 0; //WiFi模块当前状态
- static int wifi_ack_delay = 0; //WiFi应答等待
- static int wifi_set_ssid = 0; //WiFi应答SSID设置
- uint32_t unlink_time = 0;
- extern uint32_t pc_link_timeout;
- char TCP_IP_PORT[8] = {"8001"};
- char MAC_ADDR[20] = {0};
- uint32_t broadDevFlag = 0;
- extern uint8_t pc_channel_recv;
- /* TX and AT transactions share one UART; only the initial CIPSEND may enter
- * WAIT_PROMPT. An uncertain timeout never sends another AT into data mode. */
- enum { TX_IDLE, TX_WAIT_PROMPT, TX_WAIT_RESULT, TX_FAULT };
- static unsigned tx_phase;
- static uint32_t at_started, tx_started;
- static uint32_t retry_started;
- static int retry_wait;
- static int at_pending, at_owner, at_retries;
- static int deferred_close, ap_found, link_is_tcp;
- static unsigned rx_line_len, rx_ipd_left, rx_ipd_accept, rx_frame_len;
- static uint32_t rx_last_byte;
- static char rx_line[256];
- static uint8_t rx_frame[CMD_BUF_SIZE + 9];
- static volatile uint8_t prov_request;
- static uint8_t prov_active, prov_step, prov_link, prov_bad, prov_ready;
- static uint32_t prov_started;
- static char prov_json[256];
- static unsigned prov_len;
- static void wifi_provision_process(void);
- static int wifi_provision_line(const char *line);
- static void wifi_provision_byte(uint8_t byte);
- static void wifi_line(const char *line);
- static void wifi_fault(const char *why);
- static void wifi_rx_reset(void)
- {
- rx_line_len = rx_ipd_left = rx_ipd_accept = rx_frame_len = 0;
- }
- static void wifi_enter(int state)
- {
- wifi_state = state;
- at_pending = 0;
- wifi_ack_delay = 0;
- at_retries = 0;
- retry_wait = 0;
- if (state != WIFI_TRANS) broadDevFlag = 0;
- }
- static void wifi_fault(const char *why)
- {
- if (tx_phase == TX_FAULT) return;
- Van_Device_Printf(VAN_LOG_WIFI, "\nWiFi uncertain UART phase: %s; reset ESP to recover\n", why);
- tx_phase = TX_FAULT;
- at_pending = 0;
- wifi_ack_delay = 0;
- wifi_tx_len = 0;
- broadDevFlag = 0;
- wifi_rx_reset();
- }
- uint16_t WriteComm2(char *data, uint16_t len)
- {
- return (uint16_t)HAL_UART_Transmit((UART_HandleTypeDef *)sysinf.ESPUart,
- (const uint8_t *)data, len, 1000);
- }
- void ESP32_Send_AT_Cmd(char *cmd, uint32_t time)
- {
- char buff[256];
- int n;
- if (tx_phase != TX_IDLE || at_pending) return;
- n = my_sprintf(buff, sizeof(buff), "%s\r\n", cmd);
- if (n < 0 || (unsigned)n >= sizeof(buff)) {
- Van_Device_Printf(VAN_LOG_WIFI, "\nAT command too long\n");
- return;
- }
- at_started = HAL_GetTick();
- wifi_ack_delay = time;
- at_owner = wifi_state;
- at_pending = 1;
- if (strncmp(cmd, "AT+CWJAP=", 9) && strncmp(cmd, "AT+CWSAP=", 9))
- Van_Device_Printf(VAN_LOG_WIFI, "\nW--> %s", buff);
- if (WriteComm2(buff, (uint16_t)n) != HAL_OK) wifi_fault("AT UART write");
- }
- void ESP32_AT(void)
- {
- ESP32_Send_AT_Cmd("AT",5000);
- }
- /*恢复出厂设置*/
- void ESP32_AT_Restore(void)
- {
- ESP32_Send_AT_Cmd("AT+RESTORE",500);
- }
- /*复位*/
- void ESP32_AT_RST(void)
- {
- ESP32_Send_AT_Cmd("AT+RST",8000);
- }
- /*上电自动连接AP*/
- void ESP32_AT_AUTOCONN(void)
- {
- ESP32_Send_AT_Cmd("AT+CWAUTOCONN=0",5000);
- }
- /*WIFI AP/STA/AP+STA模式选择*/
- void ESP32_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode)
- {
- switch ( enumMode )
- {
- case STA:
- ESP32_Send_AT_Cmd ( "AT+CWMODE=1", 5000 );
- break;
- case AP:
- ESP32_Send_AT_Cmd ( "AT+CWMODE=2", 5000 );
- break;
- case STA_AP:
- ESP32_Send_AT_Cmd ( "AT+CWMODE=3", 5000 );
- break;
- default:
- break;
- }
- }
- /*WIFI加入AP*/
- void ESP32_JoinAP( char * pSSID, char * pPassWord, char * pMacAddr)
- {
- char cCmd [192];
- my_sprintf ( cCmd, sizeof(cCmd), "AT+CWJAP=\"%s\",\"%s\",\"%s\"", pSSID, pPassWord,pMacAddr);
- ESP32_Send_AT_Cmd( cCmd,5000 );
- }
- /*WIFI建立AP*/
- void ESP32_SetupAP( char * pSSID, char * pPassWord)
- {
- char cCmd [192];
- my_sprintf ( cCmd,sizeof(cCmd), "AT+CWSAP=\"%s\",\"%s\"", pSSID, pPassWord );
- ESP32_Send_AT_Cmd( cCmd, 5000 );
- }
- /*WIFI查询IP*/
- void ESP32_GetIp(void)
- {
- ESP32_Send_AT_Cmd( "AT+CIPSTA?", 5000 );
- }
- /*WIFI禁止自动连接*/
- void ESP32_DisAutoLink(void)
- {
- ESP32_Send_AT_Cmd( "AT+CWAUTOCONN=0", 5000 );
- }
- void ESP32_CWLAP(char * pSSID)
- {
- char cCmd [80];
- my_sprintf ( cCmd, sizeof(cCmd), "AT+CWLAP=\"%s\"", pSSID);
- ESP32_Send_AT_Cmd( cCmd, 5000 );
- }
- /*WIFI关闭回显*/
- void ESP32_EchoOff(void)
- {
- ESP32_Send_AT_Cmd( "ATE0", 5000 );
- }
- /*WIFI初始化*/
- void ESP32_Init(void)
- {
- ESP32_Send_AT_Cmd( "+++", 5000 );
- }
- /*WIFI 单/多连接*/
- void ESP32_Enable_MultipleId (uint8_t enumEnUnvarnishTx )
- {
- char cCmd [20];
- my_sprintf ( cCmd, sizeof(cCmd), "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );
- ESP32_Send_AT_Cmd ( cCmd, 5000 );
- }
- /*WIFI AP作为服务端开启或关闭,1---开启服务:0---关闭服务*/
- void ESP32_AP_Server (uint8_t open)
- {
- char cCmd [192];
- my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPSERVER=%d", open);
- ESP32_Send_AT_Cmd( cCmd, 5000 );
- }
- /*WIFI STA选择TCP或UDP协议*/
- void ESP32_Link_Server(ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
- {
- char cStr [100] = { 0 }, cCmd [128];
- switch ( enumE )
- {
- case enumTCP:
- my_sprintf ( cStr, sizeof(cStr), "\"%s\",\"%s\",%s,6", "TCP", ip, ComNum );
- break;
- case enumUDP:
- my_sprintf ( cStr,sizeof(cStr), "\"%s\",\"%s\",%s,9090,0", "UDP", ip, ComNum );
- break;
- default:
- break;
- }
- if ( id < 5 )
- my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPSTART=%d,%s", id, cStr);
- else
- my_sprintf ( cCmd, sizeof(cCmd), "AT+CIPSTART=%s", cStr );
- ESP32_Send_AT_Cmd ( cCmd,5000 );
- }
- /*WIFI透传*/
- void ESP32_UnvarnishSend ( void )
- {
- ESP32_Send_AT_Cmd( "AT+CIPMODE=1", 5000 );//设置透传模式
- }
- /*WIFI停止TCP*/
- void ESP32_STOPTCP ( ENUM_ID_NO_TypeDef id )
- {
- char cCmd [60];
- my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPCLOSE=%d", id);
- ESP32_Send_AT_Cmd ( cCmd, 20000 );
- }
- /*退出透传*/
- void ESP32_ExitUnvarnishSend( void )
- {
- ESP32_Send_AT_Cmd("+++", 5000);
- }
- ///*设置默认波特率为460800*/
- //void ESP32_SET_BUAR(void)
- //{
- // ESP32_Send_AT_Cmd("AT+UART_DEF=460800,8,1,0,0","OK",NULL,500);
- //}
- int WIFI_ReSend(void)
- {
- char cmd[40];
- if (!wifi_tx_len) return 0;
- if ((!prov_active && wifi_state != WIFI_TRANS) || tx_phase == TX_FAULT) return -1;
- if (tx_phase != TX_IDLE || at_pending) return -2;
- if (wifi_tx_len > WIFI_TX_BUF_SIZE) return -3;
- my_sprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d,%d", prov_active ? prov_link : 0, wifi_tx_len);
- ESP32_Send_AT_Cmd(cmd, 3000);
- if (tx_phase == TX_FAULT) return -4;
- at_pending = 0;
- tx_phase = TX_WAIT_PROMPT;
- tx_started = HAL_GetTick();
- return 0;
- }
- int WIFI_Send_Data(uint8_t *data, uint16_t len, uint8_t flag)
- {
- int ret;
- if (prov_active || wifi_state != WIFI_TRANS || tx_phase != TX_IDLE || at_pending) return -1;
- if (wifi_tx_len) return -2;
- if (!data || !len || len > WIFI_TX_BUF_SIZE) return -3;
- memcpy(wifi_tx_buf, data, len);
- wifi_tx_len = len;
- if (!flag) return 0;
- ret = WIFI_ReSend();
- return ret < 0 ? ret : len;
- }
- int WIFI_Send_MSG(uint8_t *head, uint8_t *data, uint8_t *crc, uint16_t len)
- {
- int ret;
- if (prov_active || wifi_state != WIFI_TRANS || tx_phase != TX_IDLE || at_pending || wifi_tx_len) return -1;
- if (!head || !crc || (!data && len) || len > WIFI_TX_BUF_SIZE - 8) return -2;
- memcpy(wifi_tx_buf, head, 6);
- if (len) memcpy(wifi_tx_buf + 6, data, len);
- memcpy(wifi_tx_buf + 6 + len, crc, 2);
- wifi_tx_len = len + 8;
- ret = WIFI_ReSend();
- return ret < 0 ? ret : len + 8;
- }
- int WIFI_SendIlde(void)
- {
- return !prov_active && wifi_state == WIFI_TRANS && tx_phase == TX_IDLE && !at_pending && wifi_tx_len == 0;
- }
- void WIFI_set_ssid(void)
- {
- wifi_set_ssid = 1;
- deferred_close = 1;
- }
- void WIFI_set_CloseConnect(void)
- {
- deferred_close = 1;
- }
- /* Retained helper, with a valid-range bound at every candidate position. */
- char *find_str_loop(void *src, int size, volatile uint32_t *start, uint32_t end, char *str)
- {
- unsigned offset, length, valid, i, pos;
- uint8_t *b = src;
- if (!src || !start || !str || size <= 0 || *start >= (unsigned)size || end >= (unsigned)size) return NULL;
- length = strlen(str);
- valid = (end + size - *start) % size;
- for (offset = 0; offset + length <= valid; ++offset) {
- pos = (*start + offset) % size;
- for (i = 0; i < length && b[(pos + i) % size] == (uint8_t)str[i]; ++i) {}
- if (i == length) {
- *start = (pos + length) % size;
- return (char *)(b + pos);
- }
- }
- return NULL;
- }
- /* Only a complete, bounded frame is passed to the project's DecodeNew.
- * A private linear window avoids its empty-ring ambiguity and preserves the
- * hardware RX cursor. DecodeNew owns checksum and protocol decoding. */
- static void wifi_frame_byte(uint8_t byte)
- {
- unsigned length, total, cursor;
- uint8_t payload[CMD_BUF_SIZE + 1];
- CmdMessage message;
- rx_frame[rx_frame_len++] = byte;
- while (rx_frame_len) {
- if (rx_frame[0] != 0xaa || (rx_frame_len > 1 && rx_frame[1] != 0x55)) goto discard;
- if (rx_frame_len < 6) return;
- length = rx_frame[4] | ((unsigned)rx_frame[5] << 8);
- if (length > CMD_BUF_SIZE) goto discard;
- total = length + 8;
- if (rx_frame_len < total) return;
- cursor = 0;
- memset(&message, 0, sizeof(message));
- if (DecodeNew(&message, payload, rx_frame, &cursor, total, sizeof(rx_frame)) <= 0) goto discard;
- payload[length] = 0;
- message.data = (char *)payload;
- /* Consume before dispatch: callbacks may request a close or enqueue TX. */
- rx_frame_len -= total;
- memmove(rx_frame, rx_frame + total, rx_frame_len);
- if (message.cmd == PC_CMD_SETIP && length >= 5 && memcmp(payload, "Mini7", 5) == 0) continue;
- sysinf.pc_channel_recv = PC_CONNECT_TYPE_WIFI;
- sysinf.pc_link_timeout = 0;
- Van_Device_Printf(VAN_LOG_WIFI, "\nWiFi RX cmd=%d len=%d", message.cmd, length);
- #ifdef ONECHIP_MINI_ONE
- if (message.cmd == UINON_CMD_THEROM_GET && length == 4) deal_mUnion_cmd(&message);
- else
- #endif
- query_pc_cmd(&message);
- continue;
- discard:
- --rx_frame_len;
- memmove(rx_frame, rx_frame + 1, rx_frame_len);
- }
- }
- static void wifi_rx_byte(uint8_t byte)
- {
- char *end, *begin;
- unsigned long id, length;
- if (rx_ipd_left) {
- --rx_ipd_left;
- if (rx_ipd_accept && tx_phase != TX_FAULT) {
- if (prov_active) wifi_provision_byte(byte);
- else wifi_frame_byte(byte);
- }
- return;
- }
- if (!rx_line_len && byte == '>') {
- wifi_line(">");
- return;
- }
- if (!rx_line_len && (byte == '\r' || byte == '\n' || byte == ' ')) return;
- if (rx_line_len == sizeof(rx_line) - 1) {
- wifi_fault("AT line overflow");
- return;
- }
- rx_line[rx_line_len++] = byte;
- rx_line[rx_line_len] = 0;
- if (byte == ':' && strncmp(rx_line, "+IPD,", 5) == 0) {
- begin = rx_line + 5;
- id = strtoul(begin, &end, 10);
- if (*begin < '0' || *begin > '9' || end == begin || *end != ',' || id > 4) goto malformed;
- begin = end + 1;
- length = strtoul(begin, &end, 10);
- if (*begin < '0' || *begin > '9' || end == begin || *end != ':' || end[1] || length > 65535) goto malformed;
- rx_ipd_left = length;
- rx_ipd_accept = (id == 0);
- if (prov_active) {
- rx_ipd_accept = (prov_step == 10 && id <= 4 && (!prov_len || prov_link == id));
- if (rx_ipd_accept) prov_link = (uint8_t)id;
- }
- rx_line_len = 0;
- return;
- }
- if (byte == '\n') {
- while (rx_line_len && (rx_line[rx_line_len - 1] == '\r' || rx_line[rx_line_len - 1] == '\n'))
- rx_line[--rx_line_len] = 0;
- wifi_line(rx_line);
- rx_line_len = 0;
- }
- return;
- malformed:
- wifi_fault("invalid +IPD header");
- }
- static void wifi_online(void)
- {
- wifi_enter(WIFI_TRANS);
- broadDevFlag = 1;
- sysinf.s10_flag = 1;
- }
- static void wifi_line(const char *line)
- {
- const char *p, *q;
- if (prov_active && wifi_provision_line(line)) return;
- if (at_pending && (!strcmp(line, "ERROR") || !strcmp(line, "FAIL")))
- Van_Device_Printf(VAN_LOG_WIFI, "\nWiFi AT state=%d reply=%s\n", wifi_state, line);
- if (strcmp(line, "ready") == 0) {
- tx_phase = TX_IDLE;
- wifi_tx_len = 0;
- wifi_rx_reset();
- wifi_enter(WIFI_POWERON);
- return;
- }
- if (tx_phase == TX_FAULT) return;
- if (strcmp(line, ">") == 0) {
- if (tx_phase != TX_WAIT_PROMPT) {
- Van_Device_Printf(VAN_LOG_WIFI, "\nWiFi unexpected prompt ignored\n");
- return;
- }
- tx_phase = TX_WAIT_RESULT;
- tx_started = HAL_GetTick();
- wifi_ack_delay = 7000; /* TCP SO_SNDTIMEO=6000 plus MCU margin. */
- if (WriteComm2((char *)wifi_tx_buf, wifi_tx_len) != HAL_OK) wifi_fault("payload UART write");
- return;
- }
- if (!strcmp(line, "SEND OK") || !strcmp(line, "SEND FAIL")) {
- if (tx_phase == TX_WAIT_RESULT) {
- Van_Device_Printf(VAN_LOG_WIFI, "\nW<-- %s\n", line);
- tx_phase = TX_IDLE;
- wifi_tx_len = 0;
- wifi_ack_delay = 0;
- }
- return;
- }
- /* CWJAP can disconnect the old association before joining the requested AP.
- * Wait for its final OK/FAIL instead of resetting an in-progress join. */
- if (!strcmp(line, "WIFI DISCONNECT") && wifi_state == WIFI_LINK_AP && at_pending)
- return;
- if (!strcmp(line, "0,CLOSED") || !strcmp(line, "CLOSED") || !strcmp(line, "WIFI DISCONNECT")) {
- if (tx_phase == TX_WAIT_PROMPT) {
- wifi_fault("closed before prompt");
- return;
- }
- tx_phase = TX_IDLE;
- wifi_tx_len = 0;
- rx_frame_len = 0;
- wifi_enter(!strcmp(line, "WIFI DISCONNECT") ? WIFI_POWEROFF : WIFI_LISTEN);
- return;
- }
- if (wifi_state == WIFI_CWLAP && strncmp(line, "+CWLAP:", 7) == 0) {
- /* Quoted strings are SSID and BSSID; RSSI between them is numeric. */
- p = strchr(line, '"');
- if (!p) return;
- q = strchr(p + 1, '"');
- if (!q) return;
- if ((unsigned)(q - p - 1) != strlen(sysinf.wifiname) ||
- memcmp(p + 1, sysinf.wifiname, q - p - 1)) return;
- p = strchr(q + 1, '"');
- if (!p) return;
- q = strchr(p + 1, '"');
- if (!q || q - p - 1 != 17) return;
- memcpy(MAC_ADDR, p + 1, 17);
- MAC_ADDR[17] = 0;
- ap_found = 1;
- return;
- }
- if (!strcmp(line, "ERROR") || !strcmp(line, "FAIL")) {
- if (tx_phase == TX_WAIT_PROMPT) {
- /* Explicit rejection: ESP did not enter data mode. Upper layer retries. */
- tx_phase = TX_IDLE;
- wifi_tx_len = 0;
- wifi_ack_delay = 0;
- } else if (tx_phase == TX_WAIT_RESULT) {
- wifi_fault("ERROR during payload transaction");
- } else if (at_pending) {
- at_pending = 0;
- wifi_ack_delay = 0;
- if (wifi_state == WIFI_TCPOPT) wifi_enter(WIFI_CLOSE);
- retry_wait = 1; retry_started = HAL_GetTick();
- }
- return;
- }
- if (strcmp(line, "OK") || !at_pending || at_owner != wifi_state) return;
- at_pending = 0;
- wifi_ack_delay = 0;
- switch (wifi_state) {
- case WIFI_POWEROFF: /* AT+RST's OK is not the boot-ready notification. */
- case WIFI_ERROR:
- at_pending = 1; at_started = HAL_GetTick(); wifi_ack_delay = 8000; break;
- case WIFI_POWERON: wifi_enter(WIFI_INIT); break;
- case WIFI_INIT: wifi_enter(WIFI_STATION); break;
- case WIFI_STATION: wifi_enter(WIFI_CWLAP); break;
- case WIFI_CWLAP:
- if (ap_found) wifi_enter(WIFI_DISAUTO);
- else {
- Van_Device_Printf(VAN_LOG_WIFI, "\nWiFi scan completed: configured SSID not found\n");
- retry_wait = 1; retry_started = HAL_GetTick();
- }
- break;
- case WIFI_DISAUTO: wifi_enter(WIFI_LINK_AP); break;
- case WIFI_LINK_AP: wifi_enter(WIFI_GET_IP); break;
- case WIFI_GET_IP:
- if (wifi_set_ssid) {
- char result = 1;
- wifi_set_ssid = 0;
- data_send_to_pc(PC_CMD_SETWIFI, &result, 1);
- }
- wifi_enter(WIFI_SETMUX); break;
- case WIFI_SETMUX: wifi_enter(WIFI_IPDINFO); break;
- case WIFI_IPDINFO: wifi_enter(WIFI_LISTEN); break;
- case WIFI_LISTEN:
- if (link_is_tcp) wifi_enter(WIFI_TCPOPT);
- else wifi_online();
- break;
- case WIFI_TCPOPT: wifi_online(); break;
- case WIFI_CLOSE:
- rx_frame_len = 0;
- wifi_enter(wifi_set_ssid ? WIFI_POWEROFF : WIFI_LISTEN);
- break;
- default: break;
- }
- }
- void WIFI_recv_deal(void)
- {
- unsigned budget = WIFI_RX_BUF_SIZE;
- if (g_wifi_rx_fault) {
- uint8_t cause = g_wifi_rx_fault;
- g_wifi_rx_fault = 0;
- g_wifi_rx_head = g_wifi_rx_last;
- wifi_fault((cause & 2) ? "UART hardware overrun" : "RX ring full");
- }
- while (budget-- && g_wifi_rx_head != g_wifi_rx_last) {
- uint8_t byte = g_wifi_rx_buf[g_wifi_rx_head];
- g_wifi_rx_head = (g_wifi_rx_head + 1) % WIFI_RX_BUF_SIZE;
- rx_last_byte = HAL_GetTick();
- wifi_rx_byte(byte);
- }
- if (rx_ipd_left && (uint32_t)(HAL_GetTick() - rx_last_byte) >= 3000)
- wifi_fault("incomplete +IPD");
- }
- void WIFI_send_deal(void)
- {
- uint32_t now = HAL_GetTick();
- if (tx_phase == TX_FAULT) return;
- if (retry_wait) {
- if ((uint32_t)(now - retry_started) < 2000u) return;
- retry_wait = 0;
- }
- if (tx_phase != TX_IDLE) {
- if ((uint32_t)(now - tx_started) >= (tx_phase == TX_WAIT_PROMPT ? 3000u : 7000u))
- wifi_fault(tx_phase == TX_WAIT_PROMPT ? "prompt timeout" : "SEND result timeout");
- return;
- }
- if (at_pending) {
- if ((uint32_t)(now - at_started) < (uint32_t)wifi_ack_delay) return;
- at_pending = 0;
- wifi_ack_delay = 0;
- Van_Device_Printf(VAN_LOG_WIFI, "\nAT timeout state=%d\n", wifi_state);
- }
- if (deferred_close) {
- deferred_close = 0;
- wifi_tx_len = 0;
- wifi_enter(wifi_set_ssid ? WIFI_POWEROFF : WIFI_CLOSE);
- }
- if (wifi_state == WIFI_TRANS) {
- if (wifi_tx_len) WIFI_ReSend();
- return;
- }
- if (++at_retries > MAX_RESEND_TIME) {
- if (wifi_set_ssid) {
- char result = (wifi_state == WIFI_CWLAP) ? 0xff : 0xfe;
- wifi_set_ssid = 0;
- data_send_to_pc(PC_CMD_SETWIFI, &result, 1);
- }
- wifi_enter(WIFI_POWEROFF);
- }
- switch (wifi_state) {
- case WIFI_POWEROFF:
- case WIFI_ERROR: ESP32_AT_RST(); break;
- case WIFI_POWERON: ESP32_AT(); break;
- case WIFI_INIT: ESP32_EchoOff(); break;
- case WIFI_STATION: ESP32_Net_Mode_Choose(STA); break;
- case WIFI_CWLAP: ap_found = 0; ESP32_CWLAP(sysinf.wifiname); break;
- case WIFI_DISAUTO: ESP32_DisAutoLink(); break;
- case WIFI_LINK_AP: ESP32_JoinAP(sysinf.wifiname, sysinf.password, MAC_ADDR); break;
- case WIFI_GET_IP: ESP32_GetIp(); break;
- case WIFI_SETMUX: ESP32_Enable_MultipleId(1); break;
- case WIFI_IPDINFO: ESP32_Send_AT_Cmd("AT+CIPDINFO=0", 3000); break;
- case WIFI_LISTEN:
- rx_frame_len = 0;
- link_is_tcp = sysinf.connectTcpFlag != 0;
- if (link_is_tcp) ESP32_Link_Server(enumTCP, sysinf.TCP_IP_Addr, sysinf.TCP_IP_PORT, Multiple_ID_0);
- else ESP32_Link_Server(enumUDP, User_ESP32_UDPServer_IP, User_ESP32_UDPServer_PORT, Multiple_ID_0);
- break;
- case WIFI_TCPOPT: ESP32_Send_AT_Cmd("AT+CIPTCPOPT=0,,,6000", 3000); break;
- case WIFI_CLOSE: ESP32_STOPTCP(Multiple_ID_0); break;
- default: wifi_enter(WIFI_POWEROFF); break;
- }
- }
- void WIFI_process(void)
- {
- WIFI_recv_deal();
- if (prov_request && !prov_active && tx_phase == TX_IDLE && !at_pending) {
- prov_request = 0; prov_active = 1; prov_step = 0;
- prov_len = prov_bad = prov_ready = 0;
- wifi_tx_len = 0; wifi_rx_reset(); wifi_enter(WIFI_POWEROFF);
- Van_Device_Printf(VAN_LOG_WIFI, "\nProvision start\n");
- }
- if (prov_active) wifi_provision_process();
- else WIFI_send_deal();
- }
- /* Keep the public formatter and make its length argument effective. */
- int my_sprintf(char *out, unsigned int size, const char *format, ...)
- {
- int n;
- va_list args;
- if (!out || !size || !format) return -1;
- va_start(args, format);
- n = vsnprintf(out, size, format, args);
- va_end(args);
- out[size - 1] = 0;
- return n;
- }
- static int wifi_prov_parse_json(const char *json, char *ssid, uint16_t ssidCap,
- char *pwd, uint16_t pwdCap)
- {
- cJSON *root = NULL;
- cJSON *it = NULL;
- int rlt = -1;
- if (json == NULL || json[0] != '{' || ssid == NULL || pwd == NULL)
- return -1;
- ssid[0] = '\0';
- pwd[0] = '\0';
- root = cJSON_Parse(json);
- if (root == NULL)
- return -1;
- it = cJSON_GetObjectItem(root, "ssid");
- if (it == NULL || !cJSON_IsString(it) || it->valuestring == NULL ||
- it->valuestring[0] == '\0')
- goto out; /* 必须包含非空ssid */
- if (strlen(it->valuestring) >= (size_t)ssidCap)
- goto out; /* ssid超长 */
- strcpy(ssid, it->valuestring);
- it = cJSON_GetObjectItem(root, "password");
- if (it != NULL && cJSON_IsString(it) && it->valuestring != NULL)
- {
- if (strlen(it->valuestring) >= (size_t)pwdCap)
- goto out; /* 密码超长 */
- strcpy(pwd, it->valuestring); /* 允许开放网络密码为空 */
- }
- rlt = 0;
- out:
- cJSON_Delete(root);
- return rlt;
- }
- /* SoftAP uses the same stream parser and CIPSEND transaction as STA. */
- uint8_t WIFI_provision_active(void) { return prov_active; }
- uint8_t WIFI_provision_request(void) {
- if (prov_active) return 0;
- prov_request = 1; return 1;
- }
- static void wifi_provision_byte(uint8_t byte) {
- if (prov_bad || prov_ready) return;
- if (prov_len >= sizeof(prov_json)-1) { prov_bad = 1; return; }
- if (byte == '\r' || byte == '\n') return;
- prov_json[prov_len++] = (char)byte;
- prov_json[prov_len] = 0;
- if (!rx_ipd_left && prov_len && prov_json[prov_len-1] == '}') prov_ready = 1;
- }
- static void wifi_provision_exit(void) {
- prov_active = 0; prov_step = 0; prov_len = 0;
- wifi_tx_len = 0; wifi_rx_reset(); wifi_enter(WIFI_POWEROFF);
- }
- static int wifi_provision_line(const char *line) {
- if (!strcmp(line, "ready")) {
- tx_phase = TX_IDLE; wifi_tx_len = 0; wifi_rx_reset();
- at_pending = 0; wifi_ack_delay = 0;
- prov_step = 1; prov_started = HAL_GetTick();
- return 1;
- }
- if (tx_phase != TX_IDLE) return 0; /* shared prompt/result handling */
- if (at_pending && !strcmp(line, "OK")) {
- if (prov_step == 0) return 1; /* reset must finish with ready */
- at_pending = 0; wifi_ack_delay = 0; ++prov_step;
- prov_started = HAL_GetTick(); return 1;
- }
- if (at_pending && (!strcmp(line, "ERROR") || !strcmp(line, "FAIL"))) {
- Van_Device_Printf(VAN_LOG_WIFI, "\nProvision command rejected step=%d\n", prov_step);
- wifi_provision_exit(); return 1;
- }
- return 1;
- }
- static void wifi_provision_process(void) {
- char cmd[160];
- uint32_t now = HAL_GetTick();
- if (tx_phase == TX_FAULT) return;
- if (tx_phase != TX_IDLE) {
- if ((uint32_t)(now-tx_started) >= (tx_phase == TX_WAIT_PROMPT ? 3000u : 7000u))
- wifi_fault("provision send timeout");
- return;
- }
- if (at_pending) {
- if ((uint32_t)(now-at_started) >= (uint32_t)wifi_ack_delay) {
- Van_Device_Printf(VAN_LOG_WIFI, "\nProvision command timeout step=%d\n", prov_step);
- wifi_provision_exit();
- }
- return;
- }
- switch (prov_step) {
- case 0: ESP32_Send_AT_Cmd("AT+RST",10000); break;
- case 1: ESP32_Send_AT_Cmd("ATE0",5000); break;
- case 2: ESP32_Send_AT_Cmd("AT+CWMODE=2",5000); break;
- case 3:
- my_sprintf(cmd,sizeof(cmd),"AT+CWSAP=\"%s\",\"%s\",6,3","OneChip_Mini7","test1234");
- ESP32_Send_AT_Cmd(cmd,5000); break;
- case 4: ESP32_Send_AT_Cmd("AT+CIPAP?",5000); break;
- case 5: ESP32_Send_AT_Cmd("AT+CWDHCP?",5000); break;
- case 6: ESP32_Send_AT_Cmd("AT+CIPMUX=1",5000); break;
- case 7: ESP32_Send_AT_Cmd("AT+CIPDINFO=0",5000); break;
- case 8: ESP32_Send_AT_Cmd("AT+CIPSERVER=1,8002",5000); break;
- case 9: prov_step=10; prov_started=now; break;
- case 10:
- if ((uint32_t)(now-prov_started)>=300000u) { wifi_provision_exit(); break; }
- if (prov_bad && !rx_ipd_left) {
- prov_len=prov_bad=prov_ready=0; break;
- }
- if (prov_ready && !rx_ipd_left) {
- char ssid[sizeof(sysinf.wifiname)], pwd[sizeof(sysinf.password)];
- int valid = wifi_prov_parse_json(prov_json,ssid,sizeof(ssid),pwd,sizeof(pwd)) == 0;
- if (valid) {
- strcpy(sysinf.wifiname,ssid); strcpy(sysinf.password,pwd);
- valid = cfg_save_cfg_param() != 0;
- }
- if (valid)
- my_sprintf((char *)wifi_tx_buf,sizeof(wifi_tx_buf),
- "{\"v\":1,\"status\":\"accepted\",\"sn\":\"%.7s\"}\r\n", sysinf.SN);
- else
- my_sprintf((char *)wifi_tx_buf,sizeof(wifi_tx_buf),
- "{\"v\":1,\"status\":\"rejected\",\"reason\":\"invalid\"}\r\n");
- wifi_tx_len = (uint16_t)strlen((char *)wifi_tx_buf);
- WIFI_ReSend(); prov_step = valid ? 11 : 12;
- }
- break;
- case 11: wifi_provision_exit(); break;
- case 12: prov_len=prov_bad=prov_ready=0; prov_step=10; prov_started=now; break;
- default: wifi_provision_exit(); break;
- }
- }
|