FreeCalypso > hg > themwi-system-sw
view sip-in/bye_out.c @ 123:a36b731bfef9
sip-manual-out: implement sending BYE and CANCEL
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 29 Sep 2022 17:21:11 -0800 |
parents | c1c94b7fc2e2 |
children | 4e16aeafbfbf |
line wrap: on
line source
/* * In this module we implement our UAC functionality of sending BYE. */ #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <syslog.h> #include "../libsip/parse.h" #include "../libsip/resp_ident.h" #include "../libsip/out_msg.h" #include "call.h" extern struct call *find_call_by_sip_id(); extern struct in_addr sip_bind_ip; extern unsigned sip_bind_port; extern unsigned max_forwards; extern unsigned sip_linger_acked; extern unsigned sip_linger_error; fill_bye_out_msg(msg, call) struct sip_msg_out *msg; struct call *call; { char strbuf[80]; int rc; rc = start_request_out_msg_urilen(msg, "BYE", call->from_uri, call->from_uri_len); if (rc < 0) return rc; sprintf(strbuf, "SIP/2.0/UDP %s:%u", inet_ntoa(sip_bind_ip), sip_bind_port); rc = out_msg_add_header(msg, "Via", strbuf); if (rc < 0) return rc; rc = out_msg_add_header(msg, "From", call->invite_to); if (rc < 0) return rc; rc = out_msg_add_header(msg, "To", call->invite_from); if (rc < 0) return rc; rc = out_msg_add_header(msg, "Call-ID", call->sip_call_id); if (rc < 0) return rc; rc = out_msg_add_header(msg, "CSeq", "1 BYE"); if (rc < 0) return rc; sprintf(strbuf, "%u", max_forwards); rc = out_msg_add_header(msg, "Max-Forwards", strbuf); if (rc < 0) return rc; out_msg_finish(msg); return 0; } void initiate_bye(call) struct call *call; { struct sip_msg_out msg; int rc; rc = fill_bye_out_msg(&msg, call); if (rc < 0) { syslog(LOG_ERR, "outgoing BYE request msg length exceeded"); call->sip_state = SIP_STATE_MSG_SIZE_ERR; sip_mark_end_time(call, sip_linger_error); transition_dead_sip(call); return; } sip_tx_packet(&msg, &call->udp_sin); call->sip_state = SIP_STATE_BYE_SENT; call->sip_tx_count = 1; } void process_sip_response(msg, sin) struct sip_pkt_rx *msg; struct sockaddr_in *sin; { struct sip_resp_ident rid; struct call *call; int rc; rc = sip_resp_extract_ident(msg, &rid); if (rc < 0) { syslog(LOG_ERR, "SIP %03u response: bad or missing %s header", msg->status_code, rid.error_field); return; } call = find_call_by_sip_id(rid.call_id); if (!call) { syslog(LOG_ERR, "SIP %03u response: unmatched Call-ID", msg->status_code); return; } if (rid.cseq_num != 1 || strcmp(rid.cseq_method, "BYE")) { syslog(LOG_ERR, "UAC received %03u response with unknown CSeq %u %.32s", msg->status_code, rid.cseq_num, rid.cseq_method); return; } if (msg->status_code < 200) return; if (call->sip_state == SIP_STATE_BYE_SENT) { call->sip_state = SIP_STATE_ENDED; if (msg->status_code <= 299) sip_mark_end_time(call, sip_linger_acked); else sip_mark_end_time(call, sip_linger_error); transition_dead_sip(call); } }