/*****************************************************************************
 Debug macros.

Copyright (C) 1997-2017 AudioScience, Inc. All rights reserved.

This software is provided 'as-is', without any express or implied warranty.
In no event will AudioScience Inc. be held liable for any damages arising
from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This copyright notice and list of conditions may not be altered or removed
   from any source distribution.

AudioScience, Inc. <support@audioscience.com>

( This license is GPL compatible see http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses )

*****************************************************************************/

#ifndef _HPIDEBUG_H
#define _HPIDEBUG_H

#ifdef HPI_BUILD_INCLUDE_INTERNAL
#include "hpi_internal.h"
#else
#include "hpi.h"
#endif

#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif

/* Define debugging levels.  */
enum { HPI_DEBUG_LEVEL_ERROR    = 0, /* Always log errors */
	HPI_DEBUG_LEVEL_WARNING = 1,
	HPI_DEBUG_LEVEL_NOTICE  = 2,
	HPI_DEBUG_LEVEL_INFO    = 3,
	HPI_DEBUG_LEVEL_DEBUG   = 4,
	HPI_DEBUG_LEVEL_VERBOSE = 5	/* Same printk level as DEBUG */
};

#ifndef HPI_DEBUG_LEVEL_DEFAULT
#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
#endif

/* an OS can define an extra flag string that is appended to
   the start of each message, eg see linux kernel hpios.h */
#ifndef HPI_DEBUG_FLAG_ERROR
#define HPI_DEBUG_FLAG_ERROR
#define HPI_DEBUG_FLAG_WARNING
#define HPI_DEBUG_FLAG_NOTICE
#define HPI_DEBUG_FLAG_INFO
#define HPI_DEBUG_FLAG_DEBUG
#define HPI_DEBUG_FLAG_VERBOSE
#endif

#ifndef HPI_BUILD_SANITISE
/* OSes without printf-like function must provide plain string output
   and define HPIOS_DEBUG_PRINT to the name of this function.
   The printf functionality then provided by hpidebug.c::hpi_debug_printf
*/
// Default DBG character type definitions.

#ifndef DBG_TEXT
#define DBG_TEXT(s) s
#define DBG_CHAR char
#endif

#if defined HPIOS_DEBUG_PRINT && !defined HPIOS_DEBUG_PRINTF
#define HPIOS_DEBUG_PRINTF hpi_debug_printf
void hpi_debug_printf(DBG_CHAR *fmt, ...);
#endif

#if !defined HPIOS_DEBUG_PRINT && !defined HPIOS_DEBUG_PRINTF  && defined HPI_BUILD_DEBUG
#undef HPI_BUILD_DEBUG
#ifdef _MSC_VER
#pragma message ("Warning: Can't debug with this build because no debug print functions defined")
#else
#warning Can not debug with this build because no debug print functions defined
#endif
#endif
#endif

#ifdef SOURCEFILE_NAME
#ifndef FILE_LINE
#define FILE_LINE  DBG_TEXT(SOURCEFILE_NAME) DBG_TEXT(":") DBG_TEXT(__stringify(__LINE__)) DBG_TEXT(" ")
#endif
#else
#ifndef FILE_LINE
#define FILE_LINE  DBG_TEXT(__FILE__) DBG_TEXT(":") DBG_TEXT(__stringify(__LINE__)) DBG_TEXT(" ")
#endif
#endif

#ifdef HPI_BUILD_DEBUG
#if defined(HPI_OS_WIN32_USER) || defined(HPI_OS_WDM)
#ifdef HPI_OS_WIN32_USER
#define HPI_DEBUG_BREAK		DebugBreak
#else // HPI_OS_WDM
#define HPI_DEBUG_BREAK		DbgBreakPoint
#endif
#define HPI_DEBUG_ASSERT(_expression) \
	do { \
		if (!(_expression)) { \
			HPIOS_DEBUG_PRINTF( HPI_DEBUG_FLAG_ERROR  FILE_LINE \
				DBG_TEXT("ASSERT ") DBG_TEXT(__stringify(_expression))); \
			HPI_DEBUG_BREAK(); \
		} \
	} while (0)
