Ein Commandline interface, wo man von der console and der rtpengine
bestimme Dinge abfragen kann.

Author:    Frederic-Philippe Metz <Frederic.Metz@1und1.de>
pull/60/head
Frederic-Philippe Metz 11 years ago committed by Richard Fuchs
parent ee655bdcc6
commit 131c9e8110

@ -162,6 +162,7 @@ option and which are reproduced below:
-F, --no-fallback Only start when kernel module is available -F, --no-fallback Only start when kernel module is available
-i, --interface=[NAME/]IP[!IP] Local interface for RTP -i, --interface=[NAME/]IP[!IP] Local interface for RTP
-l, --listen-tcp=[IP:]PORT TCP port to listen on -l, --listen-tcp=[IP:]PORT TCP port to listen on
-c, --listen-cli=[IP46:]PORT TCP port to listen on, CLI (command line interface)
-u, --listen-udp=[IP46:]PORT UDP port to listen on -u, --listen-udp=[IP46:]PORT UDP port to listen on
-n, --listen-ng=[IP46:]PORT UDP port to listen on, NG protocol -n, --listen-ng=[IP46:]PORT UDP port to listen on, NG protocol
-T, --tos=INT TOS value to set on streams -T, --tos=INT TOS value to set on streams
@ -267,6 +268,10 @@ The options are described in more detail below.
It is recommended to specify not only a local port number, but also 127.0.0.1 as interface to bind to. It is recommended to specify not only a local port number, but also 127.0.0.1 as interface to bind to.
* -c, --listen-cli
TCP ip and port to listen for the CLI (command line interface).
* -t, --tos * -t, --tos
Takes an integer as argument and if given, specifies the TOS value that should be set in outgoing Takes an integer as argument and if given, specifies the TOS value that should be set in outgoing

@ -61,7 +61,7 @@ endif
SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \ SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \
bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \ bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \
crypto.c rtp.c call_interfaces.c dtls.c log.c crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c
OBJS= $(SRCS:.c=.o) OBJS= $(SRCS:.c=.o)

@ -2645,7 +2645,7 @@ restart:
} }
/* returns call with master_lock held in W, or NULL if not found */ /* returns call with master_lock held in W, or NULL if not found */
static struct call *call_get(const str *callid, struct callmaster *m) { struct call *call_get(const str *callid, struct callmaster *m) {
struct call *ret; struct call *ret;
rwlock_lock_r(&m->hashlock); rwlock_lock_r(&m->hashlock);

@ -420,6 +420,7 @@ struct packet_stream *__packet_stream_new(struct call *call);
struct call *call_get_or_create(const str *callid, struct callmaster *m); struct call *call_get_or_create(const str *callid, struct callmaster *m);
struct call *call_get_opmode(const str *callid, struct callmaster *m, enum call_opmode opmode); struct call *call_get_opmode(const str *callid, struct callmaster *m, enum call_opmode opmode);
struct call_monologue *call_get_mono_dialogue(struct call *call, const str *fromtag, const str *totag); struct call_monologue *call_get_mono_dialogue(struct call *call, const str *fromtag, const str *totag);
struct call *call_get(const str *callid, struct callmaster *m);
int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams, const struct sdp_ng_flags *flags); int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams, const struct sdp_ng_flags *flags);
int call_delete_branch(struct callmaster *m, const str *callid, const str *branch, int call_delete_branch(struct callmaster *m, const str *callid, const str *branch,
const str *fromtag, const str *totag, bencode_item_t *output); const str *fromtag, const str *totag, bencode_item_t *output);

