Harald Welte has submitted this change and it was merged. ( 
https://gerrit.osmocom.org/14041 )

Change subject: Request Osmux CID and forward it in Assign Req and Assign Compl
......................................................................

Request Osmux CID and forward it in Assign Req and Assign Compl

Related: OS#2551
Depends: osmo-mgw.git I73b4c62baf39050da81d65553cbea07bc51163de
Change-Id: I5b14e34481e890669c9ee02dba81eba84293cebb
---
M include/osmocom/msc/call_leg.h
M include/osmocom/msc/ran_msg.h
M include/osmocom/msc/rtp_stream.h
M src/libmsc/call_leg.c
M src/libmsc/msc_a.c
M src/libmsc/ran_msg_a.c
M src/libmsc/rtp_stream.c
7 files changed, 111 insertions(+), 8 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved



diff --git a/include/osmocom/msc/call_leg.h b/include/osmocom/msc/call_leg.h
index d8380f5..f35816c 100644
--- a/include/osmocom/msc/call_leg.h
+++ b/include/osmocom/msc/call_leg.h
@@ -44,6 +44,8 @@

        /* Prevent events from deallocating for certain release code paths, to 
prevent use-after-free problems. */
        bool deallocating;
+
+       bool ran_peer_supports_osmux;
 };

 enum call_leg_event {
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 4d0485d..af0822b 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -84,6 +84,8 @@
        const struct osmo_sockaddr_str *cn_rtp;
        const struct gsm0808_channel_type *channel_type;
        enum nsap_addr_enc rab_assign_addr_enc;
+       bool osmux_present;
+       uint8_t osmux_cid;
 };

 struct ran_cipher_mode_command {
@@ -223,6 +225,8 @@
                        struct osmo_sockaddr_str remote_rtp;
                        bool codec_present;
                        enum mgcp_codecs codec;
+                       bool osmux_present;
+                       uint8_t osmux_cid;
                } assignment_complete;
                struct {
                        enum gsm0808_cause bssap_cause;
diff --git a/include/osmocom/msc/rtp_stream.h b/include/osmocom/msc/rtp_stream.h
index 794e806..c53c4f1 100644
--- a/include/osmocom/msc/rtp_stream.h
+++ b/include/osmocom/msc/rtp_stream.h
@@ -44,6 +44,15 @@
        struct osmo_mgcpc_ep_ci *ci;

        enum mgcp_connection_mode crcx_conn_mode;
+
+       /* configured to use Osmux */
+       bool use_osmux;
+       /* Allocated by our MGW, negative means invalid, not yet known */
+       int local_osmux_cid;
+       /* Allocated by BSC MGW, negative means invalid, not yet known */
+       int remote_osmux_cid;
+        /* Whether remote_osmux_cid has been communicated to MGW */
+       bool remote_osmux_cid_sent_to_mgw;
 };

 #define RTP_STREAM_FMT "local=" RTP_IP_PORT_FMT ",remote=" RTP_IP_PORT_FMT
@@ -57,6 +66,7 @@

 void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec);
 void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct 
osmo_sockaddr_str *r);
+void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t 
osmux_cid);
 int rtp_stream_commit(struct rtp_stream *rtps);

 void rtp_stream_release(struct rtp_stream *rtps);
diff --git a/src/libmsc/call_leg.c b/src/libmsc/call_leg.c
index 46405bc..794eda2 100644
--- a/src/libmsc/call_leg.c
+++ b/src/libmsc/call_leg.c
@@ -321,6 +321,10 @@
        if (call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans))
                return -EIO;
        cl->rtp[dir]->crcx_conn_mode = cl->crcx_conn_mode[dir];
+       if (dir == RTP_TO_RAN && cl->ran_peer_supports_osmux) {
+               cl->rtp[dir]->use_osmux = true;
+               cl->rtp[dir]->remote_osmux_cid = -1; /* wildcard */
+       }
        if (codec_if_known)
                rtp_stream_set_codec(cl->rtp[dir], *codec_if_known);
        if (remote_addr_if_known && 
osmo_sockaddr_str_is_set(remote_addr_if_known))
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index cfba545..b311df3 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -527,6 +527,8 @@
                .assignment_command = {
                        .cn_rtp = &msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local,
                        .channel_type = &channel_type,
+                       .osmux_present = 
msc_a->cc.call_leg->rtp[RTP_TO_RAN]->use_osmux,
+                       .osmux_cid = 
msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid,
                },
        };
        if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
