Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/wifi_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ typedef enum {
wifi_app_inst_sta_mgr = wifi_app_inst_base << 17,
wifi_app_inst_memwraptool = wifi_app_inst_base << 18,
wifi_app_inst_csi_analytics = wifi_app_inst_base << 19,
wifi_app_inst_max = wifi_app_inst_base << 20
wifi_app_inst_uahf = wifi_app_inst_base << 20,
wifi_app_inst_max = wifi_app_inst_base << 21
} wifi_app_inst_t;

typedef struct {
Expand Down
164 changes: 164 additions & 0 deletions source/apps/uahf/server1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 4096

// --- URL decode helper ---
void url_decode(char *src, char *dest) {
char a, b;
while (*src) {
if ((*src == '%') &&
((a = src[1]) && (b = src[2])) &&
(isxdigit(a) && isxdigit(b))) {
if (a >= 'a') a -= 'a' - 'A';
if (a >= 'A') a -= ('A' - 10);
else a -= '0';
if (b >= 'a') b -= 'a' - 'A';
if (b >= 'A') b -= ('A' - 10);
else b -= '0';
*dest++ = 16 * a + b;
src += 3;
} else if (*src == '+') {
*dest++ = ' ';
src++;
} else {
*dest++ = *src++;
}
}
*dest = '\0';
}

// --- Function to compose page dynamically ---
void send_html_page(int client_fd, int showThanks)
{
char page[8000];

snprintf(page, sizeof(page),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n\r\n"
"<html>"
"<head>"
"<title>OneWifi Web Server</title>"
"<style>"
"body { background: linear-gradient(to bottom right, #4facfe, #00f2fe); "
" font-family: Arial; color: white; text-align:center; padding-top:50px; }"
"h1 { font-size: 40px; text-shadow: 2px 2px #000; }"
".note { background: rgba(0,0,0,0.4); padding: 15px; margin: 20px auto; "
" width: 50%%; border-radius: 8px; font-size: 22px; color: #ffeb3b; }"
"form { background: rgba(0,0,0,0.3); padding: 20px; display:inline-block; border-radius: 10px; }"
"input { padding: 10px; margin: 5px; border-radius: 5px; border: none; }"
"input[type='submit'] { background:#ff9800; color:white; cursor:pointer; }"
"</style>"
"</head>"
"<body>"
"<h1>OneWifi Web Server</h1>");

if (showThanks) {
strcat(page,
"<div class='note'>Thank you for providing the details!</div>");
}

strcat(page,
"<h3>Please enter your login details</h3>"
"<form method='POST' action='/'>"
"<input name='username' placeholder='Username'><br>"
"<input name='password' type='password' placeholder='Password'><br>"
"<input type='submit' value='Login'>"
"</form>"
"</body></html>");

write(client_fd, page, strlen(page));
}

int main() {
int server_fd, client_fd;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
char buffer[BUFFER_SIZE];

server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket failed");
exit(1);
}

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind failed");
exit(1);
}

listen(server_fd, 3);
printf("Server running on port %d...\n", PORT);

while (1) {
client_fd = accept(server_fd, (struct sockaddr *)&addr, &addrlen);
if (client_fd < 0) {
perror("accept");
continue;
}

memset(buffer, 0, BUFFER_SIZE);
read(client_fd, buffer, BUFFER_SIZE);

// ---- GET Request ----
if (strncmp(buffer, "GET", 3) == 0) {
int showThanks = 0;

if (strstr(buffer, "thanks=1"))
showThanks = 1;

send_html_page(client_fd, showThanks);
}

// ---- POST Request ----
else if (strncmp(buffer, "POST", 4) == 0) {

// Extract POST body (optional)
char *body = strstr(buffer, "\r\n\r\n");
if (body) body += 4;

char username[200] = {0}, password[200] = {0};
char decoded[400];

char *u = strstr(body, "username=");
char *p = strstr(body, "password=");

if (u && p) {
sscanf(u, "username=%199[^&]", username);
sscanf(p, "password=%199[^&]", password);

url_decode(username, decoded);
strcpy(username, decoded);

url_decode(password, decoded);
strcpy(password, decoded);

printf("User submitted: %s / %s\n", username, password);
}

printf("POST received - redirecting with thank you note...\n");

// Redirect to same page with thank-you flag
const char *redirect =
"HTTP/1.1 303 See Other\r\n"
"Location: /?thanks=1\r\n"
"Content-Length: 0\r\n"
"\r\n";

write(client_fd, redirect, strlen(redirect));
}

close(client_fd);
}

