1 /*
2    Debug and error messages
3    Meant to be included in ow.h
4    Separated just for readability
5 */
6 
7 /* OWFS source code
8    1-wire filesystem for linux
9    {c} 2006 Paul H Alfille
10    License GPL2.0
11 */
12 
13 #ifndef OW_DEBUG_H
14 #define OW_DEBUG_H
15 
16 #include <config.h>
17 #include "owfs_config.h"
18 
19 #ifdef HAVE_SYS_UIO_H
20 #include <sys/uio.h>
21 #endif
22 
23 #include <stdarg.h>
24 
25 /* rwlocks in pthread is preferred. If not, use own implementation with semaphores. */
26 #define PTHREAD_RWLOCK 1
27 
28 #if OW_MUTEX_DEBUG
29 // Detect double unlock etc. (PTHREAD_MUTEX_ERRORCHECK)
30 // This should not be used for smaller embedded systems
31 #define EXTENDED_MUTEX_DEBUG
32 
33 // Allow debugging rwlocks.
34 #define EXTENDED_RWLOCK_DEBUG
35 #else
36 #undef  EXTENDED_MUTEX_DEBUG
37 #undef  EXTENDED_RWLOCK_DEBUG
38 #endif
39 
40 /* module/ownet/c/src/include/ow_debug.h & module/owlib/src/include/ow_debug.h
41    are identical except this define */
42 #define OWNETC_OW_DEBUG 1
43 
44 /* error functions */
45 enum e_err_level { e_err_default, e_err_connect, e_err_call, e_err_data,
46 	e_err_detail, e_err_debug, e_err_beyond,
47 };
48 enum e_err_type { e_err_type_level, e_err_type_error, };
49 enum e_err_print { e_err_print_mixed, e_err_print_syslog,
50 	e_err_print_console,
51 };
52 
53 void err_msg(enum e_err_type errnoflag, enum e_err_level level, const char * file, int line, const char * func, const char *fmt, ...);
54 void _Debug_Bytes(const char *title, const unsigned char *buf, int length);
55 void fatal_error(const char * file, int line, const char * func, const char *fmt, ...);
return_ok(void)56 static inline int return_ok(void) { return 0; }
57 
58 void print_timestamp_(const char * file, int line, const char * func, const char *fmt, ...);
59 #define print_timestamp(...)    print_timestamp_(__FILE__,__LINE__,__func__,__VA_ARGS__);
60 
61 extern int log_available;
62 
63 #define debug_crash() {												\
64 	char *crash_ptr = NULL;                                         \
65 	print_timestamp_(__FILE__,__LINE__,__func__,"debug_crash");     \
66 	*crash_ptr = '\000'; /* Crash with segmentation-fault */        \
67 	}
68 
69 #if OW_DEBUG
70 #define LEVEL_DEFAULT(...)    if (Globals.error_level>=e_err_default) {\
71     err_msg(e_err_type_level,e_err_default,__FILE__,__LINE__,__func__,__VA_ARGS__); }
72 #define LEVEL_CONNECT(...)    if (Globals.error_level>=e_err_connect) {\
73     err_msg(e_err_type_level,e_err_connect,__FILE__,__LINE__,__func__,__VA_ARGS__); }
74 #define LEVEL_CALL(...)       if (Globals.error_level>=e_err_call)  {\
75     err_msg(e_err_type_level,e_err_call,   __FILE__,__LINE__,__func__,__VA_ARGS__); }
76 #define LEVEL_DATA(...)       if (Globals.error_level>=e_err_data) {\
77     err_msg(e_err_type_level,e_err_data,   __FILE__,__LINE__,__func__,__VA_ARGS__); }
78 #define LEVEL_DETAIL(...)     if (Globals.error_level>=e_err_detail) {\
79     err_msg(e_err_type_level,e_err_detail, __FILE__,__LINE__,__func__,__VA_ARGS__); }
80 #define LEVEL_DEBUG(...)      if (Globals.error_level>=e_err_debug) {\
81     err_msg(e_err_type_level,e_err_debug,  __FILE__,__LINE__,__func__,__VA_ARGS__); }
82 
83 #define ERROR_DEFAULT(...)    if (Globals.error_level>=e_err_default) {\
84     err_msg(e_err_type_error,e_err_default,__FILE__,__LINE__,__func__,__VA_ARGS__); }
85 #define ERROR_CONNECT(...)    if (Globals.error_level>=e_err_connect) {\
86     err_msg(e_err_type_error,e_err_connect,__FILE__,__LINE__,__func__,__VA_ARGS__); }
87 #define ERROR_CALL(...)       if (Globals.error_level>=e_err_call)  {\
88     err_msg(e_err_type_error,e_err_call,   __FILE__,__LINE__,__func__,__VA_ARGS__); }
89 #define ERROR_DATA(...)       if (Globals.error_level>=e_err_data) {\
90     err_msg(e_err_type_error,e_err_data,   __FILE__,__LINE__,__func__,__VA_ARGS__); }
91 #define ERROR_DETAIL(...)     if (Globals.error_level>=e_err_detail) {\
92     err_msg(e_err_type_error,e_err_detail, __FILE__,__LINE__,__func__,__VA_ARGS__); }
93 #define ERROR_DEBUG(...)      if (Globals.error_level>=e_err_debug) {\
94     err_msg(e_err_type_error,e_err_debug,  __FILE__,__LINE__,__func__,__VA_ARGS__); }
95 
96 #define FATAL_ERROR(...) fatal_error(__FILE__, __LINE__, __func__, __VA_ARGS__)
97 
98 #define Debug_OWQ(owq)        if (Globals.error_level>=e_err_debug) { _print_owq(owq); }
99 #define Debug_Bytes(title,buf,length)    if (Globals.error_level>=e_err_beyond) { _Debug_Bytes(title,buf,length) ; }
100 
101 #else /* not OW_DEBUG */
102 
103 #define LEVEL_DEFAULT(...)    do { } while (0)
104 #define LEVEL_CONNECT(...)    do { } while (0)
105 #define LEVEL_CALL(...)       do { } while (0)
106 #define LEVEL_DATA(...)       do { } while (0)
107 #define LEVEL_DETAIL(...)     do { } while (0)
108 #define LEVEL_DEBUG(...)      do { } while (0)
109 
110 #define ERROR_DEFAULT(...)    do { } while (0)
111 #define ERROR_CONNECT(...)    do { } while (0)
112 #define ERROR_CALL(...)       do { } while (0)
113 #define ERROR_DATA(...)       do { } while (0)
114 #define ERROR_DETAIL(...)     do { } while (0)
115 #define ERROR_DEBUG(...)      do { } while (0)
116 
117 #define FATAL_ERROR(...)      do { exit(EXIT_FAILURE); } while (0)
118 
119 #define Debug_Bytes(title,buf,length)    do { } while (0)
120 #define Debug_OWQ(owq)        do { } while (0)
121 
122 #endif /* OW_DEBUG */
123 
124 /* Make sure strings are safe for printf */
125 #define SAFESTRING(x) ((x) ? (x):"")
126 
127 /* Easy way to show 64bit serial numbers */
128 #define SNformat	"%.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X"
129 #define SNvar(sn)	(sn)[0],(sn)[1],(sn)[2],(sn)[3],(sn)[4],(sn)[5],(sn)[6],(sn)[7]
130 
131 #include "ow_mutex.h"
132 
133 #endif							/* OW_DEBUG_H */
134