gmm: Implement rx RAU Reject
Change-Id: I0d4d8288b78cfd3140c786a52a3906eaf37ebe6b
This commit is contained in:
parent
b182b7c26d
commit
d2fd394e4d
|
@ -51,7 +51,7 @@ enum gprs_gmm_ms_fsm_events {
|
||||||
GPRS_GMM_MS_EV_SR_REJECTED, /* (Iu only) */
|
GPRS_GMM_MS_EV_SR_REJECTED, /* (Iu only) */
|
||||||
GPRS_GMM_MS_EV_SR_ACCEPTED, /* (Iu only) */
|
GPRS_GMM_MS_EV_SR_ACCEPTED, /* (Iu only) */
|
||||||
GPRS_GMM_MS_EV_RAU_REQUESTED,
|
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_RAU_ACCEPTED,
|
||||||
GPRS_GMM_MS_EV_LOW_LVL_FAIL,
|
GPRS_GMM_MS_EV_LOW_LVL_FAIL,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1137,6 +1137,49 @@ rejected:
|
||||||
return -EINVAL; /* TODO: what to do on error? */
|
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 */
|
/* 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)
|
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:
|
case GSM48_MT_GMM_RA_UPD_ACK:
|
||||||
rc = gprs_gmm_rx_rau_acc(gmme, gh, len);
|
rc = gprs_gmm_rx_rau_acc(gmme, gh, len);
|
||||||
break;
|
break;
|
||||||
|
case GSM48_MT_GMM_RA_UPD_REJ:
|
||||||
|
rc = gprs_gmm_rx_rau_rej(gmme, gh, len);
|
||||||
|
break;
|
||||||
case GSM48_MT_GMM_ID_REQ:
|
case GSM48_MT_GMM_ID_REQ:
|
||||||
rc = gprs_gmm_rx_id_req(gmme, gh, len);
|
rc = gprs_gmm_rx_id_req(gmme, gh, len);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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 gprs_gmm_ms_fsm_ctx *ctx = (struct gprs_gmm_ms_fsm_ctx *)fi->priv;
|
||||||
struct osmo_gprs_llc_prim *llc_prim_tx;
|
struct osmo_gprs_llc_prim *llc_prim_tx;
|
||||||
|
enum gsm48_gmm_cause cause;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case GPRS_GMM_MS_EV_RAU_REJECTED:
|
case GPRS_GMM_MS_EV_RAU_REJECTED:
|
||||||
// causes #13, #15, #25
|
cause = *(uint8_t *)data;
|
||||||
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
|
/* 3GPP TS 24.008 Figure 4.1b */
|
||||||
// else
|
switch (cause) {
|
||||||
//mm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_DEREGISTERED_INITIATED);
|
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;
|
break;
|
||||||
case GPRS_GMM_MS_EV_RAU_ACCEPTED:
|
case GPRS_GMM_MS_EV_RAU_ACCEPTED:
|
||||||
gprs_gmm_gmme_t3316_stop(ctx->gmme);
|
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),
|
X(GPRS_GMM_MS_EV_RAU_ACCEPTED),
|
||||||
.out_state_mask =
|
.out_state_mask =
|
||||||
X(GPRS_GMM_MS_ST_REGISTERED) |
|
X(GPRS_GMM_MS_ST_REGISTERED) |
|
||||||
X(GPRS_GMM_MS_ST_DEREGISTERED_INITIATED) |
|
|
||||||
X(GPRS_GMM_MS_ST_DEREGISTERED),
|
X(GPRS_GMM_MS_ST_DEREGISTERED),
|
||||||
.name = "RAUInitidated",
|
.name = "RAUInitidated",
|
||||||
.action = st_gmm_ms_rau_initiated,
|
.action = st_gmm_ms_rau_initiated,
|
||||||
|
|
Loading…
Reference in New Issue