return 0;
}

202 changes: 202 additions & 0 deletions source/apps/uahf/uahf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#include "uahf.h"
#include "uahf_server.h"
#include "stdlib.h"
#include "wifi_ctrl.h"
#include "wifi_hal.h"
#include "wifi_mgr.h"
#include "wifi_util.h"
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/time.h>

void* uahf_worker_task(void* arg) {
wifi_app_t* app = (wifi_app_t*)arg;
uahf_data_t* d = GET_UAHF(app);

wifi_util_error_print(WIFI_APPS, "UAHF: starting server in detached thread\n");

// 1. Run the server directly (BLOCKING)
// This will sit here until the user submits the form and the loop breaks
uahf_start_server(app);
wifi_util_error_print(WIFI_APPS, "UAHF: server exited from detached thread\n");

// 2. Update State (Critical Section)
pthread_mutex_lock(&d->app_lock);

d->worker_running = false;
d->worker_done = true; // Signal main thread that data is in d->username/password
pthread_mutex_unlock(&d->app_lock);

wifi_util_error_print(WIFI_CTRL, "UAHF Result: User=%s, Pass=%s\n",
d->username, d->password);

// Pass to AppMgr or other logic
// process_login(d->username, d->password);


/* reviewed options to apply data gotten from the server:
* 1. dmcli (doesnt seem to work - ignored with start_station_Vaps);, without vaps doesnt start
* precondition - update Security_SetParamStringValue in cosa_wifi_dml.c
* Due to checking security_mode_support_radius() (likely set by ignite in start_extender_Vaps) on vaps,
* it prevents saving a passphrase. Cooment "return FALSE";
* 2. copy-paster start_station_vaps; done with start_uahf_vaps() method;
* Once errors were fixed and logic slightly improved it triggers SIGSEGV crash while working on first vap (mesh_Sta_2g);
*
* 3. manually reconfigure station vaps;
* a) removing hardcodes from start_station_vaps,esp. disabling radius
* b) forget about start_station_vaps
* 4. start vaps properly configured from the beginning (commenting start_station_vaps or replacing them);
*
*/

#define BUFFER_SIZE 4096
/*char command_buffer[BUFFER_SIZE];
int len = snprintf( command_buffer, BUFFER_SIZE, "dmcli eRT setv Device.WiFi.SSID.15.SSID string %s", d->username);
if (len == 0) printf("have to use this somewhere to disable -Wall error");
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : about to call set ssid for vap 15\n", __func__, __LINE__);

system(command_buffer);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called set ssid for vap 15\n", __func__, __LINE__);

len = snprintf( command_buffer, BUFFER_SIZE, "dmcli eRT setv Device.WiFi.SSID.16.SSID string %s", d->username);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : about to call set ssid for vap 16\n", __func__, __LINE__);

system(command_buffer);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called set ssid for vap 16\n", __func__, __LINE__);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : about to call set ssid for vap 24\n", __func__, __LINE__);

len = snprintf( command_buffer, BUFFER_SIZE, "dmcli eRT setv Device.WiFi.SSID.24.SSID string %s", d->username);
system(command_buffer);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called set ssid for vap 24\n", __func__, __LINE__);

len = snprintf( command_buffer, BUFFER_SIZE,
"dmcli eRT setv Device.WiFi.AccessPoint.15.Security.KeyPassphrase string %s", d->password);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : about to call set psk for vap 15\n", __func__, __LINE__);

system(command_buffer);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called set psk for vap 15\n", __func__, __LINE__);

len = snprintf( command_buffer, BUFFER_SIZE,
"dmcli eRT setv Device.WiFi.AccessPoint.16.Security.KeyPassphrase string %s", d->password);

wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : will call set psk for vap 16, with %s \n", __func__, __LINE__, d->password);

system(command_buffer);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called set psk for vap 16\n", __func__, __LINE__);
wifi_util_error_print(WIFI_APPS, "%s:%d: cmd: %s\n", __func__, __LINE__, command_buffer);

len = snprintf( command_buffer, BUFFER_SIZE,
"dmcli eRT setv Device.WiFi.AccessPoint.24.Security.KeyPassphrase string %s", d->password);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : about to call set psk for vap 24\n", __func__, __LINE__);

system(command_buffer);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called set psk for vap 24, call start ext vaps\n", __func__, __LINE__);

system("dmcli eRT setv Device.WiFi.ApplyAccessPointSettings bool true"); */
//wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : will call start extender vaps\n", __func__, __LINE__);


wifi_util_error_print(WIFI_APPS, "%s:%d: will call start station vaps\n", __func__, __LINE__);

start_station_vaps(TRUE, d->username, d->password);
wifi_util_error_print(WIFI_APPS, "%s:%d: called start station vaps, exit\n", __func__, __LINE__);

start_extender_vaps();
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf : called start extender vaps\n", __func__, __LINE__);



return NULL;
}

