Change in osmo-sip-connector[master]: forward full SDP between MNCC and SIP

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

neels gerrit-no-reply at lists.osmocom.org
Mon Nov 25 23:18:54 UTC 2019


neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sip-connector/+/16222 )


Change subject: forward full SDP between MNCC and SIP
......................................................................

forward full SDP between MNCC and SIP

Populate the new 'sdp' field added in MNCC v6, to enable full SDP codec
negotiation between osmo-msc and SIP.

Remove obsoleted code, since osmo-sip-connector now is fully out of the loop of
handling audio codecs in any way.

The only reason to parse or modify SDP is the recently added SIP re-INVITE
handling, which needs to set the send/recv modes via 'a=sendrecv',
a='sendonly', ... attributes.

Change-Id: I3df5d06f38ee2d122706a9ebffde7db4f2bd6bae
---
M src/call.c
M src/call.h
M src/mncc.c
M src/sip.c
M src/vty.c
5 files changed, 62 insertions(+), 68 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/22/16222/1

diff --git a/src/call.c b/src/call.c
index 9f593ea..487be56 100644
--- a/src/call.c
+++ b/src/call.c
@@ -172,3 +172,13 @@
 		return "Unknown call type";
 	}
 }
+
+void call_leg_update_sdp(struct call_leg *leg, const char *sdp)
+{
+	/* If no SDP was received, keep whatever SDP was previously seen. */
+	if (!sdp || !*sdp)
+		return;
+	OSMO_STRLCPY_ARRAY(leg->sdp, sdp);
+	LOGP(DAPP, LOGL_NOTICE, "call(%u) leg(0x%p) received SDP: %s\n",
+	     leg->call->id, leg, leg->sdp);
+}
diff --git a/src/call.h b/src/call.h
index 7f67066..d19c9eb 100644
--- a/src/call.h
+++ b/src/call.h
@@ -118,12 +118,6 @@
 	struct nua_handle_s *nua_handle;
 	enum sip_cc_state state;
 	enum sip_dir dir;
-
-	/* mo field */
-	const char *wanted_codec;
-
-	/* mt field */
-	const char *sdp_payload;
 };
 
 enum mncc_cc_state {
@@ -162,6 +156,8 @@
 
 struct call_leg *call_leg_other(struct call_leg *leg);
 
+void call_leg_update_sdp(struct call_leg *cl, const char *sdp);
+
 void call_leg_release(struct call_leg *leg);
 
 
diff --git a/src/mncc.c b/src/mncc.c
index f2e2579..d74ed44 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -184,11 +184,13 @@
 	mncc.callref = leg->callref;
 	mncc.ip = ntohl(other->ip);
 	mncc.port = other->port;
+
+	/* Send payload_type as legacy compatibility, in addition full SDP. */
 	mncc.payload_type = other->payload_type;
-	/*
-	 * FIXME: mncc.payload_msg_type should already be compatible.. but
-	 * payload_type should be different..
-	 */
+
+	/* Send full SDP info forwarded from SIP, since MNCC protocol version 6: */
+	OSMO_STRLCPY_ARRAY(mncc.sdp, other->sdp);
+
 	struct in_addr net = { .s_addr = other->ip };
 	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
 	LOGP(DMNCC, LOGL_DEBUG, "SEND rtp_connect: IP=(%s) PORT=(%u)\n", ip_addr, mncc.port);
@@ -396,6 +398,8 @@
 		return mncc_send(conn, MNCC_REJ_REQ, rtp->callref);
 	}
 
+	call_leg_update_sdp(&leg->base, rtp->sdp);
+
 	/* extract information about where the RTP is */
 	if (rtp->ip != 0 || rtp->port != 0 || rtp->payload_type != 0)
 		return;
@@ -433,6 +437,8 @@
 	leg->base.payload_type = rtp->payload_type;
 	leg->base.payload_msg_type = rtp->payload_msg_type;
 
+	call_leg_update_sdp(&leg->base, rtp->sdp);
+
 	/* TODO.. now we can continue with the call */
 	struct in_addr net = { .s_addr = leg->base.ip };
 	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
@@ -501,7 +507,6 @@
 		return mncc_send(conn, MNCC_REJ_REQ, data->callref);
 	}
 
-	/* TODO.. bearer caps and better audio handling */
 	if (!continue_setup(conn, data)) {
 		LOGP(DMNCC, LOGL_ERROR,
 			"MNCC screening parameters failed leg(%u)\n", data->callref);
@@ -529,6 +534,9 @@
 	memcpy(&leg->calling, &data->calling, sizeof(leg->calling));
 	memcpy(&leg->imsi, data->imsi, sizeof(leg->imsi));
 
+	/* forward full SDP description of audio codecs */
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_INFO,
 		"Created call(%u) with MNCC leg(%u) IMSI(%.16s)\n",
 		call->id, leg->callref, data->imsi);
