00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <fcntl.h>
00020 #include <stdio.h>
00021 #include <time.h>
00022 #include <ctype.h>
00023 #ifndef _MSC_VER
00024 #include <unistd.h>
00025 #endif
00026 #include <signal.h>
00027
00028 #include "iaxclient.h"
00029
00030 #define LEVEL_INCREMENT 0.10
00031
00032
00033 static char *output_filename = NULL;
00034 static char *username = NULL;
00035 static char *password = NULL;
00036 static char *host = NULL;
00037 int do_levels = 0;
00038 int intercom = 0;
00039 int initialized = 0;
00040 int reg_id = 0;
00041
00042
00043
00044
00045 void killem(void)
00046 {
00047 if (initialized)
00048 iaxc_shutdown();
00049 if (reg_id){
00050 iaxc_unregister(reg_id);
00051 }
00052 return;
00053 }
00054
00055 void signal_handler(int signum)
00056 {
00057 if ( signum == SIGTERM || signum == SIGINT )
00058 {
00059 killem();
00060 exit(0);
00061 }
00062 }
00063
00064 void fatal_error(char *err) {
00065 killem();
00066 fprintf(stderr, "FATAL ERROR: %s\n", err);
00067 exit(1);
00068 }
00069
00070 void mysleep(void)
00071 {
00072 iaxc_millisleep(10);
00073 }
00074
00075 int state_event_callback(struct iaxc_ev_call_state call){
00076 if((call.state & IAXC_CALL_STATE_RINGING))
00077 {
00078 printf("Receiving Incoming Call Request...\n");
00079 if ( intercom )
00080 {
00081 printf("Intercom mode, answer automatically\n");
00082 return iaxc_select_call(call.callNo);
00083 }
00084 }
00085 return 0;
00086 }
00087 int levels_callback(float input, float output) {
00088 if(do_levels) fprintf(stderr, "IN: %f OUT: %f\n", input, output);
00089 return 0;
00090 }
00091
00092 int netstat_callback(struct iaxc_ev_netstats n) {
00093 static int i;
00094 if(i++%25 == 0)
00095 fprintf(stderr, "RTT\t"
00096 "Rjit\tRlos%%\tRlosC\tRpkts\tRdel\tRdrop\tRooo\t"
00097 "Ljit\tLlos%%\tLlosC\tLpkts\tLdel\tLdrop\tLooo\n"
00098 );
00099
00100 fprintf(stderr, "%d\t"
00101 "%d\t%d\t%d\t%d\t%d\t%d\t%d\t"
00102 "%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
00103
00104 n.rtt,
00105
00106 n.remote.jitter,
00107 n.remote.losspct,
00108 n.remote.losscnt,
00109 n.remote.packets,
00110 n.remote.delay,
00111 n.remote.dropped,
00112 n.remote.ooo,
00113
00114 n.local.jitter,
00115 n.local.losspct,
00116 n.local.losscnt,
00117 n.local.packets,
00118 n.local.delay,
00119 n.local.dropped,
00120 n.local.ooo
00121 );
00122
00123 return 0;
00124 }
00125
00126 int iaxc_callback(iaxc_event e)
00127 {
00128 switch(e.type) {
00129 case IAXC_EVENT_LEVELS:
00130 return levels_callback(e.ev.levels.input, e.ev.levels.output);
00131 case IAXC_EVENT_NETSTAT:
00132 return netstat_callback(e.ev.netstats);
00133 case IAXC_EVENT_TEXT:
00134 return 0;
00135 case IAXC_EVENT_STATE:
00136 return state_event_callback(e.ev.call);
00137 default:
00138 return 0;
00139 }
00140 }
00141
00142 void list_devices()
00143 {
00144 struct iaxc_audio_device *devs;
00145 int nDevs, input, output, ring;
00146 int i;
00147
00148 iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring);
00149 for(i=0;i<nDevs;i++) {
00150 fprintf(stderr, "DEVICE ID=%d NAME=%s CAPS=%lx\n", devs[i].devID, devs[i].name, devs[i].capabilities);
00151 }
00152 }
00153
00154 void usage()
00155 {
00156 fprintf(stderr, "Usage: testcall [-?] [-v] [-i] [-s SILENCE_THRESHOLD] [-u USERNAME -p PASSWORD -h HOST]\n");
00157 exit(1);
00158 }
00159
00160 int main(int argc, char **argv)
00161 {
00162 FILE *f;
00163 char c;
00164 int i;
00165 char *dest = NULL;
00166 double silence_threshold = -99;
00167 double level;
00168
00169 f = stdout;
00170
00171 for(i=1;i<argc;i++)
00172 {
00173 if(argv[i][0] == '-')
00174 {
00175 switch(tolower(argv[i][1]))
00176 {
00177 case '?':
00178 usage();
00179 break;
00180 case 'v':
00181 do_levels = 1;
00182 break;
00183 case 'i':
00184 intercom = 1;
00185 break;
00186 case 's':
00187 if(i+1 >= argc) usage();
00188 silence_threshold = atof(argv[++i]);
00189 break;
00190 case 'u':
00191 if(i+1 >= argc) usage();
00192 username = argv[++i];
00193 break;
00194 case 'p':
00195 if(i+1 >= argc) usage();
00196 password = argv[++i];
00197 break;
00198 case 'h':
00199 if(i+1 >= argc) usage();
00200 host = argv[++i];
00201 break;
00202
00203 default:
00204 usage();
00205 }
00206 } else {
00207 dest=argv[i];
00208 }
00209 }
00210
00211
00212 printf("settings: \n");
00213 printf("\tsilence threshold: %f\n", silence_threshold);
00214 printf("\tlevel output: %s\n", do_levels ? "on" : "off");
00215
00216
00217 atexit(killem);
00218
00219
00220 signal(SIGINT, signal_handler);
00221 signal(SIGTERM, signal_handler);
00222
00223 if ( iaxc_initialize(1) ) fatal_error("cannot initialize iaxclient!");
00224 initialized = 1;
00225
00226
00227
00228 iaxc_set_formats(IAXC_FORMAT_GSM,IAXC_FORMAT_GSM);
00229
00230
00231 iaxc_set_silence_threshold(silence_threshold);
00232
00233 list_devices();
00234
00235
00236 iaxc_set_event_callback(iaxc_callback);
00237
00238
00239 fprintf(f, "\n\
00240 TestCall accept some keyboard input while it's running.\n\
00241 You must hit 'enter' for your keypresses to be recognized,\n\
00242 although you can type more than one key on a line\n\
00243 \n\
00244 q: hangup and exit.\n\
00245 a: answer incoming call\n\
00246 t: terminate call\n\
00247 0-9 * or #: dial those DTMF digits.\n\
00248 g: increase input level\n\
00249 b: decrease input level\n\
00250 h: increase output level\n\
00251 n: decrease output level\n\
00252 Enter: display current audio levels\n");
00253 if(dest) {
00254 fprintf(f, "Calling %s\n", dest);
00255
00256 iaxc_call(dest);
00257 }
00258
00259 iaxc_start_processing_thread();
00260
00261 if (username && password && host)
00262 reg_id = iaxc_register(username, password, host);
00263
00264 printf("ready for keyboard input\n");
00265
00266 if(output_filename) {
00267 for(;;)
00268 iaxc_millisleep(10*1000);
00269 }
00270 while((c = getc(stdin)))
00271 {
00272 switch (tolower(c))
00273 {
00274 case 'a':
00275 printf("Answering call 0\n");
00276 iaxc_select_call(0);
00277 break;
00278 case 'g':
00279 level = iaxc_input_level_get();
00280 level += LEVEL_INCREMENT;
00281 if ( level > 1.00 ) level = 1.00;
00282 printf("Increasing input level to %f\n", level);
00283 iaxc_input_level_set(level);
00284 break;
00285 case 'b':
00286 level = iaxc_input_level_get();
00287 level -= LEVEL_INCREMENT;
00288 if ( level < 0 ) level = 0.00;
00289 printf("Decreasing input level to %f\n", level);
00290 iaxc_input_level_set(level);
00291 break;
00292 case 'h':
00293 level = iaxc_output_level_get();
00294 level += LEVEL_INCREMENT;
00295 if ( level > 1.00 ) level = 1.00;
00296 printf("Increasing output level to %f\n", level);
00297 iaxc_output_level_set(level);
00298 break;
00299 case 'n':
00300 level = iaxc_output_level_get();
00301 level -= LEVEL_INCREMENT;
00302 if ( level < 0 ) level = 0.00;
00303 printf("Decreasing output level to %f\n", level);
00304 iaxc_output_level_set(level);
00305 break;
00306 case 'q':
00307 printf("Hanging up and exiting\n");
00308 iaxc_dump_call();
00309 iaxc_millisleep(1000);
00310 iaxc_stop_processing_thread();
00311 exit(0);
00312 break;
00313 case 't':
00314 printf("Terminating call 0\n");
00315 iaxc_dump_call();
00316 break;
00317 case '1': case '2': case '3': case '4': case '5':
00318 case '6': case '7': case '8': case '9': case '0':
00319 case '#': case '*':
00320 printf ("sending %c\n", c);
00321 iaxc_send_dtmf(c);
00322 break;
00323 case '\r':
00324 break;
00325 case '\n':
00326 printf("Input level = %f -- Output level = %f\n", iaxc_input_level_get(), iaxc_output_level_get());
00327 break;
00328 default:
00329 printf("Unknown command '%c'\n", c);
00330 }
00331 }
00332
00333 return 0;
00334 }