225 lines
4.5 KiB
C
225 lines
4.5 KiB
C
/*
|
|
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
|
* Copyright (C) 2009-2010 Howard Chu
|
|
*
|
|
* This file is part of librtmp.
|
|
*
|
|
* librtmp is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2.1,
|
|
* or (at your option) any later version.
|
|
*
|
|
* librtmp is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with librtmp see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/lgpl.html
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
|
|
#include "rtmp_sys.h"
|
|
#include "log.h"
|
|
|
|
#define MAX_PRINT_LEN 2048
|
|
|
|
RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
|
|
|
|
static int neednl;
|
|
|
|
static FILE *fmsg;
|
|
|
|
static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
|
|
|
|
static const char *levels[] = {
|
|
"CRIT", "ERROR", "WARNING", "INFO",
|
|
"DEBUG", "DEBUG2"
|
|
};
|
|
|
|
static void rtmp_log_default(int level, const char *format, va_list vl)
|
|
{
|
|
char str[MAX_PRINT_LEN]="";
|
|
|
|
vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
|
|
|
|
/* Filter out 'no-name' */
|
|
if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
|
|
return;
|
|
|
|
if ( !fmsg ) fmsg = stderr;
|
|
|
|
if ( level <= RTMP_debuglevel ) {
|
|
if (neednl) {
|
|
putc('\n', fmsg);
|
|
neednl = 0;
|
|
}
|
|
fprintf(fmsg, "%s: %s\n", levels[level], str);
|
|
#ifdef _DEBUG
|
|
fflush(fmsg);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void RTMP_LogSetOutput(FILE *file)
|
|
{
|
|
fmsg = file;
|
|
}
|
|
|
|
void RTMP_LogSetLevel(RTMP_LogLevel level)
|
|
{
|
|
RTMP_debuglevel = level;
|
|
}
|
|
|
|
void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
|
|
{
|
|
cb = cbp;
|
|
}
|
|
|
|
RTMP_LogLevel RTMP_LogGetLevel()
|
|
{
|
|
return RTMP_debuglevel;
|
|
}
|
|
|
|
void RTMP_Log(int level, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
|
|
if ( level > RTMP_debuglevel )
|
|
return;
|
|
|
|
va_start(args, format);
|
|
cb(level, format, args);
|
|
va_end(args);
|
|
}
|
|
|
|
static const char hexdig[] = "0123456789abcdef";
|
|
|
|
void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
|
|
{
|
|
unsigned long i;
|
|
char line[50], *ptr;
|
|
|
|
if ( level > RTMP_debuglevel )
|
|
return;
|
|
|
|
ptr = line;
|
|
|
|
for(i=0; i<len; i++) {
|
|
*ptr++ = hexdig[0x0f & (data[i] >> 4)];
|
|
*ptr++ = hexdig[0x0f & data[i]];
|
|
if ((i & 0x0f) == 0x0f) {
|
|
*ptr = '\0';
|
|
ptr = line;
|
|
RTMP_Log(level, "%s", line);
|
|
} else {
|
|
*ptr++ = ' ';
|
|
}
|
|
}
|
|
if (i & 0x0f) {
|
|
*ptr = '\0';
|
|
RTMP_Log(level, "%s", line);
|
|
}
|
|
}
|
|
|
|
void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
|
|
{
|
|
#define BP_OFFSET 9
|
|
#define BP_GRAPH 60
|
|
#define BP_LEN 80
|
|
char line[BP_LEN];
|
|
unsigned long i;
|
|
|
|
if ( !data || level > RTMP_debuglevel )
|
|
return;
|
|
|
|
/* in case len is zero */
|
|
line[0] = '\0';
|
|
|
|
for ( i = 0 ; i < len ; i++ ) {
|
|
int n = i % 16;
|
|
unsigned off;
|
|
|
|
if( !n ) {
|
|
if( i ) RTMP_Log( level, "%s", line );
|
|
memset( line, ' ', sizeof(line)-2 );
|
|
line[sizeof(line)-2] = '\0';
|
|
|
|
off = i % 0x0ffffU;
|
|
|
|
line[2] = hexdig[0x0f & (off >> 12)];
|
|
line[3] = hexdig[0x0f & (off >> 8)];
|
|
line[4] = hexdig[0x0f & (off >> 4)];
|
|
line[5] = hexdig[0x0f & off];
|
|
line[6] = ':';
|
|
}
|
|
|
|
off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
|
|
line[off] = hexdig[0x0f & ( data[i] >> 4 )];
|
|
line[off+1] = hexdig[0x0f & data[i]];
|
|
|
|
off = BP_GRAPH + n + ((n >= 8)?1:0);
|
|
|
|
if ( isprint( data[i] )) {
|
|
line[BP_GRAPH + n] = data[i];
|
|
} else {
|
|
line[BP_GRAPH + n] = '.';
|
|
}
|
|
}
|
|
|
|
RTMP_Log( level, "%s", line );
|
|
}
|
|
|
|
/* These should only be used by apps, never by the library itself */
|
|
void RTMP_LogPrintf(const char *format, ...)
|
|
{
|
|
char str[MAX_PRINT_LEN]="";
|
|
int len;
|
|
va_list args;
|
|
va_start(args, format);
|
|
len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
|
|
va_end(args);
|
|
|
|
if ( RTMP_debuglevel==RTMP_LOGCRIT )
|
|
return;
|
|
|
|
if ( !fmsg ) fmsg = stderr;
|
|
|
|
if (neednl) {
|
|
putc('\n', fmsg);
|
|
neednl = 0;
|
|
}
|
|
|
|
if (len > MAX_PRINT_LEN-1)
|
|
len = MAX_PRINT_LEN-1;
|
|
fprintf(fmsg, "%s", str);
|
|
if (str[len-1] == '\n')
|
|
fflush(fmsg);
|
|
}
|
|
|
|
void RTMP_LogStatus(const char *format, ...)
|
|
{
|
|
char str[MAX_PRINT_LEN]="";
|
|
va_list args;
|
|
va_start(args, format);
|
|
vsnprintf(str, MAX_PRINT_LEN-1, format, args);
|
|
va_end(args);
|
|
|
|
if ( RTMP_debuglevel==RTMP_LOGCRIT )
|
|
return;
|
|
|
|
if ( !fmsg ) fmsg = stderr;
|
|
|
|
fprintf(fmsg, "%s", str);
|
|
fflush(fmsg);
|
|
neednl = 1;
|
|
}
|