|  | @ -86,6 +86,83 @@ | 
		
	
		
			
				|  |  | #include "freertos/ringbuf.h"
 |  |  | #include "freertos/ringbuf.h"
 | 
		
	
		
			
				|  |  | #include "values.h"
 |  |  | #include "values.h"
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | // Prototypes
 | 
		
	
		
			
				|  |  |  |  |  | void accessPointStart(const char *SSID, IPAddress ip, IPAddress netmask); | 
		
	
		
			
				|  |  |  |  |  | void actionError(void); | 
		
	
		
			
				|  |  |  |  |  | void actionOk(void); | 
		
	
		
			
				|  |  |  |  |  | static int arrSortHelper(const void* a, const void* b); | 
		
	
		
			
				|  |  |  |  |  | void batteryVoltageTester(void); | 
		
	
		
			
				|  |  |  |  |  | void buttonHandler(); | 
		
	
		
			
				|  |  |  |  |  | void deepSleepManager(void); | 
		
	
		
			
				|  |  |  |  |  | bool digitalReadFromAll(const uint8_t _channel); | 
		
	
		
			
				|  |  |  |  |  | void doButtonActions(void); | 
		
	
		
			
				|  |  |  |  |  | void doRfidCardModifications(const uint32_t mod); | 
		
	
		
			
				|  |  |  |  |  | void doCmdAction(const uint16_t mod); | 
		
	
		
			
				|  |  |  |  |  | bool dumpNvsToSd(char *_namespace, char *_destFile); | 
		
	
		
			
				|  |  |  |  |  | bool endsWith (const char *str, const char *suf); | 
		
	
		
			
				|  |  |  |  |  | bool fileValid(const char *_fileItem); | 
		
	
		
			
				|  |  |  |  |  | void freeMultiCharArray(char **arr, const uint32_t cnt); | 
		
	
		
			
				|  |  |  |  |  | uint8_t getRepeatMode(void); | 
		
	
		
			
				|  |  |  |  |  | bool getWifiEnableStatusFromNVS(void); | 
		
	
		
			
				|  |  |  |  |  | void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); | 
		
	
		
			
				|  |  |  |  |  | void convertAsciiToUtf8(String asciiString, char *utf8String); | 
		
	
		
			
				|  |  |  |  |  | void convertUtf8ToAscii(String utf8String, char *asciiString); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleFileStorageTask(void *parameter); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleListRequest(AsyncWebServerRequest *request); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleDeleteRequest(AsyncWebServerRequest *request); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleCreateRequest(AsyncWebServerRequest *request); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleRenameRequest(AsyncWebServerRequest *request); | 
		
	
		
			
				|  |  |  |  |  | void explorerHandleAudioRequest(AsyncWebServerRequest *request); | 
		
	
		
			
				|  |  |  |  |  | void headphoneVolumeManager(void); | 
		
	
		
			
				|  |  |  |  |  | bool isNumber(const char *str); | 
		
	
		
			
				|  |  |  |  |  | void loggerNl(const uint8_t _currentLogLevel, const char *str, const uint8_t _logLevel); | 
		
	
		
			
				|  |  |  |  |  | void logger(const uint8_t _currentLogLevel, const char *str, const uint8_t _logLevel); | 
		
	
		
			
				|  |  |  |  |  | float measureBatteryVoltage(void); | 
		
	
		
			
				|  |  |  |  |  | #ifdef MQTT_ENABLE
 | 
		
	
		
			
				|  |  |  |  |  |     void callback(const char *topic, const byte *payload, uint32_t length); | 
		
	
		
			
				|  |  |  |  |  |     bool publishMqtt(const char *topic, const char *payload, bool retained); | 
		
	
		
			
				|  |  |  |  |  |     void postHeartbeatViaMqtt(void); | 
		
	
		
			
				|  |  |  |  |  |     bool reconnect(); | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  | size_t nvsRfidWriteWrapper (const char *_rfidCardId, const char *_track, const uint32_t _playPosition, const uint8_t _playMode, const uint16_t _trackLastPlayed, const uint16_t _numberOfTracks); | 
		
	
		
			
				|  |  |  |  |  | void onWebsocketEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); | 
		
	
		
			
				|  |  |  |  |  | #ifdef PORT_EXPANDER_ENABLE
 | 
		
	
		
			
				|  |  |  |  |  |     bool portExpanderHandler(); | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  | bool processJsonRequest(char *_serialJson); | 
		
	
		
			
				|  |  |  |  |  | void randomizePlaylist (char *str[], const uint32_t count); | 
		
	
		
			
				|  |  |  |  |  | char ** returnPlaylistFromWebstream(const char *_webUrl); | 
		
	
		
			
				|  |  |  |  |  | char ** returnPlaylistFromSD(File _fileOrDirectory); | 
		
	
		
			
				|  |  |  |  |  | #ifdef RFID_READER_TYPE_PN5180
 | 
		
	
		
			
				|  |  |  |  |  |     void rfidScanner(void *parameter); | 
		
	
		
			
				|  |  |  |  |  | #else
 | 
		
	
		
			
				|  |  |  |  |  |     void rfidScanner(void); | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  | void sleepHandler(void) ; | 
		
	
		
			
				|  |  |  |  |  | void sortPlaylist(const char** arr, int n); | 
		
	
		
			
				|  |  |  |  |  | bool startsWith(const char *str, const char *pre); | 
		
	
		
			
				|  |  |  |  |  | String templateProcessor(const String& templ); | 
		
	
		
			
				|  |  |  |  |  | void trackControlToQueueSender(const uint8_t trackCommand); | 
		
	
		
			
				|  |  |  |  |  | void rfidPreferenceLookupHandler (void); | 
		
	
		
			
				|  |  |  |  |  | void sendWebsocketData(uint32_t client, uint8_t code); | 
		
	
		
			
				|  |  |  |  |  | void setupVolume(void); | 
		
	
		
			
				|  |  |  |  |  | void trackQueueDispatcher(const char *_sdFile, const uint32_t _lastPlayPos, const uint32_t _playMode, const uint16_t _trackLastPlayed); | 
		
	
		
			
				|  |  |  |  |  | #ifdef USEROTARY_ENABLE
 | 
		
	
		
			
				|  |  |  |  |  |     void rotaryVolumeHandler(const int32_t _minVolume, const int32_t _maxVolume); | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  | void volumeToQueueSender(const int32_t _newVolume, bool reAdjustRotary); | 
		
	
		
			
				|  |  |  |  |  | wl_status_t wifiManager(void); | 
		
	
		
			
				|  |  |  |  |  | bool writeWifiStatusToNVS(bool wifiStatus); | 
		
	
		
			
				|  |  |  |  |  | void bluetoothHandler(void); | 
		
	
		
			
				|  |  |  |  |  | uint8_t readOperationModeFromNVS(void); | 
		
	
		
			
				|  |  |  |  |  | bool setOperationMode(uint8_t operationMode); | 
		
	
		
			
				|  |  |  |  |  | char * x_calloc(uint32_t _allocSize, uint32_t _unitSize); | 
		
	
		
			
				|  |  |  |  |  | char * x_malloc(uint32_t _allocSize); | 
		
	
		
			
				|  |  |  |  |  | char * x_strdup(const char *_str); | 
		
	
		
			
				|  |  |  |  |  | char * x_strndup(const char *_str, uint32_t _len); | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  | // Serial-logging buffer
 |  |  | // Serial-logging buffer
 | 
		
	
		
			
				|  |  | uint8_t serialLoglength = 200; |  |  | uint8_t serialLoglength = 200; | 
		
	
		
			
				|  |  | char *logBuf;   // Defintion in setup()
 |  |  | char *logBuf;   // Defintion in setup()
 | 
		
	
	
		
			
				|  | @ -174,8 +251,8 @@ uint8_t sleepTimer = 30;                                // Sleep timer in minute | 
		
	
		
			
				|  |  | // FTP
 |  |  | // FTP
 | 
		
	
		
			
				|  |  | uint8_t ftpUserLength = 10;                             // Length will be published n-1 as maxlength to GUI
 |  |  | uint8_t ftpUserLength = 10;                             // Length will be published n-1 as maxlength to GUI
 | 
		
	
		
			
				|  |  | uint8_t ftpPasswordLength = 15;                         // Length will be published n-1 as maxlength to GUI
 |  |  | uint8_t ftpPasswordLength = 15;                         // Length will be published n-1 as maxlength to GUI
 | 
		
	
		
			
				|  |  | char *ftpUser = strndup((char*) "esp32", ftpUserLength);                // FTP-user (default; can be changed later via GUI)
 |  |  |  | 
		
	
		
			
				|  |  | char *ftpPassword = strndup((char*) "esp32", ftpPasswordLength);        // FTP-password (default; can be changed later via GUI)
 |  |  |  | 
		
	
		
			
				|  |  |  |  |  | char *ftpUser = x_strndup((char*) "esp32", ftpUserLength);                // FTP-user (default; can be changed later via GUI)
 | 
		
	
		
			
				|  |  |  |  |  | char *ftpPassword = x_strndup((char*) "esp32", ftpPasswordLength);        // FTP-password (default; can be changed later via GUI)
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | // Don't change anything here unless you know what you're doing
 |  |  | // Don't change anything here unless you know what you're doing
 | 
		
	
	
		
			
				|  | @ -229,9 +306,9 @@ uint8_t mqttUserLength = 16; | 
		
	
		
			
				|  |  | uint8_t mqttPasswordLength = 16; |  |  | uint8_t mqttPasswordLength = 16; | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | // Please note: all of them are defaults that can be changed later via GUI
 |  |  | // Please note: all of them are defaults that can be changed later via GUI
 | 
		
	
		
			
				|  |  | char *mqtt_server = strndup((char*) "192.168.2.43", mqttServerLength);      // IP-address of MQTT-server (if not found in NVS this one will be taken)
 |  |  |  | 
		
	
		
			
				|  |  | char *mqttUser = strndup((char*) "mqtt-user", mqttUserLength);              // MQTT-user
 |  |  |  | 
		
	
		
			
				|  |  | char *mqttPassword = strndup((char*) "mqtt-password", mqttPasswordLength);  // MQTT-password*/
 |  |  |  | 
		
	
		
			
				|  |  |  |  |  | char *mqtt_server = x_strndup((char*) "192.168.2.43", mqttServerLength);      // IP-address of MQTT-server (if not found in NVS this one will be taken)
 | 
		
	
		
			
				|  |  |  |  |  | char *mqttUser = x_strndup((char*) "mqtt-user", mqttUserLength);              // MQTT-user
 | 
		
	
		
			
				|  |  |  |  |  | char *mqttPassword = x_strndup((char*) "mqtt-password", mqttPasswordLength);  // MQTT-password*/
 | 
		
	
		
			
				|  |  | uint16_t mqttPort = 1883;                                                       // MQTT-Port
 |  |  | uint16_t mqttPort = 1883;                                                       // MQTT-Port
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | char stringDelimiter[] = "#";                               // Character used to encapsulate data in linear NVS-strings (don't change)
 |  |  | char stringDelimiter[] = "#";                               // Character used to encapsulate data in linear NVS-strings (don't change)
 | 
		
	
	
		
			
				|  | @ -376,77 +453,6 @@ QueueHandle_t explorerFileUploadStatusQueue; | 
		
	
		
			
				|  |  |     #define EXPANDER_5_ENABLE
 |  |  |     #define EXPANDER_5_ENABLE
 | 
		
	
		
			
				|  |  | #endif
 |  |  | #endif
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | // Prototypes
 |  |  |  | 
		
	
		
			
				|  |  | void accessPointStart(const char *SSID, IPAddress ip, IPAddress netmask); |  |  |  | 
		
	
		
			
				|  |  | void actionError(void); |  |  |  | 
		
	
		
			
				|  |  | void actionOk(void); |  |  |  | 
		
	
		
			
				|  |  | static int arrSortHelper(const void* a, const void* b); |  |  |  | 
		
	
		
			
				|  |  | void batteryVoltageTester(void); |  |  |  | 
		
	
		
			
				|  |  | void buttonHandler(); |  |  |  | 
		
	
		
			
				|  |  | void deepSleepManager(void); |  |  |  | 
		
	
		
			
				|  |  | bool digitalReadFromAll(const uint8_t _channel); |  |  |  | 
		
	
		
			
				|  |  | void doButtonActions(void); |  |  |  | 
		
	
		
			
				|  |  | void doRfidCardModifications(const uint32_t mod); |  |  |  | 
		
	
		
			
				|  |  | void doCmdAction(const uint16_t mod); |  |  |  | 
		
	
		
			
				|  |  | bool dumpNvsToSd(char *_namespace, char *_destFile); |  |  |  | 
		
	
		
			
				|  |  | bool endsWith (const char *str, const char *suf); |  |  |  | 
		
	
		
			
				|  |  | bool fileValid(const char *_fileItem); |  |  |  | 
		
	
		
			
				|  |  | void freeMultiCharArray(char **arr, const uint32_t cnt); |  |  |  | 
		
	
		
			
				|  |  | uint8_t getRepeatMode(void); |  |  |  | 
		
	
		
			
				|  |  | bool getWifiEnableStatusFromNVS(void); |  |  |  | 
		
	
		
			
				|  |  | void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); |  |  |  | 
		
	
		
			
				|  |  | void convertAsciiToUtf8(String asciiString, char *utf8String); |  |  |  | 
		
	
		
			
				|  |  | void convertUtf8ToAscii(String utf8String, char *asciiString); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleFileStorageTask(void *parameter); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleListRequest(AsyncWebServerRequest *request); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleDeleteRequest(AsyncWebServerRequest *request); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleCreateRequest(AsyncWebServerRequest *request); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleRenameRequest(AsyncWebServerRequest *request); |  |  |  | 
		
	
		
			
				|  |  | void explorerHandleAudioRequest(AsyncWebServerRequest *request); |  |  |  | 
		
	
		
			
				|  |  | void headphoneVolumeManager(void); |  |  |  | 
		
	
		
			
				|  |  | bool isNumber(const char *str); |  |  |  | 
		
	
		
			
				|  |  | void loggerNl(const uint8_t _currentLogLevel, const char *str, const uint8_t _logLevel); |  |  |  | 
		
	
		
			
				|  |  | void logger(const uint8_t _currentLogLevel, const char *str, const uint8_t _logLevel); |  |  |  | 
		
	
		
			
				|  |  | float measureBatteryVoltage(void); |  |  |  | 
		
	
		
			
				|  |  | #ifdef MQTT_ENABLE
 |  |  |  | 
		
	
		
			
				|  |  |     void callback(const char *topic, const byte *payload, uint32_t length); |  |  |  | 
		
	
		
			
				|  |  |     bool publishMqtt(const char *topic, const char *payload, bool retained); |  |  |  | 
		
	
		
			
				|  |  |     void postHeartbeatViaMqtt(void); |  |  |  | 
		
	
		
			
				|  |  |     bool reconnect(); |  |  |  | 
		
	
		
			
				|  |  | #endif
 |  |  |  | 
		
	
		
			
				|  |  | size_t nvsRfidWriteWrapper (const char *_rfidCardId, const char *_track, const uint32_t _playPosition, const uint8_t _playMode, const uint16_t _trackLastPlayed, const uint16_t _numberOfTracks); |  |  |  | 
		
	
		
			
				|  |  | void onWebsocketEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); |  |  |  | 
		
	
		
			
				|  |  | #ifdef PORT_EXPANDER_ENABLE
 |  |  |  | 
		
	
		
			
				|  |  |     bool portExpanderHandler(); |  |  |  | 
		
	
		
			
				|  |  | #endif
 |  |  |  | 
		
	
		
			
				|  |  | bool processJsonRequest(char *_serialJson); |  |  |  | 
		
	
		
			
				|  |  | void randomizePlaylist (char *str[], const uint32_t count); |  |  |  | 
		
	
		
			
				|  |  | char ** returnPlaylistFromWebstream(const char *_webUrl); |  |  |  | 
		
	
		
			
				|  |  | char ** returnPlaylistFromSD(File _fileOrDirectory); |  |  |  | 
		
	
		
			
				|  |  | #ifdef RFID_READER_TYPE_PN5180
 |  |  |  | 
		
	
		
			
				|  |  |     void rfidScanner(void *parameter); |  |  |  | 
		
	
		
			
				|  |  | #else
 |  |  |  | 
		
	
		
			
				|  |  |     void rfidScanner(void); |  |  |  | 
		
	
		
			
				|  |  | #endif
 |  |  |  | 
		
	
		
			
				|  |  | void sleepHandler(void) ; |  |  |  | 
		
	
		
			
				|  |  | void sortPlaylist(const char** arr, int n); |  |  |  | 
		
	
		
			
				|  |  | bool startsWith(const char *str, const char *pre); |  |  |  | 
		
	
		
			
				|  |  | String templateProcessor(const String& templ); |  |  |  | 
		
	
		
			
				|  |  | void trackControlToQueueSender(const uint8_t trackCommand); |  |  |  | 
		
	
		
			
				|  |  | void rfidPreferenceLookupHandler (void); |  |  |  | 
		
	
		
			
				|  |  | void sendWebsocketData(uint32_t client, uint8_t code); |  |  |  | 
		
	
		
			
				|  |  | void setupVolume(void); |  |  |  | 
		
	
		
			
				|  |  | void trackQueueDispatcher(const char *_sdFile, const uint32_t _lastPlayPos, const uint32_t _playMode, const uint16_t _trackLastPlayed); |  |  |  | 
		
	
		
			
				|  |  | #ifdef USEROTARY_ENABLE
 |  |  |  | 
		
	
		
			
				|  |  |     void rotaryVolumeHandler(const int32_t _minVolume, const int32_t _maxVolume); |  |  |  | 
		
	
		
			
				|  |  | #endif
 |  |  |  | 
		
	
		
			
				|  |  | void volumeToQueueSender(const int32_t _newVolume, bool reAdjustRotary); |  |  |  | 
		
	
		
			
				|  |  | wl_status_t wifiManager(void); |  |  |  | 
		
	
		
			
				|  |  | bool writeWifiStatusToNVS(bool wifiStatus); |  |  |  | 
		
	
		
			
				|  |  | void bluetoothHandler(void); |  |  |  | 
		
	
		
			
				|  |  | uint8_t readOperationModeFromNVS(void); |  |  |  | 
		
	
		
			
				|  |  | bool setOperationMode(uint8_t operationMode); |  |  |  | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | /* Wrapper-function for serial-logging (with newline)
 |  |  | /* Wrapper-function for serial-logging (with newline)
 | 
		
	
	
		
			
				|  | @ -486,6 +492,59 @@ void actionOk(void) { | 
		
	
		
			
				|  |  | } |  |  | } | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | // Wraps strdup(). Without PSRAM, strdup is called => so heap is used.
 | 
		
	
		
			
				|  |  |  |  |  | // With PSRAM being available, the same is done what strdup() does, but with allocation on PSRAM.
 | 
		
	
		
			
				|  |  |  |  |  | char * x_strdup(const char *_str) { | 
		
	
		
			
				|  |  |  |  |  |     if (!psramInit()) { | 
		
	
		
			
				|  |  |  |  |  |         return strdup(_str); | 
		
	
		
			
				|  |  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |  |         char *dst = (char *) ps_malloc(strlen (_str) + 1); | 
		
	
		
			
				|  |  |  |  |  |         if (dst == NULL) { | 
		
	
		
			
				|  |  |  |  |  |             return NULL; | 
		
	
		
			
				|  |  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  |         strcpy(dst, _str); | 
		
	
		
			
				|  |  |  |  |  |         return dst; | 
		
	
		
			
				|  |  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | // Wraps strndup(). Without PSRAM, strdup is called => so heap is used.
 | 
		
	
		
			
				|  |  |  |  |  | // With PSRAM being available, the same is done what strndup() does, but with allocation on PSRAM.
 | 
		
	
		
			
				|  |  |  |  |  | char * x_strndup(const char *_str, uint32_t _len) { | 
		
	
		
			
				|  |  |  |  |  |     if (!psramInit()) { | 
		
	
		
			
				|  |  |  |  |  |         return strndup(_str, _len); | 
		
	
		
			
				|  |  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |  |         char *dst = (char *) ps_malloc(_len + 1); | 
		
	
		
			
				|  |  |  |  |  |         if (dst == NULL) { | 
		
	
		
			
				|  |  |  |  |  |             return NULL; | 
		
	
		
			
				|  |  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  |         strncpy(dst, _str, _len); | 
		
	
		
			
				|  |  |  |  |  |         dst[_len] = '\0'; | 
		
	
		
			
				|  |  |  |  |  |         return dst; | 
		
	
		
			
				|  |  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | // Wraps ps_malloc() and malloc(). Selection depends on whether PSRAM is available or not.
 | 
		
	
		
			
				|  |  |  |  |  | char * x_malloc(uint32_t _allocSize) { | 
		
	
		
			
				|  |  |  |  |  |     if (psramInit()) { | 
		
	
		
			
				|  |  |  |  |  |         return (char *) ps_malloc(_allocSize); | 
		
	
		
			
				|  |  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |  |         return (char *) malloc(_allocSize); | 
		
	
		
			
				|  |  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | // Wraps ps_calloc() and calloc(). Selection depends on whether PSRAM is available or not.
 | 
		
	
		
			
				|  |  |  |  |  | char * x_calloc(uint32_t _allocSize, uint32_t _unitSize) { | 
		
	
		
			
				|  |  |  |  |  |     if (psramInit()) { | 
		
	
		
			
				|  |  |  |  |  |         return (char *) ps_calloc(_allocSize, _unitSize); | 
		
	
		
			
				|  |  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |  |         return (char *) calloc(_allocSize, _unitSize); | 
		
	
		
			
				|  |  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  | void IRAM_ATTR onTimer() { |  |  | void IRAM_ATTR onTimer() { | 
		
	
		
			
				|  |  |   xSemaphoreGiveFromISR(timerSemaphore, NULL); |  |  |   xSemaphoreGiveFromISR(timerSemaphore, NULL); | 
		
	
		
			
				|  |  | } |  |  | } | 
		
	
	
		
			
				|  | @ -509,7 +568,7 @@ void IRAM_ATTR onTimer() { | 
		
	
		
			
				|  |  |             if (!lastRfidPlayed.compareTo("-1")) { |  |  |             if (!lastRfidPlayed.compareTo("-1")) { | 
		
	
		
			
				|  |  |                 loggerNl(serialDebug,(char *) FPSTR(unableToRestoreLastRfidFromNVS), LOGLEVEL_INFO); |  |  |                 loggerNl(serialDebug,(char *) FPSTR(unableToRestoreLastRfidFromNVS), LOGLEVEL_INFO); | 
		
	
		
			
				|  |  |             } else { |  |  |             } else { | 
		
	
		
			
				|  |  |                 char *lastRfid = strdup(lastRfidPlayed.c_str()); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |                 char *lastRfid = x_strdup(lastRfidPlayed.c_str()); | 
		
	
		
			
				|  |  |                 xQueueSend(rfidCardQueue, &lastRfid, 0); |  |  |                 xQueueSend(rfidCardQueue, &lastRfid, 0); | 
		
	
		
			
				|  |  |                 snprintf(logBuf, serialLoglength, "%s: %s", (char *) FPSTR(restoredLastRfidFromNVS), lastRfidPlayed.c_str()); |  |  |                 snprintf(logBuf, serialLoglength, "%s: %s", (char *) FPSTR(restoredLastRfidFromNVS), lastRfidPlayed.c_str()); | 
		
	
		
			
				|  |  |                 loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); |  |  |                 loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); | 
		
	
	
		
			
				|  | @ -937,8 +996,8 @@ bool reconnect() { | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | // Is called if there's a new MQTT-message for us
 |  |  | // Is called if there's a new MQTT-message for us
 | 
		
	
		
			
				|  |  | void callback(const char *topic, const byte *payload, uint32_t length) { |  |  | void callback(const char *topic, const byte *payload, uint32_t length) { | 
		
	
		
			
				|  |  |     char *receivedString = strndup((char*)payload, length); |  |  |  | 
		
	
		
			
				|  |  |     char *mqttTopic = strdup(topic); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     char *receivedString = x_strndup((char*)payload, length); | 
		
	
		
			
				|  |  |  |  |  |     char *mqttTopic = x_strdup(topic); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     snprintf(logBuf, serialLoglength, "%s: [Topic: %s] [Command: %s]", (char *) FPSTR(mqttMsgReceived), mqttTopic, receivedString); |  |  |     snprintf(logBuf, serialLoglength, "%s: [Topic: %s] [Command: %s]", (char *) FPSTR(mqttMsgReceived), mqttTopic, receivedString); | 
		
	
		
			
				|  |  |     loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); |  |  |     loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); | 
		
	
	
		
			
				|  | @ -952,7 +1011,7 @@ void callback(const char *topic, const byte *payload, uint32_t length) { | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     // New track to play? Take RFID-ID as input
 |  |  |     // New track to play? Take RFID-ID as input
 | 
		
	
		
			
				|  |  |     else if (strcmp_P(topic, topicRfidCmnd) == 0) { |  |  |     else if (strcmp_P(topic, topicRfidCmnd) == 0) { | 
		
	
		
			
				|  |  |         char *_rfidId = strdup(receivedString); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         char *_rfidId = x_strdup(receivedString); | 
		
	
		
			
				|  |  |         xQueueSend(rfidCardQueue, &_rfidId, 0); |  |  |         xQueueSend(rfidCardQueue, &_rfidId, 0); | 
		
	
		
			
				|  |  |         //free(_rfidId);
 |  |  |         //free(_rfidId);
 | 
		
	
		
			
				|  |  |     } |  |  |     } | 
		
	
	
		
			
				|  | @ -1211,7 +1270,7 @@ bool fileValid(const char *_fileItem) { | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | // Adds webstream to playlist; same like returnPlaylistFromSD() but always only one entry
 |  |  | // Adds webstream to playlist; same like returnPlaylistFromSD() but always only one entry
 | 
		
	
		
			
				|  |  | char ** returnPlaylistFromWebstream(const char *_webUrl) { |  |  | char ** returnPlaylistFromWebstream(const char *_webUrl) { | 
		
	
		
			
				|  |  |     char *webUrl = strdup(_webUrl); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     char *webUrl = x_strdup(_webUrl); | 
		
	
		
			
				|  |  |     static char **url; |  |  |     static char **url; | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     if (url != NULL) { |  |  |     if (url != NULL) { | 
		
	
	
		
			
				|  | @ -1219,14 +1278,10 @@ char ** returnPlaylistFromWebstream(const char *_webUrl) { | 
		
	
		
			
				|  |  |         freeMultiCharArray(url, strtoul(*url, NULL, 10)); |  |  |         freeMultiCharArray(url, strtoul(*url, NULL, 10)); | 
		
	
		
			
				|  |  |     } |  |  |     } | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |         url = (char **) ps_malloc(sizeof(char *) * 2); |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |         url = (char **) malloc(sizeof(char *) * 2); |  |  |  | 
		
	
		
			
				|  |  |     } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     url = (char **) x_malloc(sizeof(char *) * 2); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     url[0] = strdup("1");         // Number of files is always 1 in url-mode
 |  |  |  | 
		
	
		
			
				|  |  |     url[1] = strdup(webUrl); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     url[0] = x_strdup("1");         // Number of files is always 1 in url-mode
 | 
		
	
		
			
				|  |  |  |  |  |     url[1] = x_strdup(webUrl); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     free(webUrl); |  |  |     free(webUrl); | 
		
	
		
			
				|  |  |     return ++url; |  |  |     return ++url; | 
		
	
	
		
			
				|  | @ -1257,11 +1312,7 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     // File-mode
 |  |  |     // File-mode
 | 
		
	
		
			
				|  |  |     if (!_fileOrDirectory.isDirectory()) { |  |  |     if (!_fileOrDirectory.isDirectory()) { | 
		
	
		
			
				|  |  |         if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |             files = (char **) ps_malloc(sizeof(char *) * 2); |  |  |  | 
		
	
		
			
				|  |  |         } else { |  |  |  | 
		
	
		
			
				|  |  |             files = (char **) malloc(sizeof(char *) * 2);        // +1 because [0] is used for number of elements; [1] -> [n] is used for payload
 |  |  |  | 
		
	
		
			
				|  |  |         } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         files = (char **) x_malloc(sizeof(char *) * 2); | 
		
	
		
			
				|  |  |         if (files == NULL) { |  |  |         if (files == NULL) { | 
		
	
		
			
				|  |  |             loggerNl(serialDebug, (char *) FPSTR(unableToAllocateMemForPlaylist), LOGLEVEL_ERROR); |  |  |             loggerNl(serialDebug, (char *) FPSTR(unableToAllocateMemForPlaylist), LOGLEVEL_ERROR); | 
		
	
		
			
				|  |  |             actionError(); |  |  |             actionError(); | 
		
	
	
		
			
				|  | @ -1270,15 +1321,10 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { | 
		
	
		
			
				|  |  |         loggerNl(serialDebug, (char *) FPSTR(fileModeDetected), LOGLEVEL_INFO); |  |  |         loggerNl(serialDebug, (char *) FPSTR(fileModeDetected), LOGLEVEL_INFO); | 
		
	
		
			
				|  |  |         strncpy(fileNameBuf, (char *) _fileOrDirectory.name(), sizeof(fileNameBuf) / sizeof(fileNameBuf[0])); |  |  |         strncpy(fileNameBuf, (char *) _fileOrDirectory.name(), sizeof(fileNameBuf) / sizeof(fileNameBuf[0])); | 
		
	
		
			
				|  |  |         if (fileValid(fileNameBuf)) { |  |  |         if (fileValid(fileNameBuf)) { | 
		
	
		
			
				|  |  |             if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |                 files = (char **) ps_malloc(sizeof(char *) * 2); |  |  |  | 
		
	
		
			
				|  |  |             } else { |  |  |  | 
		
	
		
			
				|  |  |                 files = (char **) malloc(sizeof(char *) * 2); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |             files = (char **) x_malloc(sizeof(char *) * 2); | 
		
	
		
			
				|  |  |  |  |  |             files[1] = x_strdup(fileNameBuf); | 
		
	
		
			
				|  |  |         } |  |  |         } | 
		
	
		
			
				|  |  | 
 |  |  |  | 
		
	
		
			
				|  |  |             files[1] = strdup(fileNameBuf); |  |  |  | 
		
	
		
			
				|  |  |         } |  |  |  | 
		
	
		
			
				|  |  |         files[0] = strdup("1");         // Number of files is always 1 in file-mode
 |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         files[0] = x_strdup("1");         // Number of files is always 1 in file-mode
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |         return ++files; |  |  |         return ++files; | 
		
	
		
			
				|  |  |     } |  |  |     } | 
		
	
	
		
			
				|  | @ -1286,13 +1332,12 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { | 
		
	
		
			
				|  |  |     // Directory-mode
 |  |  |     // Directory-mode
 | 
		
	
		
			
				|  |  |     uint16_t allocCount = 1; |  |  |     uint16_t allocCount = 1; | 
		
	
		
			
				|  |  |     uint16_t allocSize = 512; |  |  |     uint16_t allocSize = 512; | 
		
	
		
			
				|  |  |     char *serializedPlaylist; |  |  |  | 
		
	
		
			
				|  |  | 
 |  |  |  | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |     if (psramInit()) { | 
		
	
		
			
				|  |  |         serializedPlaylist = (char*) ps_calloc(allocSize, sizeof(char)); |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |         serializedPlaylist = (char*) calloc(allocSize, sizeof(char)); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         allocSize = 16384;      // There's enough PSRAM. So we don't have to care...
 | 
		
	
		
			
				|  |  |     } |  |  |     } | 
		
	
		
			
				|  |  |  |  |  |     char *serializedPlaylist; | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  |     serializedPlaylist = (char*) x_calloc(allocSize, sizeof(char)); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     while (true) { |  |  |     while (true) { | 
		
	
	
		
			
				|  | @ -1333,11 +1378,7 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { | 
		
	
		
			
				|  |  |     } |  |  |     } | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     // Alloc only necessary number of playlist-pointers
 |  |  |     // Alloc only necessary number of playlist-pointers
 | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |         files = (char **) ps_malloc(sizeof(char *) * cnt + 1); |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |         files = (char **) malloc(sizeof(char *) * cnt + 1); |  |  |  | 
		
	
		
			
				|  |  |     } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     files = (char **) x_malloc(sizeof(char *) * cnt + 1); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     if (files == NULL) { |  |  |     if (files == NULL) { | 
		
	
		
			
				|  |  |         loggerNl(serialDebug, (char *) FPSTR(unableToAllocateMemForPlaylist), LOGLEVEL_ERROR); |  |  |         loggerNl(serialDebug, (char *) FPSTR(unableToAllocateMemForPlaylist), LOGLEVEL_ERROR); | 
		
	
	
		
			
				|  | @ -1351,17 +1392,13 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { | 
		
	
		
			
				|  |  |     token = strtok(serializedPlaylist, stringDelimiter); |  |  |     token = strtok(serializedPlaylist, stringDelimiter); | 
		
	
		
			
				|  |  |     uint32_t pos = 1; |  |  |     uint32_t pos = 1; | 
		
	
		
			
				|  |  |     while (token != NULL) { |  |  |     while (token != NULL) { | 
		
	
		
			
				|  |  |         files[pos++] = strdup(token); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         files[pos++] = x_strdup(token); | 
		
	
		
			
				|  |  |         token = strtok(NULL, stringDelimiter); |  |  |         token = strtok(NULL, stringDelimiter); | 
		
	
		
			
				|  |  |     } |  |  |     } | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     free(serializedPlaylist); |  |  |     free(serializedPlaylist); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |         files[0] = (char *) ps_malloc(sizeof(char) * 5); |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |         files[0] = (char *) malloc(sizeof(char) * 5); |  |  |  | 
		
	
		
			
				|  |  |     } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     files[0] = (char *) x_malloc(sizeof(char) * 5); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     if (files[0] == NULL) { |  |  |     if (files[0] == NULL) { | 
		
	
		
			
				|  |  |         loggerNl(serialDebug, (char *) FPSTR(unableToAllocateMemForPlaylist), LOGLEVEL_ERROR); |  |  |         loggerNl(serialDebug, (char *) FPSTR(unableToAllocateMemForPlaylist), LOGLEVEL_ERROR); | 
		
	
	
		
			
				|  | @ -1862,11 +1899,7 @@ void rfidScanner(void) { | 
		
	
		
			
				|  |  |         mfrc522.PICC_HaltA(); |  |  |         mfrc522.PICC_HaltA(); | 
		
	
		
			
				|  |  |         mfrc522.PCD_StopCrypto1(); |  |  |         mfrc522.PCD_StopCrypto1(); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |         if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |             cardIdString = (char *) ps_malloc(cardIdSize*3 +1); |  |  |  | 
		
	
		
			
				|  |  |         } else { |  |  |  | 
		
	
		
			
				|  |  |             cardIdString = (char *) malloc(cardIdSize*3 +1); |  |  |  | 
		
	
		
			
				|  |  |         } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         cardIdString = (char *) x_malloc(cardIdSize*3 +1); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |         if (cardIdString == NULL) { |  |  |         if (cardIdString == NULL) { | 
		
	
		
			
				|  |  |             logger(serialDebug, (char *) FPSTR(unableToAllocateMem), LOGLEVEL_ERROR); |  |  |             logger(serialDebug, (char *) FPSTR(unableToAllocateMem), LOGLEVEL_ERROR); | 
		
	
	
		
			
				|  | @ -1930,11 +1963,7 @@ void rfidScanner(void *parameter) { | 
		
	
		
			
				|  |  |             nfc14443.setupRF(); |  |  |             nfc14443.setupRF(); | 
		
	
		
			
				|  |  |             uint8_t uid[10]; |  |  |             uint8_t uid[10]; | 
		
	
		
			
				|  |  |             if (nfc14443.isCardPresent() && nfc14443.readCardSerial(uid)) { |  |  |             if (nfc14443.isCardPresent() && nfc14443.readCardSerial(uid)) { | 
		
	
		
			
				|  |  |                 if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |                     cardIdString = (char *) ps_malloc(cardIdSize*3 +1); |  |  |  | 
		
	
		
			
				|  |  |                 } else { |  |  |  | 
		
	
		
			
				|  |  |                     cardIdString = (char *) malloc(cardIdSize*3 +1); |  |  |  | 
		
	
		
			
				|  |  |                 } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |                 cardIdString = (char *) x_malloc(cardIdSize*3 +1); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |                 if (cardIdString == NULL) { |  |  |                 if (cardIdString == NULL) { | 
		
	
		
			
				|  |  |                     logger(serialDebug, (char *) FPSTR(unableToAllocateMem), LOGLEVEL_ERROR); |  |  |                     logger(serialDebug, (char *) FPSTR(unableToAllocateMem), LOGLEVEL_ERROR); | 
		
	
	
		
			
				|  | @ -1977,11 +2006,7 @@ void rfidScanner(void *parameter) { | 
		
	
		
			
				|  |  |             // try to read ISO15693 inventory
 |  |  |             // try to read ISO15693 inventory
 | 
		
	
		
			
				|  |  |             ISO15693ErrorCode rc = nfc15693.getInventory(uid); |  |  |             ISO15693ErrorCode rc = nfc15693.getInventory(uid); | 
		
	
		
			
				|  |  |             if (rc == ISO15693_EC_OK) { |  |  |             if (rc == ISO15693_EC_OK) { | 
		
	
		
			
				|  |  |                 if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |                     cardIdString = (char *) ps_malloc(cardIdSize*3 +1); |  |  |  | 
		
	
		
			
				|  |  |                 } else { |  |  |  | 
		
	
		
			
				|  |  |                     cardIdString = (char *) malloc(cardIdSize*3 +1); |  |  |  | 
		
	
		
			
				|  |  |                 } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |                 cardIdString = (char *) x_malloc(cardIdSize*3 +1); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |                 if (cardIdString == NULL) { |  |  |                 if (cardIdString == NULL) { | 
		
	
		
			
				|  |  |                     logger(serialDebug, (char *) FPSTR(unableToAllocateMem), LOGLEVEL_ERROR); |  |  |                     logger(serialDebug, (char *) FPSTR(unableToAllocateMem), LOGLEVEL_ERROR); | 
		
	
	
		
			
				|  | @ -2589,11 +2614,7 @@ void trackControlToQueueSender(const uint8_t trackCommand) { | 
		
	
		
			
				|  |  | // playmode to the track-queue.
 |  |  | // playmode to the track-queue.
 | 
		
	
		
			
				|  |  | void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, const uint32_t _playMode, const uint16_t _trackLastPlayed) { |  |  | void trackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, const uint32_t _playMode, const uint16_t _trackLastPlayed) { | 
		
	
		
			
				|  |  |     char *filename; |  |  |     char *filename; | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |         filename = (char *) ps_malloc(sizeof(char) * 255); |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |         filename = (char *) malloc(sizeof(char) * 255); |  |  |  | 
		
	
		
			
				|  |  |     } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     filename = (char *) x_malloc(sizeof(char) * 255); | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |     strncpy(filename, _itemToPlay, 255); |  |  |     strncpy(filename, _itemToPlay, 255); | 
		
	
		
			
				|  |  |     playProperties.startAtFilePos = _lastPlayPos; |  |  |     playProperties.startAtFilePos = _lastPlayPos; | 
		
	
	
		
			
				|  | @ -3200,7 +3221,7 @@ void rfidPreferenceLookupHandler (void) { | 
		
	
		
			
				|  |  |     if (rfidStatus == pdPASS) { |  |  |     if (rfidStatus == pdPASS) { | 
		
	
		
			
				|  |  |         lastTimeActiveTimestamp = millis(); |  |  |         lastTimeActiveTimestamp = millis(); | 
		
	
		
			
				|  |  |         free(currentRfidTagId); |  |  |         free(currentRfidTagId); | 
		
	
		
			
				|  |  |         currentRfidTagId = strdup(rfidTagId); |  |  |  | 
		
	
		
			
				|  |  |  |  |  |         currentRfidTagId = x_strdup(rfidTagId); | 
		
	
		
			
				|  |  |         free(rfidTagId); |  |  |         free(rfidTagId); | 
		
	
		
			
				|  |  |         snprintf(logBuf, serialLoglength, "%s: %s", (char *) FPSTR(rfidTagReceived), currentRfidTagId); |  |  |         snprintf(logBuf, serialLoglength, "%s: %s", (char *) FPSTR(rfidTagReceived), currentRfidTagId); | 
		
	
		
			
				|  |  |         sendWebsocketData(0, 10);       // Push new rfidTagId to all websocket-clients
 |  |  |         sendWebsocketData(0, 10);       // Push new rfidTagId to all websocket-clients
 | 
		
	
	
		
			
				|  | @ -3707,11 +3728,8 @@ bool processJsonRequest(char *_serialJson) { | 
		
	
		
			
				|  |  | // Sends JSON-answers via websocket
 |  |  | // Sends JSON-answers via websocket
 | 
		
	
		
			
				|  |  | void sendWebsocketData(uint32_t client, uint8_t code) { |  |  | void sendWebsocketData(uint32_t client, uint8_t code) { | 
		
	
		
			
				|  |  |     char *jBuf; |  |  |     char *jBuf; | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |     jBuf = (char *) ps_calloc(255, sizeof(char)); |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |     jBuf = (char *) calloc(255, sizeof(char));          // In heap to save static memory
 |  |  |  | 
		
	
		
			
				|  |  | } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     jBuf = (char *) x_calloc(255, sizeof(char)); | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |     const size_t CAPACITY = JSON_OBJECT_SIZE(1) + 20; |  |  |     const size_t CAPACITY = JSON_OBJECT_SIZE(1) + 20; | 
		
	
		
			
				|  |  |     StaticJsonDocument<CAPACITY> doc; |  |  |     StaticJsonDocument<CAPACITY> doc; | 
		
	
		
			
				|  |  |     JsonObject object = doc.to<JsonObject>(); |  |  |     JsonObject object = doc.to<JsonObject>(); | 
		
	
	
		
			
				|  | @ -4522,11 +4540,7 @@ void printWakeUpReason() { | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  | void setup() { |  |  | void setup() { | 
		
	
		
			
				|  |  |     Serial.begin(115200); |  |  |     Serial.begin(115200); | 
		
	
		
			
				|  |  |     if (psramInit()) { |  |  |  | 
		
	
		
			
				|  |  |         logBuf = (char*) ps_calloc(serialLoglength, sizeof(char)); // Buffer for all log-messages
 |  |  |  | 
		
	
		
			
				|  |  |     } else { |  |  |  | 
		
	
		
			
				|  |  |         logBuf = (char*) calloc(serialLoglength, sizeof(char)); // Buffer for all log-messages
 |  |  |  | 
		
	
		
			
				|  |  |     } |  |  |  | 
		
	
		
			
				|  |  |  |  |  |     logBuf = (char*) x_calloc(serialLoglength, sizeof(char)); // Buffer for all log-messages
 | 
		
	
		
			
				|  |  |     #if (WAKEUP_BUTTON <= 39)
 |  |  |     #if (WAKEUP_BUTTON <= 39)
 | 
		
	
		
			
				|  |  |         esp_sleep_enable_ext0_wakeup((gpio_num_t) WAKEUP_BUTTON, 0); |  |  |         esp_sleep_enable_ext0_wakeup((gpio_num_t) WAKEUP_BUTTON, 0); | 
		
	
		
			
				|  |  |     #endif
 |  |  |     #endif
 | 
		
	
	
		
			
				|  | 
 |