FreeCalypso > hg > themwi-system-sw
view sip-manual-out/uac.c @ 112:6aa63cf4620a
sip-in call clearing: select timeout implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 28 Sep 2022 18:59:55 -0800 |
parents | d7b6b8973a83 |
children | a4450ae8fd09 |
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/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[]; char to_tag[MAX_TO_TAG+1]; add_req_boilerplate(msg, cseq) 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 (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; return out_msg_add_header(msg, "Max-Forwards", "70"); } 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"); 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; { char *call_id_hdr, *cseq_hdr; call_id_hdr = get_single_header(msg, "Call-ID", "i", (int *) 0); if (!call_id_hdr) { printf("Got SIP response w/o Call-ID header\n"); return; } if (strcmp(call_id_hdr, call_id)) { printf("Got SIP response with wrong Call-ID\n"); return; } cseq_hdr = get_single_header(msg, "CSeq", (char *) 0, (int *) 0); if (!cseq_hdr) { printf("Got SIP response w/o CSeq header\n"); return; } if (!strcmp(cseq_hdr, "1 INVITE")) handle_invite_response(msg, sin); else printf("Got SIP resp for our Call-ID with unknown CSeq %s\n", cseq_hdr); }