requires_voice_stream -> ch_indctr
Use the full gsm0808_chan_indicator value throughout the lchan related structs (assignment_fsm_data, gsm_lchan, lchan_activate_info, lchan_modify_info) instead of reducing it to the boolean requires_voice_stream. This is needed so we don't lose the information whether an lchan was requested for data or speech (both need an rtp stream). Add a new bsc_chan_ind_requires_rtp_stream function and use it in conditionals like the previous requires_voice_stream. Related: OS#4393 Change-Id: I1538c1e6d5cd61559af7c1e2860afd0269dda367
This commit is contained in:
parent
2fd39821f6
commit
41ede5345c
|
@ -15,7 +15,7 @@ msc {
|
||||||
ts note ts [label="A dyn TS may be in PDCH mode and will asynchronously switch off PDCH first. A
|
ts note ts [label="A dyn TS may be in PDCH mode and will asynchronously switch off PDCH first. A
|
||||||
non-dynamic TS is ready immediately."];
|
non-dynamic TS is ready immediately."];
|
||||||
|||;
|
|||;
|
||||||
--- [label="IF requires_voice_stream"];
|
--- [label="IF requires_rtp_stream"];
|
||||||
lchan -> rtp [label="lchan_rtp_fsm_start()"];
|
lchan -> rtp [label="lchan_rtp_fsm_start()"];
|
||||||
rtp abox rtp [label="allocate\n LCHAN_RTP_ST_\nWAIT_MGW_ENDPOINT_\nAVAILABLE"];
|
rtp abox rtp [label="allocate\n LCHAN_RTP_ST_\nWAIT_MGW_ENDPOINT_\nAVAILABLE"];
|
||||||
--- [label="IF no endpoint-CI yet"];
|
--- [label="IF no endpoint-CI yet"];
|
||||||
|
@ -29,7 +29,7 @@ msc {
|
||||||
rtp note mgwep [label="The CRCX OK has assigned us a new endpoint CI number"];
|
rtp note mgwep [label="The CRCX OK has assigned us a new endpoint CI number"];
|
||||||
rtp abox rtp [label="LCHAN_RTP_ST_WAIT_LCHAN_READY"];
|
rtp abox rtp [label="LCHAN_RTP_ST_WAIT_LCHAN_READY"];
|
||||||
--- [label="END: no endpoint-CI yet"];
|
--- [label="END: no endpoint-CI yet"];
|
||||||
--- [label="END: requires_voice_stream"];
|
--- [label="END: requires_rtp_stream"];
|
||||||
|||;
|
|||;
|
||||||
...;
|
...;
|
||||||
ts -> lchan [label="LCHAN_EV_TS_READY"];
|
ts -> lchan [label="LCHAN_EV_TS_READY"];
|
||||||
|
@ -60,7 +60,7 @@ msc {
|
||||||
lchan abox lchan [label="LCHAN_ST_WAIT_\nRLL_RTP_ESTABLISH\nT3101"];
|
lchan abox lchan [label="LCHAN_ST_WAIT_\nRLL_RTP_ESTABLISH\nT3101"];
|
||||||
|||;
|
|||;
|
||||||
|||;
|
|||;
|
||||||
--- [label="IF requires_voice_stream"];
|
--- [label="IF requires_rtp_stream"];
|
||||||
lchan -> rtp [label="LCHAN_RTP_EV_LCHAN_READY"];
|
lchan -> rtp [label="LCHAN_RTP_EV_LCHAN_READY"];
|
||||||
|||;
|
|||;
|
||||||
--- [label="IF ip.access style BTS"];
|
--- [label="IF ip.access style BTS"];
|
||||||
|
@ -99,7 +99,7 @@ msc {
|
||||||
...;
|
...;
|
||||||
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED\nvia gscon_change_primary_lchan()"];
|
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED\nvia gscon_change_primary_lchan()"];
|
||||||
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
|
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
|
||||||
--- [label="END: requires_voice_stream"];
|
--- [label="END: requires_rtp_stream"];
|
||||||
|||;
|
|||;
|
||||||
|||;
|
|||;
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ msc {
|
||||||
lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ESTABLISHED\n(see Handover FSM diagrams)"];
|
lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ESTABLISHED\n(see Handover FSM diagrams)"];
|
||||||
--- [label="END"];
|
--- [label="END"];
|
||||||
...;
|
...;
|
||||||
--- [label="IF requires_voice_stream"];
|
--- [label="IF requires_rtp_stream"];
|
||||||
lchan rbox lchan [label="Assignment or Handover FSM:"];
|
lchan rbox lchan [label="Assignment or Handover FSM:"];
|
||||||
lchan -> mgwep [label="CRCX/MDCX to-MSC"];
|
lchan -> mgwep [label="CRCX/MDCX to-MSC"];
|
||||||
...;
|
...;
|
||||||
|
@ -125,7 +125,7 @@ msc {
|
||||||
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED"];
|
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED"];
|
||||||
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
|
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
|
||||||
rtp box rtp [label="Forget any Rollback info"];
|
rtp box rtp [label="Forget any Rollback info"];
|
||||||
--- [label="END: requires_voice_stream"];
|
--- [label="END: requires_rtp_stream"];
|
||||||
|
|
||||||
...;
|
...;
|
||||||
...;
|
...;
|
||||||
|
|
|
@ -13,3 +13,4 @@ void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct ms
|
||||||
void bsc_cm_update(struct gsm_subscriber_connection *conn,
|
void bsc_cm_update(struct gsm_subscriber_connection *conn,
|
||||||
const uint8_t *cm2, uint8_t cm2_len,
|
const uint8_t *cm2, uint8_t cm2_len,
|
||||||
const uint8_t *cm3, uint8_t cm3_len);
|
const uint8_t *cm3, uint8_t cm3_len);
|
||||||
|
bool bsc_chan_ind_requires_rtp_stream(enum gsm0808_chan_indicator ch_indctr);
|
||||||
|
|
|
@ -179,7 +179,7 @@ struct assignment_fsm_data {
|
||||||
*/
|
*/
|
||||||
struct assignment_request req;
|
struct assignment_request req;
|
||||||
|
|
||||||
bool requires_voice_stream;
|
enum gsm0808_chan_indicator ch_indctr;
|
||||||
struct channel_mode_and_rate selected_ch_mode_rate;
|
struct channel_mode_and_rate selected_ch_mode_rate;
|
||||||
|
|
||||||
struct osmo_fsm_inst *fi;
|
struct osmo_fsm_inst *fi;
|
||||||
|
|
|
@ -122,7 +122,7 @@ struct lchan_activate_info {
|
||||||
struct gsm_subscriber_connection *for_conn;
|
struct gsm_subscriber_connection *for_conn;
|
||||||
struct channel_mode_and_rate ch_mode_rate;
|
struct channel_mode_and_rate ch_mode_rate;
|
||||||
struct gsm_encr encr;
|
struct gsm_encr encr;
|
||||||
bool requires_voice_stream;
|
enum gsm0808_chan_indicator ch_indctr;
|
||||||
bool wait_before_switching_rtp; /*< true = requires LCHAN_EV_READY_TO_SWITCH_RTP */
|
bool wait_before_switching_rtp; /*< true = requires LCHAN_EV_READY_TO_SWITCH_RTP */
|
||||||
uint16_t msc_assigned_cic;
|
uint16_t msc_assigned_cic;
|
||||||
/* During intra-BSC handover, we keep the MGW endpoint intact and just re-route to the new lchan. This
|
/* During intra-BSC handover, we keep the MGW endpoint intact and just re-route to the new lchan. This
|
||||||
|
@ -159,7 +159,7 @@ static inline const char *lchan_modify_for_name(enum lchan_modify_for modify_for
|
||||||
struct lchan_modify_info {
|
struct lchan_modify_info {
|
||||||
enum lchan_modify_for modify_for;
|
enum lchan_modify_for modify_for;
|
||||||
struct channel_mode_and_rate ch_mode_rate;
|
struct channel_mode_and_rate ch_mode_rate;
|
||||||
bool requires_voice_stream;
|
enum gsm0808_chan_indicator ch_indctr;
|
||||||
uint16_t msc_assigned_cic;
|
uint16_t msc_assigned_cic;
|
||||||
|
|
||||||
/* The TSC Set to use if 'use' is true, otherwise automatically determine the TSC Set value to use. Valid range
|
/* The TSC Set to use if 'use' is true, otherwise automatically determine the TSC Set value to use. Valid range
|
||||||
|
@ -216,6 +216,7 @@ struct gsm_lchan {
|
||||||
|
|
||||||
struct channel_mode_and_rate ch_mode_rate;
|
struct channel_mode_and_rate ch_mode_rate;
|
||||||
struct gsm48_multi_rate_conf mr_conf_filtered;
|
struct gsm48_multi_rate_conf mr_conf_filtered;
|
||||||
|
enum gsm0808_chan_indicator ch_indctr;
|
||||||
bool activ_ack; /*< true as soon as RSL Chan Activ Ack is received */
|
bool activ_ack; /*< true as soon as RSL Chan Activ Ack is received */
|
||||||
bool immediate_assignment_sent;
|
bool immediate_assignment_sent;
|
||||||
/*! This flag ensures that when an lchan activation has succeeded, and we have already
|
/*! This flag ensures that when an lchan activation has succeeded, and we have already
|
||||||
|
@ -239,6 +240,7 @@ struct gsm_lchan {
|
||||||
|
|
||||||
struct channel_mode_and_rate ch_mode_rate;
|
struct channel_mode_and_rate ch_mode_rate;
|
||||||
struct gsm48_multi_rate_conf mr_conf_filtered;
|
struct gsm48_multi_rate_conf mr_conf_filtered;
|
||||||
|
enum gsm0808_chan_indicator ch_indctr;
|
||||||
/* Actually used TSC Set. */
|
/* Actually used TSC Set. */
|
||||||
int tsc_set;
|
int tsc_set;
|
||||||
/* Actually used TSC. */
|
/* Actually used TSC. */
|
||||||
|
@ -324,6 +326,7 @@ struct gsm_lchan {
|
||||||
* channel_mode_and_rate. */
|
* channel_mode_and_rate. */
|
||||||
struct channel_mode_and_rate current_ch_mode_rate;
|
struct channel_mode_and_rate current_ch_mode_rate;
|
||||||
struct gsm48_multi_rate_conf current_mr_conf;
|
struct gsm48_multi_rate_conf current_mr_conf;
|
||||||
|
enum gsm0808_chan_indicator current_ch_indctr;
|
||||||
|
|
||||||
/* Circuit-Switched TSC Set in use, or -1 if no specific TSC Set was requested. The valid range is 1-4 as
|
/* Circuit-Switched TSC Set in use, or -1 if no specific TSC Set was requested. The valid range is 1-4 as
|
||||||
* described in the spec 3GPP TS 45.002. */
|
* described in the spec 3GPP TS 45.002. */
|
||||||
|
|
|
@ -194,8 +194,8 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate voice related fields */
|
/* Generate rtp related fields */
|
||||||
if (conn->assignment.requires_voice_stream) {
|
if (bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr)) {
|
||||||
perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
||||||
|
|
||||||
if (gscon_is_aoip(conn)) {
|
if (gscon_is_aoip(conn)) {
|
||||||
|
@ -238,7 +238,7 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gscon_is_aoip(conn) && conn->assignment.requires_voice_stream &&
|
if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr) &&
|
||||||
conn->assignment.req.use_osmux)
|
conn->assignment.req.use_osmux)
|
||||||
_gsm0808_ass_compl_extend_osmux(resp, osmux_cid);
|
_gsm0808_ass_compl_extend_osmux(resp, osmux_cid);
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
|
||||||
|
|
||||||
if (check_chan_mode_rate_against_ch_indctr(conn) < 0)
|
if (check_chan_mode_rate_against_ch_indctr(conn) < 0)
|
||||||
return;
|
return;
|
||||||
conn->assignment.requires_voice_stream = (req->ch_indctr != GSM0808_CHAN_SIGN);
|
conn->assignment.ch_indctr = req->ch_indctr;
|
||||||
|
|
||||||
if (!req->target_lchan && reuse_existing_lchan(conn)) {
|
if (!req->target_lchan && reuse_existing_lchan(conn)) {
|
||||||
/* The already existing lchan is suitable for this mode */
|
/* The already existing lchan is suitable for this mode */
|
||||||
|
@ -649,7 +649,7 @@ static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, u
|
||||||
.for_conn = conn,
|
.for_conn = conn,
|
||||||
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
|
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
|
||||||
.encr = conn->lchan->encr,
|
.encr = conn->lchan->encr,
|
||||||
.requires_voice_stream = conn->assignment.requires_voice_stream,
|
.ch_indctr = conn->assignment.ch_indctr,
|
||||||
.msc_assigned_cic = req->msc_assigned_cic,
|
.msc_assigned_cic = req->msc_assigned_cic,
|
||||||
.re_use_mgw_endpoint_from_lchan = conn->lchan,
|
.re_use_mgw_endpoint_from_lchan = conn->lchan,
|
||||||
.ta = conn->lchan->last_ta,
|
.ta = conn->lchan->last_ta,
|
||||||
|
@ -765,7 +765,7 @@ static void assignment_fsm_wait_lchan_established(struct osmo_fsm_inst *fi, uint
|
||||||
static void assignment_fsm_post_lchan_established(struct osmo_fsm_inst *fi)
|
static void assignment_fsm_post_lchan_established(struct osmo_fsm_inst *fi)
|
||||||
{
|
{
|
||||||
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
||||||
if (conn->assignment.requires_voice_stream)
|
if (bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr))
|
||||||
assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC);
|
assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC);
|
||||||
else
|
else
|
||||||
assignment_success(conn);
|
assignment_success(conn);
|
||||||
|
@ -775,7 +775,7 @@ static void assignment_fsm_wait_mgw_endpoint_to_msc_onenter(struct osmo_fsm_inst
|
||||||
{
|
{
|
||||||
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
||||||
|
|
||||||
OSMO_ASSERT(conn->assignment.requires_voice_stream);
|
OSMO_ASSERT(bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr));
|
||||||
|
|
||||||
LOG_ASSIGNMENT(conn, LOGL_DEBUG,
|
LOG_ASSIGNMENT(conn, LOGL_DEBUG,
|
||||||
"Connecting MGW endpoint to the MSC's RTP port: %s:%u\n",
|
"Connecting MGW endpoint to the MSC's RTP port: %s:%u\n",
|
||||||
|
@ -839,7 +839,7 @@ static void assignment_fsm_wait_lchan_modified_onenter(struct osmo_fsm_inst *fi,
|
||||||
struct lchan_modify_info modif_info = {
|
struct lchan_modify_info modif_info = {
|
||||||
.modify_for = MODIFY_FOR_ASSIGNMENT,
|
.modify_for = MODIFY_FOR_ASSIGNMENT,
|
||||||
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
|
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
|
||||||
.requires_voice_stream = conn->assignment.requires_voice_stream,
|
.ch_indctr = conn->assignment.ch_indctr,
|
||||||
.msc_assigned_cic = req->msc_assigned_cic,
|
.msc_assigned_cic = req->msc_assigned_cic,
|
||||||
/* keep previous training sequence code. TSC is always present, TSC Set may or may not be an explicit
|
/* keep previous training sequence code. TSC is always present, TSC Set may or may not be an explicit
|
||||||
* value. */
|
* value. */
|
||||||
|
|
|
@ -862,7 +862,7 @@ static int trigger_vamos_mode_modify(struct vty *vty, struct gsm_lchan *lchan, b
|
||||||
struct lchan_modify_info info = {
|
struct lchan_modify_info info = {
|
||||||
.modify_for = MODIFY_FOR_VTY,
|
.modify_for = MODIFY_FOR_VTY,
|
||||||
.ch_mode_rate = lchan->current_ch_mode_rate,
|
.ch_mode_rate = lchan->current_ch_mode_rate,
|
||||||
.requires_voice_stream = (lchan->fi_rtp != NULL),
|
.ch_indctr = lchan->current_ch_indctr,
|
||||||
.vamos = vamos,
|
.vamos = vamos,
|
||||||
.tsc_set = {
|
.tsc_set = {
|
||||||
.present = (tsc_set >= 0),
|
.present = (tsc_set >= 0),
|
||||||
|
@ -1625,7 +1625,7 @@ static int lchan_act_single(struct vty *vty, struct gsm_lchan *lchan, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
info.activ_for = ACTIVATE_FOR_VTY;
|
info.activ_for = ACTIVATE_FOR_VTY;
|
||||||
info.requires_voice_stream = false;
|
info.ch_indctr = GSM0808_CHAN_SIGN;
|
||||||
info.ch_mode_rate.chan_rate = chan_t_to_chan_rate(lchan_t);
|
info.ch_mode_rate.chan_rate = chan_t_to_chan_rate(lchan_t);
|
||||||
|
|
||||||
if (activate == 2 || lchan->vamos.is_secondary) {
|
if (activate == 2 || lchan->vamos.is_secondary) {
|
||||||
|
|
|
@ -607,3 +607,14 @@ void bsc_cm_update(struct gsm_subscriber_connection *conn,
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
msgb_free(resp);
|
msgb_free(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bsc_chan_ind_requires_rtp_stream(enum gsm0808_chan_indicator ch_indctr)
|
||||||
|
{
|
||||||
|
switch (ch_indctr) {
|
||||||
|
case GSM0808_CHAN_SPEECH:
|
||||||
|
case GSM0808_CHAN_DATA:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -409,7 +409,7 @@ static void handover_start_intra_bsc(struct gsm_subscriber_connection *conn)
|
||||||
.for_conn = conn,
|
.for_conn = conn,
|
||||||
.ch_mode_rate = conn->lchan->current_ch_mode_rate,
|
.ch_mode_rate = conn->lchan->current_ch_mode_rate,
|
||||||
.encr = conn->lchan->encr,
|
.encr = conn->lchan->encr,
|
||||||
.requires_voice_stream = conn->lchan->mgw_endpoint_ci_bts ? true : false,
|
.ch_indctr = conn->lchan->current_ch_indctr,
|
||||||
.msc_assigned_cic = conn->ho.inter_bsc_in.msc_assigned_cic,
|
.msc_assigned_cic = conn->ho.inter_bsc_in.msc_assigned_cic,
|
||||||
.re_use_mgw_endpoint_from_lchan = conn->lchan,
|
.re_use_mgw_endpoint_from_lchan = conn->lchan,
|
||||||
.wait_before_switching_rtp = true,
|
.wait_before_switching_rtp = true,
|
||||||
|
@ -630,18 +630,6 @@ static bool parse_ho_request(struct gsm_subscriber_connection *conn, const struc
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool chan_mode_is_tch(enum gsm48_chan_mode mode)
|
|
||||||
{
|
|
||||||
switch (gsm48_chan_mode_to_non_vamos(mode)) {
|
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
|
||||||
case GSM48_CMODE_SPEECH_EFR:
|
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn,
|
void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn,
|
||||||
struct msgb *ho_request_msg)
|
struct msgb *ho_request_msg)
|
||||||
{
|
{
|
||||||
|
@ -739,7 +727,7 @@ void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn,
|
||||||
.activ_for = ACTIVATE_FOR_HANDOVER,
|
.activ_for = ACTIVATE_FOR_HANDOVER,
|
||||||
.for_conn = conn,
|
.for_conn = conn,
|
||||||
.ch_mode_rate = ch_mode_rate,
|
.ch_mode_rate = ch_mode_rate,
|
||||||
.requires_voice_stream = chan_mode_is_tch(ch_mode_rate.chan_mode),
|
.ch_indctr = req->ct.ch_indctr,
|
||||||
.msc_assigned_cic = req->msc_assigned_cic,
|
.msc_assigned_cic = req->msc_assigned_cic,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -943,7 +931,7 @@ static void send_handover_performed(struct gsm_subscriber_connection *conn)
|
||||||
ho_perf_params.chosen_encr_alg = ALG_A5_NR_TO_BSSAP(lchan->encr.alg_a5_n);
|
ho_perf_params.chosen_encr_alg = ALG_A5_NR_TO_BSSAP(lchan->encr.alg_a5_n);
|
||||||
ho_perf_params.chosen_encr_alg_present = true;
|
ho_perf_params.chosen_encr_alg_present = true;
|
||||||
|
|
||||||
if (ho->new_lchan->activate.info.requires_voice_stream) {
|
if (bsc_chan_ind_requires_rtp_stream(ho->new_lchan->activate.info.ch_indctr)) {
|
||||||
/* Speech Version (chosen) 3.2.2.51 */
|
/* Speech Version (chosen) 3.2.2.51 */
|
||||||
ho_perf_params.speech_version_chosen = gsm0808_permitted_speech(lchan->type,
|
ho_perf_params.speech_version_chosen = gsm0808_permitted_speech(lchan->type,
|
||||||
lchan->current_ch_mode_rate.chan_mode);
|
lchan->current_ch_mode_rate.chan_mode);
|
||||||
|
@ -1129,7 +1117,7 @@ static void ho_fsm_wait_lchan_active(struct osmo_fsm_inst *fi, uint32_t event, v
|
||||||
* So create an MSC side endpoint CI only if a voice lchan is established for an incoming inter-BSC
|
* So create an MSC side endpoint CI only if a voice lchan is established for an incoming inter-BSC
|
||||||
* handover on AoIP. Otherwise go on to send a Handover Command and wait for the Detect.
|
* handover on AoIP. Otherwise go on to send a Handover Command and wait for the Detect.
|
||||||
*/
|
*/
|
||||||
if (ho->new_lchan->activate.info.requires_voice_stream
|
if (bsc_chan_ind_requires_rtp_stream(ho->new_lchan->activate.info.ch_indctr)
|
||||||
&& (ho->scope & HO_INTER_BSC_IN)
|
&& (ho->scope & HO_INTER_BSC_IN)
|
||||||
&& gscon_is_aoip(conn))
|
&& gscon_is_aoip(conn))
|
||||||
ho_fsm_state_chg(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC);
|
ho_fsm_state_chg(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <osmocom/bsc/abis_rsl.h>
|
#include <osmocom/bsc/abis_rsl.h>
|
||||||
#include <osmocom/bsc/bsc_rll.h>
|
#include <osmocom/bsc/bsc_rll.h>
|
||||||
#include <osmocom/bsc/gsm_04_08_rr.h>
|
#include <osmocom/bsc/gsm_04_08_rr.h>
|
||||||
|
#include <osmocom/bsc/gsm_08_08.h>
|
||||||
#include <osmocom/bsc/assignment_fsm.h>
|
#include <osmocom/bsc/assignment_fsm.h>
|
||||||
#include <osmocom/bsc/handover_fsm.h>
|
#include <osmocom/bsc/handover_fsm.h>
|
||||||
#include <osmocom/bsc/bsc_msc_data.h>
|
#include <osmocom/bsc/bsc_msc_data.h>
|
||||||
|
@ -689,6 +690,8 @@ static int lchan_activate_set_ch_mode_rate_and_mr_config(struct gsm_lchan *lchan
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lchan->activate.ch_indctr = lchan->activate.info.ch_indctr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,6 +720,7 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p
|
||||||
struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;
|
struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;
|
||||||
struct lchan_activate_info *info = &lchan->activate.info;
|
struct lchan_activate_info *info = &lchan->activate.info;
|
||||||
int ms_power_dbm = bts->ms_max_power;
|
int ms_power_dbm = bts->ms_max_power;
|
||||||
|
bool requires_rtp_stream;
|
||||||
|
|
||||||
if (lchan->release.requested) {
|
if (lchan->release.requested) {
|
||||||
lchan_fail("Release requested while activating");
|
lchan_fail("Release requested while activating");
|
||||||
|
@ -760,12 +764,13 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p
|
||||||
lchan->activate.tsc = lchan->activate.info.tsc.present ? lchan->activate.info.tsc.val : gsm_ts_tsc(lchan->ts);
|
lchan->activate.tsc = lchan->activate.info.tsc.present ? lchan->activate.info.tsc.val : gsm_ts_tsc(lchan->ts);
|
||||||
|
|
||||||
use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);
|
use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);
|
||||||
|
requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr);
|
||||||
|
|
||||||
LOG_LCHAN(lchan, LOGL_INFO,
|
LOG_LCHAN(lchan, LOGL_INFO,
|
||||||
"Activation requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s encr-alg=A5/%u ck=%s\n",
|
"Activation requested: %s rtp=%s MGW-ci=%s type=%s tch-mode=%s encr-alg=A5/%u ck=%s\n",
|
||||||
lchan_activate_mode_name(lchan->activate.info.activ_for),
|
lchan_activate_mode_name(lchan->activate.info.activ_for),
|
||||||
lchan->activate.info.requires_voice_stream ? "yes" : "no",
|
requires_rtp_stream ? "yes" : "no",
|
||||||
lchan->activate.info.requires_voice_stream ?
|
requires_rtp_stream ?
|
||||||
(use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new")
|
(use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new")
|
||||||
: "none",
|
: "none",
|
||||||
gsm_chan_t_name(lchan->type),
|
gsm_chan_t_name(lchan->type),
|
||||||
|
@ -779,7 +784,7 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p
|
||||||
osmo_fsm_inst_dispatch(lchan->ts->fi, TS_EV_LCHAN_REQUESTED, lchan);
|
osmo_fsm_inst_dispatch(lchan->ts->fi, TS_EV_LCHAN_REQUESTED, lchan);
|
||||||
|
|
||||||
/* Prepare an MGW endpoint CI if appropriate. */
|
/* Prepare an MGW endpoint CI if appropriate. */
|
||||||
if (lchan->activate.info.requires_voice_stream)
|
if (requires_rtp_stream)
|
||||||
lchan_rtp_fsm_start(lchan);
|
lchan_rtp_fsm_start(lchan);
|
||||||
|
|
||||||
if (lchan->activate.info.imm_ass_time == IMM_ASS_TIME_PRE_TS_ACK) {
|
if (lchan->activate.info.imm_ass_time == IMM_ASS_TIME_PRE_TS_ACK) {
|
||||||
|
@ -938,6 +943,7 @@ static void post_activ_ack_accept_preliminary_settings(struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
lchan->current_ch_mode_rate = lchan->activate.ch_mode_rate;
|
lchan->current_ch_mode_rate = lchan->activate.ch_mode_rate;
|
||||||
lchan->current_mr_conf = lchan->activate.mr_conf_filtered;
|
lchan->current_mr_conf = lchan->activate.mr_conf_filtered;
|
||||||
|
lchan->current_ch_indctr = lchan->activate.ch_indctr;
|
||||||
lchan->vamos.enabled = lchan->activate.info.vamos;
|
lchan->vamos.enabled = lchan->activate.info.vamos;
|
||||||
lchan->tsc_set = lchan->activate.tsc_set;
|
lchan->tsc_set = lchan->activate.tsc_set;
|
||||||
lchan->tsc = lchan->activate.tsc;
|
lchan->tsc = lchan->activate.tsc;
|
||||||
|
@ -1019,16 +1025,17 @@ static void lchan_fsm_post_activ_ack(struct osmo_fsm_inst *fi)
|
||||||
static void lchan_fsm_wait_rll_rtp_establish_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
static void lchan_fsm_wait_rll_rtp_establish_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
{
|
{
|
||||||
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
|
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
|
||||||
|
bool requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr);
|
||||||
|
|
||||||
if (lchan->fi_rtp)
|
if (lchan->fi_rtp)
|
||||||
osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_LCHAN_READY, 0);
|
osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_LCHAN_READY, 0);
|
||||||
/* Prepare an MGW endpoint CI if appropriate (late). */
|
/* Prepare an MGW endpoint CI if appropriate (late). */
|
||||||
else if (lchan->activate.info.requires_voice_stream)
|
else if (requires_rtp_stream)
|
||||||
lchan_rtp_fsm_start(lchan);
|
lchan_rtp_fsm_start(lchan);
|
||||||
|
|
||||||
/* When activating a channel for VTY, skip waiting for activity from
|
/* When activating a channel for VTY, skip waiting for activity from
|
||||||
* lchan_rtp_fsm, but only if no voice stream is required. */
|
* lchan_rtp_fsm, but only if no rtp stream is required. */
|
||||||
if (lchan->activate.info.activ_for == ACTIVATE_FOR_VTY &&
|
if (lchan->activate.info.activ_for == ACTIVATE_FOR_VTY && !requires_rtp_stream) {
|
||||||
!lchan->activate.info.requires_voice_stream) {
|
|
||||||
lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED);
|
lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1036,14 +1043,15 @@ static void lchan_fsm_wait_rll_rtp_establish_onenter(struct osmo_fsm_inst *fi, u
|
||||||
static void lchan_fsm_wait_rll_rtp_establish(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
static void lchan_fsm_wait_rll_rtp_establish(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
{
|
{
|
||||||
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
|
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
|
||||||
|
bool requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
|
||||||
case LCHAN_EV_RLL_ESTABLISH_IND:
|
case LCHAN_EV_RLL_ESTABLISH_IND:
|
||||||
if (!lchan->activate.info.requires_voice_stream
|
if (!requires_rtp_stream || lchan_rtp_established(lchan)) {
|
||||||
|| lchan_rtp_established(lchan)) {
|
|
||||||
LOG_LCHAN(lchan, LOGL_DEBUG,
|
LOG_LCHAN(lchan, LOGL_DEBUG,
|
||||||
"%s\n",
|
"%s\n",
|
||||||
(lchan->activate.info.requires_voice_stream ?
|
(requires_rtp_stream ?
|
||||||
"RTP already established earlier" : "no voice stream required"));
|
"RTP already established earlier" : "no voice stream required"));
|
||||||
lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED);
|
lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED);
|
||||||
}
|
}
|
||||||
|
@ -1118,19 +1126,19 @@ static void lchan_fsm_wait_rsl_chan_mode_modify_ack(struct osmo_fsm_inst *fi, ui
|
||||||
/* The Channel Mode Modify was ACKed, now the requested values become the accepted and used values. */
|
/* The Channel Mode Modify was ACKed, now the requested values become the accepted and used values. */
|
||||||
lchan->current_ch_mode_rate = lchan->modify.ch_mode_rate;
|
lchan->current_ch_mode_rate = lchan->modify.ch_mode_rate;
|
||||||
lchan->current_mr_conf = lchan->modify.mr_conf_filtered;
|
lchan->current_mr_conf = lchan->modify.mr_conf_filtered;
|
||||||
|
lchan->current_ch_indctr = lchan->modify.ch_indctr;
|
||||||
lchan->tsc_set = lchan->modify.tsc_set;
|
lchan->tsc_set = lchan->modify.tsc_set;
|
||||||
lchan->tsc = lchan->modify.tsc;
|
lchan->tsc = lchan->modify.tsc;
|
||||||
lchan->vamos.enabled = lchan->modify.info.vamos;
|
lchan->vamos.enabled = lchan->modify.info.vamos;
|
||||||
|
|
||||||
if (lchan->modify.info.requires_voice_stream
|
if (bsc_chan_ind_requires_rtp_stream(lchan->modify.info.ch_indctr) && !lchan->fi_rtp) {
|
||||||
&& !lchan->fi_rtp) {
|
|
||||||
/* Continue with RTP stream establishing as done in lchan_activate(). Place the requested values in
|
/* Continue with RTP stream establishing as done in lchan_activate(). Place the requested values in
|
||||||
* lchan->activate.info and continue with voice stream setup. */
|
* lchan->activate.info and continue with voice stream setup. */
|
||||||
lchan->activate.info = (struct lchan_activate_info){
|
lchan->activate.info = (struct lchan_activate_info){
|
||||||
.activ_for = ACTIVATE_FOR_MODE_MODIFY_RTP,
|
.activ_for = ACTIVATE_FOR_MODE_MODIFY_RTP,
|
||||||
.for_conn = lchan->conn,
|
.for_conn = lchan->conn,
|
||||||
.ch_mode_rate = lchan->modify.ch_mode_rate,
|
.ch_mode_rate = lchan->modify.ch_mode_rate,
|
||||||
.requires_voice_stream = true,
|
.ch_indctr = lchan->modify.info.ch_indctr,
|
||||||
.msc_assigned_cic = lchan->modify.info.msc_assigned_cic,
|
.msc_assigned_cic = lchan->modify.info.msc_assigned_cic,
|
||||||
};
|
};
|
||||||
if (lchan_activate_set_ch_mode_rate_and_mr_config(lchan))
|
if (lchan_activate_set_ch_mode_rate_and_mr_config(lchan))
|
||||||
|
@ -1239,6 +1247,7 @@ static void lchan_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void
|
||||||
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
|
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
|
||||||
struct lchan_modify_info *modif_info;
|
struct lchan_modify_info *modif_info;
|
||||||
struct osmo_mgcpc_ep_ci *use_mgwep_ci;
|
struct osmo_mgcpc_ep_ci *use_mgwep_ci;
|
||||||
|
bool requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->modify.info.ch_indctr);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case LCHAN_EV_RLL_ESTABLISH_IND:
|
case LCHAN_EV_RLL_ESTABLISH_IND:
|
||||||
|
@ -1289,6 +1298,8 @@ static void lchan_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lchan->modify.ch_indctr = lchan->modify.info.ch_indctr;
|
||||||
|
|
||||||
/* If enabling VAMOS mode and no specific TSC Set was selected, make sure to select a sane TSC Set by
|
/* If enabling VAMOS mode and no specific TSC Set was selected, make sure to select a sane TSC Set by
|
||||||
* default: Set 1 for the primary and Set 2 for the shadow lchan. For non-VAMOS lchans, TSC Set 1. */
|
* default: Set 1 for the primary and Set 2 for the shadow lchan. For non-VAMOS lchans, TSC Set 1. */
|
||||||
if (lchan->modify.info.tsc_set.present)
|
if (lchan->modify.info.tsc_set.present)
|
||||||
|
@ -1301,10 +1312,10 @@ static void lchan_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void
|
||||||
lchan->modify.tsc = lchan->modify.info.tsc.present ? lchan->modify.info.tsc.val : gsm_ts_tsc(lchan->ts);
|
lchan->modify.tsc = lchan->modify.info.tsc.present ? lchan->modify.info.tsc.val : gsm_ts_tsc(lchan->ts);
|
||||||
|
|
||||||
LOG_LCHAN(lchan, LOGL_INFO,
|
LOG_LCHAN(lchan, LOGL_INFO,
|
||||||
"Modification requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s tsc=%d/%u\n",
|
"Modification requested: %s rtp=%s MGW-ci=%s type=%s tch-mode=%s tsc=%d/%u\n",
|
||||||
lchan_modify_for_name(lchan->modify.info.modify_for),
|
lchan_modify_for_name(lchan->modify.info.modify_for),
|
||||||
lchan->modify.info.requires_voice_stream ? "yes" : "no",
|
requires_rtp_stream ? "yes" : "no",
|
||||||
lchan->modify.info.requires_voice_stream ?
|
requires_rtp_stream ?
|
||||||
(use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new")
|
(use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new")
|
||||||
: "none",
|
: "none",
|
||||||
gsm_chan_t_name(lchan->type),
|
gsm_chan_t_name(lchan->type),
|
||||||
|
@ -1806,9 +1817,9 @@ static int lchan_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||||
lchan->release.rsl_error_cause = RSL_ERR_INTERWORKING;
|
lchan->release.rsl_error_cause = RSL_ERR_INTERWORKING;
|
||||||
lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
|
lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
|
||||||
if (fi->state == LCHAN_ST_WAIT_RLL_RTP_ESTABLISH) {
|
if (fi->state == LCHAN_ST_WAIT_RLL_RTP_ESTABLISH) {
|
||||||
lchan_fail("Timeout (rll_ready=%s,voice_require=%s,voice_ready=%s)",
|
lchan_fail("Timeout (rll_ready=%s,rtp_require=%s,voice_ready=%s)",
|
||||||
(lchan->sapis[0] != LCHAN_SAPI_UNUSED) ? "yes" : "no",
|
(lchan->sapis[0] != LCHAN_SAPI_UNUSED) ? "yes" : "no",
|
||||||
lchan->activate.info.requires_voice_stream ? "yes" : "no",
|
bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr) ? "yes" : "no",
|
||||||
lchan_rtp_established(lchan) ? "yes" : "no");
|
lchan_rtp_established(lchan) ? "yes" : "no");
|
||||||
} else {
|
} else {
|
||||||
lchan_fail("Timeout");
|
lchan_fail("Timeout");
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <osmocom/bsc/bsc_subscriber.h>
|
#include <osmocom/bsc/bsc_subscriber.h>
|
||||||
#include <osmocom/bsc/paging.h>
|
#include <osmocom/bsc/paging.h>
|
||||||
#include <osmocom/bsc/gsm_04_08_rr.h>
|
#include <osmocom/bsc/gsm_04_08_rr.h>
|
||||||
|
#include <osmocom/bsc/gsm_08_08.h>
|
||||||
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
|
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
|
||||||
#include <osmocom/bsc/codec_pref.h>
|
#include <osmocom/bsc/codec_pref.h>
|
||||||
#include <osmocom/bsc/data_rate_pref.h>
|
#include <osmocom/bsc/data_rate_pref.h>
|
||||||
|
@ -1618,7 +1619,7 @@ int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn, struct
|
||||||
new_lchan->current_ch_mode_rate.chan_mode),
|
new_lchan->current_ch_mode_rate.chan_mode),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gscon_is_aoip(conn) && new_lchan->activate.info.requires_voice_stream) {
|
if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(new_lchan->activate.info.ch_indctr)) {
|
||||||
struct osmo_sockaddr_str to_msc_rtp;
|
struct osmo_sockaddr_str to_msc_rtp;
|
||||||
const struct mgcp_conn_peer *rtp_info = osmo_mgcpc_ep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc);
|
const struct mgcp_conn_peer *rtp_info = osmo_mgcpc_ep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc);
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1693,7 +1694,7 @@ enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection
|
||||||
};
|
};
|
||||||
|
|
||||||
/* speech_codec_chosen */
|
/* speech_codec_chosen */
|
||||||
if (ho->new_lchan->activate.info.requires_voice_stream && gscon_is_aoip(conn)) {
|
if (bsc_chan_ind_requires_rtp_stream(ho->new_lchan->activate.info.ch_indctr) && gscon_is_aoip(conn)) {
|
||||||
int perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
int perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
||||||
params.speech_codec_chosen_present = true;
|
params.speech_codec_chosen_present = true;
|
||||||
rc = gsm0808_speech_codec_from_chan_type(¶ms.speech_codec_chosen, perm_spch);
|
rc = gsm0808_speech_codec_from_chan_type(¶ms.speech_codec_chosen, perm_spch);
|
||||||
|
|
Loading…
Reference in New Issue