aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gprs_gmm.h4
-rw-r--r--openbsc/src/gprs/gprs_bssgp.c20
-rw-r--r--openbsc/src/gprs/gprs_gmm.c48
3 files changed, 68 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h
index 2cea6f419..b91b489d3 100644
--- a/openbsc/include/openbsc/gprs_gmm.h
+++ b/openbsc/include/openbsc/gprs_gmm.h
@@ -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 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 */
diff --git a/openbsc/src/gprs/gprs_bssgp.c b/openbsc/src/gprs/gprs_bssgp.c
index 89b78662e..c7c49d4bd 100644
--- a/openbsc/src/gprs/gprs_bssgp.c
+++ b/openbsc/src/gprs/gprs_bssgp.c
@@ -40,6 +40,7 @@
#include <openbsc/gprs_llc.h>
#include <openbsc/gprs_ns.h>
#include <openbsc/gprs_sgsn.h>
+#include <openbsc/gprs_gmm.h>
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 gprs_ra_id raid;
uint32_t tlli;
+ int rc;
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
!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));
- /* FIXME: pass the SUSPEND request to GMM */
- /* SEND SUSPEND_ACK or SUSPEND_NACK */
+ /* Inform GMM about the SUSPEND request */
+ 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);
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 gprs_ra_id raid;
uint32_t tlli;
+ uint8_t suspend_ref;
+ int rc;
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
!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));
+ suspend_ref = *TLVP_VAL(tp, BSSGP_IE_SUSPEND_REF_NR);
DEBUGP(DBSSGP, "BSSGP BVCI=%u TLLI=0x%08x RESUME\n", ctx->bvci, tlli);
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
- /* FIXME: pass the RESUME request to GMM */
- /* SEND RESUME_ACK or RESUME_NACK */
+ /* Inform GMM about the RESUME request */
+ 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);
return 0;
}
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index ad9a546ec..17d2ed07f 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -1270,3 +1270,51 @@ int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme)
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;
+}