int uahf_update(wifi_app_t *app) {
uahf_data_t* d = GET_UAHF(app);
wifi_util_error_print(WIFI_APPS, "%s:%d: Init uahf-update\n", __func__, __LINE__);

// --- Trigger Server ---
if (!d->worker_running && !d->worker_done) {
wifi_util_error_print(WIFI_APPS, "%s:%d: wILL try to create thread\n", __func__, __LINE__);

pthread_mutex_lock(&d->app_lock);

// Clear old data just in case
memset(d->username, 0, sizeof(d->username));
memset(d->password, 0, sizeof(d->password));

if (!d->worker_running) {
d->worker_running = true;

// --- SPAWN THREAD (NON-BLOCKING) ---
// We create a separate thread to handle the blocking server.
// pthread_create returns immediately.

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 128 * 1024);
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf:about to spawn a thread with server\n", __func__, __LINE__);

if (pthread_create(&d->worker_tid, &attr, uahf_worker_task, app) == 0) {
pthread_detach(d->worker_tid); // Fire and forget
wifi_util_error_print(WIFI_APPS, "%s:%d: uahf: started thread with server\n", __func__, __LINE__);

} else {
d->worker_running = false;
}
pthread_attr_destroy(&attr);
}
pthread_mutex_unlock(&d->app_lock);

}
// wifi_util_error_print(WIFI_APPS, "%s:%d: uahf after spawning a thread block\n", __func__, __LINE__);

// --- Process Results --
// dead cpde for now
if (d->worker_done) {
pthread_mutex_lock(&d->app_lock);
if (d->worker_done) {

// SUCCESS: Data is now available directly in the struct
wifi_util_error_print(WIFI_APPS, "UAHF Result: User=%s, Pass=%s\n",
d->username, d->password);


d->worker_done = true; //for now we leave it here,so that it isn't restarted several times.
}
pthread_mutex_unlock(&d->app_lock);
}
//wifi_util_error_print(WIFI_APPS, "%s:%d: uahf: exit\n", __func__, __LINE__);

return RETURN_OK;
}

int uahf_init(wifi_app_t *app, unsigned int create_flag)
{

memset(&app->data.u.uahf_data, 0, sizeof(uahf_data_t));
pthread_mutex_init(&app->data.u.uahf_data.app_lock, NULL);

if (app_init(app, create_flag) != 0) {
return RETURN_ERR;
}
wifi_util_error_print(WIFI_APPS, "%s:%d: Init uahf\n", __func__, __LINE__);

return RETURN_OK;
}

int uahf_deinit(wifi_app_t *app)
{
return RETURN_OK;
}

/*
int my_app_deinit(wifi_app_t* app) {
MyHttpState* state = GET_STATE(app);
if (state->worker_running) {
// In a real app, you'd kill the thread or wait.
// For a demo, a small sleep or warning is sufficient.
printf("Warning: App closing while worker is active.\n");
}
return 0;
*/
Loading
Loading