#else
#define HPI_DEBUG_ASSERT(_expression) \
	do { \
		if (!(_expression)) { \
			HPIOS_DEBUG_PRINTF( HPI_DEBUG_FLAG_ERROR  FILE_LINE \
				DBG_TEXT("ASSERT ") DBG_TEXT(__stringify(_expression))); \
		} \
	} while (0)
#endif

#if defined HPI_OS_LINUX_KERNEL || defined HPI_OS_OSX
#define HPI_DEBUG_LOG(level, ...) \
	do { \
		if (hpiDebugLevel >= HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF(HPI_DEBUG_FLAG_##level \
                        FILE_LINE  __VA_ARGS__); \
		} \
	} while (0)
#ifndef HPI_BUILD_SANITISE
#define HPI_DEBUG_LOG0 HPI_DEBUG_LOG
#define HPI_DEBUG_LOG1 HPI_DEBUG_LOG
#define HPI_DEBUG_LOG2 HPI_DEBUG_LOG
#define HPI_DEBUG_LOG3 HPI_DEBUG_LOG
#define HPI_DEBUG_LOG4 HPI_DEBUG_LOG
#define HPI_DEBUG_LOG5 HPI_DEBUG_LOG
#endif
#else
#define HPI_DEBUG_LOG0(level,fmt) \
	do { \
		if (hpiDebugLevel >= HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF( HPI_DEBUG_FLAG_##level  FILE_LINE \
				DBG_TEXT(__stringify(level))  DBG_TEXT(" ") DBG_TEXT(fmt)); \
		} \
	} while (0)

#define HPI_DEBUG_LOG1(level,fmt,p1) \
	do { \
		if (hpiDebugLevel >= HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF( HPI_DEBUG_FLAG_##level  FILE_LINE \
				DBG_TEXT(__stringify(level))  DBG_TEXT(" ") DBG_TEXT(fmt),p1); \
		} \
	} while (0)

#define HPI_DEBUG_LOG2(level,fmt,p1,p2) \
	do { \
		if (hpiDebugLevel>=HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF(HPI_DEBUG_FLAG_##level FILE_LINE \
				DBG_TEXT(__stringify(level)) DBG_TEXT(" ") DBG_TEXT(fmt),p1,p2); \
		} \
	} while (0)

#define HPI_DEBUG_LOG3(level,fmt,p1,p2,p3) \
	do { \
		if (hpiDebugLevel>=HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF(HPI_DEBUG_FLAG_##level FILE_LINE \
				DBG_TEXT(__stringify(level)) DBG_TEXT(" ") DBG_TEXT(fmt),p1,p2,p3); \
		} \
	} while (0)

#define HPI_DEBUG_LOG4(level,fmt,p1,p2,p3,p4) \
	do { \
		if (hpiDebugLevel>=HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF(HPI_DEBUG_FLAG_##level FILE_LINE \
				DBG_TEXT(__stringify(level)) DBG_TEXT(" ") DBG_TEXT(fmt),p1,p2,p3,p4); \
		} \
	} while (0)
#define HPI_DEBUG_LOG5(level,fmt,p1,p2,p3,p4,p5) \
	do { \
		if (hpiDebugLevel>=HPI_DEBUG_LEVEL_##level) { \
			HPIOS_DEBUG_PRINTF(HPI_DEBUG_FLAG_##level FILE_LINE \
				DBG_TEXT(__stringify(level)) DBG_TEXT(" ") DBG_TEXT(fmt),p1,p2,p3,p4,p5); \
		} \
	} while (0)
#endif /* if HPI_OS_LINUX else */

#else
#define HPI_DEBUG_ASSERT(_expression)
#define HPI_DEBUG_LOG0(level,fmt)
#define HPI_DEBUG_LOG1(level,fmt,p1)
#define HPI_DEBUG_LOG2(level,fmt,p1,p2)
#define HPI_DEBUG_LOG3(level,fmt,p1,p2,p3)
#define HPI_DEBUG_LOG4(level,fmt,p1,p2,p3,p4)
#define HPI_DEBUG_LOG5(level,fmt,p1,p2,p3,p4,p5)
#endif

void HPI_DebugInit(void);
int HPI_DebugLevelSet(int level);
int HPI_DebugLevelGet(void);
// needed by Linux driver for dynamic debug level changes
extern int hpiDebugLevel;

