|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
debug.c
Abstract:
Routines for displaying debug messages.
Environment:
User Mode - Win32
--*/
#if DBG
///////////////////////////////////////////////////////////////////////////////
// //
// Include files //
// //
///////////////////////////////////////////////////////////////////////////////
#include "globals.h"
#include "provider.h"
#include "registry.h"
#include <stdio.h>
#include <stdarg.h>
#include <crtdbg.h>
///////////////////////////////////////////////////////////////////////////////
// //
// Private definitions //
// //
///////////////////////////////////////////////////////////////////////////////
#define DEBUG_FORMAT_HEADER "H323 "
#define DEBUG_FORMAT_TIMESTAMP "[%02u:%02u:%02u.%03u"
#define DEBUG_FORMAT_THREADID ",tid=%x] "
#define MAX_DEBUG_STRLEN 512
#define STATUS_MASK_ERROR 0x0000FFFF
#define STATUS_MASK_FACILITY 0x0FFF0000
///////////////////////////////////////////////////////////////////////////////
// //
// Private procedures //
// //
///////////////////////////////////////////////////////////////////////////////
VOID OutputDebugMessage( LPSTR pszDebugMessage )
/*++
Routine Description:
Writes debug message to specified log(s).
Args:
pszDebugMessage - zero-terminated string containing debug message.
Return Values:
None.
--*/
{ // initialize descriptor
static FILE * fd = NULL;
// check if logfile output specified
if (g_RegistrySettings.dwLogType & DEBUG_OUTPUT_FILE) {
// validate
if (fd == NULL) {
// attempt to open log file
fd = fopen(g_RegistrySettings.szLogFile, "w"); }
// validate
if (fd != NULL) {
// output entry to stream
fprintf(fd, "%s", pszDebugMessage);
// flush stream
fflush(fd); } }
// check if debugger output specified
if (g_RegistrySettings.dwLogType & DEBUG_OUTPUT_DEBUGGER) {
// output entry to debugger
OutputDebugStringA(pszDebugMessage); } }
///////////////////////////////////////////////////////////////////////////////
// //
// Public procedures //
// //
///////////////////////////////////////////////////////////////////////////////
VOID H323DbgPrint( DWORD dwLevel, LPSTR szFormat, ... ) /*++
Routine Description:
Debug output routine for service provider.
Arguments:
Same as printf.
Return Values:
None. --*/
{ va_list Args; SYSTEMTIME SystemTime; char szDebugMessage[MAX_DEBUG_STRLEN+1]; int nLengthRemaining; int nLength = 0;
// see if level enabled
if (dwLevel <= g_RegistrySettings.dwLogLevel) {
// retrieve local time
GetLocalTime(&SystemTime);
// add component header to the debug message
nLength += sprintf(&szDebugMessage[nLength], DEBUG_FORMAT_HEADER );
// add timestamp to the debug message
nLength += sprintf(&szDebugMessage[nLength], DEBUG_FORMAT_TIMESTAMP, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds );
// add thread id to the debug message
nLength += sprintf(&szDebugMessage[nLength], DEBUG_FORMAT_THREADID, GetCurrentThreadId() );
// point at first argument
va_start(Args, szFormat);
// determine number of bytes left in buffer
nLengthRemaining = sizeof(szDebugMessage) - nLength;
// add user specified debug message
_vsnprintf(&szDebugMessage[nLength], nLengthRemaining, szFormat, Args );
// release pointer
va_end(Args);
// output message to specified sink
OutputDebugMessage(szDebugMessage); } }
PSTR H323IndicationToString( BYTE bIndication ) /*++
Routine Description:
Converts indication from call control module to string.
Arguments:
bIndication - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszIndicationStrings[] = { NULL, "CC_RINGING_INDICATION", "CC_CONNECT_INDICATION", "CC_TX_CHANNEL_OPEN_INDICATION", "CC_RX_CHANNEL_REQUEST_INDICATION", "CC_RX_CHANNEL_CLOSE_INDICATION", "CC_MUTE_INDICATION", "CC_UNMUTE_INDICATION", "CC_PEER_ADD_INDICATION", "CC_PEER_DROP_INDICATION", "CC_PEER_CHANGE_CAP_INDICATION", "CC_CONFERENCE_TERMINATION_INDICATION", "CC_HANGUP_INDICATION", "CC_RX_NONSTANDARD_MESSAGE_INDICATION", "CC_MULTIPOINT_INDICATION", "CC_PEER_UPDATE_INDICATION", "CC_H245_MISCELLANEOUS_COMMAND_INDICATION", "CC_H245_MISCELLANEOUS_INDICATION_INDICATION", "CC_H245_CONFERENCE_REQUEST_INDICATION", "CC_H245_CONFERENCE_RESPONSE_INDICATION", "CC_H245_CONFERENCE_COMMAND_INDICATION", "CC_H245_CONFERENCE_INDICATION_INDICATION", "CC_FLOW_CONTROL_INDICATION", "CC_TX_CHANNEL_CLOSE_REQUEST_INDICATION", "CC_REQUEST_MODE_INDICATION", "CC_REQUEST_MODE_RESPONSE_INDICATION", "CC_VENDOR_ID_INDICATION", "CC_MAXIMUM_AUDIO_VIDEO_SKEW_INDICATION", "CC_T120_CHANNEL_REQUEST_INDICATION", "CC_T120_CHANNEL_OPEN_INDICATION", "CC_BANDWIDTH_CHANGED_INDICATION", "CC_ACCEPT_CHANNEL_INDICATION", "CC_TERMINAL_ID_REQUEST_INDICATION" };
// make sure index value within bounds
return (bIndication < H323GetNumStrings(apszIndicationStrings)) ? apszIndicationStrings[bIndication] : NULL ; }
PSTR CCStatusToString( DWORD dwStatus ) /*++
Routine Description:
Converts call control status to string.
Arguments:
dwStatus - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszCCStatusStrings[] = { NULL, "CC_PEER_REJECT", "CC_BAD_PARAM", "CC_BAD_SIZE", "CC_ACTIVE_CONNECTIONS", "CC_INTERNAL_ERROR", "CC_NOT_IMPLEMENTED", "CC_DUPLICATE_CONFERENCE_ID", "CC_ILLEGAL_IN_MULTIPOINT", "CC_NOT_MULTIPOINT_CAPABLE", "CC_PEER_CANCEL", NULL, NULL, NULL, "CC_NO_MEMORY", NULL, NULL, NULL, NULL, NULL, NULL, "CC_GKI_STATE", "CC_GKI_CALL_STATE", "CC_GKI_LISTEN_NOT_FOUND", "CC_GATEKEEPER_REFUSED", "CC_INVALID_WITHOUT_GATEKEEPER", "CC_GKI_IP_ADDRESS", "CC_GKI_LOAD" };
// adjust code within bounds
dwStatus -= ERROR_LOCAL_BASE_ID;
// make sure index value within bounds
return (dwStatus < H323GetNumStrings(apszCCStatusStrings)) ? apszCCStatusStrings[dwStatus] : NULL ; }
PSTR CCRejectReasonToString( DWORD dwReason ) { static PSTR apszCCRejectReasonStrings[] = { NULL, "CC_REJECT_NO_BANDWIDTH", "CC_REJECT_GATEKEEPER_RESOURCES", "CC_REJECT_UNREACHABLE_DESTINATION", "CC_REJECT_DESTINATION_REJECTION", "CC_REJECT_INVALID_REVISION", "CC_REJECT_NO_PERMISSION", "CC_REJECT_UNREACHABLE_GATEKEEPER", "CC_REJECT_GATEWAY_RESOURCES", "CC_REJECT_BAD_FORMAT_ADDRESS", "CC_REJECT_ADAPTIVE_BUSY", "CC_REJECT_IN_CONF", "CC_REJECT_ROUTE_TO_GATEKEEPER", "CC_REJECT_CALL_FORWARDED", "CC_REJECT_ROUTE_TO_MC", "CC_REJECT_UNDEFINED_REASON", "CC_REJECT_INTERNAL_ERROR", "CC_REJECT_NORMAL_CALL_CLEARING", "CC_REJECT_USER_BUSY", "CC_REJECT_NO_ANSWER", "CC_REJECT_NOT_IMPLEMENTED", "CC_REJECT_MANDATORY_IE_MISSING", "CC_REJECT_INVALID_IE_CONTENTS", "CC_REJECT_TIMER_EXPIRED", "CC_REJECT_CALL_DEFLECTION", "CC_REJECT_GATEKEEPER_TERMINATED" };
// make sure index value within bounds
return (dwReason < H323GetNumStrings(apszCCRejectReasonStrings)) ? apszCCRejectReasonStrings[dwReason] : NULL ; }
PSTR Q931StatusToString( DWORD dwStatus ) /*++
Routine Description:
Converts Q.931 status to string.
Arguments:
dwStatus - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszQ931StatusStrings[] = { NULL, "Q931_BAD_PARAM", "Q931_DUPLICATE_LISTEN", "Q931_INTERNAL_ERROR", "Q931_BAD_SIZE", "Q931_NO_MEMORY", "Q931_NOT_IMPLEMENTED", "Q931_NOT_INITIALIZED", "Q931_DUPLICATE_INITIALIZE", "Q931_SUBSYSTEM_FAILURE", "Q931_OUT_OF_SEQUENCE", "Q931_PEER_UNREACHABLE", "Q931_SETUP_TIMER_EXPIRED", "Q931_RINGING_TIMER_EXPIRED", "Q931_INCOMPATIBLE_VERSION", "Q931_OPTION_NOT_IMPLEMENTED", "Q931_ENDOFINPUT", "Q931_INVALID_FIELD", "Q931_NO_FIELD_DATA", "Q931_INVALID_PROTOCOL", "Q931_INVALID_MESSAGE_TYPE", "Q931_MANDATORY_IE_MISSING", "Q931_BAD_IE_CONTENT" };
// adjust code within bounds
dwStatus -= ERROR_LOCAL_BASE_ID;
// make sure index value within bounds
return (dwStatus < H323GetNumStrings(apszQ931StatusStrings)) ? apszQ931StatusStrings[dwStatus] : NULL ; }
PSTR H245StatusToString( DWORD dwStatus ) /*++
Routine Description:
Converts H.245 status to string.
Arguments:
dwStatus - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszH245StatusStrings[] = { NULL, "H245_ERROR_INVALID_DATA_FORMAT", "H245_ERROR_NOMEM", "H245_ERROR_NOSUP", "H245_ERROR_PARAM", "H245_ERROR_ALREADY_INIT", "H245_ERROR_NOT_CONNECTED", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "H245_ERROR_NORESOURCE", "H245_ERROR_NOTIMP", "H245_ERROR_SUBSYS", "H245_ERROR_FATAL", "H245_ERROR_MAXTBL", "H245_ERROR_CHANNEL_INUSE", "H245_ERROR_INVALID_CAPID", "H245_ERROR_INVALID_OP", "H245_ERROR_UNKNOWN", "H245_ERROR_NOBANDWIDTH", "H245_ERROR_LOSTCON", "H245_ERROR_INVALID_MUXTBLENTRY", "H245_ERROR_INVALID_INST", "H245_ERROR_INPROCESS", "H245_ERROR_INVALID_STATE", "H245_ERROR_TIMEOUT", "H245_ERROR_INVALID_CHANNEL", "H245_ERROR_INVALID_CAPDESCID", "H245_ERROR_CANCELED", "H245_ERROR_MUXELEMENT_DEPTH", "H245_ERROR_MUXELEMENT_WIDTH", "H245_ERROR_ASN1", "H245_ERROR_NO_MUX_CAPS", "H245_ERROR_NO_CAPDESC" };
// remove error base id
dwStatus -= ERROR_BASE_ID;
// make sure index value within bounds
return (dwStatus < H323GetNumStrings(apszH245StatusStrings)) ? apszH245StatusStrings[dwStatus] : NULL ; }
PSTR WinsockStatusToString( DWORD dwStatus ) /*++
Routine Description:
Converts winsock status to string.
Arguments:
dwStatus - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszWinsockStatusStrings[] = { NULL, NULL, NULL, NULL, "WSAEINTR", NULL, NULL, NULL, NULL, "WSAEBADF", NULL, NULL, NULL, "WSAEACCES", "WSAEFAULT", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WSAEINVAL", NULL, "WSAEMFILE", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WSAEWOULDBLOCK", "WSAEINPROGRESS", "WSAEALREADY", "WSAENOTSOCK", "WSAEDESTADDRREQ", "WSAEMSGSIZE", "WSAEPROTOTYPE", "WSAENOPROTOOPT", "WSAEPROTONOSUPPORT", "WSAESOCKTNOSUPPORT", "WSAEOPNOTSUPP", "WSAEPFNOSUPPORT", "WSAEAFNOSUPPORT", "WSAEADDRINUSE", "WSAEADDRNOTAVAIL", "WSAENETDOWN", "WSAENETUNREACH", "WSAENETRESET", "WSAECONNABORTED", "WSAECONNRESET", "WSAENOBUFS", "WSAEISCONN", "WSAENOTCONN", "WSAESHUTDOWN", "WSAETOOMANYREFS", "WSAETIMEDOUT", "WSAECONNREFUSED", "WSAELOOP", "WSAENAMETOOLONG", "WSAEHOSTDOWN", "WSAEHOSTUNREACH", "WSAENOTEMPTY", "WSAEPROCLIM", "WSAEUSERS", "WSAEDQUOT", "WSAESTALE", "WSAEREMOTE" };
// validate status
if (dwStatus < WSABASEERR) { return NULL; }
// adjust error code
dwStatus -= WSABASEERR;
// make sure index value within bounds
return (dwStatus < H323GetNumStrings(apszWinsockStatusStrings)) ? apszWinsockStatusStrings[dwStatus] : NULL ; }
PSTR H323StatusToString( DWORD dwStatus ) /*++
Routine Description:
Converts status to string.
Arguments:
dwStatus - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ DWORD dwFacility;
static PSTR pszDefaultString = "ERROR"; static PSTR pszNoErrorString = "NOERROR";
// retrieve facility code from statuse code
dwFacility = ((dwStatus & STATUS_MASK_FACILITY) >> 16);
// check for success
if (dwStatus == NOERROR) {
// return success string
return pszNoErrorString;
} else if (dwFacility == FACILITY_CALLCONTROL) {
// return call control status string
return CCStatusToString(dwStatus & STATUS_MASK_ERROR);
} else if (dwFacility == FACILITY_Q931) {
// return Q931 status string
return Q931StatusToString(dwStatus & STATUS_MASK_ERROR);
} else if (dwFacility == FACILITY_H245) {
// return H245 status string
return H245StatusToString(dwStatus & STATUS_MASK_ERROR);
} else if (dwFacility == FACILITY_WINSOCK) {
// return H245 status string
return WinsockStatusToString(dwStatus & STATUS_MASK_ERROR);
} else {
// return default string
return pszDefaultString; } }
PSTR H323CallStateToString( DWORD dwCallState ) /*++
Routine Description:
Converts tapi call state to string.
Arguments:
dwCallState - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ DWORD i; DWORD dwBitMask;
static PSTR apszCallStateStrings[] = { "IDLE", "OFFERING", "ACCEPTED", "DIALTONE", "DIALING", "RINGBACK", "BUSY", "SPECIALINFO", "CONNECTED", "PROCEEDING", "ONHOLD", "CONFERENCED", "ONHOLDPENDCONF", "ONHOLDPENDTRANSFER", "DISCONNECTED", "UNKNOWN" };
// keep shifting bit until the call state matchs the one specified
for(i = 0, dwBitMask = 1; dwCallState != dwBitMask; i++, dwBitMask <<= 1) ;
// return corresponding string
return apszCallStateStrings[i]; }
PSTR H323DirToString( DWORD dwDir ) /*++
Routine Description:
Converts H.245 direction to string.
Arguments:
dwDir - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszH245DirStrings[] = { "H245_CAPDIR_DONTCARE", "H245_CAPDIR_RMTRX", "H245_CAPDIR_RMTTX", "H245_CAPDIR_RMTRXTX", "H245_CAPDIR_LCLRX", "H245_CAPDIR_LCLTX", "H245_CAPDIR_LCLRXTX" };
// make sure index value within bounds
return (dwDir < H323GetNumStrings(apszH245DirStrings)) ? apszH245DirStrings[dwDir] : NULL ; }
PSTR H323DataTypeToString( DWORD dwDataType ) /*++
Routine Description:
Converts H.245 data type to string.
Arguments:
dwDataType - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszH245DataTypeStrings[] = { "H245_DATA_DONTCARE", "H245_DATA_NONSTD", "H245_DATA_NULL", "H245_DATA_VIDEO", "H245_DATA_AUDIO", "H245_DATA_DATA", "H245_DATA_ENCRYPT_D", "H245_DATA_CONFERENCE", "H245_DATA_MUX" };
// make sure index value within bounds
return (dwDataType < H323GetNumStrings(apszH245DataTypeStrings)) ? apszH245DataTypeStrings[dwDataType] : NULL ; }
PSTR H323ClientTypeToString( DWORD dwClientType ) /*++
Routine Description:
Converts H.245 client type to string.
Arguments:
dwClientType - Specifies value to convert.
Return Values:
Returns string describing value. --*/
{ static PSTR apszH245ClientTypeStrings[] = { "H245_CLIENT_DONTCARE", "H245_CLIENT_NONSTD", "H245_CLIENT_VID_NONSTD", "H245_CLIENT_VID_H261", "H245_CLIENT_VID_H262", "H245_CLIENT_VID_H263", "H245_CLIENT_VID_IS11172", "H245_CLIENT_AUD_NONSTD", "H245_CLIENT_AUD_G711_ALAW64", "H245_CLIENT_AUD_G711_ALAW56", "H245_CLIENT_AUD_G711_ULAW64", "H245_CLIENT_AUD_G711_ULAW56", "H245_CLIENT_AUD_G722_64", "H245_CLIENT_AUD_G722_56", "H245_CLIENT_AUD_G722_48", "H245_CLIENT_AUD_G723", "H245_CLIENT_AUD_G728", "H245_CLIENT_AUD_G729", "H245_CLIENT_AUD_GDSVD", "H245_CLIENT_AUD_IS11172", "H245_CLIENT_AUD_IS13818", "H245_CLIENT_DAT_NONSTD", "H245_CLIENT_DAT_T120", "H245_CLIENT_DAT_DSMCC", "H245_CLIENT_DAT_USERDATA", "H245_CLIENT_DAT_T84", "H245_CLIENT_DAT_T434", "H245_CLIENT_DAT_H224", "H245_CLIENT_DAT_NLPID", "H245_CLIENT_DAT_DSVD", "H245_CLIENT_DAT_H222", "H245_CLIENT_ENCRYPTION_TX", "H245_CLIENT_ENCRYPTION_RX", "H245_CLIENT_CONFERENCE", "H245_CLIENT_MUX_NONSTD", "H245_CLIENT_MUX_H222", "H245_CLIENT_MUX_H223", "H245_CLIENT_MUX_VGMUX", "H245_CLIENT_MUX_H2250", "H245_CLIENT_MUX_H223_ANNEX_A" };
// make sure index value within bounds
return (dwClientType < H323GetNumStrings(apszH245ClientTypeStrings)) ? apszH245ClientTypeStrings[dwClientType] : NULL ; }
PSTR H323MiscCommandToString( DWORD dwMiscCommand ) /*++
Routine Description:
Converts H.245 command to string.
Arguments:
dwMiscCommand - Miscellaneous H.245 command.
Return Values:
Returns string describing value. --*/
{ static PSTR apszH245MiscCommandStrings[] = { "equaliseDelay", "zeroDelay", "multipointModeCommand", "cnclMltpntMdCmmnd", "videoFreezePicture", "videoFastUpdatePicture", "videoFastUpdateGOB", "MCd_tp_vdTmprlSptlTrdOff", "videoSendSyncEveryGOB", "vdSndSyncEvryGOBCncl", "videoFastUpdateMB" };
// make sure index value within bounds
return (dwMiscCommand < H323GetNumStrings(apszH245MiscCommandStrings)) ? apszH245MiscCommandStrings[dwMiscCommand] : "Unknown" ; }
PSTR H323MSPCommandToString( DWORD dwCommand )
/*++
Routine Description:
Converts MSP command to string.
Arguments:
Command - Type of MSP command.
Return Values:
Returns string describing value. --*/
{ static PSTR apszMSPCommandStrings[] = { "CMD_CHANNEL_OPEN", "CMD_CHANNEL_OPEN_REPLY", "CMD_CHANNEL_CLOSE", "CMD_CALL_CONNECT", "CMD_CALL_DISCONNECT", "CMD_KEYFRAME" };
// make sure index value within bounds
return (dwCommand < H323GetNumStrings(apszMSPCommandStrings)) ? apszMSPCommandStrings[dwCommand] : NULL ; }
PSTR H323AddressTypeToString( DWORD dwAddressType )
/*++
Routine Description:
Converts TAPI address type to string.
Arguments:
dwAddressType - TAPI address type.
Return Values:
Returns string describing value. --*/
{ switch (dwAddressType) {
case LINEADDRESSTYPE_PHONENUMBER: return "PHONENUMBER"; case LINEADDRESSTYPE_SDP: return "SDP"; case LINEADDRESSTYPE_EMAILNAME: return "EMAILNAME"; case LINEADDRESSTYPE_DOMAINNAME: return "DOMAINNAME"; case LINEADDRESSTYPE_IPADDRESS: return "IPADDRESS"; default: return "unknown"; } }
#endif // DBG
|