flightgear/3rdparty/iaxclient-2/simpleclient/iaxvoipclient.c
2022-11-12 21:36:02 +08:00

335 lines
7.6 KiB
C

/*
* testcall: make a single test call with IAXCLIENT
*
* IAX Support for talking to Asterisk and other Gnophone clients
*
* Copyright (C) 1999, Linux Support Services, Inc.
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU Lesser (Library) General Public License
*/
/* #define PRINTCHUCK /\* enable this to indicate chucked incomming packets *\/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <signal.h>
#include "iaxclient.h"
#define LEVEL_INCREMENT 0.10f
/* static int answered_call; */
static char *output_filename = NULL;
static char *username = NULL;
static char *password = NULL;
static char *host = NULL;
int do_levels = 0;
int intercom = 0;
int initialized = 0;
int reg_id = 0;
/* routine called at exit to shutdown audio I/O and close nicely.
NOTE: If all this isnt done, the system doesnt not handle this
cleanly and has to be rebooted. What a pile of doo doo!! */
void killem(void)
{
if (initialized)
iaxc_shutdown();
if (reg_id){
iaxc_unregister(reg_id);
}
return;
}
void signal_handler(int signum)
{
if ( signum == SIGTERM || signum == SIGINT )
{
killem();
exit(0);
}
}
void fatal_error(char *err) {
killem();
fprintf(stderr, "FATAL ERROR: %s\n", err);
exit(1);
}
void mysleep(void)
{
iaxc_millisleep(10);
}
int state_event_callback(struct iaxc_ev_call_state call){
if((call.state & IAXC_CALL_STATE_RINGING))
{
printf("Receiving Incoming Call Request...\n");
if ( intercom )
{
printf("Intercom mode, answer automatically\n");
return iaxc_select_call(call.callNo);
}
}
return 0;
}
int levels_callback(float input, float output) {
if(do_levels) fprintf(stderr, "IN: %f OUT: %f\n", input, output);
return 0;
}
int netstat_callback(struct iaxc_ev_netstats n) {
static int i;
if(i++%25 == 0)
fprintf(stderr, "RTT\t"
"Rjit\tRlos%%\tRlosC\tRpkts\tRdel\tRdrop\tRooo\t"
"Ljit\tLlos%%\tLlosC\tLpkts\tLdel\tLdrop\tLooo\n"
);
fprintf(stderr, "%d\t"
"%d\t%d\t%d\t%d\t%d\t%d\t%d\t"
"%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
n.rtt,
n.remote.jitter,
n.remote.losspct,
n.remote.losscnt,
n.remote.packets,
n.remote.delay,
n.remote.dropped,
n.remote.ooo,
n.local.jitter,
n.local.losspct,
n.local.losscnt,
n.local.packets,
n.local.delay,
n.local.dropped,
n.local.ooo
);
return 0;
}
int iaxc_callback(iaxc_event e)
{
switch(e.type) {
case IAXC_EVENT_LEVELS:
return levels_callback(e.ev.levels.input, e.ev.levels.output);
case IAXC_EVENT_NETSTAT:
return netstat_callback(e.ev.netstats);
case IAXC_EVENT_TEXT:
return 0; // don't handle
case IAXC_EVENT_STATE:
return state_event_callback(e.ev.call);
default:
return 0; // not handled
}
}
void list_devices()
{
struct iaxc_audio_device *devs;
int nDevs, input, output, ring;
int i;
iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring);
for(i=0;i<nDevs;i++) {
fprintf(stderr, "DEVICE ID=%d NAME=%s CAPS=%lx\n", devs[i].devID, devs[i].name, devs[i].capabilities);
}
}
void usage()
{
fprintf(stderr, "Usage: testcall [-?] [-v] [-i] [-s SILENCE_THRESHOLD] [-u USERNAME -p PASSWORD -h HOST]\n");
exit(1);
}
int main(int argc, char **argv)
{
FILE *f;
char c;
int i;
char *dest = NULL;
float silence_threshold = -99.0f;
float level;
f = stdout;
for(i=1;i<argc;i++)
{
if(argv[i][0] == '-')
{
switch(tolower(argv[i][1]))
{
case '?':
usage();
break;
case 'v':
do_levels = 1;
break;
case 'i':
intercom = 1;
break;
case 's':
if(i+1 >= argc) usage();
silence_threshold = (float)atof(argv[++i]);
break;
case 'u':
if(i+1 >= argc) usage();
username = argv[++i];
break;
case 'p':
if(i+1 >= argc) usage();
password = argv[++i];
break;
case 'h':
if(i+1 >= argc) usage();
host = argv[++i];
break;
default:
usage();
}
} else {
dest=argv[i];
}
}
printf("settings: \n");
printf("\tsilence threshold: %f\n", silence_threshold);
printf("\tlevel output: %s\n", do_levels ? "on" : "off");
/* activate the exit handler */
atexit(killem);
/* install signal handler to catch CRTL-Cs */
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
if ( iaxc_initialize(1) ) fatal_error("cannot initialize iaxclient!");
initialized = 1;
// iaxc_set_formats(IAXC_FORMAT_SPEEX,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM|IAXC_FORMAT_SPEEX);
// iaxc_set_formats(IAXC_FORMAT_SPEEX,IAXC_FORMAT_SPEEX);
// iaxc_set_formats(IAXC_FORMAT_GSM,IAXC_FORMAT_GSM);
// iaxc_set_formats(IAXC_FORMAT_ULAW,IAXC_FORMAT_ULAW);
iaxc_set_formats(IAXC_FORMAT_ULAW,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM|IAXC_FORMAT_SPEEX);
iaxc_set_silence_threshold(silence_threshold);
list_devices();
//if(do_levels)
iaxc_set_event_callback(iaxc_callback);
fprintf(f, "\n\
TestCall accept some keyboard input while it's running.\n\
You must hit 'enter' for your keypresses to be recognized,\n\
although you can type more than one key on a line\n\
\n\
q: hangup and exit.\n\
a: answer incoming call\n\
t: terminate call\n\
0-9 * or #: dial those DTMF digits.\n\
g: increase input level\n\
b: decrease input level\n\
h: increase output level\n\
n: decrease output level\n\
Enter: display current audio levels\n");
if(dest) {
fprintf(f, "Calling %s\n", dest);
iaxc_call(dest);
}
iaxc_start_processing_thread();
if (username && password && host)
reg_id = iaxc_register(username, password, host);
printf("ready for keyboard input\n");
if(output_filename) {
for(;;)
iaxc_millisleep(10*1000);
}
while((c = getc(stdin)))
{
switch (tolower(c))
{
case 'a':
printf("Answering call 0\n");
iaxc_select_call(0);
break;
case 'g':
level = iaxc_input_level_get();
level += LEVEL_INCREMENT;
if ( level > 1.00 ) level = 1.00;
printf("Increasing input level to %f\n", level);
iaxc_input_level_set(level);
break;
case 'b':
level = iaxc_input_level_get();
level -= LEVEL_INCREMENT;
if ( level < 0 ) level = 0.00;
printf("Decreasing input level to %f\n", level);
iaxc_input_level_set(level);
break;
case 'h':
level = iaxc_output_level_get();
level += LEVEL_INCREMENT;
if ( level > 1.00 ) level = 1.00;
printf("Increasing output level to %f\n", level);
iaxc_output_level_set(level);
break;
case 'n':
level = iaxc_output_level_get();
level -= LEVEL_INCREMENT;
if ( level < 0 ) level = 0.00;
printf("Decreasing output level to %f\n", level);
iaxc_output_level_set(level);
break;
case 'q':
printf("Hanging up and exiting\n");
iaxc_dump_call();
iaxc_millisleep(1000);
iaxc_stop_processing_thread();
exit(0);
break;
case 't':
printf("Terminating call 0\n");
iaxc_dump_call();
break;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0':
case '#': case '*':
printf ("sending %c\n", c);
iaxc_send_dtmf(c);
break;
case '\r':
break;
case '\n':
printf("Input level = %f -- Output level = %f\n", iaxc_input_level_get(), iaxc_output_level_get());
break;
default:
printf("Unknown command '%c'\n", c);
}
}
return 0;
}