Added display of current active TEI values (L2) at lcradmin.
[lcr.git] / lcradmin.c
index 748ca50..b8b9ac3 100644 (file)
@@ -43,6 +43,7 @@ int   show_interfaces = 2,
 
 enum {
        MODE_STATE,
+       MODE_PORTINFO,
        MODE_INTERFACE,
        MODE_ROUTE,
        MODE_DIAL,
@@ -668,24 +669,59 @@ const char *admin_state(int sock, char *argv[])
                        color(white);
                        if (m[i].u.i.block >= 2)
                        {
-                               SPRINT(buffer, "%s (%d)%s", m[i].u.i.interface_name, m[i].u.i.portnum, (m[i].u.i.extension)?" (extension)":"");
+                               if (m[i].u.i.portnum < 0)
+                                       SPRINT(buffer, "%s (port ?: %s)%s", m[i].u.i.interface_name, m[i].u.i.portname, (m[i].u.i.extension)?" exten":"");
+                               else
+                                       SPRINT(buffer, "%s (port %d: %s)%s", m[i].u.i.interface_name, m[i].u.i.portnum, m[i].u.i.portname, (m[i].u.i.extension)?" extension":"");
                                addstr(buffer);
                                color(red);
                                addstr("  not loaded");
                        } else
                        {
-                               SPRINT(buffer, "%s (%d) %s %s%s use:%d", m[i].u.i.interface_name, m[i].u.i.portnum, (m[i].u.i.ntmode)?"NT-mode":"TE-mode", (m[i].u.i.ptp)?"ptp ":"ptmp", (m[i].u.i.extension)?" extension":"", m[i].u.i.use);
+                               SPRINT(buffer, "%s", m[i].u.i.interface_name);
+                               addstr(buffer);
+                               color(yellow);
+                               SPRINT(buffer, "(port %d: %s)", m[i].u.i.portnum, m[i].u.i.portname);
+                               addstr(buffer);
+                               color(cyan);
+                               SPRINT(buffer, " %s %s%s%s%s", (m[i].u.i.ntmode)?"NT":"TE", (m[i].u.i.ptp)?"ptp":"ptmp", (m[i].u.i.l1hold)?" l1hold":"", (m[i].u.i.l2hold)?" l2hold":"", (m[i].u.i.extension)?" extension":"");
+                               addstr(buffer);
+                               if (m[i].u.i.use)
+                                       color(green);
+                               else
+                                       color(blue);
+                               SPRINT(buffer, " use:%d", m[i].u.i.use);
                                addstr(buffer);
                                if (m[i].u.i.ptp || !m[i].u.i.ntmode)
                                {
-                                       color((m[i].u.i.l2link)?green:red);
-                                       addstr((m[i].u.i.l2link)?"  L2 UP":"  L2 down");
+                                       color((m[i].u.i.l2link > 0)?green:red);
+                                       if (m[i].u.i.l2link < 0)
+                                               addstr("  L2 unkn");
+                                       else
+                                               addstr((m[i].u.i.l2link)?"  L2 UP":"  L2 down");
+                               } else
+                               {
+                                       k = 0;
+                                       color(green);
+                                       j = 0;
+                                       while(j < 128)
+                                       {
+                                               if (m[i].u.i.l2mask[j>>3] & (1 << (j&7)))
+                                               {
+                                                       SPRINT(buffer, "%s%d", k?",":"  TEI(", j);
+                                                       addstr(buffer);
+                                                       k = 1;
+                                               }
+                                               j++;
+                                       }
+                                       if (k)
+                                               addstr(")");
                                }
                                color((m[i].u.i.l1link > 0)?green:blue);
                                if (m[i].u.i.l1link < 0)
-                                       addstr("  L1 unknown");
+                                       addstr("  L1 unkn");
                                else
-                                       addstr((m[i].u.i.l1link)?"  L1 ACTIVE":"  L1 inactive");
+                                       addstr((m[i].u.i.l1link)?"  L1 UP":"  L1 down");
                                if (m[i].u.i.los)
                                {
                                        color(red);
@@ -1123,6 +1159,7 @@ const char *admin_state(int sock, char *argv[])
                            !!strncmp(enter_string, "release ", 8) &&
                            !!strncmp(enter_string, "block ", 6) &&
                            !!strncmp(enter_string, "unblock ", 8) &&
+                           !!strncmp(enter_string, "load ", 5) &&
                            !!strncmp(enter_string, "unload ", 7))
                        {
                                SPRINT(logline[logcur++ % LOGLINES], "usage:");
@@ -1130,7 +1167,7 @@ const char *admin_state(int sock, char *argv[])
                                SPRINT(logline[logcur++ % LOGLINES], "route (reload routing.conf)");
                                SPRINT(logline[logcur++ % LOGLINES], "release <EP> (release endpoint with given ID)");
                                SPRINT(logline[logcur++ % LOGLINES], "block <port> (block port for further calls)");
-                               SPRINT(logline[logcur++ % LOGLINES], "unblock <port> (unblock port for further calls, load if not loaded)");
+                               SPRINT(logline[logcur++ % LOGLINES], "unblock/load <port> (unblock port for further calls, load if not loaded)");
                                SPRINT(logline[logcur++ % LOGLINES], "unload <port> (unload mISDN stack, release call calls)");
                        } else
                        {
@@ -1254,6 +1291,170 @@ const char *admin_state(int sock, char *argv[])
        return(NULL);
 }
 
+const char *admin_portinfo(int sock, int argc, char *argv[])
+{
+       struct admin_message    msg,
+                               *m;
+       int                     i, ii, j;
+       int                     num;
+       int                     len;
+       int                     off;
+
+       /* send state request command */
+       memset(&msg, 0, sizeof(msg));
+       msg.message = ADMIN_REQUEST_STATE;
+       if (write(sock, &msg, sizeof(msg)) != sizeof(msg))
+       {
+               cleanup_curses();
+               return("Broken pipe while sending command.");
+       }
+
+       /* receive response */
+       if (read(sock, &msg, sizeof(msg)) != sizeof(msg))
+       {
+               cleanup_curses();
+               return("Broken pipe while receiving response.");
+       }
+
+       if (msg.message != ADMIN_RESPONSE_STATE)
+       {
+               cleanup_curses();
+               return("Response not valid. Expecting state response.");
+       }
+       num = msg.u.s.interfaces + msg.u.s.remotes + msg.u.s.joins + msg.u.s.epoints + msg.u.s.ports;
+       m = (struct admin_message *)MALLOC(num*sizeof(struct admin_message));
+       off=0;
+       if (num)
+       {
+               readagain:
+               if ((len = read(sock, ((unsigned char *)(m))+off, num*sizeof(struct admin_message)-off)) != num*(int)sizeof(struct admin_message)-off)
+               {
+                       if (len <= 0) {
+                               FREE(m, 0);
+                               cleanup_curses();
+                               return("Broken pipe while receiving state infos.");
+                       }
+                       if (len < num*(int)sizeof(struct admin_message))
+                       {
+                               off+=len;
+                               goto readagain;
+                       }
+               }
+       }
+       j = 0;
+       i = 0;
+       while(i < msg.u.s.interfaces)
+       {
+               if (m[j].message != ADMIN_RESPONSE_S_INTERFACE)
+               {
+                       FREE(m, 0);
+                       cleanup_curses();
+                       return("Response not valid. Expecting interface information.");
+               }
+               i++;
+               j++;
+       }
+       i = 0;
+       while(i < msg.u.s.remotes)
+       {
+               if (m[j].message != ADMIN_RESPONSE_S_REMOTE)
+               {
+                       FREE(m, 0);
+                       cleanup_curses();
+                       return("Response not valid. Expecting remote application information.");
+               }
+               i++;
+               j++;
+       }
+       i = 0;
+       while(i < msg.u.s.joins)
+       {
+               if (m[j].message != ADMIN_RESPONSE_S_JOIN)
+               {
+                       FREE(m, 0);
+                       cleanup_curses();
+                       return("Response not valid. Expecting join information.");
+               }
+               i++;
+               j++;
+       }
+       i = 0;
+       while(i < msg.u.s.epoints)
+       {
+               if (m[j].message != ADMIN_RESPONSE_S_EPOINT)
+               {
+                       FREE(m, 0);
+                       cleanup_curses();
+                       return("Response not valid. Expecting endpoint information.");
+               }
+               i++;
+               j++;
+       }
+       i = 0;
+       while(i < msg.u.s.ports)
+       {
+               if (m[j].message != ADMIN_RESPONSE_S_PORT)
+               {
+                       FREE(m, 0);
+                       cleanup_curses();
+                       return("Response not valid. Expecting port information.");
+               }
+               i++;
+               j++;
+       }
+       // now j is the number of message blocks
+
+       /* output interfaces */
+       i = 0;
+       ii = i + msg.u.s.interfaces;
+       while(i < ii)
+       {
+               if (argc > 2)
+               {
+                       if (!!strcmp(argv[2], m[i].u.i.interface_name))
+                       {
+                               i++;
+                               continue;
+                       }
+               }
+               printf("%s:\n", m[i].u.i.interface_name);
+               if (m[i].u.i.portnum < 0)
+                       printf("\t port = unknown\n");
+               else
+                       printf("\t port = %d \"%s\"\n",m[i].u.i.portnum, m[i].u.i.portname);
+               printf("\t extension = %s\n", (m[i].u.i.extension)?"yes":"no");
+               if (m[i].u.i.block >= 2)
+               {
+                       printf("\t status = not loaded\n");
+               } else
+               {
+                       if (m[i].u.i.block)
+                               printf("\t status = blocked\n");
+                       else
+                               printf("\t status = unblocked\n");
+                       printf("\t mode = %s %s%s%s\n", (m[i].u.i.ntmode)?"NT-mode":"TE-mode", (m[i].u.i.ptp)?"ptp":"ptmp", (m[i].u.i.l1hold)?" l1hold":"", (m[i].u.i.l2hold)?" l2hold":"");
+                       if (m[i].u.i.l1link < 0)
+                               printf("\t l1 link = unknown\n");
+                       else
+                               printf("\t l1 link = %s\n", (m[i].u.i.l1link)?"up":"down");
+                       if (m[i].u.i.ptp || !m[i].u.i.ntmode)
+                       {
+                               if (m[i].u.i.l2link < 0)
+                                       printf("\t l2 link = unknown\n");
+                               else
+                                       printf("\t l2 link = %s\n", (m[i].u.i.l2link)?"up":"down");
+                       }
+                       printf("\t usage = %d\n", m[i].u.i.use);
+               }
+               i++;
+       }
+
+       /* free memory */
+       FREE(m, 0);
+
+       return(NULL);
+}
+
 
 /*
  * Send command and show error message.
@@ -1585,6 +1786,7 @@ const char *admin_trace(int sock, int argc, char *argv[])
        memset(&msg, 0, sizeof(msg));
        msg.message = ADMIN_TRACE_REQUEST;
        msg.u.trace_req.detail = 3;
+       msg.u.trace_req.port = -1;
 
        /* parse args */
        i = 2;
@@ -1644,12 +1846,13 @@ int main(int argc, char *argv[])
                printf("\n");
                printf("Usage: %s state | interface | route | dial ...\n", argv[0]);
                printf("state - View current states using graphical console output.\n");
-               printf("interface - Tell LCR to reload \"interface.conf\".\n");
+               printf("portinfo - Get info of current ports.\n");
+               printf("interface [<portname>] - Tell LCR to reload \"interface.conf\".\n");
                printf("route - Tell LCR to reload \"route.conf\".\n");
                printf("dial <extension> <number> - Tell LCR the next number to dial for extension.\n");
                printf("release <number> - Tell LCR to release endpoint with given number.\n");
                printf("block <port> - Block given port.\n");
-               printf("unblock <port> - Unblock given port.\n");
+               printf("unblock/load <port> - Unblock given port.\n");
                printf("unload <port> - Unload port. To load port use 'block' or 'unblock'.\n");
                printf("testcall [options] <interface> <callerid> <number> [present|restrict [<capability>]] - Testcall\n");
                printf(" -> options = --setup-timeout <seconds> --proceeding-timeout <seconds>\n");
@@ -1666,6 +1869,10 @@ int main(int argc, char *argv[])
        {
                mode = MODE_STATE;
        } else
+       if (!(strcasecmp(argv[1],"portinfo")))
+       {
+               mode = MODE_PORTINFO;
+       } else
        if (!(strcasecmp(argv[1],"interface")))
        {
                mode = MODE_INTERFACE;
@@ -1686,7 +1893,8 @@ int main(int argc, char *argv[])
                        goto usage;
                mode = MODE_RELEASE;
        } else
-       if (!(strcasecmp(argv[1],"unblock")))
+       if (!(strcasecmp(argv[1],"unblock"))
+        || !(strcasecmp(argv[1],"load")))
        {
                if (argc <= 2)
                        goto usage;
@@ -1746,6 +1954,10 @@ int main(int argc, char *argv[])
                ret = admin_state(sock, argv);
                break;
        
+               case MODE_PORTINFO:
+               ret = admin_portinfo(sock, argc, argv);
+               break;
+       
                case MODE_INTERFACE:
                case MODE_ROUTE:
                ret = admin_cmd(sock, mode, NULL, NULL);