@@ -638,6 +646,8 @@
 	if (!leg)
 		return;
 
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_INFO, "leg(%u) is now connected.\n", leg->callref);
 	stop_cmd_timer(leg, MNCC_SETUP_COMPL_IND);
 	leg->state = MNCC_CC_CONNECTED;
@@ -672,6 +682,8 @@
 	if (!leg)
 		return;
 
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_DEBUG,
 		"leg(%u) confirmed. creating RTP socket.\n",
 		leg->callref);
@@ -690,6 +702,8 @@
 	if (!leg)
 		return;
 
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_DEBUG,
 		"leg(%u) is alerting.\n", leg->callref);
 
@@ -768,6 +782,8 @@
 	if (!leg)
 		return;
 
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_DEBUG, "leg(%u) setup completed\n", leg->callref);
 
 	other_leg = call_leg_other(&leg->base);
@@ -797,6 +813,8 @@
 	if (!leg)
 		return;
 
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_DEBUG, "leg(%u) DTMF key=%c\n", leg->callref, data->keypad);
 
 	other_leg = call_leg_other(&leg->base);
@@ -819,6 +837,8 @@
 	if (!leg)
 		return;
 
+	call_leg_update_sdp(&leg->base, data->sdp);
+
 	LOGP(DMNCC, LOGL_DEBUG, "leg(%u) DTMF key=%c\n", leg->callref, data->keypad);
 
 	mncc_fill_header(&out_mncc, MNCC_STOP_DTMF_RSP, leg->callref);
@@ -898,12 +918,12 @@
 		OSMO_STRLCPY_ARRAY(mncc.called.number, call->dest);
 	}
 