#ifndef HPI_OS_LINUX_KERNEL
extern int hpiDebugHaltOnFatal;
int HPI_DebugSetHaltOnFatal(int onoff);
#endif

#if defined HPI_BUILD_INCLUDE_INTERNAL

void hpi_debug_message(
	struct hpi_message *phm,
	DBG_CHAR *szFileline
);

void hpi_debug_data(uint16_t *pdata, uint32_t len);

#ifndef HPI_DEBUG_DATA
#define HPI_DEBUG_DATA(pdata, len) \
	do { \
		if (hpiDebugLevel >= HPI_DEBUG_LEVEL_VERBOSE) \
			hpi_debug_data(pdata, len); \
	} while (0)
#endif

#ifndef HPI_DEBUG_MESSAGE
#define HPI_DEBUG_MESSAGE(level, phm) \
	do { \
		if (hpiDebugLevel >= HPI_DEBUG_LEVEL_##level) { \
			hpi_debug_message(phm, HPI_DEBUG_FLAG_##level \
				FILE_LINE DBG_TEXT(__stringify(level))); \
		} \
	} while (0)
#endif

#ifndef HPI_DEBUG_RESPONSE
#ifndef HPI_OS_LINUX_KERNEL
#define HPI_DEBUG_RESPONSE(phr) \
	do { \
		char err_string[64]; \
		if ((hpiDebugLevel >= HPI_DEBUG_LEVEL_DEBUG) && (phr->wError)) { \
			HPI_GetErrorText(phr->wError, err_string); \
			HPI_DEBUG_LOG3(ERROR, \
				DBG_TEXT("#%d, %s, %d\n"), \
				phr->wError,  err_string, phr->wSpecificError); \
		} else if (hpiDebugLevel >= HPI_DEBUG_LEVEL_VERBOSE) { \
			HPI_DEBUG_LOG0(VERBOSE, DBG_TEXT("HPI Response OK \n")); \
		} \
		if (hpiDebugHaltOnFatal && \
			(phr->wError >= HPI_ERROR_DSP_COMMUNICATION) && \
			(hpiDebugLevel != -1)) { \
				HPI_DEBUG_LOG0(ERROR, DBG_TEXT("Fatal error; logging halted.\n")); \
				hpiDebugLevel = -1; \
		} \
	} while (0)
#else
#define HPI_DEBUG_RESPONSE(phr) \
	do { \
		if (((hpiDebugLevel >= HPI_DEBUG_LEVEL_DEBUG) && \
			((phr)->wError)) ||\
		(hpiDebugLevel >= HPI_DEBUG_LEVEL_VERBOSE)) \
			printk(KERN_DEBUG "HPI_RES%d,%d,%d\n", \
				(phr)->version, (phr)->wError, (phr)->wSpecificError); \
	} while (0)
#endif
#endif

#endif

#if ! (defined HPI_BUILD_DEBUG)
#undef HPI_DEBUG_DATA
#undef HPI_DEBUG_MESSAGE
#undef HPI_DEBUG_RESPONSE
#undef HPIOS_DEBUG_PRINTF

#define HPI_DEBUG_DATA(x,y)
#define HPI_DEBUG_MESSAGE(l, x)
#define HPI_DEBUG_RESPONSE(x)
#ifdef __GNUC__
#define HPIOS_DEBUG_PRINTF(...)
#else
#define HPIOS_DEBUG_PRINTF
#endif
#endif

#ifndef compile_time_assert
#define compile_time_assert(cond, msg) \
    typedef char msg[(cond) ? 1 : -1]
#endif

#ifndef HPI_OS_LINUX_KERNEL
#ifdef HPI_BUILD_INCLUDE_INTERNAL
	  /* check that size is exactly some number */
