1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
14 struct trace trace[MAX_NESTED_TRACES];
15 int trace_current = -1;
16 char trace_string[MX_TRACE_ELEMENTS * 100 + 400];
18 static char *spaces[11] = {
33 * initializes a new trace
34 * all values will be reset
36 void start_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name);
38 if (++trace_current == MAX_NESTED_TRACES)
40 PERROR("maximum nesting level of traces exceeding: %d, exitting!\n", MAX_NESTED_TRACES);
41 PERROR("last trace=%s\n", trace[MAX_NESTED_TRACE-1].name);
44 memset(trace[trace_current], 0, sizeof(struct trace));
45 trace[trace_current].port = port;
46 if (interface) if (interface[0])
47 SCPY(trace[trace_current].interface, interface);
48 if (caller) if (caller[0])
49 SCPY(trace[trace_current].caller, caller);
50 if (dialing) if (dialing[0])
51 SCPY(trace[trace_current].dialing, dialing);
52 trace[trace_current].direction = direction;
53 if (category) if (category[0])
54 SCPY(trace[trace_current].category, category);
55 if (name) if (name[0])
56 SCPY(trace[trace_current].name, name);
57 trace[trace_current].sec = now_tv.tv_sec;
58 trace[trace_current].usec = now_tv.tv_usec;
63 * adds a new element to the trace
64 * if subelement is given, element will also contain a subelement
65 * if multiple subelements belong to same element, name must be equal for all subelements
67 void add_trace(char *name, char *sub, const char *fmt, ...);
72 if (trace_current < 0)
74 PERROR("add_trace called without start_trace, exitting.\n");
79 if (trace[trace_current].elements == MAX_TRACE_ELEMENTS)
81 PERROR("trace with name=%s exceeds the maximum number of elements (%d)\n", trace.name, MAX_TRACE_ELEMENTS);
85 /* check for required name value */
91 PERROR("trace with name=%s gets element with no string\n", trace->name);
95 /* write name, sub and value */
96 SCPY(trace[trace_current].element[trace[trace_current].elements].name, name);
98 SCPY(trace[trace_current].element[trace[trace_current].elements].sub, sub);
102 VUNPRINT(trace[trace_current].element[trace[trace_current].element].value, sizeof(trace[trace_current].element[trace[trace_current].elements].value)-1, fmt, args);
106 /* increment elements */
107 trace[trace_current].elements++;
113 * this function will put the trace to sockets and logfile, if requested
115 void end_trace(void);
118 if (trace_current < 0)
120 PERROR("end_trace called without start_trace, exitting.\n");
124 /* process log file */
127 string = print_trace(1, 0, NULL, NULL, NULL, -1, "AP", NULL);
128 fwrite(string, strlen(string), 1, fp);
131 /* reduce nesting level */
137 * prints trace to socket or log
138 * detail: 1 = brief, 2=short, 3=long
140 static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, int direction, char *category);
142 trace_string[0] = '\0';
150 if (port && trace.port)
151 if (port != trace.port) return;
152 if (interface && interface[0] && trace.interface[0])
153 if (!!strcasecmp(interface, trace.interface)) return;
154 if (caller && caller[0] && trace.caller[0])
155 if (!!strcasecmp(caller, trace.caller)) return;
156 if (dialing && dialing[0] && trace.dialing[0])
157 if (!!strcasecmp(dialing, trace.dialing)) return;
158 if (direction && trace.direction)
159 if (direction != trace.direction) return;
160 if (category && category[0] && trace.category[0])
161 if (!!strcasecmp(category, trace.category)) return;
166 /* "Port: 1 (BRI PTMP TE)" */
169 mISDNport = mISDNport_first;
172 if (mISDNport->number == trace.port)
174 mISDNport = mISDNport->next;
177 SPRINT(buffer, "Port: %d (%s %s %s)", port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->nt)?"NT":"TE");
179 SPRINT(buffer, "Port: %d (does not exist}\n", port);
180 SCAT(trace_string, buffer);
182 SCAT(trace_string, "Port: ---");
184 if (trace.interface[0])
186 /* " Interface: 'Ext'" */
187 SPRINT(buffer, " Interface: '%s'", trace.interface);
188 SCAT(trace_string, buffer);
190 SCAT(trace_string, " Interface: ---");
194 /* " Caller: '021256493'" */
195 SPRINT(buffer, " Caller: '%s'\n", trace.caller);
196 SCAT(trace_string, buffer);
198 SCAT(trace_string, " Caller: ---\n");
200 /* "Time: 25.08.73 05:14:39.282" */
201 tm = localtime(&trace.sec);
202 SPRINT(buffer, "Time: %02d.%02d.%02d %02d:%02d:%02d.%03d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100, tm->tm_hour, tm->tm_min, tm->tm_sec, trace->usec/1000);
203 SCAT(trace_string, buffer);
207 /* " Direction: out" */
208 SPRINT(buffer, " Direction: %s", (trace.direction==DIRECTION_OUT)?"OUT":"IN");
209 SCAT(trace_string, buffer);
211 SCAT(trace_string, " Direction: ---");
213 if (trace.dialing[0])
215 /* " Dialing: '57077'" */
216 SPRINT(buffer, " Dialing: '%s'\n", trace.dialing);
217 SCAT(trace_string, buffer);
219 SCAT(trace_string, " Dialing: ---\n");
221 SCAT(trace_string, "------------------------------------------------------------------------------\n");
224 /* "L3: CC_SETUP (net->user)" */
225 SPRINT(buffer, "%s: %s", trace.category[0]?trace.category:"--", trace.name[0]?trace.name:"<unknown>");
226 SCAT(trace_string, buffer);
233 while(i < trace.elements)
235 SPRINT(buffer, " %s", trace.element[i].name);
236 if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name))
238 SCAT(trace_string, buffer);
239 if (trace.element[i].sub[0])
240 SPRINT(buffer, " %s=%s", trace.element[i].sub, value);
242 SPRINT(buffer, " %s", value);
243 SCAT(trace_string, buffer);
246 SCAT(trace_string, "\n");
251 SCAT(trace_string, "\n");
253 while(i < trace.elements)
255 SPRINT(buffer, " %s%s", trace.element[i].name, spaces[strlen(trace.element[i].name)]);
256 if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name))
258 SCAT(trace_string, buffer);
259 if (trace.element[i].sub[0])
260 SPRINT(buffer, " : %s%s = %s\n", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value);
262 SPRINT(buffer, " : %s\n", value);
263 SCAT(trace_string, buffer);
271 SCAT(trace_string, "\n");