00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <assert.h>
00022
00023 #if defined(WIN32) || defined(_WIN32_WCE)
00024 #include <stdlib.h>
00025 #endif
00026
00027
00028 #if ! HAVE_VSNPRINTF
00029 # if HAVE__VSNPRINTF
00030 # define vsnprintf _vsnprintf
00031 # endif
00032 #endif
00033
00034 #include "iaxclient_lib.h"
00035 #include "audio_portaudio.h"
00036 #include "audio_encode.h"
00037 #ifdef USE_VIDEO
00038 #include "video.h"
00039 #endif
00040 #include "iax-client.h"
00041 #include "jitterbuf.h"
00042
00043 #if STDC_HEADERS
00044 # include <stdarg.h>
00045 #else
00046 # if HAVE_VARARGS_H
00047 # include <varargs.h>
00048 # endif
00049 #endif
00050
00051 #ifdef AUDIO_ALSA
00052 #include "audio_alsa.h"
00053 #endif
00054
00055 #define IAXC_ERROR IAXC_TEXT_TYPE_ERROR
00056 #define IAXC_STATUS IAXC_TEXT_TYPE_STATUS
00057 #define IAXC_NOTICE IAXC_TEXT_TYPE_NOTICE
00058
00059 #define DEFAULT_CALLERID_NAME "Not Available"
00060 #define DEFAULT_CALLERID_NUMBER "7005551212"
00061
00062 #undef JB_DEBUGGING
00063
00064
00065 static long jb_target_extra = -1;
00066
00067 struct iaxc_registration
00068 {
00069 struct iax_session *session;
00070 struct timeval last;
00071 char host[256];
00072 char user[256];
00073 char pass[256];
00074 long refresh;
00075 int id;
00076 struct iaxc_registration *next;
00077 };
00078
00079 static int next_registration_id = 0;
00080 static struct iaxc_registration *registrations = NULL;
00081
00082 static struct iaxc_audio_driver audio_driver;
00083
00084 static int audio_format_capability;
00085 static int audio_format_preferred;
00086
00087
00088
00089 static unsigned int audio_prefs = 0;
00090
00091 void * post_event_handle = NULL;
00092 int post_event_id = 0;
00093
00094 static int minimum_outgoing_framesize = 160;
00095
00096 static MUTEX iaxc_lock;
00097 static MUTEX event_queue_lock;
00098
00099 static short iaxci_bound_port = -1;
00100
00101
00102 static int source_udp_port = IAX_DEFAULT_PORTNO;
00103
00104 int iaxci_audio_output_mode = 0;
00105
00106 int selected_call;
00107 struct iaxc_call* calls;
00108 int max_calls;
00109
00110 static void service_network();
00111 static int service_audio();
00112
00113
00114 static iaxc_sendto_t iaxc_sendto = (iaxc_sendto_t)sendto;
00115 static iaxc_recvfrom_t iaxc_recvfrom = (iaxc_recvfrom_t)recvfrom;
00116
00117
00118 static THREAD main_proc_thread;
00119 #ifdef USE_VIDEO
00120 static THREAD video_proc_thread;
00121 #endif
00122 #if defined(WIN32) || defined(_WIN32_WCE)
00123 static THREADID main_proc_thread_id;
00124 #ifdef USE_VIDEO
00125 static THREADID video_proc_thread_id;
00126 #endif
00127 #endif
00128
00129
00130 static int main_proc_thread_flag = -1;
00131 #ifdef USE_VIDEO
00132 static int video_proc_thread_flag = -1;
00133 #endif
00134
00135 static iaxc_event_callback_t iaxc_event_callback = NULL;
00136
00137
00138
00139 static iaxc_event *event_queue = NULL;
00140
00141
00142 static void get_iaxc_lock()
00143 {
00144 MUTEXLOCK(&iaxc_lock);
00145 }
00146
00147
00148 static void put_iaxc_lock()
00149 {
00150 iaxc_event *prev, *event;
00151
00152 MUTEXLOCK(&event_queue_lock);
00153 event = event_queue;
00154 event_queue = NULL;
00155 MUTEXUNLOCK(&event_queue_lock);
00156
00157 MUTEXUNLOCK(&iaxc_lock);
00158
00159 while (event)
00160 {
00161 iaxci_post_event(*event);
00162 prev = event;
00163 event = event->next;
00164 free(prev);
00165 }
00166 }
00167
00168 EXPORT void iaxc_set_audio_output(int mode)
00169 {
00170 iaxci_audio_output_mode = mode;
00171 }
00172
00173 long iaxci_usecdiff(struct timeval * t0, struct timeval * t1)
00174 {
00175 return (t0->tv_sec - t1->tv_sec) * 1000000L + t0->tv_usec - t1->tv_usec;
00176 }
00177
00178 long iaxci_msecdiff(struct timeval * t0, struct timeval * t1)
00179 {
00180 return iaxci_usecdiff(t0, t1) / 1000L;
00181 }
00182
00183 EXPORT void iaxc_set_event_callback(iaxc_event_callback_t func)
00184 {
00185 iaxc_event_callback = func;
00186 }
00187
00188 EXPORT int iaxc_set_event_callpost(void *handle, int id)
00189 {
00190 post_event_handle = handle;
00191 post_event_id = id;
00192 iaxc_event_callback = iaxci_post_event_callback;
00193 return 0;
00194 }
00195
00196 EXPORT void iaxc_free_event(iaxc_event *e)
00197 {
00198 free(e);
00199 }
00200
00201 EXPORT struct iaxc_ev_levels *iaxc_get_event_levels(iaxc_event *e)
00202 {
00203 return &e->ev.levels;
00204 }
00205
00206 EXPORT struct iaxc_ev_text *iaxc_get_event_text(iaxc_event *e)
00207 {
00208 return &e->ev.text;
00209 }
00210
00211 EXPORT struct iaxc_ev_call_state *iaxc_get_event_state(iaxc_event *e)
00212 {
00213 return &e->ev.call;
00214 }
00215
00216
00217 static void default_message_callback(const char * message)
00218 {
00219 fprintf(stderr, "IAXCLIENT: %s\n", message);
00220 }
00221
00222
00223 void iaxci_post_event(iaxc_event e)
00224 {
00225 if ( e.type == 0 )
00226 {
00227 iaxci_usermsg(IAXC_ERROR,
00228 "Error: something posted to us an invalid event");
00229 return;
00230 }
00231
00232 if ( MUTEXTRYLOCK(&iaxc_lock) )
00233 {
00234 iaxc_event **tail;
00235
00236
00237 MUTEXLOCK(&event_queue_lock);
00238 tail = &event_queue;
00239 e.next = NULL;
00240 while ( *tail )
00241 tail = &(*tail)->next;
00242 *tail = (iaxc_event *)malloc(sizeof(iaxc_event));
00243 memcpy(*tail, &e, sizeof(iaxc_event));
00244 MUTEXUNLOCK(&event_queue_lock);
00245 return;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 MUTEXUNLOCK(&iaxc_lock);
00259
00260 if ( iaxc_event_callback )
00261 {
00262 int rv;
00263
00264 rv = iaxc_event_callback(e);
00265
00266 if ( e.type == IAXC_EVENT_VIDEO )
00267 {
00268
00269
00270
00271 free(e.ev.video.data);
00272 }
00273 else if ( e.type == IAXC_EVENT_AUDIO )
00274 {
00275 free(e.ev.audio.data);
00276 }
00277
00278 if ( rv < 0 )
00279 default_message_callback(
00280 "IAXCLIENT: BIG PROBLEM, event callback returned failure!");
00281
00282 if ( rv > 0 )
00283 return;
00284
00285
00286 }
00287
00288 switch ( e.type )
00289 {
00290 case IAXC_EVENT_TEXT:
00291 default_message_callback(e.ev.text.message);
00292
00293 return;
00294 }
00295 }
00296
00297
00298 void iaxci_usermsg(int type, const char *fmt, ...)
00299 {
00300 va_list args;
00301 iaxc_event e;
00302
00303 e.type = IAXC_EVENT_TEXT;
00304 e.ev.text.type = type;
00305 e.ev.text.callNo = -1;
00306 va_start(args, fmt);
00307 vsnprintf(e.ev.text.message, IAXC_EVENT_BUFSIZ, fmt, args);
00308 va_end(args);
00309
00310 iaxci_post_event(e);
00311 }
00312
00313
00314 void iaxci_do_levels_callback(float input, float output)
00315 {
00316 iaxc_event e;
00317 e.type = IAXC_EVENT_LEVELS;
00318 e.ev.levels.input = input;
00319 e.ev.levels.output = output;
00320 iaxci_post_event(e);
00321 }
00322
00323 void iaxci_do_state_callback(int callNo)
00324 {
00325 iaxc_event e;
00326 if ( callNo < 0 || callNo >= max_calls )
00327 return;
00328 e.type = IAXC_EVENT_STATE;
00329 e.ev.call.callNo = callNo;
00330 e.ev.call.state = calls[callNo].state;
00331 e.ev.call.format = calls[callNo].format;
00332 e.ev.call.vformat = calls[callNo].vformat;
00333 strncpy(e.ev.call.remote, calls[callNo].remote, IAXC_EVENT_BUFSIZ);
00334 strncpy(e.ev.call.remote_name, calls[callNo].remote_name, IAXC_EVENT_BUFSIZ);
00335 strncpy(e.ev.call.local, calls[callNo].local, IAXC_EVENT_BUFSIZ);
00336 strncpy(e.ev.call.local_context, calls[callNo].local_context, IAXC_EVENT_BUFSIZ);
00337 iaxci_post_event(e);
00338 }
00339
00340 void iaxci_do_registration_callback(int id, int reply, int msgcount)
00341 {
00342 iaxc_event e;
00343 e.type = IAXC_EVENT_REGISTRATION;
00344 e.ev.reg.id = id;
00345 e.ev.reg.reply = reply;
00346 e.ev.reg.msgcount = msgcount;
00347 iaxci_post_event(e);
00348 }
00349
00350 void iaxci_do_audio_callback(int callNo, unsigned int ts, int source,
00351 int encoded, int format, int size, unsigned char *data)
00352 {
00353 iaxc_event e;
00354
00355 e.type = IAXC_EVENT_AUDIO;
00356 e.ev.audio.ts = ts;
00357 e.ev.audio.encoded = encoded;
00358 assert(source == IAXC_SOURCE_REMOTE || source == IAXC_SOURCE_LOCAL);
00359 e.ev.audio.source = source;
00360 e.ev.audio.size = size;
00361 e.ev.audio.callNo = callNo;
00362 e.ev.audio.format = format;
00363
00364 e.ev.audio.data = (unsigned char *)malloc(size);
00365
00366 if ( !e.ev.audio.data )
00367 {
00368 iaxci_usermsg(IAXC_ERROR,
00369 "failed to allocate memory for audio event");
00370 return;
00371 }
00372
00373 memcpy(e.ev.audio.data, data, size);
00374
00375 iaxci_post_event(e);
00376 }
00377
00378 static int iaxc_remove_registration_by_id(int id)
00379 {
00380 struct iaxc_registration *curr, *prev;
00381 int count = 0;
00382 for ( prev = NULL, curr = registrations; curr != NULL;
00383 prev = curr, curr = curr->next )
00384 {
00385 if ( curr->id == id )
00386 {
00387 count++;
00388 if ( curr->session != NULL )
00389 iax_destroy( curr->session );
00390 if ( prev != NULL )
00391 prev->next = curr->next;
00392 else
00393 registrations = curr->next;
00394 free( curr );
00395 break;
00396 }
00397 }
00398 return count;
00399 }
00400
00401 EXPORT int iaxc_first_free_call()
00402 {
00403 int i;
00404 for ( i = 0; i < max_calls; i++ )
00405 if ( calls[i].state == IAXC_CALL_STATE_FREE )
00406 return i;
00407
00408 return -1;
00409 }
00410
00411
00412 static void iaxc_clear_call(int toDump)
00413 {
00414
00415 calls[toDump].state = IAXC_CALL_STATE_FREE;
00416 calls[toDump].format = 0;
00417 calls[toDump].vformat = 0;
00418 calls[toDump].session = NULL;
00419 iaxci_do_state_callback(toDump);
00420 }
00421
00422
00423
00424 EXPORT int iaxc_select_call(int callNo)
00425 {
00426
00427
00428
00429 if ( callNo >= max_calls )
00430 {
00431 iaxci_usermsg(IAXC_ERROR, "Error: tried to select out_of_range call %d", callNo);
00432 return -1;
00433 }
00434
00435
00436 if ( callNo < 0 )
00437 {
00438 if ( selected_call >= 0 )
00439 {
00440 calls[selected_call].state &= ~IAXC_CALL_STATE_SELECTED;
00441 }
00442 selected_call = callNo;
00443 return 0;
00444 }
00445
00446
00447 if ( callNo != selected_call )
00448 {
00449 if ( selected_call >= 0 )
00450 {
00451 calls[selected_call].state &= ~IAXC_CALL_STATE_SELECTED;
00452 iaxci_do_state_callback(selected_call);
00453 }
00454 selected_call = callNo;
00455 calls[selected_call].state |= IAXC_CALL_STATE_SELECTED;
00456 }
00457
00458
00459 if ( !(calls[selected_call].state & IAXC_CALL_STATE_OUTGOING) &&
00460 (calls[selected_call].state & IAXC_CALL_STATE_RINGING) )
00461 {
00462 iaxc_answer_call(selected_call);
00463 } else
00464 {
00465
00466 iaxci_do_state_callback(selected_call);
00467 }
00468
00469 return 0;
00470 }
00471
00472
00473 EXPORT int iaxc_selected_call()
00474 {
00475 return selected_call;
00476 }
00477
00478 EXPORT void iaxc_set_networking(iaxc_sendto_t st, iaxc_recvfrom_t rf)
00479 {
00480 iaxc_sendto = st;
00481 iaxc_recvfrom = rf;
00482 }
00483
00484 EXPORT void iaxc_set_jb_target_extra( long value )
00485 {
00486
00487 jb_target_extra = value;
00488 }
00489
00490 static void jb_errf(const char *fmt, ...)
00491 {
00492 va_list args;
00493 char buf[1024];
00494
00495 va_start(args, fmt);
00496 vsnprintf(buf, 1024, fmt, args);
00497 va_end(args);
00498
00499 iaxci_usermsg(IAXC_ERROR, buf);
00500 }
00501
00502 static void jb_warnf(const char *fmt, ...)
00503 {
00504 va_list args;
00505 char buf[1024];
00506
00507 va_start(args, fmt);
00508 vsnprintf(buf, 1024, fmt, args);
00509 va_end(args);
00510
00511 iaxci_usermsg(IAXC_NOTICE, buf);
00512 }
00513
00514 #ifdef JB_DEBUGGING
00515 static void jb_dbgf(const char *fmt, ...)
00516 {
00517 va_list args;
00518
00519 va_start(args, fmt);
00520 vfprintf(stderr, fmt, args);
00521 va_end(args);
00522 }
00523 #endif
00524
00525 static void setup_jb_output()
00526 {
00527 #ifdef JB_DEBUGGING
00528 jb_setoutput(jb_errf, jb_warnf, jb_dbgf);
00529 #else
00530 jb_setoutput(jb_errf, jb_warnf, NULL);
00531 #endif
00532 }
00533
00534
00535 EXPORT void iaxc_set_preferred_source_udp_port(int port)
00536 {
00537 source_udp_port = port;
00538 }
00539
00540
00541 EXPORT int iaxc_video_bypass_jitter(int mode)
00542 {
00543
00544
00545
00546
00547
00548
00549
00550
00551 return iax_video_bypass_jitter(calls[selected_call].session,mode);
00552 }
00553
00554 EXPORT short iaxc_get_bind_port()
00555 {
00556 return iaxci_bound_port;
00557 }
00558
00559 EXPORT int iaxc_initialize(int num_calls)
00560 {
00561 int i;
00562 int port;
00563
00564 os_init();
00565
00566 setup_jb_output();
00567
00568 MUTEXINIT(&iaxc_lock);
00569 MUTEXINIT(&event_queue_lock);
00570
00571 iaxc_set_audio_prefs(0);
00572
00573 if ( iaxc_recvfrom != (iaxc_recvfrom_t)recvfrom )
00574 iax_set_networking(iaxc_sendto, iaxc_recvfrom);
00575
00576
00577
00578
00579
00580
00581 if ( (port = iax_init(source_udp_port)) < 0 )
00582 {
00583 iaxci_usermsg(IAXC_ERROR,
00584 "Fatal error: failed to initialize iax with port %d",
00585 port);
00586 return -1;
00587 }
00588
00589 if ( iaxc_recvfrom == (iaxc_recvfrom_t)recvfrom )
00590 iaxci_bound_port = (short)port;
00591 else
00592 iaxci_bound_port = -1;
00593
00594
00595 iax_set_jb_target_extra( jb_target_extra );
00596
00597 max_calls = num_calls;
00598
00599 if ( max_calls <= 0 )
00600 max_calls = 1;
00601
00602
00603 calls = (struct iaxc_call *)calloc(sizeof(struct iaxc_call), max_calls);
00604 if ( !calls )
00605 {
00606 iaxci_usermsg(IAXC_ERROR, "Fatal error: can't allocate memory");
00607 return -1;
00608 }
00609
00610 selected_call = -1;
00611
00612 for ( i = 0; i < max_calls; i++ )
00613 {
00614 strncpy(calls[i].callerid_name, DEFAULT_CALLERID_NAME, IAXC_EVENT_BUFSIZ);
00615 strncpy(calls[i].callerid_number, DEFAULT_CALLERID_NUMBER, IAXC_EVENT_BUFSIZ);
00616 }
00617
00618 #ifndef AUDIO_ALSA
00619 if ( pa_initialize(&audio_driver, 8000) )
00620 {
00621 iaxci_usermsg(IAXC_ERROR, "failed pa_initialize");
00622 return -1;
00623 }
00624 #else
00625
00626
00627
00628
00629
00630
00631
00632 if ( alsa_initialize(&audio_driver, 8000) )
00633 return -1;
00634 #endif
00635
00636 audio_format_capability =
00637 IAXC_FORMAT_ULAW |
00638 IAXC_FORMAT_ALAW |
00639 #ifdef CODEC_GSM
00640 IAXC_FORMAT_GSM |
00641 #endif
00642 IAXC_FORMAT_SPEEX;
00643 audio_format_preferred = IAXC_FORMAT_SPEEX;
00644
00645 #ifdef USE_VIDEO
00646 if ( video_initialize() )
00647 {
00648 iaxci_usermsg(IAXC_ERROR,
00649 "iaxc_initialize: cannot initialize video!\n");
00650 }
00651 #endif
00652
00653 return 0;
00654 }
00655
00656 EXPORT void iaxc_shutdown()
00657 {
00658 iaxc_dump_all_calls();
00659
00660 get_iaxc_lock();
00661
00662 audio_driver.destroy(&audio_driver);
00663 #ifdef USE_VIDEO
00664 video_destroy();
00665 #endif
00666
00667 put_iaxc_lock();
00668 #ifdef WIN32
00669 closesocket(iax_get_fd());
00670 #endif
00671
00672 free(calls);
00673
00674 MUTEXDESTROY(&event_queue_lock);
00675 MUTEXDESTROY(&iaxc_lock);
00676 }
00677
00678
00679 EXPORT void iaxc_set_formats(int preferred, int allowed)
00680 {
00681 audio_format_capability = allowed;
00682 audio_format_preferred = preferred;
00683 }
00684
00685 EXPORT void iaxc_set_min_outgoing_framesize(int samples)
00686 {
00687 minimum_outgoing_framesize = samples;
00688 }
00689
00690 EXPORT void iaxc_set_callerid(const char * name, const char * number)
00691 {
00692 int i;
00693
00694 for ( i = 0; i < max_calls; i++ )
00695 {
00696 strncpy(calls[i].callerid_name, name, IAXC_EVENT_BUFSIZ);
00697 strncpy(calls[i].callerid_number, number, IAXC_EVENT_BUFSIZ);
00698 }
00699 }
00700
00701 static void iaxc_note_activity(int callNo)
00702 {
00703 if ( callNo < 0 )
00704 return;
00705 gettimeofday(&calls[callNo].last_activity, NULL);
00706 }
00707
00708 static void iaxc_refresh_registrations()
00709 {
00710 struct iaxc_registration *cur;
00711 struct timeval now;
00712
00713 gettimeofday(&now,NULL);
00714
00715 for ( cur = registrations; cur != NULL; cur = cur->next )
00716 {
00717
00718
00719 if ( iaxci_usecdiff(&now, &cur->last) > cur->refresh - 1 * 1000 *1000 )
00720 {
00721 if ( cur->session != NULL )
00722 {
00723 iax_destroy( cur->session );
00724 }
00725 cur->session = iax_session_new();
00726 if ( !cur->session )
00727 {
00728 iaxci_usermsg(IAXC_ERROR, "Can't make new registration session");
00729 return;
00730 }
00731 iax_register(cur->session, cur->host, cur->user, cur->pass, 60);
00732 cur->last = now;
00733 }
00734 }
00735 }
00736
00737 #define LOOP_SLEEP 5 // In ms
00738 static THREADFUNCDECL(main_proc_thread_func)
00739 {
00740 static int refresh_registration_count = 0;
00741
00742 THREADFUNCRET(ret);
00743
00744
00745 iaxci_prioboostbegin();
00746
00747 while ( !main_proc_thread_flag )
00748 {
00749 get_iaxc_lock();
00750
00751 service_network();
00752 service_audio();
00753
00754
00755 if ( refresh_registration_count++ > 1000/LOOP_SLEEP )
00756 {
00757 iaxc_refresh_registrations();
00758 refresh_registration_count = 0;
00759 }
00760
00761 put_iaxc_lock();
00762
00763 iaxc_millisleep(LOOP_SLEEP);
00764 }
00765
00766
00767 iaxci_prioboostend();
00768
00769 main_proc_thread_flag = -1;
00770
00771 return ret;
00772 }
00773
00774 #ifdef USE_VIDEO
00775 static THREADFUNCDECL(video_proc_thread_func)
00776 {
00777 struct iaxc_call *call;
00778
00779 while ( !video_proc_thread_flag )
00780 {
00781 if (selected_call >= 0)
00782 call = &calls[selected_call];
00783 else
00784 call = NULL;
00785
00786 video_send_video(call, selected_call);
00787 video_send_stats(call);
00788
00789
00790 iaxc_millisleep(LOOP_SLEEP);
00791 }
00792
00793 video_proc_thread_flag = -1;
00794
00795 return 0;
00796 }
00797 #endif
00798
00799 EXPORT int iaxc_start_processing_thread()
00800 {
00801 main_proc_thread_flag = 0;
00802
00803 if ( THREADCREATE(main_proc_thread_func, NULL, main_proc_thread,
00804 main_proc_thread_id) == THREADCREATE_ERROR)
00805 return -1;
00806
00807 #ifdef USE_VIDEO
00808 video_proc_thread_flag = 0;
00809
00810 if ( THREADCREATE(video_proc_thread_func, NULL, video_proc_thread,
00811 video_proc_thread_id) == THREADCREATE_ERROR)
00812 return -1;
00813 #endif
00814
00815 return 0;
00816 }
00817
00818 EXPORT int iaxc_stop_processing_thread()
00819 {
00820 if ( main_proc_thread_flag >= 0 )
00821 {
00822 main_proc_thread_flag = 1;
00823 THREADJOIN(main_proc_thread);
00824 }
00825
00826 #ifdef USE_VIDEO
00827 if ( video_proc_thread_flag >= 0 )
00828 {
00829 video_proc_thread_flag = 1;
00830 THREADJOIN(video_proc_thread);
00831 }
00832 #endif
00833
00834 return 0;
00835 }
00836
00837 static int service_audio()
00838 {
00839
00840 short buf [4096];
00841
00842 int want_send_audio =
00843 selected_call >= 0 &&
00844 ((calls[selected_call].state & IAXC_CALL_STATE_OUTGOING) ||
00845 (calls[selected_call].state & IAXC_CALL_STATE_COMPLETE))
00846 && !(audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE);
00847
00848 int want_local_audio =
00849 (audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_RAW) ||
00850 (audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED);
00851
00852 if ( want_local_audio || want_send_audio )
00853 {
00854 for ( ;; )
00855 {
00856 int to_read;
00857 int cmin;
00858
00859 audio_driver.start(&audio_driver);
00860
00861
00862 cmin = want_send_audio && calls[selected_call].encoder ?
00863 calls[selected_call].encoder->minimum_frame_size :
00864 1;
00865
00866 to_read = cmin > minimum_outgoing_framesize ?
00867 cmin : minimum_outgoing_framesize;
00868
00869
00870 if ( to_read % cmin )
00871 to_read += cmin - (to_read % cmin);
00872
00873 if ( to_read > (int)(sizeof(buf) / sizeof(short)) )
00874 {
00875 fprintf(stderr,
00876 "internal error: to_read > sizeof(buf)\n");
00877 exit(1);
00878 }
00879
00880
00881 if ( audio_driver.input(&audio_driver, buf, &to_read) )
00882 {
00883 iaxci_usermsg(IAXC_ERROR, "ERROR reading audio\n");
00884 break;
00885 }
00886
00887
00888 if ( !to_read )
00889 break;
00890
00891 if ( audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_RAW )
00892 iaxci_do_audio_callback(selected_call, 0,
00893 IAXC_SOURCE_LOCAL, 0, 0,
00894 to_read * 2, (unsigned char *)buf);
00895
00896 if ( want_send_audio )
00897 audio_send_encoded_audio(&calls[selected_call],
00898 selected_call, buf,
00899 calls[selected_call].format &
00900 IAXC_AUDIO_FORMAT_MASK,
00901 to_read);
00902 }
00903 }
00904 else
00905 {
00906 static int i = 0;
00907
00908 audio_driver.stop(&audio_driver);
00909
00921 if ( i++ % 50 == 0 )
00922 iaxci_do_levels_callback(-99,-99);
00923 }
00924
00925 return 0;
00926 }
00927
00928
00929 static void handle_text_event(struct iax_event *e, int callNo)
00930 {
00931 iaxc_event ev;
00932 int len;
00933
00934 if ( callNo < 0 )
00935 return;
00936
00937 memset(&ev, 0, sizeof(iaxc_event));
00938 ev.type = IAXC_EVENT_TEXT;
00939 ev.ev.text.type = IAXC_TEXT_TYPE_IAX;
00940 ev.ev.text.callNo = callNo;
00941
00942 len = e->datalen <= IAXC_EVENT_BUFSIZ - 1 ? e->datalen : IAXC_EVENT_BUFSIZ - 1;
00943 strncpy(ev.ev.text.message, (char *) e->data, len);
00944 iaxci_post_event(ev);
00945 }
00946
00947
00948 void handle_url_event( struct iax_event *e, int callNo )
00949 {
00950 iaxc_event ev;
00951
00952 if ( callNo < 0 )
00953 return;
00954
00955 ev.ev.url.callNo = callNo;
00956 ev.type = IAXC_EVENT_URL;
00957 strcpy( ev.ev.url.url, "" );
00958
00959 switch ( e->subclass )
00960 {
00961 case AST_HTML_URL:
00962 ev.ev.url.type = IAXC_URL_URL;
00963 if ( e->datalen )
00964 {
00965 if ( e->datalen > IAXC_EVENT_BUFSIZ )
00966 {
00967 fprintf( stderr, "ERROR: URL too long %d > %d\n",
00968 e->datalen, IAXC_EVENT_BUFSIZ );
00969 } else
00970 {
00971 strncpy( ev.ev.url.url, (char *) e->data, e->datalen );
00972 }
00973 }
00974
00975 break;
00976 case AST_HTML_LINKURL:
00977 ev.ev.url.type = IAXC_URL_LINKURL;
00978
00979 break;
00980 case AST_HTML_LDCOMPLETE:
00981 ev.ev.url.type = IAXC_URL_LDCOMPLETE;
00982
00983 break;
00984 case AST_HTML_UNLINK:
00985 ev.ev.url.type = IAXC_URL_UNLINK;
00986
00987 break;
00988 case AST_HTML_LINKREJECT:
00989 ev.ev.url.type = IAXC_URL_LINKREJECT;
00990
00991 break;
00992 default:
00993 fprintf( stderr, "Unknown URL event %d\n", e->subclass );
00994 break;
00995 }
00996 iaxci_post_event( ev );
00997 }
00998
00999
01000 EXPORT int iaxc_get_netstats(int call, int *rtt, struct iaxc_netstat *local,
01001 struct iaxc_netstat *remote)
01002 {
01003 return iax_get_netstats(calls[call].session, rtt,
01004 (struct iax_netstat *)local,
01005 (struct iax_netstat *)remote);
01006 }
01007
01008
01009 static void generate_netstat_event(int callNo)
01010 {
01011 iaxc_event ev;
01012
01013 if ( callNo < 0 )
01014 return;
01015
01016 ev.type = IAXC_EVENT_NETSTAT;
01017 ev.ev.netstats.callNo = callNo;
01018
01019
01020 if ( !iaxc_get_netstats(callNo, &ev.ev.netstats.rtt,
01021 &ev.ev.netstats.local, &ev.ev.netstats.remote))
01022 iaxci_post_event(ev);
01023 }
01024
01025 static void handle_audio_event(struct iax_event *e, int callNo)
01026 {
01027 int total_consumed = 0;
01028 short fr[4096];
01029 const int fr_samples = sizeof(fr) / sizeof(short);
01030 int samples, format;
01031 #ifdef WIN32
01032 int cycles_max = 100;
01033 #endif
01034 struct iaxc_call *call;
01035
01036 if ( callNo < 0 )
01037 return;
01038
01039 call = &calls[callNo];
01040
01041 if ( callNo != selected_call )
01042 {
01043
01044 return;
01045 }
01046
01047 samples = fr_samples;
01048 format = call->format & IAXC_AUDIO_FORMAT_MASK;
01049
01050 do
01051 {
01052 int bytes_decoded;
01053
01054 int mainbuf_delta = fr_samples - samples;
01055
01056 bytes_decoded = audio_decode_audio(call,
01057 fr,
01058 e->data + total_consumed,
01059 e->datalen - total_consumed,
01060 format,
01061 &samples);
01062
01063 if ( bytes_decoded < 0 )
01064 {
01065 iaxci_usermsg(IAXC_STATUS,
01066 "Bad or incomplete voice packet. Unable to decode. dropping");
01067 return;
01068 }
01069
01070
01071 if ( audio_prefs & IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED )
01072 iaxci_do_audio_callback(callNo, e->ts, IAXC_SOURCE_REMOTE,
01073 1, format & IAXC_AUDIO_FORMAT_MASK,
01074 e->datalen - total_consumed,
01075 e->data + total_consumed);
01076
01077 #ifdef WIN32
01078
01079 cycles_max--;
01080 if (cycles_max<0)
01081 {
01082 iaxc_millisleep(0);
01083 }
01084
01085 #endif
01086 total_consumed += bytes_decoded;
01087 if ( audio_prefs & IAXC_AUDIO_PREF_RECV_REMOTE_RAW )
01088 {
01089
01090
01091
01092
01093 int size = (fr_samples - samples - mainbuf_delta) * 2;
01094 iaxci_do_audio_callback(callNo, e->ts, IAXC_SOURCE_REMOTE,
01095 0, 0, size, (unsigned char *)fr);
01096 }
01097
01098 if ( iaxci_audio_output_mode )
01099 continue;
01100
01101 audio_driver.output(&audio_driver, fr,
01102 fr_samples - samples - mainbuf_delta);
01103 } while ( total_consumed < e->datalen );
01104 }
01105
01106 #ifdef USE_VIDEO
01107 static void handle_video_event(struct iax_event *e, int callNo)
01108 {
01109 struct iaxc_call *call;
01110
01111 if ( callNo < 0 )
01112 return;
01113
01114 if ( e->datalen == 0 )
01115 {
01116 iaxci_usermsg(IAXC_STATUS, "Received 0-size packet. Unable to decode.");
01117 return;
01118 }
01119
01120 call = &calls[callNo];
01121
01122 if ( callNo != selected_call )
01123 {
01124
01125 return;
01126 }
01127
01128 if ( call->vformat )
01129 {
01130 if ( video_recv_video(call, selected_call, e->data,
01131 e->datalen, e->ts, call->vformat) < 0 )
01132 {
01133 iaxci_usermsg(IAXC_STATUS,
01134 "Bad or incomplete video packet. Unable to decode.");
01135 return;
01136 }
01137 }
01138 }
01139 #endif
01140
01141 static void iaxc_handle_network_event(struct iax_event *e, int callNo)
01142 {
01143 if ( callNo < 0 )
01144 return;
01145
01146 iaxc_note_activity(callNo);
01147
01148 switch ( e->etype )
01149 {
01150 case IAX_EVENT_NULL:
01151 break;
01152 case IAX_EVENT_HANGUP:
01153 iaxci_usermsg(IAXC_STATUS, "Call disconnected by remote");
01154
01155 iaxc_clear_call(callNo);
01156 break;
01157 case IAX_EVENT_REJECT:
01158 iaxci_usermsg(IAXC_STATUS, "Call rejected by remote");
01159 iaxc_clear_call(callNo);
01160 break;
01161 case IAX_EVENT_ACCEPT:
01162 calls[callNo].format = e->ies.format & IAXC_AUDIO_FORMAT_MASK;
01163 calls[callNo].vformat = e->ies.format & IAXC_VIDEO_FORMAT_MASK;
01164 if ( !(e->ies.format & IAXC_VIDEO_FORMAT_MASK) )
01165 {
01166 iaxci_usermsg(IAXC_NOTICE,
01167 "Failed video codec negotiation.");
01168 }
01169 iaxci_usermsg(IAXC_STATUS,"Call %d accepted", callNo);
01170 break;
01171 case IAX_EVENT_ANSWER:
01172 calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
01173 calls[callNo].state |= IAXC_CALL_STATE_COMPLETE;
01174 iaxci_do_state_callback(callNo);
01175 iaxci_usermsg(IAXC_STATUS,"Call %d answered", callNo);
01176
01177
01178 break;
01179 case IAX_EVENT_BUSY:
01180 calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
01181 calls[callNo].state |= IAXC_CALL_STATE_BUSY;
01182 iaxci_do_state_callback(callNo);
01183 iaxci_usermsg(IAXC_STATUS, "Call %d busy", callNo);
01184 break;
01185 case IAX_EVENT_VOICE:
01186 handle_audio_event(e, callNo);
01187 if ((calls[callNo].state & IAXC_CALL_STATE_OUTGOING) &&
01188 (calls[callNo].state & IAXC_CALL_STATE_RINGING) )
01189 {
01190 calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
01191 iaxci_do_state_callback(callNo);
01192 iaxci_usermsg(IAXC_STATUS,"Call %d progress",
01193 callNo);
01194 }
01195 break;
01196 #ifdef USE_VIDEO
01197 case IAX_EVENT_VIDEO:
01198
01199
01200
01201 handle_video_event(e, callNo);
01202
01203 break;
01204 #endif
01205 case IAX_EVENT_TEXT:
01206 handle_text_event(e, callNo);
01207 break;
01208 case IAX_EVENT_RINGA:
01209 calls[callNo].state |= IAXC_CALL_STATE_RINGING;
01210 iaxci_do_state_callback(callNo);
01211 iaxci_usermsg(IAXC_STATUS,"Call %d ringing", callNo);
01212 break;
01213 case IAX_EVENT_PONG:
01214 generate_netstat_event(callNo);
01215 break;
01216 case IAX_EVENT_URL:
01217 handle_url_event(e, callNo);
01218 break;
01219 case IAX_EVENT_CNG:
01220
01221 break;
01222 case IAX_EVENT_TIMEOUT:
01223 iax_hangup(e->session, "Call timed out");
01224 iaxci_usermsg(IAXC_STATUS, "Call %d timed out.", callNo);
01225 iaxc_clear_call(callNo);
01226 break;
01227 case IAX_EVENT_TRANSFER:
01228 calls[callNo].state |= IAXC_CALL_STATE_TRANSFER;
01229 iaxci_do_state_callback(callNo);
01230 iaxci_usermsg(IAXC_STATUS,"Call %d transfer released", callNo);
01231 break;
01232 default:
01233 iaxci_usermsg(IAXC_STATUS, "Unknown event: %d for call %d", e->etype, callNo);
01234 break;
01235 }
01236 }
01237
01238 EXPORT int iaxc_unregister( int id )
01239 {
01240 int count = 0;
01241 get_iaxc_lock();
01242 count = iaxc_remove_registration_by_id(id);
01243 put_iaxc_lock();
01244 return count;
01245 }
01246
01247 EXPORT int iaxc_register(const char * user, const char * pass, const char * host)
01248 {
01249 struct iaxc_registration *newreg;
01250
01251 newreg = (struct iaxc_registration *)malloc(sizeof (struct iaxc_registration));
01252 if ( !newreg )
01253 {
01254 iaxci_usermsg(IAXC_ERROR, "Can't make new registration");
01255 return -1;
01256 }
01257
01258 get_iaxc_lock();
01259 newreg->session = iax_session_new();
01260 if ( !newreg->session )
01261 {
01262 iaxci_usermsg(IAXC_ERROR, "Can't make new registration session");
01263 put_iaxc_lock();
01264 return -1;
01265 }
01266
01267 gettimeofday(&newreg->last,NULL);
01268 newreg->refresh = 60*1000*1000;
01269
01270 strncpy(newreg->host, host, 256);
01271 strncpy(newreg->user, user, 256);
01272 strncpy(newreg->pass, pass, 256);
01273
01274
01275 iax_register(newreg->session, host, user, pass, 300);
01276
01277
01278 newreg->id = ++next_registration_id;
01279 newreg->next = registrations;
01280 registrations = newreg;
01281
01282 put_iaxc_lock();
01283 return newreg->id;
01284 }
01285
01286 static void codec_destroy( int callNo )
01287 {
01288 if ( calls[callNo].encoder )
01289 {
01290 calls[callNo].encoder->destroy( calls[callNo].encoder );
01291 calls[callNo].encoder = NULL;
01292 }
01293 if ( calls[callNo].decoder )
01294 {
01295 calls[callNo].decoder->destroy( calls[callNo].decoder );
01296 calls[callNo].decoder = NULL;
01297 }
01298 if ( calls[callNo].vdecoder )
01299 {
01300 calls[callNo].vdecoder->destroy(calls[callNo].vdecoder);
01301 calls[callNo].vdecoder = NULL;
01302 }
01303 if ( calls[callNo].vencoder )
01304 {
01305 calls[callNo].vencoder->destroy(calls[callNo].vencoder);
01306 calls[callNo].vencoder = NULL;
01307 }
01308 }
01309
01310 EXPORT int iaxc_call(const char * num)
01311 {
01312 return iaxc_call_ex(num, NULL, NULL, 1);
01313 }
01314
01315 EXPORT int iaxc_call_ex(const char *num, const char* callerid_name, const char* callerid_number, int video)
01316 {
01317 int video_format_capability = 0;
01318 int video_format_preferred = 0;
01319 int callNo = -1;
01320 struct iax_session *newsession;
01321 char *ext = strstr(num, "/");
01322
01323 get_iaxc_lock();
01324
01325
01326 if (selected_call < 0)
01327 {
01328 callNo = iaxc_first_free_call();
01329 } else
01330 {
01331
01332 if (calls[selected_call].state & IAXC_CALL_STATE_ACTIVE)
01333 {
01334 callNo = iaxc_first_free_call();
01335 } else
01336 {
01337 callNo = selected_call;
01338 }
01339 }
01340
01341 if (callNo < 0)
01342 {
01343 iaxci_usermsg(IAXC_STATUS, "No free call appearances");
01344 goto iaxc_call_bail;
01345 }
01346
01347 newsession = iax_session_new();
01348 if (!newsession)
01349 {
01350 iaxci_usermsg(IAXC_ERROR, "Can't make new session");
01351 goto iaxc_call_bail;
01352 }
01353
01354 calls[callNo].session = newsession;
01355
01356 codec_destroy( callNo );
01357
01358 if (ext)
01359 {
01360 strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
01361 strncpy(calls[callNo].remote, ++ext, IAXC_EVENT_BUFSIZ);
01362 } else
01363 {
01364 strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
01365 strncpy(calls[callNo].remote, "" , IAXC_EVENT_BUFSIZ);
01366 }
01367
01368 if (callerid_number != NULL)
01369 strncpy(calls[callNo].callerid_number, callerid_number, IAXC_EVENT_BUFSIZ);
01370
01371 if (callerid_name != NULL)
01372 strncpy(calls[callNo].callerid_name, callerid_name, IAXC_EVENT_BUFSIZ);
01373
01374 strncpy(calls[callNo].local , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ);
01375 strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ);
01376
01377 calls[callNo].state = IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_OUTGOING;
01378
01379
01380 iaxc_note_activity(callNo);
01381 calls[callNo].last_ping = calls[callNo].last_activity;
01382
01383 #ifdef USE_VIDEO
01384 if (video)
01385 iaxc_video_format_get_cap(&video_format_preferred, &video_format_capability);
01386 #endif
01387
01388 iaxci_usermsg(IAXC_NOTICE, "Originating an %s call",
01389 video_format_preferred ? "audio+video" : "audio only");
01390 iax_call(calls[callNo].session, calls[callNo].callerid_number,
01391 calls[callNo].callerid_name, num, NULL, 0,
01392 audio_format_preferred | video_format_preferred,
01393 audio_format_capability | video_format_capability);
01394
01395
01396 iaxc_select_call(callNo);
01397
01398 iaxc_call_bail:
01399 put_iaxc_lock();
01400
01401 return callNo;
01402 }
01403
01404 EXPORT void iaxc_send_busy_on_incoming_call(int callNo)
01405 {
01406 if ( callNo < 0 )
01407 return;
01408
01409 iax_busy(calls[callNo].session);
01410 }
01411
01412 EXPORT void iaxc_answer_call(int callNo)
01413 {
01414 if (callNo < 0) return;
01415
01416 calls[callNo].state |= IAXC_CALL_STATE_COMPLETE;
01417 calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
01418 iax_answer(calls[callNo].session);
01419 iaxci_do_state_callback(callNo);
01420 }
01421
01422 EXPORT void iaxc_blind_transfer_call(int callNo, const char * dest_extension)
01423 {
01424 if ((callNo < 0) ||
01425 !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE))
01426 return;
01427
01428 iax_transfer(calls[callNo].session, dest_extension);
01429 }
01430
01431 EXPORT void iaxc_setup_call_transfer(int sourceCallNo, int targetCallNo)
01432 {
01433 if ((sourceCallNo < 0) || (targetCallNo < 0) ||
01434 ((calls[sourceCallNo].state & IAXC_CALL_STATE_ACTIVE) == 0) ||
01435 ((calls[targetCallNo].state & IAXC_CALL_STATE_ACTIVE) == 0))
01436 return;
01437
01438 iax_setup_transfer(calls[sourceCallNo].session, calls[targetCallNo].session);
01439 }
01440
01441 static void iaxc_dump_one_call(int callNo)
01442 {
01443 if (callNo < 0)
01444 return;
01445 if (calls[callNo].state == IAXC_CALL_STATE_FREE)
01446 return;
01447
01448 iax_hangup(calls[callNo].session,"Dumped Call");
01449 iaxci_usermsg(IAXC_STATUS, "Hanging up call %d", callNo);
01450 iaxc_clear_call(callNo);
01451 }
01452
01453 EXPORT void iaxc_dump_all_calls(void)
01454 {
01455 int callNo;
01456 get_iaxc_lock();
01457 for ( callNo = 0; callNo < max_calls; callNo++ )
01458 iaxc_dump_one_call(callNo);
01459 put_iaxc_lock();
01460 }
01461
01462
01463 EXPORT void iaxc_dump_call(void)
01464 {
01465 if (selected_call >= 0)
01466 {
01467 get_iaxc_lock();
01468 iaxc_dump_one_call(selected_call);
01469 put_iaxc_lock();
01470 }
01471 }
01472
01473 EXPORT void iaxc_reject_call(void)
01474 {
01475 if (selected_call >= 0)
01476 {
01477 iaxc_reject_call_number(selected_call);
01478 }
01479 }
01480
01481 EXPORT void iaxc_reject_call_number( int callNo )
01482 {
01483 if (callNo >= 0)
01484 {
01485 get_iaxc_lock();
01486 iax_reject(calls[callNo].session, "Call rejected manually.");
01487 iaxc_clear_call(callNo);
01488 put_iaxc_lock();
01489 }
01490 }
01491
01492 EXPORT void iaxc_send_dtmf(char digit)
01493 {
01494 if (selected_call >= 0)
01495 {
01496 get_iaxc_lock();
01497 if (calls[selected_call].state & IAXC_CALL_STATE_ACTIVE)
01498 iax_send_dtmf(calls[selected_call].session,digit);
01499 put_iaxc_lock();
01500 }
01501 }
01502
01503 EXPORT void iaxc_send_text(const char * text)
01504 {
01505 if (selected_call >= 0)
01506 {
01507 get_iaxc_lock();
01508 if (calls[selected_call].state & IAXC_CALL_STATE_ACTIVE)
01509 iax_send_text(calls[selected_call].session, text);
01510 put_iaxc_lock();
01511 }
01512 }
01513
01514 EXPORT void iaxc_send_url(const char * url, int link)
01515 {
01516 if (selected_call >= 0)
01517 {
01518 get_iaxc_lock();
01519 if (calls[selected_call].state & IAXC_CALL_STATE_ACTIVE)
01520 iax_send_url(calls[selected_call].session, url, link);
01521 put_iaxc_lock();
01522 }
01523 }
01524
01525 static int iaxc_find_call_by_session(struct iax_session *session)
01526 {
01527 int i;
01528 for ( i = 0; i < max_calls; i++ )
01529 if (calls[i].session == session)
01530 return i;
01531 return -1;
01532 }
01533
01534 static struct iaxc_registration *iaxc_find_registration_by_session(
01535 struct iax_session *session)
01536 {
01537 struct iaxc_registration *reg;
01538 for (reg = registrations; reg != NULL; reg = reg->next)
01539 if (reg->session == session) break;
01540 return reg;
01541 }
01542
01543 static void iaxc_handle_regreply(struct iax_event *e, struct iaxc_registration *reg)
01544 {
01545 iaxci_do_registration_callback(reg->id, e->etype, e->ies.msgcount);
01546
01547
01548
01549
01550 iax_destroy(reg->session);
01551 reg->session = NULL;
01552
01553 if (e->etype == IAX_EVENT_REGREJ)
01554 {
01555
01556 iaxc_remove_registration_by_id(reg->id);
01557 }
01558 }
01559
01560
01561 static int iaxc_choose_codec(int formats)
01562 {
01563 int i;
01564 static int codecs[] =
01565 {
01566 IAXC_FORMAT_ULAW,
01567 IAXC_FORMAT_ALAW,
01568 IAXC_FORMAT_SLINEAR,
01569 IAXC_FORMAT_G726,
01570 IAXC_FORMAT_ADPCM,
01571 IAXC_FORMAT_GSM,
01572 IAXC_FORMAT_ILBC,
01573 IAXC_FORMAT_SPEEX,
01574 IAXC_FORMAT_LPC10,
01575 IAXC_FORMAT_G729A,
01576 IAXC_FORMAT_G723_1,
01577
01578
01579 IAXC_FORMAT_JPEG,
01580 IAXC_FORMAT_PNG,
01581 IAXC_FORMAT_H261,
01582 IAXC_FORMAT_H263,
01583 IAXC_FORMAT_H263_PLUS,
01584 IAXC_FORMAT_MPEG4,
01585 IAXC_FORMAT_H264,
01586 IAXC_FORMAT_THEORA,
01587 };
01588 for ( i = 0; i < (int)(sizeof(codecs) / sizeof(int)); i++ )
01589 if ( codecs[i] & formats )
01590 return codecs[i];
01591 return 0;
01592 }
01593
01594 static void iaxc_handle_connect(struct iax_event * e)
01595 {
01596 #ifdef USE_VIDEO
01597 int video_format_capability;
01598 int video_format_preferred;
01599 #endif
01600 int video_format = 0;
01601 int format = 0;
01602 int callno;
01603
01604 callno = iaxc_first_free_call();
01605
01606 if ( callno < 0 )
01607 {
01608 iaxci_usermsg(IAXC_STATUS,
01609 "%i \n Incoming Call, but no appearances",
01610 callno);
01611
01612
01613 iax_accept(e->session, audio_format_preferred & e->ies.capability);
01614 iax_busy(e->session);
01615 return;
01616 }
01617
01618
01619
01620 format = audio_format_capability & e->ies.format;
01621 if ( !format )
01622 {
01623
01624 format = audio_format_preferred & e->ies.capability;
01625 }
01626
01627 if ( !format )
01628 {
01629
01630 format = audio_format_capability & e->ies.capability;
01631
01632
01633 if ( format )
01634 {
01635 format = iaxc_choose_codec(format);
01636 }
01637 }
01638
01639 if ( !format )
01640 {
01641 iax_reject(e->session, "Could not negotiate common codec");
01642 return;
01643 }
01644
01645 #ifdef USE_VIDEO
01646 iaxc_video_format_get_cap(&video_format_preferred,
01647 &video_format_capability);
01648
01649
01650 video_format = (e->ies.format & IAXC_VIDEO_FORMAT_MASK);
01651
01652 if (video_format)
01653 {
01654
01655 video_format &= video_format_capability;
01656
01657 if ( !video_format )
01658 {
01659
01660 video_format = video_format_preferred &
01661 (e->ies.capability & IAXC_VIDEO_FORMAT_MASK);
01662 }
01663
01664 if ( !video_format )
01665 {
01666
01667 video_format = video_format_capability &
01668 (e->ies.capability & IAXC_VIDEO_FORMAT_MASK);
01669
01670
01671 if ( video_format )
01672 {
01673 video_format = iaxc_choose_codec(video_format);
01674 }
01675 }
01676
01677
01678 if ( !video_format )
01679 {
01680 iaxci_usermsg(IAXC_NOTICE,
01681 "Notice: could not negotiate common video codec");
01682 iaxci_usermsg(IAXC_NOTICE,
01683 "Notice: switching to audio-only call");
01684 }
01685 }
01686 #endif
01687
01688 calls[callno].vformat = video_format;
01689 calls[callno].format = format;
01690
01691 if ( e->ies.called_number )
01692 strncpy(calls[callno].local, e->ies.called_number,
01693 IAXC_EVENT_BUFSIZ);
01694 else
01695 strncpy(calls[callno].local, "unknown",
01696 IAXC_EVENT_BUFSIZ);
01697
01698 if ( e->ies.called_context )
01699 strncpy(calls[callno].local_context, e->ies.called_context,
01700 IAXC_EVENT_BUFSIZ);
01701 else
01702 strncpy(calls[callno].local_context, "",
01703 IAXC_EVENT_BUFSIZ);
01704
01705 if ( e->ies.calling_number )
01706 strncpy(calls[callno].remote, e->ies.calling_number,
01707 IAXC_EVENT_BUFSIZ);
01708 else
01709 strncpy(calls[callno].remote, "unknown",
01710 IAXC_EVENT_BUFSIZ);
01711
01712 if ( e->ies.calling_name )
01713 strncpy(calls[callno].remote_name, e->ies.calling_name,
01714 IAXC_EVENT_BUFSIZ);
01715 else
01716 strncpy(calls[callno].remote_name, "unknown",
01717 IAXC_EVENT_BUFSIZ);
01718
01719 iaxc_note_activity(callno);
01720 iaxci_usermsg(IAXC_STATUS, "Call from (%s)", calls[callno].remote);
01721
01722 codec_destroy( callno );
01723
01724 calls[callno].session = e->session;
01725 calls[callno].state = IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING;
01726
01727 iax_accept(calls[callno].session, format | video_format);
01728 iax_ring_announce(calls[callno].session);
01729
01730 iaxci_do_state_callback(callno);
01731
01732 iaxci_usermsg(IAXC_STATUS, "Incoming call on line %d", callno);
01733 }
01734
01735 static void service_network()
01736 {
01737 struct iax_event *e = 0;
01738 int callNo;
01739 struct iaxc_registration *reg;
01740
01741 while ( (e = iax_get_event(0)) )
01742 {
01743 #ifdef WIN32
01744 iaxc_millisleep(0);
01745 #endif
01746
01747 callNo = iaxc_find_call_by_session(e->session);
01748 if (callNo >= 0)
01749 {
01750 iaxc_handle_network_event(e, callNo);
01751 } else if ((reg = iaxc_find_registration_by_session(e->session)) != NULL)
01752 {
01753 iaxc_handle_regreply(e,reg);
01754 } else if ((e->etype == IAX_EVENT_REGACK) || (e->etype == IAX_EVENT_REGREJ))
01755 {
01756 iaxci_usermsg(IAXC_ERROR, "Unexpected registration reply");
01757 } else if (e->etype == IAX_EVENT_REGREQ)
01758 {
01759 iaxci_usermsg(IAXC_ERROR,
01760 "Registration requested by someone, but we don't understand!");
01761 } else if (e->etype == IAX_EVENT_CONNECT)
01762 {
01763 iaxc_handle_connect(e);
01764 } else if (e->etype == IAX_EVENT_TIMEOUT)
01765 {
01766 iaxci_usermsg(IAXC_STATUS,
01767 "Timeout for a non-existant session. Dropping",
01768 e->etype);
01769 } else if ( e->etype == IAX_EVENT_NULL )
01770 {
01771
01772
01773
01774 } else
01775 {
01776 iaxci_usermsg(IAXC_STATUS,
01777 "Event (type %d) for a non-existant session. Dropping",
01778 e->etype);
01779 }
01780 iax_event_free(e);
01781 }
01782 }
01783
01784 EXPORT int iaxc_audio_devices_get(struct iaxc_audio_device **devs, int *nDevs,
01785 int *input, int *output, int *ring)
01786 {
01787 *devs = audio_driver.devices;
01788 *nDevs = audio_driver.nDevices;
01789 audio_driver.selected_devices(&audio_driver, input, output, ring);
01790 return 0;
01791 }
01792
01793 EXPORT int iaxc_audio_devices_set(int input, int output, int ring)
01794 {
01795 int ret = 0;
01796 get_iaxc_lock();
01797 ret = audio_driver.select_devices(&audio_driver, input, output, ring);
01798 put_iaxc_lock();
01799 return ret;
01800 }
01801
01802 EXPORT float iaxc_input_level_get()
01803 {
01804 return audio_driver.input_level_get(&audio_driver);
01805 }
01806
01807 EXPORT float iaxc_output_level_get()
01808 {
01809 return audio_driver.output_level_get(&audio_driver);
01810 }
01811
01812 EXPORT int iaxc_input_level_set(float level)
01813 {
01814 return audio_driver.input_level_set(&audio_driver, level);
01815 }
01816
01817 EXPORT int iaxc_output_level_set(float level)
01818 {
01819 return audio_driver.output_level_set(&audio_driver, level);
01820 }
01821
01822 EXPORT int iaxc_play_sound(struct iaxc_sound *s, int ring)
01823 {
01824 int ret = 0;
01825 get_iaxc_lock();
01826 ret = audio_driver.play_sound(s,ring);
01827 put_iaxc_lock();
01828 return ret;
01829 }
01830
01831 EXPORT int iaxc_stop_sound(int id)
01832 {
01833 int ret = 0;
01834 get_iaxc_lock();
01835 ret = audio_driver.stop_sound(id);
01836 put_iaxc_lock();
01837 return ret;
01838 }
01839
01840 EXPORT int iaxc_quelch(int callNo, int MOH)
01841 {
01842 struct iax_session *session = calls[callNo].session;
01843 if (!session)
01844 return -1;
01845
01846 return iax_quelch_moh(session, MOH);
01847 }
01848
01849 EXPORT int iaxc_unquelch(int call)
01850 {
01851 return iax_unquelch(calls[call].session);
01852 }
01853
01854 EXPORT int iaxc_mic_boost_get( void )
01855 {
01856 return audio_driver.mic_boost_get( &audio_driver ) ;
01857 }
01858
01859 EXPORT int iaxc_mic_boost_set( int enable )
01860 {
01861 return audio_driver.mic_boost_set( &audio_driver, enable ) ;
01862 }
01863
01864 #ifdef LIBVER
01865
01866 EXPORT char* iaxc_version(char * ver)
01867 {
01868 strncpy(ver, LIBVER, IAXC_EVENT_BUFSIZ);
01869 return ver;
01870 }
01871
01872 #endif
01873
01874 EXPORT unsigned int iaxc_get_audio_prefs(void)
01875 {
01876 return audio_prefs;
01877 }
01878
01879 EXPORT int iaxc_set_audio_prefs(unsigned int prefs)
01880 {
01881 unsigned int prefs_mask =
01882 IAXC_AUDIO_PREF_RECV_LOCAL_RAW |
01883 IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED |
01884 IAXC_AUDIO_PREF_RECV_REMOTE_RAW |
01885 IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED |
01886 IAXC_AUDIO_PREF_SEND_DISABLE;
01887
01888 if ( prefs & ~prefs_mask )
01889 return -1;
01890
01891 audio_prefs = prefs;
01892 return 0;
01893 }