osmith has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-bsc/+/31551 )


Change subject: assignment_fsm: chan mode check: support CSD
......................................................................

assignment_fsm: chan mode check: support CSD

Replace check_requires_voice_stream, which used to iterate over
ch_mode_rate_list and verify that all entries are either for speech or
signalling. Instead verify in check_chan_mode_rate_against_ch_indctr,
that all entries of ch_mode_rate_list have a chan_mode that matches the
ch_indctr (data, speech, signalling; called "speech / data indicator" in
3GPP TS 48.008 § 3.2.2.11).

This ensures that all of them are either data, speech or signalling and
not mixed.

Related: OS#4393
Change-Id: Iee5cbfee84d7f2ad59ee2d5a19891a2b59bbafff
---
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/assignment_fsm.c
M src/osmo-bsc/osmo_bsc_bssap.c
3 files changed, 49 insertions(+), 32 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/51/31551/1

diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 8c4dcce..b77a16e 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -163,6 +163,9 @@
        /* The TSC to use if 'use' is true, otherwise automatically determine 
the TSC value to use. Valid range is 0 to
         * 7, as described in 3GPP TS 45.002. */
        struct optional_val tsc;
+
+       /* The "speech / data indicator" from 3GPP TS 48.008 § 3.2.2.11 Channel 
Type (speech/data/signalling). */
+       enum gsm0808_chan_indicator ch_indctr;
 };

 /* State of an ongoing Assignment, while the assignment_fsm is still busy. 
This serves as state separation to keep the
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index d382f10..d23d726 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -369,62 +369,53 @@
        OSMO_ASSERT(osmo_fsm_register(&assignment_fsm) == 0);
 }

-static int check_requires_voice(bool *requires_voice, enum gsm48_chan_mode 
chan_mode)
+static int chan_mode_to_ch_indctr(enum gsm48_chan_mode chan_mode)
 {
-       *requires_voice = false;
-
        switch (gsm48_chan_mode_to_non_vamos(chan_mode)) {
+       case GSM48_CMODE_DATA_14k5:
+       case GSM48_CMODE_DATA_12k0:
+       case GSM48_CMODE_DATA_6k0:
+       case GSM48_CMODE_DATA_3k6:
+               return GSM0808_CHAN_DATA;
        case GSM48_CMODE_SPEECH_V1:
        case GSM48_CMODE_SPEECH_EFR:
        case GSM48_CMODE_SPEECH_AMR:
-               *requires_voice = true;
-               break;
+               return GSM0808_CHAN_SPEECH;
        case GSM48_CMODE_SIGN:
-               *requires_voice = false;
-               break;
+               return GSM0808_CHAN_SIGN;
        default:
                return -EINVAL;
        }
-
-       return 0;
 }

-/* Check if the incoming assignment request requires a voice stream or not,
- * we will look at the preferred and the alternate channel mode and also make
- * sure that both are consistent. */
-static int check_requires_voice_stream(struct gsm_subscriber_connection *conn)
+/* Check if the incoming assignment request has a channel mode that is
+ * inconsistent with ch_indctr, e.g. GSM48_CMODE_DATA_14k5 and
+ * GSM0808_CHAN_SPEECH */
+static int check_chan_mode_rate_against_ch_indctr(struct 
gsm_subscriber_connection *conn)
 {
-       bool requires_voice_pref = false, requires_voice_alt;
        struct assignment_request *req = &conn->assignment.req;
        struct osmo_fsm_inst *fi = conn->fi;
-       int i, rc;
-
-       /* When the assignment request indicates that there is an alternate
-        * rate available (e.g. "Full or Half rate channel, Half rate
-        * preferred..."), then both must be either voice or either signalling,
-        * a mismatch is not permitted */
+       int i;
+       uint8_t ch_indctr;

        for (i = 0; i < req->n_ch_mode_rate; i++) {
-               rc = check_requires_voice(&requires_voice_alt, 
req->ch_mode_rate_list[i].chan_mode);
-               if (rc < 0) {
+               ch_indctr = 
chan_mode_to_ch_indctr(req->ch_mode_rate_list[i].chan_mode);
+               if (ch_indctr < 0) {
                        
assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP,
                                        "Channel mode not supported (prev level 
%d): %s", i,
                                        
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode));
                        return -EINVAL;
                }

-               if (i==0)
-                       requires_voice_pref = requires_voice_alt;
-               else if (requires_voice_alt != requires_voice_pref) {
+               if (ch_indctr != req->ch_indctr) {
                        
assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP,
-                                       "Requested a mix of Signalling and 
non-Signalling channel modes: %s != %s",
-                                       
gsm48_chan_mode_name(req->ch_mode_rate_list[0].chan_mode),
-                                       
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode));
+                                       "Channel mode %s has ch_indctr %d, 
channel type has ch_indctr %d",
+                                       
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode),
+                                       ch_indctr, req->ch_indctr);
                        return -EINVAL;
                }
        }

-       conn->assignment.requires_voice_stream = requires_voice_pref;
        return 0;
 }

@@ -470,6 +461,8 @@
                        .present = (tsc >= 0),
                        .val = tsc,
                },
+
+               .ch_indctr = 
chan_mode_to_ch_indctr(lchan->current_ch_mode_rate.chan_mode),
        };

        if (to_lchan)
@@ -528,10 +521,9 @@

        assignment_count(CTR_ASSIGNMENT_ATTEMPTED);

-       /* Check if we need a voice stream. If yes, set the appropriate struct
-        * members in conn */
-       if (check_requires_voice_stream(conn) < 0)
+       if (check_chan_mode_rate_against_ch_indctr(conn) < 0)
                return;
+       conn->assignment.requires_voice_stream = (req->ch_indctr != 
GSM0808_CHAN_SIGN);

        if (!req->target_lchan && reuse_existing_lchan(conn)) {
                /* The already existing lchan is suitable for this mode */
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 5226cbc..48f0b87 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -1135,6 +1135,8 @@
                goto reject;
        }

+       req.ch_indctr = ct.ch_indctr;
+
        return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, 
&req);

 reject:

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

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Iee5cbfee84d7f2ad59ee2d5a19891a2b59bbafff
Gerrit-Change-Number: 31551
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <[email protected]>
Gerrit-MessageType: newchange

Reply via email to