FreeCalypso > hg > sipout-test-utils
diff test-voice/uac.c @ 0:35c0d9f03c0a
beginning with sipout-test-voice,
a copy of sip-manual-out from themwi-system-sw
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 03 Mar 2024 23:20:19 -0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-voice/uac.c Sun Mar 03 23:20:19 2024 -0800 @@ -0,0 +1,142 @@ +/* + * 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"); + } + extract_resp_sdp(msg); + if (msg->status_code >= 200) { + printf("Sending ACK\n"); + send_ack(sin); + if (msg->status_code <= 299) + invite_200_rtpout(); + } +} + +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); +}