Files
squeezelite-esp32/components/tools/tools.h
2025-03-18 17:38:34 -04:00

353 lines
12 KiB
C

/*
*
* Sebastien L. 2023, sle118@hotmail.com
* Philippe G. 2023, philippe_44@outlook.com
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*
* License Overview:
* ----------------
* The MIT License is a permissive open source license. As a user of this software, you are free to:
* - Use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of this software.
* - Use the software for private, commercial, or any other purposes.
*
* Conditions:
* - You must include the above copyright notice and this permission notice in all
* copies or substantial portions of the Software.
*
* The MIT License offers a high degree of freedom and is well-suited for both open source and
* commercial applications. It places minimal restrictions on how the software can be used,
* modified, and redistributed. For more details on the MIT License, please refer to the link above.
*/
#pragma once
#include "esp_log.h"
#include "cJSON.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#ifdef __cplusplus
#include "cpp_tools.h"
extern "C" {
#endif
/**
* @def QUOTE
* Converts the argument name into a string.
*
* @param name The name to be converted into a string.
*/
#ifndef QUOTE
#define QUOTE(name) #name
#endif
/**
* @def STR
* Converts a macro value into a string.
*
* @param macro The macro whose value is to be converted into a string.
*/
#ifndef STR
#define STR(macro) QUOTE(macro)
#endif
/**
* @def STR_OR_ALT
* Returns the string 'str' or an alternative 'alt' if 'str' is NULL.
*
* @param str The string to check.
* @param alt The alternative string to return if 'str' is NULL.
*/
#ifndef STR_OR_ALT
#ifdef __cplusplus
#define STR_OR_ALT(str, alt) (str!=nullptr ? str : alt)
#else
#define STR_OR_ALT(str, alt) (str ? str : alt)
#endif
#endif
/**
* @def STR_OR_BLANK
* Returns the string 'p' or an empty string if 'p' is NULL.
*
* @param p The string to check.
*/
#ifndef STR_OR_BLANK
#ifdef __cplusplus
#define STR_OR_BLANK(p) p == nullptr ? "" : p
#else
#define STR_OR_BLANK(p) p == NULL ? "" : p
#endif
#endif
/**
* @def ESP_LOG_DEBUG_EVENT
* Logs a debug event with a given tag.
*
* @param tag The tag associated with the log message.
* @param e The event to log.
*/
#define ESP_LOG_DEBUG_EVENT(tag, e) ESP_LOGD(tag, "evt: " e)
/**
* @def FREE_AND_NULL
* Frees a pointer if it's not NULL and sets it to NULL.
*
* @param x The pointer to free and nullify.
*/
#ifndef FREE_AND_NULL
#define FREE_AND_NULL(x) \
if (x) { \
free(x); \
x = NULL; \
}
#endif
/**
* @def CASE_TO_STR
* A switch case that returns the string representation of a case constant.
*
* @param x The case constant.
*/
#ifndef CASE_TO_STR
#define CASE_TO_STR(x) \
case x: \
return STR(x); \
break;
#endif
/**
* @def ENUM_TO_STRING
* A switch case for an enum that returns the string representation of the enum value.
*
* @param g The enum value.
*/
#define ENUM_TO_STRING(g) \
case g: \
return STR(g); \
break;
/**
* @fn void utf8_decode(char* src)
* Decodes a string encoded in UTF-8 to CP1252 in place.
* The result is stored in the same buffer as the input.
*
* @param src A pointer to the null-terminated string to be decoded.
*/
void utf8_decode(char* src);
/**
* @fn void* malloc_init_external(size_t sz)
* Allocates memory in PSRAM and initializes it to zero.
*
* This function attempts to allocate a block of memory of size 'sz' in PSRAM.
* If allocation is successful, the memory is initialized to zero.
*
* @param sz The size of memory to allocate in bytes.
* @return A pointer to the allocated memory block or NULL if allocation fails.
*/
void* malloc_init_external(size_t sz);
/**
* @fn void* clone_obj_psram(void* source, size_t source_sz)
* Clones an object into PSRAM.
*
* This function allocates memory in PSRAM and copies the contents of the
* source object into the newly allocated memory. The size of the source
* object is specified by 'source_sz'.
*
* @param source A pointer to the source object to clone.
* @param source_sz The size of the source object in bytes.
* @return A pointer to the cloned object in PSRAM or NULL if allocation fails.
*/
void* clone_obj_psram(void* source, size_t source_sz);
/**
* @fn char* strdup_psram(const char* source)
* Duplicates a string into PSRAM.
*
* This function allocates enough memory in PSRAM to hold a copy of 'source',
* including the null terminator, and then copies the string into the new memory.
*
* @param source A pointer to the null-terminated string to duplicate.
* @return A pointer to the duplicated string in PSRAM or NULL if allocation fails.
*/
char* strdup_psram(const char* source);
/**
* @fn const char* get_mem_flag_desc(int flags)
* Returns a string describing memory allocation flags.
*
* This function takes memory allocation flags as an argument and returns
* a string representation of these flags. The description includes various
* memory capabilities like EXEC, DMA, SPIRAM, etc.
*
* @param flags The memory allocation flags to describe.
* @return A string representation of the memory allocation flags.
*/
const char* get_mem_flag_desc(int flags);
/**
* @fn const char* get_mac_str()
* Returns a string representation of the device's MAC address.
*
* This function reads the MAC address of the device and returns a string
* representation of the last three bytes of the MAC address. It uses a static
* buffer to store the MAC address string.
*
* @return A string representation of the device's MAC address.
*/
const char* get_mac_str();
/**
* @fn char* alloc_get_string_with_mac(const char* val)
* Allocates a new string which is a concatenation of the provided value and the device's MAC address.
*
* This function concatenates 'val' with the device's MAC address string and returns
* a pointer to the newly allocated string.
*
* @param val The string to concatenate with the MAC address.
* @return A pointer to the newly allocated string, or NULL if allocation fails.
*/
char* alloc_get_string_with_mac(const char* val);
/**
* @fn char* alloc_get_fallback_unique_name()
* Allocates a unique name for the device based on predefined configurations or fallbacks.
*
* This function creates a unique name by concatenating a base name defined by
* configuration macros (CONFIG_LWIP_LOCAL_HOSTNAME, CONFIG_FW_PLATFORM_NAME)
* or a fallback prefix "squeezelite-" with the device's MAC address.
*
* @return A pointer to the newly allocated unique name, or NULL if allocation fails.
*/
char* alloc_get_fallback_unique_name();
/**
* @fn char* alloc_get_formatted_mac_string(uint8_t mac[6])
* Allocates and returns a formatted MAC address string.
*
* This function formats a given MAC address into a human-readable string,
* allocating the necessary memory dynamically.
*
* @param mac An array containing the 6-byte MAC address.
* @return A pointer to the dynamically allocated MAC address string, or NULL if allocation fails.
*/
char* alloc_get_formatted_mac_string(uint8_t mac[6]);
/**
* @fn const char* str_or_unknown(const char* str)
* Returns the input string or a placeholder for unknown string.
*
* If the input string is not NULL, it returns the string. Otherwise,
* it returns a predefined placeholder for unknown strings.
*
* @param str The input string.
* @return The input string or a placeholder if the input is NULL.
*/
const char* str_or_unknown(const char* str);
/**
* @fn const char* str_or_null(const char* str)
* Returns the input string or a placeholder for null string.
*
* If the input string is not NULL, it returns the string. Otherwise,
* it returns a predefined placeholder for null strings.
*
* @param str The input string.
* @return The input string or a placeholder if the input is NULL.
*/
const char* str_or_null(const char* str);
/**
* @fn esp_log_level_t get_log_level_from_char(char* level)
* Converts a string representation of a log level to its corresponding `esp_log_level_t` enum value.
*
* The function supports log level strings like "NONE", "ERROR", "WARN", "INFO", "DEBUG", and "VERBOSE".
*
* @param level The log level as a string.
* @return The corresponding `esp_log_level_t` value, or ESP_LOG_WARN if the string does not match any log level.
*/
esp_log_level_t get_log_level_from_char(char* level);
/**
* @fn const char* get_log_level_desc(esp_log_level_t level)
* Returns the string description of a given `esp_log_level_t` log level.
*
* @param level The log level as an `esp_log_level_t` enum.
* @return The string description of the log level.
*/
const char* get_log_level_desc(esp_log_level_t level);
/**
* @fn void set_log_level(char* tag, char* level)
* Sets the log level for a specific tag.
*
* The log level is specified as a string and converted internally to the corresponding `esp_log_level_t` value.
*
* @param tag The tag for which to set the log level.
* @param level The log level as a string.
*/
void set_log_level(char* tag, char* level);
/**
* @fn BaseType_t xTaskCreateEXTRAM(TaskFunction_t pvTaskCode, const char* const pcName, configSTACK_DEPTH_TYPE usStackDepth, void* pvParameters,
* UBaseType_t uxPriority, TaskHandle_t* pxCreatedTask) Creates a new task with its stack allocated in external RAM (PSRAM). Use these to dynamically
* create tasks whose stack is on EXTRAM. Be aware that it requires configNUM_THREAD_LOCAL_STORAGE_POINTERS to bet set to 2 at least (index 0 is used
* by pthread and this uses index 1, obviously
*
* @param pvTaskCode Pointer to the task entry function.
* @param pcName Task name.
* @param usStackDepth Stack depth in words.
* @param pvParameters Pointer to the task's parameters.
* @param uxPriority Task priority.
* @param pxCreatedTask Pointer to a variable to store the task's handle.
* @return pdPASS on success, pdFAIL on failure.
*/
BaseType_t xTaskCreateEXTRAM(TaskFunction_t pvTaskCode, const char* const pcName, configSTACK_DEPTH_TYPE usStackDepth, void* pvParameters,
UBaseType_t uxPriority, TaskHandle_t* pxCreatedTask);
/**
* @fn void vTaskDeleteEXTRAM(TaskHandle_t xTask)
* Deletes a task and cleans up its allocated resources.
* This function should be used in place of vTaskDelete for tasks created with xTaskCreateEXTRAM.
*
* @param xTask Handle to the task to be deleted.
*/
void vTaskDeleteEXTRAM(TaskHandle_t xTask);
/**
* @fn void dump_json_content(const char* prefix, cJSON* json, int level)
* Dumps the content of a cJSON object to the log.
*
* @param prefix Prefix for the log message.
* @param json Pointer to the cJSON object to dump.
* @param level Logging level for the output.
*/
void dump_json_content(const char* prefix, cJSON* json, int level);
#ifndef gettime_ms
// body is provided somewhere else...
uint32_t _gettime_ms_(void);
#define gettime_ms _gettime_ms_
#endif
/**
* @def TRACE_DEBUG
* A macro for debug tracing.
*
* This macro prints a formatted debug message to the standard output.
* The message includes the name of the function and the line number from which
* the macro is called, followed by a custom formatted message.
*
* @param msgformat A printf-style format string for the custom message.
* @param ... Variable arguments for the format string.
*/
#ifndef TRACE_DEBUG
#define TRACE_DEBUG(msgformat, ...) printf("%-30s%-5d" msgformat "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
#ifdef __cplusplus
}
#endif