send keys over WebSocket

This commit is contained in:
2025-07-20 17:38:02 -04:00
parent d25218898b
commit f628003c66
12 changed files with 1688 additions and 1127 deletions
+62 -47
View File
@@ -10,9 +10,11 @@
#include "hardware/sync.h"
#include "pico/multicore.h"
#include "server.h"
#include "parse_keys.h"
#include "dhcpserver.h"
#include "websocket.h"
#include "server.h"
uint8_t led_code = 0;
static uint8_t ip[4];
@@ -29,9 +31,6 @@ static void *current_connection;
// list of SSI variable names for lwIP SSI handler
const char * __not_in_flash("httpd") ssi_tags[] = {
"num",
"caps",
"scroll",
"ssid",
"pass",
"host",
@@ -142,6 +141,12 @@ void run_http_server() {
http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags));
printf("HTTP server initialized\n");
// start the websocket server
ws_server_init();
ws_set_open_handler(ws_open_handler);
ws_set_receive_handler(ws_receive_handler);
printf("Websocket server initialized\n");
// start a watchdog timer with 8 seconds so it can reboot if it disconnects
watchdog_enable(8000,1);
@@ -242,79 +247,58 @@ bool net_config_load(net_config *config) {
uint16_t __time_critical_func(ssi_handler)(int iIndex, char *pcInsert, int iInsertLen) {
size_t printed;
switch (iIndex) {
case 0: //num - numlock status
if (led_code & 1) {
printed = snprintf(pcInsert, iInsertLen, "on");
} else {
printed = snprintf(pcInsert, iInsertLen, "off");
}
break;
case 1: //caps - capslock status
if (led_code & 2) {
printed = snprintf(pcInsert, iInsertLen, "on");
} else {
printed = snprintf(pcInsert, iInsertLen, "off");
}
break;
case 2: //scroll - scrollock status
if (led_code & 4) {
printed = snprintf(pcInsert, iInsertLen, "on");
} else {
printed = snprintf(pcInsert, iInsertLen, "off");
}
break;
case 3: //ssid - network config SSID
case 0: //ssid - network config SSID
if (config_loaded && wifi.ssid) {
printed = snprintf(pcInsert, iInsertLen, "value=\"%s\"", wifi.ssid);
} else {
printed = 0;
}
break;
case 4: //pass - network config password
case 1: //pass - network config password
if (config_loaded && wifi.pass) {
printed = snprintf(pcInsert, iInsertLen, "value=\"%s\"", wifi.pass);
} else {
printed = 0;
}
break;
case 5: //host - network config hostname
case 2: //host - network config hostname
if (config_loaded && wifi.host) {
printed = snprintf(pcInsert, iInsertLen, "value=\"%s\"", wifi.host);
} else {
printed = 0;
}
break;
case 6:
case 3:
case 4:
case 5:
case 6: //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-3));
} else {
printed = 0;
}
break;
case 7:
case 8:
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));
case 9:
case 10: //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-7));
} else {
printed = 0;
}
break;
case 10:
case 11:
case 12:
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 {
printed = 0;
}
break;
case 14:
case 15:
case 16:
case 17: //gw0-3 - network config manual gateway parts
case 13:
case 14: //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));
printed = snprintf(pcInsert, iInsertLen, "value=\"%d\"", ip4_addr_get_byte(&(wifi.gw), iIndex-11));
} else {
printed = 0;
}
break;
case 18: // dhcp - network config DHCP client enabled/disabled
case 15: // dhcp - network config DHCP client enabled/disabled
if ((!config_loaded) || !(wifi.manual) ){
printed = snprintf(pcInsert, iInsertLen, "checked");
} else {
@@ -448,7 +432,7 @@ void httpd_post_finished(void *connection, char *response_uri, u16_t response_ur
current_connection = NULL;
}
// Return a value for a parameter from POST
// return a value for a parameter from POST
char *find_post_param(struct pbuf *p, const char *param, char *buf, size_t len) {
size_t param_len = strlen(param);
uint16_t param_pos = pbuf_memfind(p, param, param_len, 0);
@@ -474,9 +458,40 @@ char *find_post_param(struct pbuf *p, const char *param, char *buf, size_t len)
return NULL;
}
const void ws_open_handler(struct ws_state * wss) {
send_indicators();
}
// handler for data received on websocket connection
const void ws_receive_handler(uint8_t *data, uint16_t len) {
if (strncmp(data, "K: ", 3)==0) {
parse_key_list(&data[3]);
} else if (strncmp(data, "M: ", 3) == 0) {
parse_mouse_list(&data[3]);
}
}
// save keyboard's LED indicator status to memory
void set_indicator(uint8_t const* buffer) {
led_code = *buffer;
send_indicators();
}
// read individual bits for indicator LED status and send over websocket to client
void send_indicators(void){
char buf[16]="";
if (led_code & 1) {
strcat(buf, "num,");
}
if (led_code & 2) {
strcat(buf, "caps,");
}
if (led_code & 4) {
strcat(buf, "scroll");
}
ws_send_all(buf, strlen(buf));
}
// take URL-formatted string from GET request and turn into regular string