Commit 81c8b2d6 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Added a global debug level var

parent b9f7f002
......@@ -17,6 +17,9 @@ ADD_EXECUTABLE(freeDiameterd ${FD_COMMON_SRC} main.c)
LINK_DIRECTORIES(${CURRENT_BINARY_DIR}/../libfreeDiameter)
TARGET_LINK_LIBRARIES(freeDiameterd libfreeDiameter ${FD_LIBS})
# Save the list of files, if needed
SET(FD_COMMON_SRC ${FD_COMMON_SRC} PARENT_SCOPE)
# The unary tests directory
OPTION(SKIP_TESTS "Skip compilation of the tests?" OFF)
IF ( NOT SKIP_TESTS )
......
......@@ -19,10 +19,11 @@ SET(TEST_LIST
#############################
# Some parameters for the tests
# Add this flag to add some debug information in the tests themselves
ADD_DEFINITIONS(-DTEST_DEBUG)
ADD_DEFINITIONS(-DTRACE_LEVEL=NONE)
INCLUDE_DIRECTORIES( ".." )
INCLUDE_DIRECTORIES( "../../libfreeDiameter" )
SET(TEST_COMMON_SRC "")
......@@ -34,6 +35,10 @@ ENDFOREACH(SRC_FILE)
# SET(TEST_COMMON_SRC ${TEST_COMMON_SRC} "${CMAKE_CURRENT_BINARY_DIR}/../${SRC_FILE}")
# ENDFOREACH(SRC_FILE)
FOREACH( SRC_FILE ${LFD_SRC})
SET(TEST_COMMON_SRC ${TEST_COMMON_SRC} "../../libfreeDiameter/${SRC_FILE}")
ENDFOREACH(SRC_FILE)
# Create an archive with the daemon common files (all but main)
ADD_LIBRARY(fDcore STATIC ${TEST_COMMON_SRC})
......@@ -42,6 +47,6 @@ ADD_LIBRARY(fDcore STATIC ${TEST_COMMON_SRC})
# Compile each test
FOREACH( TEST ${TEST_LIST} )
ADD_EXECUTABLE(${TEST} ${TEST}.c tests.h)
TARGET_LINK_LIBRARIES(${TEST} libfreeDiameter fDcore ${FD_LIBS})
TARGET_LINK_LIBRARIES(${TEST} fDcore ${FD_LIBS})
ADD_TEST(${TEST} ${EXECUTABLE_OUTPUT_PATH}/${TEST})
ENDFOREACH( TEST )
......@@ -435,7 +435,7 @@ int main(int argc, char *argv[])
CHECK( 0, fd_msg_avp_setvalue ( avpi, &value ) );
memset(&buf, 0, sizeof(buf)); /* Test that the OS value is really copied */
CHECK( 0, fd_msg_update_length ( avpi ) );
#if 1
#if 0
fd_log_debug("AVP octet string, 'This\\0 is a b...'\n");
fd_msg_dump_one(0, avpi);
#endif
......
......@@ -51,8 +51,6 @@
#define TEST_TIMEOUT 5 /* 5 seconds */
#endif /* TEST_TIMEOUT */
static int test_verbosity = 0;
/* Standard includes */
#include <getopt.h>
#include <time.h>
......@@ -75,9 +73,11 @@ static int test_verbosity = 0;
exit(PASS); \
}
static int test_verbo = 0;
/* Define the standard check routines */
#define CHECK( _val, _assert ){ \
if (test_verbosity > 0) { \
if (test_verbo > 0) { \
fprintf(stderr, \
"%s:%-4d: CHECK( " #_assert " == "\
#_val " )\n", \
......@@ -110,11 +110,11 @@ static inline void parse_cmdline(int argc, char * argv[]) {
while ((c = getopt (argc, argv, "dqn")) != -1) {
switch (c) {
case 'd': /* Increase verbosity of debug messages. */
test_verbosity++;
test_verbo++;
break;
case 'q': /* Decrease verbosity then remove debug messages. */
test_verbosity--;
case 'q': /* Decrease verbosity. */
test_verbo--;
break;
case 'n': /* Disable the timeout of the test. */
......@@ -125,6 +125,7 @@ static inline void parse_cmdline(int argc, char * argv[]) {
return;
}
}
fd_g_debug_lvl = (test_verbo > 0) ? (test_verbo - 1) : 0;
if (!no_timeout)
alarm(TEST_TIMEOUT);
}
......
......@@ -121,7 +121,6 @@ extern pthread_key_t fd_log_thname;
*/
char * fd_log_time ( char * buf, size_t len );
/************************** DEBUG MACROS ************************************/
/* levels definitions */
#define NONE 0 /* Display no debug message */
......@@ -136,16 +135,19 @@ char * fd_log_time ( char * buf, size_t len );
#define TRACE_LEVEL INFO
#endif /* TRACE_LEVEL */
/* The level of the file being compiled */
/* The level of the file being compiled. */
static int local_debug_level = TRACE_LEVEL;
/* helper macros (pre-processor hacks) */
/* A global level, changed by configuration or cmd line for example. default is 0. */
extern int fd_g_debug_lvl;
/* helper macros (pre-processor hacks to allow macro arguments) */
#define __str( arg ) #arg
#define _stringize( arg ) __str( arg )
#define __agr( arg1, arg2 ) arg1 ## arg2
#define _aggregate( arg1, arg2 ) __agr( arg1, arg2 )
/* Some portability tricks to get nice function name in __PRETTY_FUNCTION__ */
/* Some portability code to get nice function name in __PRETTY_FUNCTION__ */
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
......@@ -158,9 +160,9 @@ static int local_debug_level = TRACE_LEVEL;
#endif /* __PRETTY_FUNCTION__ */
/* Boolean for tracing at a certain level */
#define TRACE_BOOL(_level_) ( (_level_) <= local_debug_level )
#define TRACE_BOOL(_level_) ( (_level_) <= local_debug_level + fd_g_debug_lvl )
/* The general debug macro, each call results in two lines of debug messages */
/* The general debug macro, each call results in two lines of debug messages (change the macro for more compact output) */
#define TRACE_DEBUG(level,format,args... ) { \
if ( TRACE_BOOL(level) ) { \
char __buf[25]; \
......@@ -172,15 +174,15 @@ static int local_debug_level = TRACE_LEVEL;
} \
}
/* Helper for function entry */
/* Helper for function entry -- for very detailed trace of the execution */
#define TRACE_ENTRY(_format,_args... ) \
TRACE_DEBUG(FCTS, "->%s (" #_args ") = (" _format ") >", __PRETTY_FUNCTION__, ##_args );
/* Helper for debugging by adding traces */
/* Helper for debugging by adding traces -- for debuging a specific location of the code */
#define TRACE_HERE() \
TRACE_DEBUG(INFO, " -- debug checkpoint -- ");
TRACE_DEBUG(NONE, " -- debug checkpoint -- ");
/* Helper for tracing the CHECK_* macros bellow */
/* Helper for tracing the CHECK_* macros bellow -- very very verbose code execution! */
#define TRACE_DEBUG_ALL( str ) \
TRACE_DEBUG(CALL, str );
......@@ -402,7 +404,7 @@ static __inline__ int fd_thr_term(pthread_t * th)
return ret;
}
/* Cleanups for cancellation (all threads should be safely cancelable!) */
/* Cleanups for cancellation (all threads should be safely cancelable...) */
static __inline__ void fd_cleanup_mutex( void * mutex )
{
CHECK_POSIX_DO( pthread_mutex_unlock((pthread_mutex_t *)mutex), /* */);
......@@ -1273,8 +1275,99 @@ The "parent" parameter can not be NULL. It points to the object (grouped avp or
#define ER_DIAMETER_TOO_BUSY 3004
#define ER_DIAMETER_REDIRECT_INDICATION 3006
/* Iterator on the rules of a parent object */
int fd_dict_iterate_rules ( struct dict_object *parent, void * data, int (*cb)(void *, struct dict_rule_data *) );
/*============================================================*/
/* SESSIONS */
/*============================================================*/
/*
* The libfreeDiameter does not provide a full support of the sessions state machines as described in the RFC3588.
* It only provides a basic support allowing an extension to associate some state with a session identifier, and retrieve
* this data later.
*
* A session is an opaque object, associated with a value of a Session-Id AVP.
* An extension that wants to associate data with the session must first register as session module client
* with the sess_regext function to get an identifier object (sess_reg_t).
*
* The module manages tuplets ( sess_id_t *, sess_reg_t *, void *). The following functions are used to manage these tuplets:
* sess_data_reg : associate a pointer with a given session for a given module client.
* sess_data_dereg: removes an association.
* sess_data_get : get the pointer associated with an association without changing it.
*
* Note that creating an association calls sess_link as a side effect, and removing the association calls sess_unlink.
*
* QUICK TUTORIAL:
* For an extension that wants to implement a session state machine, here is a quick guide.
*
* First, the extension must define a structure to save the session state, for example appstate_t.
*
* Since the extension will use the session module, it creates a sess_reg_t by calling sess_regext.
*
* If the extension behaves as a client, it receives external events that trig the start of a new sessions.
* When such event occurs, the extension calls sess_new with the appropriate parameters to create a new session.
* It initializes an appstate_t structure with the data of this session and creates an association with sess_data_reg (%).
* Then it creates a message (application-specific) to request authentication and/or authorization for the service
* and the message is sent.
*
* Later, assuming that the extension has registered appropriate callbacks in the dispatcher module, when a message
* is received, the extension can retrieve the state of the session with the sess_data_get function.
*
* Finaly, when the extension decides to terminate the session (timer, or as result of a message exchange), it
* calls sess_data_dereg in order to destroy the binding in the daemon. When last message refering this session is freed,
* the session data is freed.
*
* (%) A this time, the extension must call sess_unlink in order to counter the effects of the sess_new function.
* This allows to have the session destroyed when no more data is associated to it.
/*============================================================*/
/* DISPATCH */
/*============================================================*/
/* The dispatch process consists in passing a message to some handlers
(typically provided by extensions) based on its content (app id, cmd code...) */
/* The dispatch module has two main roles:
* - help determine if a message can be handled locally (during the routing step)
* - pass the message to the callback(s) that will handle it (during the dispatch step)
*
* These are the possibilities for registering a callback:
*
* -> For All messages.
* This callback is called for all messages that are handled locally. This should be used only
* internally by the daemon, or for debug purpose.
*
* -> by AVP value (constants).
* This callback will be called when a message is received and contains a certain AVP with a specified value.
*
* -> by AVP.
* This callback will be called when the received message contains a certain AVP.
*
* -> by command-code.
* This callback will be called when the message is a specific command.
*
* -> by application.
* This callback will be called when the message has a specific application-id.
*
* ( by vendor: would this be useful? it may be added later)
*
* Note that several criteria may be selected at the same time, for example command-code AND application id.
*
* When a callback is called, it receives the message as parameter, and eventually a pointer to
* the AVP in the message when this is appropriate.
*
* The callback must process the message, and eventually create an answer to it. See the definition
* bellow for more information.
*
* If no callback has handled the message, a default handler will be called with the effect of
* requeuing the message for forwarding on the network to another peer (for requests, if possible), or
* discarding the message (for answers).
*/
/*============================================================*/
......
......@@ -23,3 +23,6 @@ SET_TARGET_PROPERTIES(libfreeDiameter PROPERTIES OUTPUT_NAME "freeDiameter")
# The library itself needs other libraries
TARGET_LINK_LIBRARIES(libfreeDiameter ${FD_LIBS})
# Save the list of files for testcases in the daemon's directory
SET(LFD_SRC ${LFD_SRC} PARENT_SCOPE)
......@@ -45,5 +45,9 @@
extern const char * type_base_name[];
void fd_msg_eteid_init(void);
/* Iterator on the rules of a parent object */
int fd_dict_iterate_rules ( struct dict_object *parent, void * data, int (*cb)(void *, struct dict_rule_data *) );
#endif /* _LIBFD_H */
......@@ -39,6 +39,7 @@
pthread_mutex_t fd_log_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_key_t fd_log_thname;
int fd_g_debug_lvl = 0;
/* Log a debug message */
void fd_log_debug ( char * format, ... )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment