<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/19792">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lchan_fsm: make rsl mode-modify working again<br><br>osmo-nitb supports the modification of an lchan if the lchan is<br>compatible but in the wrong mode. This feature was dropped in the<br>transition to AoIP/bsc-split. However, osmo-bsc still has code to<br>generate and parse the messeages, but the FSMs do not support a mode<br>modify yetm<br><br>Lets add handling for mode-modify to the lchan_fsm and assignment_fsm in<br>order to support mode modify again<br><br>Change-Id: I2c5a283b1ee33745cc1fcfcc09a0f9382224e2eb<br>Related: OS#4549<br>---<br>M doc/assignment-fsm.dot<br>M doc/assignment.msc<br>M doc/lchan-fsm.dot<br>M doc/lchan.msc<br>M include/osmocom/bsc/bts.h<br>M include/osmocom/bsc/lchan_fsm.h<br>M src/osmo-bsc/abis_rsl.c<br>M src/osmo-bsc/assignment_fsm.c<br>M src/osmo-bsc/gsm_04_08_rr.c<br>M src/osmo-bsc/lchan_fsm.c<br>10 files changed, 252 insertions(+), 47 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/assignment-fsm.dot b/doc/assignment-fsm.dot</span><br><span>index 5a3a2b9..c218153 100644</span><br><span>--- a/doc/assignment-fsm.dot</span><br><span>+++ b/doc/assignment-fsm.dot</span><br><span>@@ -22,6 +22,7 @@</span><br><span>        bssap -> gscon [label="GSCON_EV_ASSIGNMENT_START\ndata=struct assignment_request",style=dotted]</span><br><span> </span><br><span>     gscon -> WAIT_LCHAN_ACTIVE [label="assignment_fsm_start()",style=dotted]</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon -> WAIT_LCHAN_ESTABLISHED [label="assignment_fsm_start()\n(mode modify)",style=dotted]</span><br><span>         WAIT_LCHAN_ACTIVE -> lchan [label="lchan_activate()\nFOR_ASSIGNMENT",style=dotted]</span><br><span>         lchan -> WAIT_LCHAN_ACTIVE [label="ASSIGNMENT_EV_\nLCHAN_\nACTIVE,ERROR",style=dotted]</span><br><span>  lchan -> WAIT_LCHAN_ESTABLISHED [label="ASSIGNMENT_EV_\nLCHAN_\nESTABLISHED,ERROR",style=dotted]</span><br><span>diff --git a/doc/assignment.msc b/doc/assignment.msc</span><br><span>index 4e690a8..fae088f 100644</span><br><span>--- a/doc/assignment.msc</span><br><span>+++ b/doc/assignment.msc</span><br><span>@@ -9,6 +9,14 @@</span><br><span>        gscon note gscon [label="GSCON_EV_ASSIGNMENT_START\n data=struct assignment_request"];</span><br><span>     gscon abox gscon [label="ST_ASSIGNMENT"];</span><br><span>  ass <- gscon [label="assignment_fsm_start()"];</span><br><span style="color: hsl(120, 100%, 40%);">+   |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="IF current lchan supports requested channel mode (re-use)"];</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan <- ass [label="LCHAN_EV_REQUEST_MODE_MODIFY"];</span><br><span style="color: hsl(120, 100%, 40%);">+     ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ass rbox ass [label="see below"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ |||;</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="ELSE: if current lchan does not support requested channel mode (establish new lchan)"];</span><br><span>        ass abox ass [label="ASSIGNMENT_ST_\nWAIT_LCHAN_ACTIVE"];</span><br><span> </span><br><span>      |||;</span><br><span>diff --git a/doc/lchan-fsm.dot b/doc/lchan-fsm.dot</span><br><span>index b726b0c..fe35903 100644</span><br><span>--- a/doc/lchan-fsm.dot</span><br><span>+++ b/doc/lchan-fsm.dot</span><br><span>@@ -38,4 +38,10 @@</span><br><span>   rtp -> WAIT_RLL_RTP_ESTABLISH [label="LCHAN_EV_RTP_READY",style=dotted]</span><br><span>         rtp -> ESTABLISHED [label="LCHAN_EV_RTP_RELEASED",style=dotted]</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      ESTABLISHED -> WAIT_RR_CHAN_MODE_MODIFY_ACK [label="LCHAN_EV_REQUEST_MODE_MODIFY"]</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_RR_CHAN_MODE_MODIFY_ACK -> WAIT_RSL_CHAN_MODE_MODIFY_ACK [label="LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK"]</span><br><span style="color: hsl(120, 100%, 40%);">+ WAIT_RSL_CHAN_MODE_MODIFY_ACK -> WAIT_RLL_RTP_ESTABLISH [label="LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK\nwhen adding RTP"]</span><br><span style="color: hsl(120, 100%, 40%);">+     WAIT_RSL_CHAN_MODE_MODIFY_ACK -> ESTABLISHED [label="LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK\nno change to RTP"]</span><br><span style="color: hsl(120, 100%, 40%);">+       WAIT_RR_CHAN_MODE_MODIFY_ACK -> BORKEN [label="error/timeout",style=dashed]</span><br><span style="color: hsl(120, 100%, 40%);">+      WAIT_RSL_CHAN_MODE_MODIFY_ACK -> BORKEN [label="error/timeout",style=dashed]</span><br><span> }</span><br><span>diff --git a/doc/lchan.msc b/doc/lchan.msc</span><br><span>index e2caa48..b0e32d6 100644</span><br><span>--- a/doc/lchan.msc</span><br><span>+++ b/doc/lchan.msc</span><br><span>@@ -129,6 +129,26 @@</span><br><span>       ...;</span><br><span>         ...;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      ms rbox mgwep [label="On Mode Modify (e.g. change a TCH lchan from signalling to voice)"];</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan abox lchan [label="LCHAN_ST_\nWAIT_RR_CHAN_\nMODE_MODIFY_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+       ms <= lchan [label="RR Chan Mode Modif"];</span><br><span style="color: hsl(120, 100%, 40%);">+        ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RR Chan Mode Modif Ack"];</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan abox lchan [label="LCHAN_ST_\nWAIT_RSL_CHAN_\nMODE_MODIFY_ACK"];</span><br><span style="color: hsl(120, 100%, 40%);">+      ms <= lchan [label="RSL MT Mode Modify Req"];</span><br><span style="color: hsl(120, 100%, 40%);">+    ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ms => lchan [label="RSL MT Mode Modify Ack"];</span><br><span style="color: hsl(120, 100%, 40%);">+    --- [label="IF adding RTP stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan abox lchan [label="LCHAN_ST_WAIT_\nRLL_RTP_ESTABLISH\nT3101"];</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan rbox rtp [label="See above at 'LCHAN_RTP_EV_LCHAN_READY'"];</span><br><span style="color: hsl(120, 100%, 40%);">+   --- [label="IF not adding RTP stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+     lchan abox lchan [label="LCHAN_ST_\nESTABLISHED"];</span><br><span style="color: hsl(120, 100%, 40%);">+  --- [label="END: whether adding voice stream"];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+  ...;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       ms rbox mgwep [label="When the MS or BTS release the lchan"];</span><br><span>      lchan abox lchan [label="LCHAN_ST_\nESTABLISHED"];</span><br><span>         ms -> lchan [label="RLL Release Ind for SAPI=0"];</span><br><span>diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h</span><br><span>index 5506a86..a50c70e 100644</span><br><span>--- a/include/osmocom/bsc/bts.h</span><br><span>+++ b/include/osmocom/bsc/bts.h</span><br><span>@@ -50,6 +50,8 @@</span><br><span>  BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK,</span><br><span>     BTS_CTR_LCHAN_BORKEN_EV_VTY,</span><br><span>         BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RR_CHAN_MODE_MODIFY_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RSL_CHAN_MODE_MODIFY_ACK,</span><br><span>     BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED,</span><br><span>      BTS_CTR_TS_BORKEN_FROM_UNUSED,</span><br><span>       BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT,</span><br><span>@@ -136,6 +138,8 @@</span><br><span>  [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK] =      {"lchan_borken:from_state:wait_activ_ack", "Transitions from lchan WAIT_ACTIV_ACK state to BORKEN state"},</span><br><span>     [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK] = {"lchan_borken:from_state:wait_rf_release_ack", "Transitions from lchan WAIT_RF_RELEASE_ACK state to BORKEN state"},</span><br><span>   [BTS_CTR_LCHAN_BORKEN_FROM_BORKEN] =              {"lchan_borken:from_state:borken", "Transitions from lchan BORKEN state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RR_CHAN_MODE_MODIFY_ACK] = {"lchan_borken:from_state:wait_rr_chan_mode_modify_ack", "Transitions from lchan WAIT_RR_CHAN_MODE_MODIFY_ACK state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RSL_CHAN_MODE_MODIFY_ACK] = {"lchan_borken:from_state:wait_rsl_chan_mode_modify_ack", "Transitions from lchan RSL_CHAN_MODE_MODIFY_ACK state to BORKEN state"},</span><br><span>  [BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN] =             {"lchan_borken:from_state:unknown", "Transitions from an unknown lchan state to BORKEN state"},</span><br><span>        [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK] =        {"lchan_borken:event:chan_activ_ack", "CHAN_ACTIV_ACK received in the lchan BORKEN state"},</span><br><span>    [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK] =       {"lchan_borken:event:chan_activ_nack", "CHAN_ACTIV_NACK received in the lchan BORKEN state"},</span><br><span>diff --git a/include/osmocom/bsc/lchan_fsm.h b/include/osmocom/bsc/lchan_fsm.h</span><br><span>index 55ab024..df3ed22 100644</span><br><span>--- a/include/osmocom/bsc/lchan_fsm.h</span><br><span>+++ b/include/osmocom/bsc/lchan_fsm.h</span><br><span>@@ -18,6 +18,8 @@</span><br><span>     LCHAN_ST_WAIT_TS_READY,</span><br><span>      LCHAN_ST_WAIT_ACTIV_ACK, /*< After RSL Chan Act Ack, lchan is active but RTP not configured. */</span><br><span>   LCHAN_ST_WAIT_RLL_RTP_ESTABLISH,</span><br><span style="color: hsl(120, 100%, 40%);">+      LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+        LCHAN_ST_WAIT_RSL_CHAN_MODE_MODIFY_ACK,</span><br><span>      LCHAN_ST_ESTABLISHED, /*< Active and RTP is fully configured. */</span><br><span>  LCHAN_ST_WAIT_RLL_RTP_RELEASED,</span><br><span>      LCHAN_ST_WAIT_BEFORE_RF_RELEASE,</span><br><span>@@ -40,10 +42,11 @@</span><br><span>       LCHAN_EV_RLL_REL_CONF,</span><br><span>       LCHAN_EV_RSL_RF_CHAN_REL_ACK,</span><br><span>        LCHAN_EV_RLL_ERR_IND,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* FIXME: not yet implemented: Chan Mode Modify, see assignment_fsm_start(). */</span><br><span style="color: hsl(0, 100%, 40%);">- LCHAN_EV_CHAN_MODE_MODIF_ACK,</span><br><span style="color: hsl(0, 100%, 40%);">-   LCHAN_EV_CHAN_MODE_MODIF_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+       LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+     LCHAN_EV_RR_CHAN_MODE_MODIFY_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+   LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+    LCHAN_EV_RSL_CHAN_MODE_MODIFY_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+   LCHAN_EV_REQUEST_MODE_MODIFY,</span><br><span> };</span><br><span> </span><br><span> void lchan_fsm_init();</span><br><span>diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c</span><br><span>index d3f7de2..03d53c5 100644</span><br><span>--- a/src/osmo-bsc/abis_rsl.c</span><br><span>+++ b/src/osmo-bsc/abis_rsl.c</span><br><span>@@ -1186,10 +1186,12 @@</span><br><span>         case RSL_MT_MODE_MODIFY_ACK:</span><br><span>                 LOG_LCHAN(msg->lchan, LOGL_DEBUG, "CHANNEL MODE MODIFY ACK\n");</span><br><span>                 count_codecs(sign_link->trx->bts, msg->lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK, NULL);</span><br><span>               break;</span><br><span>       case RSL_MT_MODE_MODIFY_NACK:</span><br><span>                LOG_LCHAN(msg->lchan, LOGL_DEBUG, "CHANNEL MODE MODIFY NACK\n");</span><br><span>                rate_ctr_inc(&sign_link->trx->bts->bts_ctrs->ctr[BTS_CTR_MODE_MODIFY_NACK]);</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RSL_CHAN_MODE_MODIFY_NACK, NULL);</span><br><span>              break;</span><br><span>       case RSL_MT_IPAC_PDCH_ACT_ACK:</span><br><span>               rc = rsl_rx_ipacc_pdch(msg, "ACT ACK", TS_EV_PDCH_ACT_ACK);</span><br><span>diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c</span><br><span>index ca29daa..fde028e 100644</span><br><span>--- a/src/osmo-bsc/assignment_fsm.c</span><br><span>+++ b/src/osmo-bsc/assignment_fsm.c</span><br><span>@@ -379,9 +379,8 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Check if the conn is already associated with an lchan. If yes, we will check</span><br><span style="color: hsl(0, 100%, 40%);">- * if that lchan is compatible with the preferred rate/codec. If the lchan</span><br><span style="color: hsl(0, 100%, 40%);">- * turns out to be incompatible we try with the alternate rate/codec. */</span><br><span style="color: hsl(120, 100%, 40%);">+/* Decide if we should re-use an existing lchan. For this we check if the</span><br><span style="color: hsl(120, 100%, 40%);">+ * current lchan is compatible with one of the requested modes. */</span><br><span> static bool reuse_existing_lchan(struct gsm_subscriber_connection *conn)</span><br><span> {</span><br><span>  struct assignment_request *req = &conn->assignment.req;</span><br><span>@@ -395,22 +394,10 @@</span><br><span>       for (i = 0; i < req->n_ch_mode_rate; i++)</span><br><span>              if (lchan_type_compat_with_mode(conn->lchan->type, &req->ch_mode_rate[i])) {</span><br><span>                    conn->lchan->ch_mode_rate = req->ch_mode_rate[i];</span><br><span style="color: hsl(0, 100%, 40%);">-                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        return true;</span><br><span>                 }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (i == req->n_ch_mode_rate)</span><br><span style="color: hsl(0, 100%, 40%);">-                return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (conn->lchan->tch_mode != conn->lchan->ch_mode_rate.chan_mode) {</span><br><span style="color: hsl(0, 100%, 40%);">-         /* FIXME: send Channel Mode Modify to put the current lchan in the right mode, and kick</span><br><span style="color: hsl(0, 100%, 40%);">-          * off its RTP stream setup code path. See gsm48_lchan_modify() and</span><br><span style="color: hsl(0, 100%, 40%);">-              * gsm48_rx_rr_modif_ack(), and see lchan_fsm.h LCHAN_EV_CHAN_MODE_MODIF_* */</span><br><span style="color: hsl(0, 100%, 40%);">-           LOG_ASSIGNMENT(conn, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                               "Current lchan would be compatible, but Channel Mode Modify is not implemented\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            return false;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  return false;</span><br><span> }</span><br><span> </span><br><span> void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,</span><br><span>@@ -447,22 +434,57 @@</span><br><span>             return;</span><br><span> </span><br><span>  /* There may be an already existing lchan, if yes, try to work with</span><br><span style="color: hsl(0, 100%, 40%);">-      * the existing lchan */</span><br><span style="color: hsl(120, 100%, 40%);">+       * the existing lchan. */</span><br><span>    if (reuse_existing_lchan(conn)) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* If the requested mode and the current TCH mode matches up, just send the</span><br><span style="color: hsl(120, 100%, 40%);">+            * assignment complete directly and be done with the assignment procedure. */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (conn->lchan->tch_mode == conn->lchan->ch_mode_rate.chan_mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOG_ASSIGNMENT(conn, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     "Current lchan mode is compatible with requested chan_mode,"</span><br><span style="color: hsl(120, 100%, 40%);">+                                " sending BSSMAP Assignment Complete directly."</span><br><span style="color: hsl(120, 100%, 40%);">+                                     " requested chan_mode=%s; current lchan is %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   gsm48_chan_mode_name(conn->lchan->ch_mode_rate.chan_mode),</span><br><span style="color: hsl(120, 100%, 40%);">+                                      gsm_lchan_name(conn->lchan));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     send_assignment_complete(conn);</span><br><span style="color: hsl(120, 100%, 40%);">+                       /* If something went wrong during send_assignment_complete(),</span><br><span style="color: hsl(120, 100%, 40%);">+                  * the fi will be gone from error handling in there. */</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (conn->assignment.fi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         assignment_count_result(CTR_ASSIGNMENT_COMPLETED);</span><br><span style="color: hsl(120, 100%, 40%);">+                            osmo_fsm_inst_term(conn->assignment.fi, OSMO_FSM_TERM_REGULAR, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                     return;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* The requested mode does not match the current TCH mode but the lchan is</span><br><span style="color: hsl(120, 100%, 40%);">+             * compatible. We will initiate a mode modify procedure. */</span><br><span>          LOG_ASSIGNMENT(conn, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                               "Current lchan is compatible with requested chan_mode,"</span><br><span style="color: hsl(0, 100%, 40%);">-                               " sending BSSMAP Assignment Complete directly."</span><br><span style="color: hsl(0, 100%, 40%);">-                               " requested chan_mode=%s; current lchan is %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           "Current lchan mode is not compatible with requested chan_mode,"</span><br><span style="color: hsl(120, 100%, 40%);">+                            " so we will modify it. requested chan_mode=%s; current lchan is %s\n",</span><br><span>                            gsm48_chan_mode_name(conn->lchan->ch_mode_rate.chan_mode),</span><br><span>                             gsm_lchan_name(conn->lchan));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             send_assignment_complete(conn);</span><br><span style="color: hsl(0, 100%, 40%);">-         /* If something went wrong during send_assignment_complete(), the fi will be gone from</span><br><span style="color: hsl(0, 100%, 40%);">-           * error handling in there. */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (conn->assignment.fi) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   assignment_count_result(CTR_ASSIGNMENT_COMPLETED);</span><br><span style="color: hsl(0, 100%, 40%);">-                      osmo_fsm_inst_term(conn->assignment.fi, OSMO_FSM_TERM_REGULAR, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(120, 100%, 40%);">+             info = (struct lchan_activate_info){</span><br><span style="color: hsl(120, 100%, 40%);">+                  .activ_for = FOR_ASSIGNMENT,</span><br><span style="color: hsl(120, 100%, 40%);">+                  .for_conn = conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                     .chan_mode = conn->lchan->ch_mode_rate.chan_mode,</span><br><span style="color: hsl(120, 100%, 40%);">+                       .encr = conn->lchan->encr,</span><br><span style="color: hsl(120, 100%, 40%);">+                      .s15_s0 = conn->lchan->ch_mode_rate.s15_s0,</span><br><span style="color: hsl(120, 100%, 40%);">+                     .requires_voice_stream = conn->assignment.requires_voice_stream,</span><br><span style="color: hsl(120, 100%, 40%);">+                   .msc_assigned_cic = req->msc_assigned_cic,</span><br><span style="color: hsl(120, 100%, 40%);">+                 .re_use_mgw_endpoint_from_lchan = conn->lchan,</span><br><span style="color: hsl(120, 100%, 40%);">+             };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_fsm_inst_dispatch(conn->lchan->fi, LCHAN_EV_REQUEST_MODE_MODIFY, &info);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Since we opted not to allocate a new lchan, the new lchan is still the old lchan. */</span><br><span style="color: hsl(120, 100%, 40%);">+               conn->assignment.new_lchan = conn->lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Also we need to skip the RR assignment, so we jump forward and wait for the lchan_fsm until it</span><br><span style="color: hsl(120, 100%, 40%);">+              * reaches the established state again. */</span><br><span style="color: hsl(120, 100%, 40%);">+            assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_LCHAN_ESTABLISHED);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>            return;</span><br><span>      }</span><br><span> </span><br><span>@@ -682,6 +704,7 @@</span><br><span>          .out_state_mask = 0</span><br><span>                  | S(ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE)</span><br><span>                         | S(ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE)</span><br><span style="color: hsl(120, 100%, 40%);">+                       | S(ASSIGNMENT_ST_WAIT_LCHAN_ESTABLISHED) /* MODE MODIFY */</span><br><span>                  ,</span><br><span>    },</span><br><span>   [ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE] = {</span><br><span>diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c</span><br><span>index be114f0..848f623 100644</span><br><span>--- a/src/osmo-bsc/gsm_04_08_rr.c</span><br><span>+++ b/src/osmo-bsc/gsm_04_08_rr.c</span><br><span>@@ -655,7 +655,6 @@</span><br><span> </span><br><span> int gsm48_rx_rr_modif_ack(struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- int rc;</span><br><span>      struct gsm48_hdr *gh = msgb_l3(msg);</span><br><span>         struct gsm48_chan_mode_modify *mod =</span><br><span>                                 (struct gsm48_chan_mode_modify *) gh->data;</span><br><span>@@ -689,15 +688,7 @@</span><br><span>                break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* We've successfully modified the MS side of the channel,</span><br><span style="color: hsl(0, 100%, 40%);">-   * now go on to modify the BTS side of the channel */</span><br><span style="color: hsl(0, 100%, 40%);">-   rc = rsl_chan_mode_modify_req(msg->lchan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* FIXME: we not only need to do this after mode modify, but</span><br><span style="color: hsl(0, 100%, 40%);">-     * also after channel activation */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (is_ipaccess_bts(msg->lchan->ts->trx->bts) && mod->mode != GSM48_CMODE_SIGN)</span><br><span style="color: hsl(0, 100%, 40%);">-          rsl_tx_ipacc_crcx(msg->lchan);</span><br><span style="color: hsl(0, 100%, 40%);">-       return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span> }</span><br><span> </span><br><span> int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg)</span><br><span>@@ -970,9 +961,9 @@</span><br><span>             case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:</span><br><span>                        rc = gsm48_rx_rr_modif_ack(msg);</span><br><span>                     if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                          osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_CHAN_MODE_MODIF_ERROR, &rc);</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RR_CHAN_MODE_MODIFY_ERROR, &rc);</span><br><span>                   else</span><br><span style="color: hsl(0, 100%, 40%);">-                            osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_CHAN_MODE_MODIF_ACK, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                              osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK, msg);</span><br><span>                         break;</span><br><span>               case GSM48_MT_RR_CLSM_CHG:</span><br><span>                   handle_classmark_chg(conn, msg);</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index 26bfd29..115c3da 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -59,6 +59,7 @@</span><br><span>    switch (lchan->fi->state) {</span><br><span>    case LCHAN_ST_WAIT_RLL_RTP_ESTABLISH:</span><br><span>        case LCHAN_ST_ESTABLISHED:</span><br><span style="color: hsl(120, 100%, 40%);">+    case LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK:</span><br><span>          return true;</span><br><span>         default:</span><br><span>             return false;</span><br><span>@@ -249,7 +250,7 @@</span><br><span>  } while(0)</span><br><span> </span><br><span> /* Which state to transition to when lchan_fail() is called in a given state. */</span><br><span style="color: hsl(0, 100%, 40%);">-uint32_t lchan_fsm_on_error[32] = {</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t lchan_fsm_on_error[34] = {</span><br><span>   [LCHAN_ST_UNUSED]                       = LCHAN_ST_UNUSED,</span><br><span>   [LCHAN_ST_WAIT_TS_READY]                = LCHAN_ST_UNUSED,</span><br><span>   [LCHAN_ST_WAIT_ACTIV_ACK]               = LCHAN_ST_BORKEN,</span><br><span>@@ -260,6 +261,8 @@</span><br><span>     [LCHAN_ST_WAIT_RF_RELEASE_ACK]          = LCHAN_ST_BORKEN,</span><br><span>   [LCHAN_ST_WAIT_AFTER_ERROR]             = LCHAN_ST_UNUSED,</span><br><span>   [LCHAN_ST_BORKEN]                       = LCHAN_ST_BORKEN,</span><br><span style="color: hsl(120, 100%, 40%);">+    [LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK] = LCHAN_ST_BORKEN,</span><br><span style="color: hsl(120, 100%, 40%);">+    [LCHAN_ST_WAIT_RSL_CHAN_MODE_MODIFY_ACK]        = LCHAN_ST_BORKEN,</span><br><span> };</span><br><span> </span><br><span> #define lchan_fail(fmt, args...) lchan_fail_to(lchan_fsm_on_error[fi->state], fmt, ## args)</span><br><span>@@ -797,6 +800,10 @@</span><br><span>        struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span>        if (lchan->fi_rtp)</span><br><span>                osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_LCHAN_READY, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Prepare an MGW endpoint CI if appropriate (late). */</span><br><span style="color: hsl(120, 100%, 40%);">+       else if (lchan->activate.info.requires_voice_stream)</span><br><span style="color: hsl(120, 100%, 40%);">+               lchan_rtp_fsm_start(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static void lchan_fsm_wait_rll_rtp_establish(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span>@@ -833,6 +840,66 @@</span><br><span>  }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void lchan_fsm_wait_rr_chan_mode_modify_ack_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_lchan_modify(lchan, lchan->activate.info.chan_mode);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void lchan_fsm_wait_rr_chan_mode_modify_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    case LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+                lchan_fsm_state_chg(LCHAN_ST_WAIT_RSL_CHAN_MODE_MODIFY_ACK);</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case LCHAN_EV_RR_CHAN_MODE_MODIFY_ERROR:</span><br><span style="color: hsl(120, 100%, 40%);">+              lchan_fail("Failed to change channel mode on the MS side: %s in state %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           osmo_fsm_event_name(fi->fsm, event),</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmo_fsm_inst_state_name(fi));</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void lchan_fsm_wait_rsl_chan_mode_modify_ack_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = rsl_chan_mode_modify_req(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              lchan_fail("Failed to send rsl message to change the channel mode on the BTS side: state %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_fsm_inst_state_name(fi));</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void lchan_fsm_wait_rsl_chan_mode_modify_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    case LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+               if (lchan->activate.info.requires_voice_stream)</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan_fsm_state_chg(LCHAN_ST_WAIT_RLL_RTP_ESTABLISH);</span><br><span style="color: hsl(120, 100%, 40%);">+         else</span><br><span style="color: hsl(120, 100%, 40%);">+                  lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED);</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     case LCHAN_EV_RSL_CHAN_MODE_MODIFY_NACK:</span><br><span style="color: hsl(120, 100%, 40%);">+              lchan_fail("Failed to change channel mode on the BTS side: %s in state %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          osmo_fsm_event_name(fi->fsm, event),</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmo_fsm_inst_state_name(fi));</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void lchan_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span> {</span><br><span>      struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span>@@ -909,6 +976,8 @@</span><br><span> static void lchan_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span>  struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct lchan_activate_info *info;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_mgcpc_ep_ci *use_mgwep_ci;</span><br><span> </span><br><span>   switch (event) {</span><br><span>     case LCHAN_EV_RLL_ESTABLISH_IND:</span><br><span>@@ -935,6 +1004,48 @@</span><br><span>                        osmo_fsm_inst_state_name(fi));</span><br><span>            return;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   case LCHAN_EV_REQUEST_MODE_MODIFY:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* FIXME: Add missing implementation to handle an already existing RTP voice stream on MODE MODIFY.</span><br><span style="color: hsl(120, 100%, 40%);">+            * there may be transitions from VOICE to SIGNALLING and also from VOICE to VOICE with a different</span><br><span style="color: hsl(120, 100%, 40%);">+             * codec. */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (lchan->fi_rtp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       lchan_fail("MODE MODIFY not implemented when RTP voice stream is already active (VOICE => SIGNALLING, VOICE/CODEC_A => VOICE/CODEC_B)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    return;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           info = data;</span><br><span style="color: hsl(120, 100%, 40%);">+          lchan->activate.info = *info;</span><br><span style="color: hsl(120, 100%, 40%);">+              use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (info->chan_mode == GSM48_CMODE_SPEECH_AMR) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (lchan_mr_config(lchan, info->s15_s0) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         lchan_fail("Can not generate multirate configuration IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                return;</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG_LCHAN(lchan, LOGL_INFO,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "Modification requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s encr-alg=A5/%u ck=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         lchan_activate_mode_name(lchan->activate.info.activ_for),</span><br><span style="color: hsl(120, 100%, 40%);">+                          lchan->activate.info.requires_voice_stream ? "yes" : "no",</span><br><span style="color: hsl(120, 100%, 40%);">+                     lchan->activate.info.requires_voice_stream ?</span><br><span style="color: hsl(120, 100%, 40%);">+                       (use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new")</span><br><span style="color: hsl(120, 100%, 40%);">+                        : "none",</span><br><span style="color: hsl(120, 100%, 40%);">+                   gsm_lchant_name(lchan->type),</span><br><span style="color: hsl(120, 100%, 40%);">+                      gsm48_chan_mode_name(lchan->tch_mode),</span><br><span style="color: hsl(120, 100%, 40%);">+                     (lchan->activate.info.encr.alg_id ? : 1) - 1,</span><br><span style="color: hsl(120, 100%, 40%);">+                      lchan->activate.info.encr.key_len ? osmo_hexdump_nospc(lchan->activate.info.encr.key,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                          lchan->activate.info.encr.key_len) : "none");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* While the mode is changed the lchan is virtually "not activated", at least</span><br><span style="color: hsl(120, 100%, 40%);">+                * from the FSM implementations perspective */</span><br><span style="color: hsl(120, 100%, 40%);">+                lchan->activate.concluded = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Initiate mode modification, start with the MS side (RR) */</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan_fsm_state_chg(LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK);</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    default:</span><br><span>             OSMO_ASSERT(false);</span><br><span>  }</span><br><span>@@ -1090,6 +1201,12 @@</span><br><span>   case LCHAN_ST_BORKEN:</span><br><span>                ctr = BTS_CTR_LCHAN_BORKEN_FROM_BORKEN;</span><br><span>              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+           ctr = BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RR_CHAN_MODE_MODIFY_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case LCHAN_ST_WAIT_RSL_CHAN_MODE_MODIFY_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+          ctr = BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RSL_CHAN_MODE_MODIFY_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span>       default:</span><br><span>             ctr = BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN;</span><br><span>     }</span><br><span>@@ -1223,6 +1340,32 @@</span><br><span>                   | S(LCHAN_ST_WAIT_RLL_RTP_RELEASED)</span><br><span>                  ,</span><br><span>    },</span><br><span style="color: hsl(120, 100%, 40%);">+    [LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK] = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .name = "WAIT_CHAN_RR_MODE_MODIFY_ACK",</span><br><span style="color: hsl(120, 100%, 40%);">+             .onenter = lchan_fsm_wait_rr_chan_mode_modify_ack_onenter,</span><br><span style="color: hsl(120, 100%, 40%);">+            .action = lchan_fsm_wait_rr_chan_mode_modify_ack,</span><br><span style="color: hsl(120, 100%, 40%);">+             .in_event_mask = 0</span><br><span style="color: hsl(120, 100%, 40%);">+                    | S(LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK)</span><br><span style="color: hsl(120, 100%, 40%);">+                 | S(LCHAN_EV_RR_CHAN_MODE_MODIFY_ERROR)</span><br><span style="color: hsl(120, 100%, 40%);">+                       ,</span><br><span style="color: hsl(120, 100%, 40%);">+             .out_state_mask = 0</span><br><span style="color: hsl(120, 100%, 40%);">+                   | S(LCHAN_ST_BORKEN)</span><br><span style="color: hsl(120, 100%, 40%);">+                  | S(LCHAN_ST_WAIT_RSL_CHAN_MODE_MODIFY_ACK)</span><br><span style="color: hsl(120, 100%, 40%);">+                   ,</span><br><span style="color: hsl(120, 100%, 40%);">+     },</span><br><span style="color: hsl(120, 100%, 40%);">+    [LCHAN_ST_WAIT_RSL_CHAN_MODE_MODIFY_ACK] = {</span><br><span style="color: hsl(120, 100%, 40%);">+          .name = "WAIT_RSL_CHAN_MODE_MODIFY_ACK",</span><br><span style="color: hsl(120, 100%, 40%);">+            .onenter = lchan_fsm_wait_rsl_chan_mode_modify_ack_onenter,</span><br><span style="color: hsl(120, 100%, 40%);">+           .action = lchan_fsm_wait_rsl_chan_mode_modify_ack,</span><br><span style="color: hsl(120, 100%, 40%);">+            .in_event_mask = 0</span><br><span style="color: hsl(120, 100%, 40%);">+                    | S(LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK)</span><br><span style="color: hsl(120, 100%, 40%);">+                        | S(LCHAN_EV_RSL_CHAN_MODE_MODIFY_NACK)</span><br><span style="color: hsl(120, 100%, 40%);">+                       ,</span><br><span style="color: hsl(120, 100%, 40%);">+             .out_state_mask = 0</span><br><span style="color: hsl(120, 100%, 40%);">+                   | S(LCHAN_ST_BORKEN)</span><br><span style="color: hsl(120, 100%, 40%);">+                  | S(LCHAN_ST_WAIT_RLL_RTP_ESTABLISH)</span><br><span style="color: hsl(120, 100%, 40%);">+                  ,</span><br><span style="color: hsl(120, 100%, 40%);">+     },</span><br><span>   [LCHAN_ST_ESTABLISHED] = {</span><br><span>           .name = "ESTABLISHED",</span><br><span>             .onenter = lchan_fsm_established_onenter,</span><br><span>@@ -1233,12 +1376,14 @@</span><br><span>                  | S(LCHAN_EV_RLL_ESTABLISH_IND) /* ignored */</span><br><span>                        | S(LCHAN_EV_RTP_ERROR)</span><br><span>                      | S(LCHAN_EV_RTP_RELEASED)</span><br><span style="color: hsl(120, 100%, 40%);">+                    | S(LCHAN_EV_REQUEST_MODE_MODIFY)</span><br><span>                    ,</span><br><span>            .out_state_mask = 0</span><br><span>                  | S(LCHAN_ST_UNUSED)</span><br><span>                         | S(LCHAN_ST_WAIT_RLL_RTP_RELEASED)</span><br><span>                  | S(LCHAN_ST_WAIT_BEFORE_RF_RELEASE)</span><br><span>                         | S(LCHAN_ST_WAIT_RF_RELEASE_ACK)</span><br><span style="color: hsl(120, 100%, 40%);">+                     | S(LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK)</span><br><span>                   ,</span><br><span>    },</span><br><span>   [LCHAN_ST_WAIT_RLL_RTP_RELEASED] = {</span><br><span>@@ -1324,8 +1469,10 @@</span><br><span>        OSMO_VALUE_STRING(LCHAN_EV_RLL_REL_CONF),</span><br><span>    OSMO_VALUE_STRING(LCHAN_EV_RSL_RF_CHAN_REL_ACK),</span><br><span>     OSMO_VALUE_STRING(LCHAN_EV_RLL_ERR_IND),</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_VALUE_STRING(LCHAN_EV_CHAN_MODE_MODIF_ACK),</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_VALUE_STRING(LCHAN_EV_CHAN_MODE_MODIF_ERROR),</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_VALUE_STRING(LCHAN_EV_RR_CHAN_MODE_MODIFY_ACK),</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_VALUE_STRING(LCHAN_EV_RR_CHAN_MODE_MODIFY_ERROR),</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_VALUE_STRING(LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_VALUE_STRING(LCHAN_EV_RSL_CHAN_MODE_MODIFY_NACK),</span><br><span>       {}</span><br><span> };</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/19792">change 19792</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bsc/+/19792"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I2c5a283b1ee33745cc1fcfcc09a0f9382224e2eb </div>
<div style="display:none"> Gerrit-Change-Number: 19792 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>