Skip to content

Commit

Permalink
refactor cgiwifi API to use modern AJAX style (was template). Also cl…
Browse files Browse the repository at this point in the history
…eanup some other cgi.
  • Loading branch information
pabbott-lumitec committed Jul 28, 2022
1 parent 7ff76ae commit 787799e
Show file tree
Hide file tree
Showing 12 changed files with 872 additions and 732 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ set (libesphttpd_SOURCES "core/auth.c"
"core/sha1.c"
"core/libesphttpd_base64.c"
"util/captdns.c"
"util/cgi_common.c"
"util/cgiflash.c"
"util/cgiredirect.c"
"util/cgiwebsocket.c"
"util/cgiwifi.c"
"util/cgiredirect.c"
"util/esp32_flash.c"
"util/esp32_httpd_vfs.c"
"util/esp32_wifi.c")

Expand Down
157 changes: 157 additions & 0 deletions README-wifi_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Libesphttpd WiFi-API

Functions to configure ESP32 WiFi settings via HTTP API.

## GUI
See the example js/html code for the GUI here: https://github.com/chmorgan/esphttpd-freertos/blob/master/html/wifi/index.html

## Functions defined in libesphttpd/cgiwifi.h

* __cgiWiFiScan()__

Gets the results of an earler scan in JSON format. Optionally start a new scan.

Examples:
* `http://my-esp32-ip/wifi/scan?clear=1&start=1` - Clear the previous results and start a new scan. Returned APs list will be empty and inProgress will be true.

Note: If client is connected via WiFi, then start=1 may interrupt communication breifly, so use sparingly.
* `http://my-esp32-ip/wifi/scan` - After sending start command, poll this until `inProgress:false` and APs list contains results.

Note: "enc" value is from `enum wifi_auth_mode_t`, where 0=Open, 1=WEP, 2+ is WPA.

GET/POST args:
```js
"clear": number // 1: Clear the previous results first.
"start": number // 1: Start a new scan now.
```
Response:
```js
{
"args": { // Args are repeated here in the response
"clear": number,
"start": number,
},
"APs": [{
"essid": string, // Name of AP discovered
"bssid": string, // MAC of AP discoverd
"rssi": number, // Signal strength i.e. -55
"enc": number, // WiFi security (encryption) type.
"channel": number // Channel used by AP
},{...}],
"working": boolean, // A scan is in progress. Poll this.
"success": boolean, // CGI success/fail
"error": string, // Optional error message if failure
}
```

* __cgiWiFiConnect()__

Set WiFi STAtion (ESP WiFI Client) settings and trigger a connection.

Note: The "success" response of this CGI call does not indicate if the WiFi connection succeeds. Poll /wifi/sta (cgiWiFiConnStatus) for connection pending/success/fail.

Examples:
* http://my-esp32-ip/wifi/connect?ssid=my-ssid&pass=mysecretpasswd - Trigger a connection attempt to the AP with the given SSID and password.

GET/POST args:
```js
"ssid": string
"pass": string
```
Response:
```js
{
"args": { // Args are repeated here in the response
"ssid": string,
"pass": string,
},
"success": boolean, // CGI success/fail
"error": string, // Optional error message if failure
}
```

* __cgiWiFiSetMode()__

CGI used to get/set the WiFi mode.

The mode values are defined by `enum wifi_mode_t`
```c
0 /**< null mode */
1 /**< WiFi station mode */
2 /**< WiFi soft-AP mode */
3 /**< WiFi station + soft-AP mode */
```

Examples
* i.e. http://ip/wifi/mode?mode=1 - Change mode to WIFI_MODE_STA

GET/POST args:
```js
"mode": number // The desired Mode (as number specified in enum wifi_mode_t)
"force": number // 1: Force the change, regardless of whether ESP's STA is connected to an AP.
```
Response:
```js
{
"args": { // Args are repeated here in the response
"mode": number,
"force": number,
},
"mode": number, // The current Mode (as number specified in enum wifi_mode_t)
"mode_str": string, // The current Mode (as a string specified in wifi_mode_names[]= "Disabled","STA","AP""AP+STA")
"success": boolean, // CGI success/fail
"error": string, // Optional error message if failure
}
```

* __cgiWiFiStartWps()__

CGI for triggering a WPS push button connection attempt.

* __cgiWiFiAPSettings()__

CGI for get/set settings in AP mode.

Examples:
* http://ip/wifi/ap?ssid=myssid&pass=mypass&chan=1 - Change AP settings

GET/POST args:
```js
"chan": number,
"ssid": string,
"pass": string
```
Response:
```js
{
"args": { // Args are repeated here in the response
"chan": number,
"ssid": string,
"pass": string,
},
"enabled" : boolean, // AP is enabled
"success": boolean, // CGI success/fail
"error": string, // Optional error message if failure
}
```

* __cgiWiFiConnStatus()__

CGI returning the current state of the WiFi STA connection to an AP.

