unified socket application interface (for asterisk and maybe other apps)
[lcr.git] / trace.c
diff --git a/trace.c b/trace.c
index bb63ec2..f7ff74b 100644 (file)
--- a/trace.c
+++ b/trace.c
@@ -12,7 +12,7 @@
 #include "main.h"
 
 struct trace trace;
-char trace_string[MX_TRACE_ELEMENTS * 100 + 400];
+char trace_string[MAX_TRACE_ELEMENTS * 100 + 400];
 
 static char *spaces[11] = {
        "          ",
@@ -32,21 +32,21 @@ static char *spaces[11] = {
  * initializes a new trace
  * all values will be reset
  */
-void start_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name);
+void start_trace(int port, struct interface *interface, char *caller, char *dialing, int direction, int category, int serial, char *name)
 {
        if (trace.name[0])
                PERROR("trace already started (name=%s)\n", trace.name);
-       memset(trace, 0, sizeof(struct trace));
+       memset(&trace, 0, sizeof(struct trace));
        trace.port = port;
-       if (interface) if (interface[0])
-               SCPY(trace.interface, interface);
+       if (interface)
+               SCPY(trace.interface, interface->name);
        if (caller) if (caller[0])
                SCPY(trace.caller, caller);
        if (dialing) if (dialing[0])
                SCPY(trace.dialing, dialing);
        trace.direction = direction;
-       if (category) if (category[0])
-               SCPY(trace.category, category);
+       trace.category = category;
+       trace.serial = serial;
        if (name) if (name[0])
                SCPY(trace.name, name);
        trace.sec = now_tv.tv_sec;
@@ -59,7 +59,7 @@ void start_trace(int port, char *interface, char *caller, char *dialing, int dir
  * if subelement is given, element will also contain a subelement
  * if multiple subelements belong to same element, name must be equal for all subelements
  */
-void add_trace(char *name, char *sub, const char *fmt, ...);
+void add_trace(char *name, char *sub, const char *fmt, ...)
 {
        va_list args;
 
@@ -72,7 +72,7 @@ void add_trace(char *name, char *sub, const char *fmt, ...);
        if (!name[0])
        {
                nostring:
-               PERROR("trace with name=%s gets element with no string\n", trace->name);
+               PERROR("trace with name=%s gets element with no string\n", trace.name);
                return;
        }
        
@@ -83,7 +83,7 @@ void add_trace(char *name, char *sub, const char *fmt, ...);
        if (fmt) if (fmt[0])
        {
                va_start(args, fmt);
-               VUNPRINT(trace.element[trace.element].value, sizeof(trace.element[trace.elements].value)-1, fmt, args);
+               VUNPRINT(trace.element[trace.elements].value, sizeof(trace.element[trace.elements].value)-1, fmt, args);
                va_end(args);
        }
 
@@ -93,67 +93,56 @@ void add_trace(char *name, char *sub, const char *fmt, ...);
 
 
 /*
- * trace ends
- * this function will put the trace to sockets and logfile, if requested
- */
-void end_trace(void);
-{
-       if (!trace.name[0])
-               PERROR("trace not started\n");
-       
-       /* process log file */
-       if (options.log[0])
-       {
-               string = print_trace(1, 0, NULL, NULL, NULL, -1, "AP", NULL);
-               fwrite(string, strlen(string), 1, fp);
-       }
-
-       memset(trace, 0, sizeof(struct trace));
-}
-
-
-/*
  * prints trace to socket or log
  * detail: 1 = brief, 2=short, 3=long
  */
-static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, char *category);
+static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, int category)
 {
-       trace_string[0] = '\0';
        char buffer[256];
+       time_t ti = trace.sec;
        struct tm *tm;
+       struct mISDNport *mISDNport;
+       int i;
+
+       trace_string[0] = '\0'; // always clear string
 
        if (detail < 1)
-               return;
+               return(NULL);
 
        /* filter trace */
        if (port && trace.port)
-               if (port != trace.port) return;
-       if (interface && interface[0] && trace.interface[0])
-               if (!!strcasecmp(interface, trace.interface)) return;
-       if (caller && caller[0] && trace.caller[0])
-               if (!!strcasecmp(caller, trace.caller)) return;
-       if (dialing && dialing[0] && trace.dialing[0])
-               if (!!strcasecmp(dialing, trace.dialing)) return;
-       if (category && category[0] && trace.category[0])
-               if (!!strcasecmp(category, trace.category)) return;
+               if (port != trace.port) return(NULL);
+       if (interface) if (interface[0] && trace.interface[0])
+               if (!!strcasecmp(interface, trace.interface)) return(NULL);
+       if (caller) if (caller[0] && trace.caller[0])
+               if (!!strncasecmp(caller, trace.caller, strlen(trace.caller))) return(NULL);
+       if (dialing) if (dialing[0] && trace.dialing[0])
+               if (!!strncasecmp(dialing, trace.dialing, strlen(trace.dialing))) return(NULL);
+       if (category && trace.category)
+               if (!(category & trace.category)) return(NULL);
 
        /* head */
        if (detail >= 3)
        {
+               SCAT(trace_string, "------------------------------------------------------------------------------\n");
                /* "Port: 1 (BRI PTMP TE)" */
-               if (port)
+               if (trace.port)
                {
                        mISDNport = mISDNport_first;
                        while(mISDNport)
                        {
-                               if (mISDNport->number == trace.port)
+                               if (mISDNport->portnum == trace.port)
                                        break;
                                mISDNport = mISDNport->next;
                        }
                        if (mISDNport)
-                               SPRINT(buffer, "Port: %d (%s %s %s)", port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->nt)?"NT":"TE");
-                       else
-                               SPRINT(buffer, "Port: %d (does not exist}\n", port);
+                       {
+                               SPRINT(buffer, "Port: %d (%s %s %s)", trace.port, (mISDNport->pri)?"PRI":"BRI", (mISDNport->ptp)?"PTP":"PTMP", (mISDNport->ntmode)?"NT":"TE");
+                               /* copy interface, if we have a port */
+                               if (mISDNport->ifport) if (mISDNport->ifport->interface)
+                               SCPY(trace.interface, mISDNport->ifport->interface->name);
+                       } else
+                               SPRINT(buffer, "Port: %d (does not exist)\n", trace.port);
                        SCAT(trace_string, buffer);
                } else
                        SCAT(trace_string, "Port: ---");
@@ -175,8 +164,8 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
                        SCAT(trace_string, "  Caller: ---\n");
 
                /* "Time: 25.08.73 05:14:39.282" */
-               tm = localtime(&trace.sec);
-               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);
+               tm = localtime(&ti);
+               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);
                SCAT(trace_string, buffer);
 
                if (trace.direction)
@@ -198,8 +187,30 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
                SCAT(trace_string, "------------------------------------------------------------------------------\n");
        }
 
