int sal_call_refer(SalOp *op, const char *refer_to){ belle_sip_header_address_t *referred_by; belle_sip_header_refer_to_t* refer_to_header; if (op->dialog) { referred_by=(belle_sip_header_address_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_dialog_get_local_party(op->dialog))); }else{ referred_by=BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op)); } refer_to_header=belle_sip_header_refer_to_create(belle_sip_header_address_parse(refer_to)); return sal_call_refer_to(op,refer_to_header,belle_sip_header_referred_by_create(referred_by)); }
int sal_call_refer_with_replaces(SalOp *op, SalOp *other_call_op){ belle_sip_dialog_state_t other_call_dialog_state=other_call_op->dialog?belle_sip_dialog_get_state(other_call_op->dialog):BELLE_SIP_DIALOG_NULL; belle_sip_dialog_state_t op_dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; belle_sip_header_replaces_t* replaces; belle_sip_header_refer_to_t* refer_to; belle_sip_header_referred_by_t* referred_by; const char* from_tag; const char* to_tag; char* escaped_replaces; /*first, build refer to*/ if ((other_call_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) && (other_call_dialog_state!=BELLE_SIP_DIALOG_EARLY)) { ms_error("wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED or BELE_SIP_DIALOG_EARLY", belle_sip_dialog_state_to_string(other_call_dialog_state), other_call_op); return -1; } if (op_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) { ms_error("wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED", belle_sip_dialog_state_to_string(op_dialog_state), op); return -1; } refer_to=belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->dialog)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(refer_to)); /*rfc3891 ... 4. User Agent Client Behavior: Sending a Replaces Header A User Agent that wishes to replace a single existing early or confirmed dialog with a new dialog of its own, MAY send the target User Agent an INVITE request containing a Replaces header field. The User Agent Client (UAC) places the Call-ID, to-tag, and from-tag information for the target dialog in a single Replaces header field and sends the new INVITE to the target.*/ from_tag=belle_sip_dialog_get_local_tag(other_call_op->dialog); to_tag=belle_sip_dialog_get_remote_tag(other_call_op->dialog); replaces=belle_sip_header_replaces_create(belle_sip_header_call_id_get_call_id(belle_sip_dialog_get_call_id(other_call_op->dialog)) ,from_tag,to_tag); escaped_replaces=belle_sip_header_replaces_value_to_escaped_string(replaces); belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)),"Replaces",escaped_replaces); belle_sip_free(escaped_replaces); referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(op->dialog)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(referred_by)); return sal_call_refer_to(op,refer_to,referred_by); }
int sal_call_refer_with_replaces(SalOp *op, SalOp *other_call_op){ belle_sip_dialog_state_t other_call_dialog_state=other_call_op->dialog?belle_sip_dialog_get_state(other_call_op->dialog):BELLE_SIP_DIALOG_NULL; belle_sip_dialog_state_t op_dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; belle_sip_header_replaces_t* replaces; belle_sip_header_refer_to_t* refer_to; belle_sip_header_referred_by_t* referred_by; const char* from_tag; const char* to_tag; char* escaped_replaces; /*first, build refer to*/ if (other_call_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) { ms_error(" wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED",belle_sip_dialog_state_to_string(other_call_dialog_state) ,other_call_op); return -1; } if (op_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) { ms_error(" wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED",belle_sip_dialog_state_to_string(op_dialog_state) ,op); return -1; } refer_to=belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->dialog)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(refer_to)); if (belle_sip_dialog_is_server(other_call_op->dialog)) { to_tag=belle_sip_dialog_get_local_tag(other_call_op->dialog); from_tag=belle_sip_dialog_get_remote_tag(other_call_op->dialog);; } else { from_tag=belle_sip_dialog_get_local_tag(other_call_op->dialog); to_tag=belle_sip_dialog_get_remote_tag(other_call_op->dialog);; } replaces=belle_sip_header_replaces_create(belle_sip_header_call_id_get_call_id(belle_sip_dialog_get_call_id(other_call_op->dialog)) ,from_tag,to_tag); escaped_replaces=belle_sip_header_replaces_value_to_escaped_string(replaces); belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)),"Replaces",escaped_replaces); belle_sip_free(escaped_replaces); referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(op->dialog)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(referred_by)); return sal_call_refer_to(op,refer_to,referred_by); }