Examples:
* `http://my-esp32-ip/wifi/sta` - Get the state of the STAtion

Response:
```js
{
"ssid": string, // SSID that the STAtion should connect to.
"pass": string, // WiFi network password.
"enabled" : boolean, // STA is enabled
"ip" : string, // Optional IP address of STAtion (only if connected)
"working": boolean, // A connect is in progress. Poll this.
"connected": boolean, // STAtion is connected to a WiFi network. Poll this.
"success": boolean, // CGI success/fail
"error": string, // Optional error message if failure
}
```
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,9 @@ of a DNS-server (started by calling `captdnsInit()`) resolving all hostnames int
ESP8266/ESP32. These redirect functions can then be used to further redirect the client to the hostname of
the ESP8266/ESP32.

* Flash updating functions (OTA) - see [README-flash_api](./README-flash_api.md)
* __Flash updating functions (OTA)__ - see [README-flash_api](./README-flash_api.md)

* __cgiWiFi* functions__ (arg: various)
These are used to change WiFi mode, scan for access points, associate to an access point etcetera. See
the example projects for an implementation that uses this function call. [FreeRTOS Example](https://github.com/chmorgan/esphttpd-freertos)
* __WiFi settings functions__ - see [README-wifi_api.md](./README-wifi_api.md)

* __cgiWebsocket__ (arg: connect function)
This CGI is used to set up a websocket. Websockets are described later in this document. See
Expand Down
43 changes: 43 additions & 0 deletions include/libesphttpd/cgi_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Functions commonly used in cgi handlers for libesphttpd */

#ifndef CGI_COMMON_H
#define CGI_COMMON_H

#include "libesphttpd/httpd.h"
#include "cJSON.h"

// Parses *allArgs (i.e. connData->getArgs or connData->post.buff) for a signed integer by name of *argName and returns int value at *pvalue.
bool cgiGetArgDecS32(const char *allArgs, const char *argName, int *pvalue, char *buff, int buffLen);
// Parses *allArgs (i.e. connData->getArgs or connData->post.buff) for a unsigned int (i.e. ?uintval=123)
bool cgiGetArgDecU32(const char *allArgs, const char *argName, uint32_t *pvalue, char *buff, int buffLen);
// Parses *allArgs (i.e. connData->getArgs or connData->post.buff) for a uint32_t from a hexadecimal string (i.e. ?hexval=0123ABCD )
bool cgiGetArgHexU32(const char *allArgs, const char *argName, uint32_t *pvalue, char *buff, int buffLen);
// Parses *allArgs (i.e. connData->getArgs or connData->post.buff) for a string value. (just a wrapper for httpdFindArg())
bool cgiGetArgString(const char *allArgs, const char *argName, char *buff, int buffLen);


void cgiJsonResponseHeaders(HttpdConnData *connData);
void cgiJavascriptResponseHeaders(HttpdConnData *connData);

/**
* Example usage of cgiJsonResponseCommonMulti for multipart json response (i.e. larger than 1kB)
*
CgiStatus cgiFn(HttpdConnData *connData)
{
cJSON *jsroot = NULL;
if (connData->cgiData == NULL)
{
//First call to this cgi.
jsroot = cJSON_CreateObject();
...
cgiJsonResponseHeaders(connData);
}
return cgiJsonResponseCommonMulti(connData, &connData->cgiData, jsroot); // Send the json response!
}
*/
CgiStatus cgiJsonResponseCommonMulti(HttpdConnData *connData, void **statepp, cJSON *jsroot);
CgiStatus cgiJsonResponseCommonSingle(HttpdConnData *connData, cJSON *jsroot);

CgiStatus cgiJavascriptResponseCommon(HttpdConnData *connData, cJSON *jsroot, const char *jsObjName);

#endif //CGI_COMMON_H
1 change: 0 additions & 1 deletion include/libesphttpd/cgiwifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ CgiStatus cgiWiFiConnStatus(HttpdConnData *connData);
#include <esp_event.h>
esp_err_t initCgiWifi(void);
esp_err_t startCgiWifi(void);
void cgiWifiEventCb(system_event_t *event);
CgiStatus cgiWiFiStartWps(HttpdConnData *connData);
#endif

Expand Down
6 changes: 3 additions & 3 deletions util/captdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static const char* TAG = "captdns";
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#else
#include "FreeRTOS.h"
#include "task.h"
Expand Down Expand Up @@ -234,8 +234,8 @@ static void ICACHE_FLASH_ATTR captdnsRecv(struct sockaddr_in *premote_addr, char
setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes;
//Grab the current IP of the softap interface
#ifdef ESP32
tcpip_adapter_ip_info_t info;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &info);
esp_netif_ip_info_t info;
esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"), &info);
#else
struct ip_info info;
wifi_get_ip_info(SOFTAP_IF, &info);
Expand Down
Loading

0 comments on commit 787799e

Please sign in to comment.