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);
+}