gmm: Implement rx RAU Reject

Change-Id: I0d4d8288b78cfd3140c786a52a3906eaf37ebe6b
This commit is contained in:
Pau Espin 2023-05-26 17:14:26 +02:00
parent b182b7c26d
commit d2fd394e4d
3 changed files with 60 additions and 6 deletions

View File

@ -51,7 +51,7 @@ enum gprs_gmm_ms_fsm_events {
GPRS_GMM_MS_EV_SR_REJECTED, /* (Iu only) */
GPRS_GMM_MS_EV_SR_ACCEPTED, /* (Iu only) */
GPRS_GMM_MS_EV_RAU_REQUESTED,
GPRS_GMM_MS_EV_RAU_REJECTED,
GPRS_GMM_MS_EV_RAU_REJECTED, /* data: ptr to "uint8_t cause" */
GPRS_GMM_MS_EV_RAU_ACCEPTED,
GPRS_GMM_MS_EV_LOW_LVL_FAIL,
};

View File

@ -1137,6 +1137,49 @@ rejected:
return -EINVAL; /* TODO: what to do on error? */
}
/* Rx GMM Routing area update reject, 9.4.17 */
static int gprs_gmm_rx_rau_rej(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
{
uint8_t *buf = &gh->data[0];
struct tlv_parsed tp;
uint8_t cause = GMM_CAUSE_SEM_INCORR_MSG;
bool force_standby_indicated;
int rc;
if (len < sizeof(*gh) + 2) {
LOGGMME(gmme, LOGL_ERROR, "Rx GMM ROUTING AREA UPDATE REJECT with wrong size %u\n", len);
goto rejected;
}
cause = buf[0];
force_standby_indicated = (buf[1] >> 4) == 0x01;
buf += 2;
LOGGMME(gmme, LOGL_NOTICE, "Rx GMM ROUTING AREA UPDATE REJECT cause='%s' (%u) force_stdby=%u\n",
get_value_string(gsm48_gmm_cause_names, cause), cause, force_standby_indicated);
if (force_standby_indicated)
gprs_gmm_gmme_ready_timer_stop(gmme);
if (len > (buf - (uint8_t *)gh)) {
rc = gprs_gmm_tlv_parse(&tp, buf, len - (buf - (uint8_t *)gh));
if (rc < 0) {
LOGGMME(gmme, LOGL_ERROR, "Rx GMM ROUTING AREA UPDATE REJECT: failed to parse TLVs %d\n", rc);
goto rejected;
}
if (TLVP_PRES_LEN(&tp, GSM48_IE_GMM_TIMER_T3302, 1))
gmme->t3302 = *TLVP_VAL(&tp, GSM48_IE_GMM_TIMER_T3302);
if (TLVP_PRES_LEN(&tp, GSM48_IE_GMM_TIMER_T3346, 1))
gmme->t3346 = *TLVP_VAL(&tp, GSM48_IE_GMM_TIMER_T3346);
}
rejected:
rc = osmo_fsm_inst_dispatch(gmme->ms_fsm.fi, GPRS_GMM_MS_EV_RAU_REJECTED, &cause);
return -EINVAL;
}
/* Rx GMM Identity Request, 9.2.10 */
static int gprs_gmm_rx_id_req(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
{
@ -1380,6 +1423,9 @@ int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int
case GSM48_MT_GMM_RA_UPD_ACK:
rc = gprs_gmm_rx_rau_acc(gmme, gh, len);
break;
case GSM48_MT_GMM_RA_UPD_REJ:
rc = gprs_gmm_rx_rau_rej(gmme, gh, len);
break;
case GSM48_MT_GMM_ID_REQ:
rc = gprs_gmm_rx_id_req(gmme, gh, len);
break;

View File

@ -239,13 +239,22 @@ static void st_gmm_ms_rau_initiated(struct osmo_fsm_inst *fi, uint32_t event, vo
{
struct gprs_gmm_ms_fsm_ctx *ctx = (struct gprs_gmm_ms_fsm_ctx *)fi->priv;
struct osmo_gprs_llc_prim *llc_prim_tx;
enum gsm48_gmm_cause cause;
switch (event) {
case GPRS_GMM_MS_EV_RAU_REJECTED:
// causes #13, #15, #25
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
// else
//mm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_DEREGISTERED_INITIATED);
cause = *(uint8_t *)data;
/* 3GPP TS 24.008 Figure 4.1b */
switch (cause) {
case GMM_CAUSE_ROAMING_NOTALLOWED:
case GMM_CAUSE_NO_SUIT_CELL_IN_LA:
case GMM_CAUSE_NOT_AUTH_FOR_CSG:
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
break;
default:
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_DEREGISTERED);
break;
}
break;
case GPRS_GMM_MS_EV_RAU_ACCEPTED:
gprs_gmm_gmme_t3316_stop(ctx->gmme);
@ -351,7 +360,6 @@ static struct osmo_fsm_state gmm_ms_fsm_states[] = {
X(GPRS_GMM_MS_EV_RAU_ACCEPTED),
.out_state_mask =
X(GPRS_GMM_MS_ST_REGISTERED) |
X(GPRS_GMM_MS_ST_DEREGISTERED_INITIATED) |
X(GPRS_GMM_MS_ST_DEREGISTERED),
.name = "RAUInitidated",
.action = st_gmm_ms_rau_initiated,