FreeCalypso > hg > themwi-system-sw
view sip-manual-out/uac.c @ 171:4f1f3f799295
doc/Codec-library-depend: article written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 21 Nov 2022 01:01:39 -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); }