Commit 5d566fcc authored by Benjamin REIS's avatar Benjamin REIS

Add reason header to CANCEL and add tests for reason headers

parent 685cb1f0
......@@ -217,31 +217,12 @@ static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
if (op->base.local_media) sdp_process(op);
}
void sal_call_cancel_invite(SalOp* op) {
belle_sip_request_t* cancel;
ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
if (cancel){
sal_op_send_request(op,cancel);
}else if (op->dialog){
belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);;
/*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
* because already terminated*/
switch(state){
case BELLE_SIP_DIALOG_EARLY:
case BELLE_SIP_DIALOG_NULL:
/*force kill the dialog*/
ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
belle_sip_dialog_delete(op->dialog);
break;
default:
break;
}
}
void sal_call_cancel_invite(SalOp *op) {
sal_call_cancel_invite_with_info(op,NULL);
}
static void cancelling_invite(SalOp *op) {
sal_call_cancel_invite(op);
static void cancelling_invite(SalOp *op, const SalErrorInfo *info) {
sal_call_cancel_invite_with_info(op, info);
op->state=SalOpStateTerminating;
}
......@@ -284,7 +265,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
/*it wasn't sent */
if (code<200) {
cancelling_invite(op);
cancelling_invite(op, NULL);
}else{
/* no need to send the INVITE because the UAS rejected the INVITE*/
if (op->dialog==NULL) call_set_released(op);
......@@ -441,12 +422,13 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
if (release_call) call_set_released(op);
}
static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, belle_sip_request_t* request,int status_code) {
static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request) {
belle_sip_response_t* resp;
belle_sip_request_t* server_req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction));
op->state = SalOpStateTerminating;
op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
sal_op_set_reason_error_info(op, BELLE_SIP_MESSAGE(request));
resp=sal_op_create_response_from_request(op,request,status_code);
sal_op_set_reason_error_info(op, BELLE_SIP_MESSAGE(cancel_request ? cancel_request : server_req));
resp=sal_op_create_response_from_request(op,server_req,status_code);
belle_sip_server_transaction_send_response(server_transaction,resp);
}
......@@ -623,11 +605,7 @@ 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,200));
/*terminate invite transaction*/
call_terminated(op
,op->pending_server_trans
,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),487);
call_terminated(op,op->pending_server_trans,487,req);
} else {
/*call leg does not exist*/
belle_sip_server_transaction_send_response(server_transaction
......@@ -671,7 +649,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
ms_message("Ignored received ack since a new client transaction has been started since.");
}
} else if(strcmp("BYE",method)==0) {
call_terminated(op,server_transaction,req,200);
call_terminated(op,server_transaction,200,req);
/*call end not notified by dialog deletion because transaction can end before dialog*/
} else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) {
if (is_update && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) {
......@@ -957,6 +935,33 @@ static belle_sip_header_reason_t *sal_call_make_reason_header( const SalErrorInf
return NULL;
}
void sal_call_cancel_invite_with_info(SalOp* op, const SalErrorInfo *info) {
belle_sip_request_t* cancel;
ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
if (cancel){
if (info != NULL){
belle_sip_header_reason_t* reason = sal_call_make_reason_header(info);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(cancel),BELLE_SIP_HEADER(reason));
}
sal_op_send_request(op,cancel);
}else if (op->dialog){
belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);;
/*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
* because already terminated*/
switch(state){
case BELLE_SIP_DIALOG_EARLY:
case BELLE_SIP_DIALOG_NULL:
/*force kill the dialog*/
ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
belle_sip_dialog_delete(op->dialog);
break;
default:
break;
}
}
}
int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*optional*/){
belle_sip_response_t* response;
belle_sip_header_contact_t* contact=NULL;
......@@ -1123,7 +1128,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){
op->state=SalOpStateTerminated;
} else if (op->pending_client_trans){
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){
cancelling_invite(op);
cancelling_invite(op, p_sei);
}else{
/* Case where the CANCEL cannot be sent because no provisional response was received so far.
* The Op must be kept for the time of the transaction in case a response is received later.
......@@ -1139,7 +1144,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){
sal_call_decline_with_error_info(op, p_sei,NULL);
op->state=SalOpStateTerminated;
} else {
cancelling_invite(op);
cancelling_invite(op, p_sei);
}
break;
}
......
......@@ -850,9 +850,11 @@ static void call_terminated(SalOp *op, const char *from){
break;
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
linphone_error_info_set(call->ei,NULL, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL);
call->non_op_error = TRUE;
break;
if(sal_op_get_reason_error_info(op)->reason != SalReasonNone) {
linphone_error_info_set(call->ei,NULL, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL);
call->non_op_error = TRUE;
}
break;
default:
break;
}
......
......@@ -750,6 +750,7 @@ int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optio
int sal_call_decline_with_error_info(SalOp *h, const SalErrorInfo* info, const char *redirection /*optional*/);
int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent);
void sal_call_cancel_invite(SalOp *op);
void sal_call_cancel_invite_with_info(SalOp* op, const SalErrorInfo *info);
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h);
LINPHONE_PUBLIC SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
int sal_call_refer(SalOp *h, const char *refer_to);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment