changeset 81:915f0f397fb6

sip-in: beginning of outgoing BYE support
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 20 Sep 2022 20:11:44 -0800
parents a9944b66dcc5
children ff4b76a107a1
files libsip/out_msg.c sip-in/Makefile sip-in/bye_out.c sip-in/call_list.c sip-in/retrans.c
diffstat 5 files changed, 102 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libsip/out_msg.c	Tue Sep 20 19:35:34 2022 -0800
+++ b/libsip/out_msg.c	Tue Sep 20 20:11:44 2022 -0800
@@ -22,6 +22,21 @@
 	return(0);
 }
 
+start_request_out_msg_urilen(msg, method, uri, uri_len)
+	struct sip_msg_out *msg;
+	char *method, *uri;
+	unsigned uri_len;
+{
+	unsigned len;
+
+	len = strlen(method) + uri_len + (2 + 7 + 2);
+	if (len + 2 > MAX_SIP_TX_PACKET)
+		return(-1);
+	sprintf(msg->buf, "%s %.*s SIP/2.0\r\n", method, uri_len, uri);
+	msg->msg_len = len;
+	return(0);
+}
+
 start_response_out_msg(msg, status)
 	struct sip_msg_out *msg;
 	char *status;
--- a/sip-in/Makefile	Tue Sep 20 19:35:34 2022 -0800
+++ b/sip-in/Makefile	Tue Sep 20 20:11:44 2022 -0800
@@ -1,9 +1,9 @@
 CC=	gcc
 CFLAGS=	-O2
 PROG=	themwi-sip-in
-OBJS=	bye_in.o call_list.o call_setup.o cancel.o disconnect.o invite.o main.o\
-	mgw_ops.o mgw_sock.o mncc_handle.o mncc_sock.o readconf.o retrans.o \
-	sip_ack.o sip_log.o sip_uas.o sip_udp.o
+OBJS=	bye_in.o bye_out.o call_list.o call_setup.o cancel.o disconnect.o \
+	invite.o main.o mgw_ops.o mgw_sock.o mncc_handle.o mncc_sock.o \
+	readconf.o retrans.o sip_ack.o sip_log.o sip_uas.o sip_udp.o
 LIBS=	../libnumdb/libnumdb.a ../libsip/libsip.a ../libutil/libutil.a
 INSTBIN=/usr/local/bin
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sip-in/bye_out.c	Tue Sep 20 20:11:44 2022 -0800
@@ -0,0 +1,74 @@
+/*
+ * In this module we implement our UAC functionality of sending BYE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <syslog.h>
+#include "../libsip/parse.h"
+#include "../libsip/out_msg.h"
+#include "call.h"
+
+extern struct in_addr sip_bind_ip;
+extern unsigned sip_bind_port;
+
+fill_bye_out_msg(msg, call)
+	struct sip_msg_out *msg;
+	struct call *call;
+{
+	char strbuf[80];
+	int rc;
+
+	rc = start_request_out_msg_urilen(msg, "BYE", call->from_uri,
+					  call->from_uri_len);
+	if (rc < 0)
+		return 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", call->invite_to);
+	if (rc < 0)
+		return rc;
+	rc = out_msg_add_header(msg, "To", call->invite_from);
+	if (rc < 0)
+		return rc;
+	rc = out_msg_add_header(msg, "Call-ID", call->sip_call_id);
+	if (rc < 0)
+		return rc;
+	rc = out_msg_add_header(msg, "CSeq", "1 BYE");
+	if (rc < 0)
+		return rc;
+	rc = out_msg_add_header(msg, "Max-Forwards", "70");
+	if (rc < 0)
+		return rc;
+	out_msg_finish(msg);
+	return 0;
+}
+
+void
+initiate_bye(call)
+	struct call *call;
+{
+	struct sip_msg_out msg;
+	int rc;
+
+	rc = fill_bye_out_msg(&msg, call);
+	if (rc < 0) {
+		syslog(LOG_ERR, "outgoing BYE request msg length exceeded");
+		call->sip_state = SIP_STATE_MSG_SIZE_ERR;
+		/* TODO: transition from TEARDOWN to DEAD_SIP */
+		return;
+	}
+	sip_tx_packet(&msg, &call->udp_sin);
+	call->sip_state = SIP_STATE_BYE_SENT;
+	call->sip_tx_count = 1;
+}
--- a/sip-in/call_list.c	Tue Sep 20 19:35:34 2022 -0800
+++ b/sip-in/call_list.c	Tue Sep 20 20:11:44 2022 -0800
@@ -63,6 +63,7 @@
 		switch (call->sip_state) {
 		case SIP_STATE_INVITE_200:
 		case SIP_STATE_INVITE_ERR:
+		case SIP_STATE_BYE_SENT:
 			*retrans = 1;
 			break;
 		}
--- a/sip-in/retrans.c	Tue Sep 20 19:35:34 2022 -0800
+++ b/sip-in/retrans.c	Tue Sep 20 20:11:44 2022 -0800
@@ -33,12 +33,11 @@
 				sip_tx_packet(&msg, &call->udp_sin);
 				call->sip_tx_count++;
 			} else {
-				/* TODO: send BYE */
-				call->sip_state = SIP_STATE_ENDED;
 				call->overall_state = OVERALL_STATE_TEARDOWN;
 				disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
 						GSM48_CC_CAUSE_INTERWORKING);
 				disconnect_tmgw(call);
+				initiate_bye(call);
 			}
 			break;
 		case SIP_STATE_INVITE_ERR:
@@ -51,6 +50,14 @@
 			} else
 				call->sip_state = SIP_STATE_ENDED;
 			break;
+		case SIP_STATE_BYE_SENT:
+			if (call->sip_tx_count < cfg_retrans_count) {
+				fill_bye_out_msg(&msg, call);
+				sip_tx_packet(&msg, &call->udp_sin);
+				call->sip_tx_count++;
+			} else
+				call->sip_state = SIP_STATE_ENDED;
+			break;
 		}
 	}
 }