示例#1
0
void sal_op_kill_dialog(SalOp *op) {
	ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
	belle_sip_dialog_delete(op->dialog);
}
示例#2
0
文件: dialog.c 项目: natib/belle-sip
/*
 * return 0 if message should be delivered to the next listener, otherwise, its a retransmision, just keep it
 * */
int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* transaction, int as_uas){
	int is_retransmition=FALSE;
	int delete_dialog=FALSE;
	belle_sip_request_t *req=belle_sip_transaction_get_request(transaction);
	belle_sip_response_t *resp=belle_sip_transaction_get_response(transaction);
	int code=-1;

	belle_sip_message("Dialog [%p]: now updated by transaction [%p].",obj, transaction);
	
	belle_sip_object_ref(transaction);
	if (obj->last_transaction) belle_sip_object_unref(obj->last_transaction);
	obj->last_transaction=transaction;
	
	if (!as_uas){
		belle_sip_header_privacy_t *privacy_header=belle_sip_message_get_header_by_type(req,belle_sip_header_privacy_t);
		SET_OBJECT_PROPERTY(obj,privacy,privacy_header);
	}
	
	if (!resp)
		return 0;


	/*first update local/remote cseq*/
	if (as_uas) {
		belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_cseq_t);
		obj->remote_cseq=belle_sip_header_cseq_get_seq_number(cseq);
	}

	code=belle_sip_response_get_status_code(resp);
	switch (obj->state){
		case BELLE_SIP_DIALOG_NULL:
			/*alway establish a dialog*/
			if (code>100 && code<300 && (strcmp(belle_sip_request_get_method(req),"INVITE")==0 || strcmp(belle_sip_request_get_method(req),"SUBSCRIBE")==0)) {
				belle_sip_dialog_establish(obj,req,resp);
				if (code<200){
					set_state(obj,BELLE_SIP_DIALOG_EARLY);
					break;
				}/* no break  for code >200 because need to call belle_sip_dialog_establish_full*/
			}/* no break*/
		case BELLE_SIP_DIALOG_EARLY:
			/*don't terminate dialog for UPDATE*/
			if (code>=300 && (strcmp(belle_sip_request_get_method(req),"INVITE")==0 || strcmp(belle_sip_request_get_method(req),"SUBSCRIBE")==0)) {
				/*12.3 Termination of a Dialog
			   	   Independent of the method, if a request outside of a dialog generates
			   	   a non-2xx final response, any early dialogs created through
			   	   provisional responses to that request are terminated.  The mechanism
			   	   for terminating confirmed dialogs is method specific.*/
					belle_sip_dialog_delete(obj);
					break;
			}
			if (code>=200 && code<300 && (strcmp(belle_sip_request_get_method(req),"INVITE")==0 || strcmp(belle_sip_request_get_method(req),"SUBSCRIBE")==0))
				belle_sip_dialog_establish_full(obj,req,resp);
			break;
		case BELLE_SIP_DIALOG_CONFIRMED:
			code=belle_sip_response_get_status_code(resp);
			if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
				if (code>=200 && code<300){
					/*refresh the remote_target*/
					belle_sip_header_contact_t *ct;
					if (as_uas){
						ct=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);

					}else{
						set_last_out_invite(obj,req);
						ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
					}
					if (ct){
						belle_sip_object_unref(obj->remote_target);
						obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);
					}
					/*handle possible retransmission of 200Ok */
					if (!as_uas && (is_retransmition=(belle_sip_dialog_handle_200Ok(obj,resp)==0))) {
						return is_retransmition;
					} else {
						obj->needs_ack=TRUE; /*REINVITE case, ack needed by both uas and uac*/
					}
				}else if (code>=300){
					/*final response, ack will be automatically sent by transaction layer*/
					obj->needs_ack=FALSE;
				}
			} else if (strcmp(belle_sip_request_get_method(req),"BYE")==0 && (/*(*/code>=200 /*&& code<300) || code==481 || code==408*/)){
				/*15.1.1 UAC Behavior

				   A BYE request is constructed as would any other request within a
				   dialog, as described in Section 12.

				   Once the BYE is constructed, the UAC core creates a new non-INVITE
				   client transaction, and passes it the BYE request.  The UAC MUST
				   consider the session terminated (and therefore stop sending or
				   listening for media) as soon as the BYE request is passed to the
				   client transaction.  If the response for the BYE is a 481
				   (Call/Transaction Does Not Exist) or a 408 (Request Timeout) or no
				   response at all is received for the BYE (that is, a timeout is
				   returned by the client transaction), the UAC MUST consider the
				   session and the dialog terminated. */
				/*what should we do with other reponse >300 ?? */
				obj->needs_ack=FALSE; /*no longuer need ACK*/
				if (obj->terminate_on_bye) delete_dialog=TRUE;
			}
		break;
		case BELLE_SIP_DIALOG_TERMINATED:
			/*ignore*/
		break;
	}
	if (delete_dialog) belle_sip_dialog_delete(obj);
	else {
		belle_sip_dialog_process_queue(obj);
	}
	return 0;
}