@@ -620,8 +622,9 @@
                        return;
                }
                LOG_MSC_A(msc_a, LOGL_DEBUG,
-                         "MGW endpoint's RTP address available for the CI %s: 
" OSMO_SOCKADDR_STR_FMT "\n",
-                         rtp_direction_name(rtps->dir), 
OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local));
+                         "MGW endpoint's RTP address available for the CI %s: 
" OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n",
+                         rtp_direction_name(rtps->dir), 
OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local),
+                         rtps->use_osmux ? "yes" : "no", 
rtps->local_osmux_cid);
                switch (rtps->dir) {
                case RTP_TO_RAN:
                        msc_a_call_leg_ran_local_addr_available(msc_a);
@@ -1257,9 +1260,20 @@
                return;
        }

+       if (rtps_to_ran->use_osmux != ac->assignment_complete.osmux_present) {
+               LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Osmux usage ass request 
and complete don't match: %d vs %d\n",
+                        rtps_to_ran->use_osmux, 
ac->assignment_complete.osmux_present);
+               call_leg_release(msc_a->cc.call_leg);
+               return;
+       }
+
        /* Update RAN-side endpoint CI: */
        rtp_stream_set_codec(rtps_to_ran, ac->assignment_complete.codec);
        rtp_stream_set_remote_addr(rtps_to_ran, 
&ac->assignment_complete.remote_rtp);
+       if (rtps_to_ran->use_osmux)
+               rtp_stream_set_remote_osmux_cid(rtps_to_ran,
+                                               
ac->assignment_complete.osmux_cid);
+
        rtp_stream_commit(rtps_to_ran);

        /* Setup CN side endpoint CI:
@@ -1592,6 +1606,8 @@
 static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans 
*cc_trans)
 {
        struct call_leg *cl = msc_a->cc.call_leg;
+       struct msc_i *msc_i = msc_a_msc_i(msc_a);
+       struct gsm_network *net = msc_a_net(msc_a);

        OSMO_ASSERT(!msc_a->cc.active_trans);
        msc_a->cc.active_trans = cc_trans;
@@ -1612,6 +1628,16 @@
                        cl->crcx_conn_mode[RTP_TO_RAN] = MGCP_CONN_LOOPBACK;
        }

+       if (net->use_osmux != OSMUX_USAGE_OFF) {
+               msc_i = msc_a_msc_i(msc_a);
+               if (msc_i->c.remote_to) {
+                       /* TODO: investigate what to do in this case */
+                       LOG_MSC_A(msc_a, LOGL_ERROR, "Osmux not yet supported 
for inter-MSC");
+               } else {
+                       cl->ran_peer_supports_osmux = 
msc_i->ran_conn->ran_peer->remote_supports_osmux;
+               }
+       }
+
        /* This will lead to either MSC_EV_CALL_LEG_LOCAL_ADDR_AVAILABLE or 
MSC_EV_CALL_LEG_TERM.
         * If the local address is already known, then immediately trigger. */
        if (call_leg_local_ip(cl, RTP_TO_RAN))
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 64590a1..fd8afdc 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -269,6 +269,7 @@
 {
        struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, 
GSM0808_IE_AOIP_TRASP_ADDR);
        struct tlv_p_entry *ie_speech_codec = TLVP_GET(tp, 
GSM0808_IE_SPEECH_CODEC);
+       struct tlv_p_entry *ie_osmux_cid = TLVP_GET(tp, 
GSM0808_IE_OSMO_OSMUX_CID);
        struct sockaddr_storage rtp_addr;
        struct sockaddr_in *rtp_addr_in;
        struct gsm0808_speech_codec sc;
@@ -300,6 +301,15 @@
                }
        }

