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.orgneels 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>