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>