[GPRS] SGSN: Pass BSSGP SUSPEND/RESUME up to GMM and alter MMCTX state
This commit is contained in:
parent
f54e7e2102
commit
5bfe499366
|
@ -11,4 +11,8 @@ int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
|
||||||
|
|
||||||
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
|
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
|
||||||
|
|
||||||
|
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
|
||||||
|
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
||||||
|
uint8_t suspend_ref);
|
||||||
|
|
||||||
#endif /* _GPRS_GMM_H */
|
#endif /* _GPRS_GMM_H */
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <openbsc/gprs_llc.h>
|
#include <openbsc/gprs_llc.h>
|
||||||
#include <openbsc/gprs_ns.h>
|
#include <openbsc/gprs_ns.h>
|
||||||
#include <openbsc/gprs_sgsn.h>
|
#include <openbsc/gprs_sgsn.h>
|
||||||
|
#include <openbsc/gprs_gmm.h>
|
||||||
|
|
||||||
void *bssgp_tall_ctx = NULL;
|
void *bssgp_tall_ctx = NULL;
|
||||||
|
|
||||||
|
@ -363,6 +364,7 @@ static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
|
||||||
(struct bssgp_normal_hdr *) msgb_bssgph(msg);
|
(struct bssgp_normal_hdr *) msgb_bssgph(msg);
|
||||||
struct gprs_ra_id raid;
|
struct gprs_ra_id raid;
|
||||||
uint32_t tlli;
|
uint32_t tlli;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
|
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
|
||||||
!TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
|
!TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
|
||||||
|
@ -378,8 +380,11 @@ static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
|
||||||
|
|
||||||
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
|
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
|
||||||
|
|
||||||
/* FIXME: pass the SUSPEND request to GMM */
|
/* Inform GMM about the SUSPEND request */
|
||||||
/* SEND SUSPEND_ACK or SUSPEND_NACK */
|
rc = gprs_gmm_rx_suspend(&raid, tlli);
|
||||||
|
if (rc < 0)
|
||||||
|
return bssgp_tx_suspend_nack(msgb_nsei(msg), tlli, NULL);
|
||||||
|
|
||||||
bssgp_tx_suspend_ack(msgb_nsei(msg), tlli, &raid, 0);
|
bssgp_tx_suspend_ack(msgb_nsei(msg), tlli, &raid, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -392,6 +397,8 @@ static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
|
||||||
(struct bssgp_normal_hdr *) msgb_bssgph(msg);
|
(struct bssgp_normal_hdr *) msgb_bssgph(msg);
|
||||||
struct gprs_ra_id raid;
|
struct gprs_ra_id raid;
|
||||||
uint32_t tlli;
|
uint32_t tlli;
|
||||||
|
uint8_t suspend_ref;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
|
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
|
||||||
!TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA) ||
|
!TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA) ||
|
||||||
|
@ -402,13 +409,18 @@ static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
|
||||||
}
|
}
|
||||||
|
|
||||||
tlli = ntohl(*(uint32_t *)TLVP_VAL(tp, BSSGP_IE_TLLI));
|
tlli = ntohl(*(uint32_t *)TLVP_VAL(tp, BSSGP_IE_TLLI));
|
||||||
|
suspend_ref = *TLVP_VAL(tp, BSSGP_IE_SUSPEND_REF_NR);
|
||||||
|
|
||||||
DEBUGP(DBSSGP, "BSSGP BVCI=%u TLLI=0x%08x RESUME\n", ctx->bvci, tlli);
|
DEBUGP(DBSSGP, "BSSGP BVCI=%u TLLI=0x%08x RESUME\n", ctx->bvci, tlli);
|
||||||
|
|
||||||
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
|
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
|
||||||
|
|
||||||
/* FIXME: pass the RESUME request to GMM */
|
/* Inform GMM about the RESUME request */
|
||||||
/* SEND RESUME_ACK or RESUME_NACK */
|
rc = gprs_gmm_rx_resume(&raid, tlli, suspend_ref);
|
||||||
|
if (rc < 0)
|
||||||
|
return bssgp_tx_resume_nack(msgb_nsei(msg), tlli, &raid,
|
||||||
|
NULL);
|
||||||
|
|
||||||
bssgp_tx_resume_ack(msgb_nsei(msg), tlli, &raid);
|
bssgp_tx_resume_ack(msgb_nsei(msg), tlli, &raid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1270,3 +1270,51 @@ int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme)
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
|
||||||
|
{
|
||||||
|
struct sgsn_mm_ctx *mmctx;
|
||||||
|
|
||||||
|
mmctx = sgsn_mm_ctx_by_tlli(tlli, raid);
|
||||||
|
if (!mmctx) {
|
||||||
|
LOGP(DMM, LOGL_NOTICE, "SUSPEND request for unknown "
|
||||||
|
"TLLI=%08x\n", tlli);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmctx->mm_state != GMM_REGISTERED_NORMAL) {
|
||||||
|
LOGP(DMM, LOGL_NOTICE, "SUSPEND request while state "
|
||||||
|
"!= REGISTERED (TLLI=%08x)\n", tlli);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */
|
||||||
|
mmctx->mm_state = GMM_REGISTERED_SUSPENDED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
||||||
|
uint8_t suspend_ref)
|
||||||
|
{
|
||||||
|
struct sgsn_mm_ctx *mmctx;
|
||||||
|
|
||||||
|
/* FIXME: make use of suspend reference? */
|
||||||
|
|
||||||
|
mmctx = sgsn_mm_ctx_by_tlli(tlli, raid);
|
||||||
|
if (!mmctx) {
|
||||||
|
LOGP(DMM, LOGL_NOTICE, "RESUME request for unknown "
|
||||||
|
"TLLI=%08x\n", tlli);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmctx->mm_state != GMM_REGISTERED_SUSPENDED) {
|
||||||
|
LOGP(DMM, LOGL_NOTICE, "RESUME request while state "
|
||||||
|
"!= SUSPENDED (TLLI=%08x)\n", tlli);
|
||||||
|
/* FIXME: should we not simply ignore it? */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transition from SUSPENDED to NORMAL */
|
||||||
|
mmctx->mm_state = GMM_REGISTERED_NORMAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue