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); }
/* * 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; }