+       if (ie_osmux_cid) {
+               rc = 
gsm0808_dec_osmux_cid(&ran_dec_msg.assignment_complete.osmux_cid, 
ie_osmux_cid->val, ie_osmux_cid->len);
+               if (rc < 0) {
+                       LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Unable to decode Osmux 
CID\n");
+                       return -EINVAL;
+               }
+               ran_dec_msg.assignment_complete.osmux_present = true;
+       }
+
        if (ie_speech_codec) {
                /* Decode Speech Codec (Chosen) element */
                rc = gsm0808_dec_speech_codec(&sc, ie_speech_codec->val, 
ie_speech_codec->len);
@@ -902,6 +912,13 @@
        return 0;
 }

+static void _gsm0808_assignment_extend_osmux(struct msgb *msg, uint8_t cid)
+{
+       OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /*TL not in len */
+       msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, cid);
+       msg->l3h[1] = msgb_l3len(msg) - 2;
+}
+
 /* Compose a BSSAP Assignment Command.
  * Passing an RTP address is optional.
  * The msub is passed merely for error logging. */
@@ -912,6 +929,7 @@
        struct gsm0808_speech_codec_list *use_scl = NULL;
        struct sockaddr_storage rtp_addr;
        struct sockaddr_storage *use_rtp_addr = NULL;
+       struct msgb *msg;
        int rc;

        if (!ac->channel_type) {
@@ -952,7 +970,10 @@
                }
        }

-       return gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, 
use_scl, NULL);
+       msg = gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, 
NULL);
+       if (ac->osmux_present)
+               _gsm0808_assignment_extend_osmux(msg, ac->osmux_cid);
+       return msg;
 }

 /* For an A5/N number a5_n set dst to the matching GSM0808_ALG_ID_A5_<n>. */
diff --git a/src/libmsc/rtp_stream.c b/src/libmsc/rtp_stream.c
index afe24ad..c3880bf 100644
--- a/src/libmsc/rtp_stream.c
+++ b/src/libmsc/rtp_stream.c
@@ -82,11 +82,19 @@
                        OSMO_STRBUF_PRINTF(sb, ":no-codec");
                else if (!rtps->codec_sent_to_mgw)
                        OSMO_STRBUF_PRINTF(sb, ":codec-not-sent");
+               if (rtps->use_osmux) {
+                       if (rtps->remote_osmux_cid < 0)
+                               OSMO_STRBUF_PRINTF(sb, ":no-remote-osmux-cid");
+                       else if (!rtps->remote_osmux_cid_sent_to_mgw)
+                               OSMO_STRBUF_PRINTF(sb, 
":remote-osmux-cid-not-sent");
+               }
        }
        if (osmo_sockaddr_str_is_set(&rtps->local))
                OSMO_STRBUF_PRINTF(sb, ":local-%s-%u", rtps->local.ip, 
rtps->local.port);
        if (osmo_sockaddr_str_is_set(&rtps->remote))
                OSMO_STRBUF_PRINTF(sb, ":remote-%s-%u", rtps->remote.ip, 
rtps->remote.port);
+       if (rtps->use_osmux)
+               OSMO_STRBUF_PRINTF(sb, ":osmux-%d-%d", rtps->local_osmux_cid, 
rtps->remote_osmux_cid);

        /* Replace any dots in the IP address, dots not allowed as FSM instance 
name */
        for (p = buf; *p; p++)
@@ -117,6 +125,8 @@
                .call_id = call_id,
                .for_trans = for_trans,
                .dir = dir,
+               .local_osmux_cid = -2,
+               .remote_osmux_cid = -2,
        };

        rtp_stream_update_id(rtps);
@@ -130,6 +140,7 @@
            && osmo_sockaddr_str_is_set(&rtps->local)
            && osmo_sockaddr_str_is_set(&rtps->remote)
            && rtps->remote_sent_to_mgw
+           && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
            && rtps->codec_known)
                rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED);
 }