-	/*
-	 * TODO/FIXME:
-	 *  - Determine/request channel based on offered audio codecs
-	 *  - Screening, redirect?
-	 *  - Synth. the bearer caps based on codecs?
-	 */
+	/* The call->initial leg is a SIP call leg that starts an MT call. There was SDP received in the SIP INVITE that
+	 * started this call. This here will be the call->remote, always forwarding the SDP that came in on
+	 * call->initial. */
+	if (call->initial)
+		OSMO_STRLCPY_ARRAY(mncc.sdp, call->initial->sdp);
+
 	rc = write(conn->fd.fd, &mncc, sizeof(mncc));
 	if (rc != sizeof(mncc)) {
 		LOGP(DMNCC, LOGL_ERROR, "Failed to send message leg(%u)\n",
diff --git a/src/sip.c b/src/sip.c
index 5eaa94b..70551c5 100644
--- a/src/sip.c
+++ b/src/sip.c
@@ -43,6 +43,12 @@
 static void sip_hold_call(struct call_leg *_leg);
 static void sip_retrieve_call(struct call_leg *_leg);
 
+static const char *sip_get_sdp(const sip_t *sip)
+{
+	if (!sip || !sip->sip_payload)
+		return NULL;
+	return sip->sip_payload->pl_data;
+}
 
 /* Find a SIP Call leg by given nua_handle */
 static struct sip_call_leg *sip_find_leg(nua_handle_t *nh)
@@ -72,17 +78,12 @@
 	if (!other)
 		return;
 
-	/* Extract SDP for session in progress with matching codec */
-	if (status == 183)
-		sdp_extract_sdp(leg, sip, false);
-
 	LOGP(DSIP, LOGL_INFO, "leg(%p) is now progressing.\n", leg);
 	other->ring_call(other);
 }
 
 static void call_connect(struct sip_call_leg *leg, const sip_t *sip)
 {
-	/* extract SDP file and if compatible continue */
 	struct call_leg *other = call_leg_other(&leg->base);
 
 	if (!other) {
@@ -91,13 +92,6 @@
 		return;
 	}
 
-	if (!sdp_extract_sdp(leg, sip, false)) {
-		LOGP(DSIP, LOGL_ERROR, "leg(%p) incompatible audio, releasing\n", leg);
-		nua_cancel(leg->nua_handle, TAG_END());
-		other->release_call(other);
-		return;
-	}
-
 	LOGP(DSIP, LOGL_INFO, "leg(%p) is now connected(%s).\n", leg, sip->sip_call_id->i_id);
 	leg->state = SIP_CC_CONNECTED;
 	other->connect_call(other);
@@ -114,20 +108,8 @@
 
 	LOGP(DSIP, LOGL_INFO, "Incoming call(%s) handle(%p)\n", sip->sip_call_id->i_id, nh);
 
-	if (!sdp_screen_sdp(sip)) {
-		LOGP(DSIP, LOGL_ERROR, "No supported codec.\n");
-		nua_respond(nh, SIP_406_NOT_ACCEPTABLE, TAG_END());
-		nua_handle_destroy(nh);
-		return;
-	}
-
 	call = call_sip_create();
-	if (!call) {
-		LOGP(DSIP, LOGL_ERROR, "No supported codec.\n");
-		nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
-		nua_handle_destroy(nh);
-		return;
-	}
+	OSMO_ASSERT(call);
 
 	if (sip->sip_to)
 		to = sip->sip_to->a_url->url_user;
@@ -145,27 +127,6 @@
 	leg->state = SIP_CC_DLG_CNFD;
 	leg->dir = SIP_DIR_MO;
 
-	/*
-	 * FIXME/TODO.. we need to select the codec at some point. But it is
-	 * not this place. It starts with the TCH/F vs. TCH/H selection based
-	 * on the offered codecs, and then RTP_CREATE should have it. So both
-	 * are GSM related... and do not belong here. Just pick the first codec
-	 * so the IP address, port and payload type is set.
-	 */
-	if (!sdp_extract_sdp(leg, sip, true)) {
-		LOGP(DSIP, LOGL_ERROR, "leg(%p) no audio, releasing\n", leg);
-		nua_respond(nh, SIP_406_NOT_ACCEPTABLE, TAG_END());
-		nua_handle_destroy(nh);
-		call_leg_release(&leg->base);
-		return;
-	}
-	struct in_addr net = { .s_addr = leg->base.ip };
-	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
-	LOGP(DSIP, LOGL_INFO, "SDP Extracted: IP=(%s) PORT=(%u) PAYLOAD=(%u).\n",
-		               ip_addr,
-		               leg->base.port,
-		               leg->base.payload_type);
-
 	leg->base.release_call = sip_release_call;
 	leg->base.ring_call = sip_ring_call;
 	leg->base.connect_call = sip_connect_call;
@@ -175,7 +136,8 @@
 	leg->agent = agent;
 	leg->nua_handle = nh;
 	nua_handle_bind(nh, leg);
-	leg->sdp_payload = talloc_strdup(leg, sip->sip_payload->pl_data);
+
+	call_leg_update_sdp(&leg->base, sip_get_sdp(sip));
 
 	app_route_call(call,
 			talloc_strdup(leg, from),
@@ -218,6 +180,8 @@
 	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
 	LOGP(DSIP, LOGL_DEBUG, "pre re-INVITE have IP:port (%s:%u)\n", ip_addr, leg->base.port);
 
+	call_leg_update_sdp(&leg->base, sip_get_sdp(sip));
+
 	if (mode == sdp_sendonly) {
 		/* SIP side places call on HOLD */
 		sdp = sdp_create_file(leg, other, sdp_recvonly);
@@ -330,6 +294,8 @@
 		struct sip_call_leg *leg;
 		leg = (struct sip_call_leg *) hmagic;
 
+		call_leg_update_sdp(&leg->base, sip_get_sdp(sip));
+
 		/* MT call is moving forward */
 
 		/* The dialogue is now confirmed */
@@ -366,8 +332,10 @@
 		 * respond to the re-INVITE query. */
 		if (sip->sip_payload && sip->sip_payload->pl_data) {
 			struct sip_call_leg *leg = sip_find_leg(nh);
-			if (leg)
+			if (leg) {
+				call_leg_update_sdp(&leg->base, sip_get_sdp(sip));
 				sip_handle_reinvite(leg, nh, sip);
+			}
 		}
 	} else if (event == nua_r_bye || event == nua_r_cancel) {
 		/* our bye or hang up is answered */
@@ -393,9 +361,10 @@
 
 		if (status == 100) {
 			struct sip_call_leg *leg = sip_find_leg(nh);
-			if (leg)
+			if (leg) {
+				call_leg_update_sdp(&leg->base, sip_get_sdp(sip));
 				sip_handle_reinvite(leg, nh, sip);
-			else
+			} else
 				new_call((struct sip_agent *) magic, nh, sip);
 		}
 	} else if (event == nua_i_cancel) {
diff --git a/src/vty.c b/src/vty.c
index ea76d46..863f9c1 100644
--- a/src/vty.c
+++ b/src/vty.c
@@ -211,7 +211,6 @@
 				get_value_string(sip_state_vals, sip->state), VTY_NEWLINE);
 		vty_out(vty, " SIP dir(%s)%s",
 				get_value_string(sip_dir_vals, sip->dir), VTY_NEWLINE);
-		vty_out(vty, " SIP wanted_codec(%s)%s", sip->wanted_codec, VTY_NEWLINE);
 		break;
 	case CALL_TYPE_MNCC:
 		mncc = (struct mncc_call_leg *) leg;

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-sip-connector/+/16222
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sip-connector
Gerrit-Branch: master
Gerrit-Change-Id: I3df5d06f38ee2d122706a9ebffde7db4f2bd6bae
Gerrit-Change-Number: 16222
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191125/164523df/attachment.htm>


More information about the gerrit-log mailing list