<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12388">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">make sure early lchan act failure resets the lchan<br><br>Fix crash after AMR configuration fails.<br><br>The crash is due to an assertion that finds a non-NULL conn in the lchan, when<br>re-using an lchan that has failed in AMR configuration earlier on. That is<br>because the AMR config still happens in state UNUSED.<br><br> DCHAN ERROR lchan(0-0-2-TCH_F_TCH_H_PDCH-0)[0x6120000066a0]{UNUSED}: (type=TCH_F) lchan allocation failed in state UNUSED: Can not generate multirate configuration IE<br> ...<br> DCHAN DEBUG lchan(0-0-2-TCH_F_TCH_H_PDCH-0)[0x6120000066a0]{UNUSED}: (type=TCH_F) After failure handling, already in state UNUSED<br> ...<br> ...<br> DCHAN DEBUG lchan(0-0-2-TCH_F_TCH_H_PDCH-0)[0x6120000066a0]{UNUSED}: Received Event LCHAN_EV_ACTIVATE (lchan_fsm.c:324)<br> Assert failed !lchan->conn ../../../../src/osmo-bsc/src/osmo-bsc/lchan_fsm.c:491<br><br>The FSM design idea is that when returning to the UNUSED state, all lchan state<br>is cleared. However, when calling lchan_activate(), a failure may happen still<br>in state UNUSED, so that we don't transition *back* to UNUSED properly.<br><br>So, first transition out of UNUSED before failures can happen. (Other ways to<br>solve this would be to invoke lchan clearing even if already in UNUSED, but<br>semantically, transitioning first makes more sense.)<br><br>Upon LCHAN_EV_ACTIVATE, just remember the lchan_activate_info and transition to<br>WAIT_TS_READY, so that on lchan_fail(), we can normally transition back to<br>UNUSED and clear the lchan.<br><br>Move the initial lchan activation code to lchan_fsm_wait_ts_ready_onenter().<br><br>Also, there is a bit of duplication of members of the lchan->activate (lchan<br>state) and the lchan_activate_info (passed to lchan_activate()) structs. The<br>fix for this also removes the dup:<br><br>Add struct lchan_activate_info as child struct at lchan->activate.info, drop<br>the other lchan->activate members that would dup .info.*. Move struct<br>lchan_activate_info declaration to gsm_data.h.<br><br>Apply the new '.info' member struct throughout the code.<br><br>Related: OS#3737<br>Change-Id: Ide665b10fa3f4583059c55346db8da833959e3cc<br>---<br>M include/osmocom/bsc/gsm_data.h<br>M include/osmocom/bsc/lchan_fsm.h<br>M src/osmo-bsc/assignment_fsm.c<br>M src/osmo-bsc/bsc_subscr_conn_fsm.c<br>M src/osmo-bsc/handover_fsm.c<br>M src/osmo-bsc/lchan_fsm.c<br>M src/osmo-bsc/lchan_rtp_fsm.c<br>M src/osmo-bsc/osmo_bsc_bssap.c<br>8 files changed, 105 insertions(+), 107 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index cf34c6f..2090142 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -503,6 +503,19 @@</span><br><span> static inline const char *lchan_activate_mode_name(enum lchan_activate_mode activ_for)</span><br><span> { return get_value_string(lchan_activate_mode_names, activ_for); }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct lchan_activate_info {</span><br><span style="color: hsl(120, 100%, 40%);">+ enum lchan_activate_mode activ_for;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_subscriber_connection *for_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* This always is for a specific lchan, so its lchan->type indicates full or half rate.</span><br><span style="color: hsl(120, 100%, 40%);">+ * When a dyn TS was selected, the lchan->type has been set to the desired rate. */</span><br><span style="color: hsl(120, 100%, 40%);">+ enum gsm48_chan_mode chan_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t s15_s0;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool requires_voice_stream;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool wait_before_switching_rtp; /*< true = requires LCHAN_EV_READY_TO_SWITCH_RTP */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t msc_assigned_cic;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *re_use_mgw_endpoint_from_lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct gsm_lchan {</span><br><span> /* The TS that we're part of */</span><br><span> struct gsm_bts_trx_ts *ts;</span><br><span>@@ -517,18 +530,14 @@</span><br><span> struct mgwep_ci *mgw_endpoint_ci_bts;</span><br><span> </span><br><span> struct {</span><br><span style="color: hsl(0, 100%, 40%);">- enum lchan_activate_mode activ_for;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct lchan_activate_info info;</span><br><span> bool activ_ack; /*< true as soon as RSL Chan Activ Ack is received */</span><br><span> bool immediate_assignment_sent;</span><br><span> /*! This flag ensures that when an lchan activation has succeeded, and we have already</span><br><span> * sent ACKs like Immediate Assignment or BSSMAP Assignment Complete, and if other errors</span><br><span> * occur later, e.g. during release, that we don't send a NACK out of context. */</span><br><span> bool concluded;</span><br><span style="color: hsl(0, 100%, 40%);">- bool requires_voice_stream;</span><br><span style="color: hsl(0, 100%, 40%);">- bool wait_before_switching_rtp; /*< true = requires LCHAN_EV_READY_TO_SWITCH_RTP */</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t msc_assigned_cic;</span><br><span> enum gsm0808_cause gsm0808_error_cause;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_lchan *re_use_mgw_endpoint_from_lchan;</span><br><span> } activate;</span><br><span> </span><br><span> struct {</span><br><span>diff --git a/include/osmocom/bsc/lchan_fsm.h b/include/osmocom/bsc/lchan_fsm.h</span><br><span>index 48cd383..55ab024 100644</span><br><span>--- a/include/osmocom/bsc/lchan_fsm.h</span><br><span>+++ b/include/osmocom/bsc/lchan_fsm.h</span><br><span>@@ -52,19 +52,6 @@</span><br><span> void lchan_release(struct gsm_lchan *lchan, bool do_rr_release,</span><br><span> bool err, enum gsm48_rr_cause cause_rr);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct lchan_activate_info {</span><br><span style="color: hsl(0, 100%, 40%);">- enum lchan_activate_mode activ_for;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_subscriber_connection *for_conn;</span><br><span style="color: hsl(0, 100%, 40%);">- /* This always is for a specific lchan, so its lchan->type indicates full or half rate.</span><br><span style="color: hsl(0, 100%, 40%);">- * When a dyn TS was selected, the lchan->type has been set to the desired rate. */</span><br><span style="color: hsl(0, 100%, 40%);">- enum gsm48_chan_mode chan_mode;</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t s15_s0;</span><br><span style="color: hsl(0, 100%, 40%);">- bool requires_voice_stream;</span><br><span style="color: hsl(0, 100%, 40%);">- bool wait_before_switching_rtp;</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t msc_assigned_cic;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_lchan *old_lchan;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void lchan_activate(struct gsm_lchan *lchan, struct lchan_activate_info *info);</span><br><span> void lchan_ready_to_switch_rtp(struct gsm_lchan *lchan);</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c</span><br><span>index 93362f8..a24f7f9 100644</span><br><span>--- a/src/osmo-bsc/assignment_fsm.c</span><br><span>+++ b/src/osmo-bsc/assignment_fsm.c</span><br><span>@@ -385,7 +385,7 @@</span><br><span> .s15_s0 = req->s15_s0,</span><br><span> .requires_voice_stream = conn->assignment.requires_voice_stream,</span><br><span> .msc_assigned_cic = req->msc_assigned_cic,</span><br><span style="color: hsl(0, 100%, 40%);">- .old_lchan = conn->lchan,</span><br><span style="color: hsl(120, 100%, 40%);">+ .re_use_mgw_endpoint_from_lchan = conn->lchan,</span><br><span> };</span><br><span> lchan_activate(conn->assignment.new_lchan, &info);</span><br><span> }</span><br><span>diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>index 85e754f..c1ac6eb 100644</span><br><span>--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>@@ -550,7 +550,7 @@</span><br><span> } else</span><br><span> verb = MGCP_VERB_CRCX;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- gscon_ensure_mgw_endpoint(conn, for_lchan->activate.msc_assigned_cic);</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon_ensure_mgw_endpoint(conn, for_lchan->activate.info.msc_assigned_cic);</span><br><span> </span><br><span> if (!conn->user_plane.mgw_endpoint) {</span><br><span> LOGPFSML(conn->fi, LOGL_ERROR, "Unable to allocate endpoint info\n");</span><br><span>diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c</span><br><span>index aae50b9..35f2e55 100644</span><br><span>--- a/src/osmo-bsc/handover_fsm.c</span><br><span>+++ b/src/osmo-bsc/handover_fsm.c</span><br><span>@@ -360,7 +360,7 @@</span><br><span> .chan_mode = conn->lchan->tch_mode,</span><br><span> .requires_voice_stream = conn->lchan->mgw_endpoint_ci_bts ? true : false,</span><br><span> .msc_assigned_cic = conn->ho.inter_bsc_in.msc_assigned_cic,</span><br><span style="color: hsl(0, 100%, 40%);">- .old_lchan = conn->lchan,</span><br><span style="color: hsl(120, 100%, 40%);">+ .re_use_mgw_endpoint_from_lchan = conn->lchan,</span><br><span> .wait_before_switching_rtp = true,</span><br><span> };</span><br><span> </span><br><span>@@ -706,7 +706,7 @@</span><br><span> ho_perf_params.chosen_encr_alg = lchan->encr.alg_id;</span><br><span> ho_perf_params.chosen_encr_alg_present = true;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (ho->new_lchan->activate.requires_voice_stream) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ho->new_lchan->activate.info.requires_voice_stream) {</span><br><span> /* Speech Version (chosen) 3.2.2.51 */</span><br><span> ho_perf_params.speech_version_chosen = gsm0808_permitted_speech(lchan->type, lchan->tch_mode);</span><br><span> ho_perf_params.speech_version_chosen_present = true;</span><br><span>@@ -1010,7 +1010,7 @@</span><br><span> struct gsm_subscriber_connection *conn = ho_fi_conn(fi);</span><br><span> struct handover *ho = &conn->ho;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (ho->new_lchan->activate.requires_voice_stream</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ho->new_lchan->activate.info.requires_voice_stream</span><br><span> && (ho->scope & HO_INTER_BSC_IN))</span><br><span> ho_fsm_state_chg(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC);</span><br><span> else</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index c873025..fc1bcbf 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -151,7 +151,7 @@</span><br><span> return;</span><br><span> lchan->activate.concluded = true;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- switch (lchan->activate.activ_for) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (lchan->activate.info.activ_for) {</span><br><span> case FOR_MS_CHANNEL_REQUEST:</span><br><span> /* No signalling to do here, MS is free to use the channel, and should go on to connect</span><br><span> * to the MSC and establish a subscriber connection. */</span><br><span>@@ -201,7 +201,7 @@</span><br><span> </span><br><span> default:</span><br><span> LOG_LCHAN(lchan, LOGL_NOTICE, "lchan %s fully established\n",</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_activate_mode_name(lchan->activate.activ_for));</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan_activate_mode_name(lchan->activate.info.activ_for));</span><br><span> break;</span><br><span> }</span><br><span> }</span><br><span>@@ -238,7 +238,7 @@</span><br><span> lchan_set_last_error(_lchan, "lchan %s in state %s: " fmt, \</span><br><span> _lchan->activate.concluded ? "failure" : "allocation failed", \</span><br><span> osmo_fsm_state_name(fsm, state_was), ## args); \</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_on_activation_failure(_lchan, _lchan->activate.activ_for, _lchan->conn); \</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan_on_activation_failure(_lchan, _lchan->activate.info.activ_for, _lchan->conn); \</span><br><span> if (fi->state != state_chg) \</span><br><span> lchan_fsm_state_chg(state_chg); \</span><br><span> else \</span><br><span>@@ -481,8 +481,6 @@</span><br><span> {</span><br><span> struct lchan_activate_info *info = data;</span><br><span> struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm48_multi_rate_conf mr_conf;</span><br><span> </span><br><span> switch (event) {</span><br><span> </span><br><span>@@ -493,63 +491,8 @@</span><br><span> lchan_set_last_error(lchan, NULL);</span><br><span> lchan->release.requested = false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- lchan->conn = info->for_conn;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.activ_for = info->activ_for;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.requires_voice_stream = info->requires_voice_stream;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.wait_before_switching_rtp = info->wait_before_switching_rtp;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.msc_assigned_cic = info->msc_assigned_cic;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->activate.info = *info;</span><br><span> lchan->activate.concluded = false;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.re_use_mgw_endpoint_from_lchan = info->old_lchan;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (info->old_lchan)</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->encr = info->old_lchan->encr;</span><br><span style="color: hsl(0, 100%, 40%);">- else {</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->encr = (struct gsm_encr){</span><br><span style="color: hsl(0, 100%, 40%);">- .alg_id = RSL_ENC_ALG_A5(0), /* no encryption */</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* If there is a previous lchan, and the new lchan is on the same cell as previous one,</span><br><span style="color: hsl(0, 100%, 40%);">- * take over power and TA values. Otherwise, use max power and zero TA. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (info->old_lchan && info->old_lchan->ts->trx->bts == bts) {</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->ms_power = info->old_lchan->ms_power;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->bs_power = info->old_lchan->bs_power;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->rqd_ta = info->old_lchan->rqd_ta;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);</span><br><span style="color: hsl(0, 100%, 40%);">- /* From lchan_reset():</span><br><span style="color: hsl(0, 100%, 40%);">- * - bs_power is still zero, 0dB reduction, output power = Pn.</span><br><span style="color: hsl(0, 100%, 40%);">- * - TA is still zero, to be determined by RACH. */</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%);">- if (info->chan_mode == GSM48_CMODE_SPEECH_AMR) {</span><br><span style="color: hsl(0, 100%, 40%);">- gsm48_mr_cfg_from_gsm0808_sc_cfg(&mr_conf, info->s15_s0);</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan_mr_config(lchan, &mr_conf) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_fail("Can not generate multirate configuration IE\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return;</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- switch (info->chan_mode) {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SIGN:</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->tch_mode = GSM48_CMODE_SIGN;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SPEECH_V1:</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SPEECH_EFR:</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SPEECH_AMR:</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->tch_mode = info->chan_mode;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_fail("Not implemented: cannot activate for chan mode %s",</span><br><span style="color: hsl(0, 100%, 40%);">- gsm48_chan_mode_name(info->chan_mode));</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> lchan_fsm_state_chg(LCHAN_ST_WAIT_TS_READY);</span><br><span> break;</span><br><span> </span><br><span>@@ -561,18 +504,75 @@</span><br><span> static void lchan_fsm_wait_ts_ready_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 style="color: hsl(0, 100%, 40%);">- struct mgwep_ci *use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm48_multi_rate_conf mr_conf;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgwep_ci *use_mgwep_ci;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct lchan_activate_info *info = &lchan->activate.info;</span><br><span> </span><br><span> if (lchan->release.requested) {</span><br><span> lchan_fail("Release requested while activating");</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->conn = info->for_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (old_lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->encr = old_lchan->encr;</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->encr = (struct gsm_encr){</span><br><span style="color: hsl(120, 100%, 40%);">+ .alg_id = RSL_ENC_ALG_A5(0), /* no encryption */</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%);">+ /* If there is a previous lchan, and the new lchan is on the same cell as previous one,</span><br><span style="color: hsl(120, 100%, 40%);">+ * take over power and TA values. Otherwise, use max power and zero TA. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (old_lchan && old_lchan->ts->trx->bts == bts) {</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ms_power = old_lchan->ms_power;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->bs_power = old_lchan->bs_power;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->rqd_ta = old_lchan->rqd_ta;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* From lchan_reset():</span><br><span style="color: hsl(120, 100%, 40%);">+ * - bs_power is still zero, 0dB reduction, output power = Pn.</span><br><span style="color: hsl(120, 100%, 40%);">+ * - TA is still zero, to be determined by RACH. */</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%);">+ if (info->chan_mode == GSM48_CMODE_SPEECH_AMR) {</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_mr_cfg_from_gsm0808_sc_cfg(&mr_conf, info->s15_s0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan_mr_config(lchan, &mr_conf) < 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%);">+ switch (info->chan_mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SIGN:</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->tch_mode = GSM48_CMODE_SIGN;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SPEECH_V1:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SPEECH_EFR:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SPEECH_AMR:</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->tch_mode = info->chan_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</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%);">+ lchan_fail("Not implemented: cannot activate for chan mode %s",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_chan_mode_name(info->chan_mode));</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%);">+ use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> LOG_LCHAN(lchan, LOGL_INFO,</span><br><span> "Activation requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_activate_mode_name(lchan->activate.activ_for),</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.requires_voice_stream ? "yes" : "no",</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.requires_voice_stream ?</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> (use_mgwep_ci ? mgwep_ci_name(use_mgwep_ci) : "new")</span><br><span> : "none",</span><br><span> gsm_lchant_name(lchan->type),</span><br><span>@@ -583,7 +583,7 @@</span><br><span> osmo_fsm_inst_dispatch(lchan->ts->fi, TS_EV_LCHAN_REQUESTED, lchan);</span><br><span> </span><br><span> /* Prepare an MGW endpoint CI if appropriate. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->activate.requires_voice_stream)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->activate.info.requires_voice_stream)</span><br><span> lchan_rtp_fsm_start(lchan);</span><br><span> }</span><br><span> </span><br><span>@@ -627,7 +627,7 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- switch (lchan->activate.activ_for) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (lchan->activate.info.activ_for) {</span><br><span> case FOR_MS_CHANNEL_REQUEST:</span><br><span> act_type = RSL_ACT_INTRA_IMM_ASS;</span><br><span> break;</span><br><span>@@ -709,7 +709,7 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- switch (lchan->activate.activ_for) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (lchan->activate.info.activ_for) {</span><br><span> </span><br><span> case FOR_MS_CHANNEL_REQUEST:</span><br><span> rc = rsl_tx_imm_assignment(lchan);</span><br><span>@@ -764,7 +764,7 @@</span><br><span> </span><br><span> default:</span><br><span> LOG_LCHAN(lchan, LOGL_NOTICE, "lchan %s is now active\n",</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_activate_mode_name(lchan->activate.activ_for));</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan_activate_mode_name(lchan->activate.info.activ_for));</span><br><span> break;</span><br><span> }</span><br><span> </span><br><span>@@ -784,7 +784,7 @@</span><br><span> switch (event) {</span><br><span> </span><br><span> case LCHAN_EV_RLL_ESTABLISH_IND:</span><br><span style="color: hsl(0, 100%, 40%);">- if (!lchan->activate.requires_voice_stream</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!lchan->activate.info.requires_voice_stream</span><br><span> || lchan_rtp_established(lchan))</span><br><span> lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED);</span><br><span> return;</span><br><span>@@ -1381,6 +1381,8 @@</span><br><span> if (!lchan)</span><br><span> return;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->activate.info.for_conn = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> conn = lchan->conn;</span><br><span> if (conn) {</span><br><span> /* Log for both lchan FSM and conn FSM to ease reading the log in case of problems */</span><br><span>diff --git a/src/osmo-bsc/lchan_rtp_fsm.c b/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>index 6ab3da4..84cc287 100644</span><br><span>--- a/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>@@ -111,9 +111,9 @@</span><br><span> </span><br><span> /* Use old lchan only if there is an MGW endpoint present. Otherwise, on ROLLBACK, we might put</span><br><span> * an endpoint "back" to an lchan that never had one to begin with. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->activate.re_use_mgw_endpoint_from_lchan</span><br><span style="color: hsl(0, 100%, 40%);">- && !lchan->activate.re_use_mgw_endpoint_from_lchan->mgw_endpoint_ci_bts)</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.re_use_mgw_endpoint_from_lchan = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->activate.info.re_use_mgw_endpoint_from_lchan</span><br><span style="color: hsl(120, 100%, 40%);">+ && !lchan->activate.info.re_use_mgw_endpoint_from_lchan->mgw_endpoint_ci_bts)</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->activate.info.re_use_mgw_endpoint_from_lchan = NULL;</span><br><span> </span><br><span> lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_MGW_ENDPOINT_AVAILABLE);</span><br><span> }</span><br><span>@@ -127,8 +127,8 @@</span><br><span> return lchan->mgw_endpoint_ci_bts;</span><br><span> if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED))</span><br><span> return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->activate.re_use_mgw_endpoint_from_lchan)</span><br><span style="color: hsl(0, 100%, 40%);">- return lchan->activate.re_use_mgw_endpoint_from_lchan->mgw_endpoint_ci_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->activate.info.re_use_mgw_endpoint_from_lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+ return lchan->activate.info.re_use_mgw_endpoint_from_lchan->mgw_endpoint_ci_bts;</span><br><span> return NULL;</span><br><span> }</span><br><span> </span><br><span>@@ -147,7 +147,7 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- mgwep = gscon_ensure_mgw_endpoint(lchan->conn, lchan->activate.msc_assigned_cic);</span><br><span style="color: hsl(120, 100%, 40%);">+ mgwep = gscon_ensure_mgw_endpoint(lchan->conn, lchan->activate.info.msc_assigned_cic);</span><br><span> if (!mgwep) {</span><br><span> lchan_rtp_fail("Internal error: cannot obtain MGW endpoint handle for conn");</span><br><span> return;</span><br><span>@@ -232,7 +232,7 @@</span><br><span> {</span><br><span> struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->activate.wait_before_switching_rtp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->activate.info.wait_before_switching_rtp) {</span><br><span> LOG_LCHAN_RTP(lchan, LOGL_DEBUG,</span><br><span> "Waiting for an event by caller before switching RTP\n");</span><br><span> lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_READY_TO_SWITCH_RTP);</span><br><span>@@ -305,7 +305,7 @@</span><br><span> return;</span><br><span> </span><br><span> case LCHAN_RTP_EV_READY_TO_SWITCH_RTP:</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.wait_before_switching_rtp = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->activate.info.wait_before_switching_rtp = false;</span><br><span> return;</span><br><span> </span><br><span> case LCHAN_RTP_EV_RELEASE:</span><br><span>@@ -365,7 +365,7 @@</span><br><span> return;</span><br><span> </span><br><span> case LCHAN_RTP_EV_READY_TO_SWITCH_RTP:</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.wait_before_switching_rtp = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->activate.info.wait_before_switching_rtp = false;</span><br><span> return;</span><br><span> </span><br><span> case LCHAN_RTP_EV_RELEASE:</span><br><span>@@ -437,7 +437,7 @@</span><br><span> uint32_t prev_state)</span><br><span> {</span><br><span> struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_lchan *old_lchan = lchan->activate.re_use_mgw_endpoint_from_lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;</span><br><span> </span><br><span> if (lchan->release.requested) {</span><br><span> lchan_rtp_fail("Release requested while activating");</span><br><span>@@ -514,7 +514,7 @@</span><br><span> static void lchan_rtp_fsm_rollback_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span> {</span><br><span> struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_lchan *old_lchan = lchan->activate.re_use_mgw_endpoint_from_lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;</span><br><span> </span><br><span> if (!lchan->mgw_endpoint_ci_bts || !old_lchan) {</span><br><span> osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, 0);</span><br><span>@@ -526,7 +526,7 @@</span><br><span> static void lchan_rtp_fsm_rollback(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span> struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_lchan *old_lchan = lchan->activate.re_use_mgw_endpoint_from_lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;</span><br><span> </span><br><span> switch (event) {</span><br><span> </span><br><span>@@ -560,7 +560,7 @@</span><br><span> struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi);</span><br><span> </span><br><span> /* Make sure that we will not hand back the MGW endpoint to any old lchan from here on. */</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->activate.re_use_mgw_endpoint_from_lchan = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->activate.info.re_use_mgw_endpoint_from_lchan = NULL;</span><br><span> }</span><br><span> </span><br><span> static void lchan_rtp_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>index 60ec5fb..f2ccf2c 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>@@ -1101,7 +1101,7 @@</span><br><span> };</span><br><span> </span><br><span> /* speech_codec_chosen */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ho->new_lchan->activate.requires_voice_stream && gscon_is_aoip(conn)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ho->new_lchan->activate.info.requires_voice_stream && gscon_is_aoip(conn)) {</span><br><span> int perm_spch = gsm0808_permitted_speech(lchan->type, lchan->tch_mode);</span><br><span> params.speech_codec_chosen_present = true;</span><br><span> rc = gsm0808_speech_codec_from_chan_type(¶ms.speech_codec_chosen, perm_spch);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12388">change 12388</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/12388"/><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-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ide665b10fa3f4583059c55346db8da833959e3cc </div>
<div style="display:none"> Gerrit-Change-Number: 12388 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: Pau Espin Pedrol <pespin@sysmocom.de> </div>