-       /* "L3: CC_SETUP (net->user)" */
-       SPRINT(buffer, "%s: %s", trace.category[0]?trace.category:"--", trace.name[0]?trace.name:"<unknown>");
+       if (detail < 3)
+       {
+               tm = localtime(&ti);
+               SPRINT(buffer, "%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);
+               SCAT(trace_string, buffer);
+       }
+
+       /* "CH(45): CC_SETUP (net->user)" */
+       switch (trace.category)
+       {       case CATEGORY_CH:
+               SCAT(trace_string, "CH");
+               break;
+
+               case CATEGORY_EP:
+               SCAT(trace_string, "EP");
+               break;
+
+               default:
+               SCAT(trace_string, "--");
+       }
+       if (trace.serial)
+               SPRINT(buffer, "(%lu): %s", trace.serial, trace.name[0]?trace.name:"<unknown>");
+       else
+               SPRINT(buffer, ": %s", trace.name[0]?trace.name:"<unknown>");
        SCAT(trace_string, buffer);
 
        /* elements */
@@ -214,14 +225,14 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
                                buffer[0] = '\0';
                        SCAT(trace_string, buffer);
                        if (trace.element[i].sub[0])
-                               SPRINT(buffer, " %s=", trace.element[i].sub, value);
+                               SPRINT(buffer, " %s=", trace.element[i].sub);
                        else
-                               SPRINT(buffer, " ", value);
+                               SPRINT(buffer, " ");
                        SCAT(trace_string, buffer);
-                       if (strchr(value, ' '))
-                               SPRINT(buffer, "'%s'", value);
+                       if (strchr(trace.element[i].value, ' '))
+                               SPRINT(buffer, "'%s'", trace.element[i].value);
                        else
-                               SPRINT(buffer, "%s", value);
+                               SPRINT(buffer, "%s", trace.element[i].value);
                        SCAT(trace_string, buffer);
                        i++;
                }