#define function_count_check(sym, size) \
    compile_time_assert((sym##_FUNCTION_COUNT) == (size), \
            strings_match_defs_##sym)

/* These strings should be generated using a macro which defines
   the corresponding symbol values.  */

#ifdef HPI_OS_DELETE
/*? Not used anywhere */
#define HPI_OBJ_STRINGS \
{ \
  DBG_TEXT("SUBSYSTEM"), \
  DBG_TEXT("ADAPTER"), \
  DBG_TEXT("OSTREAM"), \
  DBG_TEXT("ISTREAM"), \
  DBG_TEXT("MIXER"), \
  DBG_TEXT("NODE"), \
  DBG_TEXT("CONTROL"), \
  DBG_TEXT("NVMEMORY"), \
  DBG_TEXT("DIGITALIO"), \
  DBG_TEXT("WATCHDOG"), \
  DBG_TEXT("CLOCK"), \
  DBG_TEXT("PROFILE"), \
  DBG_TEXT("CONTROLEX"), \
  DBG_TEXT("ASYNCEVENT") \
}
#endif

#define HPI_SUBSYS_STRINGS \
{ \
  DBG_TEXT("SUBSYS_OPEN"), \
  DBG_TEXT("SUBSYS_GET_VERSION"), \
  DBG_TEXT("SUBSYS_GET_INFO"), \
  DBG_TEXT("SUBSYS_FIND_ADAPTERS"), \
  DBG_TEXT("SUBSYS_CREATE_ADAPTER"), \
  DBG_TEXT("SUBSYS_CLOSE"), \
  DBG_TEXT("SUBSYS_DELETE_ADAPTER"), \
  DBG_TEXT("SUBSYS_DRIVER_LOAD"), \
  DBG_TEXT("SUBSYS_DRIVER_UNLOAD"), \
  DBG_TEXT("SUBSYS_READ_PORT_8"), \
  DBG_TEXT("SUBSYS_WRITE_PORT_8"), \
  DBG_TEXT("SUBSYS_GET_NUM_ADAPTERS"), \
  DBG_TEXT("SUBSYS_GET_ADAPTER"), \
  DBG_TEXT("SUBSYS_SET_NETWORK_INTERFACE"), \
  DBG_TEXT("SUBSYS_ENTITY_INFO"), \
  DBG_TEXT("SUBSYS_ENTITY_GET"), \
  DBG_TEXT("SUBSYS_ENTITY_SET"), \
  DBG_TEXT("SUBSYS_WAKE_ADAPTER"), \
}
function_count_check(HPI_SUBSYS, 18);

#define HPI_ADAPTER_STRINGS \
{ \
  DBG_TEXT("ADAPTER_OPEN"), \
  DBG_TEXT("ADAPTER_CLOSE"), \
  DBG_TEXT("ADAPTER_GET_INFO"), \
  DBG_TEXT("ADAPTER_GET_ASSERT"), \
  DBG_TEXT("ADAPTER_TEST_ASSERT"), \
  DBG_TEXT("ADAPTER_SET_MODE"), \
  DBG_TEXT("ADAPTER_GET_MODE"), \
  DBG_TEXT("ADAPTER_ENABLE_CAPABILITY"), \
  DBG_TEXT("ADAPTER_SELFTEST"), \
  DBG_TEXT("ADAPTER_FIND_OBJECT"), \
  DBG_TEXT("ADAPTER_QUERY_FLASH"), \
  DBG_TEXT("ADAPTER_START_FLASH"), \
  DBG_TEXT("ADAPTER_PROGRAM_FLASH"), \
  DBG_TEXT("ADAPTER_SET_PROPERTY"), \
  DBG_TEXT("ADAPTER_GET_PROPERTY"), \
  DBG_TEXT("ADAPTER_ENUM_PROPERTY"), \
  DBG_TEXT("ADAPTER_MODULE_INFO"), \
  DBG_TEXT("ADAPTER_DEBUG_READ"), \
  DBG_TEXT("ADAPTER_IRQ_QUERY_AND_CLEAR"), \
  DBG_TEXT("ADAPTER_IRQ_CALLBACK"), \
  DBG_TEXT("ADAPTER_DELETE"), \
  DBG_TEXT("ADAPTER_READ_FLASH"), \
  DBG_TEXT("ADAPTER_END_FLASH"), \
  DBG_TEXT("ADAPTER_FILESTORE_DELETE_ALL"), \
}

function_count_check(HPI_ADAPTER, 24);

#define HPI_OSTREAM_STRINGS \
{ \
  DBG_TEXT("OSTREAM_OPEN"), \
  DBG_TEXT("OSTREAM_CLOSE"), \
  DBG_TEXT("OSTREAM_WRITE"), \
  DBG_TEXT("OSTREAM_START"), \
  DBG_TEXT("OSTREAM_STOP"), \
  DBG_TEXT("OSTREAM_RESET"), \
  DBG_TEXT("OSTREAM_GET_INFO"), \
  DBG_TEXT("OSTREAM_QUERY_FORMAT"), \
  DBG_TEXT("OSTREAM_DATA"), \
  DBG_TEXT("OSTREAM_SET_VELOCITY"), \
  DBG_TEXT("OSTREAM_SET_PUNCHINOUT"), \
  DBG_TEXT("OSTREAM_SINEGEN"), \
  DBG_TEXT("OSTREAM_ANC_RESET"), \
  DBG_TEXT("OSTREAM_ANC_GET_INFO"), \
  DBG_TEXT("OSTREAM_ANC_READ"), \
  DBG_TEXT("OSTREAM_SET_TIMESCALE"), \
  DBG_TEXT("OSTREAM_SET_FORMAT"), \
  DBG_TEXT("OSTREAM_HOSTBUFFER_ALLOC"), \
  DBG_TEXT("OSTREAM_HOSTBUFFER_FREE"), \
  DBG_TEXT("OSTREAM_GROUP_ADD"), \
  DBG_TEXT("OSTREAM_GROUP_GETMAP"), \
  DBG_TEXT("OSTREAM_GROUP_RESET"), \
  DBG_TEXT("OSTREAM_HOSTBUFFER_GET_INFO"), \
  DBG_TEXT("OSTREAM_WAIT_START"), \
  DBG_TEXT("OSTREAM_WAIT"), \
  DBG_TEXT("OSTREAM_GET_TIMESTAMP"), \
}
function_count_check(HPI_OSTREAM, 26);

#define HPI_ISTREAM_STRINGS \
{ \
  DBG_TEXT("ISTREAM_OPEN"), \
  DBG_TEXT("ISTREAM_CLOSE"), \
  DBG_TEXT("ISTREAM_SET_FORMAT"), \
  DBG_TEXT("ISTREAM_READ"), \
  DBG_TEXT("ISTREAM_START"), \
  DBG_TEXT("ISTREAM_STOP"), \
  DBG_TEXT("ISTREAM_RESET"), \
  DBG_TEXT("ISTREAM_GET_INFO"), \
  DBG_TEXT("ISTREAM_QUERY_FORMAT"), \
  DBG_TEXT("ISTREAM_ANC_RESET"), \
  DBG_TEXT("ISTREAM_ANC_GET_INFO"), \
  DBG_TEXT("ISTREAM_ANC_WRITE"), \
  DBG_TEXT("ISTREAM_HOSTBUFFER_ALLOC"), \
  DBG_TEXT("ISTREAM_HOSTBUFFER_FREE"), \
  DBG_TEXT("ISTREAM_GROUP_ADD"), \
  DBG_TEXT("ISTREAM_GROUP_GETMAP"), \
  DBG_TEXT("ISTREAM_GROUP_RESET"), \
  DBG_TEXT("ISTREAM_HOSTBUFFER_GET_INFO"), \
  DBG_TEXT("ISTREAM_WAIT_START"), \
  DBG_TEXT("ISTREAM_WAIT"), \
  DBG_TEXT("ISTREAM_GET_TIMESTAMP"), \
}
function_count_check(HPI_ISTREAM, 21);

#define HPI_MIXER_STRINGS \
{ \
  DBG_TEXT("MIXER_OPEN"), \
  DBG_TEXT("MIXER_CLOSE"), \
  DBG_TEXT("MIXER_GET_INFO"), \
  DBG_TEXT("MIXER_GET_NODE_INFO"), \
  DBG_TEXT("MIXER_GET_CONTROL"), \
  DBG_TEXT("MIXER_SET_CONNECTION"), \
  DBG_TEXT("MIXER_GET_CONNECTIONS"), \
  DBG_TEXT("MIXER_GET_CONTROL_BY_INDEX"), \
  DBG_TEXT("MIXER_GET_CONTROL_ARRAY_BY_INDEX"), \
  DBG_TEXT("MIXER_GET_CONTROL_MULTIPLE_VALUES"), \
  DBG_TEXT("MIXER_STORE"), \
  DBG_TEXT("HPI_MIXER_GET_CACHE_INFO"), \
  DBG_TEXT("HPI_MIXER_GET_BLOCK_HANDLE"), \
  DBG_TEXT("HPI_MIXER_GET_PARAMETER_HANDLE"), \
  DBG_TEXT("HPI_MIXER_STORE_STATUS"), \
}
function_count_check(HPI_MIXER, 15);

#define HPI_CONTROL_STRINGS \
{ \
  DBG_TEXT("CONTROL_GET_INFO"), \
  DBG_TEXT("CONTROL_GET_STATE"), \
  DBG_TEXT("CONTROL_SET_STATE") \
}
function_count_check(HPI_CONTROL, 3);

#define HPI_NVMEMORY_STRINGS \
{ \
  DBG_TEXT("NVMEMORY_OPEN"), \
  DBG_TEXT("NVMEMORY_READ_BYTE"), \
  DBG_TEXT("NVMEMORY_WRITE_BYTE") \
}
function_count_check(HPI_NVMEMORY, 3);

#define HPI_DIGITALIO_STRINGS \
{ \
  DBG_TEXT("GPIO_OPEN"), \
  DBG_TEXT("GPIO_READ_BIT"), \
  DBG_TEXT("GPIO_WRITE_BIT"), \
  DBG_TEXT("GPIO_READ_ALL"), \
  DBG_TEXT("GPIO_WRITE_STATUS") \
}
function_count_check(HPI_GPIO, 5);

#define HPI_WATCHDOG_STRINGS \
{ \
  DBG_TEXT("WATCHDOG_OPEN"), \
  DBG_TEXT("WATCHDOG_SET_TIME"), \
  DBG_TEXT("WATCHDOG_PING") \
}

#define HPI_CLOCK_STRINGS \
{ \
  DBG_TEXT("CLOCK_OPEN"), \
  DBG_TEXT("CLOCK_SET_TIME"), \
  DBG_TEXT("CLOCK_GET_TIME") \
}

#define HPI_PROFILE_STRINGS \
{ \
  DBG_TEXT("PROFILE_OPEN_ALL"), \
  DBG_TEXT("PROFILE_START_ALL"), \
  DBG_TEXT("PROFILE_STOP_ALL"), \
  DBG_TEXT("PROFILE_GET"), \
  DBG_TEXT("PROFILE_GET_IDLECOUNT"), \
  DBG_TEXT("PROFILE_GET_NAME"), \
  DBG_TEXT("PROFILE_GET_UTILIZATION") \
}
function_count_check(HPI_PROFILE, 7);

#define HPI_ASYNCEVENT_STRINGS \
{ \
  DBG_TEXT("ASYNCEVENT_OPEN"), \
  DBG_TEXT("ASYNCEVENT_CLOSE  "), \
  DBG_TEXT("ASYNCEVENT_WAIT"), \
  DBG_TEXT("ASYNCEVENT_GETCOUNT"), \
  DBG_TEXT("ASYNCEVENT_GET"), \
  DBG_TEXT("ASYNCEVENT_SENDEVENTS") \
}
function_count_check(HPI_ASYNCEVENT, 6);

#endif /* ifdef HPI_BUILD_INCLUDE_INTERNAL */


#define HPI_CONTROL_TYPE_STRINGS \
{ \
	DBG_TEXT("null control"), \
	DBG_TEXT("CONNECTION"), \
	DBG_TEXT("VOLUME"), \
	DBG_TEXT("METER"), \
	DBG_TEXT("MUTE"), \
	DBG_TEXT("MULTIPLEXER"), \
	DBG_TEXT("AESEBU_TRANSMITTER"), \
	DBG_TEXT("AESEBU_RECEIVER"), \
	DBG_TEXT("LEVEL"), \
	DBG_TEXT("TUNER"), \
	DBG_TEXT("ONOFFSWITCH"), \
	DBG_TEXT("VOX"), \
	DBG_TEXT("AES18_TRANSMITTER"), \
	DBG_TEXT("AES18_RECEIVER"), \
	DBG_TEXT("AES18_BLOCKGENERATOR"), \
	DBG_TEXT("CHANNEL_MODE"), \
	DBG_TEXT("BITSTREAM"), \
	DBG_TEXT("SAMPLECLOCK"), \
	DBG_TEXT("MICROPHONE"), \
	DBG_TEXT("PARAMETRIC_EQ"), \
	DBG_TEXT("COMPANDER"), \
	DBG_TEXT("COBRANET"), \
	DBG_TEXT("TONE_DETECT"), \
	DBG_TEXT("SILENCE_DETECT"), \
	DBG_TEXT("PAD"), \
	DBG_TEXT("SRC") , \
	DBG_TEXT("UNIVERSAL") \
}

compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
		    controltype_strings_match_defs);

#define HPI_SOURCENODE_STRINGS \
{ \
	DBG_TEXT("no source"), \
	DBG_TEXT("SOURCENODE_OSTREAM"), \
	DBG_TEXT("SOURCENODE_LINEIN"), \
	DBG_TEXT("SOURCENODE_AESEBU_IN"), \
	DBG_TEXT("SOURCENODE_TUNER"), \
	DBG_TEXT("SOURCENODE_RF"), \
	DBG_TEXT("SOURCENODE_CLOCK_SOURCE"), \
	DBG_TEXT("SOURCENODE_RAW_BITSTREAM"), \
	DBG_TEXT("SOURCENODE_MICROPHONE"), \
	DBG_TEXT("SOURCENODE_COBRANET"), \
	DBG_TEXT("SOURCENODE_ANALOG"), \
	DBG_TEXT("SOURCENODE_ADAPTER"), \
	DBG_TEXT("SOURCENODE_RTP"), \
	DBG_TEXT("SOURCENODE_INTERNAL"), \
	DBG_TEXT("SOURCENODE_AVB_STREAM"), \
	DBG_TEXT("SOURCENODE_BLULINK"), \
	DBG_TEXT("SOURCENODE_AVB_AUDIO") \
}

compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_NONE + 1) ==
		    (17), sourcenode_strings_match_defs);

