/********************************************************************************* * Copyright: (C) 2023 LingYun IoT System Studio. * All rights reserved. * * Filename: at-esp32.c * Description: This file is ESP32 AT command low level API functions * * Version: 1.0.0(11/08/23) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "11/08/23 16:18:43" * ********************************************************************************/ #include "logger.h" #include "at-esp32.h" /*+------------------------+ *| Baisc AT command | *+------------------------+*/ static inline int check_at_ready(comport_t *comport) { int times = 6; int ready = 0; while( times-- ) { if( 0 == send_atcmd_check_ok(comport, "AT", 500) ) { ready = 1; break; } } return ready; } /* AT command: AT+RST */ int esp32_reset(comport_t *comport) { int rv; rv = send_atcmd(comport, "AT+RST", 5000, "ready", AT_ERRSTR, NULL, 0); if( rv < 0) { log_error("send AT command to reset ESP32 failed, rv=%d\n", rv); return -1; } if( check_at_ready(comport) ) { log_info("send AT to reset ESP32 and AT command ready\n"); return 0; } else { log_info("send AT to reset ESP32 but AT command not ready\n"); return -3; } } /* AT command: AT+RESTORE */ int esp32_restore(comport_t *comport) { int rv; //rv = send_atcmd_check_ok(comport, "AT+RESTORE", 5000); rv = send_atcmd(comport, "AT+RESTORE", 5000, "ready", AT_ERRSTR, NULL, 0); if( rv < 0) { log_error("send AT command to restore ESP32 failed, rv=%d\n", rv); return -1; } if( check_at_ready(comport) ) { log_info("send AT command to resstore ESP32 ready\n"); return 0; } else { log_error("send AT command to restore ESP32 but AT not ready\n"); return -3; } } /* AT command: ATE1 or ATE0 */ int esp32_set_echo(comport_t *comport, int enable) { char *at = enable? "ATE1" : "ATE0"; return send_atcmd_check_ok(comport, at, 500); } /* AT command: AT+GMR */ int esp32_get_firmware(comport_t *comport, char *version, int size) { if( !version || size<=0 ) return -1; return send_atcmd_check_value(comport, "AT+GMR", 2000, version, size); } /* AT command: AT+SYSSTORE */ int esp32_set_sysstore(comport_t *comport, int enable) { char at[ATCMD_LEN]={'\0'}; snprintf(at, sizeof(at), "AT+SYSSTORE=%d", enable?1:0); return send_atcmd_check_ok(comport, at, 1000); } /*+------------------------+ *| WiFi AT command | *+------------------------+*/ /* AT command: AT+CWMODE */ int esp32_set_wmode(comport_t *comport, workmode_t mode, int autoconn) { char at[ATCMD_LEN]={'\0'}; snprintf(at, sizeof(at), "AT+CWMODE=%d,%d", mode, autoconn?1:0); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CIPSTAMAC/CIPAPMAC */ int esp32_get_macaddr(comport_t *comport, workmode_t mode, char *mac) { if( !mac ) return -1; if( MODE_SOFTAP == mode ) return send_atcmd_check_request(comport, "AT+CIPAPMAC?", 3000, mac, MAC_LEN); else return send_atcmd_check_request(comport, "AT+CIPSTAMAC?", 3000, mac, MAC_LEN); } /* AT command: AT+CIPSTA/AT+CIPAP */ int esp32_set_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway) { char at[ATCMD_LEN]={'\0'}; if( !ip || !gateway ) return -1; if( MODE_SOFTAP == mode ) snprintf(at, sizeof(at), "AT+CIPAP=\"%s\",\"%s\"", ip, gateway); else snprintf(at, sizeof(at), "AT+CIPSTA=\"%s\",\"%s\"", ip, gateway); return send_atcmd_check_ok(comport, at, 2000); } /* AT command: AT+CIPSTA/AT+CIPAP */ int esp32_get_ipaddr(comport_t *comport, workmode_t mode, char *ip, char *gateway) { char *at = MODE_SOFTAP==mode? "AT+CIPAP?" : "AT+CIPSTA?"; char buf[ATCMD_REPLY_LEN]; int rv; if( !ip || !gateway ) return -1; rv = send_atcmd_check_value(comport, at, 3000, buf, sizeof(buf)); if( rv < 0) { log_error("AT command query IP address failed, rv=%d\n", rv); return rv; } rv = parser_request_value(buf, "ip", ip, IP_LEN); if( rv < 0 ) { log_error("Parser query IP address failed, rv=%d\n", rv); return rv; } rv = parser_request_value(buf, "gateway", gateway, IP_LEN); if( rv < 0 ) { log_error("Parser query gateway address failed, rv=%d\n", rv); return rv; } return 0; } /* AT command: AT+CWDHCP */ int esp32_set_dhcp(comport_t *comport, workmode_t mode, int enable) { char at[ATCMD_LEN]={'\0'}; snprintf(at, sizeof(at), "AT+CWDHCP=%d,%d", enable?1:0, mode); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CWAUTOCONN */ int esp32_set_autoconn(comport_t *comport, int enable) { char at[ATCMD_LEN]={'\0'}; snprintf(at, sizeof(at), "AT+CWAUTOCONN=%d", enable?1:0); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CWLAP */ int esp32_list_ap(comport_t *comport, char *buf, int size) { if( !buf || size<=0 ) return -1; return send_atcmd_check_value(comport, "AT+CWLAP", 8000, buf, size); } /* AT command: AT+CWJAP */ int esp32_connect_ap(comport_t *comport, char *ssid, char *pwd) { char at[ATCMD_LEN]={'\0'}; if( !ssid || !pwd ) return -1; snprintf(at, sizeof(at), "AT+CWJAP=\"%s\",\"%s\"", ssid, pwd); return send_atcmd_check_ok(comport, at, 15000); } /* AT command: AT+CWQAP */ int esp32_disconn_ap(comport_t *comport) { return send_atcmd_check_ok(comport, "AT+CWQAP", 5000); } /* AT command: AT+CWSTATE? status value: * - 0: ESP32 station has not started any Wi-Fi connection. * - 1: ESP32 station has connected to an AP, but does not get an IPv4 address yet. * - 2: ESP32 station has connected to an AP, and got an IPv4 address. * - 3: ESP32 station is in Wi-Fi connecting or reconnecting state. * - 4: ESP32 station is in Wi-Fi disconnected state */ int esp32_join_status(comport_t *comport, int *status, char *ssid) { char buf[ATCMD_REPLY_LEN]; int rv; if( !status || !ssid ) return -1; rv = send_atcmd_check_request(comport, "AT+CWSTATE?", 3000, buf, sizeof(buf)); if( rv < 0) { log_error("AT command query join status failed, rv=%d\n", rv); return rv; } sscanf(buf, "%d,%s", status, ssid); return 0; } /* AT command: AT+PING */ int esp32_ping(comport_t *comport, char *host, int timeout) { char at[ATCMD_LEN]={'\0'}; if( !host ) return -1; snprintf(at, sizeof(at), "AT+PING=\"%s\"", host); return send_atcmd_check_ok(comport, at, timeout); } /* AT command: AT+CWSAP */ int esp32_set_softap(comport_t *comport, char *ssid, char *pwd, int channel, encmode_t encmode) { char at[ATCMD_LEN]={'\0'}; if( !ssid || !pwd ) return -1; snprintf(at, sizeof(at), "AT+CWSAP=\"%s\",\"%s\",%d,%d", ssid, pwd, channel, encmode); return send_atcmd_check_ok(comport, at, 5000); } /* AT command: AT+CWLIF */ int esp32_list_client(comport_t *comport, char *buf, int size) { if( !buf || size<=0 ) return -1; return send_atcmd_check_value(comport, "AT+CWLIF", 8000, buf, size); } /*+------------------------+ *| Socket AT command | *+------------------------+*/ /* AT command: AT+CIPMUX */ int esp32_set_socket_mux(comport_t *comport, int enable) { char at[ATCMD_LEN]={'\0'}; snprintf(at, sizeof(at), "AT+CIPMUX=%d", enable?1:0); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CIPSERVERMAXCONN */ int esp32_set_socket_clients(comport_t *comport, int max) { char at[ATCMD_LEN]={'\0'}; if( max <= 0 ) return -1; snprintf(at, sizeof(at), "AT+CIPSERVERMAXCONN=%d", max); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CIPSTO, timeout unit second */ int esp32_set_socket_timeout(comport_t *comport, int timeout) { char at[ATCMD_LEN]={'\0'}; if( timeout <= 0 ) return -1; snprintf(at, sizeof(at), "AT+CIPSTO=%d", timeout); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CIPSERVER */ int esp32_set_tcp_server(comport_t *comport, int port) { char at[ATCMD_LEN]={'\0'}; if( port <= 0 ) return -1; snprintf(at, sizeof(at), "AT+CIPSERVER=1,%d,\"TCP\"", port); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CIPSERVER */ int esp32_del_tcp_server(comport_t *comport, int port) { char at[ATCMD_LEN]={'\0'}; if( port <= 0 ) return -1; snprintf(at, sizeof(at), "AT+CIPSERVER=0,%d,\"TCP\"", port); return send_atcmd_check_ok(comport, at, 1500); } /* AT command: AT+CIPSTART */ int esp32_set_tcp_client(comport_t *comport, int mux, char *host, int port) { char at[ATCMD_LEN]={'\0'}; char buf[ATCMD_REPLY_LEN]={'\0'}; int keepalive = 60; /* unit second */ int rv,linkid = 0; if( !host || port <= 0 ) return -1; rv = esp32_set_socket_mux(comport, mux); if(rv < 0) return rv; if( mux ) snprintf(at, sizeof(at), "AT+CIPSTART=1,\"TCP\",\"%s\",%d,%d", host, port, keepalive); else snprintf(at, sizeof(at), "AT+CIPSTART=\"TCP\",\"%s\",%d,%d", host, port, keepalive); rv = send_atcmd_check_value(comport, at, 1500, buf, sizeof(buf)); if(rv < 0) return rv; sscanf(buf, "%d,", &linkid); return linkid; }