X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=admin_client.c;h=02624a08d164519cbef490e5b4dbe276fe2bfbc1;hp=41430f6092b2fad54c15da4946cb26221d859ba7;hb=701b046a45c2c79cc6d07ac3a4f84f499f7ed376;hpb=2ed0fee489c37a6e2d4473f6185ebbe3e746ac11 diff --git a/admin_client.c b/admin_client.c index 41430f6..02624a0 100644 --- a/admin_client.c +++ b/admin_client.c @@ -1,6 +1,6 @@ /*****************************************************************************\ ** ** -** PBX4Linux ** +** Linux Call Router ** ** ** **---------------------------------------------------------------------------** ** Copyright: Andreas Eversberg ** @@ -20,9 +20,11 @@ #include #include #include -#include "save.h" -#include "call.h" -#include "callpbx.h" +#include "macro.h" +#include "join.h" +#include "joinpbx.h" +#include "extension.h" +#include "message.h" #include "admin.h" #include "cause.h" @@ -42,7 +44,11 @@ enum { MODE_ROUTE, MODE_DIAL, MODE_RELEASE, + MODE_UNBLOCK, + MODE_BLOCK, + MODE_UNLOAD, MODE_TESTCALL, + MODE_TRACE, }; char *text_interfaces[] = { @@ -67,7 +73,7 @@ char red = 1, white = 7; #define LOGLINES 128 -char logline[LOGLINES][256]; +char logline[LOGLINES][512]; unsigned long logcur = 0; int logfh = -1; char logfile[128]; @@ -351,7 +357,7 @@ int debug_epoint(struct admin_message *msg, struct admin_message *m, int line, i } /* loop all related ports */ ltee = 0; - j = msg->u.s.interfaces+msg->u.s.calls+msg->u.s.epoints; + j = msg->u.s.interfaces+msg->u.s.joins+msg->u.s.epoints; jj = j + msg->u.s.ports; while(j < jj) { @@ -382,39 +388,47 @@ int debug_epoint(struct admin_message *msg, struct admin_message *m, int line, i return(line); } -int debug_call(struct admin_message *msg, struct admin_message *m, int line, int i) +int debug_join(struct admin_message *msg, struct admin_message *m, int line, int i) { - unsigned long call = m[i].u.c.serial; + unsigned long join = m[i].u.j.serial; char buffer[256]; int j, jj; color(white); - SPRINT(buffer,"CALL(%d)", call); + SPRINT(buffer,"JOIN(%d)", join); addstr(buffer); - if (m[i].u.c.partyline) + if (m[i].u.j.partyline) { color(cyan); addstr(" partyline="); color(white); - SPRINT(buffer, "%d\n", m[i].u.c.partyline); + SPRINT(buffer, "%d\n", m[i].u.j.partyline); + addstr(buffer); + } + if (m[i].u.j.remote[0]) + { + color(cyan); + addstr(" remote="); + color(white); + SPRINT(buffer, "%s\n", m[i].u.j.remote); addstr(buffer); } /* find number of epoints */ - j = msg->u.s.interfaces+msg->u.s.calls; + j = msg->u.s.interfaces+msg->u.s.joins; jj = j + msg->u.s.epoints; i = 0; while(j < jj) { - if (m[j].u.e.call == call) + if (m[j].u.e.join == join) i++; j++; } /* loop all related endpoints */ - j = msg->u.s.interfaces+msg->u.s.calls; + j = msg->u.s.interfaces+msg->u.s.joins; jj = j + msg->u.s.epoints; while(j < jj) { - if (m[j].u.e.call == call) + if (m[j].u.e.join == join) { i--; move(++line>1?line:1, 1); @@ -433,13 +447,13 @@ int debug_call(struct admin_message *msg, struct admin_message *m, int line, int return(line); } -char *admin_state(int sock) +char *admin_state(int sock, char *argv[]) { struct admin_message msg, *m; - char buffer[256], + char buffer[512], *p; - int line, offset = 0; + int line, offset = 0, hoffset = 0; int i, ii, j, jj, k; unsigned long l, ll; int num; @@ -447,6 +461,8 @@ char *admin_state(int sock) int off; int ltee; int anything; + int enter = 0; + char enter_string[128] = "", ch; /* flush logfile name */ logfile[0] = '\0'; @@ -458,7 +474,7 @@ char *admin_state(int sock) /* send reload command */ memset(&msg, 0, sizeof(msg)); msg.message = ADMIN_REQUEST_STATE; -// printf("sizeof=%d\n",sizeof(msg)); +// printf("sizeof=%d\n",sizeof(msg));fflush(stdout); if (write(sock, &msg, sizeof(msg)) != sizeof(msg)) { cleanup_curses(); @@ -471,32 +487,31 @@ char *admin_state(int sock) 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.calls + msg.u.s.epoints + msg.u.s.ports; - if (!(m = (struct admin_message *)malloc(num*sizeof(struct admin_message)))) - { - cleanup_curses(); - return("Not enough memory for messages."); - } + 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; -readagain: - if ((len = read(sock, ((unsigned char *)(m))+off, - num*sizeof(struct admin_message)-off)) != num*sizeof(struct admin_message)-off) + if (num) { - if (len <= 0) { - free(m); -// fprintf(stderr, "got=%d expected=%d\n", i, num*sizeof(struct admin_message)); - cleanup_curses(); - return("Broken pipe while receiving state infos."); - } - if (len < num*sizeof(struct admin_message)) + readagain: + if ((len = read(sock, ((unsigned char *)(m))+off, num*sizeof(struct admin_message)-off)) != num*(int)sizeof(struct admin_message)-off) { - off+=len; - goto readagain; + if (len <= 0) { + FREE(m, 0); + // fprintf(stderr, "got=%d expected=%d\n", i, num*sizeof(struct admin_message)); + cleanup_curses(); + return("Broken pipe while receiving state infos."); + } + if (len < num*(int)sizeof(struct admin_message)) + { + off+=len; + goto readagain; + } } } j = 0; @@ -507,7 +522,7 @@ readagain: // fprintf(stderr, "j=%d message=%d\n", j, m[j].message); if (m[j].message != ADMIN_RESPONSE_S_INTERFACE) { - free(m); + FREE(m, 0); cleanup_curses(); return("Response not valid. Expecting interface information."); } @@ -515,13 +530,25 @@ readagain: j++; } i = 0; - while(i < msg.u.s.calls) + while(i < msg.u.s.remotes) { - if (m[j].message != ADMIN_RESPONSE_S_CALL) + if (m[j].message != ADMIN_RESPONSE_S_REMOTE) { - free(m); + FREE(m, 0); cleanup_curses(); - return("Response not valid. Expecting call information."); + 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++; @@ -531,7 +558,7 @@ readagain: { if (m[j].message != ADMIN_RESPONSE_S_EPOINT) { - free(m); + FREE(m, 0); cleanup_curses(); return("Response not valid. Expecting endpoint information."); } @@ -543,7 +570,7 @@ readagain: { if (m[j].message != ADMIN_RESPONSE_S_PORT) { - free(m); + FREE(m, 0); cleanup_curses(); return("Response not valid. Expecting port information."); } @@ -633,116 +660,140 @@ readagain: /* show interface summary */ move(++line>1?line:1, 0); color(white); - - SPRINT(buffer, "%s(%d) '%s' %s use:%d ", (m[i].u.i.ntmode)?"NT":"TE", m[i].u.i.portnum, m[i].u.i.interface_name, (m[i].u.i.ptp)?"ptp ":"ptmp", m[i].u.i.use); - addstr(buffer); - if (m[i].u.i.ptp || !m[i].u.i.ntmode) + if (m[i].u.i.block >= 2) { - color((m[i].u.i.l2link)?green:red); - addstr((m[i].u.i.l2link)?" L2 UP":" L2 down"); - } - color((m[i].u.i.l1link)?green:blue); - addstr((m[i].u.i.l1link)?" L1 ACTIVE":" L1 inactive"); - if (line+2 >= LINES) goto end; - /* show channels */ - if (show_interfaces > 1) + SPRINT(buffer, "%s (%d)%s", m[i].u.i.interface_name, m[i].u.i.portnum, (m[i].u.i.extension)?" (extension)":""); + addstr(buffer); + color(red); + addstr(" not loaded"); + } else { - ltee = 0; - j = k =0; - jj = m[i].u.i.channels; - while(j < jj) + 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); + 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.l1link)?green:blue); + addstr((m[i].u.i.l1link)?" L1 ACTIVE":" L1 inactive"); + if (m[i].u.i.block) + { + color(red); + addstr(" blocked"); + } + if (line+2 >= LINES) goto end; + /* show channels */ + if (show_interfaces > 1) { - /* show all channels */ - if (show_interfaces>2 || m[i].u.i.busy[j]>0) + ltee = 0; + j = k =0; + jj = m[i].u.i.channels; + while(j < jj) { - color(cyan); - /* show left side / right side */ - if ((k & 1) && (COLS > 70)) - { - move(line>1?line:1,4+((COLS-4)/2)); - } else - { - move(++line>1?line:1, 1); - LTEE - ltee = 1; - } - k++; - color(white); - if (m[i].u.i.pri) - SPRINT(buffer,"S%2d: ", j+1+(j>=15)); - else - SPRINT(buffer,"B%2d: ", j+1); - addstr(buffer); - if (!m[i].u.i.ptp) - goto ptmp; - if (m[i].u.i.l2link) - { - ptmp: - color((m[i].u.i.busy[j])?yellow:blue); - addstr((m[i].u.i.busy[j])?"busy":"idle"); - } else - { - color(red); - addstr("blk "); - } - if (m[i].u.i.port[j]) + /* show all channels */ + if (show_interfaces>2 || m[i].u.i.busy[j]>0) { - /* search for port */ - l = msg.u.s.interfaces+msg.u.s.calls+msg.u.s.epoints; - ll = l+msg.u.s.ports; - while(l < ll) + color(cyan); + /* show left side / right side */ + if ((k & 1) && (COLS > 70)) { - if (m[l].u.p.serial == m[i].u.i.port[j]) + move(line>1?line:1,4+((COLS-4)/2)); + } else + { + move(++line>1?line:1, 1); + LTEE + ltee = 1; + } + k++; + color(white); + if (m[i].u.i.pri) + SPRINT(buffer,"S%2d: ", j+1+(j>=15)); + else + SPRINT(buffer,"B%2d: ", j+1); + addstr(buffer); + if (!m[i].u.i.ptp) + goto ptmp; + if (m[i].u.i.l2link && m[i].u.i.block==0) + { + ptmp: + color((m[i].u.i.busy[j])?yellow:blue); + addstr((m[i].u.i.busy[j])?"busy":"idle"); + } else + { + color(red); + addstr("blk "); + } + if (m[i].u.i.port[j]) + { + /* search for port */ + l = msg.u.s.interfaces+msg.u.s.joins+msg.u.s.epoints; + ll = l+msg.u.s.ports; + while(l < ll) { - SPRINT(buffer, " %s(%ld)", m[l].u.p.name, m[l].u.p.serial); - addstr(buffer); + if (m[l].u.p.serial == m[i].u.i.port[j]) + { + SPRINT(buffer, " %s(%ld)", m[l].u.p.name, m[l].u.p.serial); + addstr(buffer); + } + l++; } - l++; } - } - if (line+2 >= LINES) - { - if (ltee) + if (line+2 >= LINES) { - color(cyan); - move(line>1?line:1, 1); - LLCORNER + if (ltee) + { + color(cyan); + move(line>1?line:1, 1); + LLCORNER + } + goto end; } - goto end; } + j++; } - j++; - } - if (ltee) - { - color(cyan); - move(line>1?line:1, 1); - LLCORNER - } - if (line+2 >= LINES) goto end; - /* show summary if no channels were shown */ - if (show_interfaces<2 && ltee==0) - { - color(cyan); - move(++line>1?line:1, 1); - LLCORNER - - if (m[i].u.i.l2link) + if (ltee) { - color(green); - SPRINT(buffer,"all %d channels free", m[i].u.i.channels); - } else + color(cyan); + move(line>1?line:1, 1); + LLCORNER + } + if (line+2 >= LINES) goto end; + /* show summary if no channels were shown */ + if (show_interfaces<2 && ltee==0) { - color(red); - SPRINT(buffer,"all %d channels blocked", m[i].u.i.channels); + color(cyan); + move(++line>1?line:1, 1); + LLCORNER + + if (m[i].u.i.l2link && m[i].u.i.block==0) + { + color(green); + SPRINT(buffer,"all %d channels free", m[i].u.i.channels); + } else + { + color(red); + SPRINT(buffer,"all %d channels blocked", m[i].u.i.channels); + } + addstr(buffer); } - addstr(buffer); + if (line+2 >= LINES) goto end; } - if (line+2 >= LINES) goto end; } i++; anything = 1; } + i = 0; + ii = i + msg.u.s.remotes; + while(i < ii) + { + /* show remote summary */ + move(++line>1?line:1, 0); + color(white); + SPRINT(buffer, "Remote: %s", m[i].u.r.name); + addstr(buffer); + i++; + } if (anything) line++; if (line+2 >= LINES) goto end; @@ -751,12 +802,12 @@ readagain: if (show_calls == 1) { anything = 0; - i = msg.u.s.interfaces+msg.u.s.calls; + i = msg.u.s.interfaces+msg.u.s.joins; ii = i+msg.u.s.epoints; while(i < ii) { /* for each endpoint... */ - if (!m[i].u.e.call) + if (!m[i].u.e.join) { move(++line>1?line:1, 0); color(white); @@ -791,20 +842,20 @@ readagain: anything = 1; } j = msg.u.s.interfaces; - jj = j+msg.u.s.calls; + jj = j+msg.u.s.joins; while(j < jj) { /* for each call... */ move(++line>1?line:1, 0); color(white); - SPRINT(buffer, "(%d):", m[j].u.c.serial); + SPRINT(buffer, "(%d):", m[j].u.j.serial); addstr(buffer); - i = msg.u.s.interfaces+msg.u.s.calls; + i = msg.u.s.interfaces+msg.u.s.joins; ii = i+msg.u.s.epoints; while(i < ii) { /* for each endpoint... */ - if (m[i].u.e.call == m[j].u.c.serial) + if (m[i].u.e.join == m[j].u.j.serial) { color(white); SPRINT(buffer, " (%d)", m[i].u.e.serial); @@ -841,7 +892,7 @@ readagain: { /* show all ports with no epoint */ anything = 0; - i = msg.u.s.interfaces+msg.u.s.calls+msg.u.s.epoints; + i = msg.u.s.interfaces+msg.u.s.joins+msg.u.s.epoints; ii = i+msg.u.s.ports; while(i < ii) { @@ -861,11 +912,11 @@ readagain: /* show all epoints with no call */ anything = 0; - i = msg.u.s.interfaces+msg.u.s.calls; + i = msg.u.s.interfaces+msg.u.s.joins; ii = i+msg.u.s.epoints; while(i < ii) { - if (!m[i].u.e.call) + if (!m[i].u.e.join) { move(++line>1?line:1, 4); if (line+2 >= LINES) goto end; @@ -879,15 +930,15 @@ readagain: line++; if (line+2 >= LINES) goto end; - /* show all calls */ + /* show all joins */ anything = 0; i = msg.u.s.interfaces; - ii = i+msg.u.s.calls; + ii = i+msg.u.s.joins; while(i < ii) { move(++line>1?line:1, 0); if (line+2 >= LINES) goto end; - line = debug_call(&msg, m, line, i); + line = debug_join(&msg, m, line, i); if (line+2 >= LINES) goto end; i++; anything = 1; @@ -915,10 +966,19 @@ readagain: while(l!=ll) { move(line++>1?line-1:1, 0); - SCPY(buffer, logline[l % LOGLINES]); - if (COLS < (int)sizeof(buffer)) - buffer[COLS] = '\0'; - addstr(buffer); + if (strlen(logline[l % LOGLINES]) > hoffset) + SCPY(buffer, logline[l % LOGLINES] + hoffset); + else + buffer[0] = '\0'; + if (COLS < (int)strlen(buffer)) + { + buffer[COLS-1] = '\0'; + addstr(buffer); + color(red); + addch('*'); + color(white); + } else + addstr(buffer); l++; } } @@ -926,14 +986,14 @@ readagain: end: /* free memory */ - free(m); + FREE(m, 0); /* display name/time */ // move(0, 0); // hline(' ', COLS); move(0, 0); color(white); msg.u.s.version_string[sizeof(msg.u.s.version_string)-1] = '\0'; - SPRINT(buffer, "PBX4Linux %s", msg.u.s.version_string); + SPRINT(buffer, "LCR %s", msg.u.s.version_string); addstr(buffer); if (COLS>50) { @@ -954,13 +1014,23 @@ readagain: color(red); addstr(buffer); } + if (hoffset) + { + move(1, 13); + SPRINT(buffer, "H-Offset +%d", hoffset); + color(red); + addstr(buffer); + } /* display end */ move(LINES-2, 0); color(white); hline(ACS_HLINE, COLS); move(LINES-1, 0); color(white); - SPRINT(buffer, "i = interfaces '%s' c = calls '%s' l = log q = quit +/- = scroll", text_interfaces[show_interfaces], text_calls[show_calls]); + if (enter) + SPRINT(buffer, "-> %s", enter_string); + else + SPRINT(buffer, "i=interfaces '%s' c=calls '%s' l=log q=quit +-*/=scroll enter", text_interfaces[show_interfaces], text_calls[show_calls]); addstr(buffer); refresh(); @@ -972,47 +1042,125 @@ readagain: goto again; } - /* user input */ - switch(getch()) + if (enter) { - case 12: /* refresh */ - cleanup_curses(); - init_curses(); - goto again; - break; - - case 3: /* abort */ - case 'q': - case 'Q': - break; + /* user input in enter mode */ + ch = getch(); + if (ch == 10) + { + FILE *fp; + + enter = 0; + if (!enter_string[0]) + goto again; + + SPRINT(logline[logcur++ % LOGLINES], "> %s", enter_string); + if (!!strncmp(enter_string, "interface", 10) && + !!strncmp(enter_string, "route", 6) && + !!strncmp(enter_string, "release ", 8) && + !!strncmp(enter_string, "block ", 6) && + !!strncmp(enter_string, "unblock ", 8) && + !!strncmp(enter_string, "unload ", 7)) + { + SPRINT(logline[logcur++ % LOGLINES], "usage:"); + SPRINT(logline[logcur++ % LOGLINES], "interface (reload interface.conf)"); + SPRINT(logline[logcur++ % LOGLINES], "route (reload routing.conf)"); + SPRINT(logline[logcur++ % LOGLINES], "release (release endpoint with given ID)"); + SPRINT(logline[logcur++ % LOGLINES], "block (block port for further calls)"); + SPRINT(logline[logcur++ % LOGLINES], "unblock (unblock port for further calls, load if not loaded)"); + SPRINT(logline[logcur++ % LOGLINES], "unload (unload mISDN stack, release call calls)"); + } else + { + /* applend output to log window */ + SPRINT(buffer, "%s %s", argv[0], enter_string); + fp = popen(buffer, "r"); + if (fp) + { + while(fgets(logline[logcur % LOGLINES], sizeof(logline[0]), fp)) + logline[logcur++ % LOGLINES][sizeof(logline[0])-1] = '\0'; + pclose(fp); + } else + { + SPRINT(logline[logcur++ % LOGLINES], "failed to execute '%s'", buffer); + } + } + logline[logcur % LOGLINES][0] = '\0'; + enter_string[0] = '\0'; + goto again; + } + if (ch>=32 && ch<=126) + { + SCCAT(enter_string, ch); + goto again; + } else + if (ch==8 || ch==127) + { + if (enter_string[0]) + enter_string[strlen(enter_string)-1] = '\0'; + goto again; + } else + if (ch != 3) + { + usleep(250000); + goto again; + } + } else + { + /* user input in normal mode */ + switch(getch()) + { + case 12: /* refresh */ + cleanup_curses(); + init_curses(); + goto again; + break; - case 'i': /* toggle interface */ - show_interfaces++; - if (show_interfaces > 3) show_interfaces = 0; - goto again; + case 3: /* abort */ + case 'q': + case 'Q': + break; - case 'c': /* toggle calls */ - show_calls++; - if (show_calls > 2) show_calls = 0; - goto again; + case 'i': /* toggle interface */ + show_interfaces++; + if (show_interfaces > 3) show_interfaces = 0; + goto again; - case 'l': /* toggle log */ - show_log++; - if (show_log > 1) show_log = 0; - goto again; + case 'c': /* toggle calls */ + show_calls++; + if (show_calls > 2) show_calls = 0; + goto again; - case '+': /* scroll down */ - offset++; - goto again; - - case '-': /* scroll up */ - if (offset) - offset--; - goto again; + case 'l': /* toggle log */ + show_log++; + if (show_log > 1) show_log = 0; + goto again; - default: - usleep(250000); - goto again; + case '+': /* scroll down */ + offset++; + goto again; + + case '-': /* scroll up */ + if (offset) + offset--; + goto again; + + case '*': /* scroll right */ + hoffset += 2; + goto again; + + case '/': /* scroll left */ + if (hoffset) + hoffset -= 2; + goto again; + + case 10: /* entermode */ + enter = 1; + goto again; + + default: + usleep(250000); + goto again; + } } /* check for logfh */ @@ -1052,6 +1200,21 @@ char *admin_cmd(int sock, int mode, char *extension, char *number) msg.message = ADMIN_REQUEST_CMD_RELEASE; SCPY(msg.u.x.message, number); break; + case MODE_UNBLOCK: + msg.message = ADMIN_REQUEST_CMD_BLOCK; + msg.u.x.portnum = atoi(number); + msg.u.x.block = 0; + break; + case MODE_BLOCK: + msg.message = ADMIN_REQUEST_CMD_BLOCK; + msg.u.x.portnum = atoi(number); + msg.u.x.block = 1; + break; + case MODE_UNLOAD: + msg.message = ADMIN_REQUEST_CMD_BLOCK; + msg.u.x.portnum = atoi(number); + msg.u.x.block = 2; + break; } if (write(sock, &msg, sizeof(msg)) != sizeof(msg)) @@ -1078,6 +1241,12 @@ char *admin_cmd(int sock, int mode, char *extension, char *number) if (msg.message != ADMIN_RESPONSE_CMD_RELEASE) return("Response not valid."); break; + case MODE_UNBLOCK: + case MODE_BLOCK: + case MODE_UNLOAD: + if (msg.message != ADMIN_RESPONSE_CMD_BLOCK) + return("Response not valid."); + break; } /* process response */ @@ -1202,6 +1371,79 @@ next: /* + * makes a trace + */ +char *admin_trace(int sock, int argc, char *argv[]) +{ + static struct admin_message msg; + int i; + + /* show help */ + if (argc > 2) if (!strcasecmp(argv[2], "help")) + { + printf("Trace Help\n----------\n"); + printf("%s trace [brief|short] [= [...]]\n\n", argv[0]); + printf("By default a complete trace is shown in detailed format.\n"); + printf("To show a more compact format, use 'brief' or 'short' keyword.\n"); + printf("Use filter values to select specific trace messages.\n"); + printf("All given filter values must match. If no filter is given, anything matches.\n\n"); + printf("Filters:\n"); + printf(" category=\n"); + printf(" 0x01 = CH: channel object trace\n"); + printf(" 0x02 = EP: endpoint object trace\n"); + printf(" port= select only given port for trace\n"); + printf(" interface= select only given interface for trace\n"); + printf(" caller= select only given caller id for trace\n"); + printf(" dialing= select only given dialed number for trace\n"); + return(NULL); + } + + /* init trace request */ + memset(&msg, 0, sizeof(msg)); + msg.message = ADMIN_TRACE_REQUEST; + msg.u.trace_req.detail = 3; + + /* parse args */ + i = 2; + while(i < argc) + { + if (!strcasecmp(argv[i], "brief")) + msg.u.trace_req.detail = 1; + else if (!strcasecmp(argv[i], "short")) + msg.u.trace_req.detail = 2; + else if (!strncasecmp(argv[i], "category=", 9)) + msg.u.trace_req.category = atoi(argv[i]+9); + else if (!strncasecmp(argv[i], "port=", 5)) + msg.u.trace_req.port = atoi(argv[i]+5); + else if (!strncasecmp(argv[i], "interface=", 10)) + SCPY(msg.u.trace_req.interface, argv[i]+10); + else if (!strncasecmp(argv[i], "caller=", 7)) + SCPY(msg.u.trace_req.caller, argv[i]+7); + else if (!strncasecmp(argv[i], "dialing=", 8)) + SCPY(msg.u.trace_req.dialing, argv[i]+8); + else return("Invalid trace option, try 'trace help'."); + + i++; + } + + /* send trace request */ + if (write(sock, &msg, sizeof(msg)) != sizeof(msg)) + return("Broken pipe while sending trace request."); + + /* receive response */ +next: + if (read(sock, &msg, sizeof(msg)) != sizeof(msg)) + return("Broken pipe while receiving response."); + + if (msg.message != ADMIN_TRACE_RESPONSE) + return("Response not valid."); + + printf("%s", msg.u.trace_rsp.text); + goto next; +} + + +/* * main function */ int main(int argc, char *argv[]) @@ -1220,12 +1462,17 @@ 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 PBX to reload \"interface.conf\".\n"); - printf("route - Tell PBX to reload \"route.conf\".\n"); - printf("dial - Tell PBX the next number to dial for extension.\n"); - printf("release - Tell PBX to release endpoint with given number.\n"); + printf("interface - Tell LCR to reload \"interface.conf\".\n"); + printf("route - Tell LCR to reload \"route.conf\".\n"); + printf("dial - Tell LCR the next number to dial for extension.\n"); + printf("release - Tell LCR to release endpoint with given number.\n"); + printf("block - Block given port.\n"); + printf("unblock - Unblock given port.\n"); + printf("unload - Unload port. To load port use 'block' or 'unblock'.\n"); printf("testcall [present|restrict []] - Testcall\n"); printf(" -> capability = (Values must be numbers, -1 to omit.)\n"); + printf("trace [brief|short] [ [...]] - Shows call trace. Use filter to reduce output.\n"); + printf(" -> Use 'trace help' to see filter description.\n"); printf("\n"); return(0); } @@ -1255,12 +1502,34 @@ int main(int argc, char *argv[]) goto usage; mode = MODE_RELEASE; } else + if (!(strcasecmp(argv[1],"unblock"))) + { + if (argc <= 2) + goto usage; + mode = MODE_UNBLOCK; + } else + if (!(strcasecmp(argv[1],"block"))) + { + if (argc <= 2) + goto usage; + mode = MODE_BLOCK; + } else + if (!(strcasecmp(argv[1],"unload"))) + { + if (argc <= 2) + goto usage; + mode = MODE_UNLOAD; + } else if (!(strcasecmp(argv[1],"testcall"))) { if (argc <= 4) goto usage; mode = MODE_TESTCALL; } else + if (!(strcasecmp(argv[1],"trace"))) + { + mode = MODE_TRACE; + } else { goto usage; } @@ -1278,7 +1547,7 @@ int main(int argc, char *argv[]) if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0) { close(sock); - fprintf(stderr, "Failed to connect to socket \"%s\".\nIs PBX4Linux running?\n", sock_address.sun_path); + fprintf(stderr, "Failed to connect to socket \"%s\".\nIs LCR running?\n", sock_address.sun_path); exit(EXIT_FAILURE); } @@ -1286,7 +1555,7 @@ int main(int argc, char *argv[]) switch(mode) { case MODE_STATE: - ret = admin_state(sock); + ret = admin_state(sock, argv); break; case MODE_INTERFACE: @@ -1299,11 +1568,17 @@ int main(int argc, char *argv[]) break; case MODE_RELEASE: + case MODE_UNBLOCK: + case MODE_BLOCK: + case MODE_UNLOAD: ret = admin_cmd(sock, mode, NULL, argv[2]); break; case MODE_TESTCALL: ret = admin_testcall(sock, argc, argv); + + case MODE_TRACE: + ret = admin_trace(sock, argc, argv); } close(sock);