/
singlwolf
/
Radiola-2S3
Обзор
Документация
Войти
/
singlwolf
/
Radiola-2S3
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/net_work.cpp
564 строки
13 KB
SinglWolf
v1.0.4
07 апр 2026, 08:56
07 апр 2026, 08:56
3a9f57c
Код
Авторство
О чём код?
#include "net_work.h" #include "web_server.h" #include "telnet.h" #include "esp_wifi.h" #include "WiFi.h" #include "eeStorage.h" #include "services.h" #include "screens.h" #include "audioVS.h" #include <NetBIOS.h> #include "esp_sntp.h" #include <ESPmDNS.h> #include <lwip/sockets.h> #include <lwip/netdb.h> #include "lv_i18n.h" #define txtPrintInfo(fmt, ...) \ do \ { \ printf(LOG_COLOR_I); \ printf(fmt, ##__VA_ARGS__); \ printf(LOG_RESET_COLOR "\n"); \ } while (0) // #define txtPrintWarn(fmt, ...) \ do \ { \ printf(LOG_COLOR_W); \ printf(fmt, ##__VA_ARGS__); \ printf(LOG_RESET_COLOR "\n"); \ } while (0) // #define txtPrintError(fmt, ...) \ do \ { \ printf(LOG_COLOR_E); \ printf(fmt, ##__VA_ARGS__); \ printf(LOG_RESET_COLOR "\n"); \ } while (0) Net network; static bool ready = false; static int8_t rssi = -128; static void obtain_time(); static char localIp[20] = {0}; bool updSaveCurrConfig = false; bool updSaveTdaConfig = false; bool breakPlaying = false, Reconnect = false; static uint8_t updateRSSI, CounterSaveCurrConfig, CounterSaveTdaConfig = 0; #define UPDATERSSI 5 #define TIMESAVECURRCONF 20 #define TIMESAVETDACONF 20 // static bool BlinkingDot = true; static bool StateSync = false; static lv_timer_t *updater_clock = nullptr; static lv_timer_t *sync_clock = nullptr; lv_timer_t *blink = nullptr; char oldTimeStr[16] = {}; // void update_blink(lv_timer_t *timer) { lv_obj_t *no_sync = objects.clock_label; bool *user_data = (bool *)lv_timer_get_user_data(timer); if (*user_data) { if (lv_obj_has_flag_any(no_sync, LV_OBJ_FLAG_HIDDEN)) { lv_obj_remove_flag(no_sync, LV_OBJ_FLAG_HIDDEN); } } if (BlinkingDot) // { lv_obj_add_flag(objects.play_state_label, LV_OBJ_FLAG_HIDDEN); if (!user_data) lv_obj_add_flag(no_sync, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_remove_flag(objects.play_state_label, LV_OBJ_FLAG_HIDDEN); if (!user_data) lv_obj_remove_flag(no_sync, LV_OBJ_FLAG_HIDDEN); } BlinkingDot = !BlinkingDot; } // void reset_blink() { if (blink != nullptr) lv_timer_reset(blink); } // void stop_blink() { lv_timer_pause(blink); } // void start_blink(bool sync) { if (blink == nullptr) blink = lv_timer_create(update_blink, 500, &StateSync); if (!lv_timer_get_paused(blink)) lv_timer_pause(blink); lv_timer_resume(blink); } // bool beginWIFI(bool silent = false); // bool Net::getReady() { return ready; } // char *Net::getDate(bool df) { const char *days_week_long[7] = { _("ВОСКРЕСЕНЬЕ"), _("ПОНЕДЕЛЬНИК"), _("ВТОРНИК"), _("СРЕДА"), _("ЧЕТВЕРГ"), _("ПЯТНИЦА"), _("СУББОТА"), }; // static const char *months_long[12] = { _("ЯНВАРЯ"), _("ФЕВРАЛЯ"), _("МАРТА"), _("АПРЕЛЯ"), _("МАЯ"), _("ИЮНЯ"), _("ИЮЛЯ"), _("АВГУСТА"), _("СЕНТЯБРЯ"), _("ОКТЯБРЯ"), _("НОЯБРЯ"), _("ДЕКАБРЯ"), }; char *strdate = reinterpret_cast<char *>(rmalloc(sizeof(char) * 64)); // struct tm timeinfo; getLocalTime(&timeinfo); size_t length = strftime(strdate, 30, "%d ", &timeinfo); strcpy(strdate + length, months_long[timeinfo.tm_mon]); length = strlen(strdate); strcpy(strdate + length, ", "); length = strlen(strdate); if (df) { strcpy(strdate + length, days_week_long[timeinfo.tm_wday]); } else { const char *days_week_short[] = { _("ВС"), _("ПН"), _("ВТ"), _("СР"), _("ЧТ"), _("ПТ"), _("СБ"), // _("ВСЕ"), }; // strcpy(strdate + length, days_week_short[timeinfo.tm_wday]); char y_tmp[14]; strftime(y_tmp, 14, _(". %Y г."), &timeinfo); length = strlen(strdate); strcpy(strdate + length, y_tmp); } return strdate; } //----------------------------------------------------------------- void syncDateTime(lv_timer_t *timer) { if (eeprom.SyncSysDateTime()) { txtPrintInfo("DS3231: %s", _("ВРЕМЯ СИНХРОНИЗИРОВАНО")); } else { print_info("DS3231: %s", _("ошибка чтения времени!")); while (true) { delay(10); } } } void update_clock(lv_timer_t *timer) { char TimeStr[16] = {}; struct tm timeinfo; getLocalTime(&timeinfo); strftime(TimeStr, 16, "%H %M", &timeinfo); if (strcmp(oldTimeStr, TimeStr) != 0) { serv.evtSetClock(); strcpy(oldTimeStr, TimeStr); } if (updateRSSI >= UPDATERSSI) { serv.evtUpateRssi(); updateRSSI = 0; } updateRSSI++; if (updSaveCurrConfig) { CounterSaveCurrConfig++; } if (CounterSaveCurrConfig >= TIMESAVECURRCONF) { updSaveCurrConfig = false; CounterSaveCurrConfig = 0; eeprom.SaveCurrConfig(); serv.evtSetWarn(false); } // if (updSaveTdaConfig) { CounterSaveTdaConfig++; } if (CounterSaveTdaConfig >= TIMESAVETDACONF) { updSaveTdaConfig = false; CounterSaveTdaConfig = 0; eeprom.tda->save_nvs(); serv.evtSetWarn(false); } // if (Config->i2c.bmp) { if (!timeinfo.tm_sec) { serv.startShowSensor(); } } // if (!Config->alarm.on) return; bool alarm = false; if (!Config->alarm.week) { uint8_t i = 0; for (i = 0; i < 7; i++) { if ((Config->alarm.day[i]) && (timeinfo.tm_wday == i)) { alarm = true; break; } } } else { alarm = true; } if (alarm) { if (Config->alarm.hours == timeinfo.tm_hour) { if (Config->alarm.minutes == timeinfo.tm_min) { txtPrintError("ALARM!!!!!!"); } } } } // void Net::save_curr_conf() { updSaveCurrConfig = true; serv.evtSetWarn(true); CounterSaveCurrConfig = 0; } void Net::save_tda_conf() { updSaveTdaConfig = true; serv.evtSetWarn(true); CounterSaveTdaConfig = 0; } /////////////////////////////////////////////////////////////////// char *Net::getIp() { return (localIp); } // void TimeSyncHandle(struct timeval *tv) { if (ee->rts.on) { if (!ee->rts.run) { txtPrintError("DS3231: %s", _("обнаружен сбой питания, синхронизация!")); } else if (!ee->rts.last) { txtPrintWarn("DS3231: %s", _("первый запуск, синхронизация!")); } else { txtPrintInfo("DS3231: %s", _("еженедельная синхронизация!")); } time_t now; struct tm timeinfo; time(&now); localtime_r(&now, &timeinfo); if (!eeprom.RTCwrite(&timeinfo)) { print_info("DS3231: %s", _("ошибка записи времени!")); while (true) { delay(10); } } ee->rts.last = now; eeprom.SaveEEdata(); esp_sntp_stop(); if (sync_clock == nullptr) sync_clock = lv_timer_create(syncDateTime, 3600000, nullptr); } eeprom.time_sync = true; txtPrintInfo("%s", _("ВРЕМЯ СИНХРОНИЗИРОВАНО")); if (updater_clock == nullptr) { updater_clock = lv_timer_create(update_clock, 1000, nullptr); } else { lv_timer_reset(updater_clock); reset_blink(); } start_blink(eeprom.time_sync); } static void obtain_time() { if (esp_sntp_enabled()) esp_sntp_stop(); esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); esp_sntp_setservername(0, ee->ntp[0].c_str()); esp_sntp_setservername(1, ee->ntp[1].c_str()); esp_sntp_setservername(2, ee->ntp[3].c_str()); esp_sntp_setservername(3, ee->ntp[3].c_str()); sntp_set_time_sync_notification_cb(TimeSyncHandle); esp_sntp_init(); // wait for time to be set uint8_t retry = 0; const uint8_t retry_count = 10; if (!ee->rts.on || !ee->rts.run || !ee->rts.last) { while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) { print_info("%s (%u/%u)", _("СИНХРОНИЗАЦИЯ ВРЕМЕНИ"), retry, retry_count); delay(1000); } delay(100); if (!eeprom.time_sync) { txtPrintError("%s", _("ВРЕМЯ НЕ СИНХРОНИЗИРОВАНО")); delay(1000); } } } // set hostname in mDNS esp_err_t Net::setHostname(const char *hostname) { MDNS.end(); if (!MDNS.begin(hostname)) { printf(LOG_COLOR_E "Error setting up MDNS responder!" LOG_RESET_COLOR); printf("\n"); return ESP_ERR_INVALID_RESPONSE; } else { printf(LOG_COLOR_W "mDNS Hostname: %s.local" LOG_RESET_COLOR, hostname); printf("\n"); } MDNS.addService("_http", "_tcp", 80); if (!NBNS.begin(hostname)) { printf(LOG_COLOR_E "Error setting up NBNS hostname!" LOG_RESET_COLOR); printf("\n"); return ESP_ERR_INVALID_RESPONSE; } return ESP_OK; } // int8_t getRSSI() { return rssi; } // void update_rssi() { rssi = WiFi.RSSI(); web.setRSSI(rssi); } // void SoftAP() { txtPrintError("WIFI GO TO AP MODE\n"); network.state = WIFI_AP; delay(10); print_info("Access Point: \"" PROGNAME "\"\nPassword: 1234567890\nAddress: 192.168.4.1\nТочка доступа: \"" PROGNAME "\"\nПароль: 1234567890\nАдрес: 192.168.4.1"); WiFi.mode(WIFI_AP_STA); IPAddress ipAddr(192, 168, 4, 1); IPAddress mask(255, 255, 255, 0); IPAddress dhcp_lease_start(192, 168, 4, 100); WiFi.softAPConfig(ipAddr, ipAddr, mask, dhcp_lease_start); WiFi.softAP(PROGNAME, "1234567890", 2, 0, 1, true); ready = true; } // void Got_IP(WiFiEvent_t event, WiFiEventInfo_t info) { Reconnect = false; if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) { printf(" WiFi %s\n", _("подключен")); ESP_ERROR_CHECK(network.setHostname(ee->host.c_str())); } IPAddress myIP = IPAddress(info.got_ip.ip_info.ip.addr); strcpy(localIp, myIP.toString().c_str()); printf("IP : %s\n", localIp); myIP = IPAddress(info.got_ip.ip_info.netmask.addr); printf("MASK : %s\n", myIP.toString().c_str()); myIP = IPAddress(info.got_ip.ip_info.gw.addr); printf("GATEWAY: %s\n\n", myIP.toString().c_str()); // wifi_country_t myCountry = {}; // esp_err_t err = esp_wifi_get_country(&myCountry); // if (err != ESP_OK) // { // printf("GET Country Code Error: %s\n", esp_err_to_name(err)); // } // else // { // printf("Country Code: %c%c%c\n", myCountry.cc[0], myCountry.cc[1], myCountry.cc[2]); // printf("Start channel: %u\n", myCountry.schan); // printf("Total channel number: %u\n", myCountry.nchan); // printf("Country policy: %d\n", myCountry.policy); // } // delay(500); if (network.state == WIFI_AP) { return; } if (!eeprom.time_sync) { obtain_time(); } if (ee->rts.on && eeprom.time_sync) { updater_clock = lv_timer_create(update_clock, 1000, nullptr); sync_clock = lv_timer_create(syncDateTime, 3600000, nullptr); } start_blink(eeprom.time_sync); network.state = WIFI_STA; ready = true; if (breakPlaying) player.play(eeprom.GetID()); } // #define WIFI_ATTEMPTS 16 // bool beginWIFI(bool silent) { WiFi.mode(WIFI_STA); if (!silent) { print_info("%s %s", _("Подключение к Wi-Fi"), ee->ssid.c_str()); } WiFi.begin(ee->ssid.c_str(), ee->pass.c_str()); uint8_t errcnt = 0; while (WiFi.status() != WL_CONNECTED) { if (!silent) Serial.print("."); delay(500); errcnt++; if (errcnt > WIFI_ATTEMPTS) { errcnt = 0; if (!silent) Serial.println(); return false; break; } } return true; } // void Net::begin() { WiFi.setSleep(false); esp_wifi_set_ps(WIFI_PS_NONE); WiFi.setAutoReconnect(ee->autowifi); // txtPrintWarn("getAutoReconnect(): %s", WiFi.getAutoReconnect() ? "true" : "false"); WiFi.onEvent(Got_IP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP); WiFi.onEvent( [](WiFiEvent_t event, WiFiEventInfo_t info) { // vTaskDelay(10); if (!ee->autowifi || web.needReboot) { web.needReboot = false; txtPrintError("reboot"); fflush(stdout); vTaskDelay(100); WiFi.mode(WIFI_OFF); vTaskDelay(100); ESP.restart(); } else { network.state = WIFI_OFF; txtPrintError("WiFi lost connection.\nReason: %u\n", info.wifi_sta_disconnected.reason); if (!Reconnect) { Serial.printf("Reconnecting to %s...\n", ee->ssid.c_str()); breakPlaying = player.isPlaying(); if (breakPlaying) { player.stop(); } Reconnect = true; WiFi.reconnect(); } } }, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED); if (!ee->ssid.length() || !beginWIFI()) { // WiFi.disconnect(true, true); // delete old config SoftAP(); } web.begin(); telnet.begin(); if (network.state == WIFI_STA) { update_rssi(); } }