@@ -148,17 +159,27 @@
                }

                osmo_sockaddr_str_from_str(&rtps->local, crcx_info->addr, 
crcx_info->port);
+               if (rtps->use_osmux != crcx_info->x_osmo_osmux_use) {
+                       LOG_RTPS(rtps, LOGL_ERROR, "Osmux usage request and 
response don't match: %d vs %d",
+                                rtps->use_osmux, crcx_info->x_osmo_osmux_use);
+                       /* TODO: proper failure path */
+                       OSMO_ASSERT(rtps->use_osmux != 
crcx_info->x_osmo_osmux_use);
+               }
+               if (crcx_info->x_osmo_osmux_use)
+                       rtps->local_osmux_cid = crcx_info->x_osmo_osmux_cid;
                rtp_stream_update_id(rtps);
                osmo_fsm_inst_dispatch(fi->proc.parent, 
CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, rtps);
                check_established(rtps);

                if ((!rtps->remote_sent_to_mgw || !rtps->codec_sent_to_mgw)
                    && osmo_sockaddr_str_is_set(&rtps->remote)
+                   && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
                    && rtps->codec_known) {
                        LOG_RTPS(rtps, LOGL_DEBUG,
-                                "local ip:port set;%s%s triggering MDCX to 
send the new settings\n",
+                                "local ip:port set;%s%s%s triggering MDCX to 
send the new settings\n",
                                 (!rtps->remote_sent_to_mgw)? " remote ip:port 
not yet sent," : "",
-                                (!rtps->codec_sent_to_mgw)? " codec not yet 
sent," : "");
+                                (!rtps->codec_sent_to_mgw)? " codec not yet 
sent," : "",
+                                (rtps->use_osmux && 
!rtps->remote_osmux_cid_sent_to_mgw) ? "Osmux CID not yet sent,": "");
                        rtp_stream_do_mdcx(rtps);
                }
                return;
@@ -172,6 +193,7 @@
        case RTP_STREAM_EV_MDCX_FAIL:
                rtps->remote_sent_to_mgw = false;
                rtps->codec_sent_to_mgw = false;
+               rtps->remote_osmux_cid_sent_to_mgw = false;
                rtp_stream_update_id(rtps);
                rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING);
                return;
@@ -280,6 +302,8 @@
        verb_info = (struct mgcp_conn_peer){
                .call_id = rtps->call_id,
                .ptime = 20,
+               .x_osmo_osmux_use = rtps->use_osmux,
+               .x_osmo_osmux_cid = rtps->remote_osmux_cid,
        };

        if (verb == MGCP_VERB_CRCX)
@@ -353,9 +377,10 @@
                return 0;
        }

-       LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: 
updating%s%s\n",
+       LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: 
updating%s%s%s\n",
                 rtps->remote_sent_to_mgw ? "" : " remote-RTP-IP-port",
-                rtps->codec_sent_to_mgw ? "" : " codec");
+                rtps->codec_sent_to_mgw ? "" : " codec",
+                (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) ? "" 
: " remote-Osmux-CID");
        return rtp_stream_do_mdcx(rtps);
 }

@@ -380,6 +405,16 @@
        rtp_stream_update_id(rtps);
 }

+void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t 
osmux_cid)
+{
+       if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
+               rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
+       LOG_RTPS(rtps, LOGL_DEBUG, "setting remote Osmux CID to %u\n", 
osmux_cid);
+       rtps->remote_osmux_cid = osmux_cid;
+       rtps->remote_osmux_cid_sent_to_mgw = false;
+       rtp_stream_update_id(rtps);
+}
+
 bool rtp_stream_is_established(struct rtp_stream *rtps)
 {
        if (!rtps)
@@ -389,7 +424,8 @@
        if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED)
                return false;
        if (!rtps->remote_sent_to_mgw
-           || !rtps->codec_sent_to_mgw)
+           || !rtps->codec_sent_to_mgw
+           || (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw))
                return false;
        return true;
 }

--
To view, visit https://gerrit.osmocom.org/14041
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I5b14e34481e890669c9ee02dba81eba84293cebb
Gerrit-Change-Number: 14041
Gerrit-PatchSet: 4
Gerrit-Owner: Pau Espin Pedrol <[email protected]>
Gerrit-Reviewer: Harald Welte <[email protected]>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Neels Hofmeyr <[email protected]>

Reply via email to