@ -0,0 +1,308 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <netinet/in.h>
#include <errno.h>
#include <glib.h>
#include "poller.h"
#include "aux.h"
#include "log.h"
#include "call.h"
#include "cli.h"
static const char* TRUNCATED = " ... Output truncated. Increase Output Buffer ...\n";
#define truncate_output(x) do { x -= strlen(TRUNCATED)+1; x += sprintf(x,"%s",TRUNCATED); } while (0);
#define ADJUSTLEN(printlen,outbuflen,replybuffer) do { if (printlen>=(outbufend-replybuffer)) \
truncate_output(replybuffer); \
replybuffer += (printlen>=outbufend-replybuffer)?outbufend-replybuffer:printlen; } while (0);
static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) {
str callid;
struct call* c=0;
struct call_monologue *ml;
struct call_media *md;
struct packet_stream *ps;
GSList *l;
GList *k, *o;
char buf[64];
int printlen=0;
if (len<=1) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return;
}
++buffer; --len; // one space
str_init_len(&callid,buffer,len);
c = call_get(&callid, m);
if (!c) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nCall Id not found (%s).\n\n",callid.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return;
}
printlen = snprintf (replybuffer,(outbufend-replybuffer), "\ncallid: %30s | deletionmark:%4s | created:%12i\n\n", c->callid.s , c->ml_deleted?"yes":"no", (int)c->created);
ADJUSTLEN(printlen,outbufend,replybuffer);
for (l = c->monologues; l; l = l->next) {
ml = l->data;
printlen = snprintf(replybuffer,(outbufend-replybuffer), "--- Tag '"STR_FORMAT"', callduration "
"%u:%02u , in dialogue with '"STR_FORMAT"'\n",
STR_FMT(&ml->tag),
(unsigned int) (poller_now - ml->created) / 60,
(unsigned int) (poller_now - ml->created) % 60,
ml->active_dialogue ? ml->active_dialogue->tag.len : 6,
ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)");
ADJUSTLEN(printlen,outbufend,replybuffer);
for (k = ml->medias.head; k; k = k->next) {
md = k->data;
for (o = md->streams.head; o; o = o->next) {
ps = o->data;
if (PS_ISSET(ps, FALLBACK_RTCP))
continue;
smart_ntop_p(buf, &ps->endpoint.ip46, sizeof(buf));
printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, port %5u <> %15s:%-5hu%s, "
"%llu p, %llu b, %llu e\n",
md->index,
(unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
buf, ps->endpoint.port,
(!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) ? " (RTCP)" : "",
(unsigned long long) ps->stats.packets,
(unsigned long long) ps->stats.bytes,
(unsigned long long) ps->stats.errors);
ADJUSTLEN(printlen,outbufend,replybuffer);
}
}
}
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_w(&c->master_lock); // because of call_get(..)
}
static void cli_incoming_list(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) {
GHashTableIter iter;
gpointer key, value;
str *ptrkey;
struct call *call;
int printlen=0;
static const char* LIST_NUMSESSIONS = "numsessions";
static const char* LIST_SESSIONS = "sessions";
static const char* LIST_SESSION = "session";
if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return;
}
++buffer; --len; // one space
if (len>=strlen(LIST_NUMSESSIONS) && strncmp(buffer,LIST_NUMSESSIONS,strlen(LIST_NUMSESSIONS)) == 0) {
rwlock_lock_r(&m->hashlock);
printlen = snprintf(replybuffer, outbufend-replybuffer, "Current Sessions on rtpengine:%i\n", g_hash_table_size(m->callhash));
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_r(&m->hashlock);
} else if (len>=strlen(LIST_SESSIONS) && strncmp(buffer,LIST_SESSIONS,strlen(LIST_SESSIONS)) == 0) {
rwlock_lock_r(&m->hashlock);
if (g_hash_table_size(m->callhash)==0) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "No sessions on this media relay.\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_r(&m->hashlock);
return;
}
g_hash_table_iter_init (&iter, m->callhash);
while (g_hash_table_iter_next (&iter, &key, &value)) {
ptrkey = (str*)key;
call = (struct call*)value;
printlen = snprintf(replybuffer, outbufend-replybuffer, "callid: %30s | deletionmark:%4s | created:%12i\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created);
ADJUSTLEN(printlen,outbufend,replybuffer);
}
rwlock_unlock_r(&m->hashlock);
} else if (len>=strlen(LIST_SESSION) && strncmp(buffer,LIST_SESSION,strlen(LIST_SESSION)) == 0) {
cli_incoming_list_callid(buffer+strlen(LIST_SESSION), len-strlen(LIST_SESSION), m, replybuffer, outbufend);
} else {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s:%s\n", "Unknown 'list' command", buffer);
ADJUSTLEN(printlen,outbufend,replybuffer);
}
}
static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) {
str termparam;
struct call* c=0;
int printlen=0;
GHashTableIter iter;
gpointer key, value;
if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return;
}
++buffer; --len; // one space
str_init_len(&termparam,buffer,len);
// --- terminate all calls
if (!str_memcmp(&termparam,"all")) {
while (g_hash_table_size(m->callhash)) {
g_hash_table_iter_init (&iter, m->callhash);
g_hash_table_iter_next (&iter, &key, &value);
c = (struct call*)value;
if (!c) continue;
call_destroy(c);
}
ilog(LOG_INFO,"All calls terminated by operator.");
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All calls terminated by operator.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return;
}
// --- terminate a dedicated call id
c = call_get(&termparam, m);
if (!c) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "\nCall Id not found (%s).\n\n",termparam.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return;
}
call_destroy(c);
printlen = snprintf(replybuffer, outbufend-replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",termparam.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
ilog(LOG_WARN, "Call Id (%s) successfully terminated by operator.",termparam.s);
rwlock_unlock_w(&c->master_lock);
}
static void cli_incoming(int fd, void *p, uintptr_t u) {
int nfd;
struct sockaddr_in sin;
struct cli *cli = (void *) p;
socklen_t sinl;
static const int BUFLENGTH = 4096*1024;
char replybuffer[BUFLENGTH]; memset(&replybuffer,0,BUFLENGTH);
char* outbuf = replybuffer;
const char* outbufend = replybuffer+BUFLENGTH;
static const int MAXINPUT = 1024;
char inbuf[MAXINPUT]; memset(&inbuf,0,MAXINPUT);
int inlen = 0, readbytes = 0;
int rc=0;
mutex_lock(&cli->lock);
next:
sinl = sizeof(sin);
nfd = accept(fd, (struct sockaddr *) &sin, &sinl);
if (nfd == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
sprintf(replybuffer, "Could currently not accept CLI commands. Reason:%s\n", strerror(errno));
goto cleanup;
}
ilog(LOG_INFO, "Accept error:%s\n", strerror(errno));
goto next;
}
ilog(LOG_INFO, "New cli connection from " DF, DP(sin));
do {
readbytes = read(nfd, inbuf+inlen, MAXINPUT);
if (readbytes == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
ilog(LOG_INFO, "Could currently not read CLI commands. Reason:%s\n", strerror(errno));
goto cleanup;
}
ilog(LOG_INFO, "Could currently not read CLI commands. Reason:%s\n", strerror(errno));
}
inlen += readbytes;
} while (readbytes > 0);
ilog(LOG_INFO, "Got CLI command:%s\n",inbuf);
static const char* LIST = "list";
static const char* TERMINATE = "terminate";
if (inlen>=strlen(LIST) && strncmp(inbuf,LIST,strlen(LIST)) == 0) {
cli_incoming_list(inbuf+strlen(LIST), inlen-strlen(LIST), cli->callmaster, outbuf, outbufend);
} else if (inlen>=strlen(TERMINATE) && strncmp(inbuf,TERMINATE,strlen(TERMINATE)) == 0) {
cli_incoming_terminate(inbuf+strlen(TERMINATE), inlen-strlen(TERMINATE), cli->callmaster, outbuf, outbufend);
} else {
sprintf(replybuffer, "%s:%s\n", "Unknown or incomplete command:", inbuf);
}
do {
rc += write( nfd, (char *)&replybuffer, strlen(replybuffer) );
} while (rc < strlen(replybuffer));
cleanup:
close(nfd);
mutex_unlock(&cli->lock);
}
static void control_closed(int fd, void *p, uintptr_t u) {
abort();
}
struct cli *cli_new(struct poller *p, u_int32_t ip, u_int16_t port, struct callmaster *m) {
struct cli *c;
int fd;
struct sockaddr_in sin;
struct poller_item i;
if (!p || !m)
return NULL;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
return NULL;
nonblock(fd);
reuseaddr(fd);
ZERO(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ip;
sin.sin_port = htons(port);
if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)))
goto fail;
if (listen(fd, 5))
goto fail;
c = obj_alloc0("cli_udp", sizeof(*c), NULL);
c->fd = fd;
c->poller = p;
c->callmaster = m;
mutex_init(&c->lock);
ZERO(i);
i.fd = fd;
i.closed = control_closed;
i.readable = cli_incoming;
i.obj = &c->obj;
if (poller_add_item(p, &i))
goto fail2;
obj_put(c);
return c;
fail2:
obj_put(c);
fail:
close(fd);
return NULL;
}

