diff test-voice/main.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/main.c	Sun Mar 03 23:20:19 2024 -0800
@@ -0,0 +1,200 @@
+/*
+ * This is the main module for sip-manual-out test program.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "../libsip/out_msg.h"
+#include "../libsip/sdp.h"
+
+extern int sip_socket;
+extern struct in_addr sip_bind_ip, sip_dest_ip;
+extern unsigned sip_bind_port, sip_dest_port;
+extern char sip_dest_domain[];
+extern struct sockaddr_in rtp_local_addr;
+extern int rtp_udp_fd, rtcp_udp_fd;
+extern int rtp_out_enable;
+
+struct sockaddr_in sip_dest_sin;
+char from_uri[128], to_uri[128], call_id[128];
+struct timeval cur_event_time;
+unsigned max_forwards = 70;
+int declare_100rel_supp;
+int pcma_codec_pref, pcma_codec_force;
+
+send_invite_req()
+{
+	struct sip_msg_out msg;
+	struct sdp_gen sdp;
+	int rc;
+
+	rc = start_request_out_msg(&msg, "INVITE", to_uri);
+	if (rc < 0) {
+msg_size_err:	fprintf(stderr, "composing INVITE req: msg size error\n");
+		exit(1);
+	}
+	rc = add_req_boilerplate(&msg, "1 INVITE", 0);
+	if (rc < 0)
+		goto msg_size_err;
+	rc = add_contact_header(&msg);
+	if (rc < 0)
+		goto msg_size_err;
+	if (declare_100rel_supp) {
+		rc = out_msg_add_header(&msg, "Supported", "100rel");
+		if (rc < 0)
+			goto msg_size_err;
+	}
+	rc = out_msg_add_header(&msg, "Content-Type", "application/sdp");
+	if (rc < 0)
+		goto msg_size_err;
+	bzero(&sdp, sizeof sdp);
+	sdp.conn_ip = rtp_local_addr.sin_addr;
+	sdp.conn_port = ntohs(rtp_local_addr.sin_port);
+	if (pcma_codec_force)
+		sdp.codec_mask = SDP_CODEC_MASK_PCMA;
+	else {
+		sdp.codec_mask = SDP_CODEC_MASK_BOTH;
+		if (pcma_codec_pref)
+			sdp.codec_mask |= SDP_CODEC_MASK_PCMA_PREF;
+	}
+	sdp.session_id = sdp.conn_port << 16;
+	sdp.owner_ip = sip_bind_ip;
+	rc = out_msg_finish_sdp(&msg, &sdp);
+	if (rc < 0)
+		goto msg_size_err;
+	sip_tx_packet(&msg, &sip_dest_sin);
+}
+
+static void
+preliminary_proc(argc, argv)
+	char **argv;
+{
+	extern int optind;
+	extern char *optarg;
+	char *logfile;
+	int opt, rc;
+
+	logfile = 0;
+	while ((opt = getopt(argc, argv, "aAl:m:r")) != EOF) {
+		switch (opt) {
+		case 'a':
+			pcma_codec_pref = 1;
+			continue;
+		case 'A':
+			pcma_codec_force = 1;
+			continue;
+		case 'l':
+			logfile = optarg;
+			continue;
+		case 'm':
+			max_forwards = atoi(optarg);
+			continue;
+		case 'r':
+			declare_100rel_supp = 1;
+			continue;
+		default:
+		usage:
+			fprintf(stderr,
+			"usage: %s [options] dest-conf from-num to-num\n",
+				argv[0]);
+			exit(1);
+		}
+	}
+	if (argc != optind + 3)
+		goto usage;
+	read_config_file(argv[optind]);
+	open_sip_udp_socket();
+	obtain_rtp_endp();
+	sip_dest_sin.sin_family = AF_INET;
+	sip_dest_sin.sin_addr = sip_dest_ip;
+	sip_dest_sin.sin_port = htons(sip_dest_port);
+	sprintf(from_uri, "<sip:%s@%s>;tag=out%u", argv[optind+1],
+		inet_ntoa(sip_bind_ip), ntohs(rtp_local_addr.sin_port));
+	sprintf(to_uri, "sip:%s@%s", argv[optind+2], sip_dest_domain);
+	if (logfile) {
+		rc = open_sip_log_file(logfile);
+		if (rc < 0)
+			exit(1);	/* error msg already printed */
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	fd_set fds;
+	struct timeval next_rtp_out, timeout;
+	int rc, max_fd, rtp_out_running;
+
+	preliminary_proc(argc, argv);
+	gettimeofday(&cur_event_time, 0);
+	sprintf(call_id, "%08u_%u@%s",
+		(unsigned)(cur_event_time.tv_sec % 100000000),
+		ntohs(rtp_local_addr.sin_port), inet_ntoa(sip_bind_ip));
+	send_invite_req();
+	/* main select loop */
+	max_fd = sip_socket;
+	if (rtp_udp_fd > max_fd)
+		max_fd = rtp_udp_fd;
+	if (rtcp_udp_fd > max_fd)
+		max_fd = rtcp_udp_fd;
+	rtp_out_running = 0;
+	for (;;) {
+		FD_ZERO(&fds);
+		FD_SET(0, &fds);
+		FD_SET(sip_socket, &fds);
+		FD_SET(rtp_udp_fd, &fds);
+		FD_SET(rtcp_udp_fd, &fds);
+		if (rtp_out_enable) {
+			if (!rtp_out_running) {
+				printf("Starting RTP output\n");
+				bcopy(&cur_event_time, &next_rtp_out,
+					sizeof(struct timeval));
+				rtp_out_running = 1;
+			}
+			if (timercmp(&cur_event_time, &next_rtp_out, <))
+				timersub(&next_rtp_out, &cur_event_time,
+					 &timeout);
+			else
+				timerclear(&timeout);
+			rc = select(max_fd+1, &fds, 0, 0, &timeout);
+		} else {
+			if (rtp_out_running) {
+				printf("Stopping RTP output\n");
+				rtp_out_running = 0;
+			}
+			rc = select(max_fd+1, &fds, 0, 0, 0);
+		}
+		if (rc < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		gettimeofday(&cur_event_time, 0);
+		if (FD_ISSET(0, &fds))
+			select_stdin();
+		if (FD_ISSET(sip_socket, &fds))
+			sip_socket_select();
+		if (FD_ISSET(rtp_udp_fd, &fds))
+			rtp_rx_select();
+		if (FD_ISSET(rtcp_udp_fd, &fds))
+			rtcp_rx_select();
+		if (rtp_out_running && (rc == 0)) {
+			generate_rtp_packet();
+			next_rtp_out.tv_usec += 20000;
+			if (next_rtp_out.tv_usec >= 1000000) {
+				next_rtp_out.tv_sec++;
+				next_rtp_out.tv_usec -= 1000000;
+			}
+		}
+	}
+}