From a4c096e7a4c3d8228c2e34837b6dc21dbcd69642 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 8 Feb 2013 18:11:13 +0100 Subject: [PATCH] implement vfu request --- coreapi/bellesip_sal/sal_impl.c | 6 ++-- coreapi/bellesip_sal/sal_op_call.c | 52 ++++++++++++++++++++++++--- tester/call_tester.c | 57 +++++++++++++++++++++++++++++- tester/liblinphone_tester.h | 2 ++ 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index c7705138f..c2238216b 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -161,9 +161,11 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev ,belle_sip_header_cseq_get_seq_number(cseq)); salmsg.from=from; salmsg.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); - salmsg.url=NULL; /*not implemented yet*/ + salmsg.url=NULL; /*FIXME not implemented yet*/ salmsg.message_id=message_id; - ((Sal*)sal)->callbacks.text_received((Sal*)sal,&salmsg); + op=sal_op_new((Sal*)sal); + ((Sal*)sal)->callbacks.text_received(op,&salmsg); + sal_op_release(op); belle_sip_object_unref(address); belle_sip_free(from); return; diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 60272addd..984881592 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -117,17 +117,22 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t SalOp* op = (SalOp*)op_base; belle_sip_request_t* ack; belle_sip_dialog_state_t dialog_state; - /*belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);*/ + belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); belle_sip_response_t* response=belle_sip_response_event_get_response(event); int code = belle_sip_response_get_status_code(response); char* reason; SalError error=SalErrorUnknown; SalReason sr=SalReasonUnknown; belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason"); + if (!client_transaction) { + ms_warning("Discarding state less response [%i] on op [%p]",code,op); + return; + } reason=(char*)belle_sip_response_get_reason_phrase(response); if (reason_header){ reason = ms_strdup_printf("%s %s",reason,belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(reason_header))); } + /*FIXME should be limited to early/NULL dialog*/ if (code >=400) { sal_compute_sal_errors_from_code(code,&error,&sr); op->base.root->callbacks.call_failure(op,error,sr,reason,code); @@ -177,7 +182,9 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t switch (op->state) { case SalOpStateEarly:/*invite case*/ case SalOpStateActive: /*re-invite case*/ - if (code >=200) { + if (code >=200 + && code<300 + && strcmp("INVITE",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction))))==0) { handle_sdp_from_response(op,response); ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog)); if (ack==NULL) { @@ -193,6 +200,8 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t /*if (op->state != SalOpStateActive)*/ op->base.root->callbacks.call_accepted(op); op->state=SalOpStateActive; + } else { + /*nop*/ } break; @@ -349,7 +358,18 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t process_sdp_for_invite(op,req); op->base.root->callbacks.call_updating(op); - } else { + } else if (strcmp("INFO",belle_sip_request_get_method(req))==0 + && belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)) + && strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) { + /*vfu request*/ + ms_message("Receiving VFU request on op [%p]",op); + if (op->base.root->callbacks.vfu_request){ + op->base.root->callbacks.vfu_request(op); + + } + resp=belle_sip_response_create_from_request(req,200); + belle_sip_server_transaction_send_response(server_transaction,resp); + }else{ ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); unsupported_method(server_transaction,req); } @@ -599,8 +619,30 @@ int sal_call_terminate(SalOp *op){ bool_t sal_call_autoanswer_asked(SalOp *op){ return op->auto_answer_asked; } -void sal_call_send_vfu_request(SalOp *h){ - ms_fatal("sal_call_send_vfu_request not implemented yet"); +void sal_call_send_vfu_request(SalOp *op){ + char info_body[] = + "" + "" + " " + " " + " " + " " + " " + ""; + size_t content_lenth = sizeof(info_body) - 1; + belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; /*no dialog = dialog in NULL state*/ + if (dialog_state == BELLE_SIP_DIALOG_CONFIRMED) { + belle_sip_request_t* info = belle_sip_dialog_create_request(op->dialog,"INFO"); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(info),BELLE_SIP_HEADER(belle_sip_header_content_type_create("application","media_control+xml"))); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(info),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_lenth))); + belle_sip_message_set_body(BELLE_SIP_MESSAGE(info),info_body,content_lenth); + sal_op_send_request(op,info); + } else { + ms_warning("Cannot send vfu request to [%s] because dialog [%p] in wrong state [%s]",sal_op_get_to(op) + ,op->dialog + ,belle_sip_dialog_state_to_string(dialog_state)); + } + return ; } int sal_call_is_offerer(const SalOp *h){ diff --git a/tester/call_tester.c b/tester/call_tester.c index d0a083037..bc9a75b98 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -61,6 +61,16 @@ void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState } } +static void linphone_call_cb(LinphoneCall *call,void * user_data) { + char* to=linphone_address_as_string(linphone_call_get_call_log(call)->to); + char* from=linphone_address_as_string(linphone_call_get_call_log(call)->from); + LinphoneCore* lc=(LinphoneCore*)user_data; + ms_message("call from [%s] to [%s] receive iFrame",from,to); + ms_free(to); + ms_free(from); + stats* counters = (stats*)linphone_core_get_user_data(lc); + counters->number_of_IframeDecoded++; +} static bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) { LinphoneProxyConfig* proxy; linphone_core_get_default_proxy(callee_mgr->lc,&proxy); @@ -262,6 +272,49 @@ static void call_paused_resumed_from_callee() { linphone_core_manager_destroy(pauline); } +static void call_with_video_added() { + LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new("./tester/pauline_rc"); + LinphoneCall* call_obj; + LinphoneVideoPolicy pauline_policy; + pauline_policy.automatically_accept=TRUE; + pauline_policy.automatically_initiate=TRUE; + LinphoneCallParams* marie_params; + + CU_ASSERT_TRUE(call(pauline,marie)); + + linphone_core_enable_video(marie->lc,TRUE,TRUE); + linphone_core_enable_video(pauline->lc,TRUE,FALSE); + linphone_core_set_video_policy(pauline->lc,&pauline_policy); + + call_obj = linphone_core_get_current_call(marie->lc); + marie_params = linphone_call_params_copy(linphone_call_get_current_params(call_obj)); + /*add video*/ + linphone_call_params_enable_video(marie_params,TRUE); + linphone_core_update_call(marie->lc,call_obj,marie_params); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdatedByRemote,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallUpdating,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + + CU_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)))); + CU_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)))); + + linphone_call_set_next_video_frame_decoded_callback(call_obj,linphone_call_cb,marie->lc); + /*send vfu*/ + linphone_call_send_vfu_request(call_obj); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_IframeDecoded,1)); + + /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); + 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)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void call_srtp() { LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc"); @@ -331,7 +384,9 @@ int call_test_suite () { if (NULL == CU_add_test(pSuite, "call_srtp", call_srtp)) { return CU_get_error(); } - + if (NULL == CU_add_test(pSuite, "call_with_video_added", call_with_video_added)) { + return CU_get_error(); + } return 0; } diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 03ab11b61..9f1bc97f2 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -60,6 +60,8 @@ typedef struct _stats { int number_of_NewSubscriptionRequest; int number_of_NotifyReceived; + + int number_of_IframeDecoded; }stats; typedef struct _LinphoneCoreManager { LinphoneCoreVTable v_table;