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/.
keith gerrit-no-reply at lists.osmocom.orgkeith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sip-connector/+/14994
Change subject: Handle SIP re-INVITEs
......................................................................
Handle SIP re-INVITEs
SIP end points can send periodic re-INVITES. Previous to this commit,
the osmo-sip-connector would send a new call SETUP to the MSC for each
re-INVITE.
Add a function to find if we already handle this call based on the nua handle.
Use this function to detect and respond with an ACK to re-INVITES.
Add a function to extract the media mode from the SDP.
In the case the re-INVITE has a=sendonly (HOLD) respond with a=recvonly
Change-Id: I4083ed50d0cf1b302b80354fe0c2b73fc6e14fed
---
M src/sdp.c
M src/sdp.h
M src/sip.c
3 files changed, 86 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/94/14994/1
diff --git a/src/sdp.c b/src/sdp.c
index 93e0c7f..d1d4777 100644
--- a/src/sdp.c
+++ b/src/sdp.c
@@ -32,6 +32,36 @@
#include <string.h>
+sdp_mode_t sdp_mode(const sip_t *sip) {
+
+ const char *sdp_data;
+ sdp_parser_t *parser;
+ sdp_session_t *sdp;
+
+ if (!sip->sip_payload || !sip->sip_payload->pl_data) {
+ LOGP(DSIP, LOGL_ERROR, "No SDP file\n");
+ return false;
+ }
+
+ sdp_data = sip->sip_payload->pl_data;
+ parser = sdp_parse(NULL, sdp_data, strlen(sdp_data), sdp_f_mode_0000);
+ if (!parser) {
+ LOGP(DSIP, LOGL_ERROR, "Failed to parse SDP\n");
+ return false;
+ }
+
+ sdp = sdp_session(parser);
+ if (!sdp) {
+ LOGP(DSIP, LOGL_ERROR, "No sdp session\n");
+ sdp_parser_free(parser);
+ return false;
+ }
+
+ if (!sdp->sdp_media || !sdp->sdp_media->m_mode)
+ return sdp_sendrecv;
+ return sdp->sdp_media->m_mode;
+}
+
/*
* We want to decide on the audio codec later but we need to see
* if it is even including some of the supported ones.
diff --git a/src/sdp.h b/src/sdp.h
index 72ff6b7..80c6698 100644
--- a/src/sdp.h
+++ b/src/sdp.h
@@ -8,6 +8,7 @@
struct sip_call_leg;
struct call_leg;
+sdp_mode_t sdp_mode(const sip_t *sip);
bool sdp_screen_sdp(const sip_t *sip);
bool sdp_extract_sdp(struct sip_call_leg *leg, const sip_t *sip, bool any_codec);
diff --git a/src/sip.c b/src/sip.c
index 21401c6..b5f856a 100644
--- a/src/sip.c
+++ b/src/sip.c
@@ -41,6 +41,27 @@
static void sip_connect_call(struct call_leg *_leg);
static void sip_dtmf_call(struct call_leg *_leg, int keypad);
+/* Find a SIP Call leg by given nua_handle */
+static struct sip_call_leg *sip_find_leg(nua_handle_t *nh)
+{
+ struct call *call;
+
+ llist_for_each_entry(call, &g_call_list, entry) {
+ if (call->initial && call->initial->type == CALL_TYPE_SIP) {
+ struct sip_call_leg *leg = (struct sip_call_leg *) call->initial;
+ if (leg->nua_handle == nh)
+ return leg;
+ }
+ if (call->remote && call->remote->type == CALL_TYPE_SIP) {
+ struct sip_call_leg *leg = (struct sip_call_leg *) call->remote;
+ if (leg->nua_handle == nh)
+ return leg;
+ }
+ }
+
+ return NULL;
+}
+
static void call_progress(struct sip_call_leg *leg, const sip_t *sip, int status)
{
struct call_leg *other = call_leg_other(&leg->base);
@@ -149,6 +170,32 @@
talloc_strdup(leg, to));
}
+static void sip_handle_reinvite(struct sip_call_leg *leg, nua_handle_t *nh, const sip_t *sip) {
+
+ char *sdp = NULL;
+
+ LOGP(DSIP, LOGL_NOTICE, "re-INVITE for call %s\n", sip->sip_call_id->i_id);
+ sdp_mode_t mode = sdp_mode(sip);
+ struct call_leg *other = call_leg_other(&leg->base);
+ if (mode == sdp_sendonly) {
+ LOGP(DSIP, LOGL_NOTICE, "SIP side puts call on HOLD\n");
+ sdp = sdp_create_file(leg, other, sdp_recvonly);
+ // TODO: Tell osmo-bts to stop sending RTP ?
+ } else {
+ // Regular re-INVITE. Just ACK.
+ sdp = sdp_create_file(leg, other, sdp_sendrecv);
+ }
+
+ LOGP(DSIP, LOGL_DEBUG, "Sending 200 response to re-INVITE for mode(%u)\n", mode);
+ nua_respond(nh, SIP_200_OK,
+ NUTAG_MEDIA_ENABLE(0),
+ SIPTAG_CONTENT_TYPE_STR("application/sdp"),
+ SIPTAG_PAYLOAD_STR(sdp),
+ TAG_END());
+ talloc_free(sdp);
+ return;
+}
+
/* Sofia SIP definitions come with error code numbers and strings, this
* map allows us to reuse the existing definitions.
* The map is in priority order. The first matching entry found
@@ -270,10 +317,15 @@
if (other)
other->release_call(other);
} else if (event == nua_i_invite) {
- /* new incoming leg */
+ /* new incoming leg or re-INVITE */
- if (status == 100)
- new_call((struct sip_agent *) magic, nh, sip);
+ if (status == 100) {
+ struct sip_call_leg *leg = sip_find_leg(nh);
+ if (leg)
+ sip_handle_reinvite(leg, nh, sip);
+ else
+ new_call((struct sip_agent *) magic, nh, sip);
+ }
} else if (event == nua_i_cancel) {
struct sip_call_leg *leg;
struct call_leg *other;
--
To view, visit https://gerrit.osmocom.org/c/osmo-sip-connector/+/14994
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: I4083ed50d0cf1b302b80354fe0c2b73fc6e14fed
Gerrit-Change-Number: 14994
Gerrit-PatchSet: 1
Gerrit-Owner: keith <keith at rhizomatica.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190730/0d6f86e6/attachment.htm>