From 078e2d461daf29e9c7b97d6fdcc383ee8d901fad Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 25 Apr 2014 15:07:32 +0200 Subject: [PATCH 01/47] change LinphoneEvent from/to management to only use op --- coreapi/callbacks.c | 2 +- coreapi/event.c | 32 ++++++++++++++++++-------------- coreapi/private.h | 7 +++++-- tester/call_tester.c | 29 +++++++++++++++-------------- tester/eventapi_tester.c | 6 +++++- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 2bbea45b2..94d7f17d2 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -1075,7 +1075,7 @@ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, cons if (lev==NULL) { /*out of subscribe notify */ - lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionOutgoing,eventname); + lev=linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname); } if (lc->vtable.notify_received){ const LinphoneContent *ct=linphone_content_from_sal_body(&content,body); diff --git a/coreapi/event.c b/coreapi/event.c index e95f7d454..b1c7b110d 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -74,17 +74,17 @@ LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, return lev; } -LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name){ +static LinphoneEvent *linphone_event_new_with_op_base(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name, bool_t is_out_of_dialog){ LinphoneEvent *lev=linphone_event_new_base(lc, dir, name, op); - if (dir==LinphoneSubscriptionIncoming){ - lev->resource_addr=linphone_address_clone((LinphoneAddress*)sal_op_get_to_address(op)); - lev->from=linphone_address_clone((LinphoneAddress*)sal_op_get_from_address(lev->op)); - }else{ - lev->resource_addr=linphone_address_clone((LinphoneAddress*)sal_op_get_from_address(op)); - } + lev->is_out_of_dialog_op=is_out_of_dialog; return lev; } - +LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name) { + return linphone_event_new_with_op_base(lc,op,dir,name,FALSE); +} +LinphoneEvent *linphone_event_new_with_out_of_dialog_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name) { + return linphone_event_new_with_op_base(lc,op,dir,name,TRUE); +} void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){ LinphoneCore *lc=lev->lc; if (lev->subscription_state!=state){ @@ -129,8 +129,6 @@ LinphoneEvent *linphone_core_create_subscribe(LinphoneCore *lc, const LinphoneAd LinphoneEvent *lev=linphone_event_new(lc, LinphoneSubscriptionOutgoing, event, expires); linphone_configure_op(lc,lev->op,resource,NULL,TRUE); sal_op_set_manual_refresher_mode(lev->op,!lp_config_get_int(lc->config,"sip","refresh_generic_subscribe",1)); - lev->resource_addr=linphone_address_clone(resource); - lev->from=linphone_address_clone((LinphoneAddress*)sal_op_get_from_address(lev->op)); return lev; } @@ -318,8 +316,6 @@ static void linphone_event_destroy(LinphoneEvent *lev){ if (lev->op) sal_op_release(lev->op); ms_free(lev->name); - if (lev->resource_addr) linphone_address_destroy(lev->resource_addr); - if (lev->from) linphone_address_destroy(lev->from); ms_free(lev); } @@ -341,11 +337,19 @@ const char *linphone_event_get_name(const LinphoneEvent *lev){ } const LinphoneAddress *linphone_event_get_from(const LinphoneEvent *lev){ - return lev->from; + if (lev->is_out_of_dialog_op){ + return (LinphoneAddress*)sal_op_get_to_address(lev->op); + }else{ + return (LinphoneAddress*)sal_op_get_from_address(lev->op); + } } const LinphoneAddress *linphone_event_get_resource(const LinphoneEvent *lev){ - return lev->resource_addr; + if (lev->is_out_of_dialog_op){ + return (LinphoneAddress*)sal_op_get_from_address(lev->op); + }else{ + return (LinphoneAddress*)sal_op_get_to_address(lev->op); + } } LinphoneCore *linphone_event_get_core(const LinphoneEvent *lev){ diff --git a/coreapi/private.h b/coreapi/private.h index ee980edf4..08cd1a3f3 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -710,10 +710,9 @@ struct _LinphoneEvent{ void *userdata; int refcnt; char *name; - LinphoneAddress *from; - LinphoneAddress *resource_addr; int expires; bool_t terminating; + bool_t is_out_of_dialog_op; /*used for out of dialog notify*/ }; @@ -819,6 +818,10 @@ SalReason linphone_reason_to_sal(LinphoneReason reason); LinphoneReason linphone_reason_from_sal(SalReason reason); LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires); LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name); +/** + * Useful for out of dialog notify + * */ +LinphoneEvent *linphone_event_new_with_out_of_dialog_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name); void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state); void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state); LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss); diff --git a/tester/call_tester.c b/tester/call_tester.c index 655281550..a6dc8c4ae 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -1388,31 +1388,32 @@ static void early_media_call_with_ringing(void){ CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); - /* send a 183 to initiate the early media */ + if (linphone_core_inc_invite_pending(pauline->lc)) { + /* send a 183 to initiate the early media */ - linphone_core_accept_early_media(pauline->lc, linphone_core_get_current_call(pauline->lc)); + linphone_core_accept_early_media(pauline->lc, linphone_core_get_current_call(pauline->lc)); - CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) ); - CU_ASSERT_TRUE( wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000) ); - liblinphone_tester_check_rtcp(marie, pauline); + liblinphone_tester_check_rtcp(marie, pauline); - linphone_core_accept_call(pauline->lc, linphone_core_get_current_call(pauline->lc)); + linphone_core_accept_call(pauline->lc, linphone_core_get_current_call(pauline->lc)); - CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000)); - CU_ASSERT_EQUAL(marie_call, linphone_core_get_current_call(marie->lc)); + CU_ASSERT_EQUAL(marie_call, linphone_core_get_current_call(marie->lc)); - liblinphone_tester_check_rtcp(marie, pauline); + liblinphone_tester_check_rtcp(marie, pauline); - linphone_core_terminate_all_calls(pauline->lc); + linphone_core_terminate_all_calls(pauline->lc); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); - ms_list_free(lcs); - + ms_list_free(lcs); + } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index 75bd963d4..ea1bb69a4 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -48,12 +48,16 @@ void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, Li stats* counters = get_stats(lc); LinphoneCoreManager *mgr=get_manager(lc); LinphoneContent content={0}; - + const LinphoneAddress* from_addr = linphone_event_get_from(lev); + char* from = linphone_address_as_string(from_addr); content.type="application"; content.subtype="somexml2"; content.data=(void*)notify_content; content.size=strlen(notify_content); + ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from); + ms_free(from); + switch(state){ case LinphoneSubscriptionNone: break; From 7553aa6492f1df0106ca42bbfb9cea49c5dd656e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 25 Apr 2014 23:10:12 +0200 Subject: [PATCH 02/47] - linphone now puts Route headers in requests (except register) for outbound proxy configurations, according to RFC3261 This behavior can be reverted by putting [sip]->use_no_initial_route=1 in the configuration file. - accept presence NOTIFY without bodies, instead of replying 415 - remove belle-sip warning at start due to stack not created early enough. --- coreapi/bellesip_sal/sal_impl.c | 12 +++++++++-- coreapi/bellesip_sal/sal_impl.h | 1 + coreapi/bellesip_sal/sal_op_impl.c | 17 +++++++++++++++- coreapi/bellesip_sal/sal_op_presence.c | 28 +++++++++++--------------- coreapi/linphonecore.c | 1 + include/sal/sal.h | 1 + 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 5bc256bea..a35d85822 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -424,14 +424,18 @@ Sal * sal_init(){ belle_sip_listener_callbacks_t listener_callbacks; Sal * sal=ms_new0(Sal,1); sal->auto_contacts=TRUE; + + /*first create the stack, which initializes the belle-sip object's pool for this thread*/ + belle_sip_set_log_handler(_belle_sip_log); + sal->stack = belle_sip_stack_new(NULL); + sal->user_agent=belle_sip_header_user_agent_new(); #if defined(PACKAGE_NAME) && defined(LINPHONE_VERSION) belle_sip_header_user_agent_add_product(sal->user_agent, PACKAGE_NAME "/" LINPHONE_VERSION); #endif sal_append_stack_string_to_user_agent(sal); belle_sip_object_ref(sal->user_agent); - belle_sip_set_log_handler(_belle_sip_log); - sal->stack = belle_sip_stack_new(NULL); + sal->prov = belle_sip_stack_create_provider(sal->stack,NULL); sal_nat_helper_enable(sal,TRUE); memset(&listener_callbacks,0,sizeof(listener_callbacks)); @@ -938,6 +942,10 @@ void sal_enable_test_features(Sal*ctx, bool_t enabled){ ctx->enable_test_features=enabled; } +void sal_use_no_initial_route(Sal *ctx, bool_t enabled){ + ctx->no_initial_route=enabled; +} + SalResolverContext * sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data){ return (SalResolverContext*)belle_sip_stack_resolve_a(sal->stack,name,port,family,(belle_sip_resolver_callback_t)cb,data); } diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index c203c9cb1..b6e18d76a 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -47,6 +47,7 @@ struct Sal{ bool_t use_dates; bool_t auto_contacts; bool_t enable_test_features; + bool_t no_initial_route; }; typedef enum SalOpState { diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 251420977..1b90487e0 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -122,15 +122,25 @@ belle_sip_header_t * sal_make_supported_header(Sal *sal){ return belle_sip_header_create("Supported","replaces, outbound"); } +static void add_initial_route_set(belle_sip_request_t *request, const MSList *list){ + for (;list!=NULL;list=list->next){ + SalAddress *addr=(SalAddress*)list->data; + belle_sip_header_route_t *route=belle_sip_header_route_create((belle_sip_header_address_t*)addr); + belle_sip_uri_t *uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route); + belle_sip_uri_set_lr_param(uri,1); + belle_sip_message_add_header((belle_sip_message_t*)request,(belle_sip_header_t*)route); + } +} + belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { belle_sip_header_from_t* from_header; belle_sip_header_to_t* to_header; belle_sip_provider_t* prov=op->base.root->prov; belle_sip_request_t *req; belle_sip_uri_t* req_uri; + const MSList *elem=sal_op_get_route_addresses(op); char token[10]; - if (strcmp("REGISTER",method)==0 || op->privacy==SalPrivacyNone) { from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op)) ,belle_sip_random_token(token,sizeof(token))); @@ -157,6 +167,11 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { belle_sip_header_p_preferred_identity_t* p_preferred_identity=belle_sip_header_p_preferred_identity_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(p_preferred_identity)); } + + if (elem && strcmp(method,"REGISTER")!=0 && !op->base.root->no_initial_route){ + add_initial_route_set(req,elem); + } + if (strcmp("REGISTER",method)!=0 && op->privacy!=SalPrivacyNone ){ belle_sip_header_privacy_t* privacy_header=belle_sip_header_privacy_new(); if (op->privacy&SalPrivacyCritical) diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index ca526fd5d..3be52c051 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -164,6 +164,8 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req return NULL; if (belle_sip_header_content_length_get_content_length(content_length) == 0) return NULL; + + if (body==NULL) return NULL; op->base.root->callbacks.parse_presence_requested(op, belle_sip_header_content_type_get_type(content_type), @@ -183,28 +185,22 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){ if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) { SalPresenceModel *presence_model = NULL; const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); - if (body==NULL){ - ms_error("No body in NOTIFY received from [%s]",sal_op_get_from(op)); - resp = sal_op_create_response_from_request(op, req, 415); - belle_sip_server_transaction_send_response(server_transaction,resp); - return; + if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { + sub_state=SalSubscribeTerminated; + ms_message("Outgoing subscription terminated by remote [%s]",sal_op_get_to(op)); + } else { + sub_state=SalSubscribeActive; } presence_model = process_presence_notification(op, req); - if (presence_model != NULL) { + if (presence_model != NULL || body==NULL) { /* Presence notification body parsed successfully. */ - if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { - sub_state=SalSubscribeTerminated; - ms_message("Outgoing subscription terminated by remote [%s]",sal_op_get_to(op)); - } else { - sub_state=SalSubscribeActive; - } + resp = sal_op_create_response_from_request(op, req, 200); /*create first because the op may be destroyed by notify_presence */ op->base.root->callbacks.notify_presence(op, sub_state, presence_model, NULL); - - } else { + } else if (body){ /* Formatting error in presence notification body. */ - ms_error("Wrongly formatted presence notification received"); - resp = sal_op_create_response_from_request(op, req, 400); + ms_warning("Wrongly formatted presence document."); + resp = sal_op_create_response_from_request(op, req, 488); } belle_sip_server_transaction_send_response(server_transaction,resp); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index dc69310a3..c31d1c181 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -662,6 +662,7 @@ static void sip_config_read(LinphoneCore *lc) sal_use_session_timers(lc->sal,200); } + sal_use_no_initial_route(lc->sal,lp_config_get_int(lc->config,"sip","use_no_initial_route",0)); sal_use_rport(lc->sal,lp_config_get_int(lc->config,"sip","use_rport",1)); ipv6=lp_config_get_int(lc->config,"sip","use_ipv6",-1); diff --git a/include/sal/sal.h b/include/sal/sal.h index 0d5cea3cc..2d7e4eec8 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -530,6 +530,7 @@ void sal_verify_server_cn(Sal *ctx, bool_t verify); void sal_set_uuid(Sal*ctx, const char *uuid); int sal_create_uuid(Sal*ctx, char *uuid, size_t len); void sal_enable_test_features(Sal*ctx, bool_t enabled); +void sal_use_no_initial_route(Sal *ctx, bool_t enabled); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal); From 2b5e2f2a81bbfd722dc42d33be04ed4f3defb1e3 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Mon, 28 Apr 2014 11:27:29 +0200 Subject: [PATCH 03/47] submit quality report on call end instead of on call release and add doxygen documentation --- coreapi/linphonecall.c | 14 ++++--- coreapi/quality_reporting.h | 75 ++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index a4903ed1a..70fe1656a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -794,11 +794,13 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const if (lc->vtable.call_state_changed) lc->vtable.call_state_changed(lc,call,cstate,message); - if (cstate==LinphoneCallReleased){ + if (cstate==LinphoneCallEnd){ if (call->log->status == LinphoneCallSuccess) linphone_reporting_publish(call); + } + if (cstate==LinphoneCallReleased){ if (call->op!=NULL) { /*transfer the last error so that it can be obtained even in Released state*/ if (call->non_op_error.reason==SalReasonNone){ @@ -2718,7 +2720,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEvent *ev){ OrtpEventType evt=ortp_event_get_type(ev); OrtpEventData *evd=ortp_event_get_data(ev); - + if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) { stats->round_trip_delay = rtp_session_get_round_trip_propagation(ms->sessions.rtp_session); if(stats->received_rtcp != NULL) @@ -2753,11 +2755,11 @@ void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index){ MediaStream *ms=stream_index==0 ? (MediaStream *)call->audiostream : (MediaStream *)call->videostream; /*assumption to remove*/ OrtpEvQueue *evq; OrtpEvent *ev; - + if (ms==NULL) return; /* Ensure there is no dangling ICE check list. */ if (call->ice_session == NULL) ms->ice_check_list = NULL; - + switch(ms->type){ case AudioStreamType: audio_stream_iterate((AudioStream*)ms); @@ -2776,10 +2778,10 @@ void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index){ while ((evq=stream_index==0 ? call->audiostream_app_evq : call->videostream_app_evq) && (NULL != (ev=ortp_ev_queue_get(evq)))){ OrtpEventType evt=ortp_event_get_type(ev); OrtpEventData *evd=ortp_event_get_data(ev); - + linphone_call_stats_fill(&call->stats[stream_index],ms,ev); linphone_call_notify_stats_updated(call,stream_index); - + if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ if (ms->type==AudioStreamType) linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); diff --git a/coreapi/quality_reporting.h b/coreapi/quality_reporting.h index c817feba9..c182a4210 100644 --- a/coreapi/quality_reporting.h +++ b/coreapi/quality_reporting.h @@ -26,12 +26,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern "C"{ #endif + +/** + * Linphone quality report sub object storing address related information (ip / port / MAC). + */ typedef struct reporting_addr { char * ip; int port; uint32_t ssrc; } reporting_addr_t; +/** + * Linphone quality report sub object storing media metrics information as required by RFC035. + */ + typedef struct reporting_content_metrics { // timestamps - mandatory struct { @@ -45,18 +53,13 @@ typedef struct reporting_content_metrics { char * payload_desc; // mime type int sample_rate; // clock rate int frame_duration; // to check (ptime?) - audio only - // int frame_ocets; - // int frames_per_sec; - // int packets_per_sec; char * fmtp; int packet_loss_concealment; // in voip metrics - audio only - // char * silence_suppression_state; } session_description; // jitter buffet - optional struct { int adaptive; // constant - // int rate; // constant int nominal; // no may vary during the call <- average? worst score? int max; // no may vary during the call <- average? int abs_max; // constant @@ -64,25 +67,14 @@ typedef struct reporting_content_metrics { // packet loss - optional struct { - float network_packet_loss_rate; // voip metrics (loss rate) + conversion - float jitter_buffer_discard_rate; //idem + float network_packet_loss_rate; + float jitter_buffer_discard_rate; } packet_loss; - // burst gap loss - optional - // (no) currently not implemented - // struct { - // int burst_loss_density; - // int burst_duration; - // float gap_loss_density; - // int gap_duration; - // int min_gap_threshold; - // } burst_gap_loss; - // delay - optional struct { int round_trip_delay; // no - vary int end_system_delay; // no - not implemented yet - // int one_way_delay; int symm_one_way_delay; // no - vary (depends on round_trip_delay) + not implemented (depends on end_system_delay) int interarrival_jitter; // no - not implemented yet int mean_abs_jitter; // to check @@ -92,7 +84,6 @@ typedef struct reporting_content_metrics { struct { int level; // no - vary int noise_level; // no - vary - // int residual_echo_return_loss; } signal; // quality estimates - optional @@ -101,20 +92,14 @@ typedef struct reporting_content_metrics { int rcq; //voip metrics R factor - no - vary or avg in [0..120] float moslq; // no - vary or avg - voip metrics - in [0..4.9] float moscq; // no - vary or avg - voip metrics - in [0..4.9] - - - // int extri; - // int extro; - // char * rlqestalg; - // char * rcqestalg; - // char * moslqestalg; - // char * moscqestalg; - // char * extriestalg; - // char * extroutestalg; - // char * qoestalg; } quality_estimates; } reporting_content_metrics_t; + +/** + * Linphone quality report main object created by function linphone_reporting_new(). + * It contains all fields required by RFC6035 + */ typedef struct reporting_session_report { struct { char * call_id; @@ -138,10 +123,40 @@ typedef struct reporting_session_report { reporting_session_report_t * linphone_reporting_new(); void linphone_reporting_destroy(reporting_session_report_t * report); + +/** + * Fill media information about a given call. This function must be called before + * stopping the media stream. + * @param call #LinphoneCall object to consider + * @param stats_type the media type (LINPHONE_CALL_STATS_AUDIO or LINPHONE_CALL_STATS_VIDEO) + * + */ void linphone_reporting_update(LinphoneCall * call, int stats_type); + +/** + * Fill IP information about a given call. This function must be called each + * time state is 'LinphoneCallStreamsRunning' since IP might be updated (if we + * found a direct route between caller and callee for example). + * @param call #LinphoneCall object to consider + * + */ void linphone_reporting_update_ip(LinphoneCall * call); + +/** + * Publish the report on the call end. + * @param call #LinphoneCall object to consider + * + */ void linphone_reporting_publish(LinphoneCall* call); + +/** + * Update publish report data with fresh RTCP stats, if needed. + * @param call #LinphoneCall object to consider + * @param stats_type the media type (LINPHONE_CALL_STATS_AUDIO or LINPHONE_CALL_STATS_VIDEO) + * + */ void linphone_reporting_call_stats_updated(LinphoneCall *call, int stats_type); + #ifdef __cplusplus } #endif From 037859f83ac2c48d1c7c8cca5f8c443d5fcfb9f8 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Mon, 28 Apr 2014 12:00:49 +0200 Subject: [PATCH 04/47] do not use _() macro for quality reporting data since this macro is used for localized text (gettext) --- coreapi/quality_reporting.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index c9aaf331c..58484cad7 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -55,7 +55,7 @@ static char * float_to_one_decimal_string(float f) { int floor_part = (int) rounded_f; int one_decimal_part = floorf (10 * (rounded_f - floor_part) + .5f); - return ms_strdup_printf(_("%d.%d"), floor_part, one_decimal_part); + return ms_strdup_printf("%d.%d", floor_part, one_decimal_part); } static void append_to_buffer_valist(char **buff, size_t *buff_size, size_t *offset, const char *fmt, va_list args) { @@ -354,9 +354,9 @@ void linphone_reporting_update(LinphoneCall * call, int stats_type) { return; STR_REASSIGN(report->info.call_id, ms_strdup(call->log->call_id)); - STR_REASSIGN(report->info.local_group, ms_strdup_printf(_("linphone-%s-%s-%s"), (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"), + STR_REASSIGN(report->info.local_group, ms_strdup_printf("linphone-%s-%s-%s", (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"), linphone_core_get_user_agent_name(), report->info.call_id)); - STR_REASSIGN(report->info.remote_group, ms_strdup_printf(_("linphone-%s-%s-%s"), (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"), + STR_REASSIGN(report->info.remote_group, ms_strdup_printf("linphone-%s-%s-%s", (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"), linphone_call_get_remote_user_agent(call), report->info.call_id)); if (call->dir == LinphoneCallIncoming) { From 1d7d5f47ebdee02616854d52979739cfa075e635 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Mon, 28 Apr 2014 17:53:53 +0200 Subject: [PATCH 05/47] fix crash in quality reporting if ip was not valid on call end --- coreapi/quality_reporting.c | 3 ++- mediastreamer2 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 58484cad7..df19240d8 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -235,7 +235,8 @@ static void reporting_publish(const LinphoneCall* call, const reporting_session_ // if the call was hungup too early, we might have invalid IPs information // in that case, we abort the report since it's not useful data - if (strlen(report->info.local_addr.ip) == 0 || strlen(report->info.remote_addr.ip) == 0) { + if (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0 + || report->info.remote_addr.ip == NULL || strlen(report->info.remote_addr.ip) == 0) { ms_warning("The call was hang up too early (duration: %d sec) and IP could " "not be retrieved so dropping this report", linphone_call_get_duration(call)); return; diff --git a/mediastreamer2 b/mediastreamer2 index 69cf3ba35..f6c6813f0 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 69cf3ba35c3533f8092b177bdc854a6fb45ceaa3 +Subproject commit f6c6813f0cdffaaa290d3933b7f6a92d586bae72 From c987f1a002b79eb4609d2ac01da72874566fe102 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 1 May 2014 11:41:40 +0200 Subject: [PATCH 06/47] increase wait time in subscribe tests --- tester/eventapi_tester.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index ea1bb69a4..e5c459489 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -140,7 +140,7 @@ static void subscribe_test_declined(void) { linphone_event_ref(lev); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/ ei=linphone_event_get_error_info(lev); CU_ASSERT_PTR_NOT_NULL(ei); @@ -183,8 +183,8 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTes lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,&content); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000)); /*make sure marie receives first notification before terminating*/ @@ -238,7 +238,7 @@ static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTe linphone_event_send_subscribe(lev,&content); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); /*check good receipt of custom headers*/ CU_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header"),"pouet"); From f6d63524d3589c388506c9069d4dcb7d3727f702 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 1 May 2014 12:14:05 +0200 Subject: [PATCH 07/47] fix declared number of channels in SDP for opus codec, to follow opus-rtp draft. add ugly hack to allow older versions of linphone to call new versions with opus. --- coreapi/bellesip_sal/sal_sdp.c | 2 +- coreapi/linphonecore.c | 2 +- coreapi/misc.c | 6 ------ coreapi/offeranswer.c | 15 +++++++++++++-- mediastreamer2 | 2 +- oRTP | 2 +- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index 0ee29e6da..50e3504a5 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -117,7 +117,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session mime_param= belle_sdp_mime_parameter_create ( pt->mime_type , payload_type_get_number ( pt ) , pt->clock_rate - ,stream->type==SalAudio?1:-1 ); + , pt->channels>0 ? pt->channels : -1 ); belle_sdp_mime_parameter_set_parameters ( mime_param,pt->recv_fmtp ); if ( stream->ptime>0 ) { belle_sdp_mime_parameter_set_ptime ( mime_param,stream->ptime ); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c31d1c181..b15bd71b4 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1377,7 +1377,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab linphone_core_assign_payload_type(lc,&payload_type_g729,18,"annexb=no"); linphone_core_assign_payload_type(lc,&payload_type_aaceld_22k,-1,"config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5"); linphone_core_assign_payload_type(lc,&payload_type_aaceld_44k,-1,"config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5"); - linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; usedtx=0; cbr=1"); + linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; stereo=0; sprop-stereo=0"); linphone_core_assign_payload_type(lc,&payload_type_isac,-1,NULL); linphone_core_handle_static_payloads(lc); diff --git a/coreapi/misc.c b/coreapi/misc.c index b1e9f2235..fed8191b4 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -168,12 +168,6 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl case PAYLOAD_AUDIO_PACKETIZED: codec_band=get_audio_payload_bandwidth(lc,pt); ret=bandwidth_is_greater(bandwidth_limit*1000,codec_band); - /*hack to avoid using uwb codecs when having low bitrate and video*/ - if (bandwidth_is_greater(199,bandwidth_limit)){ - if (linphone_core_video_enabled(lc) && pt->clock_rate>16000){ - ret=FALSE; - } - } //ms_message("Payload %s: %g",pt->mime_type,codec_band); break; case PAYLOAD_VIDEO: diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index df4e7507d..db2a28b76 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -39,11 +39,20 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload for (elem=l;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; + + /*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/ + if (refpt->mime_type && strcasecmp(refpt->mime_type,"opus")==0 && refpt->channels==1 + && strcasecmp(pt->mime_type,refpt->mime_type)==0){ + pt->channels=1; /*so that we respond with same number of channels */ + candidate=pt; + break; + } + /* the compare between G729 and G729A is for some stupid uncompliant phone*/ if ( pt->mime_type && refpt->mime_type && (strcasecmp(pt->mime_type,refpt->mime_type)==0 || (strcasecmp(pt->mime_type, "G729") == 0 && strcasecmp(refpt->mime_type, "G729A") == 0 )) - && pt->clock_rate==refpt->clock_rate){ + && pt->clock_rate==refpt->clock_rate && pt->channels==refpt->channels){ candidate=pt; /*good candidate, check fmtp for H264 */ if (strcasecmp(pt->mime_type,"H264")==0){ @@ -106,7 +115,9 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t res=ms_list_append(res,newp); } }else{ - ms_message("No match for %s/%i",p2->mime_type,p2->clock_rate); + if (p2->channels>0) + ms_message("No match for %s/%i/%i",p2->mime_type,p2->clock_rate,p2->channels); + else ms_message("No match for %s/%i",p2->mime_type,p2->clock_rate); } } if (reading_response){ diff --git a/mediastreamer2 b/mediastreamer2 index f6c6813f0..7f97a5c70 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit f6c6813f0cdffaaa290d3933b7f6a92d586bae72 +Subproject commit 7f97a5c7046589f4de0a742a686308ad5770348d diff --git a/oRTP b/oRTP index c09e63ddb..c329c3a47 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit c09e63ddba599a7f7da149edf6f7b290f4cfa787 +Subproject commit c329c3a478011ed4c10ffca79b8624ec6b60450c From c5f702ede74a2f724f6f5d0635a4d332e22c14e0 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 2 May 2014 11:25:59 +0200 Subject: [PATCH 08/47] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 7f97a5c70..f8658d427 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 7f97a5c7046589f4de0a742a686308ad5770348d +Subproject commit f8658d42780c966c7e2cd683c1ee445688e5d465 From 3a6aa9f08d233b7acfb0707cec55b007474fb17a Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 2 May 2014 20:24:51 +0200 Subject: [PATCH 09/47] deep modifications about audio & video codec bitrates are handled. - vbr codecs can automatically have different output bitrates depending on whether video is used and/or allowed total output bandwidth - application can specify an output IP bitrate for a given codec, which allows to control the quality of vbr codecs. Note: a belle-sip upgrade is required to fix a bug around channels parsing in rtpmap. --- coreapi/bellesip_sal/sal_op_call.c | 2 +- coreapi/linphonecall.c | 83 +++++++++++----- coreapi/linphonecore.h | 29 +++++- coreapi/misc.c | 152 +++++++++++++++++------------ coreapi/private.h | 9 +- gtk/propertybox.c | 6 +- tester/call_tester.c | 35 +++++++ 7 files changed, 222 insertions(+), 94 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 610815802..6f886d336 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -597,7 +597,7 @@ int sal_call_set_local_media_description(SalOp *op, SalMediaDescription *desc){ static belle_sip_header_allow_t *create_allow(){ belle_sip_header_allow_t* header_allow; - header_allow = belle_sip_header_allow_create("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE"); + header_allow = belle_sip_header_allow_create("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO"); return header_allow; } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 70fe1656a..bb0e8c619 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1693,17 +1693,65 @@ static void post_configure_audio_streams(LinphoneCall*call){ linphone_call_start_recording(call); } -static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){ +static int get_ideal_audio_bw(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc){ + int remote_bw=0; + int upload_bw; + int total_upload_bw=linphone_core_get_upload_bandwidth(call->core); + const LinphoneCallParams *params=&call->params; + bool_t will_use_video=linphone_core_media_description_contains_video_stream(md); + bool_t forced=FALSE; + + if (desc->bandwidth>0) remote_bw=desc->bandwidth; + else if (md->bandwidth>0) { + /*case where b=AS is given globally, not per stream*/ + remote_bw=md->bandwidth; + } + if (params->up_bw>0){ + forced=TRUE; + upload_bw=params->up_bw; + }else upload_bw=total_upload_bw; + upload_bw=get_min_bandwidth(upload_bw,remote_bw); + if (!will_use_video || forced) return upload_bw; + + if (bandwidth_is_greater(upload_bw,512)){ + upload_bw=100; + }else if (bandwidth_is_greater(upload_bw,256)){ + upload_bw=64; + }else if (bandwidth_is_greater(upload_bw,128)){ + upload_bw=40; + }else if (bandwidth_is_greater(upload_bw,0)){ + upload_bw=24; + } + return upload_bw; +} + +static int get_video_bw(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc){ + int remote_bw=0; int bw; + if (desc->bandwidth>0) remote_bw=desc->bandwidth; + else if (md->bandwidth>0) { + /*case where b=AS is given globally, not per stream*/ + remote_bw=get_remaining_bandwidth_for_video(md->bandwidth,call->audio_bw); + } + bw=get_min_bandwidth(get_remaining_bandwidth_for_video(linphone_core_get_upload_bandwidth(call->core),call->audio_bw),remote_bw); + return bw; +} + +static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){ + int bw=0; const MSList *elem; RtpProfile *prof=rtp_profile_new("Call profile"); bool_t first=TRUE; - int remote_bw=0; LinphoneCore *lc=call->core; int up_ptime=0; const LinphoneCallParams *params=&call->params; + *used_pt=-1; - + if (desc->type==SalAudio) + bw=get_ideal_audio_bw(call,md,desc); + else if (desc->type==SalVideo) + bw=get_video_bw(call,md,desc); + for(elem=desc->payloads;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; int number; @@ -1712,8 +1760,11 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m pt=payload_type_clone(pt); if ((pt->flags & PAYLOAD_TYPE_FLAG_CAN_SEND) && first) { + /*first codec in list is the selected one*/ if (desc->type==SalAudio){ - linphone_core_update_allocated_audio_bandwidth_in_call(call,pt); + /*this will update call->audio_bw*/ + linphone_core_update_allocated_audio_bandwidth_in_call(call,pt,bw); + bw=call->audio_bw; if (params->up_ptime) up_ptime=params->up_ptime; else up_ptime=linphone_core_get_upload_ptime(lc); @@ -1721,27 +1772,9 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m *used_pt=payload_type_get_number(pt); first=FALSE; } - if (desc->bandwidth>0) remote_bw=desc->bandwidth; - else if (md->bandwidth>0) { - /*case where b=AS is given globally, not per stream*/ - remote_bw=md->bandwidth; - if (desc->type==SalVideo){ - remote_bw=get_video_bandwidth(remote_bw,call->audio_bw); - } - } - - if (desc->type==SalAudio){ - int audio_bw=call->audio_bw; - if (params->up_bw){ - if (params->up_bw< audio_bw) - audio_bw=params->up_bw; - } - bw=get_min_bandwidth(audio_bw,remote_bw); - }else bw=get_min_bandwidth(get_video_bandwidth(linphone_core_get_upload_bandwidth (lc),call->audio_bw),remote_bw); - if (bw>0) pt->normal_bitrate=bw*1000; - else if (desc->type==SalAudio){ - pt->normal_bitrate=-1; - } + if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE){ + pt->normal_bitrate=get_min_bandwidth(pt->normal_bitrate,bw*1000); + } else pt->normal_bitrate=bw*1000; if (desc->ptime>0){ up_ptime=desc->ptime; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 7194bbf2c..fc02cbb23 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1580,6 +1580,33 @@ LINPHONE_PUBLIC int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *cod */ LINPHONE_PUBLIC bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const PayloadType *pt); +/** + * Tells whether the specified payload type represents a variable bitrate codec. + * @param[in] lc #LinphoneCore object. + * @param[in] pt The #PayloadType we want to know + * @returns TRUE if the payload type represents a VBR codec, FALSE if disabled. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const PayloadType *pt); + +/** + * Set an explicit bitrate (IP bitrate, not codec bitrate) for a given codec, in kbit/s. + * @param[in] lc the #LinphoneCore object + * @param[in] pt the #PayloadType to modify. + * @param[in] bitrate the IP bitrate in kbit/s. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, int bitrate); + +/** + * Get the bitrate explicitely set with linphone_core_set_payload_type_bitrate(). + * @param[in] lc the #LinphoneCore object + * @param[in] pt the #PayloadType to modify. + * @return bitrate the IP bitrate in kbit/s, or -1 if an error occured. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const PayloadType *pt); + /** * Enable or disable the use of the specified payload type. * @param[in] lc #LinphoneCore object. @@ -1616,7 +1643,7 @@ LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, cons LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt); -LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt); +LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt); /** * Create a proxy config with default values from Linphone core. diff --git a/coreapi/misc.c b/coreapi/misc.c index fed8191b4..f46ec403b 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -77,6 +77,11 @@ bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const PayloadType *p return FALSE; } +bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const PayloadType *pt){ + if (pt->type==PAYLOAD_VIDEO) return TRUE; + return !!(pt->flags & PAYLOAD_TYPE_IS_VBR); +} + int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t enabled){ if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt)){ payload_type_set_enable(pt,enabled); @@ -103,62 +108,124 @@ const char *linphone_core_get_payload_type_description(LinphoneCore *lc, Payload return NULL; } - -/*this function makes a special case for speex/8000. -This codec is variable bitrate. The 8kbit/s mode is interesting when having a low upload bandwidth, but its quality -is not very good. We 'd better use its 15kbt/s mode when we have enough bandwidth*/ -static int get_codec_bitrate(LinphoneCore *lc, const PayloadType *pt){ - int upload_bw=linphone_core_get_upload_bandwidth(lc); - if (bandwidth_is_greater(upload_bw,129) || (bandwidth_is_greater(upload_bw,33) && !linphone_core_video_enabled(lc)) ) { - if (strcmp(pt->mime_type,"speex")==0 && pt->clock_rate==8000){ - return 15000; +void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, int bitrate){ + if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){ + if (pt->flags & PAYLOAD_TYPE_IS_VBR){ + pt->normal_bitrate=bitrate*1000; + pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE; + }else{ + ms_error("Cannot set an explicit bitrate for codec %s/%i, because it is not VBR.",pt->mime_type,pt->clock_rate); } } - return pt->normal_bitrate; + ms_error("linphone_core_set_payload_type_bitrate() payload type not in audio or video list !"); } + /* *((codec-birate*ptime/8) + RTP header + UDP header + IP header)*8/ptime; *ptime=1/npacket */ -static double get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt){ + +static double get_audio_payload_bandwidth_from_codec_bitrate(const PayloadType *pt){ double npacket=50; double packet_size; int bitrate; + if (strcmp(payload_type_get_mime(&payload_type_aaceld_44k), payload_type_get_mime(pt))==0) { /*special case of aac 44K because ptime= 10ms*/ npacket=100; + }else if (strcmp(payload_type_get_mime(&payload_type_ilbc), payload_type_get_mime(pt))==0) { + npacket=1000/30.0; } - bitrate=get_codec_bitrate(lc,pt); + bitrate=pt->normal_bitrate; packet_size= (((double)bitrate)/(npacket*8))+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ; return packet_size*8.0*npacket; } -void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt){ - call->audio_bw=(int)(ceil(get_audio_payload_bandwidth(call->core,pt)/1000.0)); /*rounding codec bandwidth should be avoid, specially for AMR*/ +typedef struct vbr_codec_bitrate{ + int max_avail_bitrate; + int min_rate; + int recomended_bitrate; +}vbr_codec_bitrate_t; + +static vbr_codec_bitrate_t defauls_vbr[]={ + //{ 100, 44100, 100 }, + { 64, 44100, 50 }, + { 64, 16000, 40 }, + { 32, 16000, 32 }, + { 32, 8000, 32 }, + { 0 , 8000, 24 }, + { 0 , 0, 0 } +}; + +static int lookup_vbr_typical_bitrate(int maxbw, int clock_rate){ + vbr_codec_bitrate_t *it; + if (maxbw<=0) maxbw=defauls_vbr[0].max_avail_bitrate; + for(it=defauls_vbr;it->min_rate!=0;it++){ + if (maxbw>=it->max_avail_bitrate && clock_rate>=it->min_rate) + return it->recomended_bitrate; + } + ms_error("lookup_vbr_typical_bitrate(): should not happen."); + return 32; +} + +static int get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt, int maxbw){ + if (linphone_core_payload_type_is_vbr(lc,pt)){ + if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE){ + ms_message("PayloadType %s/%i has bitrate override",pt->mime_type,pt->clock_rate); + return pt->normal_bitrate/1000; + } + return lookup_vbr_typical_bitrate(maxbw,pt->clock_rate); + }else return (int)ceil(get_audio_payload_bandwidth_from_codec_bitrate(pt)/1000.0);/*rounding codec bandwidth should be avoid, specially for AMR*/ +} + +int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const PayloadType *pt){ + int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), + linphone_core_get_upload_bandwidth(lc)); + if (pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED){ + return get_audio_payload_bandwidth(lc,pt,maxbw); + }else if (pt->type==PAYLOAD_VIDEO){ + int video_bw; + linphone_core_update_allocated_audio_bandwidth(lc); + if (maxbw<=0) { + video_bw=1500; /*default bitrate for video stream when no bandwidth limit is set, around 1.5 Mbit/s*/ + }else{ + video_bw=get_remaining_bandwidth_for_video(maxbw,lc->audio_bw); + } + return video_bw; + } + return 0; +} + +void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt, int maxbw){ + call->audio_bw=get_audio_payload_bandwidth(call->core,pt,maxbw); ms_message("Audio bandwidth for this call is %i",call->audio_bw); } void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){ const MSList *elem; - PayloadType *max=NULL; + int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), + linphone_core_get_upload_bandwidth(lc)); + int max_codec_bitrate=0; + for(elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; if (payload_type_enabled(pt)){ - int pt_bitrate=get_codec_bitrate(lc,pt); - if (max==NULL) max=pt; - else if (max->normal_bitrateaudio_bw=(int)(get_audio_payload_bandwidth(lc,max)/1000.0); + if (max_codec_bitrate) { + lc->audio_bw=max_codec_bitrate; } } -bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit) +bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit) { double codec_band; bool_t ret=FALSE; @@ -166,7 +233,7 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl switch (pt->type){ case PAYLOAD_AUDIO_CONTINUOUS: case PAYLOAD_AUDIO_PACKETIZED: - codec_band=get_audio_payload_bandwidth(lc,pt); + codec_band=get_audio_payload_bandwidth(lc,pt,bandwidth_limit); ret=bandwidth_is_greater(bandwidth_limit*1000,codec_band); //ms_message("Payload %s: %g",pt->mime_type,codec_band); break; @@ -181,43 +248,8 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl } /* return TRUE if codec can be used with bandwidth, FALSE else*/ -bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt) -{ - double codec_band; - int allowed_bw,video_bw; - bool_t ret=FALSE; - - linphone_core_update_allocated_audio_bandwidth(lc); - allowed_bw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), - linphone_core_get_upload_bandwidth(lc)); - if (allowed_bw==0) { - allowed_bw=-1; - video_bw=1500; /*around 1.5 Mbit/s*/ - }else - video_bw=get_video_bandwidth(allowed_bw,lc->audio_bw); - - switch (pt->type){ - case PAYLOAD_AUDIO_CONTINUOUS: - case PAYLOAD_AUDIO_PACKETIZED: - codec_band=get_audio_payload_bandwidth(lc,pt); - ret=bandwidth_is_greater(allowed_bw*1000,codec_band); - /*hack to avoid using uwb codecs when having low bitrate and video*/ - if (bandwidth_is_greater(199,allowed_bw)){ - if (linphone_core_video_enabled(lc) && pt->clock_rate>16000){ - ret=FALSE; - } - } - //ms_message("Payload %s: %g",pt->mime_type,codec_band); - break; - case PAYLOAD_VIDEO: - if (video_bw>0){ - pt->normal_bitrate=video_bw*1000; - ret=TRUE; - } - else ret=FALSE; - break; - } - return ret; +bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt){ + return linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, linphone_core_get_payload_type_bitrate(lc,pt)); } bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){ diff --git a/coreapi/private.h b/coreapi/private.h index 08cd1a3f3..3553ca353 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -292,7 +292,7 @@ static inline bool_t bandwidth_is_greater(int bw1, int bw2){ else return bw1>=bw2; } -static inline int get_video_bandwidth(int total, int audio){ +static inline int get_remaining_bandwidth_for_video(int total, int audio){ if (total<=0) return 0; return total-audio-10; } @@ -307,6 +307,7 @@ static inline void set_string(char **dest, const char *src){ } #define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 +#define PAYLOAD_TYPE_BITRATE_OVERRIDE PAYLOAD_TYPE_USER_FLAG_3 void linphone_process_authentication(LinphoneCore* lc, SalOp *op); void linphone_authentication_ok(LinphoneCore *lc, SalOp *op); @@ -321,7 +322,7 @@ void linphone_subscription_answered(LinphoneCore *lc, SalOp *op); void linphone_subscription_closed(LinphoneCore *lc, SalOp *op); void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc); -void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt); +void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt, int maxbw); int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); void linphone_core_resolve_stun_server(LinphoneCore *lc); @@ -655,7 +656,7 @@ struct _LinphoneCore char *play_file; char *rec_file; time_t prevtime; - int audio_bw; + int audio_bw; /*IP bw consumed by audio codec, set as soon as used codec is known, its purpose is to know the remaining bw for video*/ LinphoneCoreWaitingCallback wait_cb; void *wait_ctx; unsigned long video_window_id; @@ -731,7 +732,7 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call); void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md); -bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit); +bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit); #define linphone_core_ready(lc) ((lc)->state==LinphoneGlobalOn || (lc)->state==LinphoneGlobalShutdown) void _linphone_core_configure_resolver(); diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 86356a97b..598e2f384 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -565,7 +565,7 @@ static void linphone_gtk_init_codec_list(GtkTreeView *listview){ "foreground",CODEC_COLOR, NULL); gtk_tree_view_append_column (listview, column); - column = gtk_tree_view_column_new_with_attributes (_("Bitrate (kbit/s)"), + column = gtk_tree_view_column_new_with_attributes (_("IP Bitrate (kbit/s)"), renderer, "text", CODEC_BITRATE, "foreground",CODEC_COLOR, @@ -621,7 +621,7 @@ static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codecl } /* get an iterator */ gtk_list_store_append(store,&iter); - bitrate=payload_type_get_bitrate(pt)/1000.0; + bitrate=linphone_core_get_payload_type_bitrate(linphone_gtk_get_core(),pt); rate=payload_type_get_rate(pt); if (pt->recv_fmtp!=NULL) params=pt->recv_fmtp; gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt), @@ -657,7 +657,7 @@ static void linphone_gtk_check_codec_bandwidth(GtkTreeView *v){ gfloat bitrate; gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1); - bitrate=payload_type_get_bitrate(pt)/1000.0; + bitrate=linphone_core_get_payload_type_bitrate(linphone_gtk_get_core(),pt); gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR, (gpointer)get_codec_color(linphone_gtk_get_core(),pt), CODEC_BITRATE, bitrate,-1); }while(gtk_tree_model_iter_next(model,&iter)); diff --git a/tester/call_tester.c b/tester/call_tester.c index a6dc8c4ae..1fd301fb4 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -25,6 +25,7 @@ #include "liblinphone_tester.h" static void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy); +static void disable_all_codecs_except_one(LinphoneCore *lc, const char *mime); void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ char* to=linphone_address_as_string(linphone_call_get_call_log(call)->to); @@ -249,6 +250,39 @@ static void simple_call(void) { linphone_core_manager_destroy(pauline); } +static void call_with_specified_codec_bitrate(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + const LinphoneCallStats *pauline_stats,*marie_stats; + bool_t call_ok; + if (linphone_core_find_payload_type(marie->lc,"opus",48000,-1)==NULL){ + ms_warning("opus codec not supported, test skipped."); + goto end; + } + + disable_all_codecs_except_one(marie->lc,"opus"); + disable_all_codecs_except_one(pauline->lc,"opus"); + + linphone_core_set_payload_type_bitrate(marie->lc, + linphone_core_find_payload_type(marie->lc,"opus",48000,-1), + 50); + linphone_core_set_payload_type_bitrate(pauline->lc, + linphone_core_find_payload_type(pauline->lc,"opus",48000,-1), + 24); + + CU_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (!call_ok) goto end; + liblinphone_tester_check_rtcp(marie,pauline); + marie_stats=linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc)); + pauline_stats=linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc)); + CU_ASSERT_TRUE(marie_stats->download_bandwidth<30); + CU_ASSERT_TRUE(pauline_stats->download_bandwidth>45); + +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void simple_call_compatibility_mode(void) { char route[256]; LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); @@ -2122,6 +2156,7 @@ test_t call_tests[] = { { "Call statistics not used if no config", statistics_not_used_without_config}, { "Call statistics not sent if call did not start", statistics_not_sent_if_call_not_started}, { "Call statistics sent if call ended normally", statistics_sent_at_call_termination}, + { "Call with specified codec bitrate", call_with_specified_codec_bitrate} }; test_suite_t call_test_suite = { From 9968ac1b8a344287bf182defde8fe1afcd229b30 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 2 May 2014 20:31:29 +0200 Subject: [PATCH 10/47] forgot to update oRTP --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index c329c3a47..bc9f28bea 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit c329c3a478011ed4c10ffca79b8624ec6b60450c +Subproject commit bc9f28beadf9336552eaa091c06bf72fd1d5e491 From 4296c3945c47602e9a3e9daea6b35a85cb2513a8 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 2 May 2014 23:22:36 +0200 Subject: [PATCH 11/47] update oRTP, fix bad error output, and restore UPDATE method in allow header (removed by mistake) --- coreapi/bellesip_sal/sal_op_call.c | 6 +++--- coreapi/misc.c | 1 + oRTP | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 6f886d336..1b0f63949 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -597,7 +597,7 @@ int sal_call_set_local_media_description(SalOp *op, SalMediaDescription *desc){ static belle_sip_header_allow_t *create_allow(){ belle_sip_header_allow_t* header_allow; - header_allow = belle_sip_header_allow_create("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO"); + header_allow = belle_sip_header_allow_create("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE"); return header_allow; } @@ -609,8 +609,8 @@ static void sal_op_fill_invite(SalOp *op, belle_sip_request_t* invite) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Supported", "timer")); } if (op->base.local_media){ - op->sdp_offering=TRUE; - set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),op->base.local_media); + op->sdp_offering=TRUE; + set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),op->base.local_media); }else op->sdp_offering=FALSE; return; } diff --git a/coreapi/misc.c b/coreapi/misc.c index f46ec403b..82f089152 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -115,6 +115,7 @@ void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, i pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE; }else{ ms_error("Cannot set an explicit bitrate for codec %s/%i, because it is not VBR.",pt->mime_type,pt->clock_rate); + return; } } ms_error("linphone_core_set_payload_type_bitrate() payload type not in audio or video list !"); diff --git a/oRTP b/oRTP index bc9f28bea..fb53b3dd2 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit bc9f28beadf9336552eaa091c06bf72fd1d5e491 +Subproject commit fb53b3dd2bcc5e889f7026bdd42b151ef7217249 From e942c6590ba23a1d544790a7026a4398c6b81862 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 5 May 2014 11:03:46 +0200 Subject: [PATCH 12/47] fix clang warning --- coreapi/bellesip_sal/sal_op_presence.c | 4 ++-- mediastreamer2 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 3be52c051..e1ab054aa 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -177,7 +177,7 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req } static void handle_notify(SalOp *op, belle_sip_request_t *req){ - belle_sip_response_t* resp; + belle_sip_response_t* resp=NULL; belle_sip_server_transaction_t* server_transaction=op->pending_server_trans; belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t); SalSubscribeStatus sub_state; @@ -202,7 +202,7 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){ ms_warning("Wrongly formatted presence document."); resp = sal_op_create_response_from_request(op, req, 488); } - belle_sip_server_transaction_send_response(server_transaction,resp); + if (resp) belle_sip_server_transaction_send_response(server_transaction,resp); } } diff --git a/mediastreamer2 b/mediastreamer2 index f8658d427..cc4c03ad5 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit f8658d42780c966c7e2cd683c1ee445688e5d465 +Subproject commit cc4c03ad5e80afc3f0f518618f061e024c6eba64 From eba52ef155b2d945db51daada777e016bce9e550 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 5 May 2014 11:27:35 +0200 Subject: [PATCH 13/47] fix bad handling of link-local ipv6 addresses --- coreapi/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/misc.c b/coreapi/misc.c index 82f089152..38f72bfe3 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1094,7 +1094,7 @@ static int get_local_ip_for_with_connect(int type, const char *dest, char *resul ms_error("getnameinfo error: %s",strerror(errno)); } /*avoid ipv6 link-local addresses*/ - if (type==AF_INET6 && strchr(result,'%')!=NULL){ + if (p_addr->sa_family==AF_INET6 && strchr(result,'%')!=NULL){ strcpy(result,"::1"); close_socket(sock); return -1; From fb2b7ee40df1954235d64d7c69899997f5ea3dfc Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 5 May 2014 11:47:19 +0200 Subject: [PATCH 14/47] ipv6 detection fix --- coreapi/linphonecore.c | 4 +++- coreapi/misc.c | 17 +++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index b15bd71b4..edd8a0c47 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1527,7 +1527,9 @@ void linphone_core_get_local_ip(LinphoneCore *lc, int af, char *result){ strncpy(result,"::1",LINPHONE_IPADDR_SIZE); return; } - }else af=AF_INET; + } + /*in all other cases use IPv4*/ + af=AF_INET; } if (linphone_core_get_local_ip_for(af,NULL,result)==0) return; diff --git a/coreapi/misc.c b/coreapi/misc.c index 38f72bfe3..e3fef7c59 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1000,12 +1000,12 @@ bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc){ #ifdef HAVE_GETIFADDRS #include -static int get_local_ip_with_getifaddrs(int type, char *address, int size) -{ +static int get_local_ip_with_getifaddrs(int type, char *address, int size){ struct ifaddrs *ifp; struct ifaddrs *ifpstart; - int ret = 0; - + char retaddr[LINPHONE_IPADDR_SIZE]={0}; + bool_t found=FALSE; + if (getifaddrs(&ifpstart) < 0) { return -1; } @@ -1022,17 +1022,18 @@ static int get_local_ip_with_getifaddrs(int type, char *address, int size) if(getnameinfo(ifp->ifa_addr, (type == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in), - address, size, NULL, 0, NI_NUMERICHOST) == 0) { - if (strchr(address, '%') == NULL) { /*avoid ipv6 link-local addresses */ + retaddr, size, NULL, 0, NI_NUMERICHOST) == 0) { + if (strchr(retaddr, '%') == NULL) { /*avoid ipv6 link-local addresses */ /*ms_message("getifaddrs() found %s",address);*/ - ret++; + found=TRUE; break; } } } } freeifaddrs(ifpstart); - return ret; + if (found) strncpy(address,retaddr,size); + return found; } #endif From b5117cf71e467fae267a452c8f5a6f0b68d78bac Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Mon, 5 May 2014 12:03:29 +0200 Subject: [PATCH 15/47] Answer 504 to UPDADE requests received in a confirmed dialog --- coreapi/bellesip_sal/sal_op_call.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 1b0f63949..9a2474b37 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -560,6 +560,18 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t belle_sip_server_transaction_send_response(server_transaction,sal_op_create_response_from_request(op,req,481)); } else if (strcmp("MESSAGE",method)==0){ sal_process_incoming_message(op,event); + } else if (strcmp("UPDATE",method)==0) { + /*rfc 3311 + * 5.2 Receiving an UPDATE + * ... + * If the UAS cannot change the session parameters without prompting the user, it SHOULD reject + * the request with a 504 response. + */ + resp=sal_op_create_response_from_request(op,req,504); + belle_sip_message_add_header( BELLE_SIP_MESSAGE(resp) + ,belle_sip_header_create( "Warning", "Cannot change the session parameters without prompting the user")); + belle_sip_server_transaction_send_response(server_transaction,resp); + return; }else{ ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); unsupported_method(server_transaction,req); From b4cda536530f49eab71c45badc6af4941b07c039 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 5 May 2014 12:11:09 +0200 Subject: [PATCH 16/47] relax time in test suite --- tester/flexisip_tester.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index 1a75cdd97..e295b61eb 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -352,11 +352,11 @@ static void call_forking_declined(bool_t declined_globaly){ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,2000)); liblinphone_tester_check_rtcp(pauline,marie2); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,3000)); linphone_core_terminate_call(marie2->lc,linphone_core_get_current_call(marie2->lc)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,3000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,3000)); } linphone_core_manager_destroy(pauline); From ad32d0f58c6ac895eed0938fccb76e3fbe49ffb4 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 5 May 2014 12:58:06 +0200 Subject: [PATCH 17/47] remove check for android, not true for opus --- coreapi/linphonecore.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index edd8a0c47..2b860816f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1189,13 +1189,6 @@ const char * linphone_core_get_version(void){ static void linphone_core_assign_payload_type(LinphoneCore *lc, PayloadType *const_pt, int number, const char *recv_fmtp){ PayloadType *pt; -#ifdef ANDROID - if (const_pt->channels==2){ - ms_message("Stereo %s codec not supported on this platform.",const_pt->mime_type); - return; - } -#endif - pt=payload_type_clone(const_pt); if (number==-1){ /*look for a free number */ From c8cdbdd5436dcecdf585abb344432b09d787389a Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 7 May 2014 12:04:53 +0200 Subject: [PATCH 18/47] allow setting explicit bitrate for video codecs --- coreapi/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/misc.c b/coreapi/misc.c index e3fef7c59..56383fa58 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -110,7 +110,7 @@ const char *linphone_core_get_payload_type_description(LinphoneCore *lc, Payload void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, int bitrate){ if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){ - if (pt->flags & PAYLOAD_TYPE_IS_VBR){ + if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){ pt->normal_bitrate=bitrate*1000; pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE; }else{ From 610f31c95f0cf3475d218a5819d9049cfcf9b9bb Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 7 May 2014 12:06:32 +0200 Subject: [PATCH 19/47] add java bindings for new payload type related API --- coreapi/linphonecore_jni.cc | 16 ++++++++++++++++ java/common/org/linphone/core/LinphoneCore.java | 14 ++++++++++++++ .../impl/org/linphone/core/LinphoneCoreImpl.java | 10 ++++++++++ 3 files changed, 40 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index bb94573f5..4124f3092 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1240,6 +1240,22 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isPayloadTypeEnabled ,jlong pt) { return (jboolean) linphone_core_payload_type_enabled((LinphoneCore*)lc, (PayloadType*)pt); } + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPayloadTypeBitrate(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jlong pt + ,jint bitrate) { + linphone_core_set_payload_type_bitrate((LinphoneCore*)lc,(PayloadType*)pt,bitrate); +} + +extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getPayloadTypeBitrate(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jlong pt) { + return (jint)linphone_core_get_payload_type_bitrate((LinphoneCore*)lc,(PayloadType*)pt); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableEchoCancellation(JNIEnv* env ,jobject thiz ,jlong lc diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 3d22e10ba..332a85be0 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -693,6 +693,20 @@ public interface LinphoneCore { */ boolean isPayloadTypeEnabled(PayloadType pt); + /** + * Set an explicit bitrate (IP bitrate, not codec bitrate) for a given codec, in kbit/s. + * @param pt the payload type + * @param bitrate target IP bitrate in kbit/s + */ + void setPayloadTypeBitrate(PayloadType pt, int bitrate); + + /** + * Get target bitrate previously set by setPayloadTypeBitrate(). + * @param pt + * @return IP bitrate in kbit/s + */ + int getPayloadTypeBitrate(PayloadType pt); + /** * Enables or disable echo cancellation. * @param enable diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 66597ca81..8cd5fe79e 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -1188,5 +1188,15 @@ class LinphoneCoreImpl implements LinphoneCore { public void stopRinging() { stopRinging(nativePtr); } + private native void setPayloadTypeBitrate(long coreptr, long payload_ptr, int bitrate); + @Override + public void setPayloadTypeBitrate(PayloadType pt, int bitrate) { + setPayloadTypeBitrate(nativePtr, ((PayloadTypeImpl)pt).nativePtr, bitrate); + } + private native int getPayloadTypeBitrate(long coreptr, long payload_ptr); + @Override + public int getPayloadTypeBitrate(PayloadType pt) { + return getPayloadTypeBitrate(nativePtr, ((PayloadTypeImpl)pt).nativePtr); + } } From 77ff00acbc834fb365cc32af1c4a08a602ca671d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 7 May 2014 21:41:56 +0200 Subject: [PATCH 20/47] improve network state monitor so that it can take into account IP address changes. --- coreapi/linphonecore.c | 21 +++++++++++++++------ coreapi/private.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2b860816f..cd1534723 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2089,23 +2089,32 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){ static void monitor_network_state(LinphoneCore *lc, time_t curtime){ - char result[LINPHONE_IPADDR_SIZE]; bool_t new_status=lc->network_last_status; + char newip[LINPHONE_IPADDR_SIZE]; /* only do the network up checking every five seconds */ if (lc->network_last_check==0 || (curtime-lc->network_last_check)>=5){ - linphone_core_get_local_ip(lc,AF_UNSPEC,result); - if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){ + linphone_core_get_local_ip(lc,AF_UNSPEC,newip); + if (strcmp(newip,"::1")!=0 && strcmp(newip,"127.0.0.1")!=0){ new_status=TRUE; - }else new_status=FALSE; - lc->network_last_check=curtime; + }else new_status=FALSE; /*no network*/ + + if (new_status==lc->network_last_status && new_status==TRUE && strcmp(newip,lc->localip)!=0){ + /*IP address change detected*/ + ms_message("IP address change detected."); + set_network_reachable(lc,FALSE,curtime); + lc->network_last_status=FALSE; + } + strncpy(lc->localip,newip,sizeof(lc->localip)); + if (new_status!=lc->network_last_status) { if (new_status){ - ms_message("New local ip address is %s",result); + ms_message("New local ip address is %s",lc->localip); } set_network_reachable(lc,new_status, curtime); lc->network_last_status=new_status; } + lc->network_last_check=curtime; } } diff --git a/coreapi/private.h b/coreapi/private.h index 3553ca353..e8294620b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -682,6 +682,7 @@ struct _LinphoneCore bool_t network_last_status; bool_t ringstream_autorelease; bool_t pad[2]; + char localip[LINPHONE_IPADDR_SIZE]; int device_rotation; int max_calls; LinphoneTunnel *tunnel; From 77e0fede43424ea526329f20f1cf24595f0af04a Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Fri, 9 May 2014 12:48:51 +0200 Subject: [PATCH 21/47] use C comment style '/* ... */' instead of C++ '// ...' one --- coreapi/quality_reporting.c | 108 ++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index df19240d8..7da31f3d1 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -31,12 +31,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /*************************************************************************** * TODO / REMINDER LIST ****************************************************************************/ - // to discuss - // For codecs that are able to change sample rates, the lowest and highest sample rates MUST be reported (e.g., 8000;16000). - // moslq == moscq - // video: what happens if doing stop/resume? - // one time value: average? worst value? - // rlq value: need algo to compute it +/*For codecs that are able to change sample rates, the lowest and highest sample rates MUST be reported (e.g., 8000;16000). +moslq == moscq +video: what happens if doing stop/resume? +one time value: average? worst value? +rlq value: need algo to compute it*/ /*************************************************************************** * END OF TODO / REMINDER LIST ****************************************************************************/ @@ -47,8 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dest = src; \ } -// since printf family functions are LOCALE dependent, float separator may differ -// depending on the user's locale (LC_NUMERIC env var). +/*since printf family functions are LOCALE dependent, float separator may differ +depending on the user's locale (LC_NUMERIC environment var).*/ static char * float_to_one_decimal_string(float f) { float rounded_f = floorf(f * 10 + .5f) / 10; @@ -71,17 +70,17 @@ static void append_to_buffer_valist(char **buff, size_t *buff_size, size_t *offs ret = belle_sip_snprintf_valist(*buff, *buff_size, offset, fmt, args); #endif - // if we are out of memory, we add some size to buffer + /*if we are out of memory, we add some size to buffer*/ if (ret == BELLE_SIP_BUFFER_OVERFLOW) { - // some compilers complain that size_t cannot be formatted as unsigned long, hence forcing cast + /*some compilers complain that size_t cannot be formatted as unsigned long, hence forcing cast*/ ms_warning("Buffer was too small to contain the whole report - doubling its size from %lu to %lu", (unsigned long)*buff_size, (unsigned long)2 * *buff_size); *buff_size += 2048; *buff = (char *) ms_realloc(*buff, *buff_size); *offset = prevoffset; - // recall myself since we did not write all things into the buffer but - // only a part of it + /*recall myself since we did not write all things into the buffer but + only a part of it*/ append_to_buffer_valist(buff, buff_size, offset, fmt, args); } } @@ -105,12 +104,12 @@ static bool_t are_metrics_filled(const reporting_content_metrics_t rm) { IF_NUM_IN_RANGE(rm.quality_estimates.moslq, 1, 5, return TRUE); IF_NUM_IN_RANGE(rm.quality_estimates.moscq, 1, 5, return TRUE); - // since these are same values than local ones, do not check them - // if (rm.session_description.payload_type != -1) return TRUE; - // if (rm.session_description.payload_desc != NULL) return TRUE; - // if (rm.session_description.sample_rate != -1) return TRUE; + /*since these are same values than local ones, do not check them*/ + /*if (rm.session_description.payload_type != -1) return TRUE;*/ + /*if (rm.session_description.payload_desc != NULL) return TRUE;*/ + /*if (rm.session_description.sample_rate != -1) return TRUE;*/ if (rm.session_description.frame_duration != -1) return TRUE; - // if (rm.session_description.fmtp != NULL) return TRUE; + /*if (rm.session_description.fmtp != NULL) return TRUE;*/ if (rm.session_description.packet_loss_concealment != -1) return TRUE; IF_NUM_IN_RANGE(rm.jitter_buffer.adaptive, 0, 3, return TRUE); @@ -138,7 +137,7 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off char * timestamps_stop_str = NULL; char * network_packet_loss_rate_str = NULL; char * jitter_buffer_discard_rate_str = NULL; - // char * gap_loss_density_str = NULL; + /*char * gap_loss_density_str = NULL;*/ char * moslq_str = NULL; char * moscq_str = NULL; @@ -149,7 +148,7 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off IF_NUM_IN_RANGE(rm.packet_loss.network_packet_loss_rate, 0, 255, network_packet_loss_rate_str = float_to_one_decimal_string(rm.packet_loss.network_packet_loss_rate / 256)); IF_NUM_IN_RANGE(rm.packet_loss.jitter_buffer_discard_rate, 0, 255, jitter_buffer_discard_rate_str = float_to_one_decimal_string(rm.packet_loss.jitter_buffer_discard_rate / 256)); - // IF_NUM_IN_RANGE(rm.burst_gap_loss.gap_loss_density, 0, 10, gap_loss_density_str = float_to_one_decimal_string(rm.burst_gap_loss.gap_loss_density)); + /*IF_NUM_IN_RANGE(rm.burst_gap_loss.gap_loss_density, 0, 10, gap_loss_density_str = float_to_one_decimal_string(rm.burst_gap_loss.gap_loss_density));*/ IF_NUM_IN_RANGE(rm.quality_estimates.moslq, 1, 5, moslq_str = float_to_one_decimal_string(rm.quality_estimates.moslq)); IF_NUM_IN_RANGE(rm.quality_estimates.moscq, 1, 5, moscq_str = float_to_one_decimal_string(rm.quality_estimates.moscq)); @@ -162,16 +161,16 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off APPEND_IF_NOT_NULL_STR(buffer, size, offset, " PD=%s", rm.session_description.payload_desc); APPEND_IF(buffer, size, offset, " SR=%d", rm.session_description.sample_rate, rm.session_description.sample_rate != -1); APPEND_IF(buffer, size, offset, " FD=%d", rm.session_description.frame_duration, rm.session_description.frame_duration != -1); - // append_to_buffer(buffer, size, offset, " FO=%d", rm.session_description.frame_ocets); - // append_to_buffer(buffer, size, offset, " FPP=%d", rm.session_description.frames_per_sec); - // append_to_buffer(buffer, size, offset, " PPS=%d", rm.session_description.packets_per_sec); + /*append_to_buffer(buffer, size, offset, " FO=%d", rm.session_description.frame_ocets);*/ + /*append_to_buffer(buffer, size, offset, " FPP=%d", rm.session_description.frames_per_sec);*/ + /*append_to_buffer(buffer, size, offset, " PPS=%d", rm.session_description.packets_per_sec);*/ APPEND_IF_NOT_NULL_STR(buffer, size, offset, " FMTP=\"%s\"", rm.session_description.fmtp); APPEND_IF(buffer, size, offset, " PLC=%d", rm.session_description.packet_loss_concealment, rm.session_description.packet_loss_concealment != -1); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " SSUP=%s", rm.session_description.silence_suppression_state); + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " SSUP=%s", rm.session_description.silence_suppression_state);*/ append_to_buffer(buffer, size, offset, "\r\nJitterBuffer:"); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBA=%d", rm.jitter_buffer.adaptive, 0, 3); - // APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBR=%d", rm.jitter_buffer.rate, 0, 15); + /*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBR=%d", rm.jitter_buffer.rate, 0, 15);*/ APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBN=%d", rm.jitter_buffer.nominal, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBM=%d", rm.jitter_buffer.max, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBX=%d", rm.jitter_buffer.abs_max, 0, 65535); @@ -180,17 +179,17 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off APPEND_IF_NOT_NULL_STR(buffer, size, offset, " NLR=%s", network_packet_loss_rate_str); APPEND_IF_NOT_NULL_STR(buffer, size, offset, " JDR=%s", jitter_buffer_discard_rate_str); - // append_to_buffer(buffer, size, offset, "\r\nBurstGapLoss:"); - // append_to_buffer(buffer, size, offset, " BLD=%d", rm.burst_gap_loss.burst_loss_density); - // append_to_buffer(buffer, size, offset, " BD=%d", rm.burst_gap_loss.burst_duration); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " GLD=%s", gap_loss_density_str); - // append_to_buffer(buffer, size, offset, " GD=%d", rm.burst_gap_loss.gap_duration); - // append_to_buffer(buffer, size, offset, " GMIN=%d", rm.burst_gap_loss.min_gap_threshold); + /*append_to_buffer(buffer, size, offset, "\r\nBurstGapLoss:");*/ + /* append_to_buffer(buffer, size, offset, " BLD=%d", rm.burst_gap_loss.burst_loss_density);*/ + /* append_to_buffer(buffer, size, offset, " BD=%d", rm.burst_gap_loss.burst_duration);*/ + /* APPEND_IF_NOT_NULL_STR(buffer, size, offset, " GLD=%s", gap_loss_density_str);*/ + /* append_to_buffer(buffer, size, offset, " GD=%d", rm.burst_gap_loss.gap_duration);*/ + /* append_to_buffer(buffer, size, offset, " GMIN=%d", rm.burst_gap_loss.min_gap_threshold);*/ append_to_buffer(buffer, size, offset, "\r\nDelay:"); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RTD=%d", rm.delay.round_trip_delay, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " ESD=%d", rm.delay.end_system_delay, 0, 65535); - // APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " OWD=%d", rm.delay.one_way_delay, 0, 65535); + /*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " OWD=%d", rm.delay.one_way_delay, 0, 65535);*/ APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " SOWD=%d", rm.delay.symm_one_way_delay, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " IAJ=%d", rm.delay.interarrival_jitter, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " MAJ=%d", rm.delay.mean_abs_jitter, 0, 65535); @@ -198,29 +197,29 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off append_to_buffer(buffer, size, offset, "\r\nSignal:"); APPEND_IF(buffer, size, offset, " SL=%d", rm.signal.level, rm.signal.level != 127); APPEND_IF(buffer, size, offset, " NL=%d", rm.signal.noise_level, rm.signal.noise_level != 127); - // append_to_buffer(buffer, size, offset, " RERL=%d", rm.signal.residual_echo_return_loss); + /*append_to_buffer(buffer, size, offset, " RERL=%d", rm.signal.residual_echo_return_loss);*/ append_to_buffer(buffer, size, offset, "\r\nQualityEst:"); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RLQ=%d", rm.quality_estimates.rlq, 1, 120); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RLQEstAlg=%s", rm.quality_estimates.rlqestalg); + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RLQEstAlg=%s", rm.quality_estimates.rlqestalg);*/ APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RCQ=%d", rm.quality_estimates.rcq, 1, 120); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RCQEstAlgo=%s", rm.quality_estimates.rcqestalg); - // append_to_buffer(buffer, size, offset, " EXTRI=%d", rm.quality_estimates.extri); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtRIEstAlg=%s", rm.quality_estimates.extriestalg); - // append_to_buffer(buffer, size, offset, " EXTRO=%d", rm.quality_estimates.extro); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtROEstAlg=%s", rm.quality_estimates.extroutestalg); + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RCQEstAlgo=%s", rm.quality_estimates.rcqestalg);*/ + /*append_to_buffer(buffer, size, offset, " EXTRI=%d", rm.quality_estimates.extri);*/ + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtRIEstAlg=%s", rm.quality_estimates.extriestalg);*/ + /*append_to_buffer(buffer, size, offset, " EXTRO=%d", rm.quality_estimates.extro);*/ + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtROEstAlg=%s", rm.quality_estimates.extroutestalg);*/ APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQ=%s", moslq_str); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQEstAlgo=%s", rm.quality_estimates.moslqestalg); + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQEstAlgo=%s", rm.quality_estimates.moslqestalg);*/ APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQ=%s", moscq_str); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQEstAlgo=%s", rm.quality_estimates.moscqestalg); - // APPEND_IF_NOT_NULL_STR(buffer, size, offset, " QoEEstAlg=%s", rm.quality_estimates.qoestalg); + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQEstAlgo=%s", rm.quality_estimates.moscqestalg);*/ + /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " QoEEstAlg=%s", rm.quality_estimates.qoestalg);*/ append_to_buffer(buffer, size, offset, "\r\n"); ms_free(timestamps_start_str); ms_free(timestamps_stop_str); ms_free(network_packet_loss_rate_str); ms_free(jitter_buffer_discard_rate_str); - // ms_free(gap_loss_density_str); + /*ms_free(gap_loss_density_str);*/ ms_free(moslq_str); ms_free(moscq_str); } @@ -233,8 +232,8 @@ static void reporting_publish(const LinphoneCall* call, const reporting_session_ size_t size = 2048; char * buffer; - // if the call was hungup too early, we might have invalid IPs information - // in that case, we abort the report since it's not useful data + /*if the call was hung up too early, we might have invalid IPs information + in that case, we abort the report since it's not useful data*/ if (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0 || report->info.remote_addr.ip == NULL || strlen(report->info.remote_addr.ip) == 0) { ms_warning("The call was hang up too early (duration: %d sec) and IP could " @@ -305,17 +304,17 @@ static void reporting_update_ip(LinphoneCall * call, int stats_type) { const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type); const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type); - // local info are always up-to-date and correct + /*local info are always up-to-date and correct*/ if (local_desc != NULL) { call->log->reports[stats_type]->info.local_addr.port = local_desc->rtp_port; STR_REASSIGN(call->log->reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr)); } if (remote_desc != NULL) { - // port is always stored in stream description struct + /*port is always stored in stream description struct*/ call->log->reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port; - // for IP it can be not set if we are using a direct route + /*for IP it can be not set if we are using a direct route*/ if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) { STR_REASSIGN(call->log->reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr)); } else { @@ -330,10 +329,9 @@ static bool_t reporting_enabled(const LinphoneCall * call) { } void linphone_reporting_update_ip(LinphoneCall * call) { - // This function can be called in two different cases: - // - 1) at start when call is starting, remote ip/port info might be the proxy ones to which callee is registered - // - 2) later, if we found a direct route between caller and callee with ICE/Stun, ip/port are updated for the direct route access - + /*This function can be called in two different cases: + - 1) at start when call is starting, remote ip/port info might be the proxy ones to which callee is registered + - 2) later, if we found a direct route between caller and callee with ICE/Stun, ip/port are updated for the direct route access*/ if (! reporting_enabled(call)) return; @@ -375,11 +373,11 @@ void linphone_reporting_update(LinphoneCall * call, int stats_type) { report->local_metrics.timestamps.start = call->log->start_date_time; report->local_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call); - //we use same timestamps for remote too + /*we use same timestamps for remote too*/ report->remote_metrics.timestamps.start = call->log->start_date_time; report->remote_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call); - // yet we use the same payload config for local and remote, since this is the largest use case + /*yet we use the same payload config for local and remote, since this is the largest use case*/ if (stats_type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) { stream = &call->audiostream->ms; local_payload = linphone_call_params_get_used_audio_codec(current_params); @@ -490,14 +488,14 @@ reporting_session_report_t * linphone_reporting_new() { metrics[i]->session_description.packet_loss_concealment = -1; metrics[i]->jitter_buffer.adaptive = -1; - // metrics[i]->jitter_buffer.rate = -1; + /*metrics[i]->jitter_buffer.rate = -1;*/ metrics[i]->jitter_buffer.nominal = -1; metrics[i]->jitter_buffer.max = -1; metrics[i]->jitter_buffer.abs_max = -1; metrics[i]->delay.round_trip_delay = -1; metrics[i]->delay.end_system_delay = -1; - // metrics[i]->delay.one_way_delay = -1; + /*metrics[i]->delay.one_way_delay = -1;*/ metrics[i]->delay.symm_one_way_delay = -1; metrics[i]->delay.interarrival_jitter = -1; metrics[i]->delay.mean_abs_jitter = -1; From a63a3f59cde3910e41a2cb2c10ba0cbb16c7c7a9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 9 May 2014 15:19:50 +0200 Subject: [PATCH 22/47] avoid sending dummy route headers as much as possible --- coreapi/bellesip_sal/sal_op_impl.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 1b90487e0..a364ce324 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -123,10 +123,23 @@ belle_sip_header_t * sal_make_supported_header(Sal *sal){ } static void add_initial_route_set(belle_sip_request_t *request, const MSList *list){ - for (;list!=NULL;list=list->next){ - SalAddress *addr=(SalAddress*)list->data; - belle_sip_header_route_t *route=belle_sip_header_route_create((belle_sip_header_address_t*)addr); - belle_sip_uri_t *uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route); + const MSList *elem; + for (elem=list;elem!=NULL;elem=elem->next){ + SalAddress *addr=(SalAddress*)elem->data; + belle_sip_header_route_t *route; + belle_sip_uri_t *uri; + /*Optimization: if the initial route set only contains one URI which is the same as the request URI, ommit it*/ + if (elem==list && list->next==NULL){ + belle_sip_uri_t *requri=belle_sip_request_get_uri(request); + /*skip the first route it is the same as the request uri*/ + if (strcmp(sal_address_get_domain(addr),belle_sip_uri_get_host(requri))==0 ){ + ms_message("Skipping top route of initial route-set because same as request-uri."); + continue; + } + } + + route=belle_sip_header_route_create((belle_sip_header_address_t*)addr); + uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route); belle_sip_uri_set_lr_param(uri,1); belle_sip_message_add_header((belle_sip_message_t*)request,(belle_sip_header_t*)route); } From 24a208100a173d1b769e830c26f89bd7d2d7df8e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 12 May 2014 12:41:32 +0200 Subject: [PATCH 23/47] * notify friend status to offline when network goes unreachable * relax timeouts of tests again * always install linphone_tunnel.h --- coreapi/Makefile.am | 10 +++------- coreapi/friend.c | 8 ++++++++ tester/call_tester.c | 2 +- tester/flexisip_tester.c | 8 ++++---- tester/tester.c | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 0beea01a4..e2db1d2c1 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -18,11 +18,7 @@ CLEANFILES=$(GITVERSION_FILE) ## Process this file with automake to produce Makefile.in linphone_includedir=$(includedir)/linphone -linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonepresence.h linphonecore_utils.h lpconfig.h sipsetup.h event.h xml2lpc.h lpc2xml.h - -if BUILD_TUNNEL -linphone_include_HEADERS+=linphone_tunnel.h -endif +linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonepresence.h linphonecore_utils.h lpconfig.h sipsetup.h event.h xml2lpc.h lpc2xml.h linphone_tunnel.h lib_LTLIBRARIES=liblinphone.la @@ -82,9 +78,9 @@ endif liblinphone_la_SOURCES+=linphone_tunnel_config.c if BUILD_TUNNEL -liblinphone_la_SOURCES+=linphone_tunnel.cc TunnelManager.cc TunnelManager.hh +liblinphone_la_SOURCES+=linphone_tunnel.cc TunnelManager.cc TunnelManager.hh linphone_tunnel.h else -liblinphone_la_SOURCES+=linphone_tunnel_stubs.c +liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h endif diff --git a/coreapi/friend.c b/coreapi/friend.c index a287b7e90..7b0ddd816 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -244,9 +244,17 @@ static void linphone_friend_unsubscribe(LinphoneFriend *lf){ static void linphone_friend_invalidate_subscription(LinphoneFriend *lf){ if (lf->outsub!=NULL) { + LinphoneCore *lc=lf->lc; sal_op_release(lf->outsub); lf->outsub=NULL; lf->subscribe_active=FALSE; + /*notify application that we no longer know the presence activity */ + if (lf->presence != NULL) { + linphone_presence_model_unref(lf->presence); + } + lf->presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,"unknown activity"); + if (lc->vtable.notify_presence_received) + lc->vtable.notify_presence_received(lc,lf); } lf->initial_subscribes_sent=FALSE; } diff --git a/tester/call_tester.c b/tester/call_tester.c index 1fd301fb4..fb9571205 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -1347,7 +1347,7 @@ static void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t e CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); } else { - ms_warning ("not tested because srtp not available"); + ms_warning ("not tested because %s not available", linphone_media_encryption_to_string(mode)); } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index e295b61eb..89c2dfe4b 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -569,8 +569,8 @@ static void early_media_call_forking(void) { linphone_call_params_destroy(params); CU_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000)); - CU_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000)); + CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,3000)); pauline_call=linphone_core_get_current_call(pauline->lc); marie1_call=linphone_core_get_current_call(marie1->lc); @@ -583,8 +583,8 @@ static void early_media_call_forking(void) { CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie2_call)->download_bandwidth>70); linphone_core_accept_call(marie1->lc,linphone_core_get_current_call(marie1->lc)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,3000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,3000)); /*marie2 should get her call terminated*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); diff --git a/tester/tester.c b/tester/tester.c index 2d734b074..3623073e4 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -141,7 +141,7 @@ bool_t wait_for_until(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int va } bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) { - return wait_for_until(lc_1, lc_2,counter,value,3000); + return wait_for_until(lc_1, lc_2,counter,value,10000); } bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) { From fc6472f49faabe8505dd8fb816a70ad4f863a1c3 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 13 May 2014 15:07:47 +0200 Subject: [PATCH 24/47] Update oRTP and ms2 submodules for work on AVPF. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index cc4c03ad5..4290b6c8f 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit cc4c03ad5e80afc3f0f518618f061e024c6eba64 +Subproject commit 4290b6c8f39855ef7a99e71574567597b9a4d923 diff --git a/oRTP b/oRTP index fb53b3dd2..d7661ae03 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit fb53b3dd2bcc5e889f7026bdd42b151ef7217249 +Subproject commit d7661ae0350fe4ba4c712cad8a4b2e1bbf1b884c From 0554cc4cee868b3903ee3292cd454d2be0ef0784 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 13 May 2014 15:32:46 +0200 Subject: [PATCH 25/47] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 4290b6c8f..2f942b812 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 4290b6c8f39855ef7a99e71574567597b9a4d923 +Subproject commit 2f942b81247ec49050200e8f631ee87d868edfba From b8c3eed489b9739927af1b418124d02cb5f6ca04 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Tue, 13 May 2014 16:42:43 +0200 Subject: [PATCH 26/47] Don't return on failure to bind UDP, so that subsequent channels are still available --- coreapi/linphonecore.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index cd1534723..a77d550ae 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1953,7 +1953,6 @@ static int apply_transports(LinphoneCore *lc){ if (tr->udp_port!=0){ if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){ transport_error(lc,"udp",tr->udp_port); - return -1; } } if (tr->tcp_port!=0){ @@ -2098,7 +2097,7 @@ static void monitor_network_state(LinphoneCore *lc, time_t curtime){ if (strcmp(newip,"::1")!=0 && strcmp(newip,"127.0.0.1")!=0){ new_status=TRUE; }else new_status=FALSE; /*no network*/ - + if (new_status==lc->network_last_status && new_status==TRUE && strcmp(newip,lc->localip)!=0){ /*IP address change detected*/ ms_message("IP address change detected."); @@ -2106,7 +2105,7 @@ static void monitor_network_state(LinphoneCore *lc, time_t curtime){ lc->network_last_status=FALSE; } strncpy(lc->localip,newip,sizeof(lc->localip)); - + if (new_status!=lc->network_last_status) { if (new_status){ ms_message("New local ip address is %s",lc->localip); From 131c00b9ee22f0d171f8db0de13b096f3451c920 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 13 May 2014 16:56:39 +0200 Subject: [PATCH 27/47] Limit the sending of VFU request if a lot of video decoding errors are reported. --- coreapi/linphonecall.c | 5 ++++- mediastreamer2 | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index bb0e8c619..c80810ba4 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1404,7 +1404,10 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u switch (event_id) { case MS_VIDEO_DECODER_DECODING_ERRORS: ms_warning("Case is MS_VIDEO_DECODER_DECODING_ERRORS"); - linphone_call_send_vfu_request(call); + if (call->videostream && (video_stream_is_decoding_error_to_be_reported(call->videostream, 5000) == TRUE)) { + video_stream_decoding_error_reported(call->videostream); + linphone_call_send_vfu_request(call); + } break; case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED: ms_message("First video frame decoded successfully"); diff --git a/mediastreamer2 b/mediastreamer2 index 2f942b812..a090ff068 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 2f942b81247ec49050200e8f631ee87d868edfba +Subproject commit a090ff06894bcb1487b53c39714593aad9d3f77d From 191d6e2f065ec84c5c1c46d83cdd87d59d134e88 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 13 May 2014 18:00:26 +0200 Subject: [PATCH 28/47] Update oRTP and ms2 submodules. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index a090ff068..d51333b63 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a090ff06894bcb1487b53c39714593aad9d3f77d +Subproject commit d51333b63b6f61c96bb861ad07e8165321c50f59 diff --git a/oRTP b/oRTP index d7661ae03..c93363ac0 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit d7661ae0350fe4ba4c712cad8a4b2e1bbf1b884c +Subproject commit c93363ac023c2122bfdfb8b0d99b811dffbad827 From 0c7af0d5f1efcc30b9ff8d91b2b92c5719ae56a8 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 14 May 2014 12:00:29 +0200 Subject: [PATCH 29/47] Update ms2 submodule + disable AVPF for the moment. --- coreapi/linphonecall.c | 1 + mediastreamer2 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index c80810ba4..5202108b7 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -197,6 +197,7 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw if (max_sample_rate) *max_sample_rate=0; for(it=codecs;it!=NULL;it=it->next){ PayloadType *pt=(PayloadType*)it->data; + payload_type_unset_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED); /* Disable AVPF for the moment. */ if (pt->flags & PAYLOAD_TYPE_ENABLED){ if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){ ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s", diff --git a/mediastreamer2 b/mediastreamer2 index d51333b63..dacf94968 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d51333b63b6f61c96bb861ad07e8165321c50f59 +Subproject commit dacf949689d0583fcacd28de316d0c8f05107452 From 1a7f7a72033586a81c4610e69a6393fd1dc49d2c Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 14 May 2014 14:57:11 +0200 Subject: [PATCH 30/47] Update ms2 submodule for VP8 fix. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index dacf94968..ec7b57ba8 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit dacf949689d0583fcacd28de316d0c8f05107452 +Subproject commit ec7b57ba82f2db382bb0b2cac6e5a5b61a1ad08d From 2bf9cd76c8474b0e75e4fd5d64701dbd2791eca9 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 14 May 2014 15:55:35 +0200 Subject: [PATCH 31/47] Update ms2 submodule for an other VP8 fix. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index ec7b57ba8..925ff2778 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ec7b57ba82f2db382bb0b2cac6e5a5b61a1ad08d +Subproject commit 925ff277832d26c7b841ed24cba1eed47dfd2b0f From a0c2e1a10ac776e8a0054d815146c9f178881d82 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 14 May 2014 16:07:42 +0200 Subject: [PATCH 32/47] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 925ff2778..43da5cddd 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 925ff277832d26c7b841ed24cba1eed47dfd2b0f +Subproject commit 43da5cddd515207ceec8bc775f82d15e199a485e From a5e581b3168c96bb3be128c9ed1a3075e863435a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 14 May 2014 16:28:55 +0200 Subject: [PATCH 33/47] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 43da5cddd..0ef0ad686 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 43da5cddd515207ceec8bc775f82d15e199a485e +Subproject commit 0ef0ad686f5c0909236547127d9d41c8574d242e From d5a88652a3a53d1d7a45e4c22de5f02be64ea0ee Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 14 May 2014 17:07:21 +0200 Subject: [PATCH 34/47] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 0ef0ad686..fc3a434df 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0ef0ad686f5c0909236547127d9d41c8574d242e +Subproject commit fc3a434df7845f20e0fc3415f25bbad4598fe3be From ad71bf10d2d78dd35711d2016db5e25e3df87ac2 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 15 May 2014 14:23:05 +0200 Subject: [PATCH 35/47] fix compilation issue on MS2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index fc3a434df..79c18b751 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit fc3a434df7845f20e0fc3415f25bbad4598fe3be +Subproject commit 79c18b75112262460fff45493e70733a2c35333c From f27a2387d4964d3631c6c1b721f5bccae5375870 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 May 2014 17:13:17 +0200 Subject: [PATCH 36/47] Add list of transient messages for messages that are still transitioning to either "delivered" or "error" state. This allows the get_history() call to return pointers that are valid when the chat_state_changed callback is called. --- coreapi/chat.c | 4 ++ coreapi/message_storage.c | 106 ++++++++++++++++++++++++-------------- coreapi/private.h | 1 + 3 files changed, 72 insertions(+), 39 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 1c97389fe..fb2a34159 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -159,6 +159,7 @@ static void linphone_chat_room_delete_remote_composing_refresh_timer(LinphoneCha */ void linphone_chat_room_destroy(LinphoneChatRoom *cr){ LinphoneCore *lc=cr->lc; + ms_list_free_with_data(cr->transient_messages, (void (*)(void*))linphone_chat_message_unref); linphone_chat_room_delete_composing_idle_timer(cr); linphone_chat_room_delete_composing_refresh_timer(cr); linphone_chat_room_delete_remote_composing_refresh_timer(cr); @@ -212,6 +213,9 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM msg->from=linphone_address_new(identity); msg->storage_id=linphone_chat_message_store(msg); + // add to transient list + cr->transient_messages = ms_list_append(cr->transient_messages, linphone_chat_message_ref(msg)); + if (cr->is_composing == LinphoneIsComposingActive) { cr->is_composing = LinphoneIsComposingIdle; } diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 360f28f0a..c7cc86e71 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -39,42 +39,61 @@ static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; +static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){ + MSList* transients = cr->transient_messages; + LinphoneChatMessage* chat; + while( transients ){ + chat = (LinphoneChatMessage*)transients->data; + if(chat->storage_id == storage_id){ + return linphone_chat_message_ref(chat); + } + transients = transients->next; + } + return NULL; +} + static void create_chat_message(char **argv, void *data){ LinphoneChatRoom *cr = (LinphoneChatRoom *)data; - LinphoneChatMessage* new_message = linphone_chat_room_create_message(cr,argv[4]); LinphoneAddress *from; struct tm ret={0}; char tmp1[80]={0}; char tmp2[80]={0}; - - if(atoi(argv[3])==LinphoneChatMessageIncoming){ - new_message->dir=LinphoneChatMessageIncoming; - from=linphone_address_new(argv[2]); - } else { - new_message->dir=LinphoneChatMessageOutgoing; - from=linphone_address_new(argv[1]); - } - linphone_chat_message_set_from(new_message,from); - linphone_address_destroy(from); + unsigned int storage_id = atoi(argv[0]); - if(argv[5]!=NULL){ - int i,j; - sscanf(argv[5],"%3c %3c%d%d:%d:%d %d",tmp1,tmp2,&ret.tm_mday, - &ret.tm_hour,&ret.tm_min,&ret.tm_sec,&ret.tm_year); - ret.tm_year-=1900; - for(i=0;i<7;i++) { - if(strcmp(tmp1,days[i])==0) ret.tm_wday=i; + // check if the message exists in the transient list, in which case we should return that one. + LinphoneChatMessage* new_message = get_transient_message(cr, storage_id); + if( new_message == NULL ){ + new_message = linphone_chat_room_create_message(cr, argv[4]); + + if(atoi(argv[3])==LinphoneChatMessageIncoming){ + new_message->dir=LinphoneChatMessageIncoming; + from=linphone_address_new(argv[2]); + } else { + new_message->dir=LinphoneChatMessageOutgoing; + from=linphone_address_new(argv[1]); } - for(j=0;j<12;j++) { - if(strcmp(tmp2,months[j])==0) ret.tm_mon=j; + linphone_chat_message_set_from(new_message,from); + linphone_address_destroy(from); + + if(argv[5]!=NULL){ + int i,j; + sscanf(argv[5],"%3c %3c%d%d:%d:%d %d",tmp1,tmp2,&ret.tm_mday, + &ret.tm_hour,&ret.tm_min,&ret.tm_sec,&ret.tm_year); + ret.tm_year-=1900; + for(i=0;i<7;i++) { + if(strcmp(tmp1,days[i])==0) ret.tm_wday=i; + } + for(j=0;j<12;j++) { + if(strcmp(tmp2,months[j])==0) ret.tm_mon=j; + } + ret.tm_isdst=-1; } - ret.tm_isdst=-1; + new_message->time=argv[5]!=NULL ? mktime(&ret) : time(NULL); + new_message->is_read=atoi(argv[6]); + new_message->state=atoi(argv[7]); + new_message->storage_id=storage_id; + new_message->external_body_url=argv[8]?ms_strdup(argv[8]):NULL; } - new_message->time=argv[5]!=NULL ? mktime(&ret) : time(NULL); - new_message->is_read=atoi(argv[6]); - new_message->state=atoi(argv[7]); - new_message->storage_id=atoi(argv[0]); - new_message->external_body_url=argv[8]?ms_strdup(argv[8]):NULL; cr->messages_hist=ms_list_prepend(cr->messages_hist,new_message); } @@ -149,18 +168,27 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg){ msg->state,msg->message,my_ctime_r(&msg->time,time_str)); linphone_sql_request(lc->db,buf); sqlite3_free(buf); + + + } + + if( msg->state == LinphoneChatMessageStateDelivered + || msg->state == LinphoneChatMessageStateNotDelivered ){ + // message is not transient anymore, we can remove it from our transient list: + msg->chat_room->transient_messages = ms_list_remove(msg->chat_room->transient_messages, msg); + linphone_chat_message_unref(msg); } } void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ LinphoneCore *lc=linphone_chat_room_get_lc(cr); int read=1; - + if (lc->db==NULL) return ; char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); char *buf=sqlite3_mprintf("update history set read=%i where remoteContact = %Q;", - read,peer); + read,peer); linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(peer); @@ -168,7 +196,7 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { LinphoneCore *lc=linphone_chat_room_get_lc(cr); - + if (lc->db==NULL) return ; char *buf=sqlite3_mprintf("update history set url=%Q where id=%i;",msg->external_body_url,msg->storage_id); @@ -179,9 +207,9 @@ void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *ms int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ LinphoneCore *lc=linphone_chat_room_get_lc(cr); int numrows=0; - + if (lc->db==NULL) return 0; - + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); char *buf=sqlite3_mprintf("select count(*) from history where remoteContact = %Q and read = 0;",peer); sqlite3_stmt *selectStatement; @@ -199,9 +227,9 @@ int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { LinphoneCore *lc=cr->lc; - + if (lc->db==NULL) return ; - + char *buf=sqlite3_mprintf("delete from history where id = %i;", msg->storage_id); linphone_sql_request(lc->db,buf); sqlite3_free(buf); @@ -209,9 +237,9 @@ void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ LinphoneCore *lc=cr->lc; - + if (lc->db==NULL) return ; - + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",peer); linphone_sql_request(lc->db,buf); @@ -224,7 +252,7 @@ MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ MSList *ret; char *buf; char *peer; - + if (lc->db==NULL) return NULL; peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); cr->messages_hist = NULL; @@ -248,7 +276,7 @@ void linphone_create_table(sqlite3* db){ char* errmsg=NULL; int ret; ret=sqlite3_exec(db,"CREATE TABLE if not exists history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);", - 0,0,&errmsg); + 0,0,&errmsg); if(ret != SQLITE_OK) { ms_error("Error in creation: %s.\n", errmsg); sqlite3_free(errmsg); @@ -269,7 +297,7 @@ void linphone_update_table(sqlite3* db) { void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) { char *buf; - + if (lc->db==NULL) return; buf=sqlite3_mprintf("SELECT remoteContact FROM history Group By remoteContact;"); linphone_sql_request_all(lc->db,buf,lc); @@ -301,7 +329,7 @@ void linphone_core_message_storage_close(LinphoneCore *lc){ } } -#else +#else unsigned int linphone_chat_message_store(LinphoneChatMessage *cr){ return 0; diff --git a/coreapi/private.h b/coreapi/private.h index e8294620b..e3a97b8e5 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -451,6 +451,7 @@ struct _LinphoneChatRoom{ LinphoneAddress *peer_url; void * user_data; MSList *messages_hist; + MSList *transient_messages; LinphoneIsComposingState remote_is_composing; LinphoneIsComposingState is_composing; belle_sip_source_t *remote_composing_refresh_timer; From 51a5189c76025f8ec7e36a878fd0e65680b9f4cf Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 May 2014 17:13:28 +0200 Subject: [PATCH 37/47] Fix leak in JNI --- coreapi/linphonecore_jni.cc | 472 ++++++++++++++++++------------------ 1 file changed, 237 insertions(+), 235 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 4124f3092..f6478c5fe 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -109,7 +109,7 @@ static void linphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, const char *levname="undef"; vsnprintf(str, sizeof(str) - 1, fmt, args); str[sizeof(str) - 1] = '\0'; - + int prio; switch(lev){ case ORTP_DEBUG: prio = ANDROID_LOG_DEBUG; levname="debug"; break; @@ -207,7 +207,7 @@ public: callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;"); transferStateId = env->GetMethodID(listenerClass,"transferState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;)V"); - + /*callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);*/ callStatsUpdatedId = env->GetMethodID(listenerClass, "callStatsUpdated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCallStats;)V"); @@ -224,7 +224,7 @@ public: /*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/ newSubscriptionRequestId = env->GetMethodID(listenerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); - + authInfoRequestedId = env->GetMethodID(listenerClass,"authInfoRequested","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); /*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/ @@ -244,8 +244,8 @@ public: "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/PublishState;)V"); notifyRecvId = env->GetMethodID(listenerClass,"notifyReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Ljava/lang/String;Lorg/linphone/core/LinphoneContent;)V"); - - + + proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); proxyCtrId = env->GetMethodID(proxyClass,"", "(Lorg/linphone/core/LinphoneCoreImpl;J)V"); @@ -268,22 +268,22 @@ public: callStatsId = env->GetMethodID(callStatsClass, "", "(JJ)V"); callSetAudioStatsId = env->GetMethodID(callClass, "setAudioStats", "(Lorg/linphone/core/LinphoneCallStats;)V"); callSetVideoStatsId = env->GetMethodID(callClass, "setVideoStats", "(Lorg/linphone/core/LinphoneCallStats;)V"); - + infoMessageClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneInfoMessageImpl")); infoMessageCtor = env->GetMethodID(infoMessageClass,"", "(J)V"); - + linphoneEventClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneEventImpl")); linphoneEventCtrId = env->GetMethodID(linphoneEventClass,"", "(J)V"); - + subscriptionStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionState")); subscriptionStateFromIntId = env->GetStaticMethodID(subscriptionStateClass,"fromInt","(I)Lorg/linphone/core/SubscriptionState;"); - + publishStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/PublishState")); publishStateFromIntId = env->GetStaticMethodID(publishStateClass,"fromInt","(I)Lorg/linphone/core/PublishState;"); - + subscriptionDirClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionDir")); subscriptionDirFromIntId = env->GetStaticMethodID(subscriptionDirClass,"fromInt","(I)Lorg/linphone/core/SubscriptionDir;"); - + configuringStateId = env->GetMethodID(listenerClass,"configuringStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;Ljava/lang/String;)V"); configuringStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RemoteProvisioningState")); configuringStateFromIntId = env->GetStaticMethodID(configuringStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;"); @@ -330,7 +330,7 @@ public: jmethodID authInfoRequestedId; jmethodID publishStateId; jmethodID notifyRecvId; - + jclass configuringStateClass; jmethodID configuringStateId; jmethodID configuringStateFromIntId; @@ -378,19 +378,19 @@ public: jclass addressClass; jmethodID addressCtrId; - + jclass infoMessageClass; jmethodID infoMessageCtor; - + jclass linphoneEventClass; jmethodID linphoneEventCtrId; - + jclass subscriptionStateClass; jmethodID subscriptionStateFromIntId; - + jclass publishStateClass; jmethodID publishStateFromIntId; - + jclass subscriptionDirClass; jmethodID subscriptionDirFromIntId; @@ -464,7 +464,7 @@ public: if (call!=NULL){ void *up=linphone_call_get_user_pointer(call); - + if (up==NULL){ jobj=env->NewObject(callClass,callCtrId,(jlong)call); jobj=env->NewGlobalRef(jobj); @@ -568,7 +568,7 @@ public: ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from) ,message ? env->NewStringUTF(message) : NULL); } - static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) { + static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); if (result != 0) { @@ -580,7 +580,7 @@ public: ,lcData->messageReceivedId ,lcData->core ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room) - ,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg)); + ,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg)); } static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { JNIEnv *env = 0; @@ -737,7 +737,7 @@ public: ,content ? create_java_linphone_content(env,content) : NULL ); } - + static void configuringStatus(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); @@ -782,7 +782,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* libmsbcg729_init(); #endif #ifdef HAVE_ISAC - libmsisac_init(); + libmsisac_init(); #endif jlong nativePtr = (jlong)linphone_core_new( &ldata->vTable @@ -824,13 +824,13 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCallImpl_sendInfoMessage(J } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_stopRinging(JNIEnv* env, jobject thiz, jlong lc) { - linphone_core_stop_ringing((LinphoneCore*)lc); + linphone_core_stop_ringing((LinphoneCore*)lc); } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { - const char* path = env->GetStringUTFChars(jpath, NULL); - linphone_core_set_chat_database_path((LinphoneCore*)lc, path); - env->ReleaseStringUTFChars(jpath, path); + const char* path = env->GetStringUTFChars(jpath, NULL); + linphone_core_set_chat_database_path((LinphoneCore*)lc, path); + env->ReleaseStringUTFChars(jpath, path); } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact(JNIEnv* env, jobject thiz, jlong lc, jstring jdisplayname, jstring jusername) { @@ -838,10 +838,10 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact(JNIEnv const char* username = jusername ? env->GetStringUTFChars(jusername, NULL) : NULL; LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed((LinphoneCore*)lc); - if (parsed != NULL) { - linphone_address_set_display_name(parsed, displayname); - linphone_address_set_username(parsed, username); - char *contact = linphone_address_as_string(parsed); + if (parsed != NULL) { + linphone_address_set_display_name(parsed, displayname); + linphone_address_set_username(parsed, username); + char *contact = linphone_address_as_string(parsed); linphone_core_set_primary_contact((LinphoneCore*)lc, contact); } @@ -851,7 +851,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact(JNIEnv extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getPrimaryContactUsername(JNIEnv* env, jobject thiz, jlong lc) { LinphoneAddress* identity = linphone_core_get_primary_contact_parsed((LinphoneCore*)lc); - const char * username = linphone_address_get_username(identity); + const char * username = linphone_address_get_username(identity); return username ? env->NewStringUTF(username) : NULL; } @@ -880,7 +880,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig( } extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigList(JNIEnv* env, jobject thiz, jlong lc) { - const MSList* proxies = linphone_core_get_proxy_config_list((LinphoneCore*)lc); + const MSList* proxies = linphone_core_get_proxy_config_list((LinphoneCore*)lc); int proxyCount = ms_list_size(proxies); jlongArray jProxies = env->NewLongArray(proxyCount); jlong *jInternalArray = env->GetLongArrayElements(jProxies, NULL); @@ -932,14 +932,14 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_getAuthInfosList(J extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_findAuthInfos(JNIEnv* env, jobject thiz, jlong lc, jstring jusername, jstring jrealm, jstring jdomain) { const char* username = env->GetStringUTFChars(jusername, NULL); - const char* realm = jrealm ? env->GetStringUTFChars(jrealm, NULL) : NULL; - const char* domain = jdomain ? env->GetStringUTFChars(jdomain, NULL) : NULL; - const LinphoneAuthInfo *authInfo = linphone_core_find_auth_info((LinphoneCore*)lc, realm, username, domain); - - if (realm) + const char* realm = jrealm ? env->GetStringUTFChars(jrealm, NULL) : NULL; + const char* domain = jdomain ? env->GetStringUTFChars(jdomain, NULL) : NULL; + const LinphoneAuthInfo *authInfo = linphone_core_find_auth_info((LinphoneCore*)lc, realm, username, domain); + + if (realm) env->ReleaseStringUTFChars(jrealm, realm); - if (domain) - env->ReleaseStringUTFChars(jdomain, domain); + if (domain) + env->ReleaseStringUTFChars(jdomain, domain); env->ReleaseStringUTFChars(jusername, username); return (jlong) authInfo; @@ -1204,7 +1204,7 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_listVideoPayloadTy codecs = codecs->next; } - env->ReleaseLongArrayElements(jCodecs, jInternalArray, 0); + env->ReleaseLongArrayElements(jCodecs, jInternalArray, 0); return jCodecs; } @@ -1287,7 +1287,7 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getCurrentCall(JNIEnv ,jlong lc ) { LinphoneCoreData *lcdata=(LinphoneCoreData*)linphone_core_get_user_data((LinphoneCore*)lc); - + return lcdata->getCall(env,linphone_core_get_current_call((LinphoneCore*)lc)); } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env @@ -1340,7 +1340,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getOrCreateChatRoom(JNI ,jstring jto) { const char* to = env->GetStringUTFChars(jto, NULL); - LinphoneChatRoom* lResult = linphone_core_get_or_create_chat_room((LinphoneCore*)lc,to); + LinphoneChatRoom* lResult = linphone_core_get_or_create_chat_room((LinphoneCore*)lc,to); env->ReleaseStringUTFChars(jto, to); return (jlong)lResult; } @@ -1746,12 +1746,12 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneAuthInfoImpl_getRealm */ JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneAuthInfoImpl_getDomain (JNIEnv *env , jobject, jlong auth_info) { - const char* domain = linphone_auth_info_get_domain((LinphoneAuthInfo*)auth_info); - if (domain) { - return env->NewStringUTF(domain); - } else { - return NULL; - } + const char* domain = linphone_auth_info_get_domain((LinphoneAuthInfo*)auth_info); + if (domain) { + return env->NewStringUTF(domain); + } else { + return NULL; + } } /* @@ -1800,10 +1800,10 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneAuthInfoImpl_setRealm */ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneAuthInfoImpl_setDomain (JNIEnv *env, jobject, jlong auth_info, jstring jdomain) { - const char* domain = jdomain ? env->GetStringUTFChars(jdomain, NULL) : NULL; - linphone_auth_info_set_domain((LinphoneAuthInfo*)auth_info, domain); - if (domain) - env->ReleaseStringUTFChars(jdomain, domain); + const char* domain = jdomain ? env->GetStringUTFChars(jdomain, NULL) : NULL; + linphone_auth_info_set_domain((LinphoneAuthInfo*)auth_info, domain); + if (domain) + env->ReleaseStringUTFChars(jdomain, domain); } /* @@ -2087,7 +2087,7 @@ extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getLocalLateRate( extern "C" void Java_org_linphone_core_LinphoneCallStatsImpl_updateStats(JNIEnv *env, jobject thiz, jlong call_ptr, jint mediatype) { if (mediatype==LINPHONE_CALL_STATS_AUDIO) linphone_call_get_audio_stats((LinphoneCall*)call_ptr); - else + else linphone_call_get_video_stats((LinphoneCall*)call_ptr); } @@ -2248,7 +2248,7 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isEchoLimiterEnabled extern "C" jobject Java_org_linphone_core_LinphoneCallImpl_getReplacedCall( JNIEnv* env ,jobject thiz ,jlong ptr) { - LinphoneCoreData *lcd=(LinphoneCoreData*)linphone_core_get_user_data(linphone_call_get_core((LinphoneCall*)ptr)); + LinphoneCoreData *lcd=(LinphoneCoreData*)linphone_core_get_user_data(linphone_call_get_core((LinphoneCall*)ptr)); return lcd->getCall(env,linphone_call_get_replaced_call((LinphoneCall*)ptr)); } @@ -2367,22 +2367,24 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getFriendByAddress(JNIE } //LinphoneChatRoom extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env - ,jobject thiz - ,jlong ptr - ,jint limit) { - MSList* history = linphone_chat_room_get_history((LinphoneChatRoom*)ptr, limit); - int historySize = ms_list_size(history); - jlongArray jHistory = env->NewLongArray(historySize); - jlong *jInternalArray = env->GetLongArrayElements(jHistory, NULL); + ,jobject thiz + ,jlong ptr + ,jint limit) { + MSList* history = linphone_chat_room_get_history((LinphoneChatRoom*)ptr, limit); + int historySize = ms_list_size(history); + jlongArray jHistory = env->NewLongArray(historySize); + jlong *jInternalArray = env->GetLongArrayElements(jHistory, NULL); - for (int i = 0; i < historySize; i++) { - jInternalArray[i] = (unsigned long) (history->data); - history = history->next; - } + for (int i = 0; i < historySize; i++) { + jInternalArray[i] = (unsigned long) (history->data); + history = history->next; + } - env->ReleaseLongArrayElements(jHistory, jInternalArray, 0); + ms_list_free(history); - return jHistory; + env->ReleaseLongArrayElements(jHistory, jInternalArray, 0); + + return jHistory; } extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_getPeerAddress(JNIEnv* env ,jobject thiz @@ -2400,37 +2402,37 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatM return (jlong) chatMessage; } extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createLinphoneChatMessage2(JNIEnv* env - ,jobject thiz - ,jlong ptr - ,jstring jmessage - ,jstring jurl - ,jint state - ,jlong time - ,jboolean read - ,jboolean incoming) { - const char* message = jmessage?env->GetStringUTFChars(jmessage, NULL):NULL; - const char* url = jurl?env->GetStringUTFChars(jurl, NULL):NULL; + ,jobject thiz + ,jlong ptr + ,jstring jmessage + ,jstring jurl + ,jint state + ,jlong time + ,jboolean read + ,jboolean incoming) { + const char* message = jmessage?env->GetStringUTFChars(jmessage, NULL):NULL; + const char* url = jurl?env->GetStringUTFChars(jurl, NULL):NULL; - LinphoneChatMessage *chatMessage = linphone_chat_room_create_message_2( - (LinphoneChatRoom *)ptr, message, url, (LinphoneChatMessageState)state, - (time_t)time, read, incoming); + LinphoneChatMessage *chatMessage = linphone_chat_room_create_message_2( + (LinphoneChatRoom *)ptr, message, url, (LinphoneChatMessageState)state, + (time_t)time, read, incoming); - if (jmessage != NULL) - env->ReleaseStringUTFChars(jmessage, message); - if (jurl != NULL) - env->ReleaseStringUTFChars(jurl, url); + if (jmessage != NULL) + env->ReleaseStringUTFChars(jmessage, message); + if (jurl != NULL) + env->ReleaseStringUTFChars(jurl, url); - return (jlong) chatMessage; + return (jlong) chatMessage; } extern "C" jint Java_org_linphone_core_LinphoneChatRoomImpl_getUnreadMessagesCount(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - return (jint) linphone_chat_room_get_unread_messages_count((LinphoneChatRoom*)ptr); + ,jobject thiz + ,jlong ptr) { + return (jint) linphone_chat_room_get_unread_messages_count((LinphoneChatRoom*)ptr); } extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_deleteHistory(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - linphone_chat_room_delete_history((LinphoneChatRoom*)ptr); + ,jobject thiz + ,jlong ptr) { + linphone_chat_room_delete_history((LinphoneChatRoom*)ptr); } JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneChatRoomImpl_compose(JNIEnv *env, jobject thiz, jlong ptr) { linphone_chat_room_compose((LinphoneChatRoom *)ptr); @@ -2439,34 +2441,34 @@ JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneChatRoomImpl_isRemoteC return (jboolean)linphone_chat_room_is_remote_composing((LinphoneChatRoom *)ptr); } extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_deleteMessage(JNIEnv* env - ,jobject thiz - ,jlong room - ,jlong msg) { - linphone_chat_room_delete_message((LinphoneChatRoom*)room, (LinphoneChatMessage*)msg); + ,jobject thiz + ,jlong room + ,jlong msg) { + linphone_chat_room_delete_message((LinphoneChatRoom*)room, (LinphoneChatMessage*)msg); } extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_markAsRead(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - linphone_chat_room_mark_as_read((LinphoneChatRoom*)ptr); + ,jobject thiz + ,jlong ptr) { + linphone_chat_room_mark_as_read((LinphoneChatRoom*)ptr); } extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_updateUrl(JNIEnv* env - ,jobject thiz - ,jlong room - ,jlong msg) { - linphone_chat_room_update_url((LinphoneChatRoom*)room, (LinphoneChatMessage*)msg); + ,jobject thiz + ,jlong room + ,jlong msg) { + linphone_chat_room_update_url((LinphoneChatRoom*)room, (LinphoneChatMessage*)msg); } extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_destroy(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - linphone_chat_room_destroy((LinphoneChatRoom*)ptr); + ,jobject thiz + ,jlong ptr) { + linphone_chat_room_destroy((LinphoneChatRoom*)ptr); } extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_store(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - linphone_chat_message_store((LinphoneChatMessage*)ptr); + ,jobject thiz + ,jlong ptr) { + linphone_chat_message_store((LinphoneChatMessage*)ptr); } extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getText(JNIEnv* env @@ -2540,51 +2542,51 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatMessageImpl_getTime(JNIEnv* } extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_getStatus(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - return (jint) linphone_chat_message_get_state((LinphoneChatMessage*)ptr); + ,jobject thiz + ,jlong ptr) { + return (jint) linphone_chat_message_get_state((LinphoneChatMessage*)ptr); } extern "C" jboolean Java_org_linphone_core_LinphoneChatMessageImpl_isRead(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - return (jboolean) linphone_chat_message_is_read((LinphoneChatMessage*)ptr); + ,jobject thiz + ,jlong ptr) { + return (jboolean) linphone_chat_message_is_read((LinphoneChatMessage*)ptr); } extern "C" jboolean Java_org_linphone_core_LinphoneChatMessageImpl_isOutgoing(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - return (jboolean) linphone_chat_message_is_outgoing((LinphoneChatMessage*)ptr); + ,jobject thiz + ,jlong ptr) { + return (jboolean) linphone_chat_message_is_outgoing((LinphoneChatMessage*)ptr); } extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_getStorageId(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - return (jint) linphone_chat_message_get_storage_id((LinphoneChatMessage*)ptr); + ,jobject thiz + ,jlong ptr) { + return (jint) linphone_chat_message_get_storage_id((LinphoneChatMessage*)ptr); } extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - linphone_chat_message_unref((LinphoneChatMessage*)ptr); + ,jobject thiz + ,jlong ptr) { + linphone_chat_message_unref((LinphoneChatMessage*)ptr); } extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_getChatRooms(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - MSList* chats = linphone_core_get_chat_rooms((LinphoneCore*)ptr); - int chatsSize = ms_list_size(chats); - jlongArray jChats = env->NewLongArray(chatsSize); - jlong *jInternalArray = env->GetLongArrayElements(jChats, NULL); + ,jobject thiz + ,jlong ptr) { + MSList* chats = linphone_core_get_chat_rooms((LinphoneCore*)ptr); + int chatsSize = ms_list_size(chats); + jlongArray jChats = env->NewLongArray(chatsSize); + jlong *jInternalArray = env->GetLongArrayElements(jChats, NULL); - for (int i = 0; i < chatsSize; i++) { - jInternalArray[i] = (unsigned long) (chats->data); - chats = chats->next; - } + for (int i = 0; i < chatsSize; i++) { + jInternalArray[i] = (unsigned long) (chats->data); + chats = chats->next; + } - env->ReleaseLongArrayElements(jChats, jInternalArray, 0); + env->ReleaseLongArrayElements(jChats, jInternalArray, 0); - return jChats; + return jChats; } extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv* env @@ -2615,7 +2617,7 @@ static void chat_room_impl_callback(LinphoneChatMessage* msg, LinphoneChatMessag method, jmessage, env->CallStaticObjectMethod(lcData->chatMessageStateClass,lcData->chatMessageStateFromIntId,(jint)state)); - + if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { env->DeleteGlobalRef(listener); env->DeleteGlobalRef(jmessage); @@ -2878,10 +2880,10 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setPreferredVideo extern "C" jintArray Java_org_linphone_core_LinphoneCoreImpl_getPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc){ MSVideoSize vsize = linphone_core_get_preferred_video_size((LinphoneCore *)lc); - jintArray arr = env->NewIntArray(2); + jintArray arr = env->NewIntArray(2); int tVsize [2]= {vsize.width,vsize.height}; - env->SetIntArrayRegion(arr, 0, 2, tVsize); - return arr; + env->SetIntArrayRegion(arr, 0, 2, tVsize); + return arr; } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){ @@ -2974,8 +2976,8 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setSignalingTransportPor } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableIpv6(JNIEnv* env,jobject thiz - ,jlong lc, jboolean enable) { - linphone_core_enable_ipv6((LinphoneCore*)lc,enable); + ,jlong lc, jboolean enable) { + linphone_core_enable_ipv6((LinphoneCore*)lc,enable); } extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isIpv6Enabled(JNIEnv* env,jobject thiz, jlong lc) { @@ -2983,7 +2985,7 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isIpv6Enabled(JNIEnv } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_adjustSoftwareVolume(JNIEnv* env,jobject thiz - ,jlong ptr, jint db) { + ,jlong ptr, jint db) { linphone_core_set_playback_gain_db((LinphoneCore *) ptr, db); } @@ -3343,7 +3345,7 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getUpnpExternalIpaddr * Method: subscribe * Signature: (JJLjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; */ -JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIEnv *env, jobject jcore, jlong coreptr, jlong addrptr, +JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIEnv *env, jobject jcore, jlong coreptr, jlong addrptr, jstring jevname, jint expires, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneCore *lc=(LinphoneCore*)coreptr; LinphoneAddress *addr=(LinphoneAddress*)addrptr; @@ -3352,7 +3354,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIE jobject jev=NULL; const char *evname=env->GetStringUTFChars(jevname,NULL); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); - + if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3388,7 +3390,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_publish(JNIEnv jobject jev=NULL; const char *evname=env->GetStringUTFChars(jevname,NULL); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); - + if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3412,8 +3414,8 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_publish(JNIEnv // LpConfig extern "C" jlong Java_org_linphone_core_LpConfigImpl_newLpConfigImpl(JNIEnv *env, jobject thiz, jstring file) { - const char *cfile = env->GetStringUTFChars(file, NULL); - LpConfig *lp = lp_config_new(cfile); + const char *cfile = env->GetStringUTFChars(file, NULL); + LpConfig *lp = lp_config_new(cfile); env->ReleaseStringUTFChars(file, cfile); return (jlong) lp; } @@ -3430,112 +3432,112 @@ extern "C" void Java_org_linphone_core_LpConfigImpl_delete(JNIEnv *env, jobject extern "C" void Java_org_linphone_core_LpConfigImpl_setInt(JNIEnv *env, jobject thiz, jlong lpc, jstring section, jstring key, jint value) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - lp_config_set_int((LpConfig *)lpc, csection, ckey, (int) value); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + lp_config_set_int((LpConfig *)lpc, csection, ckey, (int) value); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); } extern "C" jint Java_org_linphone_core_LpConfigImpl_getInt(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jint defaultValue) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - int returnValue = lp_config_get_int((LpConfig *)lpc, csection, ckey, (int) defaultValue); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); - return (jint) returnValue; + jstring section, jstring key, jint defaultValue) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + int returnValue = lp_config_get_int((LpConfig *)lpc, csection, ckey, (int) defaultValue); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); + return (jint) returnValue; } extern "C" void Java_org_linphone_core_LpConfigImpl_setFloat(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jfloat value) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - lp_config_set_float((LpConfig *)lpc, csection, ckey, (float) value); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); + jstring section, jstring key, jfloat value) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + lp_config_set_float((LpConfig *)lpc, csection, ckey, (float) value); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); } extern "C" jfloat Java_org_linphone_core_LpConfigImpl_getFloat(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jfloat defaultValue) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - float returnValue = lp_config_get_float((LpConfig *)lpc, csection, ckey, (float) defaultValue); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); - return (jfloat) returnValue; + jstring section, jstring key, jfloat defaultValue) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + float returnValue = lp_config_get_float((LpConfig *)lpc, csection, ckey, (float) defaultValue); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); + return (jfloat) returnValue; } extern "C" void Java_org_linphone_core_LpConfigImpl_setBool(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jboolean value) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - lp_config_set_int((LpConfig *)lpc, csection, ckey, value ? 1 : 0); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); + jstring section, jstring key, jboolean value) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + lp_config_set_int((LpConfig *)lpc, csection, ckey, value ? 1 : 0); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); } extern "C" jboolean Java_org_linphone_core_LpConfigImpl_getBool(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jboolean defaultValue) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - int returnValue = lp_config_get_int((LpConfig *)lpc, csection, ckey, defaultValue ? 1 : 0); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); - return (jboolean) returnValue == 1; + jstring section, jstring key, jboolean defaultValue) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + int returnValue = lp_config_get_int((LpConfig *)lpc, csection, ckey, defaultValue ? 1 : 0); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); + return (jboolean) returnValue == 1; } extern "C" void Java_org_linphone_core_LpConfigImpl_setString(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jstring value) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - const char *cvalue = value ? env->GetStringUTFChars(value, NULL) : NULL; - lp_config_set_string((LpConfig *)lpc, csection, ckey, cvalue); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); - if (value) env->ReleaseStringUTFChars(value, cvalue); + jstring section, jstring key, jstring value) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + const char *cvalue = value ? env->GetStringUTFChars(value, NULL) : NULL; + lp_config_set_string((LpConfig *)lpc, csection, ckey, cvalue); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); + if (value) env->ReleaseStringUTFChars(value, cvalue); } extern "C" jstring Java_org_linphone_core_LpConfigImpl_getString(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jstring defaultValue) { + jstring section, jstring key, jstring defaultValue) { const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - const char *cvalue = defaultValue ? env->GetStringUTFChars(defaultValue, NULL) : NULL; + const char *ckey = env->GetStringUTFChars(key, NULL); + const char *cvalue = defaultValue ? env->GetStringUTFChars(defaultValue, NULL) : NULL; const char *returnValue = lp_config_get_string((LpConfig *)lpc, csection, ckey, cvalue); - jstring jreturnValue = NULL; - if (returnValue) - jreturnValue = env->NewStringUTF(returnValue); + jstring jreturnValue = NULL; + if (returnValue) + jreturnValue = env->NewStringUTF(returnValue); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); if (cvalue) - env->ReleaseStringUTFChars(defaultValue, cvalue); + env->ReleaseStringUTFChars(defaultValue, cvalue); - return jreturnValue; + return jreturnValue; } extern "C" void Java_org_linphone_core_LpConfigImpl_setIntRange(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jint min, jint max) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - lp_config_set_range((LpConfig *)lpc, csection, ckey, min, max); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); + jstring section, jstring key, jint min, jint max) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + lp_config_set_range((LpConfig *)lpc, csection, ckey, min, max); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); } extern "C" jintArray Java_org_linphone_core_LpConfigImpl_getIntRange(JNIEnv *env, jobject thiz, jlong lpc, - jstring section, jstring key, jint defaultmin, jint defaultmax) { - const char *csection = env->GetStringUTFChars(section, NULL); - const char *ckey = env->GetStringUTFChars(key, NULL); - int *values = (int*)calloc(2, sizeof(int)); - lp_config_get_range((LpConfig *)lpc, csection, ckey, &values[0], &values[1], defaultmin, defaultmax); - jintArray returnValues = env->NewIntArray(2); - env->SetIntArrayRegion(returnValues, 0, 2, values); - ms_free(values); - env->ReleaseStringUTFChars(section, csection); - env->ReleaseStringUTFChars(key, ckey); - return returnValues; + jstring section, jstring key, jint defaultmin, jint defaultmax) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + int *values = (int*)calloc(2, sizeof(int)); + lp_config_get_range((LpConfig *)lpc, csection, ckey, &values[0], &values[1], defaultmin, defaultmax); + jintArray returnValues = env->NewIntArray(2); + env->SetIntArrayRegion(returnValues, 0, 2, values); + ms_free(values); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); + return returnValues; } static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content){ @@ -3543,19 +3545,19 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent * jmethodID ctor; jstring jtype, jsubtype, jencoding; jbyteArray jdata=NULL; - + contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl")); ctor = env->GetMethodID(contentClass,"", "(Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;)V"); - + jtype=env->NewStringUTF(content->type); jsubtype=env->NewStringUTF(content->subtype); jencoding=content->encoding ? env->NewStringUTF(content->encoding) : NULL; - + if (content->data){ jdata=env->NewByteArray(content->size); env->SetByteArrayRegion(jdata,0,content->size,(jbyte*)content->data); } - + jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata,jencoding); env->DeleteGlobalRef(contentClass); return jobj; @@ -3581,7 +3583,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getCont */ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_setContent(JNIEnv *env, jobject jobj, jlong infoptr, jstring jtype, jstring jsubtype, jstring jdata){ LinphoneContent content={0}; - + content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); content.data=(void*)env->GetStringUTFChars(jdata,NULL); @@ -3629,7 +3631,7 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_delete(JNI JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreFactoryImpl__1setLogHandler(JNIEnv *env, jobject jfactory, jobject jhandler){ static int init_done=FALSE; - + if (!init_done){ handler_class=(jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneLogHandler")); loghandler_id=env->GetMethodID(handler_class,"log", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V"); @@ -3685,7 +3687,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; - + if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3693,9 +3695,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e content.data=(void*)env->GetByteArrayElements(jdata,NULL); content.size=env->GetArrayLength(jdata); } - + err=linphone_event_notify(ev,content.type ? &content : NULL); - + if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); @@ -3714,7 +3716,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; - + if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3722,9 +3724,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( content.data=(void*)env->GetByteArrayElements(jdata,NULL); content.size=env->GetArrayLength(jdata); } - + err=linphone_event_update_subscribe(ev,content.type ? &content : NULL); - + if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); @@ -3743,7 +3745,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; - + if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3751,9 +3753,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN content.data=(void*)env->GetByteArrayElements(jdata,NULL); content.size=env->GetArrayLength(jdata); } - + err=linphone_event_update_publish(ev,content.type ? &content : NULL); - + if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); From 1ffb06aecc3fd851b940e01f0346d87f5b59946c Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 May 2014 17:20:52 +0200 Subject: [PATCH 38/47] Enable detection of SQLite3 without PKG_CONFIG --- configure.ac | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index ba4ae31a0..676f7f98e 100644 --- a/configure.ac +++ b/configure.ac @@ -767,23 +767,31 @@ AC_ARG_ENABLE(msg-storage, [enable_msg_storage=auto] ) - AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue) + if test x$enable_msg_storage != xfalse; then - PKG_CHECK_MODULES(SQLITE3,[ sqlite3 >= 3.6.0],[ + PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no]) + if test "$found_sqlite" = "no"; then + dnl Check the lib presence in case the PKG-CONFIG version is not found + AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 " + found_sqlite=yes], + [AC_MSG_ERROR([No pkg-config or alternate SQLITE found, needed for message storage.])] + ) + fi + if test "$found_sqlite" = "yes"; then SQLITE3_CFLAGS+="-DMSG_STORAGE_ENABLED" - AC_SUBST(SQLITE3_CFLAGS) - AC_SUBST(SQLITE3_LIBS) - enable_msg_storage=true - ],[ - if test x$enable_msg_storage = xtrue; then - AC_MSG_ERROR([sqlite3 required for message storage not found.]) + else + if test x$enable_msg_storage = xtrue; then + AC_MSG_ERROR([sqlite3, required for message storage, not found]) + enable_msg_storage=false fi - enable_msg_storage=false - ] ) + fi + AC_SUBST(SQLITE3_CFLAGS) + AC_SUBST(SQLITE3_LIBS) fi + PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.3.1]) From 7eefcf399ff39b8805e38b3726a19dedc89c95eb Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 15 May 2014 18:07:13 +0200 Subject: [PATCH 39/47] add more test for invite without sdp --- tester/call_tester.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index fb9571205..81fcf787c 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -587,10 +587,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee return success; } -static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - +static void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) { if (callee_with_ice){ linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); linphone_core_set_stun_server(marie->lc,"stun.linphone.org"); @@ -624,14 +621,31 @@ static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); +} +static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + _call_with_ice_base(pauline,marie,caller_with_ice,callee_with_ice,random_ports); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } - static void call_with_ice(void){ _call_with_ice(TRUE,TRUE,FALSE); } +static void call_with_ice_no_sdp(void){ +#ifdef 0 + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + + linphone_core_enable_sdp_200_ack(pauline->lc,TRUE); + _call_with_ice_base(pauline,marie,TRUE,TRUE,FALSE); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +#endif +} + static void call_with_ice_random_ports(void){ _call_with_ice(TRUE,TRUE,TRUE); } @@ -909,9 +923,7 @@ static void call_with_declined_video(void) { linphone_core_manager_destroy(pauline); } -static void video_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie) { LinphoneCallParams* callee_params; LinphoneCallParams* caller_params; LinphoneCall* marie_call; @@ -946,6 +958,19 @@ static void video_call(void) { CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); } +} +static void video_call(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + video_call_base(marie,pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} +static void video_call_no_sdp(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + linphone_core_enable_sdp_200_ack(pauline->lc,TRUE); + video_call_base(pauline,marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -2122,6 +2147,7 @@ test_t call_tests[] = { { "SRTP call with declined srtp", call_with_declined_srtp }, #ifdef VIDEO_ENABLED { "Simple video call",video_call}, + { "Video call without SDP",video_call_no_sdp}, { "SRTP ice video call", srtp_video_ice_call }, { "ZRTP ice video call", zrtp_video_ice_call }, { "Call with video added", call_with_video_added }, @@ -2144,6 +2170,7 @@ test_t call_tests[] = { { "Unattended call transfer with error", unattended_call_transfer_with_error }, { "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call }, { "Call with ICE", call_with_ice }, + { "Call with ICE without SDP", call_with_ice_no_sdp }, { "Call with ICE (random ports)", call_with_ice_random_ports }, { "Call from ICE to not ICE",ice_to_not_ice}, { "Call from not ICE to ICE",not_ice_to_ice}, From 44bafb091aac9602e5b3a0e30b93801a93d61a7e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 15 May 2014 19:13:51 +0200 Subject: [PATCH 40/47] fix crash with ICE in case of no incoming SDP --- coreapi/linphonecall.c | 2 +- tester/call_tester.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 5202108b7..a424e4e4c 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -637,7 +637,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_call_init_media_streams(call); switch (linphone_core_get_firewall_policy(call->core)) { case LinphonePolicyUseIce: - linphone_call_prepare_ice(call,TRUE); + linphone_call_prepare_ice(call,md!=NULL); break; case LinphonePolicyUseStun: call->ping_time=linphone_core_run_stun_tests(call->core,call); diff --git a/tester/call_tester.c b/tester/call_tester.c index 81fcf787c..bbbc05f23 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -634,7 +634,6 @@ static void call_with_ice(void){ } static void call_with_ice_no_sdp(void){ -#ifdef 0 LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); @@ -643,7 +642,6 @@ static void call_with_ice_no_sdp(void){ linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); -#endif } static void call_with_ice_random_ports(void){ From a53e77b669594790116c7c40e74ae1d139c98858 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 16 May 2014 10:09:45 +0200 Subject: [PATCH 41/47] Update oRTP submodule for AVPF fixes. --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index c93363ac0..519fabfed 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit c93363ac023c2122bfdfb8b0d99b811dffbad827 +Subproject commit 519fabfed1b38c9cde977d4c7a8a7c2bb642e0cb From eb6462663a6116117a2b6a6ae92b80d672d94c54 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 16 May 2014 22:13:48 +0200 Subject: [PATCH 42/47] adapt to lastest belle-sip and fix bad naming of variables. --- coreapi/remote_provisioning.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c index 3eb848b71..8c57b47ef 100644 --- a/coreapi/remote_provisioning.c +++ b/coreapi/remote_provisioning.c @@ -84,11 +84,11 @@ static int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* static void belle_request_process_response_event(void *ctx, const belle_http_response_event_t *event) { LinphoneCore *lc = (LinphoneCore *)ctx; - belle_sip_message_t *body = BELLE_SIP_MESSAGE(event->response); - const char *message = belle_sip_message_get_body(body); + belle_sip_message_t *message = BELLE_SIP_MESSAGE(event->response); + const char *body = belle_sip_message_get_body(message); if (belle_http_response_get_status_code(event->response) == 200) { - linphone_remote_provisioning_apply(lc, message); + linphone_remote_provisioning_apply(lc, body); } else { linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "http error"); } @@ -118,14 +118,17 @@ int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char return linphone_remote_provisioning_load_file(lc, file_path); } else { belle_generic_uri_t *uri=belle_generic_uri_parse(remote_provisioning_uri); - belle_http_request_listener_callbacks_t belle_request_listener = { - belle_request_process_response_event, - belle_request_process_io_error, - belle_request_process_timeout, - belle_request_process_auth_requested - }; - belle_http_request_listener_t *listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc); + belle_http_request_listener_callbacks_t belle_request_listener={0}; + belle_http_request_listener_t *listener; belle_http_request_t *request; + + belle_request_listener.process_response=belle_request_process_response_event; + belle_request_listener.process_auth_requested=belle_request_process_auth_requested; + belle_request_listener.process_io_error=belle_request_process_io_error; + belle_request_listener.process_timeout=belle_request_process_timeout; + + listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc); + if (uri==NULL) { belle_sip_error("Invalid provisioning URI [%s]",remote_provisioning_uri); From a6aa0a50a5266911780ad5cbd995d057673ac452 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 16 May 2014 22:29:46 +0200 Subject: [PATCH 43/47] fix ICE call without SDP test --- coreapi/linphonecall.c | 17 ++++++++++++----- mediastreamer2 | 2 +- tester/call_tester.c | 12 +++++++++++- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index a424e4e4c..27ce04a3a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -583,6 +583,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro LinphoneCall *call=ms_new0(LinphoneCall,1); char *from_str; const SalMediaDescription *md; + LinphoneFirewallPolicy fpol; call->dir=LinphoneCallIncoming; sal_op_set_user_pointer(op,call); @@ -628,16 +629,22 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro // In this case WE chose the media parameters according to policy. call->params.has_video &= linphone_core_media_description_contains_video_stream(md); } + fpol=linphone_core_get_firewall_policy(call->core); /*create the ice session now if ICE is required*/ - if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseIce){ - call->ice_session = ice_session_new(); - ice_session_set_role(call->ice_session, IR_Controlled); + if (fpol==LinphonePolicyUseIce){ + if (md){ + call->ice_session = ice_session_new(); + ice_session_set_role(call->ice_session, IR_Controlled); + }else{ + fpol=LinphonePolicyNoFirewall; + ms_warning("ICE not supported for incoming INVITE without SDP."); + } } /*reserve the sockets immediately*/ linphone_call_init_media_streams(call); - switch (linphone_core_get_firewall_policy(call->core)) { + switch (fpol) { case LinphonePolicyUseIce: - linphone_call_prepare_ice(call,md!=NULL); + linphone_call_prepare_ice(call,TRUE); break; case LinphonePolicyUseStun: call->ping_time=linphone_core_run_stun_tests(call->core,call); diff --git a/mediastreamer2 b/mediastreamer2 index 79c18b751..ae94af9ab 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 79c18b75112262460fff45493e70733a2c35333c +Subproject commit ae94af9abbfb56bedcd37485bc38934ebbbc9c87 diff --git a/tester/call_tester.c b/tester/call_tester.c index bbbc05f23..d20cf1fd6 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -633,12 +633,22 @@ static void call_with_ice(void){ _call_with_ice(TRUE,TRUE,FALSE); } +/*ICE is not expected to work in this case, however this should not crash*/ static void call_with_ice_no_sdp(void){ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); linphone_core_enable_sdp_200_ack(pauline->lc,TRUE); - _call_with_ice_base(pauline,marie,TRUE,TRUE,FALSE); + + linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(marie->lc,"stun.linphone.org"); + + linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(pauline->lc,"stun.linphone.org"); + + call(pauline,marie); + + liblinphone_tester_check_rtcp(marie,pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); From e7a1d7f52cbc3400e0117e89fc362e589fccd641 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Mon, 19 May 2014 10:46:42 +0200 Subject: [PATCH 44/47] Fix configure.ac to allow message_storage=auto --- configure.ac | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 676f7f98e..b3c66dc98 100644 --- a/configure.ac +++ b/configure.ac @@ -773,18 +773,15 @@ if test x$enable_msg_storage != xfalse; then PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no]) if test "$found_sqlite" = "no"; then dnl Check the lib presence in case the PKG-CONFIG version is not found - AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 " - found_sqlite=yes], - [AC_MSG_ERROR([No pkg-config or alternate SQLITE found, needed for message storage.])] - ) + AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 "; found_sqlite=yes], [foo=bar]) fi if test "$found_sqlite" = "yes"; then SQLITE3_CFLAGS+="-DMSG_STORAGE_ENABLED" else if test x$enable_msg_storage = xtrue; then AC_MSG_ERROR([sqlite3, required for message storage, not found]) - enable_msg_storage=false fi + enable_msg_storage=false fi AC_SUBST(SQLITE3_CFLAGS) From 0e7ef89a6b9f015a5a05f8a6b2674218121c3af0 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 19 May 2014 11:44:07 +0200 Subject: [PATCH 45/47] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index ae94af9ab..77022250a 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ae94af9abbfb56bedcd37485bc38934ebbbc9c87 +Subproject commit 77022250a04459648101c3b4152d83158bbe0e63 From 4a2bb40b1b13c9aa299c3dea74952721c21fd5ac Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 May 2014 11:15:55 +0200 Subject: [PATCH 46/47] Upcase SQL statements for reading convenience --- coreapi/message_storage.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index c7cc86e71..c46980d57 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -149,7 +149,7 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){ char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room)); char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg)); char datebuf[26]; - char *buf=sqlite3_mprintf("insert into history values(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q);", + char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q);", local_contact,peer,msg->dir,msg->message,my_ctime_r(&msg->time,datebuf),msg->is_read,msg->state,msg->external_body_url); linphone_sql_request(lc->db,buf); sqlite3_free(buf); @@ -164,7 +164,7 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg){ LinphoneCore *lc=msg->chat_room->lc; if (lc->db){ char time_str[26]; - char *buf=sqlite3_mprintf("update history set status=%i where message = %Q and time = %Q;", + char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE message = %Q AND time = %Q;", msg->state,msg->message,my_ctime_r(&msg->time,time_str)); linphone_sql_request(lc->db,buf); sqlite3_free(buf); @@ -187,7 +187,7 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ if (lc->db==NULL) return ; char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); - char *buf=sqlite3_mprintf("update history set read=%i where remoteContact = %Q;", + char *buf=sqlite3_mprintf("UPDATE history SET read=%i WHERE remoteContact = %Q;", read,peer); linphone_sql_request(lc->db,buf); sqlite3_free(buf); @@ -199,7 +199,7 @@ void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *ms if (lc->db==NULL) return ; - char *buf=sqlite3_mprintf("update history set url=%Q where id=%i;",msg->external_body_url,msg->storage_id); + char *buf=sqlite3_mprintf("UPDATE history SET url=%Q WHERE id=%i;",msg->external_body_url,msg->storage_id); linphone_sql_request(lc->db,buf); sqlite3_free(buf); } @@ -211,7 +211,7 @@ int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ if (lc->db==NULL) return 0; char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); - char *buf=sqlite3_mprintf("select count(*) from history where remoteContact = %Q and read = 0;",peer); + char *buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q AND read = 0;",peer); sqlite3_stmt *selectStatement; int returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL); if (returnValue == SQLITE_OK){ @@ -230,7 +230,7 @@ void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage if (lc->db==NULL) return ; - char *buf=sqlite3_mprintf("delete from history where id = %i;", msg->storage_id); + char *buf=sqlite3_mprintf("DELETE FROM history WHERE id = %i;", msg->storage_id); linphone_sql_request(lc->db,buf); sqlite3_free(buf); } @@ -241,7 +241,7 @@ void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ if (lc->db==NULL) return ; char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); - char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",peer); + char *buf=sqlite3_mprintf("DELETE FROM history WHERE remoteContact = %Q;",peer); linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(peer); @@ -257,9 +257,9 @@ MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); cr->messages_hist = NULL; if (nb_message > 0) - buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC limit %i ;",peer,nb_message); + buf=sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC LIMIT %i ;",peer,nb_message); else - buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC;",peer); + buf=sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC;",peer); linphone_sql_request_message(lc->db,buf,cr); sqlite3_free(buf); ret=cr->messages_hist; @@ -275,7 +275,7 @@ void linphone_close_storage(sqlite3* db){ void linphone_create_table(sqlite3* db){ char* errmsg=NULL; int ret; - ret=sqlite3_exec(db,"CREATE TABLE if not exists history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);", + ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);", 0,0,&errmsg); if(ret != SQLITE_OK) { ms_error("Error in creation: %s.\n", errmsg); @@ -299,7 +299,7 @@ void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) { char *buf; if (lc->db==NULL) return; - buf=sqlite3_mprintf("SELECT remoteContact FROM history Group By remoteContact;"); + buf=sqlite3_mprintf("SELECT remoteContact FROM history GROUP BY remoteContact;"); linphone_sql_request_all(lc->db,buf,lc); sqlite3_free(buf); } From d491197c914e8921339c7893ddfab0fb46f3a323 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Mon, 19 May 2014 14:12:35 +0200 Subject: [PATCH 47/47] Switch to UTC timestamp storage for messages, instead of string-based local timezone time. Migration procedure included. --- coreapi/message_storage.c | 126 +++++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 28 deletions(-) diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index c46980d57..434b7e484 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -35,10 +35,6 @@ static inline char *my_ctime_r(const time_t *t, char *buf){ #include "sqlite3.h" -static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; -static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; - - static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){ MSList* transients = cr->transient_messages; LinphoneChatMessage* chat; @@ -55,9 +51,7 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u static void create_chat_message(char **argv, void *data){ LinphoneChatRoom *cr = (LinphoneChatRoom *)data; LinphoneAddress *from; - struct tm ret={0}; - char tmp1[80]={0}; - char tmp2[80]={0}; + unsigned int storage_id = atoi(argv[0]); // check if the message exists in the transient list, in which case we should return that one. @@ -75,20 +69,12 @@ static void create_chat_message(char **argv, void *data){ linphone_chat_message_set_from(new_message,from); linphone_address_destroy(from); - if(argv[5]!=NULL){ - int i,j; - sscanf(argv[5],"%3c %3c%d%d:%d:%d %d",tmp1,tmp2,&ret.tm_mday, - &ret.tm_hour,&ret.tm_min,&ret.tm_sec,&ret.tm_year); - ret.tm_year-=1900; - for(i=0;i<7;i++) { - if(strcmp(tmp1,days[i])==0) ret.tm_wday=i; - } - for(j=0;j<12;j++) { - if(strcmp(tmp2,months[j])==0) ret.tm_mon=j; - } - ret.tm_isdst=-1; + if( argv[9] != NULL ){ + new_message->time = (time_t)atol(argv[9]); + } else { + new_message->time = time(NULL); } - new_message->time=argv[5]!=NULL ? mktime(&ret) : time(NULL); + new_message->is_read=atoi(argv[6]); new_message->state=atoi(argv[7]); new_message->storage_id=storage_id; @@ -148,9 +134,16 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){ if (lc->db){ char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room)); char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg)); - char datebuf[26]; - char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q);", - local_contact,peer,msg->dir,msg->message,my_ctime_r(&msg->time,datebuf),msg->is_read,msg->state,msg->external_body_url); + char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i);", + local_contact, + peer, + msg->dir, + msg->message, + "-1", /* use UTC field now */ + msg->is_read, + msg->state, + msg->external_body_url, + msg->time); linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(local_contact); @@ -163,9 +156,8 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){ void linphone_chat_message_store_state(LinphoneChatMessage *msg){ LinphoneCore *lc=msg->chat_room->lc; if (lc->db){ - char time_str[26]; - char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE message = %Q AND time = %Q;", - msg->state,msg->message,my_ctime_r(&msg->time,time_str)); + char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE message = %Q AND utc = %i;", + msg->state,msg->message,msg->time); linphone_sql_request(lc->db,buf); sqlite3_free(buf); @@ -275,7 +267,16 @@ void linphone_close_storage(sqlite3* db){ void linphone_create_table(sqlite3* db){ char* errmsg=NULL; int ret; - ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);", + ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS history (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "localContact TEXT NOT NULL," + "remoteContact TEXT NOT NULL," + "direction INTEGER," + "message TEXT," + "time TEXT NOT NULL," + "read INTEGER," + "status INTEGER" + ");", 0,0,&errmsg); if(ret != SQLITE_OK) { ms_error("Error in creation: %s.\n", errmsg); @@ -283,16 +284,85 @@ void linphone_create_table(sqlite3* db){ } } + +static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; +static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; +static time_t parse_time_from_db( const char* time ){ + /* messages used to be stored in the DB by using string-based time */ + struct tm ret={0}; + char tmp1[80]={0}; + char tmp2[80]={0}; + int i,j; + time_t parsed = 0; + + if( sscanf(time,"%3c %3c%d%d:%d:%d %d",tmp1,tmp2,&ret.tm_mday, + &ret.tm_hour,&ret.tm_min,&ret.tm_sec,&ret.tm_year) == 7 ){ + ret.tm_year-=1900; + for(i=0;i<7;i++) { + if(strcmp(tmp1,days[i])==0) ret.tm_wday=i; + } + for(j=0;j<12;j++) { + if(strcmp(tmp2,months[j])==0) ret.tm_mon=j; + } + ret.tm_isdst=-1; + parsed = mktime(&ret); + } + return parsed; +} + + +static int migrate_messages(void* data,int argc, char** argv, char** column_names) { + time_t new_time = parse_time_from_db(argv[1]); + if( new_time ){ + /* replace 'time' by -1 and set 'utc' to the timestamp */ + char *buf = sqlite3_mprintf("UPDATE history SET utc=%i,time='-1' WHERE id=%i", new_time, atoi(argv[0])); + if( buf) { + linphone_sql_request((sqlite3*)data, buf); + sqlite3_free(buf); + } + } else { + printf("Cannot parse time %s from id %s", argv[1], argv[0]); + } + return 0; +} + +static void linphone_migrate_timestamps(sqlite3* db){ + int ret; + char* errmsg = NULL; + + ret = sqlite3_exec(db,"SELECT id,time,direction FROM history WHERE time != '-1'", migrate_messages, db, &errmsg); + if( ret != SQLITE_OK ){ + printf("Error migrating outgoing messages: %s.\n", errmsg); + sqlite3_free(errmsg); + } else { + printf("Migrated message timestamps to UTC\n"); + } +} + void linphone_update_table(sqlite3* db) { char* errmsg=NULL; int ret; + + // for image url storage ret=sqlite3_exec(db,"ALTER TABLE history ADD COLUMN url TEXT;",NULL,NULL,&errmsg); if(ret != SQLITE_OK) { ms_warning("Table already up to date: %s.\n", errmsg); sqlite3_free(errmsg); } else { - ms_debug("Table updated successfuly."); + ms_debug("Table updated successfully for URL."); } + + // for UTC timestamp storage + ret = sqlite3_exec(db, "ALTER TABLE history ADD COLUMN utc INTEGER;", NULL,NULL,&errmsg); + if( ret != SQLITE_OK ){ + ms_warning("Table already up to date: %s.\n", errmsg); + sqlite3_free(errmsg); + } else { + ms_debug("Table updated successfully for UTC."); + } + + // migrate from old text-based timestamps to unix time-based timestamps + linphone_migrate_timestamps(db); } void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) {