static void text_message_with_external_body(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); char* to = linphone_address_as_string(marie->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message); linphone_chat_message_set_external_body_url(message,message_external_body_url="http://www.linphone.org"); { int dummy=0; wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/ reset_counters(&marie->stat); reset_counters(&pauline->stat); } linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_chat_room_send_chat_message(chat_room,message); /* check transient message list: the message should be in it, and should be the only one */ CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1); CU_ASSERT_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), message); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1); CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }
static void text_message_with_send_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); char* to = linphone_address_as_string(pauline->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message); reset_counters(&marie->stat); reset_counters(&pauline->stat); /*simultate a network error*/ sal_set_send_error(marie->lc->sal, -1); { int dummy=0; wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/ reset_counters(&marie->stat); reset_counters(&pauline->stat); } linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_chat_room_send_chat_message(chat_room,message); /* check transient message list: the message should be in it, and should be the only one */ CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1); CU_ASSERT_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), message); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); /*CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageInProgress,1);*/ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0); /* the message should have been discarded from transient list after an error */ CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0); sal_set_send_error(marie->lc->sal, 0); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }
static void two_incoming_early_media_video_calls_test(void) { char *ringback_path; LinphoneCoreManager *marie; LinphoneCoreManager *pauline; LinphoneCoreManager *laure; LinphoneCallParams *marie_params; LinphoneCallParams *pauline_params; LinphoneCallParams *laure_params; LinphoneCall *call; const MSList *calls_list; marie = linphone_core_manager_new("marie_rc"); pauline = linphone_core_manager_new("pauline_rc"); laure = linphone_core_manager_new("laure_rc"); marie_params = configure_for_early_media_video_receiving(marie); pauline_params = configure_for_early_media_video_sending(pauline); laure_params = configure_for_early_media_video_sending(laure); /* Configure early media audio to play ring during early-media and send remote ring back tone. */ linphone_core_set_ring_during_incoming_early_media(marie->lc, TRUE); ringback_path = ms_strdup_printf("%s/sounds/ringback.wav", liblinphone_tester_file_prefix); linphone_core_set_remote_ringback_tone(marie->lc, ringback_path); ms_free(ringback_path); /* Early media video call from pauline to marie. */ CU_ASSERT_TRUE(video_call_with_params(pauline, marie, pauline_params, NULL, FALSE)); /* Wait for 2s. */ wait_for_three_cores(marie->lc, pauline->lc, NULL, 2000); /* Early media video call from laure to marie. */ CU_ASSERT_TRUE(video_call_with_params(laure, marie, laure_params, NULL, FALSE)); /* Wait for 2s. */ wait_for_three_cores(marie->lc, pauline->lc, laure->lc, 2000); CU_ASSERT_EQUAL(linphone_core_get_calls_nb(marie->lc), 2); if (linphone_core_get_calls_nb(marie->lc) == 2) { calls_list = linphone_core_get_calls(marie->lc); call = (LinphoneCall *)ms_list_nth_data(calls_list, 0); CU_ASSERT_PTR_NOT_NULL(call); if (call != NULL) { LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_current_params(call)); linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionSendRecv); linphone_call_params_set_video_direction(params, LinphoneMediaDirectionSendRecv); linphone_core_accept_call_with_params(marie->lc, call, params); /* Wait for 5s. */ wait_for_three_cores(marie->lc, pauline->lc, laure->lc, 5000); } } linphone_core_terminate_all_calls(marie->lc); CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1)); CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1)); CU_ASSERT_TRUE(wait_for(marie->lc, laure->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); CU_ASSERT_TRUE(wait_for(marie->lc, laure->lc, &laure->stat.number_of_LinphoneCallEnd, 1)); CU_ASSERT_EQUAL(marie->stat.number_of_video_windows_created, 2); CU_ASSERT_EQUAL(pauline->stat.number_of_video_windows_created, 1); CU_ASSERT_EQUAL(laure->stat.number_of_video_windows_created, 1); linphone_call_params_unref(marie_params); linphone_call_params_unref(pauline_params); linphone_call_params_unref(laure_params); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(laure); }
void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){ if (index<0) linphone_core_set_default_proxy(lc,NULL); else linphone_core_set_default_proxy(lc,ms_list_nth_data(lc->sip_conf.proxies,index)); }
static void stateful_analyzer_suggest_action(MSQosAnalyzer *objbase, MSRateControlAction *action){ MSStatefulQosAnalyzer *obj=(MSStatefulQosAnalyzer*)objbase; float curbw = 0; float bw = 0; rtcpstatspoint_t* greatest_pt = NULL; /*if this is the first measure, there is not enough reliable data to use; we assume loss rate is due to non congestionned network. This is mainly useful in the case loss rate is high (>30%), to reduce quality even before the second RTCP report which can be really used. */ if (obj->curindex==1){ if (obj->network_loss_rate!=0.f){ action->type=MSRateControlActionDecreaseBitrate; action->value=obj->network_loss_rate; } }else { curbw = obj->latest ? obj->latest->bandwidth : 0.f; bw = compute_available_bw(obj); greatest_pt = ms_list_size(obj->rtcpstatspoint) ? (rtcpstatspoint_t*)ms_list_nth_data(obj->rtcpstatspoint, ms_list_size(obj->rtcpstatspoint)-1) : NULL; /*try a burst every 50 seconds (10 RTCP packets)*/ if (obj->curindex % 10 == 6){ ms_message("MSStatefulQosAnalyzer[%p]: try burst!", obj); obj->burst_state = MSStatefulQosAnalyzerBurstEnable; } /*test a min burst to avoid overestimation of available bandwidth but only if there is some loss*/ else if (greatest_pt!=NULL && greatest_pt->loss_percent>1 && (obj->curindex % 10 == 2 || obj->curindex % 10 == 3)){ ms_message("MSStatefulQosAnalyzer[%p]: try minimal burst!", obj); bw *= .33; } /*no bandwidth estimation computed*/ if (bw <= 0 || curbw <= 0){ action->type=MSRateControlActionDoNothing; action->value=0; }else if (bw > curbw){ action->type=MSRateControlActionIncreaseQuality; action->value=MAX(0, 100. * (bw / curbw - 1)); }else{ action->type=MSRateControlActionDecreaseBitrate; action->value=MAX(10, -100. * (bw / curbw - 1)); } } ms_message("MSStatefulQosAnalyzer[%p]: %s of value %d", obj, ms_rate_control_action_type_name(action->type), action->value); if (objbase->on_action_suggested!=NULL){ int i; char *data[4]; int datac = sizeof(data) / sizeof(data[0]); data[0]=ms_strdup("%loss rtt_ms cur_bw"); data[1]=ms_strdup_printf("%d %d %d" , obj->latest?(int)obj->latest->loss_percent:0 , obj->latest?(int)obj->latest->rtt:0 , obj->latest?(int)obj->latest->bandwidth:0 ); data[2]=ms_strdup("action_type action_value est_bw"); data[3]=ms_strdup_printf("%s %d %d" , ms_rate_control_action_type_name(action->type) , action->value , (int)bw ); objbase->on_action_suggested(objbase->on_action_suggested_user_pointer, datac, (const char**)data); for (i=0;i<datac;++i){ ms_free(data[i]); } } }
static bool_t linphone_ldap_contact_provider_iterate(void *data) { LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(data); if( obj->ld && obj->connected && (obj->req_count > 0) ){ // never block struct timeval timeout = {0,0}; LDAPMessage* results = NULL; int ret = ldap_result(obj->ld, LDAP_RES_ANY, LDAP_MSG_ONE, &timeout, &results); switch( ret ){ case -1: { ms_warning("Error in ldap_result : returned -1 (req_count %d): %s", obj->req_count, ldap_err2string(errno)); break; } case 0: break; // nothing to do case LDAP_RES_BIND: { ms_error("iterate: unexpected LDAP_RES_BIND"); break; } case LDAP_RES_EXTENDED: case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: case LDAP_RES_INTERMEDIATE: case LDAP_RES_SEARCH_RESULT: { LDAPMessage* message = ldap_first_message(obj->ld, results); LinphoneLDAPContactSearch* req = linphone_ldap_contact_provider_request_search(obj, ldap_msgid(message)); while( message != NULL ){ linphone_ldap_contact_provider_handle_search_result(obj, req, message ); message = ldap_next_message(obj->ld, message); } if( req && ret == LDAP_RES_SEARCH_RESULT) linphone_ldap_contact_provider_cancel_search( LINPHONE_CONTACT_PROVIDER(obj), LINPHONE_CONTACT_SEARCH(req)); break; } case LDAP_RES_MODIFY: case LDAP_RES_ADD: case LDAP_RES_DELETE: case LDAP_RES_MODDN: case LDAP_RES_COMPARE: default: ms_message("Unhandled LDAP result %x", ret); break; } if( results ) ldap_msgfree(results); } if( obj->ld && obj->connected ){ // check for pending searches unsigned int i; for( i=0; i<obj->req_count; i++){ LinphoneLDAPContactSearch* search = (LinphoneLDAPContactSearch*)ms_list_nth_data( obj->requests, i ); if( search && search->msgid == 0){ int ret; ms_message("Found pending search %p (for %s), launching...", search, search->filter); ret = linphone_ldap_contact_provider_perform_search(obj, search); if( ret != LDAP_SUCCESS ){ linphone_ldap_contact_provider_cancel_search( LINPHONE_CONTACT_PROVIDER(obj), LINPHONE_CONTACT_SEARCH(search)); } } } } return TRUE; }
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session) { const char *rtp_addr, *rtcp_addr; IceSessionState session_state = ice_session_state(session); int nb_candidates; int i, j; bool_t result; if (session_state == IS_Completed) { desc->ice_completed = TRUE; result = ice_check_list_selected_valid_local_candidate(ice_session_check_list(session, 0), &rtp_addr, NULL, NULL, NULL); if (result == TRUE) { strncpy(desc->addr, rtp_addr, sizeof(desc->addr)); } else { ms_warning("If ICE has completed successfully, rtp_addr should be set!"); } } else { desc->ice_completed = FALSE; } strncpy(desc->ice_pwd, ice_session_local_pwd(session), sizeof(desc->ice_pwd)); strncpy(desc->ice_ufrag, ice_session_local_ufrag(session), sizeof(desc->ice_ufrag)); for (i = 0; i < desc->n_active_streams; i++) { SalStreamDescription *stream = &desc->streams[i]; IceCheckList *cl = ice_session_check_list(session, i); nb_candidates = 0; if (cl == NULL) continue; if (ice_check_list_state(cl) == ICL_Completed) { stream->ice_completed = TRUE; result = ice_check_list_selected_valid_local_candidate(ice_session_check_list(session, i), &rtp_addr, &stream->rtp_port, &rtcp_addr, &stream->rtcp_port); } else { stream->ice_completed = FALSE; result = ice_check_list_default_local_candidate(ice_session_check_list(session, i), &rtp_addr, &stream->rtp_port, &rtcp_addr, &stream->rtcp_port); } if (result == TRUE) { strncpy(stream->rtp_addr, rtp_addr, sizeof(stream->rtp_addr)); strncpy(stream->rtcp_addr, rtcp_addr, sizeof(stream->rtcp_addr)); } else { memset(stream->rtp_addr, 0, sizeof(stream->rtp_addr)); memset(stream->rtcp_addr, 0, sizeof(stream->rtcp_addr)); } if ((strlen(ice_check_list_local_pwd(cl)) != strlen(desc->ice_pwd)) || (strcmp(ice_check_list_local_pwd(cl), desc->ice_pwd))) strncpy(stream->ice_pwd, ice_check_list_local_pwd(cl), sizeof(stream->ice_pwd)); else memset(stream->ice_pwd, 0, sizeof(stream->ice_pwd)); if ((strlen(ice_check_list_local_ufrag(cl)) != strlen(desc->ice_ufrag)) || (strcmp(ice_check_list_local_ufrag(cl), desc->ice_ufrag))) strncpy(stream->ice_ufrag, ice_check_list_local_ufrag(cl), sizeof(stream->ice_ufrag)); else memset(stream->ice_pwd, 0, sizeof(stream->ice_pwd)); stream->ice_mismatch = ice_check_list_is_mismatch(cl); if ((ice_check_list_state(cl) == ICL_Running) || (ice_check_list_state(cl) == ICL_Completed)) { memset(stream->ice_candidates, 0, sizeof(stream->ice_candidates)); for (j = 0; j < MIN(ms_list_size(cl->local_candidates), SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES); j++) { SalIceCandidate *sal_candidate = &stream->ice_candidates[nb_candidates]; IceCandidate *ice_candidate = ms_list_nth_data(cl->local_candidates, j); const char *default_addr = NULL; int default_port = 0; if (ice_candidate->componentID == 1) { default_addr = stream->rtp_addr; default_port = stream->rtp_port; } else if (ice_candidate->componentID == 2) { default_addr = stream->rtcp_addr; default_port = stream->rtcp_port; } else continue; if (default_addr[0] == '\0') default_addr = desc->addr; /* Only include the candidates matching the default destination for each component of the stream if the state is Completed as specified in RFC5245 section 9.1.2.2. */ if ((ice_check_list_state(cl) == ICL_Completed) && !((ice_candidate->taddr.port == default_port) && (strlen(ice_candidate->taddr.ip) == strlen(default_addr)) && (strcmp(ice_candidate->taddr.ip, default_addr) == 0))) continue; strncpy(sal_candidate->foundation, ice_candidate->foundation, sizeof(sal_candidate->foundation)); sal_candidate->componentID = ice_candidate->componentID; sal_candidate->priority = ice_candidate->priority; strncpy(sal_candidate->type, ice_candidate_type(ice_candidate), sizeof(sal_candidate->type)); strncpy(sal_candidate->addr, ice_candidate->taddr.ip, sizeof(sal_candidate->addr)); sal_candidate->port = ice_candidate->taddr.port; if ((ice_candidate->base != NULL) && (ice_candidate->base != ice_candidate)) { strncpy(sal_candidate->raddr, ice_candidate->base->taddr.ip, sizeof(sal_candidate->raddr)); sal_candidate->rport = ice_candidate->base->taddr.port; } nb_candidates++; } } if ((ice_check_list_state(cl) == ICL_Completed) && (ice_session_role(session) == IR_Controlling)) { int rtp_port, rtcp_port; memset(stream->ice_remote_candidates, 0, sizeof(stream->ice_remote_candidates)); if (ice_check_list_selected_valid_remote_candidate(cl, &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port) == TRUE) { strncpy(stream->ice_remote_candidates[0].addr, rtp_addr, sizeof(stream->ice_remote_candidates[0].addr)); stream->ice_remote_candidates[0].port = rtp_port; strncpy(stream->ice_remote_candidates[1].addr, rtcp_addr, sizeof(stream->ice_remote_candidates[1].addr)); stream->ice_remote_candidates[1].port = rtcp_port; } else { ms_error("ice: Selected valid remote candidates should be present if the check list is in the Completed state"); } } else { for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES; j++) { stream->ice_remote_candidates[j].addr[0] = '\0'; stream->ice_remote_candidates[j].port = 0; } } } }
LinphoneProxyConfig *__index_to_proxy(LinphoneCore *lc, int index){ if (index>=0) return (LinphoneProxyConfig*)ms_list_nth_data(lc->sip_conf.proxies,index); else return NULL; }