backup
[lcr.git] / trace.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** trace functions                                                           **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14 trace auch ein printdebug
15 struct trace trace;
16 char trace_string[MX_TRACE_ELEMENTS * 100 + 400];
17
18 static char *spaces[11] = {
19         "          ",
20         "         ",
21         "        ",
22         "       ",
23         "      ",
24         "     ",
25         "    ",
26         "   ",
27         "  ",
28         " ",
29         "",
30 };
31
32 /*
33  * initializes a new trace
34  * all values will be reset
35  */
36 void start_trace(int port, struct interface *interface, char *caller, char *dialing, int direction, int category, int serial, char *name)
37 {
38         if (trace.name[0])
39                 PERROR("trace already started (name=%s)\n", trace.name);
40         memset(trace, 0, sizeof(struct trace));
41         trace.port = port;
42         if (interface) if (interface[0])
43                 SCPY(trace.interface, interface);
44         if (caller) if (caller[0])
45                 SCPY(trace.caller, caller);
46         if (dialing) if (dialing[0])
47                 SCPY(trace.dialing, dialing);
48         trace.direction = direction;
49         trace.category = category;
50         trace.serial = serial;
51         if (name) if (name[0])
52                 SCPY(trace.name, name);
53         trace.sec = now_tv.tv_sec;
54         trace.usec = now_tv.tv_usec;
55 }
56
57
58 /*
59  * adds a new element to the trace
60  * if subelement is given, element will also contain a subelement
61  * if multiple subelements belong to same element, name must be equal for all subelements
62  */
63 void add_trace(char *name, char *sub, const char *fmt, ...);
64 {
65         va_list args;
66
67         if (!trace.name[0])
68                 PERROR("trace not started\n");
69         
70         /* check for required name value */
71         if (!name)
72                 goto nostring;
73         if (!name[0])
74         {
75                 nostring:
76                 PERROR("trace with name=%s gets element with no string\n", trace->name);
77                 return;
78         }
79         
80         /* write name, sub and value */
81         SCPY(trace.element[trace.elements].name, name);
82         if (sub) if (sub[0])
83                 SCPY(trace.element[trace.elements].sub, sub);
84         if (fmt) if (fmt[0])
85         {
86                 va_start(args, fmt);
87                 VUNPRINT(trace.element[trace.element].value, sizeof(trace.element[trace.elements].value)-1, fmt, args);
88                 va_end(args);
89         }
90
91         /* increment elements */
92         trace.elements++;
93 }
94
95
96 /*
97  * trace ends
98  * this function will put the trace to sockets and logfile, if requested
99  */
100 void end_trace(void);
101 {
102         if (!trace.name[0])
103                 PERROR("trace not started\n");
104         
105         /* process log file */
106         if (options.log[0])
107         {
108                 string = print_trace(1, 0, NULL, NULL, NULL, -1, "AP", CATEGORY_EP);
109                 fwrite(string, strlen(string), 1, fp);
110                 if (options.deb)
111                         debug(NULL, 0, "trace", string);
112         }
113
114         memset(trace, 0, sizeof(struct trace));
115 }
116
117
118 /*
119  * prints trace to socket or log
120  * detail: 1 = brief, 2=short, 3=long
121  */
122 static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, int category);
123 {
124         trace_string[0] = '\0';
125         char buffer[256];
126         struct tm *tm;
127
128         if (detail < 1)
129                 return;
130
131         /* filter trace */
132         if (port && trace.port)
133                 if (port != trace.port) return;
134         if (interface && interface[0] && trace.interface[0])
135                 if (!!strcasecmp(interface, trace.interface)) return;
136         if (caller && caller[0] && trace.caller[0])
137                 if (!!strcasecmp(caller, trace.caller)) return;
138         if (dialing && dialing[0] && trace.dialing[0])
139                 if (!!strcasecmp(dialing, trace.dialing)) return;
140         if (category && category[0] && trace.category[0])
141                 if (!!strcasecmp(category, trace.category)) return;
142
143         /* head */
144         if (detail >= 3)
145         {
146                 /* "Port: 1 (BRI PTMP TE)" */
147                 if (port)
148                 {
149                         mISDNport = mISDNport_first;
150                         while(mISDNport)
151                         {
152                                 if (mISDNport->number == trace.port)
153                                         break;
154                                 mISDNport = mISDNport->next;
155                         }
156                         if (mISDNport)
157                                 SPRINT(buffer, "Port: %d (%s %s %s)", port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->nt)?"NT":"TE");
158                         else
159                                 SPRINT(buffer, "Port: %d (does not exist}\n", port);
160                         SCAT(trace_string, buffer);
161                 } else
162                         SCAT(trace_string, "Port: ---");
163
164                 if (trace.interface[0])
165                 {
166                         /* "  Interface: 'Ext'" */
167                         SPRINT(buffer, "  Interface: '%s'", trace.interface);
168                         SCAT(trace_string, buffer);
169                 } else
170                         SCAT(trace_string, "  Interface: ---");
171                         
172                 if (trace.caller[0])
173                 {
174                         /* "  Caller: '021256493'" */
175                         SPRINT(buffer, "  Caller: '%s'\n", trace.caller);
176                         SCAT(trace_string, buffer);
177                 } else
178                         SCAT(trace_string, "  Caller: ---\n");
179
180                 /* "Time: 25.08.73 05:14:39.282" */
181                 tm = localtime(&trace.sec);
182                 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);
183                 SCAT(trace_string, buffer);
184
185                 if (trace.direction)
186                 {
187                         /* "  Direction: out" */
188                         SPRINT(buffer, "  Direction: %s", (trace.direction==DIRECTION_OUT)?"OUT":"IN");
189                         SCAT(trace_string, buffer);
190                 } else
191                         SCAT(trace_string, "  Direction: ---");
192
193                 if (trace.dialing[0])
194                 {
195                         /* "  Dialing: '57077'" */
196                         SPRINT(buffer, "  Dialing: '%s'\n", trace.dialing);
197                         SCAT(trace_string, buffer);
198                 } else
199                         SCAT(trace_string, "  Dialing: ---\n");
200
201                 SCAT(trace_string, "------------------------------------------------------------------------------\n");
202         }
203
204         /* "CH(45): CC_SETUP (net->user)" */
205         switch (trace.category)
206         {       case CATEGORY_CH:
207                 SCAT(trace_string, "CH");
208                 break;
209
210                 case CATEGORY_EP:
211                 SCAT(trace_string, "EP");
212                 break;
213
214                 default:
215                 SCAT(trace_string, "--");
216         }
217         if (trace.serial)
218                 SPRINT(buffer, "(%d): %s", trace.serial, trace.name[0]?trace.name:"<unknown>");
219         else
220                 SPRINT(buffer, ": %s", trace.name[0]?trace.name:"<unknown>");
221         SCAT(trace_string, buffer);
222
223         /* elements */
224         switch(detail)
225         {
226                 case 1: /* brief */
227                 i = 0;
228                 while(i < trace.elements)
229                 {
230                         SPRINT(buffer, "  %s", trace.element[i].name);
231                         if (i) if (!strcmp(trace.element[i].name, trace.element[i-1].name))
232                                 buffer[0] = '\0';
233                         SCAT(trace_string, buffer);
234                         if (trace.element[i].sub[0])
235                                 SPRINT(buffer, " %s=", trace.element[i].sub, value);
236                         else
237                                 SPRINT(buffer, " ", value);
238                         SCAT(trace_string, buffer);
239                         if (strchr(value, ' '))
240                                 SPRINT(buffer, "'%s'", value);
241                         else
242                                 SPRINT(buffer, "%s", value);
243                         SCAT(trace_string, buffer);
244                         i++;
245                 }
246                 SCAT(trace_string, "\n");
247                 break;
248
249                 case 2: /* short */
250                 case 3: /* long */
251                 SCAT(trace_string, "\n");
252                 i = 0;
253                 while(i < trace.elements)
254                 {
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))
257                                 SPRINT(buffer, "           ");
258                         SCAT(trace_string, buffer);
259                         if (trace.element[i].sub[0])
260                                 SPRINT(buffer, " : %s%s = ", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value);
261                         else
262                                 SPRINT(buffer, " :              ", value);
263                         SCAT(trace_string, buffer);
264                         if (strchr(value, ' '))
265                                 SPRINT(buffer, "'%s'\n", value);
266                         else
267                                 SPRINT(buffer, "%s\n", value);
268                         SCAT(trace_string, buffer);
269                         i++;
270                 }
271                 break;
272         }
273
274         /* end */
275         if (detail >= 3)
276                 SCAT(trace_string, "\n");
277 }
278
279
280
281 ^todo:
282 socket
283 file open
284
285