mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 21:27:57 +00:00
Introduce basic vomp console test
This commit is contained in:
parent
32ab923dcc
commit
7ed6be3690
@ -245,6 +245,7 @@ ATOM(bool_t, keyring, 0, boolean,, "")
|
||||
ATOM(bool_t, security, 0, boolean,, "")
|
||||
ATOM(bool_t, mdprequests, 0, boolean,, "")
|
||||
ATOM(bool_t, msp, 0, boolean,, "")
|
||||
ATOM(bool_t, monitor, 0, boolean,, "")
|
||||
ATOM(bool_t, radio_link, 0, boolean,, "")
|
||||
ATOM(bool_t, peers, 0, boolean,, "")
|
||||
ATOM(bool_t, overlaybuffer, 0, boolean,, "")
|
||||
|
@ -76,7 +76,8 @@ int monitor_client_open(struct monitor_state **res)
|
||||
struct socket_address addr;
|
||||
if (make_local_sockaddr(&addr, "monitor.socket") == -1)
|
||||
return -1;
|
||||
INFOF("Attempting to connect to %s", alloca_socket_address(&addr));
|
||||
if (config.debug.monitor)
|
||||
DEBUGF("Attempting to connect to %s", alloca_socket_address(&addr));
|
||||
if (socket_connect(fd, &addr.addr, addr.addrlen) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
@ -89,6 +90,8 @@ int monitor_client_open(struct monitor_state **res)
|
||||
int monitor_client_close(int fd, struct monitor_state *res){
|
||||
free(res);
|
||||
close(fd);
|
||||
if (config.debug.monitor)
|
||||
DEBUGF("Closed fd %d", fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -105,6 +108,9 @@ int monitor_client_writeline(int fd,char *fmt, ...)
|
||||
n=vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (config.debug.monitor)
|
||||
dump("Writing to monitor", msg, n);
|
||||
|
||||
return write(fd,msg,n);
|
||||
}
|
||||
|
||||
@ -126,6 +132,8 @@ int monitor_client_writeline_and_data(int fd,unsigned char *data,int bytes,char
|
||||
|
||||
bcopy(data,out+n,bytes);
|
||||
n+=bytes;
|
||||
if (config.debug.monitor)
|
||||
dump("Writing to monitor", out, n);
|
||||
return write(fd,out,n);
|
||||
}
|
||||
|
||||
@ -159,6 +167,10 @@ int monitor_client_read(int fd, struct monitor_state *res, struct monitor_comman
|
||||
WHYF("read(%d, %p, %d) returned %d", fd, res->buffer + oldOffset, MONITOR_CLIENT_BUFFER_SIZE - oldOffset, bytesRead);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (config.debug.monitor)
|
||||
dump("Read from monitor", res->buffer + oldOffset, bytesRead);
|
||||
|
||||
res->bufferBytes+=bytesRead;
|
||||
|
||||
again:
|
||||
|
@ -33,5 +33,6 @@ includeTests rhizomeprotocol
|
||||
includeTests rhizomehttp
|
||||
includeTests meshms
|
||||
includeTests directory_service
|
||||
includeTests vomp
|
||||
|
||||
runTests "$@"
|
||||
|
76
tests/vomp
Executable file
76
tests/vomp
Executable file
@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Tests for voice calls
|
||||
#
|
||||
# Copyright 2012 Serval Project, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
source "${0%/*}/../testframework.sh"
|
||||
source "${0%/*}/../testdefs.sh"
|
||||
|
||||
teardown() {
|
||||
stop_all_servald_servers
|
||||
kill_all_servald_processes
|
||||
assert_no_servald_processes
|
||||
report_all_servald_servers
|
||||
}
|
||||
|
||||
configure_servald_server() {
|
||||
create_single_identity
|
||||
add_servald_interface
|
||||
executeOk_servald config \
|
||||
set debug.mdprequests on \
|
||||
set debug.monitor on \
|
||||
set debug.vomp on \
|
||||
set log.console.level DEBUG \
|
||||
set log.console.show_time on
|
||||
}
|
||||
|
||||
vomp_connect() {
|
||||
executeOk_servald console < <(sleep 1 && echo "call $1 $2 $3" && sleep 3 && echo "say hello" && sleep 3 && echo "hangup")
|
||||
tfw_cat --stdout --stderr
|
||||
assertStdoutGrep --stdout --matches=1 "^Dialling$"
|
||||
assertStdoutGrep --stdout --matches=1 "^Codec list"
|
||||
assertStdoutGrep --stdout --matches=1 "^Ringing$"
|
||||
assertStdoutGrep --stdout --matches=1 "^Picked up$"
|
||||
assertStdoutGrep --stdout --matches=1 "^hi there$"
|
||||
assertStdoutGrep --stdout --matches=1 "^Call ended$"
|
||||
}
|
||||
|
||||
vomp_answer() {
|
||||
executeOk_servald console < <(sleep 2 && echo "answer" && sleep 2 && echo "say hi there" && sleep 3 && echo "hangup")
|
||||
tfw_cat --stdout --stderr
|
||||
assertStdoutGrep --stdout --matches=1 "^Incoming call"
|
||||
assertStdoutGrep --stdout --matches=1 "^Codec list"
|
||||
assertStdoutGrep --stdout --matches=1 "^hello$"
|
||||
assertStdoutGrep --stdout --matches=1 "^Call ended$"
|
||||
}
|
||||
|
||||
doc_call_lifecycle="Successful call lifecycle"
|
||||
setup_call_lifecycle() {
|
||||
setup_servald
|
||||
assert_no_servald_processes
|
||||
start_servald_instances +A +B
|
||||
}
|
||||
test_call_lifecycle() {
|
||||
set_instance +A
|
||||
fork vomp_answer
|
||||
set_instance +B
|
||||
fork vomp_connect $SIDA $DIDB $DIDA
|
||||
fork_wait_all
|
||||
}
|
||||
|
||||
runTests "$@"
|
6
vomp.c
6
vomp.c
@ -475,7 +475,7 @@ static void prepare_vomp_header(
|
||||
ob_append_byte(payload, VOMP_VERSION);
|
||||
ob_append_ui16(payload, call->local.session);
|
||||
ob_append_ui16(payload, call->remote.session);
|
||||
ob_append_ui16(payload, (call->remote.state<<4)|call->local.state);
|
||||
ob_append_byte(payload, (call->remote.state<<4)|call->local.state);
|
||||
|
||||
// keep trying to punch a NAT tunnel for 10s
|
||||
// note that requests are rate limited internally to one packet per second
|
||||
@ -526,6 +526,8 @@ static int vomp_send_status_remote(struct vomp_call_state *call)
|
||||
call->local.sequence++;
|
||||
|
||||
ob_flip(payload);
|
||||
if (config.debug.vomp)
|
||||
ob_dump(payload, "payload");
|
||||
overlay_send_frame(&header, payload);
|
||||
ob_free(payload);
|
||||
|
||||
@ -563,6 +565,8 @@ int vomp_received_audio(struct vomp_call_state *call, int audio_codec, int time,
|
||||
ob_append_bytes(payload, audio, audio_length);
|
||||
|
||||
ob_flip(payload);
|
||||
if (config.debug.vomp)
|
||||
ob_dump(payload, "payload");
|
||||
overlay_send_frame(&header, payload);
|
||||
ob_free(payload);
|
||||
|
||||
|
133
vomp_console.c
133
vomp_console.c
@ -64,10 +64,23 @@
|
||||
#include "strbuf.h"
|
||||
#include "strbuf_helpers.h"
|
||||
|
||||
int call_token=-1;
|
||||
int seen_audio=0;
|
||||
int monitor_client_fd=-1;
|
||||
struct monitor_state *monitor_state;
|
||||
static void read_lines(struct sched_ent *alarm);
|
||||
static int console_dial(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_answer(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_hangup(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_audio(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_usage(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static void console_command(char *line);
|
||||
static void monitor_read(struct sched_ent *alarm);
|
||||
|
||||
struct cli_schema console_commands[]={
|
||||
{console_answer,{"answer",NULL},0,"Answer an incoming phone call"},
|
||||
{console_dial,{"call","<sid>","[<local_number>]","[<remote_extension>]",NULL},0,"Start dialling a given person"},
|
||||
{console_hangup,{"hangup",NULL},0,"Hangup the phone line"},
|
||||
{console_usage,{"help",NULL},0,"This usage message"},
|
||||
{console_audio,{"say","...",NULL},0,"Send a text string to the other party"},
|
||||
{NULL, {NULL, NULL, NULL}, 0, NULL},
|
||||
};
|
||||
|
||||
struct line_state{
|
||||
struct sched_ent alarm;
|
||||
@ -77,20 +90,45 @@ struct line_state{
|
||||
void (*process_line)(char *line);
|
||||
};
|
||||
|
||||
struct profile_total stdin_profile={
|
||||
.name="read_lines",
|
||||
};
|
||||
struct line_state stdin_state={
|
||||
.alarm = {
|
||||
.poll = {.fd = STDIN_FILENO,.events = POLLIN},
|
||||
.function = read_lines,
|
||||
.stats=&stdin_profile
|
||||
},
|
||||
.fd=0,
|
||||
.process_line=console_command,
|
||||
};
|
||||
struct profile_total monitor_profile={
|
||||
.name="monitor_read",
|
||||
};
|
||||
struct sched_ent monitor_alarm={
|
||||
.poll = {.fd = STDIN_FILENO,.events = POLLIN},
|
||||
.function = monitor_read,
|
||||
.stats=&monitor_profile,
|
||||
};
|
||||
|
||||
int call_token=-1;
|
||||
int seen_audio=0;
|
||||
struct monitor_state *monitor_state;
|
||||
|
||||
static void send_hangup(int session_id){
|
||||
monitor_client_writeline(monitor_client_fd, "hangup %06x\n",session_id);
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "hangup %06x\n",session_id);
|
||||
}
|
||||
static void send_ringing(int session_id){
|
||||
monitor_client_writeline(monitor_client_fd, "ringing %06x\n",session_id);
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "ringing %06x\n",session_id);
|
||||
}
|
||||
static void send_pickup(int session_id){
|
||||
monitor_client_writeline(monitor_client_fd, "pickup %06x\n",session_id);
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "pickup %06x\n",session_id);
|
||||
}
|
||||
static void send_call(const char *sid, const char *caller_id, const char *remote_ext){
|
||||
monitor_client_writeline(monitor_client_fd, "call %s %s %s\n", sid, caller_id, remote_ext);
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "call %s %s %s\n", sid, caller_id, remote_ext);
|
||||
}
|
||||
static void send_audio(int session_id, unsigned char *buffer, int len, int codec){
|
||||
monitor_client_writeline_and_data(monitor_client_fd, buffer, len, "audio %06x %d\n", session_id, codec);
|
||||
monitor_client_writeline_and_data(monitor_alarm.poll.fd, buffer, len, "audio %06x %d\n", session_id, codec);
|
||||
}
|
||||
|
||||
static int remote_call(char *UNUSED(cmd), int UNUSED(argc), char **argv, unsigned char *UNUSED(data), int UNUSED(dataLen), void *UNUSED(context))
|
||||
@ -106,7 +144,7 @@ static int remote_call(char *UNUSED(cmd), int UNUSED(argc), char **argv, unsigne
|
||||
|
||||
call_token = token;
|
||||
seen_audio = 0;
|
||||
printf("Incoming call from %s (%s)\n",argv[3],argv[4]);
|
||||
printf("Incoming call for %s (%s) from %s (%s)\n", argv[1], argv[2], argv[3], argv[4]);
|
||||
fflush(stdout);
|
||||
send_ringing(token);
|
||||
return 1;
|
||||
@ -116,7 +154,7 @@ static int remote_ringing(char *UNUSED(cmd), int UNUSED(argc), char **argv, unsi
|
||||
{
|
||||
int token = strtol(argv[0], NULL, 16);
|
||||
if (call_token == token){
|
||||
printf("They're ringing\n");
|
||||
printf("Ringing\n");
|
||||
fflush(stdout);
|
||||
}else
|
||||
send_hangup(token);
|
||||
@ -127,7 +165,7 @@ static int remote_pickup(char *UNUSED(cmd), int UNUSED(argc), char **argv, unsig
|
||||
{
|
||||
int token = strtol(argv[0], NULL, 16);
|
||||
if (call_token == token){
|
||||
printf("They've picked up\n");
|
||||
printf("Picked up\n");
|
||||
fflush(stdout);
|
||||
}else
|
||||
send_hangup(token);
|
||||
@ -169,9 +207,12 @@ static int remote_audio(char *UNUSED(cmd), int UNUSED(argc), char **argv, unsign
|
||||
case VOMP_CODEC_TEXT:
|
||||
data[dataLen]=0;
|
||||
printf("%s\n",data);
|
||||
fflush(stdout);
|
||||
break;
|
||||
default:
|
||||
printf("Unhandled codec %d, len %d\n", codec, dataLen);
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
}else
|
||||
send_hangup(token);
|
||||
return 1;
|
||||
@ -221,6 +262,7 @@ struct monitor_command_handler console_handlers[]={
|
||||
{.command="AUDIO", .handler=remote_audio},
|
||||
{.command="CODECS", .handler=remote_codecs},
|
||||
{.command="INFO", .handler=remote_print},
|
||||
{.command="ERROR", .handler=remote_print},
|
||||
{.command="CALLSTATUS", .handler=remote_noop},
|
||||
{.command="KEEPALIVE", .handler=remote_noop},
|
||||
{.command="MONITORSTATUS", .handler=remote_noop},
|
||||
@ -269,11 +311,11 @@ static int console_audio(const struct cli_parsed *parsed, struct cli_context *UN
|
||||
static struct strbuf str_buf = STRUCT_STRBUF_EMPTY;
|
||||
strbuf_init(&str_buf, buf, sizeof(buf));
|
||||
unsigned i;
|
||||
for (i = 0; i < parsed->argc; ++i) {
|
||||
if (i)
|
||||
for (i = 1; i < parsed->argc; ++i) {
|
||||
if (i>1)
|
||||
strbuf_putc(&str_buf, ' ');
|
||||
if (parsed->args[i])
|
||||
strbuf_toprint_quoted(&str_buf, "\"\"", parsed->args[i]);
|
||||
strbuf_puts(&str_buf, parsed->args[i]);
|
||||
else
|
||||
strbuf_puts(&str_buf, "NULL");
|
||||
}
|
||||
@ -283,17 +325,6 @@ static int console_audio(const struct cli_parsed *parsed, struct cli_context *UN
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_usage(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
|
||||
struct cli_schema console_commands[]={
|
||||
{console_answer,{"answer",NULL},0,"Answer an incoming phone call"},
|
||||
{console_dial,{"call","<sid>","[<local_number>]","[<remote_extension>]",NULL},0,"Start dialling a given person"},
|
||||
{console_hangup,{"hangup",NULL},0,"Hangup the phone line"},
|
||||
{console_usage,{"help",NULL},0,"This usage message"},
|
||||
{console_audio,{"say","...",NULL},0,"Send a text string to the other party"},
|
||||
{NULL, {NULL, NULL, NULL}, 0, NULL},
|
||||
};
|
||||
|
||||
static int console_usage(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
|
||||
{
|
||||
cli_usage(console_commands, XPRINTF_STDIO(stdout));
|
||||
@ -329,6 +360,15 @@ static void read_lines(struct sched_ent *alarm){
|
||||
struct line_state *state=(struct line_state *)alarm;
|
||||
set_nonblock(STDIN_FILENO);
|
||||
int bytes = read(state->alarm.poll.fd, state->line_buff + state->line_pos, sizeof(state->line_buff) - state->line_pos);
|
||||
if (bytes<=0){
|
||||
if (monitor_alarm.poll.fd!=-1){
|
||||
unwatch(&monitor_alarm);
|
||||
monitor_client_close(monitor_alarm.poll.fd, monitor_state);
|
||||
monitor_alarm.poll.fd=-1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
set_block(STDIN_FILENO);
|
||||
int i = state->line_pos;
|
||||
int processed=0;
|
||||
@ -355,10 +395,11 @@ static void read_lines(struct sched_ent *alarm){
|
||||
static void monitor_read(struct sched_ent *alarm){
|
||||
if (monitor_client_read(alarm->poll.fd, monitor_state, console_handlers,
|
||||
sizeof(console_handlers)/sizeof(struct monitor_command_handler))<0){
|
||||
unwatch(alarm);
|
||||
monitor_client_close(alarm->poll.fd, monitor_state);
|
||||
alarm->poll.fd=-1;
|
||||
monitor_client_fd=-1;
|
||||
if (alarm->poll.fd!=-1){
|
||||
unwatch(alarm);
|
||||
monitor_client_close(alarm->poll.fd, monitor_state);
|
||||
alarm->poll.fd=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,40 +407,18 @@ int app_vomp_console(const struct cli_parsed *parsed, struct cli_context *UNUSED
|
||||
{
|
||||
if (config.debug.verbose)
|
||||
DEBUG_cli_parsed(parsed);
|
||||
static struct profile_total stdin_profile={
|
||||
.name="read_lines",
|
||||
};
|
||||
struct line_state stdin_state={
|
||||
.alarm = {
|
||||
.poll = {.fd = STDIN_FILENO,.events = POLLIN},
|
||||
.function = read_lines,
|
||||
.stats=&stdin_profile
|
||||
},
|
||||
.fd=0,
|
||||
.process_line=console_command,
|
||||
};
|
||||
static struct profile_total monitor_profile={
|
||||
.name="monitor_read",
|
||||
};
|
||||
struct sched_ent monitor_alarm={
|
||||
.poll = {.fd = STDIN_FILENO,.events = POLLIN},
|
||||
.function = monitor_read,
|
||||
.stats=&monitor_profile,
|
||||
};
|
||||
|
||||
monitor_client_fd = monitor_client_open(&monitor_state);
|
||||
monitor_alarm.poll.fd = monitor_client_open(&monitor_state);
|
||||
|
||||
monitor_client_writeline(monitor_client_fd, "monitor vomp %d\n",
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "monitor vomp %d\n",
|
||||
VOMP_CODEC_TEXT);
|
||||
|
||||
set_nonblock(monitor_client_fd);
|
||||
set_nonblock(monitor_alarm.poll.fd);
|
||||
|
||||
monitor_alarm.poll.fd = monitor_client_fd;
|
||||
watch(&monitor_alarm);
|
||||
|
||||
watch(&stdin_state.alarm);
|
||||
|
||||
while(monitor_client_fd!=-1){
|
||||
while(monitor_alarm.poll.fd!=-1){
|
||||
fd_poll();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user