This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-msc/+/23915 ) Change subject: Fill Last Used E-UTRAN PLMN Id when in CSFB ...................................................................... Fill Last Used E-UTRAN PLMN Id when in CSFB Since recently, osmo-bsc behaves strictly as per specs, meaning it will only send the "Cell selection indicator after release of all TCH and SDCCH IE" in RR Channel Release iff: * "Last Used E-UTRAN PLMN Id" was received in the CommonID sent MSC->BSC * "Last Used E-UTRAN PLMN Id" was received insider "old BSS to new BSS Information" in the HandoverRequest sent MSC->BSC. On the other hand, CSFB_Indicator from ClearCommand MSC->BSC is nw ignored and not taken into account. Hence, let's update osmo-msc to also behave correctly by sending the Last Used E-UTRAN PLMN ID at CommonID tx time to avoid regressions in CSFB support when running against newer osmo-bsc. Let's keep sending the CSFB Indicator in ClearCommand as we used too, in order to keep compatibility with older BSCs (as per spec). Related: SYS#5337 Change-Id: Ic5f175b179973d0a50d94f00e15f5a3e332605fc --- M include/osmocom/msc/ran_msg.h M include/osmocom/msc/vlr.h M include/osmocom/msc/vlr_sgs.h M src/libmsc/gsm_04_08.c M src/libmsc/msc_a.c M src/libmsc/ran_msg_a.c M src/libmsc/sgs_iface.c M src/libvlr/vlr.c M src/libvlr/vlr_sgs.c 9 files changed, 86 insertions(+), 5 deletions(-) Approvals: fixeria: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h index 3b08b46..1303ba3 100644 --- a/include/osmocom/msc/ran_msg.h +++ b/include/osmocom/msc/ran_msg.h @@ -220,6 +220,8 @@ } cipher_mode_reject; struct { const char *imsi; + bool last_eutran_plmn_present; + struct osmo_plmn_id last_eutran_plmn; } common_id; struct { enum gsm48_reject_value cause; diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h index 3b9bbc4..6e65283 100644 --- a/include/osmocom/msc/vlr.h +++ b/include/osmocom/msc/vlr.h @@ -193,6 +193,8 @@ vlr_sgs_lu_mminfo_cb_t mminfo_cb; enum sgsap_service_ind paging_serv_ind; struct osmo_timer_list Ts5; + bool last_eutran_plmn_present; + struct osmo_plmn_id last_eutran_plmn; } sgs; struct osmo_gsm48_classmark classmark; @@ -398,6 +400,8 @@ void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei); void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv); void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn); +void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub, + const struct osmo_plmn_id *last_eutran_plmn); bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi); bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi); diff --git a/include/osmocom/msc/vlr_sgs.h b/include/osmocom/msc/vlr_sgs.h index fa9d948..1a4984d 100644 --- a/include/osmocom/msc/vlr_sgs.h +++ b/include/osmocom/msc/vlr_sgs.h @@ -97,7 +97,7 @@ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg, vlr_sgs_lu_response_cb_t response_cb, vlr_sgs_lu_paging_cb_t paging_cb, vlr_sgs_lu_mminfo_cb_t mminfo_cb, char *mme_name, enum vlr_lu_type type, const char *imsi, - struct osmo_location_area_id *new_lai); + struct osmo_location_area_id *new_lai, struct osmo_plmn_id *last_eutran_plmn); void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub); void vlr_sgs_loc_update_rej_sent(struct vlr_subscr *vsub); void vlr_sgs_detach(struct vlr_instance *vlr, const char *imsi, bool eps); diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index 6379059..58ef074 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -1368,12 +1368,19 @@ static int msc_vlr_tx_common_id(void *msc_conn_ref) { struct msc_a *msc_a = msc_conn_ref; + struct vlr_subscr *vsub = msc_a_vsub(msc_a); struct ran_msg msg = { .msg_type = RAN_MSG_COMMON_ID, .common_id = { - .imsi = msc_a_vsub(msc_a)->imsi, + .imsi = vsub->imsi, + .last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present, }, }; + if (vsub->sgs.last_eutran_plmn_present) { + memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn, + sizeof(vsub->sgs.last_eutran_plmn)); + } + return msc_a_ran_down(msc_a, MSC_ROLE_I, &msg); } diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c index 0645c54..daa5bc7 100644 --- a/src/libmsc/msc_a.c +++ b/src/libmsc/msc_a.c @@ -1648,8 +1648,13 @@ .msg_type = RAN_MSG_COMMON_ID, .common_id = { .imsi = vsub->imsi, + .last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present, }, }; + if (vsub->sgs.last_eutran_plmn_present) { + memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn, + sizeof(vsub->sgs.last_eutran_plmn)); + } return msc_a_ran_down(msc_a, to_role, &msg); } diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c index 2890076..4cce289 100644 --- a/src/libmsc/ran_msg_a.c +++ b/src/libmsc/ran_msg_a.c @@ -1218,7 +1218,11 @@ return ran_a_make_assignment_command(caller_fi, &ran_enc_msg->assignment_command); case RAN_MSG_COMMON_ID: - return gsm0808_create_common_id(ran_enc_msg->common_id.imsi, NULL, NULL); + return gsm0808_create_common_id(ran_enc_msg->common_id.imsi, NULL, + ran_enc_msg->common_id.last_eutran_plmn_present ? + &ran_enc_msg->common_id.last_eutran_plmn : + NULL + ); case RAN_MSG_CIPHER_MODE_COMMAND: return ran_a_make_cipher_mode_command(caller_fi, &ran_enc_msg->cipher_mode_command); diff --git a/src/libmsc/sgs_iface.c b/src/libmsc/sgs_iface.c index d13449d..04302ae 100644 --- a/src/libmsc/sgs_iface.c +++ b/src/libmsc/sgs_iface.c @@ -608,12 +608,14 @@ char *mme_name; struct vlr_sgs_cfg vlr_sgs_cfg; struct vlr_subscr *vsub; + struct osmo_plmn_id last_eutran_plmn_buf, *last_eutran_plmn = NULL; /* Check for lingering connections */ vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__); if (vsub) { subscr_conn_toss(vsub); vlr_subscr_put(vsub, __func__); + vsub = NULL; } /* Determine MME-Name */ @@ -639,11 +641,29 @@ return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MISSING_MAND_IE, msg, SGSAP_IE_LAI); gsm48_decode_lai2(gsm48_lai, &new_lai); + /* 3GPP TS 23.272 sec 4.3.3 (CSFB): + * "During the SGs location update procedure, obtaining the last used LTE PLMN ID via TAI" + */ + if (TLVP_PRES_LEN(tp, SGSAP_IE_TAI, 3)) { + last_eutran_plmn = &last_eutran_plmn_buf; + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_TAI), last_eutran_plmn); + /* TODO: we could also gather the TAC from here, but we don't need it yet */ + } else if (TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3)) { + /* Since TAI is optional, let's try harder getting Last Used + * E-UTRAN PLMN ID by fetching it from E-UTRAN CGI */ + last_eutran_plmn = &last_eutran_plmn_buf; + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_EUTRAN_CGI), last_eutran_plmn); + /* TODO: we could also gather the ECI from here, but we don't need it yet */ + } else { + LOGSGC(sgc, LOGL_INFO, "Receiving SGsAP-LOCATION-UPDATE-REQUEST without TAI nor " + "E-CGI IEs, fast fallback GERAN->EUTRAN won't be possible!\n"); + } + /* Perform actual location update */ memcpy(vlr_sgs_cfg.timer, sgc->sgs->cfg.timer, sizeof(vlr_sgs_cfg.timer)); memcpy(vlr_sgs_cfg.counter, sgc->sgs->cfg.counter, sizeof(vlr_sgs_cfg.counter)); rc = vlr_sgs_loc_update(gsm_network->vlr, &vlr_sgs_cfg, sgs_tx_loc_upd_resp_cb, sgs_iface_tx_paging, - sgs_tx_mm_info_cb, mme_name, type, imsi, &new_lai); + sgs_tx_mm_info_cb, mme_name, type, imsi, &new_lai, last_eutran_plmn); if (rc != 0) { resp = gsm29118_create_lu_rej(imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, NULL); sgs_tx(sgc, resp); @@ -905,6 +925,26 @@ if (!vsub) return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, msg, SGSAP_IE_IMSI); + /* 3GPP TS 23.272 sec 4.3.3 (CSFB): + * "During the SGs location update procedure, obtaining the last used LTE PLMN ID via TAI" + */ + vsub->sgs.last_eutran_plmn_present = TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3); + if (TLVP_PRES_LEN(tp, SGSAP_IE_TAI, 3)) { + vsub->sgs.last_eutran_plmn_present = true; + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_TAI), &vsub->sgs.last_eutran_plmn); + /* TODO: we could also gather the TAC from here, but we don't need it yet */ + } else if (TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3)) { + /* Since TAI is optional, let's try harder getting Last Used + * E-UTRAN PLMN ID by fetching it from E-UTRAN CGI */ + vsub->sgs.last_eutran_plmn_present = true; + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_EUTRAN_CGI), &vsub->sgs.last_eutran_plmn); + /* TODO: we could also gather the ECI from here, but we don't need it yet */ + } else if (!vsub->sgs.last_eutran_plmn_present) { + LOGSGC(sgc, LOGL_INFO, "Receiving SGsAP-MO-CSFB-INDICATION without TAI nor " + "E-CGI IEs, and they are not known from previous SGsAP-LOCATION-UPDATE-REQUEST. " + "Fast fallback GERAN->EUTRAN won't be possible!\n"); + } + /* Check for lingering connections */ subscr_conn_toss(vsub); diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c index 33d6331..02aceef 100644 --- a/src/libvlr/vlr.c +++ b/src/libvlr/vlr.c @@ -476,6 +476,23 @@ vsub->imsi, vsub->msisdn); } +void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub, + const struct osmo_plmn_id *last_eutran_plmn) +{ + if (!vsub) + return; + if (last_eutran_plmn) { + vsub->sgs.last_eutran_plmn_present = true; + memcpy(&vsub->sgs.last_eutran_plmn, last_eutran_plmn, sizeof(*last_eutran_plmn)); + } else { + vsub->sgs.last_eutran_plmn_present = false; + } + DEBUGP(DVLR, "set Last E-UTRAN PLMN ID on subscriber: %s\n", + vsub->sgs.last_eutran_plmn_present ? + osmo_plmn_name(&vsub->sgs.last_eutran_plmn) : + "(none)"); +} + bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi) { return vsub && imsi && vsub->imsi[0] && !strcmp(vsub->imsi, imsi); diff --git a/src/libvlr/vlr_sgs.c b/src/libvlr/vlr_sgs.c index 269dda6..5659886 100644 --- a/src/libvlr/vlr_sgs.c +++ b/src/libvlr/vlr_sgs.c @@ -68,11 +68,12 @@ * \param[in] type location update type (normal or IMSI attach). * \param[in] imsi mobile identity (IMSI). * \param[in] new_lai identifier of the new location area. + * \param[in] last_eutran_plnm_id Last E-UTRAN PLMN ID (can be NULL). * \returns 0 in case of success, -EINVAL in case of error. */ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg, vlr_sgs_lu_response_cb_t response_cb, vlr_sgs_lu_paging_cb_t paging_cb, vlr_sgs_lu_mminfo_cb_t mminfo_cb, char *mme_name, enum vlr_lu_type type, const char *imsi, - struct osmo_location_area_id *new_lai) + struct osmo_location_area_id *new_lai, struct osmo_plmn_id *last_eutran_plmn) { struct vlr_subscr *vsub = NULL; @@ -93,6 +94,7 @@ vsub->sgs.paging_cb = paging_cb; vsub->sgs.mminfo_cb = mminfo_cb; vlr_subscr_set_imsi(vsub, imsi); + vlr_subscr_set_last_used_eutran_plmn_id(vsub, last_eutran_plmn); osmo_strlcpy(vsub->sgs.mme_name, mme_name, sizeof(vsub->sgs.mme_name)); osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_RX_LU_FROM_MME, NULL); -- To view, visit https://gerrit.osmocom.org/c/osmo-msc/+/23915 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-msc Gerrit-Branch: master Gerrit-Change-Id: Ic5f175b179973d0a50d94f00e15f5a3e332605fc Gerrit-Change-Number: 23915 Gerrit-PatchSet: 4 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: dexter <pmaier at sysmocom.de> Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de> Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-Reviewer: pespin <pespin at sysmocom.de> Gerrit-MessageType: merged -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210429/e7fa341a/attachment.htm>