@ -0,0 +1,18 @@
#ifndef CLI_UDP_H_
#define CLI_UDP_H_
#include <netinet/in.h>
struct cli {
struct obj obj;
struct callmaster *callmaster;
int fd;
struct poller *poller;
mutex_t lock;
};
struct cli *cli_new(struct poller *p, u_int32_t ip, u_int16_t port, struct callmaster *m);
#endif /* CLI_UDP_H_ */

@ -25,6 +25,7 @@
#include "sdp.h" #include "sdp.h"
#include "dtls.h" #include "dtls.h"
#include "call_interfaces.h" #include "call_interfaces.h"
#include "cli.h"
@ -91,6 +92,8 @@ static struct in6_addr udp_listenp;
static u_int16_t udp_listenport; static u_int16_t udp_listenport;
static struct in6_addr ng_listenp; static struct in6_addr ng_listenp;
static u_int16_t ng_listenport; static u_int16_t ng_listenport;
static u_int32_t cli_listenp;
static u_int16_t cli_listenport;
static int tos; static int tos;
static int table = -1; static int table = -1;
static int no_fallback; static int no_fallback;
@ -309,6 +312,7 @@ static void options(int *argc, char ***argv) {
char *listenps = NULL; char *listenps = NULL;
char *listenudps = NULL; char *listenudps = NULL;
char *listenngs = NULL; char *listenngs = NULL;
char *listencli = NULL;
char *redisps = NULL; char *redisps = NULL;
char *log_facility_s = NULL; char *log_facility_s = NULL;
char *log_facility_cdr_s = NULL; char *log_facility_cdr_s = NULL;
@ -323,6 +327,7 @@ static void options(int *argc, char ***argv) {
{ "listen-tcp", 'l', 0, G_OPTION_ARG_STRING, &listenps, "TCP port to listen on", "[IP:]PORT" }, { "listen-tcp", 'l', 0, G_OPTION_ARG_STRING, &listenps, "TCP port to listen on", "[IP:]PORT" },
{ "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" }, { "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" },
{ "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" }, { "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" },
{ "listen-cli", 'c', 0, G_OPTION_ARG_STRING, &listencli, "UDP port to listen on, CLI", "[IP46:]PORT" },
{ "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" }, { "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" },
{ "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" }, { "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" },
{ "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" }, { "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" },
@ -380,6 +385,10 @@ static void options(int *argc, char ***argv) {
die("Invalid IP or port (--listen-ng)"); die("Invalid IP or port (--listen-ng)");
} }
if (listencli) {if (parse_ip_port(&cli_listenp, &cli_listenport, listencli))
die("Invalid IP or port (--listen-cli)");
}
if (tos < 0 || tos > 255) if (tos < 0 || tos > 255)
die("Invalid TOS value"); die("Invalid TOS value");
@ -557,6 +566,7 @@ void create_everything(struct main_context *ctx) {
struct control_tcp *ct; struct control_tcp *ct;
struct control_udp *cu; struct control_udp *cu;
struct control_ng *cn; struct control_ng *cn;
struct cli *cl;
int kfd = -1; int kfd = -1;
void *dlh; void *dlh;
const char **strp; const char **strp;
@ -625,6 +635,14 @@ no_kernel:
die("Failed to open UDP control connection port"); die("Failed to open UDP control connection port");
} }
cl = NULL;
if (cli_listenport) {
callmaster_exclude_port(ctx->m, cli_listenport);
cl = cli_new(ctx->p, cli_listenp, cli_listenport, ctx->m);
if (!cl)
die("Failed to open UDP CLI connection port");
}
if (redis_ip) { if (redis_ip) {
dlh = dlopen(MP_PLUGIN_DIR "/rtpengine-redis.so", RTLD_NOW | RTLD_GLOBAL); dlh = dlopen(MP_PLUGIN_DIR "/rtpengine-redis.so", RTLD_NOW | RTLD_GLOBAL);
if (!dlh && !g_file_test(MP_PLUGIN_DIR "/rtpengine-redis.so", G_FILE_TEST_IS_REGULAR) if (!dlh && !g_file_test(MP_PLUGIN_DIR "/rtpengine-redis.so", G_FILE_TEST_IS_REGULAR)

@ -2,6 +2,7 @@ RUN_RTPENGINE=no
LISTEN_TCP=25060 LISTEN_TCP=25060
LISTEN_UDP=12222 LISTEN_UDP=12222
LISTEN_NG=22222 LISTEN_NG=22222
LISTEN_CLI=9900
# INTERFACES="123.234.345.456" # INTERFACES="123.234.345.456"
# INTERFACES="internal/12.23.34.45 external/23.34.45.54" # INTERFACES="internal/12.23.34.45 external/23.34.45.54"
# INTERFACES="12.23.34.45!23.34.45.56" # INTERFACES="12.23.34.45!23.34.45.56"

@ -55,6 +55,7 @@ fi
[ -z "$LISTEN_TCP" ] || OPTIONS="$OPTIONS --listen-tcp=$LISTEN_TCP" [ -z "$LISTEN_TCP" ] || OPTIONS="$OPTIONS --listen-tcp=$LISTEN_TCP"
[ -z "$LISTEN_UDP" ] || OPTIONS="$OPTIONS --listen-udp=$LISTEN_UDP" [ -z "$LISTEN_UDP" ] || OPTIONS="$OPTIONS --listen-udp=$LISTEN_UDP"
[ -z "$LISTEN_NG" ] || OPTIONS="$OPTIONS --listen-ng=$LISTEN_NG" [ -z "$LISTEN_NG" ] || OPTIONS="$OPTIONS --listen-ng=$LISTEN_NG"
[ -z "$LISTEN_CLI" ] || OPTIONS="$OPTIONS --listen-cli=$LISTEN_CLI"
[ -z "$TIMEOUT" ] || OPTIONS="$OPTIONS --timeout=$TIMEOUT" [ -z "$TIMEOUT" ] || OPTIONS="$OPTIONS --timeout=$TIMEOUT"
[ -z "$SILENT_TIMEOUT" ] || OPTIONS="$OPTIONS --silent-timeout=$SILENT_TIMEOUT" [ -z "$SILENT_TIMEOUT" ] || OPTIONS="$OPTIONS --silent-timeout=$SILENT_TIMEOUT"
[ -z "$PIDFILE" ] || OPTIONS="$OPTIONS --pidfile=$PIDFILE" [ -z "$PIDFILE" ] || OPTIONS="$OPTIONS --pidfile=$PIDFILE"

@ -1 +1,2 @@
daemon/rtpengine /usr/sbin/ daemon/rtpengine /usr/sbin/
utils/rtpengine-ctl /usr/sbin/

@ -92,6 +92,11 @@ build_opts() {
OPTS+=" --listen-ng=$LISTEN_NG" OPTS+=" --listen-ng=$LISTEN_NG"
fi fi
if [[ -n "$LISTEN_CLI" ]]
then
OPTS+=" --listen-cli=$LISTEN_CLI"
fi
if [[ -n "$TOS" ]] if [[ -n "$TOS" ]]
then then
OPTS+=" --tos=$TOS" OPTS+=" --tos=$TOS"

@ -20,6 +20,7 @@ LISTEN_UDP=127.0.0.1:2222 # IP address and port combination for UDP
# control # control
#LISTEN_NG=127.0.0.1:2223 # IP address and port combination for NG (UDP) #LISTEN_NG=127.0.0.1:2223 # IP address and port combination for NG (UDP)
# control # control
#LISTEN_CLI=127.0.0.1:9900
# #
#TOS=184 # (o) TOS value to use in outgoing packets #TOS=184 # (o) TOS value to use in outgoing packets
#TIMEOUT=60 # (o) Number of seconds after which a media stream is #TIMEOUT=60 # (o) Number of seconds after which a media stream is

@ -0,0 +1,69 @@
#!/bin/bash
#
host=127.0.0.1
port=9900
error_rc=255
prgname=${0##*/}
prgdir=${0%$prgname}
showusage() {
echo ""
echo " rectl [ -ip <ipaddress> -port <port> ] <command>"
echo ""
echo " Supported commands are:"
echo ""
echo " list [ numsessions | sessions | session <callid> ]"
echo " numsessions : prints the number of sessions"
echo " sessions : print one-liner session information"
echo " session <callid> : print detail about one session"
echo ""
echo " terminate [ all | <callid> ]"
echo " all : terminates all current sessions"
echo " <callid> : session is immediately terminated"
echo ""
echo ""
echo " Return Value:"
echo " 0 on success with ouput from server side, other values for failure."
echo ""
exit 0
}
if [ $# -eq 0 ]; then showusage; fi
command -v nc 2>&1 >/dev/null
if [ $? -ne 0 ]; then
echo "Error: rectl requires netcat to be installed."
exit 0
fi
while [ $# -gt 0 ]; do
case $1 in
"-?"|"-help"|"-h")
showusage
;;
"-ip")
shift
if [ $# -gt 0 ]; then
host=$1
else
echo "Missing parameter for option '-ip'" >&2
fi
;;
"-port")
shift
if [ $# -gt 0 ]; then
port=$1
else
echo "Missing parameter for option '-port'" >&2
fi
;;
*)
varargs="$varargs $1"
esac
shift
done
echo -n ${varargs} | nc ${host} ${port}
Loading…
Cancel
Save