Clang format changes for more readability
This commit is contained in:
274
.clang-format
Normal file
274
.clang-format
Normal file
@@ -0,0 +1,274 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCaseArrows: false
|
||||
AlignCaseColons: false
|
||||
AlignConsecutiveTableGenBreakingDAGArgColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveTableGenCondOperatorColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveTableGenDefinitionColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowBreakBeforeNoexceptSpecifier: Never
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseExpressionOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortCompoundRequirementOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakAdjacentStringLiterals: true
|
||||
BreakAfterAttributes: Leave
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakAfterReturnType: None
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakFunctionDefinitionParameters: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: true
|
||||
BreakTemplateDeclarations: MultiLine
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: false
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigits: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigits: 0
|
||||
Hex: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLines:
|
||||
AtEndOfFile: false
|
||||
AtStartOfBlock: true
|
||||
AtStartOfFile: true
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: DeriveLF
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MainIncludeChar: Quote
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: BinPack
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakScopeResolution: 500
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Leave
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
RemoveParentheses: Leave
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SkipMacroDefinitionBody: false
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeJsonColon: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterPlacementOperator: true
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
ExceptDoubleParentheses: false
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TableGenBreakInsideDAGArg: DontBreak
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
VerilogBreakBetweenInstancePorts: true
|
||||
WhitespaceSensitiveMacros:
|
||||
- BOOST_PP_STRINGIZE
|
||||
- CF_SWIFT_NAME
|
||||
- NS_SWIFT_NAME
|
||||
- PP_STRINGIZE
|
||||
- STRINGIZE
|
||||
...
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
# Set this to your ESP32's IP address for local development
|
||||
# Example: VITE_API_BASE=http://192.168.1.100
|
||||
VITE_API_BASE=http://192.168.50.216
|
||||
VITE_API_BASE=http://192.168.50.43
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
#include "appstate.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
internal esp_err_t api_system_info_handler(httpd_req_t *req) {
|
||||
internal esp_err_t api_system_info_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
@@ -21,13 +22,20 @@ internal esp_err_t api_system_info_handler(httpd_req_t *req) {
|
||||
esp_chip_info(&chip_info);
|
||||
|
||||
const char *model = "ESP32-S3";
|
||||
if (chip_info.model == CHIP_ESP32) {
|
||||
if (chip_info.model == CHIP_ESP32)
|
||||
{
|
||||
model = "ESP32";
|
||||
} else if (chip_info.model == CHIP_ESP32S2) {
|
||||
}
|
||||
else if (chip_info.model == CHIP_ESP32S2)
|
||||
{
|
||||
model = "ESP32-S2";
|
||||
} else if (chip_info.model == CHIP_ESP32S3) {
|
||||
}
|
||||
else if (chip_info.model == CHIP_ESP32S3)
|
||||
{
|
||||
model = "ESP32-S3";
|
||||
} else if (chip_info.model == CHIP_ESP32C3) {
|
||||
}
|
||||
else if (chip_info.model == CHIP_ESP32C3)
|
||||
{
|
||||
model = "ESP32-C3";
|
||||
}
|
||||
|
||||
@@ -43,9 +51,12 @@ internal esp_err_t api_system_info_handler(httpd_req_t *req) {
|
||||
cJSON_AddStringToObject(root, "firmware", app_desc->version);
|
||||
|
||||
const char *conn_type = "offline";
|
||||
if (g_Ethernet_Initialized) {
|
||||
if (g_Ethernet_Initialized)
|
||||
{
|
||||
conn_type = "ethernet";
|
||||
} else if (g_Wifi_Initialized) {
|
||||
}
|
||||
else if (g_Wifi_Initialized)
|
||||
{
|
||||
conn_type = "wifi";
|
||||
}
|
||||
cJSON_AddStringToObject(root, "connection", conn_type);
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
internal void restart_timer_callback(void *arg) { esp_restart(); }
|
||||
|
||||
internal esp_err_t api_system_reboot_handler(httpd_req_t *req) {
|
||||
internal esp_err_t api_system_reboot_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
#include "esp_eth_driver.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "ethernet_init.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
// Project includes
|
||||
#include "types.hpp"
|
||||
@@ -41,10 +42,13 @@ internal bool s_ethernet_connected = false;
|
||||
#endif
|
||||
|
||||
void ethernet_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data) {
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP)
|
||||
{
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
if (event->esp_netif != s_eth_netif) {
|
||||
if (event->esp_netif != s_eth_netif)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(kLogEthernet, "Got IPv4 event: Interface \"%s\" address: " IPSTR,
|
||||
@@ -52,31 +56,39 @@ void ethernet_event_handler(void *arg, esp_event_base_t event_base,
|
||||
|
||||
s_current_ip_info = event->ip_info;
|
||||
xSemaphoreGive(s_semph_get_ip_addrs);
|
||||
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_CONNECTED) {
|
||||
}
|
||||
else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_CONNECTED)
|
||||
{
|
||||
ESP_LOGI(kLogEthernet, "Ethernet Link Up");
|
||||
s_eth_link_up = true;
|
||||
if (s_semph_eth_link) {
|
||||
if (s_semph_eth_link)
|
||||
{
|
||||
xSemaphoreGive(s_semph_eth_link);
|
||||
}
|
||||
} else if (event_base == ETH_EVENT &&
|
||||
event_id == ETHERNET_EVENT_DISCONNECTED) {
|
||||
}
|
||||
else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_DISCONNECTED)
|
||||
{
|
||||
ESP_LOGI(kLogEthernet, "Ethernet Link Down");
|
||||
s_eth_link_up = false;
|
||||
}
|
||||
}
|
||||
|
||||
void teardown_ethernet() {
|
||||
if (s_semph_eth_link != nullptr) {
|
||||
void teardown_ethernet()
|
||||
{
|
||||
if (s_semph_eth_link != nullptr)
|
||||
{
|
||||
vSemaphoreDelete(s_semph_eth_link);
|
||||
s_semph_eth_link = nullptr;
|
||||
}
|
||||
|
||||
if (s_semph_get_ip_addrs != nullptr) {
|
||||
if (s_semph_get_ip_addrs != nullptr)
|
||||
{
|
||||
vSemaphoreDelete(s_semph_get_ip_addrs);
|
||||
s_semph_get_ip_addrs = nullptr;
|
||||
}
|
||||
|
||||
if (s_eth_netif) {
|
||||
if (s_eth_netif)
|
||||
{
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP,
|
||||
ðernet_event_handler));
|
||||
@@ -96,7 +108,8 @@ void teardown_ethernet() {
|
||||
esp_netif_deinit();
|
||||
}
|
||||
|
||||
internal esp_err_t connect_ethernet(bool blockUntilIPAcquired) {
|
||||
internal esp_err_t connect_ethernet(bool blockUntilIPAcquired)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
assert(!s_ethernet_connected &&
|
||||
"Ethernet connect called but already connected!");
|
||||
@@ -105,7 +118,8 @@ internal esp_err_t connect_ethernet(bool blockUntilIPAcquired) {
|
||||
|
||||
s_semph_get_ip_addrs = xSemaphoreCreateBinary();
|
||||
s_semph_eth_link = xSemaphoreCreateBinary();
|
||||
if (s_semph_get_ip_addrs == NULL || s_semph_eth_link == NULL) {
|
||||
if (s_semph_get_ip_addrs == NULL || s_semph_eth_link == NULL)
|
||||
{
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
// Connection is split in two steps. First we open the connection and ask for
|
||||
@@ -139,7 +153,8 @@ internal esp_err_t connect_ethernet(bool blockUntilIPAcquired) {
|
||||
// Will teardown connection properly on shutdown
|
||||
ESP_ERROR_CHECK(esp_register_shutdown_handler(&teardown_ethernet));
|
||||
|
||||
if (blockUntilIPAcquired) {
|
||||
if (blockUntilIPAcquired)
|
||||
{
|
||||
ESP_LOGI(kLogEthernet, "Waiting for IP address.");
|
||||
xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY);
|
||||
blink_last_ip_octet();
|
||||
@@ -148,7 +163,8 @@ internal esp_err_t connect_ethernet(bool blockUntilIPAcquired) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void disconnect_ethernet() {
|
||||
void disconnect_ethernet()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
assert(s_ethernet_connected &&
|
||||
"Ethernet disconnect called but not connected!");
|
||||
@@ -159,10 +175,13 @@ void disconnect_ethernet() {
|
||||
ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&teardown_ethernet));
|
||||
}
|
||||
|
||||
internal esp_err_t check_ethernet_connection(uint32_t timeoutSeconds) {
|
||||
internal esp_err_t check_ethernet_connection(uint32_t timeoutSeconds)
|
||||
{
|
||||
// Wait up to 5000ms for the physical link to negotiate
|
||||
if (!s_eth_link_up) {
|
||||
if (!xSemaphoreTake(s_semph_eth_link, pdMS_TO_TICKS(5000))) {
|
||||
if (!s_eth_link_up)
|
||||
{
|
||||
if (!xSemaphoreTake(s_semph_eth_link, pdMS_TO_TICKS(5000)))
|
||||
{
|
||||
ESP_LOGE(kLogEthernet,
|
||||
"No physical Ethernet link detected. Skipping DHCP wait.");
|
||||
return ESP_ERR_INVALID_STATE; // Special error to skip retries
|
||||
@@ -172,10 +191,13 @@ internal esp_err_t check_ethernet_connection(uint32_t timeoutSeconds) {
|
||||
ESP_LOGI(kLogEthernet, "Waiting for IP address for %d seconds.",
|
||||
timeoutSeconds);
|
||||
if (xSemaphoreTake(s_semph_get_ip_addrs,
|
||||
pdMS_TO_TICKS(timeoutSeconds * 1000))) {
|
||||
pdMS_TO_TICKS(timeoutSeconds * 1000)))
|
||||
{
|
||||
blink_last_ip_octet();
|
||||
return ESP_OK;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
@@ -187,25 +209,41 @@ internal esp_netif_t *s_wifi_netif = nullptr;
|
||||
internal SemaphoreHandle_t s_semph_get_wifi_ip_addrs = nullptr;
|
||||
internal SemaphoreHandle_t s_semph_wifi_link = nullptr;
|
||||
internal volatile bool s_wifi_link_up = false;
|
||||
internal TimerHandle_t s_wifi_reconnect_timer = nullptr;
|
||||
|
||||
#ifndef NDEBUG
|
||||
internal bool s_wifi_connected = false;
|
||||
#endif
|
||||
|
||||
// Forward declaration for timer callback
|
||||
internal void wifi_reconnect_timer_cb(TimerHandle_t xTimer);
|
||||
|
||||
void wifi_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data) {
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED)
|
||||
{
|
||||
ESP_LOGI(kLogWifi, "WiFi associated with AP.");
|
||||
s_wifi_link_up = true;
|
||||
if (s_semph_wifi_link) {
|
||||
if (s_semph_wifi_link)
|
||||
{
|
||||
xSemaphoreGive(s_semph_wifi_link);
|
||||
}
|
||||
} else if (event_base == WIFI_EVENT &&
|
||||
event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
ESP_LOGI(kLogWifi, "WiFi disconnected.");
|
||||
}
|
||||
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
|
||||
{
|
||||
ESP_LOGI(kLogWifi, "WiFi disconnected. Scheduling reconnect...");
|
||||
s_wifi_link_up = false;
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
if (s_wifi_reconnect_timer != nullptr)
|
||||
{
|
||||
xTimerStart(s_wifi_reconnect_timer, 0);
|
||||
}
|
||||
}
|
||||
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
|
||||
{
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
if (event->esp_netif != s_wifi_netif) {
|
||||
if (event->esp_netif != s_wifi_netif)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(kLogWifi, "Got IPv4 event: Interface \"%s\" address: " IPSTR,
|
||||
@@ -216,13 +254,29 @@ void wifi_event_handler(void *arg, esp_event_base_t event_base,
|
||||
}
|
||||
}
|
||||
|
||||
void teardown_wifi() {
|
||||
if (s_semph_wifi_link != nullptr) {
|
||||
internal void wifi_reconnect_timer_cb(TimerHandle_t xTimer)
|
||||
{
|
||||
ESP_LOGI(kLogWifi, "Timer expired. Executing esp_wifi_connect()...");
|
||||
esp_wifi_connect();
|
||||
}
|
||||
|
||||
void teardown_wifi()
|
||||
{
|
||||
if (s_wifi_reconnect_timer != nullptr)
|
||||
{
|
||||
xTimerStop(s_wifi_reconnect_timer, 0);
|
||||
xTimerDelete(s_wifi_reconnect_timer, 0);
|
||||
s_wifi_reconnect_timer = nullptr;
|
||||
}
|
||||
|
||||
if (s_semph_wifi_link != nullptr)
|
||||
{
|
||||
vSemaphoreDelete(s_semph_wifi_link);
|
||||
s_semph_wifi_link = nullptr;
|
||||
}
|
||||
|
||||
if (s_semph_get_wifi_ip_addrs != nullptr) {
|
||||
if (s_semph_get_wifi_ip_addrs != nullptr)
|
||||
{
|
||||
vSemaphoreDelete(s_semph_get_wifi_ip_addrs);
|
||||
s_semph_get_wifi_ip_addrs = nullptr;
|
||||
}
|
||||
@@ -234,7 +288,8 @@ void teardown_wifi() {
|
||||
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
||||
&wifi_event_handler);
|
||||
|
||||
if (s_wifi_netif) {
|
||||
if (s_wifi_netif)
|
||||
{
|
||||
esp_wifi_disconnect();
|
||||
esp_wifi_stop();
|
||||
esp_wifi_deinit();
|
||||
@@ -244,7 +299,8 @@ void teardown_wifi() {
|
||||
}
|
||||
|
||||
internal esp_err_t connect_wifi(const char *ssid, const char *password,
|
||||
bool blockUntilIPAcquired) {
|
||||
bool blockUntilIPAcquired)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
assert(!s_wifi_connected && "WiFi connect called but already connected!");
|
||||
s_wifi_connected = true;
|
||||
@@ -252,10 +308,16 @@ internal esp_err_t connect_wifi(const char *ssid, const char *password,
|
||||
|
||||
s_semph_get_wifi_ip_addrs = xSemaphoreCreateBinary();
|
||||
s_semph_wifi_link = xSemaphoreCreateBinary();
|
||||
if (s_semph_get_wifi_ip_addrs == NULL || s_semph_wifi_link == NULL) {
|
||||
if (s_semph_get_wifi_ip_addrs == NULL || s_semph_wifi_link == NULL)
|
||||
{
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
// Create a 5-second timer to avoid spamming connect requests
|
||||
s_wifi_reconnect_timer =
|
||||
xTimerCreate("wifi_recon", pdMS_TO_TICKS(5000), pdFALSE, (void *)0,
|
||||
wifi_reconnect_timer_cb);
|
||||
|
||||
// esp_netif_init() is already called by Ethernet, but safe to call multiple
|
||||
// times or we can assume it's initialized.
|
||||
s_wifi_netif = esp_netif_create_default_wifi_sta();
|
||||
@@ -285,7 +347,8 @@ internal esp_err_t connect_wifi(const char *ssid, const char *password,
|
||||
|
||||
ESP_ERROR_CHECK(esp_register_shutdown_handler(&teardown_wifi));
|
||||
|
||||
if (blockUntilIPAcquired) {
|
||||
if (blockUntilIPAcquired)
|
||||
{
|
||||
ESP_LOGI(kLogWifi, "Waiting for IP address.");
|
||||
xSemaphoreTake(s_semph_get_wifi_ip_addrs, portMAX_DELAY);
|
||||
blink_last_ip_octet();
|
||||
@@ -294,7 +357,8 @@ internal esp_err_t connect_wifi(const char *ssid, const char *password,
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void disconnect_wifi() {
|
||||
void disconnect_wifi()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
assert(s_wifi_connected && "WiFi disconnect called but not connected!");
|
||||
s_wifi_connected = false;
|
||||
@@ -304,36 +368,57 @@ void disconnect_wifi() {
|
||||
ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&teardown_wifi));
|
||||
}
|
||||
|
||||
internal esp_err_t check_wifi_connection(uint32_t timeoutSeconds) {
|
||||
internal esp_err_t check_wifi_connection(uint32_t timeoutSeconds)
|
||||
{
|
||||
// Wait up to 10000ms for the physical link to associate with the AP
|
||||
if (!s_wifi_link_up) {
|
||||
if (!xSemaphoreTake(s_semph_wifi_link, pdMS_TO_TICKS(10000))) {
|
||||
ESP_LOGE(kLogWifi,
|
||||
"Failed to associate with WiFi AP. Skipping DHCP wait.");
|
||||
return ESP_ERR_INVALID_STATE; // Special error to skip retries
|
||||
if (!s_wifi_link_up)
|
||||
{
|
||||
// If the timer isn't already running, kickstart a connection attempt now
|
||||
if (s_wifi_reconnect_timer != nullptr &&
|
||||
xTimerIsTimerActive(s_wifi_reconnect_timer) == pdFALSE)
|
||||
{
|
||||
ESP_LOGI(kLogWifi,
|
||||
"Physical link is down. Requesting immediate AP association...");
|
||||
esp_err_t err = esp_wifi_connect();
|
||||
if (err != ESP_OK && err != ESP_ERR_WIFI_CONN)
|
||||
{
|
||||
ESP_LOGE(kLogWifi, "esp_wifi_connect failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
if (!xSemaphoreTake(s_semph_wifi_link, pdMS_TO_TICKS(10000)))
|
||||
{
|
||||
ESP_LOGE(kLogWifi, "Failed to associate with WiFi AP.");
|
||||
return ESP_ERR_TIMEOUT; // Return timeout so main.cpp triggers a retry
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(kLogWifi, "Waiting for IP address for %d seconds.", timeoutSeconds);
|
||||
if (xSemaphoreTake(s_semph_get_wifi_ip_addrs,
|
||||
pdMS_TO_TICKS(timeoutSeconds * 1000))) {
|
||||
pdMS_TO_TICKS(timeoutSeconds * 1000)))
|
||||
{
|
||||
blink_last_ip_octet();
|
||||
return ESP_OK;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
internal esp_err_t get_ip_info(esp_netif_ip_info_t *ip_info) {
|
||||
internal esp_err_t get_ip_info(esp_netif_ip_info_t *ip_info)
|
||||
{
|
||||
*ip_info = s_current_ip_info;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
internal void blink_last_ip_octet() {
|
||||
internal void blink_last_ip_octet()
|
||||
{
|
||||
esp_netif_ip_info_t ip_info;
|
||||
if (get_ip_info(&ip_info) == ESP_OK) {
|
||||
if (get_ip_info(&ip_info) == ESP_OK)
|
||||
{
|
||||
uint8_t last_octet = (ip_info.ip.addr >> 24) & 0xFF;
|
||||
printf("IP Address: " IPSTR "\n", IP2STR(&ip_info.ip));
|
||||
|
||||
@@ -342,10 +427,12 @@ internal void blink_last_ip_octet() {
|
||||
int t = (last_octet / 10) % 10;
|
||||
int u = last_octet % 10;
|
||||
|
||||
if (h > 0) {
|
||||
if (h > 0)
|
||||
{
|
||||
led_blink_number(h, 255, 255, 255);
|
||||
}
|
||||
if (h > 0 || t > 0) {
|
||||
if (h > 0 || t > 0)
|
||||
{
|
||||
led_blink_number(t, 255, 255, 255);
|
||||
}
|
||||
led_blink_number(u, 255, 255, 255);
|
||||
|
||||
@@ -19,78 +19,107 @@ constexpr uint8 kGZ_Extension_Length = sizeof(".gz") - 1;
|
||||
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
|
||||
#define SCRATCH_BUFSIZE 4096
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
char scratch[SCRATCH_BUFSIZE];
|
||||
} http_server_data_t;
|
||||
|
||||
#ifdef CONFIG_CALENDINK_DEPLOY_WEB_PAGES
|
||||
// Set HTTP response content type according to file extension
|
||||
internal esp_err_t set_content_type_from_file(httpd_req_t *req,
|
||||
const char *filepath) {
|
||||
const char *filepath)
|
||||
{
|
||||
const char *type = "text/plain";
|
||||
if (strstr(filepath, ".html")) {
|
||||
if (strstr(filepath, ".html"))
|
||||
{
|
||||
type = "text/html";
|
||||
} else if (strstr(filepath, ".js")) {
|
||||
}
|
||||
else if (strstr(filepath, ".js"))
|
||||
{
|
||||
type = "application/javascript";
|
||||
} else if (strstr(filepath, ".css")) {
|
||||
}
|
||||
else if (strstr(filepath, ".css"))
|
||||
{
|
||||
type = "text/css";
|
||||
} else if (strstr(filepath, ".png")) {
|
||||
}
|
||||
else if (strstr(filepath, ".png"))
|
||||
{
|
||||
type = "image/png";
|
||||
} else if (strstr(filepath, ".ico")) {
|
||||
}
|
||||
else if (strstr(filepath, ".ico"))
|
||||
{
|
||||
type = "image/x-icon";
|
||||
} else if (strstr(filepath, ".svg")) {
|
||||
}
|
||||
else if (strstr(filepath, ".svg"))
|
||||
{
|
||||
type = "text/xml";
|
||||
}
|
||||
return httpd_resp_set_type(req, type);
|
||||
}
|
||||
|
||||
// Handler to serve static files from LittleFS
|
||||
internal esp_err_t static_file_handler(httpd_req_t *req) {
|
||||
internal esp_err_t static_file_handler(httpd_req_t *req)
|
||||
{
|
||||
char filepath[FILE_PATH_MAX];
|
||||
|
||||
// Construct real file path
|
||||
strlcpy(filepath, "/www", sizeof(filepath));
|
||||
if (req->uri[strlen(req->uri) - 1] == '/') {
|
||||
if (req->uri[strlen(req->uri) - 1] == '/')
|
||||
{
|
||||
strlcat(filepath, "/index.html", sizeof(filepath));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcat(filepath, req->uri, sizeof(filepath));
|
||||
}
|
||||
|
||||
// Default to index.html if file doesn't exist (SPA routing support)
|
||||
struct stat file_stat;
|
||||
if (stat(filepath, &file_stat) == -1) {
|
||||
if (stat(filepath, &file_stat) == -1)
|
||||
{
|
||||
// Try gzipped first, then fallback to index.html
|
||||
char filepath_gz[FILE_PATH_MAX + kGZ_Extension_Length];
|
||||
snprintf(filepath_gz, sizeof(filepath_gz), "%s.gz", filepath);
|
||||
if (stat(filepath_gz, &file_stat) == 0) {
|
||||
if (stat(filepath_gz, &file_stat) == 0)
|
||||
{
|
||||
strlcpy(filepath, filepath_gz, sizeof(filepath));
|
||||
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGW(TAG, "File not found: %s, falling back to index.html", filepath);
|
||||
snprintf(filepath, sizeof(filepath), "%s/index.html", "/www");
|
||||
if (stat(filepath, &file_stat) == -1) {
|
||||
if (stat(filepath, &file_stat) == -1)
|
||||
{
|
||||
// If index.html doesn't exist, try index.html.gz
|
||||
snprintf(filepath_gz, sizeof(filepath_gz), "%s/index.html.gz", "/www");
|
||||
if (stat(filepath_gz, &file_stat) == 0) {
|
||||
if (stat(filepath_gz, &file_stat) == 0)
|
||||
{
|
||||
strlcpy(filepath, filepath_gz, sizeof(filepath));
|
||||
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "index.html not found too.");
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since ESP32 handles .gz transparently if we tell it to via headers
|
||||
// If we requested explicitly a .gz file, set the header
|
||||
if (strstr(filepath, ".gz")) {
|
||||
if (strstr(filepath, ".gz"))
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||
}
|
||||
}
|
||||
|
||||
int fd = open(filepath, O_RDONLY, 0);
|
||||
if (fd == -1) {
|
||||
if (fd == -1)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to open file: %s", filepath);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
|
||||
"Failed to read existing file");
|
||||
@@ -103,12 +132,17 @@ internal esp_err_t static_file_handler(httpd_req_t *req) {
|
||||
char *chunk = rest_context->scratch;
|
||||
ssize_t read_bytes;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
read_bytes = read(fd, chunk, SCRATCH_BUFSIZE);
|
||||
if (read_bytes == -1) {
|
||||
if (read_bytes == -1)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to read file: %s", filepath);
|
||||
} else if (read_bytes > 0) {
|
||||
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK) {
|
||||
}
|
||||
else if (read_bytes > 0)
|
||||
{
|
||||
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK)
|
||||
{
|
||||
close(fd);
|
||||
ESP_LOGE(TAG, "File sending failed!");
|
||||
httpd_resp_sendstr_chunk(req, NULL); // Abort sending
|
||||
@@ -125,7 +159,8 @@ internal esp_err_t static_file_handler(httpd_req_t *req) {
|
||||
#endif
|
||||
|
||||
// Handler for CORS Preflight OPTIONS requests
|
||||
internal esp_err_t cors_options_handler(httpd_req_t *req) {
|
||||
internal esp_err_t cors_options_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
|
||||
@@ -134,10 +169,12 @@ internal esp_err_t cors_options_handler(httpd_req_t *req) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
internal httpd_handle_t start_webserver(void) {
|
||||
internal httpd_handle_t start_webserver(void)
|
||||
{
|
||||
http_server_data_t *rest_context =
|
||||
(http_server_data_t *)calloc(1, sizeof(http_server_data_t));
|
||||
if (rest_context == NULL) {
|
||||
if (rest_context == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG, "No memory for rest context");
|
||||
return NULL;
|
||||
}
|
||||
@@ -149,7 +186,8 @@ internal httpd_handle_t start_webserver(void) {
|
||||
httpd_handle_t server = NULL;
|
||||
ESP_LOGI(TAG, "Starting HTTP Server on port: '%d'", config.server_port);
|
||||
|
||||
if (httpd_start(&server, &config) == ESP_OK) {
|
||||
if (httpd_start(&server, &config) == ESP_OK)
|
||||
{
|
||||
// Register CORS OPTIONS handler for API routes
|
||||
httpd_uri_t cors_options_uri = {.uri = "/api/*",
|
||||
.method = HTTP_OPTIONS,
|
||||
@@ -178,8 +216,10 @@ internal httpd_handle_t start_webserver(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
internal void stop_webserver(httpd_handle_t server) {
|
||||
if (server) {
|
||||
internal void stop_webserver(httpd_handle_t server)
|
||||
{
|
||||
if (server)
|
||||
{
|
||||
httpd_stop(server);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
// Could be a config but its the GPIO on my ESP32-S3-ETH
|
||||
#define LED_GPIO GPIO_NUM_21
|
||||
|
||||
enum class led_status : uint8 {
|
||||
enum class led_status : uint8
|
||||
{
|
||||
ConnectingEthernet,
|
||||
ConnectingWifi,
|
||||
ReadyEthernet,
|
||||
@@ -17,7 +18,8 @@ enum class led_status : uint8 {
|
||||
|
||||
internal led_strip_handle_t led_strip;
|
||||
|
||||
internal void setup_led(void) {
|
||||
internal void setup_led(void)
|
||||
{
|
||||
/* LED strip initialization with the GPIO and pixels number*/
|
||||
led_strip_config_t strip_config = {};
|
||||
strip_config.strip_gpio_num = LED_GPIO;
|
||||
@@ -34,8 +36,10 @@ internal void setup_led(void) {
|
||||
|
||||
internal void destroy_led(void) { led_strip_clear(led_strip); }
|
||||
|
||||
internal void set_led_status(led_status status) {
|
||||
switch (status) {
|
||||
internal void set_led_status(led_status status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case led_status::ConnectingEthernet:
|
||||
led_strip_set_pixel(led_strip, 0, 255, 165, 0);
|
||||
break;
|
||||
@@ -54,9 +58,12 @@ internal void set_led_status(led_status status) {
|
||||
}
|
||||
led_strip_refresh(led_strip);
|
||||
}
|
||||
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b) {
|
||||
if (n <= 0) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
if (n <= 0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
led_strip_set_pixel(led_strip, 0, r, g, b);
|
||||
led_strip_refresh(led_strip);
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
@@ -67,7 +74,8 @@ internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
led_strip_set_pixel(led_strip, 0, r, g, b);
|
||||
led_strip_refresh(led_strip);
|
||||
vTaskDelay(pdMS_TO_TICKS(300));
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
internal constexpr bool kBlockUntilEthernetEstablished = false;
|
||||
|
||||
extern "C" void app_main() {
|
||||
extern "C" void app_main()
|
||||
{
|
||||
printf("Hello, Worldi!\n");
|
||||
|
||||
httpd_handle_t web_server = NULL;
|
||||
@@ -35,25 +36,30 @@ extern "C" void app_main() {
|
||||
set_led_status(led_status::ConnectingEthernet);
|
||||
g_Ethernet_Initialized = true;
|
||||
esp_err_t result = connect_ethernet(kBlockUntilEthernetEstablished);
|
||||
if (result != ESP_OK) {
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
set_led_status(led_status::Failed);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
// Check for ethernet connection until its made
|
||||
if (!kBlockUntilEthernetEstablished) {
|
||||
if (!kBlockUntilEthernetEstablished)
|
||||
{
|
||||
uint8 retries = 1;
|
||||
do {
|
||||
do
|
||||
{
|
||||
set_led_status(led_status::ConnectingEthernet);
|
||||
result = check_ethernet_connection(retries);
|
||||
|
||||
if (result == ESP_ERR_INVALID_STATE) {
|
||||
if (result == ESP_ERR_INVALID_STATE)
|
||||
{
|
||||
printf("Ethernet cable not plugged in, skipping retries.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != ESP_OK) {
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
set_led_status(led_status::Failed);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
@@ -63,7 +69,8 @@ extern "C" void app_main() {
|
||||
retries <= CONFIG_CALENDINK_ETH_RETRIES);
|
||||
}
|
||||
|
||||
if (result != ESP_OK) {
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
printf("Ethernet failed, trying wifi\n");
|
||||
disconnect_ethernet();
|
||||
g_Ethernet_Initialized = false;
|
||||
@@ -73,19 +80,23 @@ extern "C" void app_main() {
|
||||
result =
|
||||
connect_wifi(CONFIG_CALENDINK_WIFI_SSID, CONFIG_CALENDINK_WIFI_PASSWORD,
|
||||
kBlockUntilEthernetEstablished);
|
||||
if (result != ESP_OK) {
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
set_led_status(led_status::Failed);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
if (!kBlockUntilEthernetEstablished) {
|
||||
if (!kBlockUntilEthernetEstablished)
|
||||
{
|
||||
uint8 retries = 1;
|
||||
do {
|
||||
do
|
||||
{
|
||||
set_led_status(led_status::ConnectingWifi);
|
||||
result = check_wifi_connection(retries);
|
||||
|
||||
if (result != ESP_OK) {
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
set_led_status(led_status::Failed);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
@@ -95,14 +106,17 @@ extern "C" void app_main() {
|
||||
retries <= CONFIG_CALENDINK_WIFI_RETRIES);
|
||||
}
|
||||
|
||||
if (result != ESP_OK) {
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
printf("Wifi failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
set_led_status(led_status::ReadyWifi);
|
||||
printf("Will use Wifi!\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
set_led_status(led_status::ReadyEthernet);
|
||||
printf("Will use Ethernet!\n");
|
||||
}
|
||||
@@ -113,23 +127,27 @@ extern "C" void app_main() {
|
||||
web_server = start_webserver();
|
||||
|
||||
// Keep the main task alive indefinitely
|
||||
while (true) {
|
||||
while (true)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
shutdown:
|
||||
printf("Shutting down.\n");
|
||||
|
||||
if (web_server) {
|
||||
if (web_server)
|
||||
{
|
||||
stop_webserver(web_server);
|
||||
web_server = NULL;
|
||||
}
|
||||
|
||||
if (g_Ethernet_Initialized) {
|
||||
if (g_Ethernet_Initialized)
|
||||
{
|
||||
disconnect_ethernet();
|
||||
g_Ethernet_Initialized = false;
|
||||
}
|
||||
if (g_Wifi_Initialized) {
|
||||
if (g_Wifi_Initialized)
|
||||
{
|
||||
disconnect_wifi();
|
||||
g_Wifi_Initialized = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user