/* * 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 * * 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 #include #include #include #include #include #include #ifndef _MSC_VER #include #endif #include #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= 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; }