vlr: add the location update type to the callbacks tx_lu_acc/tx_lu_rej

The location update type (IMSI attach, periodic, location area change) is
required when the SGSN is using the vlr code to send back the correct PDU to the MS.
The MSC always sends Location Update Accept/Reject, but the SGSN has to transmit
either Routing Area Accept/Reject or Attach Accept/Reject.

Change-Id: I980a637333e92b15f2d516683feeaded910105b6
This commit is contained in:
Alexander Couzens
2024-10-08 21:03:26 +02:00
parent 45d9b166eb
commit 3832541c3f
4 changed files with 21 additions and 17 deletions

View File

@@ -239,8 +239,8 @@ struct vlr_ops {
/* encode + transmit an IDENTITY REQUEST towards the MS */
int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type);
int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi);
int (*tx_lu_rej)(void *msc_conn_ref, enum gsm48_reject_value cause);
int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi, enum vlr_lu_type lu_type);
int (*tx_lu_rej)(void *msc_conn_ref, enum gsm48_reject_value cause, enum vlr_lu_type lu_type);
int (*tx_cm_serv_acc)(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type);
int (*tx_cm_serv_rej)(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type,
enum gsm48_reject_value cause);
@@ -298,7 +298,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
uint32_t parent_event_failure,
void *parent_event_data,
struct vlr_instance *vlr, void *msc_conn_ref,
enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
enum vlr_lu_type lu_type, uint32_t tmsi, const char *imsi,
const struct osmo_location_area_id *old_lai,
const struct osmo_location_area_id *new_lai,
bool authentication_required,

View File

