void linphone_gtk_create_in_call_view(LinphoneCall *call){ GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame"); GtkWidget *main_window=linphone_gtk_get_main_window (); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); static int call_index=1; int idx; if (ms_list_size(linphone_core_get_calls(linphone_gtk_get_core()))==1){ /*this is the only call at this time */ call_index=1; } g_object_set_data(G_OBJECT(call_view),"call",call); g_object_set_data(G_OBJECT(call_view),"call_index",GINT_TO_POINTER(call_index)); linphone_call_set_user_pointer (call,call_view); linphone_call_ref(call); gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index)); gtk_widget_show(call_view); idx = gtk_notebook_page_num(notebook, call_view); gtk_notebook_set_current_page(notebook, idx); call_index++; linphone_gtk_enable_hold_button (call,FALSE,TRUE); linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE); }
void linphone_gtk_set_in_conference(LinphoneCall *call){ GtkWidget *mw=linphone_gtk_get_main_window(); GtkWidget *participant=find_conferencee_from_call(call); if (participant==NULL){ GtkWidget *tab=get_conference_tab(mw); const LinphoneAddress *addr=linphone_call_get_remote_address(call); participant=linphone_gtk_create_widget("main","callee_frame"); GtkWidget *sound_meter; GtkWidget *viewswitch=linphone_gtk_get_widget(mw,"viewswitch"); gchar *markup; if (linphone_address_get_display_name(addr)!=NULL){ markup=g_strdup_printf("<b>%s</b>",linphone_address_get_display_name(addr)); }else{ char *tmp=linphone_address_as_string_uri_only(addr); markup=g_strdup_printf("%s",tmp); ms_free(tmp); } gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(participant,"callee_name_label")),markup); g_free(markup); sound_meter=linphone_gtk_get_widget(participant,"sound_indicator"); linphone_gtk_init_audio_meter(sound_meter, (get_volume_t) linphone_call_get_play_volume, call); gtk_box_pack_start(GTK_BOX(tab),participant,FALSE,FALSE,PADDING_PIXELS); g_object_set_data_full(G_OBJECT(participant),"call",linphone_call_ref(call),(GDestroyNotify)linphone_call_unref); gtk_widget_show(participant); gtk_notebook_set_current_page(GTK_NOTEBOOK(viewswitch), gtk_notebook_page_num(GTK_NOTEBOOK(viewswitch),tab)); } }
static void quality_reporting_not_sent_if_call_not_started() { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); LinphoneCallLog* out_call_log; LinphoneCall* out_call; linphone_core_set_max_calls(pauline->lc,0); out_call = linphone_core_invite(marie->lc,"pauline"); linphone_call_ref(out_call); CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1); if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data); CU_ASSERT_PTR_NOT_NULL(out_call_log); CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted); } linphone_call_unref(out_call); // wait a few time... wait_for_until(marie->lc,NULL,NULL,0,1000); // since the callee was busy, there should be no publish to do CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }
static void call_failed_because_of_codecs(void) { int begin,leaked_objects; belle_sip_object_enable_leak_detector(TRUE); begin=belle_sip_object_get_object_count(); { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); LinphoneCall* out_call; disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1); disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1); out_call = linphone_core_invite_address(pauline->lc,marie->identity); linphone_call_ref(out_call); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1)); /*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/ CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000)); CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0); linphone_call_unref(out_call); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } leaked_objects=belle_sip_object_get_object_count()-begin; CU_ASSERT_TRUE(leaked_objects==0); if (leaked_objects>0){ belle_sip_object_dump_active_objects(); } }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneCall *call=NULL; const char *dest=NULL; /* take the destination sip uri from the command line arguments */ if (argc>1){ dest=argv[1]; } signal(SIGINT,stop); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Fill the LinphoneCoreVTable with application callbacks. All are optional. Here we only use the call_state_changed callbacks in order to get notifications about the progress of the call. */ vtable.call_state_changed=call_state_changed; /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); if (dest){ /* Place an outgoing call */ call=linphone_core_invite(lc,dest); if (call==NULL){ printf("Could not place call to %s\n",dest); goto end; }else printf("Call to %s is in progress...",dest); linphone_call_ref(call); } /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ linphone_core_iterate(lc); ms_usleep(50000); } if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ /* terminate the call */ printf("Terminating the call...\n"); linphone_core_terminate_call(lc,call); /*at this stage we don't need the call object */ linphone_call_unref(call); } end: printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
void linphone_gtk_create_in_call_view(LinphoneCall *call){ GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame"); GtkWidget *main_window=linphone_gtk_get_main_window (); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); static int call_index=1; int idx; GtkWidget *transfer; GtkWidget *conf; GtkWidget *button; GtkWidget *image; if (ms_list_size(linphone_core_get_calls(linphone_gtk_get_core()))==1){ /*this is the only call at this time */ call_index=1; } g_object_set_data(G_OBJECT(call_view),"call",call); g_object_set_data(G_OBJECT(call_view),"call_index",GINT_TO_POINTER(call_index)); linphone_call_set_user_pointer (call,call_view); linphone_call_ref(call); gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index)); gtk_widget_show(call_view); idx = gtk_notebook_page_num(notebook, call_view); gtk_notebook_set_current_page(notebook, idx); call_index++; linphone_gtk_enable_hold_button (call,FALSE,TRUE); linphone_gtk_enable_video_button (call,FALSE,TRUE); linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE); transfer = linphone_gtk_get_widget(call_view,"transfer_button"); gtk_button_set_image(GTK_BUTTON(transfer),gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,GTK_ICON_SIZE_BUTTON)); g_signal_connect(G_OBJECT(transfer),"clicked",(GCallback)transfer_button_clicked,call); gtk_widget_hide(transfer); conf = linphone_gtk_get_widget(call_view,"conference_button"); gtk_button_set_image(GTK_BUTTON(conf),gtk_image_new_from_stock (GTK_STOCK_ADD,GTK_ICON_SIZE_BUTTON)); g_signal_connect(G_OBJECT(conf),"clicked",(GCallback)conference_button_clicked,call); gtk_widget_hide(conf); button=linphone_gtk_get_widget(call_view,"terminate_call"); image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png")); gtk_button_set_label(GTK_BUTTON(button),_("Hang up")); gtk_button_set_image(GTK_BUTTON(button),image); gtk_widget_show(image); g_signal_connect_swapped(G_OBJECT(linphone_gtk_get_widget(call_view,"quality_indicator")),"button-press-event",(GCallback)linphone_gtk_show_call_stats,call); }
static void linphone_gtk_show_call_stats(LinphoneCall *call) { GtkWidget *w=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(w),"call_stats"); if (call_stats==NULL) { guint tid; call_stats=linphone_gtk_create_window("call_statistics", NULL); g_object_set_data(G_OBJECT(w),"call_stats",call_stats); g_object_set_data(G_OBJECT(call_stats),"call",linphone_call_ref(call)); tid=g_timeout_add(1000,(GSourceFunc)refresh_call_stats,call_stats); g_object_set_data(G_OBJECT(call_stats),"tid",GINT_TO_POINTER(tid)); g_signal_connect_swapped(G_OBJECT(call_stats),"destroy",(GCallback)on_call_stats_destroyed,(gpointer)w); show_used_codecs(call_stats,call); refresh_call_stats(call_stats); gtk_widget_show(call_stats); } }
static void quality_reporting_not_sent_if_call_not_started() { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCallLog* out_call_log; LinphoneCall* out_call; linphone_core_set_max_calls(pauline->lc,0); out_call = linphone_core_invite(marie->lc,"pauline"); linphone_call_ref(out_call); BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1, int, "%d"); if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data); BC_ASSERT_PTR_NOT_NULL(out_call_log); BC_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted, int, "%d"); }
void check_rtcp(LinphoneCall *call) { MSTimeSpec ts; linphone_call_ref(call); liblinphone_tester_clock_start(&ts); do { if (linphone_call_get_audio_stats(call)->round_trip_delay > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(call)) || linphone_call_get_video_stats(call)->round_trip_delay > 0.0)) { break; } wait_for_until(call->core, NULL, NULL, 0, 20); /*just to sleep while iterating*/ } while (!liblinphone_tester_clock_elapsed(&ts, 15000)); BC_ASSERT_GREATER(linphone_call_get_audio_stats(call)->round_trip_delay, 0.0, float, "%f"); if (linphone_call_log_video_enabled(linphone_call_get_call_log(call))) { BC_ASSERT_GREATER(linphone_call_get_video_stats(call)->round_trip_delay, 0.0, float, "%f"); } linphone_call_unref(call); }
/* * Call state notification callback */ static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,"sip:[email protected]:9998"); switch(cstate){ case LinphoneCallOutgoingRinging: printf("It is now ringing remotely !\n"); break; case LinphoneCallOutgoingEarlyMedia: printf("Receiving some early media\n"); break; case LinphoneCallConnected: printf("We are connected !\n"); break; case LinphoneCallStreamsRunning: printf("Media streams established !\n"); break; case LinphoneCallEnd: printf("Call is terminated.\n"); break; case LinphoneCallError: printf("Call failure !"); break; case LinphoneCallIncomingReceived: printf("Call incoming received !: %s\n",msg); linphone_call_ref(call); printf("Remote address: %s\n",linphone_call_get_remote_address_as_string(call)); linphone_chat_room_send_message(chat_room,"Welcome in room!\n"); linphone_call_enable_echo_cancellation (call, false); linphone_call_enable_echo_limiter(call,false); linphone_core_accept_call(lc,call); break; case LinphoneCallIncomingEarlyMedia: printf("Call incoming....!"); break; default: printf("Unhandled notification %i\n",cstate); } }
static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details, int code){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); char *msg486=_("User is busy."); char *msg480=_("User is temporarily unavailable."); /*char *retrymsg=_("%s. Retry after %i minute(s).");*/ char *msg600=_("User does not want to be disturbed."); char *msg603=_("Call declined."); const char *msg=details; LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); LinphoneCall *referer=call->referer; if (call==NULL){ ms_warning("Call faillure reported on already terminated call."); return ; } if (lc->vtable.show) lc->vtable.show(lc); if (error==SalErrorNoResponse){ msg=_("No response."); if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); }else if (error==SalErrorProtocol){ msg=details ? details : _("Protocol error."); if (lc->vtable.display_status) lc->vtable.display_status(lc, msg); }else if (error==SalErrorFailure){ switch(sr){ case SalReasonDeclined: msg=msg603; if (lc->vtable.display_status) lc->vtable.display_status(lc,msg603); break; case SalReasonBusy: msg=msg486; if (lc->vtable.display_status) lc->vtable.display_status(lc,msg486); break; case SalReasonRedirect: { ms_error("case SalReasonRedirect"); linphone_call_stop_media_streams(call); if ( call->state==LinphoneCallOutgoingInit || call->state==LinphoneCallOutgoingProgress || call->state==LinphoneCallOutgoingRinging /*push case*/ || call->state==LinphoneCallOutgoingEarlyMedia){ LinphoneAddress* redirection_to = (LinphoneAddress*)sal_op_get_remote_contact_address(call->op); if( redirection_to ){ char* url = linphone_address_as_string(redirection_to); ms_error("Redirecting call [%p] to %s",call, url); ms_free(url); linphone_call_create_op(call); linphone_core_start_invite(lc, call, redirection_to); return; } } msg=_("Redirected"); if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); } break; case SalReasonTemporarilyUnavailable: msg=msg480; if (lc->vtable.display_status) lc->vtable.display_status(lc,msg480); break; case SalReasonNotFound: if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); break; case SalReasonDoNotDisturb: msg=msg600; if (lc->vtable.display_status) lc->vtable.display_status(lc,msg600); break; case SalReasonUnsupportedContent: /*<this is for compatibility: linphone sent 415 because of SDP offer answer failure*/ case SalReasonNotAcceptable: //media_encryption_mandatory if (call->params.media_encryption == LinphoneMediaEncryptionSRTP && !linphone_core_is_media_encryption_mandatory(lc)) { int i; ms_message("Outgoing call [%p] failed with SRTP (SAVP) enabled",call); linphone_call_stop_media_streams(call); if ( call->state==LinphoneCallOutgoingInit || call->state==LinphoneCallOutgoingProgress || call->state==LinphoneCallOutgoingRinging /*push case*/ || call->state==LinphoneCallOutgoingEarlyMedia){ ms_message("Retrying call [%p] with AVP",call); /* clear SRTP local params */ call->params.media_encryption = LinphoneMediaEncryptionNone; for(i=0; i<call->localdesc->n_active_streams; i++) { call->localdesc->streams[i].proto = SalProtoRtpAvp; memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto)); } linphone_core_restart_invite(lc, call); return; } } msg=_("Incompatible media parameters."); if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); break; case SalReasonRequestPending: /*restore previous state, the application will decide to resubmit the action if relevant*/ call->reason=linphone_reason_from_sal(sr); linphone_call_set_state(call,call->prevstate,msg); return; break; default: if (lc->vtable.display_status) lc->vtable.display_status(lc,_("Call failed.")); } } /*some call error are not fatal*/ switch (call->state) { case LinphoneCallUpdating: case LinphoneCallPausing: case LinphoneCallResuming: ms_message("Call error on state [%s], restoring previous state",linphone_call_state_to_string(call->prevstate)); call->reason=linphone_reason_from_sal(sr); linphone_call_set_state(call, call->prevstate,details); return; default: break; /*nothing to do*/ } linphone_core_stop_ringing(lc); linphone_call_stop_media_streams(call); #ifdef BUILD_UPNP linphone_call_delete_upnp_session(call); #endif //BUILD_UPNP call->reason=linphone_reason_from_sal(sr); if (sr==SalReasonDeclined){ linphone_call_set_state(call,LinphoneCallEnd,"Call declined."); }else{ linphone_call_set_state(call,LinphoneCallError,details); if (sr==SalReasonBusy) linphone_core_play_named_tone(lc,LinphoneToneBusy); } if (referer){ /*notify referer of the failure*/ linphone_core_notify_refer_state(lc,referer,call); /*schedule automatic resume of the call. This must be done only after the notifications are completed due to dialog serialization of requests.*/ linphone_core_queue_task(lc,(belle_sip_source_func_t)resume_call_after_failed_transfer,linphone_call_ref(referer),"Automatic call resuming after failed transfer"); } }
static void call_received(SalOp *h){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); LinphoneCall *call; const char *from,*to; char *alt_contact; LinphoneAddress *from_addr, *to_addr; bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",TRUE); /* first check if we can answer successfully to this invite */ if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) { LinphonePresenceActivity *activity = linphone_presence_model_get_activity(lc->presence_model); switch (linphone_presence_activity_get_type(activity)) { case LinphonePresenceActivityBusy: sal_call_decline(h,SalReasonBusy,NULL); break; case LinphonePresenceActivityAppointment: case LinphonePresenceActivityMeeting: case LinphonePresenceActivityOffline: case LinphonePresenceActivityWorship: sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL); break; case LinphonePresenceActivityPermanentAbsence: alt_contact = linphone_presence_model_get_contact(lc->presence_model); if (alt_contact != NULL) { sal_call_decline(h,SalReasonRedirect,alt_contact); ms_free(alt_contact); } break; default: break; } sal_op_release(h); return; } if (!linphone_core_can_we_add_call(lc)){/*busy*/ sal_call_decline(h,SalReasonBusy,NULL); sal_op_release(h); return; } from=sal_op_get_from(h); to=sal_op_get_to(h); from_addr=linphone_address_new(from); to_addr=linphone_address_new(to); if ((already_a_call_with_remote_address(lc,from_addr) && prevent_colliding_calls) || already_a_call_pending(lc)){ ms_warning("Receiving another call while one is ringing or initiated, refusing this one with busy message."); sal_call_decline(h,SalReasonBusy,NULL); sal_op_release(h); linphone_address_destroy(from_addr); linphone_address_destroy(to_addr); return; } call=linphone_call_new_incoming(lc,from_addr,to_addr,h); /* the call is acceptable so we can now add it to our list */ linphone_core_add_call(lc,call); linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */ if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) { /* Defer ringing until the end of the ICE candidates gathering process. */ ms_message("Defer ringing to gather ICE candidates"); return; } #ifdef BUILD_UPNP if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseUpnp) && (call->upnp_session != NULL)) { /* Defer ringing until the end of the ICE candidates gathering process. */ ms_message("Defer ringing to gather uPnP candidates"); return; } #endif //BUILD_UPNP linphone_core_notify_incoming_call(lc,call); }
bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { LinphoneCall *c1,*c2; bool_t audio_success=FALSE; bool_t video_success=FALSE; bool_t text_success=FALSE; bool_t video_enabled, realtime_text_enabled; MSTimeSpec ts; c1=linphone_core_get_current_call(caller->lc); c2=linphone_core_get_current_call(callee->lc); BC_ASSERT_PTR_NOT_NULL(c1); BC_ASSERT_PTR_NOT_NULL(c2); if (!c1 || !c2) return FALSE; linphone_call_ref(c1); linphone_call_ref(c2); BC_ASSERT_EQUAL(linphone_call_params_video_enabled(linphone_call_get_current_params(c1)),linphone_call_params_video_enabled(linphone_call_get_current_params(c2)), int, "%d"); BC_ASSERT_EQUAL(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)),linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c2)), int, "%d"); video_enabled=linphone_call_params_video_enabled(linphone_call_get_current_params(c1)); realtime_text_enabled=linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)); liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { if (linphone_call_get_audio_stats(c1)->ice_state==state && linphone_call_get_audio_stats(c2)->ice_state==state ){ audio_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeAudio); check_ice_from_rtp(c2,c1,LinphoneStreamTypeAudio); break; } linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } ms_usleep(20000); }while(!liblinphone_tester_clock_elapsed(&ts,10000)); if (video_enabled){ liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { if (linphone_call_get_video_stats(c1)->ice_state==state && linphone_call_get_video_stats(c2)->ice_state==state ){ video_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeVideo); check_ice_from_rtp(c2,c1,LinphoneStreamTypeVideo); break; } linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } ms_usleep(20000); }while(!liblinphone_tester_clock_elapsed(&ts,10000)); } if (realtime_text_enabled){ liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { if (linphone_call_get_text_stats(c1)->ice_state==state && linphone_call_get_text_stats(c2)->ice_state==state ){ text_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeText); check_ice_from_rtp(c2,c1,LinphoneStreamTypeText); break; } linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } ms_usleep(20000); }while(!liblinphone_tester_clock_elapsed(&ts,10000)); } /*make sure encryption mode are preserved*/ if (c1) { const LinphoneCallParams* call_param = linphone_call_get_current_params(c1); BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller->lc), int, "%d"); } if (c2) { const LinphoneCallParams* call_param = linphone_call_get_current_params(c2); BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(callee->lc), int, "%d"); } linphone_call_unref(c1); linphone_call_unref(c2); return video_enabled ? (realtime_text_enabled ? text_success && audio_success && video_success : audio_success && video_success) : realtime_text_enabled ? text_success && audio_success : audio_success; }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneCall *call=NULL; LinphoneChatRoom *chat_room; LinphoneChatMessage *chat_message=NULL; const char *dest=NULL; LCSipTransports tp; tp.udp_port=LC_SIP_TRANSPORT_RANDOM; tp.tcp_port=LC_SIP_TRANSPORT_RANDOM; tp.tls_port=LC_SIP_TRANSPORT_RANDOM; /* take the destination sip uri from the command line arguments */ if (argc>1){ dest=argv[1]; } signal(SIGINT,stop); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); linphone_core_set_sip_transports(lc,&tp); /*to avoid port colliding with receiver*/ if (dest){ /* Place an outgoing call with rtt enabled */ LinphoneCallParams *cp = linphone_core_create_call_params(lc, NULL); linphone_call_params_enable_realtime_text(cp,TRUE); /*enable real time text*/ call=linphone_core_invite_with_params(lc,dest,cp); linphone_call_params_destroy(cp); if (call==NULL){ printf("Could not place call to %s\n",dest); goto end; }else printf("Call to %s is in progress...",dest); linphone_call_ref(call); } /*wait for call to be established*/ while (running && (linphone_call_get_state(call) == LinphoneCallOutgoingProgress || linphone_call_get_state(call) == LinphoneCallOutgoingInit)) { linphone_core_iterate(lc); ms_usleep(50000); } /*check if call is established*/ switch (linphone_call_get_state(call)) { case LinphoneCallError: case LinphoneCallReleased: case LinphoneCallEnd: printf("Could not place call to %s\n",dest); goto end; break; default: break; /*continue*/ } chat_room=linphone_call_get_chat_room(call); /*create a chat room associated to this call*/ /* main loop for sending message and doing background linphonecore work: */ while(running){ char character; /*to disable terminal buffering*/ if (system ("/bin/stty raw") == -1){ ms_error("/bin/stty error"); } character = getchar(); if (system("/bin/stty cooked") == -1){ ms_error("/bin/stty error"); } if (character==0x03) {/*CTRL C*/ running=0; break; } if (character != EOF) { /* user has typed something*/ if (chat_message == NULL) { /*create a new message*/ chat_message = linphone_chat_room_create_message(chat_room,""); /*create an empty message*/ } if (character == '\r') { /*new line, committing message*/ linphone_chat_room_send_chat_message(chat_room,chat_message); chat_message = NULL; /*reset message*/ } else { linphone_chat_message_put_char(chat_message,character); /*send char in realtime*/ } } linphone_core_iterate(lc); ms_usleep(50000); } if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ /* terminate the call */ printf("Terminating the call...\n"); linphone_core_terminate_call(lc,call); /*at this stage we don't need the call object */ linphone_call_unref(call); } end: printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
static void call_received(SalOp *h){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); char *barmesg; LinphoneCall *call; const char *from,*to; char *tmp; LinphoneAddress *from_parsed; LinphoneAddress *from_addr, *to_addr; SalMediaDescription *md; bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE); const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc); /* first check if we can answer successfully to this invite */ if (lc->presence_mode==LinphoneStatusBusy || lc->presence_mode==LinphoneStatusOffline || lc->presence_mode==LinphoneStatusDoNotDisturb || lc->presence_mode==LinphoneStatusMoved){ if (lc->presence_mode==LinphoneStatusBusy ) sal_call_decline(h,SalReasonBusy,NULL); else if (lc->presence_mode==LinphoneStatusOffline) sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL); else if (lc->presence_mode==LinphoneStatusDoNotDisturb) sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL); else if (lc->alt_contact!=NULL && lc->presence_mode==LinphoneStatusMoved) sal_call_decline(h,SalReasonRedirect,lc->alt_contact); sal_op_release(h); return; } if (!linphone_core_can_we_add_call(lc)){/*busy*/ sal_call_decline(h,SalReasonBusy,NULL); sal_op_release(h); return; } from=sal_op_get_from(h); to=sal_op_get_to(h); from_addr=linphone_address_new(from); to_addr=linphone_address_new(to); if (is_duplicate_call(lc,from_addr,to_addr)){ ms_warning("Receiving duplicated call, refusing this one."); sal_call_decline(h,SalReasonBusy,NULL); linphone_address_destroy(from_addr); linphone_address_destroy(to_addr); return; } call=linphone_call_new_incoming(lc,from_addr,to_addr,h); sal_call_set_local_media_description(h,call->localdesc); md=sal_call_get_final_media_description(h); if (md && sal_media_description_empty(md)){ sal_call_decline(h,SalReasonMedia,NULL); linphone_call_unref(call); return; } /* the call is acceptable so we can now add it to our list */ linphone_core_add_call(lc,call); from_parsed=linphone_address_new(sal_op_get_from(h)); linphone_address_clean(from_parsed); tmp=linphone_address_as_string(from_parsed); linphone_address_destroy(from_parsed); barmesg=ortp_strdup_printf("%s %s%s",tmp,_("is contacting you"), (sal_call_autoanswer_asked(h)) ?_(" and asked autoanswer."):_(".")); if (lc->vtable.show) lc->vtable.show(lc); if (lc->vtable.display_status) lc->vtable.display_status(lc,barmesg); /* play the ring if this is the only call*/ if (lc->sound_conf.ring_sndcard!=NULL && ms_list_size(lc->calls)==1){ lc->current_call=call; if (lc->ringstream && lc->dmfs_playing_start_time!=0){ ring_stop(lc->ringstream); lc->ringstream=NULL; lc->dmfs_playing_start_time=0; } if(lc->ringstream==NULL && lc->sound_conf.local_ring){ MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard; ms_message("Starting local ring..."); lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,ringcard); } else { ms_message("the local ring is already started"); } }else{ /*TODO : play a tone within the context of the current call */ } linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */ linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call"); if (call->state==LinphoneCallIncomingReceived){ sal_call_notify_ringing(h,propose_early_media || ringback_tone!=NULL); if (propose_early_media || ringback_tone!=NULL){ linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media"); linphone_core_update_streams(lc,call,md); } if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){ linphone_core_accept_call(lc,call); } } linphone_call_unref(call); ms_free(barmesg); ms_free(tmp); }