#define HPI_DESTNODE_STRINGS \
{ \
	DBG_TEXT("no destination"), \
	DBG_TEXT("DESTNODE_ISTREAM"), \
	DBG_TEXT("DESTNODE_LINEOUT"), \
	DBG_TEXT("DESTNODE_AESEBU_OUT"), \
	DBG_TEXT("DESTNODE_RF"), \
	DBG_TEXT("DESTNODE_SPEAKER"), \
	DBG_TEXT("DESTNODE_COBRANET"), \
	DBG_TEXT("DESTNODE_ANALOG"), \
	DBG_TEXT("DESTNODE_RTP"), \
	DBG_TEXT("DESTNODE_AVB_STREAM"), \
	DBG_TEXT("DESTNODE_INTERNAL"), \
	DBG_TEXT("DESTNODE_BLULINK"), \
	DBG_TEXT("DESTNODE_AVB_AUDIO") \
}
compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_NONE + 1) == (13),
		    destnode_strings_match_defs);

#ifdef HPI_OS_DELETE
/*? Not used anywhere */
#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
{ \
	DBG_TEXT("channel_mode_invalid"), \
	DBG_TEXT("CHANNEL_MODE_NORMAL"), \
	DBG_TEXT("CHANNEL_MODE_SWAP"), \
	DBG_TEXT("CHANNEL_MODE_LEFT_ONLY"), \
	DBG_TEXT("CHANNEL_MODE_RIGHT_ONLY") \
}
#endif

#ifndef HPI_OS_LINUX_KERNEL
void hpidebug_backend_error(void *ep, uint16_t wError, const DBG_CHAR **ep_name, const DBG_CHAR **err_name);
#endif

#ifdef SGT_SERIAL_LOGGING
void HpiDebug_SerialLog_Init(void);
void HpiDebug_SerialLog_SendBuffer(char *pszBuffer);
#endif

#endif /* #ifndef HPI_OS_LINUX_KERNEL */

#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#endif /* _HPIDEBUG_H_  */
