mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 15:47:39 +03:00
fixes crash on back
This commit is contained in:
parent
0fa57a6bb4
commit
0313259998
@ -50,6 +50,7 @@ void CalibreWirelessActivity::onEnter() {
|
|||||||
skipOpcode = -1;
|
skipOpcode = -1;
|
||||||
skipExtractedLpath.clear();
|
skipExtractedLpath.clear();
|
||||||
skipExtractedLength = 0;
|
skipExtractedLength = 0;
|
||||||
|
shouldExit = false;
|
||||||
|
|
||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
|
|
||||||
@ -66,30 +67,27 @@ void CalibreWirelessActivity::onEnter() {
|
|||||||
void CalibreWirelessActivity::onExit() {
|
void CalibreWirelessActivity::onExit() {
|
||||||
Activity::onExit();
|
Activity::onExit();
|
||||||
|
|
||||||
// Stop network task FIRST before touching any shared state
|
// Signal tasks to exit gracefully FIRST
|
||||||
// This prevents the task from accessing members while we clean up
|
shouldExit = true;
|
||||||
if (networkTaskHandle) {
|
|
||||||
vTaskDelete(networkTaskHandle);
|
|
||||||
networkTaskHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop display task
|
// Small delay to let tasks see the flag
|
||||||
if (displayTaskHandle) {
|
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||||
vTaskDelete(displayTaskHandle);
|
|
||||||
displayTaskHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now safe to clean up - tasks are stopped
|
// Close TCP to unblock any pending reads in the network task
|
||||||
// Turn off WiFi when exiting
|
|
||||||
WiFi.mode(WIFI_OFF);
|
|
||||||
|
|
||||||
// Stop UDP listening
|
|
||||||
udp.stop();
|
|
||||||
|
|
||||||
// Close TCP client if connected
|
|
||||||
if (tcpClient.connected()) {
|
if (tcpClient.connected()) {
|
||||||
tcpClient.stop();
|
tcpClient.stop();
|
||||||
}
|
}
|
||||||
|
udp.stop();
|
||||||
|
|
||||||
|
// Give tasks more time to notice the closed connection and exit
|
||||||
|
vTaskDelay(250 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
|
// Clear task handles (tasks self-deleted)
|
||||||
|
networkTaskHandle = nullptr;
|
||||||
|
displayTaskHandle = nullptr;
|
||||||
|
|
||||||
|
// Turn off WiFi when exiting
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
|
||||||
// Close any open file
|
// Close any open file
|
||||||
if (currentFile) {
|
if (currentFile) {
|
||||||
@ -122,23 +120,28 @@ void CalibreWirelessActivity::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CalibreWirelessActivity::displayTaskLoop() {
|
void CalibreWirelessActivity::displayTaskLoop() {
|
||||||
while (true) {
|
while (!shouldExit) {
|
||||||
if (updateRequired) {
|
if (updateRequired) {
|
||||||
updateRequired = false;
|
updateRequired = false;
|
||||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||||
render();
|
if (!shouldExit) { // Double-check after acquiring mutex
|
||||||
|
render();
|
||||||
|
}
|
||||||
xSemaphoreGive(renderingMutex);
|
xSemaphoreGive(renderingMutex);
|
||||||
}
|
}
|
||||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
vTaskDelete(nullptr); // Self-delete when done
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibreWirelessActivity::networkTaskLoop() {
|
void CalibreWirelessActivity::networkTaskLoop() {
|
||||||
while (true) {
|
while (!shouldExit) {
|
||||||
xSemaphoreTake(stateMutex, portMAX_DELAY);
|
xSemaphoreTake(stateMutex, portMAX_DELAY);
|
||||||
const auto currentState = state;
|
const auto currentState = state;
|
||||||
xSemaphoreGive(stateMutex);
|
xSemaphoreGive(stateMutex);
|
||||||
|
|
||||||
|
if (shouldExit) break;
|
||||||
|
|
||||||
switch (currentState) {
|
switch (currentState) {
|
||||||
case WirelessState::DISCOVERING:
|
case WirelessState::DISCOVERING:
|
||||||
listenForDiscovery();
|
listenForDiscovery();
|
||||||
@ -160,6 +163,7 @@ void CalibreWirelessActivity::networkTaskLoop() {
|
|||||||
|
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
vTaskDelete(nullptr); // Self-delete when done
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibreWirelessActivity::listenForDiscovery() {
|
void CalibreWirelessActivity::listenForDiscovery() {
|
||||||
@ -802,7 +806,8 @@ void CalibreWirelessActivity::handleSendBook(const std::string& data) {
|
|||||||
currentFileSize = length;
|
currentFileSize = length;
|
||||||
bytesReceived = 0;
|
bytesReceived = 0;
|
||||||
|
|
||||||
Serial.printf("[%lu] [CAL] SEND_BOOK: lpath='%s', length=%zu\n", millis(), lpath.c_str(), length);
|
Serial.printf("[%lu] [CAL] SEND_BOOK: lpath='%s', length=%zu, recvBuffer leftover=%zu\n",
|
||||||
|
millis(), lpath.c_str(), length, recvBuffer.size());
|
||||||
|
|
||||||
setState(WirelessState::RECEIVING);
|
setState(WirelessState::RECEIVING);
|
||||||
setStatus("Receiving: " + filename);
|
setStatus("Receiving: " + filename);
|
||||||
@ -824,11 +829,18 @@ void CalibreWirelessActivity::handleSendBook(const std::string& data) {
|
|||||||
// Check if recvBuffer has leftover data (binary file data that arrived with the JSON)
|
// Check if recvBuffer has leftover data (binary file data that arrived with the JSON)
|
||||||
if (!recvBuffer.empty()) {
|
if (!recvBuffer.empty()) {
|
||||||
size_t toWrite = std::min(recvBuffer.size(), binaryBytesRemaining);
|
size_t toWrite = std::min(recvBuffer.size(), binaryBytesRemaining);
|
||||||
|
Serial.printf("[%lu] [CAL] Writing %zu bytes from recvBuffer (had %zu bytes)\n",
|
||||||
|
millis(), toWrite, recvBuffer.size());
|
||||||
size_t written = currentFile.write(reinterpret_cast<const uint8_t*>(recvBuffer.data()), toWrite);
|
size_t written = currentFile.write(reinterpret_cast<const uint8_t*>(recvBuffer.data()), toWrite);
|
||||||
|
if (written != toWrite) {
|
||||||
|
Serial.printf("[%lu] [CAL] WARNING: file.write returned %zu, expected %zu\n", millis(), written, toWrite);
|
||||||
|
}
|
||||||
bytesReceived += written;
|
bytesReceived += written;
|
||||||
binaryBytesRemaining -= written;
|
binaryBytesRemaining -= written;
|
||||||
recvBuffer = recvBuffer.substr(toWrite);
|
recvBuffer = recvBuffer.substr(written); // Use written, not toWrite!
|
||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
|
Serial.printf("[%lu] [CAL] After recvBuffer write: received=%zu, remaining=%zu, recvBuffer=%zu\n",
|
||||||
|
millis(), bytesReceived, binaryBytesRemaining, recvBuffer.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,11 +868,23 @@ void CalibreWirelessActivity::handleNoop(const std::string& data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CalibreWirelessActivity::receiveBinaryData() {
|
void CalibreWirelessActivity::receiveBinaryData() {
|
||||||
|
static unsigned long lastProgressLog = 0;
|
||||||
|
|
||||||
// Read all available data in a loop to prevent TCP backpressure
|
// Read all available data in a loop to prevent TCP backpressure
|
||||||
// This is important because Calibre sends data continuously
|
// This is important because Calibre sends data continuously
|
||||||
while (binaryBytesRemaining > 0) {
|
while (binaryBytesRemaining > 0) {
|
||||||
|
if (shouldExit) return;
|
||||||
|
|
||||||
const int available = tcpClient.available();
|
const int available = tcpClient.available();
|
||||||
if (available == 0) {
|
if (available == 0) {
|
||||||
|
// Log progress periodically when waiting for data
|
||||||
|
if (millis() - lastProgressLog > 2000) {
|
||||||
|
Serial.printf("[%lu] [CAL] Binary transfer waiting: %zu/%zu bytes (%.1f%%), remaining=%zu\n",
|
||||||
|
millis(), bytesReceived, currentFileSize,
|
||||||
|
currentFileSize > 0 ? (100.0 * bytesReceived / currentFileSize) : 0.0,
|
||||||
|
binaryBytesRemaining);
|
||||||
|
lastProgressLog = millis();
|
||||||
|
}
|
||||||
// Check if connection is still alive
|
// Check if connection is still alive
|
||||||
if (!tcpClient.connected()) {
|
if (!tcpClient.connected()) {
|
||||||
Serial.printf("[%lu] [CAL] Connection lost during binary transfer. Received %zu/%zu bytes\n",
|
Serial.printf("[%lu] [CAL] Connection lost during binary transfer. Received %zu/%zu bytes\n",
|
||||||
|
|||||||
@ -66,6 +66,7 @@ class CalibreWirelessActivity final : public Activity {
|
|||||||
SemaphoreHandle_t renderingMutex = nullptr;
|
SemaphoreHandle_t renderingMutex = nullptr;
|
||||||
SemaphoreHandle_t stateMutex = nullptr;
|
SemaphoreHandle_t stateMutex = nullptr;
|
||||||
bool updateRequired = false;
|
bool updateRequired = false;
|
||||||
|
volatile bool shouldExit = false; // Signal for tasks to exit gracefully
|
||||||
|
|
||||||
WirelessState state = WirelessState::DISCOVERING;
|
WirelessState state = WirelessState::DISCOVERING;
|
||||||
const std::function<void()> onComplete;
|
const std::function<void()> onComplete;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user