@@ -239,14 +250,14 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
                                SPRINT(buffer, "           ");
                        SCAT(trace_string, buffer);
                        if (trace.element[i].sub[0])
-                               SPRINT(buffer, " : %s%s = ", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value);
+                               SPRINT(buffer, " : %s%s = ", trace.element[i].sub, spaces[strlen(trace.element[i].sub)]);
                        else
-                               SPRINT(buffer, " :              ", value);
+                               SPRINT(buffer, " :              ");
                        SCAT(trace_string, buffer);
-                       if (strchr(value, ' '))
-                               SPRINT(buffer, "'%s'\n", value);
+                       if (strchr(trace.element[i].value, ' '))
+                               SPRINT(buffer, "'%s'\n", trace.element[i].value);
                        else
-                               SPRINT(buffer, "%s\n", value);
+                               SPRINT(buffer, "%s\n", trace.element[i].value);
                        SCAT(trace_string, buffer);
                        i++;
                }
@@ -256,12 +267,83 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
        /* end */
        if (detail >= 3)
                SCAT(trace_string, "\n");
+       return(trace_string);
 }
 
 
+/*
+ * trace ends
+ * this function will put the trace to sockets and logfile, if requested
+ */
+void end_trace(void)
+{
+       char *string;
+       FILE *fp;
+       struct admin_list       *admin;
+       struct admin_queue      *response, **responsep; /* response pointer */
+
+       if (!trace.name[0])
+               PERROR("trace not started\n");
+       
+       if (options.deb || options.log[0])
+       {
+               string = print_trace(1, 0, NULL, NULL, NULL, 0);
+               if (string)
+               {
+                       /* process debug */
+                       if (options.deb)
+                               debug(NULL, 0, "trace", string);
+                       /* process log */
+                       if (options.log[0])
+                       {
+                               fp = fopen(options.log, "a");
+                               if (fp)
+                               {
+                                       fwrite(string, strlen(string), 1, fp);
+                                       fclose(fp);
+                               }
+                       }
+               }
+       }
+
+       /* process admin */
+       admin = admin_first;
+       while(admin)
+       {
+               if (admin->trace.detail)
+               {
+                       string = print_trace(admin->trace.detail, admin->trace.port, admin->trace.interface, admin->trace.caller, admin->trace.dialing, admin->trace.category);
+                       if (string)
+                       {
+                               /* seek to end of response list */
+                               response = admin->response;
+                               responsep = &admin->response;
+                               while(response)
+                               {
+                                       responsep = &response->next;
+                                       response = response->next;
+                               }
+
+                               /* create state response */
+                               response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
+                               memuse++;
+                               response->num = 1;
+                               /* message */
+                               response->am[0].message = ADMIN_TRACE_RESPONSE;
+                               SCPY(response->am[0].u.trace_rsp.text, string);
+
+                               /* attach to response chain */
+                               *responsep = response;
+                               responsep = &response->next;
+                       }
+               }
+               admin = admin->next;
+       }
+//     fwrite(string, strlen(string), 1, fp);
+
+       memset(&trace, 0, sizeof(struct trace));
+}
+
 
-^todo:
-socket
-file open