@@ -1474,14 +1474,14 @@ static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type)
}
/* VLR asks us to transmit a Location Update Accept */
static int msc_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi)
static int msc_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi, enum vlr_lu_type lu_type)
{
struct msc_a *msc_a = msc_conn_ref;
return gsm0408_loc_upd_acc(msc_a, send_tmsi);
}
/* VLR asks us to transmit a Location Update Reject */
static int msc_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
static int msc_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause, enum vlr_lu_type lu_type)
{
struct msc_a *msc_a = msc_conn_ref;
return gsm0408_loc_upd_rej(msc_a, cause);

View File

@@ -339,6 +339,7 @@ struct lu_compl_vlr_priv {
enum vlr_fsm_result result;
uint8_t cause;
bool assign_tmsi;
enum vlr_lu_type lu_type;
};
static inline struct lu_compl_vlr_priv *lu_compl_vlr_fi_priv(struct osmo_fsm_inst *fi);
@@ -434,7 +435,7 @@ static void lu_compl_vlr_new_tmsi(struct osmo_fsm_inst *fi)
osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_WAIT_TMSI_CNF,
vlr_timer_secs(vlr, 3250), 3250);
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, vsub->tmsi_new);
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, vsub->tmsi_new, lcvp->lu_type);
}
/* After completion of Subscriber_Present_VLR */
@@ -473,7 +474,7 @@ static void lu_compl_vlr_wait_subscr_pres(struct osmo_fsm_inst *fi,
vsub->tmsi = GSM_RESERVED_TMSI;
/* Location Updating Accept */
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI);
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI, lcvp->lu_type);
vlr_lu_compl_fsm_success(fi);
}
@@ -520,7 +521,7 @@ static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event,
vsub->tmsi = GSM_RESERVED_TMSI;
/* No TMSI needed, accept now. */
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI);
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI, lcvp->lu_type);
vlr_lu_compl_fsm_success(fi);
}
@@ -616,7 +617,8 @@ lu_compl_vlr_proc_alloc(struct osmo_fsm_inst *parent,
void *msc_conn_ref,
uint32_t parent_event_success,
uint32_t parent_event_failure,
bool assign_tmsi)
bool assign_tmsi,
enum vlr_lu_type lu_type)
{
struct osmo_fsm_inst *fi;
struct lu_compl_vlr_priv *lcvp;
@@ -632,6 +634,7 @@ lu_compl_vlr_proc_alloc(struct osmo_fsm_inst *parent,
lcvp->parent_event_success = parent_event_success;
lcvp->parent_event_failure = parent_event_failure;
lcvp->assign_tmsi = assign_tmsi;
lcvp->lu_type = lu_type;
fi->priv = lcvp;
return fi;
@@ -675,7 +678,7 @@ struct lu_fsm_priv {
enum vlr_fsm_result result;
uint8_t rej_cause;
enum vlr_lu_type type;
enum vlr_lu_type lu_type;
bool lu_by_tmsi;
char imsi[16];
uint32_t tmsi;
@@ -762,7 +765,7 @@ static void lu_fsm_success(struct osmo_fsm_inst *fi)
static void lu_fsm_failure(struct osmo_fsm_inst *fi, enum gsm48_reject_value rej_cause)
{
struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
lfp->vlr->ops.tx_lu_rej(lfp->msc_conn_ref, rej_cause ? : GSM48_REJECT_NETWORK_FAILURE);
lfp->vlr->ops.tx_lu_rej(lfp->msc_conn_ref, rej_cause ? : GSM48_REJECT_NETWORK_FAILURE, lfp->lu_type);
_lu_fsm_done(fi, VLR_FSM_RESULT_FAILURE);
}
@@ -773,7 +776,8 @@ static void vlr_loc_upd_start_lu_compl_fsm(struct osmo_fsm_inst *fi)
lu_compl_vlr_proc_alloc(fi, lfp->vsub, lfp->msc_conn_ref,
VLR_ULA_E_LU_COMPL_SUCCESS,
VLR_ULA_E_LU_COMPL_FAILURE,
lfp->assign_tmsi);
lfp->assign_tmsi,
lfp->lu_type);
osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm, LU_COMPL_VLR_E_START, NULL);
}
@@ -1106,7 +1110,7 @@ static void lu_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event,
/* See 3GPP TS 23.012, procedure Retrieve_IMEISV_If_Required */
if ((!vlr->cfg.retrieve_imeisv_early)
|| (lfp->type == VLR_LU_TYPE_PERIODIC && lfp->vsub->imeisv[0])) {
|| (lfp->lu_type == VLR_LU_TYPE_PERIODIC && lfp->vsub->imeisv[0])) {
/* R_IMEISV_IR1 passed */
_start_lu_main(fi);
} else {
@@ -1307,7 +1311,7 @@ static void lu_fsm_wait_lu_compl(struct osmo_fsm_inst *fi, uint32_t event,
/* TODO: Notify_gsmSCF 23.078 */
/* TODO: Authenticated Radio Contact Established -> ARC */
if (lfp->type == VLR_LU_TYPE_IMSI_ATTACH)
if (lfp->lu_type == VLR_LU_TYPE_IMSI_ATTACH)
lfp->vlr->ops.tx_mm_info(lfp->msc_conn_ref);
lu_fsm_success(fi);
@@ -1529,7 +1533,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
lfp->vlr = vlr;
lfp->msc_conn_ref = msc_conn_ref;
lfp->tmsi = tmsi;
lfp->type = type;
lfp->lu_type = type;
lfp->old_lai = *old_lai;
lfp->new_lai = *new_lai;
lfp->lu_by_tmsi = true;

View File

@@ -934,7 +934,7 @@ void crcx_ok(enum rtp_direction dir)
osmo_fsm_inst_dispatch(cl->fi, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, cl->rtp[dir]);
}
static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi)
static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi, enum vlr_lu_type lu_type)
{
struct msc_a *msc_a = msc_conn_ref;
if (send_tmsi == GSM_RESERVED_TMSI)
@@ -946,7 +946,7 @@ static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi)
return 0;
}
static int fake_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
static int fake_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause, enum vlr_lu_type lu_type)
{
struct msc_a *msc_a = msc_conn_ref;
btw("sending LU Reject for %s, cause %u", msc_a->c.fi->id, cause);