diff --git a/application.fam b/application.fam index 81d1b2cbd9f..1c72ace49ff 100644 --- a/application.fam +++ b/application.fam @@ -8,7 +8,7 @@ App( "gui", "power", ], - stack_size=20 * 1024, + stack_size=20*1024, order=90, fap_icon="images/ehternet_icon_10x10px.png", fap_category="GPIO", diff --git a/eth_save_process.c b/eth_save_process.c new file mode 100644 index 00000000000..283ad4eeec3 --- /dev/null +++ b/eth_save_process.c @@ -0,0 +1,220 @@ +#include "eth_save_process.h" + +#include +#include + +#define TAG "EthSave" + +#define STORAGE_FILE_BUF_LEN 50 + +// fuction spizzhena from archive_favorites.c +static bool storage_read_line(File* file, FuriString* str_result) { + furi_string_reset(str_result); + uint8_t buffer[STORAGE_FILE_BUF_LEN]; + bool result = false; + + do { + uint16_t read_count = storage_file_read(file, buffer, STORAGE_FILE_BUF_LEN); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + for(uint16_t i = 0; i < read_count; i++) { + if(buffer[i] == '\n') { + uint32_t position = storage_file_tell(file); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + position = position - read_count + i + 1; + + storage_file_seek(file, position, true); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + result = true; + break; + } else { + furi_string_push_back(str_result, buffer[i]); + } + } + + if(result || read_count == 0) { + break; + } + } while(true); + + return result; +} + +static bool storage_printf(File* file, const char* format, ...) { + va_list args; + va_start(args, format); + FuriString* fstring = furi_string_alloc_vprintf(format, args); + va_end(args); + if(storage_file_write(file, furi_string_get_cstr(fstring), furi_string_size(fstring)) && + storage_file_write(file, "\n", 1)) { + furi_string_free(fstring); + return true; + } + furi_string_free(fstring); + return false; +} + +static bool storage_write_config(File* file, const EthernetSaveConfig* cfg) { + storage_file_seek(file, 0, true); + storage_file_truncate(file); + + bool result = true; + result = result ? storage_printf( + file, + "mac: %02X-%02X-%02X-%02X-%02X-%02X", + cfg->mac[0], + cfg->mac[1], + cfg->mac[2], + cfg->mac[3], + cfg->mac[4], + cfg->mac[5]) : + result; + result = result ? + storage_printf( + file, "ip: %d.%d.%d.%d", cfg->ip[0], cfg->ip[1], cfg->ip[2], cfg->ip[3]) : + result; + result = + result ? + storage_printf( + file, "mask: %d.%d.%d.%d", cfg->mask[0], cfg->mask[1], cfg->mask[2], cfg->mask[3]) : + result; + result = result ? storage_printf( + file, + "gateway: %d.%d.%d.%d", + cfg->gateway[0], + cfg->gateway[1], + cfg->gateway[2], + cfg->gateway[3]) : + result; + result = + result ? + storage_printf( + file, "dns: %d.%d.%d.%d", cfg->dns[0], cfg->dns[1], cfg->dns[2], cfg->dns[3]) : + result; + result = result ? storage_printf( + file, + "ping_ip: %d.%d.%d.%d", + cfg->ping_ip[0], + cfg->ping_ip[1], + cfg->ping_ip[2], + cfg->ping_ip[3]) : + result; + return result; +} + +static void read_02X(const char* str, uint8_t* byte) { + uint8_t b[2] = {str[0], str[1]}; + + for(int i = 0; i < 2; ++i) { + if('0' <= b[i] && b[i] <= '9') { + b[i] -= '0'; + } else if('A' <= b[i] && b[i] <= 'F') { + b[i] -= 'A' - 0x0A; + } else { + b[i] = 0; + } + } + + *byte = b[1] + (b[0] << 4); +} + +static void set_default_config(EthernetSaveConfig* cfg) { + const uint8_t def_mac[6] = ETHERNET_SAVE_DEFAULT_MAC; + const uint8_t def_ip[4] = ETHERNET_SAVE_DEFAULT_IP; + const uint8_t def_mask[4] = ETHERNET_SAVE_DEFAULT_MASK; + const uint8_t def_gateway[4] = ETHERNET_SAVE_DEFAULT_GATEWAY; + const uint8_t def_dns[4] = ETHERNET_SAVE_DEFAULT_DNS; + const uint8_t def_ping_ip[4] = ETHERNET_SAVE_DEFAULT_PING_IP; + + memcpy(cfg->mac, def_mac, 6); + memcpy(cfg->ip, def_ip, 4); + memcpy(cfg->mask, def_mask, 4); + memcpy(cfg->gateway, def_gateway, 4); + memcpy(cfg->dns, def_dns, 4); + memcpy(cfg->ping_ip, def_ping_ip, 4); +} + +bool storage_read_config(File* file, EthernetSaveConfig* cfg) { + FuriString* fstring = furi_string_alloc(); + + while(storage_read_line(file, fstring)) { + const char* str = furi_string_get_cstr(fstring); + if(!strncmp(str, "mac: ", 5)) { + read_02X(str + strlen("mac: "), &cfg->mac[0]); + read_02X(str + strlen("mac: XX-"), &cfg->mac[1]); + read_02X(str + strlen("mac: XX-XX-"), &cfg->mac[2]); + read_02X(str + strlen("mac: XX-XX-XX-"), &cfg->mac[3]); + read_02X(str + strlen("mac: XX-XX-XX-XX-"), &cfg->mac[4]); + read_02X(str + strlen("mac: XX-XX-XX-XX-XX-"), &cfg->mac[5]); + } else if(!strncmp(str, "ip: ", 4)) { + } else if(!strncmp(str, "mask: ", 6)) { + } else if(!strncmp(str, "gateway: ", 9)) { + } else if(!strncmp(str, "dns: ", 5)) { + } else if(!strncmp(str, "ping_ip: ", 9)) { + } + } + + return true; +} + +void ethernet_save_process_write(const EthernetSaveConfig* config) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + File* file = storage_file_alloc(storage); + + if(!storage_file_open(file, APP_DATA_PATH("config.txt"), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + FURI_LOG_E(TAG, "Failed to open file"); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + + if(!storage_write_config(file, config)) { + FURI_LOG_E(TAG, "Failed to write cpnfig to file"); + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); +} + +void ethernet_save_process_read(EthernetSaveConfig* config) { + set_default_config(config); + + Storage* storage = furi_record_open(RECORD_STORAGE); + + File* file = storage_file_alloc(storage); + + if(!storage_file_open(file, APP_DATA_PATH("config.txt"), FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Failed to open file or file not exists"); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + if(!storage_read_config(file, config)) { + FURI_LOG_E(TAG, "Failed to read config from file"); + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + storage_file_close(file); + + storage_file_free(file); + + furi_record_close(RECORD_STORAGE); +} + +void ehternet_save_process_print(char* str) { +} \ No newline at end of file diff --git a/eth_save_process.h b/eth_save_process.h new file mode 100644 index 00000000000..820a20adb63 --- /dev/null +++ b/eth_save_process.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +typedef struct EthernetSaveConfig { + uint8_t mac[6]; + uint8_t ip[4]; + uint8_t mask[4]; + uint8_t gateway[4]; + uint8_t dns[4]; + uint8_t ping_ip[4]; +} EthernetSaveConfig; + +#define ETHERNET_SAVE_DEFAULT_MAC \ + { 0x10, 0x08, 0xDC, 0x47, 0x47, 0x54 } +#define ETHERNET_SAVE_DEFAULT_IP \ + { 192, 168, 0, 101 } +#define ETHERNET_SAVE_DEFAULT_MASK \ + { 255, 255, 255, 0 } +#define ETHERNET_SAVE_DEFAULT_GATEWAY \ + { 192, 168, 0, 1 } +#define ETHERNET_SAVE_DEFAULT_DNS \ + { 192, 168, 0, 1 } +#define ETHERNET_SAVE_DEFAULT_PING_IP \ + { 8, 8, 8, 8 } + +void ethernet_save_process_write(const EthernetSaveConfig* config); +void ethernet_save_process_read(EthernetSaveConfig* config); + +void ehternet_save_process_print(char* str); diff --git a/eth_view_process.c b/eth_view_process.c index 5862d7ab1bc..e9998f9717a 100644 --- a/eth_view_process.c +++ b/eth_view_process.c @@ -1,4 +1,5 @@ #include "eth_view_process.h" + #include "eth_worker.h" #include "eth_worker_i.h" #include "finik_eth_icons.h" @@ -12,7 +13,7 @@ #define TAG "EthView" -EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type) { +EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type, EthernetSaveConfig* config) { EthViewProcess* evp = malloc(sizeof(EthViewProcess)); evp->type = type; evp->autofill = 1; @@ -26,33 +27,16 @@ EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type) { evp->y += 22; EthViewDrawInit* init = malloc(sizeof(EthViewDrawInit)); memset(init, 0, sizeof(EthViewDrawInit)); - init->mac[0] = 0x10; - init->mac[1] = 0x08; - init->mac[2] = 0xDC; - init->mac[3] = 0x47; - init->mac[4] = 0x47; - init->mac[5] = 0x54; + init->mac = (uint8_t*)config->mac; evp->draw_struct = init; } else if(type == EthWorkerProcessStatic) { evp->y += 22; EthViewDrawStatic* stat = malloc(sizeof(EthViewDrawStatic)); memset(stat, 0, sizeof(EthViewDrawStatic)); - stat->ip[0] = 192; - stat->ip[1] = 168; - stat->ip[2] = 0; - stat->ip[3] = 101; - stat->mask[0] = 255; - stat->mask[1] = 255; - stat->mask[2] = 255; - stat->mask[3] = 0; - stat->gateway[0] = 192; - stat->gateway[1] = 168; - stat->gateway[2] = 0; - stat->gateway[3] = 1; - stat->dns[0] = 192; - stat->dns[1] = 168; - stat->dns[2] = 0; - stat->dns[3] = 1; + stat->ip = config->ip; + stat->mask = config->mask; + stat->gateway = config->gateway; + stat->dns = config->dns; evp->draw_struct = stat; evp->strings_cnt = 20; } else if(type == EthWorkerProcessDHCP) { @@ -61,10 +45,7 @@ EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type) { evp->y += 11; EthViewDrawPing* ping = malloc(sizeof(EthViewDrawPing)); memset(ping, 0, sizeof(EthViewDrawPing)); - ping->ip[0] = 8; - ping->ip[1] = 8; - ping->ip[2] = 8; - ping->ip[3] = 8; + ping->ip = config->ping_ip; evp->draw_struct = ping; evp->strings_cnt = 20; } diff --git a/eth_view_process.h b/eth_view_process.h index 7a642cddfde..3d2cdbcf8a8 100644 --- a/eth_view_process.h +++ b/eth_view_process.h @@ -1,11 +1,12 @@ #pragma once #include "eth_worker.h" +#include "eth_save_process.h" #include #define SCREEN_SYMBOLS_WIDTH 30 -EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type); +EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type, EthernetSaveConfig* config); void ethernet_view_process_free(EthViewProcess* evp); void ethernet_view_process_draw(EthViewProcess* process, Canvas* canvas); @@ -20,19 +21,19 @@ typedef struct EthViewProcessLine { struct EthViewProcess { EthViewProcessLine* fifo; + EthWorkerProcess type; uint8_t strings_cnt; - uint8_t x; - uint8_t y; uint8_t carriage; uint8_t position; uint8_t autofill; uint8_t editing; - EthWorkerProcess type; + uint8_t x; + uint8_t y; void* draw_struct; }; typedef struct EthViewDrawInit { - uint8_t mac[6]; + uint8_t* mac; uint8_t current_octet; } EthViewDrawInit; @@ -43,16 +44,16 @@ typedef enum { EthViewDrawStaticModeDNS } EthViewDrawStaticMode; typedef struct EthViewDrawStatic { - uint8_t ip[4]; - uint8_t mask[4]; - uint8_t gateway[4]; - uint8_t dns[4]; EthViewDrawStaticMode current_mode; + uint8_t* ip; + uint8_t* mask; + uint8_t* gateway; + uint8_t* dns; uint8_t current_digit; uint8_t editing; } EthViewDrawStatic; typedef struct EthViewDrawPing { - uint8_t ip[4]; uint8_t current_digit; + uint8_t* ip; } EthViewDrawPing; \ No newline at end of file diff --git a/eth_worker.c b/eth_worker.c index d9227b24087..fc05ae40882 100644 --- a/eth_worker.c +++ b/eth_worker.c @@ -1,5 +1,6 @@ #include "eth_worker_i.h" #include "eth_worker.h" +#include "eth_save_process.h" #include #include "socket.h" @@ -21,26 +22,35 @@ EthWorker* eth_worker_alloc() { eth_worker_change_state(eth_worker, EthWorkerStateModuleInit); - eth_worker->init_process = ethernet_view_process_malloc(EthWorkerProcessInit); - eth_worker->dhcp_process = ethernet_view_process_malloc(EthWorkerProcessDHCP); - eth_worker->stat_process = ethernet_view_process_malloc(EthWorkerProcessStatic); - eth_worker->ping_process = ethernet_view_process_malloc(EthWorkerProcessPing); - eth_worker->reset_process = ethernet_view_process_malloc(EthWorkerProcessReset); - eth_worker->active_process = eth_worker->init_process; + eth_worker->config = malloc(sizeof(EthernetSaveConfig)); + + ethernet_save_process_read(eth_worker->config); - //eth_worker->callback = eth_worker_change_state; + eth_worker->init_process = + ethernet_view_process_malloc(EthWorkerProcessInit, eth_worker->config); + eth_worker->dhcp_process = + ethernet_view_process_malloc(EthWorkerProcessDHCP, eth_worker->config); + eth_worker->stat_process = + ethernet_view_process_malloc(EthWorkerProcessStatic, eth_worker->config); + eth_worker->ping_process = + ethernet_view_process_malloc(EthWorkerProcessPing, eth_worker->config); + eth_worker->reset_process = + ethernet_view_process_malloc(EthWorkerProcessReset, eth_worker->config); + eth_worker->active_process = eth_worker->init_process; return eth_worker; } void eth_worker_free(EthWorker* eth_worker) { furi_assert(eth_worker); + ethernet_save_process_write(eth_worker->config); furi_thread_free(eth_worker->thread); ethernet_view_process_free(eth_worker->init_process); ethernet_view_process_free(eth_worker->dhcp_process); ethernet_view_process_free(eth_worker->stat_process); ethernet_view_process_free(eth_worker->ping_process); ethernet_view_process_free(eth_worker->reset_process); + free(eth_worker->config); free(eth_worker); } diff --git a/eth_worker_i.h b/eth_worker_i.h index 131d540910c..0f9caeaf7c8 100644 --- a/eth_worker_i.h +++ b/eth_worker_i.h @@ -3,6 +3,7 @@ #include #include "eth_worker.h" #include "eth_view_process.h" +#include "eth_save_process.h" struct EthWorkerNetConf { uint8_t mac[6]; @@ -17,6 +18,7 @@ struct EthWorkerNetConf { struct EthWorker { FuriThread* thread; void* context; + EthernetSaveConfig* config; EthViewProcess* init_process; EthViewProcess* dhcp_process; EthViewProcess* stat_process; diff --git a/finik_eth_app.c b/finik_eth_app.c index 339b48cbb43..ef05ba3754b 100644 --- a/finik_eth_app.c +++ b/finik_eth_app.c @@ -95,6 +95,7 @@ FinikEthApp* finik_eth_app_alloc() { app->view_port = view_port_alloc(); app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + app->eth_worker = eth_worker_alloc(); view_port_draw_callback_set(app->view_port, finik_eth_app_draw_callback, app); view_port_input_callback_set(app->view_port, finik_eth_app_input_callback, app->event_queue); @@ -106,8 +107,6 @@ FinikEthApp* finik_eth_app_alloc() { app->power = furi_record_open(RECORD_POWER); - app->eth_worker = eth_worker_alloc(); - //eth_worker_task(app->eth_worker); return app; @@ -121,6 +120,7 @@ void finik_eth_app_free(FinikEthApp* app) { view_port_free(app->view_port); furi_message_queue_free(app->event_queue); + eth_worker_free(app->eth_worker); furi_record_close(RECORD_GUI); furi_record_close(RECORD_NOTIFICATION);