code clean up and added comments
This commit is contained in:
@@ -26,6 +26,7 @@ static bool config_loaded = false;
|
||||
static bool bad_config = false;
|
||||
static bool reboot = false;
|
||||
|
||||
// list of SSI variable names for lwIP SSI handler
|
||||
const char * __not_in_flash("httpd") ssi_tags[] = {
|
||||
"num",
|
||||
"caps",
|
||||
@@ -56,48 +57,53 @@ static const tCGI cgi_handlers[] = {
|
||||
};
|
||||
|
||||
void run_http_server() {
|
||||
//sleep_ms(5000);
|
||||
|
||||
if (cyw43_arch_init_with_country(CYW43_COUNTRY_USA)) {
|
||||
printf("failed to initialize\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// fall back to AP mode unless Wi-Fi connection is successful
|
||||
clientmode = false;
|
||||
|
||||
// read network config from flash
|
||||
config_loaded = net_config_load(&wifi);
|
||||
|
||||
if ( config_loaded ){
|
||||
printf("read config file\n");
|
||||
cyw43_arch_enable_sta_mode();
|
||||
|
||||
// set hostname
|
||||
//cyw43_arch_lwip_begin();
|
||||
// set hostname if saved, otherwise use default setting
|
||||
struct netif *n = &cyw43_state.netif[CYW43_ITF_STA];
|
||||
if (wifi.host) {
|
||||
netif_set_hostname(n, wifi.host);
|
||||
} else {
|
||||
netif_set_hostname(n, DEFAULTHOST);
|
||||
}
|
||||
|
||||
// use manual IP address if configured
|
||||
if (wifi.manual) {
|
||||
dhcp_release_and_stop(n);
|
||||
netif_set_addr(n, &(wifi.ip), &(wifi.mask), &(wifi.gw));
|
||||
|
||||
// inform mDNS of hostname
|
||||
dhcp_inform(n);
|
||||
}
|
||||
netif_set_up(n);
|
||||
//cyw43_arch_lwip_end();
|
||||
|
||||
// attempt to connect to saved Wi-Fi network
|
||||
if(cyw43_arch_wifi_connect_timeout_ms(wifi.ssid, wifi.pass, CYW43_AUTH_WPA2_AES_PSK, 10000)){
|
||||
printf("failed to connect to %s\n", wifi.ssid);
|
||||
} else{
|
||||
// Wi-Fi client connection successful
|
||||
clientmode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!clientmode) {
|
||||
//start AP mode
|
||||
// did not connect to Wi-Fi, launch AP mode
|
||||
cyw43_arch_enable_ap_mode(DEFAULTHOST, DEFAULTPASS, CYW43_AUTH_WPA2_AES_PSK);
|
||||
|
||||
// set AP address to 192.168.0.1
|
||||
ip4_addr_t ip, mask, gw;
|
||||
IP4_ADDR(&ip, 192, 168, 0, 1);
|
||||
IP4_ADDR(&mask, 255, 255, 255, 0);
|
||||
@@ -105,12 +111,13 @@ void run_http_server() {
|
||||
netif_set_ipaddr(netif_default, &ip);
|
||||
netif_set_up(netif_default);
|
||||
|
||||
// init DHCP server to hand out addresses to connected clients
|
||||
dhcp_server_t dhcp;
|
||||
dhcp_server_init(&dhcp, &gw, &mask);
|
||||
printf("launched in AP mode\n");
|
||||
}
|
||||
|
||||
// start the server
|
||||
// start the HTTP web server for keyboard input and config page
|
||||
httpd_init();
|
||||
http_set_cgi_handlers(cgi_handlers, 3);
|
||||
for (size_t i = 0; i < LWIP_ARRAYSIZE(ssi_tags); i++) {
|
||||
@@ -120,14 +127,19 @@ void run_http_server() {
|
||||
http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags));
|
||||
printf("HTTP server initialized\n");
|
||||
|
||||
// start a watchdog timer with 8 seconds so it can reboot if it disconnects
|
||||
watchdog_enable(8000,1);
|
||||
|
||||
if (clientmode) {
|
||||
// signal that device is in client mode with solid LED on
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN,1);
|
||||
while(true) {
|
||||
if ( absolute_time_diff_us(lastCheck, get_absolute_time()) > 5000000) {
|
||||
// check if Wi-Fi is still connected every 5 seconds and
|
||||
// feed the watchdog timer if it is to prevent reboot
|
||||
if ( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == 3 ) {
|
||||
lastCheck = get_absolute_time();
|
||||
// update watchdog if reboot has not been requested
|
||||
if(!reboot){
|
||||
watchdog_update();
|
||||
}
|
||||
@@ -139,12 +151,16 @@ void run_http_server() {
|
||||
static int led = 1;
|
||||
while(true) {
|
||||
if (absolute_time_diff_us(lastCheck, get_absolute_time()) > 1000000) {
|
||||
// signal device is in AP mode with blinking LED
|
||||
led = !led;
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led);
|
||||
lastCheck = get_absolute_time();
|
||||
if ( config_loaded && (absolute_time_diff_us(lastActive, lastCheck) > 600000000)) {
|
||||
// if there is no keyboard activity for 10 minutes
|
||||
// reboot to try to (re)connect to Wi-Fi
|
||||
reboot = true;
|
||||
}
|
||||
// update watchdog unless reboot has been requested
|
||||
if(!reboot) {
|
||||
watchdog_update();
|
||||
}
|
||||
@@ -153,10 +169,11 @@ void run_http_server() {
|
||||
}
|
||||
}
|
||||
|
||||
// lwIP cgi handler for GET requests to sendkeys.cgi
|
||||
const char * sendkeys_cgi (int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
|
||||
for (int i=0; i < iNumParams; i++) {
|
||||
// search GET parameters for keys and forward for processing to USB
|
||||
if (strcmp(pcParam[i], "keys") == 0 ) {
|
||||
//printf("Web input: %s\n", pcValue[i]);
|
||||
parse_key_list(pcValue[i]);
|
||||
}
|
||||
}
|
||||
@@ -167,6 +184,7 @@ const char * sendkeys_cgi (int iIndex, int iNumParams, char *pcParam[], char *pc
|
||||
return "/success.html";
|
||||
}
|
||||
|
||||
// lwIP cgi handler for form submission of network config to wifi.cgi
|
||||
const char * save_wifi (int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
|
||||
// clear all values in manual network settings
|
||||
memset(ip, 0, sizeof(ip));
|
||||
@@ -176,6 +194,7 @@ const char * save_wifi (int iIndex, int iNumParams, char *pcParam[], char *pcVal
|
||||
bad_config = false;
|
||||
wifi.manual = true;
|
||||
|
||||
// read parameter values
|
||||
for (int i=0; i < iNumParams; i++) {
|
||||
if (strcmp(pcParam[i], "ssid") == 0){
|
||||
if (pcValue[i][0] == "\0") {
|
||||
@@ -217,8 +236,10 @@ const char * save_wifi (int iIndex, int iNumParams, char *pcParam[], char *pcVal
|
||||
}
|
||||
|
||||
if (bad_config) {
|
||||
// config is invalid, so don't save and return to config page
|
||||
return "/wifi.shtml";
|
||||
} else {
|
||||
// config is valid, prepare for saving to flash
|
||||
IP4_ADDR(&(wifi.ip), ip[0], ip[1], ip[2], ip[3]);
|
||||
if(!wifi.ip.addr) {
|
||||
wifi.ip.addr = IPADDR_NONE;
|
||||
@@ -237,6 +258,7 @@ const char * save_wifi (int iIndex, int iNumParams, char *pcParam[], char *pcVal
|
||||
|
||||
watchdog_update();
|
||||
|
||||
// save configuratitons to flash
|
||||
net_config_write(&wifi);
|
||||
|
||||
printf("wifi settings saved\n");
|
||||
@@ -245,7 +267,9 @@ const char * save_wifi (int iIndex, int iNumParams, char *pcParam[], char *pcVal
|
||||
}
|
||||
}
|
||||
|
||||
// lwIP cgi handler for reboots initiated from the web
|
||||
const char * reboot_cgi(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
|
||||
// turn on reboot flag to prevent watchdog from updating
|
||||
reboot = true;
|
||||
|
||||
return "/success.html";
|
||||
@@ -253,20 +277,28 @@ const char * reboot_cgi(int iIndex, int iNumParams, char *pcParam[], char *pcVal
|
||||
|
||||
|
||||
void net_config_write(net_config *config) {
|
||||
// core 0 must have its TinyUSB interrupts disabled to allow flash writes
|
||||
multicore_lockout_start_blocking();
|
||||
|
||||
// blank out memory for staging config save
|
||||
uint8_t buf[FLASH_PAGE_SIZE];
|
||||
memset(buf, 0x00, FLASH_PAGE_SIZE);
|
||||
memcpy(buf, config, sizeof(net_config));
|
||||
|
||||
// turn off core 1 web server interrupts to allow flash writes
|
||||
uint32_t interrupts = save_and_disable_interrupts();
|
||||
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
|
||||
flash_range_program(FLASH_TARGET_OFFSET, buf, FLASH_PAGE_SIZE);
|
||||
restore_interrupts(interrupts);
|
||||
|
||||
// erase page where save will go in flash
|
||||
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
|
||||
// write new config to flash
|
||||
flash_range_program(FLASH_TARGET_OFFSET, buf, FLASH_PAGE_SIZE);
|
||||
|
||||
// restore interrupts on both core 1 and core 0
|
||||
restore_interrupts(interrupts);
|
||||
multicore_lockout_end_blocking();
|
||||
}
|
||||
|
||||
// read network config from flash and loads to program memory
|
||||
bool net_config_load(net_config *config) {
|
||||
const uint8_t *data = (const uint8_t *) (XIP_BASE+FLASH_TARGET_OFFSET);
|
||||
memcpy(config, data, sizeof(net_config));
|
||||
@@ -274,45 +306,46 @@ bool net_config_load(net_config *config) {
|
||||
return ( (config->header == STARTFILE) && (config->footer == ENDFILE) );
|
||||
}
|
||||
|
||||
// lwIP SSI handler for loading variables into HTML pages
|
||||
uint16_t __time_critical_func(ssi_handler)(int iIndex, char *pcInsert, int iInsertLen) {
|
||||
size_t printed;
|
||||
switch (iIndex) {
|
||||
case 0: //num
|
||||
case 0: //num - numlock status
|
||||
if (led_code & 1) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "on");
|
||||
} else {
|
||||
printed = snprintf(pcInsert, iInsertLen, "off");
|
||||
}
|
||||
break;
|
||||
case 1: //caps
|
||||
case 1: //caps - capslock status
|
||||
if (led_code & 2) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "on");
|
||||
} else {
|
||||
printed = snprintf(pcInsert, iInsertLen, "off");
|
||||
}
|
||||
break;
|
||||
case 2: //scroll
|
||||
case 2: //scroll - scrollock status
|
||||
if (led_code & 4) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "on");
|
||||
} else {
|
||||
printed = snprintf(pcInsert, iInsertLen, "off");
|
||||
}
|
||||
break;
|
||||
case 3: //ssid
|
||||
case 3: //ssid - network config SSID
|
||||
if (config_loaded && wifi.ssid) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "value=\"%s\"", wifi.ssid);
|
||||
} else {
|
||||
printed = 0;
|
||||
}
|
||||
break;
|
||||
case 4: //pass
|
||||
case 4: //pass - network config password
|
||||
if (config_loaded && wifi.pass) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "value=\"%s\"", wifi.pass);
|
||||
} else {
|
||||
printed = 0;
|
||||
}
|
||||
break;
|
||||
case 5: //host
|
||||
case 5: //host - network config hostname
|
||||
if (config_loaded && wifi.host) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "value=\"%s\"", wifi.host);
|
||||
} else {
|
||||
@@ -322,7 +355,7 @@ uint16_t __time_critical_func(ssi_handler)(int iIndex, char *pcInsert, int iInse
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9: //ip0-3
|
||||
case 9: //ip0-3 - network config manual IP address parts
|
||||
if (config_loaded && wifi.ip.addr) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "value=\"%d\"", ip4_addr_get_byte(&(wifi.ip), iIndex-6));
|
||||
} else {
|
||||
@@ -332,7 +365,7 @@ uint16_t __time_critical_func(ssi_handler)(int iIndex, char *pcInsert, int iInse
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13: //mask0-3
|
||||
case 13: //mask0-3 - network config manual netmask parts
|
||||
if (config_loaded && wifi.mask.addr) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "value=\"%d\"", ip4_addr_get_byte(&(wifi.mask), iIndex-10));
|
||||
} else {
|
||||
@@ -342,14 +375,14 @@ uint16_t __time_critical_func(ssi_handler)(int iIndex, char *pcInsert, int iInse
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17: //gw0-3
|
||||
case 17: //gw0-3 - network config manual gateway parts
|
||||
if (config_loaded && wifi.gw.addr) {
|
||||
printed = snprintf(pcInsert, iInsertLen, "value=\"%d\"", ip4_addr_get_byte(&(wifi.gw), iIndex-14));
|
||||
} else {
|
||||
printed = 0;
|
||||
}
|
||||
break;
|
||||
case 18: // dhcp
|
||||
case 18: // dhcp - network config DHCP client enabled/disabled
|
||||
if ((!config_loaded) || !(wifi.manual) ){
|
||||
printed = snprintf(pcInsert, iInsertLen, "checked");
|
||||
} else {
|
||||
@@ -364,10 +397,12 @@ uint16_t __time_critical_func(ssi_handler)(int iIndex, char *pcInsert, int iInse
|
||||
return (uint16_t)printed;
|
||||
}
|
||||
|
||||
// save keyboard's LED indicator status to memory
|
||||
void set_indicator(uint8_t const* buffer) {
|
||||
led_code = *buffer;
|
||||
}
|
||||
|
||||
// turn URL-formatted string from GET request and turn into regular string
|
||||
void urldecode(char *urlstring, char *decoded) {
|
||||
uint8_t conv;
|
||||
while(*urlstring) {
|
||||
|
||||
Reference in New Issue
Block a user