FreeCalypso > hg > themwi-system-sw
view sip-manual-out/uac.c @ 124:7e04d28fae8b
sip-in: default use-100rel to no
BulkVS servers act badly when we send a reliable 180 Ringing response
to an incoming call, even though they advertise 100rel support in
the Supported header in the INVITE packet, and we probably won't be
implementing 100rel for outbound because doing per-the-spec PRACK
as a UAC is just too burdensome. Therefore, we need to consider
100rel extension as not-really-supported in themwi-system-sw.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 01 Oct 2022 15:54:50 -0800 |
parents | a36b731bfef9 |
children | 6ac96217c442 |
line wrap: on
line source
/* * Here we implement processing of SIP responses to the requests we sent out. */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "../libsip/parse.h" #include "../libsip/resp_ident.h" #include "../libsip/out_msg.h" #define MAX_TO_TAG 63 extern char *get_single_header(); extern char *extract_to_tag(); extern struct in_addr sip_bind_ip; extern unsigned sip_bind_port; extern char call_id[], from_uri[], to_uri[]; extern unsigned max_forwards; char to_tag[MAX_TO_TAG+1]; add_req_boilerplate(msg, cseq, add_to_tag) struct sip_msg_out *msg; char *cseq; { char strbuf[256]; int 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", from_uri); if (rc < 0) return rc; if (add_to_tag && to_tag[0]) { sprintf(strbuf, "<%s>;tag=%s", to_uri, to_tag); rc = out_msg_add_header(msg, "To", strbuf); } else rc = out_msg_add_header(msg, "To", to_uri); if (rc < 0) return rc; rc = out_msg_add_header(msg, "Call-ID", call_id); if (rc < 0) return rc; rc = out_msg_add_header(msg, "CSeq", cseq); if (rc < 0) return rc; sprintf(strbuf, "%u", max_forwards); return out_msg_add_header(msg, "Max-Forwards", strbuf); } add_contact_header(msg) struct sip_msg_out *msg; { char strbuf[80]; sprintf(strbuf, "<sip:%s:%u;transport=udp>", inet_ntoa(sip_bind_ip), sip_bind_port); return out_msg_add_header(msg, "Contact", strbuf); } static void send_ack(sin) struct sockaddr_in *sin; { struct sip_msg_out msg; int rc; rc = start_request_out_msg(&msg, "ACK", to_uri); if (rc < 0) { msg_size_err: fprintf(stderr, "composing ACK message: size error\n"); return; } rc = add_req_boilerplate(&msg, "1 ACK", 1); if (rc < 0) goto msg_size_err; out_msg_finish(&msg); sip_tx_packet(&msg, sin); } static void handle_invite_response(msg, sin) struct sip_pkt_rx *msg; struct sockaddr_in *sin; { char *tag; printf("Response to INVITE: %s\n", msg->status_str); tag = extract_to_tag(msg, to_uri); if (tag) { printf("To tag: %s\n", tag); if (strlen(tag) <= MAX_TO_TAG) strcpy(to_tag, tag); else printf("To tag exceeds length limit!\n"); } if (msg->status_code >= 200) { printf("Sending ACK\n"); send_ack(sin); } } void process_sip_response(msg, sin) struct sip_pkt_rx *msg; struct sockaddr_in *sin; { struct sip_resp_ident rid; int rc; rc = sip_resp_extract_ident(msg, &rid); if (rc < 0) { printf("SIP %03u response: bad or missing %s header\n", msg->status_code, rid.error_field); return; } if (strcmp(rid.call_id, call_id)) { printf("Got SIP response with wrong Call-ID\n"); return; } if (rid.cseq_num == 1 && !strcmp(rid.cseq_method, "INVITE")) handle_invite_response(msg, sin); else if (rid.cseq_num == 1 && !strcmp(rid.cseq_method, "CANCEL")) printf("Response to CANCEL: %s\n", msg->status_str); else if (rid.cseq_num == 2 && !strcmp(rid.cseq_method, "BYE")) printf("Response to BYE: %s\n", msg->status_str); else printf("Got SIP resp for our Call-ID with unknown CSeq %u %s\n", rid.cseq_num, rid.cseq_method); }