Max has uploaded this change for review. ( https://gerrit.osmocom.org/13419
Change subject: Use osmo_lcls instead of anonymous struct ...................................................................... Use osmo_lcls instead of anonymous struct This allows us to (re)use code from libosmocore for parameter checks, printing etc. Change-Id: I0f2c2a065755d9051fc7d7ce52c19ab0b7d9288a Related: OS#2487 --- M include/osmocom/bsc/gsm_data.h M include/osmocom/bsc/osmo_bsc_lcls.h M src/osmo-bsc/bsc_subscr_conn_fsm.c M src/osmo-bsc/bsc_vty.c M src/osmo-bsc/osmo_bsc_bssap.c M src/osmo-bsc/osmo_bsc_lcls.c 6 files changed, 71 insertions(+), 106 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/19/13419/1 diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index 47ca5e8..3ee7694 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -292,10 +292,7 @@ /* LCLS (local call, local switch) related state */ struct { - uint8_t global_call_ref[15]; - uint8_t global_call_ref_len; /* length of global_call_ref */ - enum gsm0808_lcls_config config; /* TS 48.008 3.2.2.116 */ - enum gsm0808_lcls_control control; /* TS 48.008 3.2.2.117 */ + struct osmo_lcls *par; /* LCLS parameters */ /* LCLS FSM */ struct osmo_fsm_inst *fi; /* pointer to "other" connection, if Call Leg Relocation was successful */ diff --git a/include/osmocom/bsc/osmo_bsc_lcls.h b/include/osmocom/bsc/osmo_bsc_lcls.h index 8bbd552..b7836ce 100644 --- a/include/osmocom/bsc/osmo_bsc_lcls.h +++ b/include/osmocom/bsc/osmo_bsc_lcls.h @@ -47,9 +47,6 @@ enum gsm0808_lcls_status lcls_get_status(const struct gsm_subscriber_connection *conn); -void lcls_update_config(struct gsm_subscriber_connection *conn, - const uint8_t *config, const uint8_t *control); - void lcls_apply_config(struct gsm_subscriber_connection *conn); extern struct osmo_fsm lcls_fsm; diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c index 1cc0c78..3f43801 100644 --- a/src/osmo-bsc/bsc_subscr_conn_fsm.c +++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c @@ -889,16 +889,28 @@ return NULL; } + conn->lcls.par = talloc_zero(conn, struct osmo_lcls); + /* indicate "IE not [yet] received" */ - conn->lcls.config = GSM0808_LCLS_CFG_NA; - conn->lcls.control = GSM0808_LCLS_CSC_NA; + conn->lcls.par->config = GSM0808_LCLS_CFG_NA; + conn->lcls.par->control = GSM0808_LCLS_CSC_NA; + conn->lcls.fi = osmo_fsm_inst_alloc_child(&lcls_fsm, conn->fi, GSCON_EV_LCLS_FAIL); + if (!conn->lcls.fi) { osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_ERROR, NULL); return NULL; } conn->lcls.fi->priv = conn; + if (conn->lchan) { + LOG_LCHAN(conn->lchan, LOGL_NOTICE, "New %s\n", osmo_lcls_dump(conn->lcls.par)); + LOG_LCHAN(conn->lchan, LOGL_NOTICE, "New %s\n", osmo_gcr_dump(conn->lcls.par)); + } else { + LOGPFSM(conn->fi, "New %s\n", osmo_lcls_dump(conn->lcls.par)); + LOGPFSM(conn->fi, "New %s\n", osmo_gcr_dump(conn->lcls.par)); + } + llist_add_tail(&conn->entry, &net->subscr_conns); return conn; } diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c index 9413d36..769ddeb 100644 --- a/src/osmo-bsc/bsc_vty.c +++ b/src/osmo-bsc/bsc_vty.c @@ -1586,16 +1586,9 @@ vty_out(vty, "conn ID=%u, MSC=%u, hodec2_fail=%d, mgw_ep=%s%s", conn->sccp.conn_id, conn->sccp.msc->nr, conn->hodec2.failures, mgw_endpoint_name(conn->user_plane.mgw_endpoint), VTY_NEWLINE); - if (conn->lcls.global_call_ref_len) { - vty_out(vty, " LCLS GCR: %s%s", - osmo_hexdump_nospc(conn->lcls.global_call_ref, conn->lcls.global_call_ref_len), - VTY_NEWLINE); - vty_out(vty, " LCLS Config: %s, LCLS Control: %s, LCLS BSS Status: %s%s", - gsm0808_lcls_config_name(conn->lcls.config), - gsm0808_lcls_control_name(conn->lcls.control), - osmo_fsm_inst_state_name(conn->lcls.fi), - VTY_NEWLINE); - } + vty_out(vty, " %s%s", osmo_lcls_dump(conn->lcls.par), VTY_NEWLINE); + vty_out(vty, " %s%s", osmo_gcr_dump(conn->lcls.par), VTY_NEWLINE); + if (conn->lchan) lchan_dump_full_vty(vty, conn->lchan); if (conn->assignment.new_lchan) diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 85aab22..74f0901 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -541,36 +541,20 @@ /* handle LCLS specific IES in BSSMAP ASS REQ */ static void bssmap_handle_ass_req_lcls(struct gsm_subscriber_connection *conn, - const struct tlv_parsed *tp) + const struct tlv_parsed *tp) { - const uint8_t *config, *control, *gcr, gcr_len = TLVP_LEN(tp, GSM0808_IE_GLOBAL_CALL_REF); - - if (gcr_len > sizeof(conn->lcls.global_call_ref)) - LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too long\n", - gcr_len); - else { - gcr = TLVP_VAL_MINLEN(tp, GSM0808_IE_GLOBAL_CALL_REF, 13); - if (gcr) { - LOGPFSM(conn->fi, "Setting GCR to %s\n", osmo_hexdump_nospc(gcr, gcr_len)); - memcpy(&conn->lcls.global_call_ref, gcr, gcr_len); - conn->lcls.global_call_ref_len = gcr_len; - } else - LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too short\n", - gcr_len); - } - - config = TLVP_VAL_MINLEN(tp, GSM0808_IE_LCLS_CONFIG, 1); - control = TLVP_VAL_MINLEN(tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, 1); - - if (config || control) { - LOGPFSM(conn->fi, "BSSMAP ASS REQ contains LCLS (%s / %s)\n", - config ? gsm0808_lcls_config_name(*config) : "NULL", - control ? gsm0808_lcls_control_name(*control) : "NULL"); - } - /* Update the LCLS state with Config + CSC (if any) */ - lcls_update_config(conn, config, control); - + LOGPFSML(conn->fi, LOGL_NOTICE, "Old %s\n", osmo_lcls_dump(conn->lcls.par)); + LOGPFSML(conn->fi, LOGL_NOTICE, "Old <%u> %s\n", conn->lcls.par->gcr_available, osmo_gcr_dump(conn->lcls.par)); + int rc = gsm0808_dec_lcls(conn->lcls.par, tp); + if (rc < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "LCLS decoding failed: %s\n", strerror(-rc)); + } else + conn->lcls.par->gcr_available = true; + LOGPFSML(conn->fi, LOGL_NOTICE, "New %s\n", osmo_lcls_dump(conn->lcls.par)); + LOGPFSML(conn->fi, LOGL_NOTICE, "New <%u> %s\n", conn->lcls.par->gcr_available, osmo_gcr_dump(conn->lcls.par)); + /* notify the LCLS FSM about new LCLS Config and/or CSC */ + osmo_fsm_inst_dispatch(conn->lcls.fi, LCLS_EV_UPDATE_CFG_CSC, conn->lcls.par); /* Do not attempt to perform correlation yet, as during processing of the ASS REQ * we don't have the MGCP/MGW connections yet, and hence couldn't enable LS. */ } @@ -581,7 +565,6 @@ { struct msgb *resp; struct tlv_parsed tp; - const uint8_t *config, *control; int rc; OSMO_ASSERT(conn); @@ -592,20 +575,8 @@ msgb_hexdump(msg)); return rc; } - config = TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONFIG, 1); - control = TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, 1); - LOGPFSM(conn->fi, "Rx LCLS CONNECT CTRL (%s / %s)\n", - config ? gsm0808_lcls_config_name(*config) : "NULL", - control ? gsm0808_lcls_control_name(*control) : "NULL"); - - if (conn->lcls.global_call_ref_len == 0) { - LOGPFSML(conn->fi, LOGL_ERROR, "Ignoring LCLS as no GCR was set before\n"); - return 0; - } - /* Update the LCLS state with Config + CSC (if any) */ - lcls_update_config(conn, TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONFIG, 1), - TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, 1)); + bssmap_handle_ass_req_lcls(conn, &tp); lcls_apply_config(conn); LOGPFSM(conn->fi, "Tx LCLS CONNECT CTRL ACK (%s)\n", diff --git a/src/osmo-bsc/osmo_bsc_lcls.c b/src/osmo-bsc/osmo_bsc_lcls.c index c1f62dc..e81e8f8 100644 --- a/src/osmo-bsc/osmo_bsc_lcls.c +++ b/src/osmo-bsc/osmo_bsc_lcls.c @@ -101,12 +101,12 @@ /* don't report back the same connection */ if (conn_other == conn_local) continue; - /* don't consider any conn where GCR length is not the same as before */ - if (conn_other->lcls.global_call_ref_len != conn_local->lcls.global_call_ref_len) - continue; - if (!memcmp(conn_other->lcls.global_call_ref, conn_local->lcls.global_call_ref, - conn_local->lcls.global_call_ref_len)) + + if (osmo_gcr_eq(&conn_other->lcls.par->gcr, &conn_local->lcls.par->gcr)) return conn_other; + else + LOGPFSM(conn_local->lcls.fi, "LCLS local %s != other %s\n", + osmo_gcr_dump(conn_local->lcls.par), osmo_gcr_dump(conn_other->lcls.par)); } return NULL; } @@ -126,7 +126,9 @@ struct gsm_subscriber_connection *conn_other; /* We can only correlate if a GCR is present */ - OSMO_ASSERT(conn_local->lcls.global_call_ref_len); + if (!conn_local->lcls.par->gcr_available) + return -EINVAL; + /* We can only correlate if we're not in active LS */ OSMO_ASSERT(conn_local->lcls.fi->state != ST_LOCALLY_SWITCHED && conn_local->lcls.fi->state != ST_LOCALLY_SWITCHED_WAIT_BREAK && @@ -146,7 +148,7 @@ conn_other = find_conn_with_same_gcr(conn_local); if (!conn_other) { /* we found no other call with same GCR: not possible */ - LOGPFSM(conn_local->lcls.fi, "Unsuccessful correlation\n"); + LOGPFSM(conn_local->lcls.fi, "Unsuccessful correlation: we found no other call with same GCR\n"); return -ENODEV; } @@ -168,25 +170,25 @@ const struct osmo_lcls *new_cfg_csc) { static struct osmo_lcls old_cfg_csc = { 0 }; - old_cfg_csc.config = conn->lcls.config; - old_cfg_csc.control = conn->lcls.control; + old_cfg_csc.config = conn->lcls.par->config; + old_cfg_csc.control = conn->lcls.par->control; if (new_cfg_csc->config != GSM0808_LCLS_CFG_NA) { if (!lcls_is_supported_config(new_cfg_csc->config)) return NULL; - if (conn->lcls.config != new_cfg_csc->config) { + if (conn->lcls.par->config != new_cfg_csc->config) { LOGPFSM(conn->lcls.fi, "LCLS update Config %s -> %s\n", - gsm0808_lcls_config_name(conn->lcls.config), + gsm0808_lcls_config_name(conn->lcls.par->config), gsm0808_lcls_config_name(new_cfg_csc->config)); - conn->lcls.config = new_cfg_csc->config; + conn->lcls.par->config = new_cfg_csc->config; } } if (new_cfg_csc->control != GSM0808_LCLS_CSC_NA) { - if (conn->lcls.control != new_cfg_csc->control) { + if (conn->lcls.par->control != new_cfg_csc->control) { LOGPFSM(conn->lcls.fi, "LCLS update Control %s -> %s\n", - gsm0808_lcls_control_name(conn->lcls.control), + gsm0808_lcls_control_name(conn->lcls.par->control), gsm0808_lcls_control_name(new_cfg_csc->control)); - conn->lcls.control = new_cfg_csc->control; + conn->lcls.par->control = new_cfg_csc->control; } } @@ -208,25 +210,7 @@ return 0; } -/* notify the LCLS FSM about new LCLS Config and/or CSC */ -void lcls_update_config(struct gsm_subscriber_connection *conn, - const uint8_t *config, const uint8_t *control) -{ - struct osmo_lcls new_cfg = { - .config = GSM0808_LCLS_CFG_NA, - .control = GSM0808_LCLS_CSC_NA, - }; - /* nothing to update, skip it */ - if (!config && !control) - return; - if (config) - new_cfg.config = *config; - if (control) - new_cfg.control = *control; - osmo_fsm_inst_dispatch(conn->lcls.fi, LCLS_EV_UPDATE_CFG_CSC, &new_cfg); -} - -/* apply the configuration, may be changed before by lcls_update_config */ +/* apply the configuration, might have been changed before by corresponding BSSMAP handlers */ void lcls_apply_config(struct gsm_subscriber_connection *conn) { osmo_fsm_inst_dispatch(conn->lcls.fi, LCLS_EV_APPLY_CFG_CSC, NULL); @@ -277,6 +261,10 @@ { mgcp_pick_codec(mdcx_info, conn->lchan, false); + LOGPFSM(conn->lcls.fi, "LCLS(%s) MGW to %s\n", + bsc_lcls_mode_name(conn->sccp.msc->lcls_mode), + mgwep_ci_name(conn->user_plane.mgw_endpoint_ci_msc)); + mgw_endpoint_ci_request(conn->user_plane.mgw_endpoint_ci_msc, MGCP_VERB_MDCX, mdcx_info, NULL, 0, 0, NULL); } @@ -295,9 +283,11 @@ case BSC_LCLS_MODE_MGW_LOOP: mdcx_info.port = conn->user_plane.msc_assigned_rtp_port; osmo_strlcpy(mdcx_info.addr, conn->user_plane.msc_assigned_rtp_addr, sizeof(mdcx_info.addr)); + LOGPFSM(conn->lcls.fi, "LCLS(%s) MDCX breaking\n", bsc_lcls_mode_name(conn->sccp.msc->lcls_mode)); lcls_mdcx(conn, &mdcx_info); break; case BSC_LCLS_MODE_BTS_LOOP: + LOGPFSM(conn->lcls.fi, "LCLS(%s) RSL breaking\n", bsc_lcls_mode_name(conn->sccp.msc->lcls_mode)); lcls_rsl(conn, false); break; case BSC_LCLS_MODE_DISABLED: @@ -314,22 +304,22 @@ struct gsm_subscriber_connection *other_conn = conn->lcls.other; OSMO_ASSERT(other_conn); - if (!lcls_is_supported_config(conn->lcls.config)) { + if (!lcls_is_supported_config(conn->lcls.par->config)) { LOGPFSM(conn->lcls.fi, "Not enabling LS due to unsupported local config\n"); return false; } - if (!lcls_is_supported_config(other_conn->lcls.config)) { + if (!lcls_is_supported_config(other_conn->lcls.par->config)) { LOGPFSM(conn->lcls.fi, "Not enabling LS due to unsupported other config\n"); return false; } - if (conn->lcls.control != GSM0808_LCLS_CSC_CONNECT) { + if (conn->lcls.par->control != GSM0808_LCLS_CSC_CONNECT) { LOGPFSM(conn->lcls.fi, "Not enabling LS due to insufficient local control\n"); return false; } - if (other_conn->lcls.control != GSM0808_LCLS_CSC_CONNECT) { + if (other_conn->lcls.par->control != GSM0808_LCLS_CSC_CONNECT) { LOGPFSM(conn->lcls.fi, "Not enabling LS due to insufficient other control\n"); return false; } @@ -378,9 +368,12 @@ } /* If there's no GCR set, we can never leave this state */ - if (conn->lcls.global_call_ref_len == 0) { - LOGPFSML(fi, LOGL_NOTICE, "No GCR set, ignoring %s\n", - osmo_fsm_event_name(fi->fsm, event)); + if (!conn->lcls.par->gcr_available) { + LOGPFSML(fi, LOGL_NOTICE, "No GCR set, ignoring %s: %s <%u> %s\n", + osmo_fsm_event_name(fi->fsm, event), + osmo_lcls_dump(conn->lcls.par), + conn->lcls.par->gcr_available, + osmo_gcr_dump(conn->lcls.par)); return; } @@ -390,7 +383,7 @@ return; return; case LCLS_EV_APPLY_CFG_CSC: - if (conn->lcls.config == GSM0808_LCLS_CFG_NA) + if (conn->lcls.par->config == GSM0808_LCLS_CFG_NA) return; if (lcls_perform_correlation(conn) != 0) { /* Correlation leads to no result: Not Possible to LS */ @@ -565,7 +558,7 @@ } /* we now have two correlated calls */ OSMO_ASSERT(conn->lcls.other); - if (!lcls_is_supported_config(conn->lcls.config)) + if (!lcls_is_supported_config(conn->lcls.par->config)) return; if (lcls_enable_possible(conn)) osmo_fsm_inst_state_chg(fi, ST_LOCALLY_SWITCHED, 0, 0); @@ -601,7 +594,7 @@ } break; case LCLS_EV_APPLY_CFG_CSC: - if (conn->lcls.control == GSM0808_LCLS_CSC_RELEASE_LCLS) { + if (conn->lcls.par->control == GSM0808_LCLS_CSC_RELEASE_LCLS) { osmo_fsm_inst_state_chg(fi, ST_LOCALLY_SWITCHED_WAIT_OTHER_BREAK, 0, 0); osmo_fsm_inst_dispatch(conn->lcls.other->lcls.fi, LCLS_EV_OTHER_BREAK, conn); /* FIXME: what if there's a new config included? */ @@ -659,9 +652,11 @@ mdcx_info = *other_mgw_info; /* Make sure the request doesn't want to use the other side's endpoint string. */ mdcx_info.endpoint[0] = 0; + LOGPFSM(fi, "LCLS(%s) MDCX making\n", bsc_lcls_mode_name(conn->sccp.msc->lcls_mode)); lcls_mdcx(conn, &mdcx_info); break; case BSC_LCLS_MODE_BTS_LOOP: + LOGPFSM(fi, "LCLS(%s) RSL making\n", bsc_lcls_mode_name(conn->sccp.msc->lcls_mode)); lcls_rsl(conn, true); break; case BSC_LCLS_MODE_DISABLED: @@ -687,7 +682,7 @@ } break; case LCLS_EV_APPLY_CFG_CSC: - if (conn->lcls.control == GSM0808_LCLS_CSC_RELEASE_LCLS) { + if (conn->lcls.par->control == GSM0808_LCLS_CSC_RELEASE_LCLS) { lcls_break_local_switching(conn); osmo_fsm_inst_state_chg(fi, ST_NO_LONGER_LS, 0, 0); osmo_fsm_inst_dispatch(conn->lcls.other->lcls.fi, LCLS_EV_OTHER_BREAK, conn); -- To view, visit https://gerrit.osmocom.org/13419 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bsc Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I0f2c2a065755d9051fc7d7ce52c19ab0b7d9288a Gerrit-Change-Number: 13419 Gerrit-PatchSet: 1 Gerrit-Owner: Max <msur...@sysmocom.de>