diff --git a/data/webui/device_specific/BUILD_ATARI/autorun.atr b/data/webui/device_specific/BUILD_ATARI/autorun.atr index bf697e36f..8b99e742a 100644 Binary files a/data/webui/device_specific/BUILD_ATARI/autorun.atr and b/data/webui/device_specific/BUILD_ATARI/autorun.atr differ diff --git a/lib/bus/sio/sio.cpp b/lib/bus/sio/sio.cpp index d52d91200..6d04dd889 100755 --- a/lib/bus/sio/sio.cpp +++ b/lib/bus/sio/sio.cpp @@ -226,7 +226,11 @@ void systemBus::_sio_process_cmd() if (it != _daisyChain.end()) { _activeDev = it->second; + // heap_trace_start(HEAP_TRACE_LEAKS); it->second->sio_process(tempFrame.commanddata, tempFrame.checksum); + // heap_trace_stop(); + // Debug_printv("heap trace follows."); + // heap_trace_dump(); } } } diff --git a/lib/device/rs232/modem.cpp b/lib/device/rs232/modem.cpp index 12b8e4a2a..d15739036 100755 --- a/lib/device/rs232/modem.cpp +++ b/lib/device/rs232/modem.cpp @@ -160,9 +160,6 @@ void rs232Modem::rs232_poll_3(uint8_t device, uint8_t aux1, uint8_t aux2) if (respond == false) return; - // Get size of handler - int filesize = fnSystem.load_firmware(FIRMWARE_850HANDLER, NULL); - // Simply return (without ACK) if we failed to get this if (filesize < 0) return; @@ -258,7 +255,6 @@ void rs232Modem::rs232_send_firmware(uint8_t loadcommand) // Load firmware from file uint8_t *code; - int codesize = fnSystem.load_firmware(firmware, &code); // NAK if we failed to get this if (codesize < 0 || code == NULL) { diff --git a/lib/device/sio/fuji.cpp b/lib/device/sio/fuji.cpp index eab7d11e3..2e46b938e 100644 --- a/lib/device/sio/fuji.cpp +++ b/lib/device/sio/fuji.cpp @@ -1868,4 +1868,4 @@ std::string sioFuji::get_host_prefix(int host_slot) return _fnHosts[host_slot].get_prefix(); } -#endif /* BUILD_ATARI */ \ No newline at end of file +#endif /* BUILD_ATARI */ diff --git a/lib/device/sio/network.cpp b/lib/device/sio/network.cpp index b33fb9221..8badb1545 100755 --- a/lib/device/sio/network.cpp +++ b/lib/device/sio/network.cpp @@ -190,7 +190,7 @@ void sioNetwork::sio_close() else sio_complete(); - Debug_printf("Before protocol delete %lu\n",esp_get_free_heap_size()); + Debug_printv("Before protocol delete %lu\n",esp_get_free_internal_heap_size()); // Delete the protocol object delete protocol; protocol = nullptr; @@ -198,7 +198,7 @@ void sioNetwork::sio_close() if (json != nullptr) delete json; - Debug_printf("After protocol delete %lu\n",esp_get_free_heap_size()); + Debug_printv("After protocol delete %lu\n",esp_get_free_internal_heap_size()); } /** @@ -245,6 +245,7 @@ void sioNetwork::sio_read() // And send off to the computer bus_to_computer((uint8_t *)receiveBuffer->data(), num_bytes, err); receiveBuffer->erase(0, num_bytes); + receiveBuffer->shrink_to_fit(); } /** diff --git a/lib/fnjson/fnjson.cpp b/lib/fnjson/fnjson.cpp index 8d79d5107..60f1fb4f8 100644 --- a/lib/fnjson/fnjson.cpp +++ b/lib/fnjson/fnjson.cpp @@ -40,7 +40,7 @@ FNJSON::~FNJSON() /** * Specify line ending */ -void FNJSON::setLineEnding(string _lineEnding) +void FNJSON::setLineEnding(const string &_lineEnding) { lineEnding = _lineEnding; } @@ -57,12 +57,12 @@ void FNJSON::setProtocol(NetworkProtocol *newProtocol) /** * Set read query string */ -void FNJSON::setReadQuery(string queryString, uint8_t queryParam) +void FNJSON::setReadQuery(const string &queryString, uint8_t queryParam) { _queryString = queryString; _queryParam = queryParam; _item = resolveQuery(); - json_bytes_remaining=readValueLen(); + json_bytes_remaining = readValueLen(); } /** @@ -88,9 +88,8 @@ string FNJSON::processString(string in) if (endpos != string::npos) { - in.erase(startpos,endpos-startpos); + in.erase(startpos, endpos - startpos); } - } #ifdef BUILD_IEC @@ -105,78 +104,74 @@ string FNJSON::processString(string in) */ string FNJSON::getValue(cJSON *item) { + stringstream ss; + if (cJSON_IsString(item)) { - stringstream ss; - Debug_printf("S: [cJSON_IsString] %s\r\n",cJSON_GetStringValue(item)); + Debug_printf("S: [cJSON_IsString] %s\r\n", cJSON_GetStringValue(item)); - ss << cJSON_GetStringValue(item); - - #ifdef BUILD_ATARI +#ifdef BUILD_ATARI // SIO AUX bits 0+1 control the mapping // Bit 0=0 - don't touch the characters // Bit 0=1 - convert the characters when possible // Bit 1=0 - convert to generic ASCII/ATASCII (no font change needed) // Bit 1=1 - convert to ATASCII international charset (need to be switched on ATARI, i.e via POKE 756,204) - + // SIO AUX2 Bit 1 set? if ((_queryParam & 1) != 0) { // yes, map special characters - string str_utf8mapping = ss.str(); + string str_utf8mapping = ss.str(); Debug_printf("S: [Mapping->ATARI]\r\n"); // SIO AUX2 Bit 2 set? if ((_queryParam & 2) != 0) { // yes, mapping to international charset - string mapFrom[] = { "á", "ù", "Ñ", "É", "ç", "ô", "ò", "ì", "£", "ï", "ü", "ä", "Ö", "ú", "ó", "ö", "Ü", "â", "û", "î", "é", "è", "ñ", "ê", "å", "à", "Å", "¡", "Ä", "ß" }; - string mapTo[] = { "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x60", "\x7b", "ss" }; - int elementCount = sizeof(mapFrom)/sizeof(mapFrom[0]); - for (int elementIndex=0; elementIndex < elementCount; elementIndex++) - if(str_utf8mapping.find(mapFrom[elementIndex]) != std::string::npos) + string mapFrom[] = {"á", "ù", "Ñ", "É", "ç", "ô", "ò", "ì", "£", "ï", "ü", "ä", "Ö", "ú", "ó", "ö", "Ü", "â", "û", "î", "é", "è", "ñ", "ê", "å", "à", "Å", "¡", "Ä", "ß"}; + string mapTo[] = {"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x60", "\x7b", "ss"}; + int elementCount = sizeof(mapFrom) / sizeof(mapFrom[0]); + for (int elementIndex = 0; elementIndex < elementCount; elementIndex++) + if (str_utf8mapping.find(mapFrom[elementIndex]) != std::string::npos) str_utf8mapping.replace(str_utf8mapping.find(mapFrom[elementIndex]), string(mapFrom[elementIndex]).size(), mapTo[elementIndex]); } else { // no, mapping to normal ASCI (workaround) - string mapFrom[] = { "Ä", "Ö", "Ü", "ä", "ö", "ü", "ß", "é", "è", "á", "à", "ó", "ò", "ú", "ù" }; - string mapTo[] = { "Ae", "Oe", "Ue", "ae", "oe", "ue", "ss", "e", "e", "a", "a", "o", "o", "u", "u" }; - int elementCount = sizeof(mapFrom)/sizeof(mapFrom[0]); - for (int elementIndex=0; elementIndex < elementCount; elementIndex++) - if(str_utf8mapping.find(mapFrom[elementIndex]) != std::string::npos) + string mapFrom[] = {"Ä", "Ö", "Ü", "ä", "ö", "ü", "ß", "é", "è", "á", "à", "ó", "ò", "ú", "ù"}; + string mapTo[] = {"Ae", "Oe", "Ue", "ae", "oe", "ue", "ss", "e", "e", "a", "a", "o", "o", "u", "u"}; + int elementCount = sizeof(mapFrom) / sizeof(mapFrom[0]); + for (int elementIndex = 0; elementIndex < elementCount; elementIndex++) + if (str_utf8mapping.find(mapFrom[elementIndex]) != std::string::npos) str_utf8mapping.replace(str_utf8mapping.find(mapFrom[elementIndex]), string(mapFrom[elementIndex]).size(), mapTo[elementIndex]); } ss.str(str_utf8mapping); - Debug_printf("S: [Mapping->ATARI] %s\r\n",ss.str().c_str()); + Debug_printf("S: [Mapping->ATARI] %s\r\n", ss.str().c_str()); } - #endif - - return processString(ss.str() + lineEnding); +#endif + ss << processString(cJSON_GetStringValue(item) + lineEnding); } else if (cJSON_IsBool(item)) { - Debug_printf("S: [cJSON_IsBool] %s\r\n",cJSON_IsTrue(item) ? "true" : "false"); + Debug_printf("S: [cJSON_IsBool] %s\r\n", cJSON_IsTrue(item) ? "true" : "false"); if (cJSON_IsTrue(item)) - return "TRUE" + lineEnding; + ss << "TRUE" + lineEnding; else if (cJSON_IsFalse(item)) - return "FALSE" + lineEnding; + ss << "FALSE" + lineEnding; } else if (cJSON_IsNull(item)) { Debug_printf("S: [cJSON_IsNull]\r\n"); - return "NULL" + lineEnding; + ss << "NULL" + lineEnding; } else if (cJSON_IsNumber(item)) { - stringstream ss; - - Debug_printf("S: [cJSON_IsNumber] %f\r\n",cJSON_GetNumberValue(item)); + Debug_printf("S: [cJSON_IsNumber] %f\r\n", cJSON_GetNumberValue(item)); // Is the number an integer? if (floor(cJSON_GetNumberValue(item)) == cJSON_GetNumberValue(item)) @@ -187,51 +182,43 @@ string FNJSON::getValue(cJSON *item) else { // no, return as double with max. 10 digits - ss << setprecision(10)<child; do { - ret += string(item->string) + lineEnding + getValue(item); + ss << item->string + lineEnding + getValue(item); } while ((item = item->next) != NULL); - - return ret; } else if (cJSON_IsArray(item)) { cJSON *child = item->child; - string ret; - do { - ret += getValue(child); + ss << getValue(child); } while ((child = child->next) != NULL); - - return ret; } - - return "UNKNOWN" + lineEnding; + else + ss << "UNKNOWN" + lineEnding; + + return ss.str(); } /** * Return requested value */ bool FNJSON::readValue(uint8_t *rx_buf, unsigned short len) -{ +{ if (_item == nullptr) return true; // error - string ret = getValue(_item); - - memcpy(rx_buf, ret.data(), len); + memcpy(rx_buf, getValue(_item).data(), len); return false; // no error. } @@ -253,7 +240,6 @@ int FNJSON::readValueLen() bool FNJSON::parse() { NetworkStatus ns; - _parseBuffer.clear(); if (_json != nullptr) cJSON_Delete(_json); @@ -275,7 +261,7 @@ bool FNJSON::parse() vTaskDelay(10); } - Debug_printf("S: %s\r\n",_parseBuffer.c_str()); + Debug_printf("S: %s\r\n", _parseBuffer.c_str()); _json = cJSON_Parse(_parseBuffer.c_str()); if (_json == nullptr) @@ -284,18 +270,12 @@ bool FNJSON::parse() return false; } - char* debugOutput = cJSON_Print(_json); - if (debugOutput != nullptr) { - Debug_printf("Parsed JSON: %s\r\n", debugOutput); - cJSON_free(debugOutput); - } - return true; } bool FNJSON::status(NetworkStatus *s) { - Debug_printf("FNJSON::status(%u) %s\r\n",json_bytes_remaining,getValue(_item).c_str()); + Debug_printf("FNJSON::status(%u) %s\r\n", json_bytes_remaining, getValue(_item).c_str()); s->connected = true; s->rxBytesWaiting = json_bytes_remaining; s->error = json_bytes_remaining == 0 ? 136 : 0; diff --git a/lib/fnjson/fnjson.h b/lib/fnjson/fnjson.h index eac5dc0ef..a19a78ae9 100644 --- a/lib/fnjson/fnjson.h +++ b/lib/fnjson/fnjson.h @@ -19,9 +19,9 @@ class FNJSON FNJSON(); virtual ~FNJSON(); - void setLineEnding(string _lineEnding); + void setLineEnding(const string &_lineEnding); void setProtocol(NetworkProtocol *newProtocol); - void setReadQuery(string queryString, uint8_t queryParam); + void setReadQuery(const string &queryString, uint8_t queryParam); cJSON *resolveQuery(); bool status(NetworkStatus *status); diff --git a/lib/ftp/fnFTP.cpp b/lib/ftp/fnFTP.cpp index 17ae4ea43..f15072e7f 100644 --- a/lib/ftp/fnFTP.cpp +++ b/lib/ftp/fnFTP.cpp @@ -652,7 +652,7 @@ fnFTP::~fnFTP() delete data; } -bool fnFTP::login(string _username, string _password, string _hostname, unsigned short _port) +bool fnFTP::login(const string &_username, const string &_password, const string &_hostname, unsigned short _port) { username = _username; password = _password; diff --git a/lib/ftp/fnFTP.h b/lib/ftp/fnFTP.h index 96fbd5b30..fdaadb0d7 100644 --- a/lib/ftp/fnFTP.h +++ b/lib/ftp/fnFTP.h @@ -42,7 +42,7 @@ class fnFTP * @param port port to login (default 21) * @return TRUE on error, FALSE on success */ - bool login(string _username, string _password, string _hostname, unsigned short _port = 21); + bool login(const string &_username, const string &_password, const string &_hostname, unsigned short _port = 21); /** * Log out of FTP server, closes control connection. diff --git a/lib/hardware/fnSystem.cpp b/lib/hardware/fnSystem.cpp index 0e61ff241..cc3cfc2e5 100755 --- a/lib/hardware/fnSystem.cpp +++ b/lib/hardware/fnSystem.cpp @@ -527,9 +527,9 @@ uint32_t SystemManager::get_psram_size() /* If buffer is NULL, simply returns size of file. Otherwise - allocates buffer for reading file contents. Buffer must be freed by caller. + allocates buffer for reading file contents. Buffer must be managed by caller. */ -int SystemManager::load_firmware(const char *filename, uint8_t **buffer) +int SystemManager::load_firmware(const char *filename, uint8_t *buffer) { Debug_printf("load_firmware '%s'\r\n", filename); @@ -551,25 +551,13 @@ int SystemManager::load_firmware(const char *filename, uint8_t **buffer) } int bytes_read = -1; - uint8_t *result = (uint8_t *)malloc(file_size); - if (result == NULL) + if (buffer == NULL) { - Debug_println("load_firmware failed to malloc"); + Debug_println("load_firmware passed in buffer was NULL"); } else { - bytes_read = fread(result, 1, file_size, f); - if (bytes_read == file_size) - { - *buffer = result; - } - else - { - free(result); - bytes_read = -1; - - Debug_printf("load_firmware only read %u bytes out of %u - failing\r\n", bytes_read, file_size); - } + bytes_read = fread(buffer, 1, file_size, f); } fclose(f); diff --git a/lib/hardware/fnSystem.h b/lib/hardware/fnSystem.h index 0a37b2dec..dae88bd98 100644 --- a/lib/hardware/fnSystem.h +++ b/lib/hardware/fnSystem.h @@ -120,7 +120,7 @@ class SystemManager void delete_tempfile(FileSystem *fs, const char *filename); void delete_tempfile(const char *filename); - int load_firmware(const char *filename, uint8_t **buffer); + int load_firmware(const char *filename, uint8_t *buffer); void debug_print_tasks(); void check_hardware_ver(); diff --git a/lib/hardware/fnUART.cpp b/lib/hardware/fnUART.cpp index 1744d0666..dfa2ba89c 100644 --- a/lib/hardware/fnUART.cpp +++ b/lib/hardware/fnUART.cpp @@ -310,7 +310,7 @@ size_t UARTManager::print(const char *str) ; } -size_t UARTManager::print(std::string str) +size_t UARTManager::print(const std::string &str) { if (!_initialized) return -1; diff --git a/lib/hardware/fnUART.h b/lib/hardware/fnUART.h index 955c9ebf9..547c18c19 100644 --- a/lib/hardware/fnUART.h +++ b/lib/hardware/fnUART.h @@ -53,7 +53,7 @@ class UARTManager //size_t print(const char *format, ...); size_t print(const char *str); - size_t print(std::string str); + size_t print(const std::string &str); size_t print(int n, int base = 10); size_t print(unsigned int n, int base = 10); size_t print(long n, int base = 10); diff --git a/lib/http/fnHttpClient.cpp b/lib/http/fnHttpClient.cpp index 97f84df19..4cce757dd 100755 --- a/lib/http/fnHttpClient.cpp +++ b/lib/http/fnHttpClient.cpp @@ -11,7 +11,6 @@ #include "utils.h" - using namespace fujinet; #define HTTPCLIENT_WAIT_FOR_CONSUMER_TASK 20000 // 20s @@ -31,8 +30,9 @@ fnHttpClient::~fnHttpClient() if (_handle != nullptr) { - Debug_printf("esp_http_client_cleanup(%p)\r\n",_handle); - Debug_printf("free heap: %lu\r\n",esp_get_free_heap_size()); + Debug_printf("esp_http_client_cleanup(%p)\r\n", _handle); + Debug_printf("free heap: %lu\r\n", esp_get_free_heap_size()); + Debug_printv("free low heap: %lu\r\n",esp_get_free_internal_heap_size()); esp_http_client_cleanup(_handle); } @@ -40,7 +40,7 @@ fnHttpClient::~fnHttpClient() } // Start an HTTP client session to the given URL -bool fnHttpClient::begin(std::string url) +bool fnHttpClient::begin(const std::string &url) { Debug_printf("fnHttpClient::begin \"%s\"\r\n", url.c_str()); @@ -70,7 +70,7 @@ int fnHttpClient::available() int result = 0; int len = -1; - if(esp_http_client_is_chunked_response(_handle)) + if (esp_http_client_is_chunked_response(_handle)) len = esp_http_client_get_chunk_length(_handle); else len = esp_http_client_get_content_length(_handle); @@ -89,7 +89,7 @@ int fnHttpClient::available() */ int fnHttpClient::read(uint8_t *dest_buffer, int dest_bufflen) { - //Debug_println("::read"); + // Debug_println("::read"); if (_handle == nullptr || dest_buffer == nullptr) return -1; @@ -104,7 +104,7 @@ int fnHttpClient::read(uint8_t *dest_buffer, int dest_bufflen) bytes_left = _buffer_len - _buffer_pos; bytes_to_copy = dest_bufflen > bytes_left ? bytes_left : dest_bufflen; - //Debug_printf("::read from buffer %d\r\n", bytes_to_copy); + // Debug_printf("::read from buffer %d\r\n", bytes_to_copy); memcpy(dest_buffer, _buffer + _buffer_pos, bytes_to_copy); _buffer_pos += bytes_to_copy; _buffer_total_read += bytes_to_copy; @@ -119,7 +119,7 @@ int fnHttpClient::read(uint8_t *dest_buffer, int dest_bufflen) // Nothing left to read - later ESP-IDF versions provide esp_http_client_is_complete_data_received() if (_transaction_done) { - //Debug_println("::read download done"); + // Debug_println("::read download done"); return bytes_copied; } @@ -136,28 +136,28 @@ int fnHttpClient::read(uint8_t *dest_buffer, int dest_bufflen) while (bytes_copied < dest_bufflen) { // Let the HTTP process task know to fill the buffer - //Debug_println("::read notifyGive"); + // Debug_println("::read notifyGive"); xTaskNotifyGive(_taskh_subtask); // Wait till the HTTP task lets us know it's filled the buffer - //Debug_println("::read notifyTake..."); - if(ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(HTTPCLIENT_WAIT_FOR_HTTP_TASK)) != 1) + // Debug_println("::read notifyTake..."); + if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(HTTPCLIENT_WAIT_FOR_HTTP_TASK)) != 1) { // Abort if we timed-out receiving the data Debug_println("::read time-out"); return -1; } - //Debug_println("::read got notification"); + // Debug_println("::read got notification"); if (_buffer_len <= 0) { - //Debug_println("::read download done"); + // Debug_println("::read download done"); return bytes_copied; } int dest_size = dest_bufflen - bytes_copied; bytes_to_copy = dest_size > _buffer_len ? _buffer_len : dest_size; - //Debug_printf("dest_size=%d, dest_bufflen=%d, bytes_copied=%d, bytes_to_copy=%d\r\n", - //dest_size, dest_bufflen, bytes_copied, bytes_to_copy); + // Debug_printf("dest_size=%d, dest_bufflen=%d, bytes_copied=%d, bytes_to_copy=%d\r\n", + // dest_size, dest_bufflen, bytes_copied, bytes_to_copy); memcpy(dest_buffer + bytes_copied, _buffer, bytes_to_copy); _buffer_pos += bytes_to_copy; @@ -171,7 +171,7 @@ int fnHttpClient::read(uint8_t *dest_buffer, int dest_bufflen) // Thorws out any waiting response body without closing the connection void fnHttpClient::_flush_response() { - //Debug_println("fnHttpClient::flush_response"); + // Debug_println("fnHttpClient::flush_response"); if (_handle == nullptr) return; @@ -191,20 +191,20 @@ void fnHttpClient::_flush_response() do { // Let the HTTP process task know to fill the buffer - //Debug_println("::flush_response notifyGive"); + // Debug_println("::flush_response notifyGive"); xTaskNotifyGive(_taskh_subtask); // Wait till the HTTP task lets us know it's filled the buffer - //Debug_println("::flush_response notifyTake..."); + // Debug_println("::flush_response notifyTake..."); ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(HTTPCLIENT_WAIT_FOR_HTTP_TASK)); } while (!_transaction_done); - //Debug_println("fnHttpClient::flush_response done"); + // Debug_println("fnHttpClient::flush_response done"); } // Close connection, but keep request resources void fnHttpClient::close() { - //Debug_println("::close"); + // Debug_println("::close"); _delete_subtask_if_running(); if (_handle != nullptr) @@ -215,7 +215,7 @@ void fnHttpClient::close() /* Typical event order: - + HTTP_EVENT_HANDLER_ON_CONNECTED HTTP_EVENT_HEADERS_SENT HTTP_EVENT_ON_HEADER - once for each header received with header_key and header_value set @@ -319,7 +319,7 @@ esp_err_t fnHttpClient::_httpevent_handler(esp_http_client_event_t *evt) ulTaskNotifyTake(1, pdMS_TO_TICKS(HTTPCLIENT_WAIT_FOR_CONSUMER_TASK)); #ifdef VERBOSE_HTTP - Debug_printf("HTTP_EVENT_ON_DATA: Data: %p, Datalen: %d\r\n", evt->data, evt->data_len); + Debug_printf("HTTP_EVENT_ON_DATA: Data: %p, Datalen: %d\r\n", evt->data, evt->data_len); #endif client->_buffer_pos = 0; @@ -334,7 +334,7 @@ esp_err_t fnHttpClient::_httpevent_handler(esp_http_client_event_t *evt) case HTTP_EVENT_ON_FINISH: // Occurs when finish a HTTP session { // This may get called more than once if esp_http_client decides to retry in order to handle a redirect or auth response - //Debug_printf("HTTP_EVENT_ON_FINISH %u\r\n", uxTaskGetStackHighWaterMark(nullptr)); + // Debug_printf("HTTP_EVENT_ON_FINISH %u\r\n", uxTaskGetStackHighWaterMark(nullptr)); // Keep track of how many times we "finish" reading a response from the server client->_redirect_count++; break; @@ -342,7 +342,7 @@ esp_err_t fnHttpClient::_httpevent_handler(esp_http_client_event_t *evt) case HTTP_EVENT_DISCONNECTED: // The connection has been disconnected client->connected = false; - //Debug_printf("HTTP_EVENT_DISCONNECTED %p:\"%s\":%u\r\n", xTaskGetCurrentTaskHandle(), pcTaskGetTaskName(nullptr), uxTaskGetStackHighWaterMark(nullptr)); + // Debug_printf("HTTP_EVENT_DISCONNECTED %p:\"%s\":%u\r\n", xTaskGetCurrentTaskHandle(), pcTaskGetTaskName(nullptr), uxTaskGetStackHighWaterMark(nullptr)); break; } return ESP_OK; @@ -358,7 +358,7 @@ void fnHttpClient::_perform_subtask(void *param) parent->_redirect_count = 0; parent->_buffer_len = 0; - //Debug_printf("esp_http_client_perform start\r\n"); + // Debug_printf("esp_http_client_perform start\r\n"); esp_err_t e = esp_http_client_perform(parent->_handle); Debug_printf("esp_http_client_perform returned %d, stack HWM %u\r\n", e, uxTaskGetStackHighWaterMark(nullptr)); @@ -373,7 +373,7 @@ void fnHttpClient::_perform_subtask(void *param) if (false == parent->_ignore_response_body) { /* - If _transaction_begin is false, then we handled the HTTP_EVENT_ON_DATA event, and + If _transaction_begin is false, then we handled the HTTP_EVENT_ON_DATA event, and read() has sent us a notification we need to accept before continuing. */ if (false == parent->_transaction_begin) @@ -387,7 +387,7 @@ void fnHttpClient::_perform_subtask(void *param) xTaskNotifyGive(parent->_taskh_consumer); } - //Debug_println("_perform_subtask_exiting"); + Debug_printv("_perform_subtask_exiting"); TaskHandle_t tmp = parent->_taskh_subtask; parent->_taskh_subtask = nullptr; vTaskDelete(tmp); @@ -423,7 +423,7 @@ int fnHttpClient::_perform() // Start a new task to perform the http client work _delete_subtask_if_running(); xTaskCreate(_perform_subtask, "perform_subtask", 4096, this, 5, &_taskh_subtask); - //Debug_printf("%08lx _perform subtask created\r\n", fnSystem.millis()); + // Debug_printf("%08lx _perform subtask created\r\n", fnSystem.millis()); // Wait until we have headers returned if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(HTTPCLIENT_WAIT_FOR_HTTP_TASK)) == 0) @@ -432,8 +432,8 @@ int fnHttpClient::_perform() //_delete_subtask_if_running(); return -1; } - //Debug_printf("%08lx _perform notified\r\n", fnSystem.millis()); - //Debug_printf("Notification of headers loaded\r\n"); + // Debug_printf("%08lx _perform notified\r\n", fnSystem.millis()); + // Debug_printf("Notification of headers loaded\r\n"); bool chunked = esp_http_client_is_chunked_response(_handle); int length = esp_http_client_get_content_length(_handle); @@ -452,10 +452,11 @@ int fnHttpClient::_perform() break; default: status = esp_http_client_get_status_code(_handle); - Debug_printf("esp_http_client_get_status_code = %u\r\n",status); + Debug_printf("esp_http_client_get_status_code = %u\r\n", status); // Other error, use fake HTTP status code 900 // it will be translated to NETWORK_ERROR_GENERAL (144) in NetworkProtocolHTTP::fserror_to_error() - if (status < 0) status = 900; + if (status < 0) + status = 900; } Debug_printf("%08lx _perform status = %d, length = %d, chunked = %d\r\n", fnSystem.millis(), status, length, chunked ? 1 : 0); return status; diff --git a/lib/http/fnHttpClient.h b/lib/http/fnHttpClient.h index 891ac04e3..ed7df825a 100755 --- a/lib/http/fnHttpClient.h +++ b/lib/http/fnHttpClient.h @@ -61,7 +61,7 @@ class fnHttpClient DEPTH_INFINITY }; - bool begin(std::string url); + bool begin(const std::string &url); void close(); int GET(); diff --git a/lib/http/httpService.h b/lib/http/httpService.h index bd90f5ad1..8163b05e8 100755 --- a/lib/http/httpService.h +++ b/lib/http/httpService.h @@ -88,7 +88,7 @@ class fnHttpService std::string getErrMsg() { return errMsg; } void clearErrMsg() { errMsg.clear(); } - void addToErrMsg(const std::string _e) { errMsg += _e; } + void addToErrMsg(const std::string &_e) { errMsg += _e; } bool errMsgEmpty() { return errMsg.empty(); } static esp_err_t get_handler_test(httpd_req_t *req); diff --git a/lib/meatloaf/peoples_url_parser.h b/lib/meatloaf/peoples_url_parser.h index 2c83d15c9..37c1852f0 100644 --- a/lib/meatloaf/peoples_url_parser.h +++ b/lib/meatloaf/peoples_url_parser.h @@ -179,7 +179,7 @@ class PeoplesUrlParser { return std::stoi(port); } - void parseUrl(std::string u) { + void parseUrl(const std::string &u) { url = u; //Debug_printv("Before [%s]", url.c_str()); diff --git a/lib/media/atari/diskTypeXex.cpp b/lib/media/atari/diskTypeXex.cpp index 530dcc89e..762b86c69 100755 --- a/lib/media/atari/diskTypeXex.cpp +++ b/lib/media/atari/diskTypeXex.cpp @@ -216,9 +216,6 @@ void MediaTypeXEX::status(uint8_t statusbuff[4]) void MediaTypeXEX::unmount() { - if (_xex_bootloader != nullptr) - free(_xex_bootloader); - // Call the parent unmount this->MediaType::unmount(); } @@ -235,7 +232,7 @@ mediatype_t MediaTypeXEX::mount(FILE *f, uint32_t disksize) _disktype = MEDIATYPE_UNKNOWN; // Load our bootloader - _xex_bootloadersize = fnSystem.load_firmware(BOOTLOADER, &_xex_bootloader); + _xex_bootloadersize = fnSystem.load_firmware(BOOTLOADER, &_xex_bootloader[0]); if (_xex_bootloadersize < 0) { Debug_printf("failed to load bootloader \"%s\"\r\n", BOOTLOADER); diff --git a/lib/media/atari/diskTypeXex.h b/lib/media/atari/diskTypeXex.h index f028edfa2..ad598e67e 100755 --- a/lib/media/atari/diskTypeXex.h +++ b/lib/media/atari/diskTypeXex.h @@ -6,7 +6,7 @@ class MediaTypeXEX : public MediaType { private: - uint8_t *_xex_bootloader = nullptr; + uint8_t _xex_bootloader[384]; int _xex_bootloadersize = 0; void _fake_vtoc(); diff --git a/lib/modem/modem.cpp b/lib/modem/modem.cpp index 62eea3fad..a5e639fe6 100755 --- a/lib/modem/modem.cpp +++ b/lib/modem/modem.cpp @@ -159,7 +159,8 @@ void modem::sio_poll_3(uint8_t device, uint8_t aux1, uint8_t aux2) return; // Get size of handler - int filesize = fnSystem.load_firmware(FIRMWARE_850HANDLER, NULL); + int filesize = 1282; + // int filesize = fnSystem.load_firmware(FIRMWARE_850HANDLER, NULL); // Simply return (without ACK) if we failed to get this if (filesize < 0) @@ -202,7 +203,8 @@ void modem::sio_poll_1() */ // Get size of relocator - int filesize = fnSystem.load_firmware(FIRMWARE_850RELOCATOR, NULL); + // int filesize = fnSystem.load_firmware(FIRMWARE_850RELOCATOR, NULL); + int filesize = 333; // Simply return (without ACK) if we failed to get this if (filesize < 0) return; @@ -240,23 +242,27 @@ void modem::sio_poll_1() void modem::sio_send_firmware(uint8_t loadcommand) { const char *firmware; + int firmware_size = 0; + if (loadcommand == SIO_MODEMCMD_LOAD_RELOCATOR) { firmware = FIRMWARE_850RELOCATOR; + firmware_size = 333; } else { if (loadcommand == SIO_MODEMCMD_LOAD_HANDLER) { firmware = FIRMWARE_850HANDLER; + firmware_size = 1282; } else return; } // Load firmware from file - uint8_t *code; - int codesize = fnSystem.load_firmware(firmware, &code); + uint8_t *code = (uint8_t *)malloc(firmware_size); + int codesize = fnSystem.load_firmware(firmware, code); // NAK if we failed to get this if (codesize < 0 || code == NULL) { diff --git a/lib/network-protocol/FS.cpp b/lib/network-protocol/FS.cpp index 893a19582..24a65d2d1 100755 --- a/lib/network-protocol/FS.cpp +++ b/lib/network-protocol/FS.cpp @@ -11,6 +11,10 @@ #include "status_error_codes.h" #include "utils.h" +#include + +#define ENTRY_BUFFER_SIZE 256 + NetworkProtocolFS::NetworkProtocolFS(string *rx_buf, string *tx_buf, string *sp_buf) : NetworkProtocol(rx_buf, tx_buf, sp_buf) { @@ -63,6 +67,7 @@ bool NetworkProtocolFS::open_dir() { openMode = DIR; dirBuffer.clear(); + dirBuffer.shrink_to_fit(); update_dir_filename(opened_url); // assume everything if no filename. @@ -82,9 +87,9 @@ bool NetworkProtocolFS::open_dir() return true; } - char *entryBuffer = (char *)malloc(256); + char *entryBuffer = (char *)malloc(ENTRY_BUFFER_SIZE); - while (read_dir_entry(entryBuffer, 255) == false) + while (read_dir_entry(entryBuffer, ENTRY_BUFFER_SIZE-1) == false) { if (aux2_open & 0x80) { @@ -100,6 +105,8 @@ bool NetworkProtocolFS::open_dir() dirBuffer += util_entry(util_crunch(string(entryBuffer)), fileSize, is_directory, is_locked) + "\x9b"; } fserror_to_error(); + + memset(entryBuffer,0,ENTRY_BUFFER_SIZE); } #ifdef BUILD_ATARI @@ -110,8 +117,6 @@ bool NetworkProtocolFS::open_dir() if (error == NETWORK_ERROR_END_OF_FILE) error = NETWORK_ERROR_SUCCESS; - free(entryBuffer); - return error != NETWORK_ERROR_SUCCESS; } @@ -166,17 +171,21 @@ bool NetworkProtocolFS::close_dir() bool NetworkProtocolFS::read(unsigned short len) { + bool ret; + switch (openMode) { case FILE: - return read_file(len); + ret = read_file(len); break; case DIR: - return read_dir(len); + ret = read_dir(len); break; default: - return true; + ret = true; } + + return ret; } bool NetworkProtocolFS::read_file(unsigned short len) @@ -195,7 +204,10 @@ bool NetworkProtocolFS::read_file(unsigned short len) { // Do block read. if (read_file_handle(buf, len) == true) + { + free(buf); return true; + } // Append to receive buffer. *receiveBuffer += string((char *)buf, len); @@ -213,13 +225,18 @@ bool NetworkProtocolFS::read_file(unsigned short len) bool NetworkProtocolFS::read_dir(unsigned short len) { + bool ret; + if (receiveBuffer->length() == 0) { *receiveBuffer = dirBuffer.substr(0, len); dirBuffer.erase(0, len); + dirBuffer.shrink_to_fit(); } - return NetworkProtocol::read(len); + ret = NetworkProtocol::read(len); + + return ret; } bool NetworkProtocolFS::write(unsigned short len) diff --git a/lib/network-protocol/HTTP.cpp b/lib/network-protocol/HTTP.cpp index 190e0a6df..0b74e940a 100755 --- a/lib/network-protocol/HTTP.cpp +++ b/lib/network-protocol/HTTP.cpp @@ -182,6 +182,7 @@ bool NetworkProtocolHTTP::open_dir_handle() { Debug_printf("Expected %u bytes, actually got %u bytes.\r\n", len, actual_len); error = NETWORK_ERROR_GENERAL; + free(buf); return true; } @@ -190,6 +191,7 @@ bool NetworkProtocolHTTP::open_dir_handle() { Debug_printf("Could not parse buffer, returning 144\r\n"); error = NETWORK_ERROR_GENERAL; + free(buf); return true; } @@ -204,6 +206,7 @@ bool NetworkProtocolHTTP::open_dir_handle() } // Directory parsed, ready to be returned by read_dir_entry() + free(buf); return false; } diff --git a/lib/utils/utils.cpp b/lib/utils/utils.cpp index 431067304..8dd4e0f2d 100644 --- a/lib/utils/utils.cpp +++ b/lib/utils/utils.cpp @@ -275,6 +275,8 @@ std::string util_long_entry(std::string filename, size_t fileSize, bool is_dir) returned_entry.replace(returned_entry.length() - stylized_filesize.length() - 1, stylized_filesize.length(), stylized_filesize); + returned_entry.shrink_to_fit(); + return returned_entry; } diff --git a/sdkconfig.defaults b/sdkconfig.defaults index b1225d064..d5d17ced2 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -872,8 +872,8 @@ CONFIG_FREERTOS_DEBUG_OCDAWARE=y # CONFIG_HEAP_POISONING_DISABLED is not set CONFIG_HEAP_POISONING_LIGHT=y # CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_OFF=y +CONFIG_HEAP_TRACING_STANDALONE=y # CONFIG_HEAP_TRACING_TOHOST is not set # CONFIG_HEAP_TASK_TRACKING is not set # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set diff --git a/src/main.cpp b/src/main.cpp index 751f6b8ac..e4fab64e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -346,9 +346,15 @@ extern "C" // Create a new high-priority task to handle the main loop // This is assigned to CPU1; the WiFi task ends up on CPU0 +#ifdef BUILD_ATARI +#define MAIN_STACKSIZE 32768 +#define MAIN_PRIORITY 10 +#else #define MAIN_STACKSIZE 32768 #define MAIN_PRIORITY 10 +#endif #define MAIN_CPUAFFINITY 1 + xTaskCreatePinnedToCore(fn_service_loop, "fnLoop", MAIN_STACKSIZE, nullptr, MAIN_PRIORITY, nullptr, MAIN_CPUAFFINITY);