pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-gprs/+/32959 )


Change subject: llc: Add APIs to submit LLGM-trigger/suspend/resume.req 
primitives
......................................................................

llc: Add APIs to submit LLGM-trigger/suspend/resume.req primitives

This commit also adds an initial implementation of
LLGM-suspend/resume.req.

Change-Id: I890c7a4ace6fb8ca362ec41bd18e9c229191a587
---
M include/osmocom/gprs/llc/llc_prim.h
M include/osmocom/gprs/llc/llc_private.h
M src/llc/llc_ll.c
M src/llc/llc_llgmm.c
4 files changed, 98 insertions(+), 3 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/59/32959/1

diff --git a/include/osmocom/gprs/llc/llc_prim.h 
b/include/osmocom/gprs/llc/llc_prim.h
index d5a424d..904e9fa 100644
--- a/include/osmocom/gprs/llc/llc_prim.h
+++ b/include/osmocom/gprs/llc/llc_prim.h
@@ -300,6 +300,9 @@
 /* Alloc primitive for LLGMM SAP: */
 struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_assign_req(uint32_t 
tlli);
 struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_reset_req(uint32_t 
tlli);
+struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_trigger_req(uint32_t 
tlli, uint8_t cause);
+struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_suspend_req(uint32_t 
tlli);
+struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_resume_req(uint32_t 
tlli);

 /* Alloc primitive for LL SAP: */
 struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_ll_establish_req(uint32_t 
tlli, enum osmo_gprs_llc_sapi ll_sapi,
diff --git a/include/osmocom/gprs/llc/llc_private.h 
b/include/osmocom/gprs/llc/llc_private.h
index 994acd8..ed68c7b 100644
--- a/include/osmocom/gprs/llc/llc_private.h
+++ b/include/osmocom/gprs/llc/llc_private.h
@@ -254,6 +254,10 @@

        /* Internal management */
        uint32_t age_timestamp;
+
+       /* TS 44.064 ยง C.2: "In addition, all states should observe the 
suspended
+        * operation (reception of LLGMM-SUSPEND-REQ) restrictions" */
+       bool suspended;
 };

 static inline struct gprs_llc_lle *gprs_llc_llme_get_lle(struct gprs_llc_llme 
*llme,
diff --git a/src/llc/llc_ll.c b/src/llc/llc_ll.c
index 43a0951..a13a7f5 100644
--- a/src/llc/llc_ll.c
+++ b/src/llc/llc_ll.c
@@ -277,9 +277,15 @@
                lle = gprs_llc_llme_get_lle(llme, llc_prim->ll.sapi);
        }

+       if (lle->llme->suspended && llc_prim->ll.sapi != 
OSMO_GPRS_LLC_SAPI_GMM) {
+               LOGLLE(lle, LOGL_NOTICE, "Dropping frame to transmit, LLME is 
suspended\n");
+               goto ret_free;
+       }
+
        rc = gprs_llc_lle_tx_ui(lle, llc_prim->ll.l3_pdu, 
llc_prim->ll.l3_pdu_len,
                                llc_prim->ll.unitdata_req.apply_gea);

+ret_free:
        msgb_free(llc_prim->oph.msg);
        return rc;
 }
diff --git a/src/llc/llc_llgmm.c b/src/llc/llc_llgmm.c
index 5834041..7b09a69 100644
--- a/src/llc/llc_llgmm.c
+++ b/src/llc/llc_llgmm.c
@@ -100,7 +100,7 @@
        return llc_prim;
 }

-/* 7.2.1.2 LLGMM-RESET.cnf (SGSN):*/
+/* 7.2.1.2 LLGMM-RESET.cnf (SGSN): */
 struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_reset_cnf(uint32_t 
tlli)
 {
        struct osmo_gprs_llc_prim *llc_prim;
@@ -109,6 +109,34 @@
        return llc_prim;
 }

+/* 7.2.1.3 LLGMM-TRIGGER.req (MS): */
+struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_trigger_req(uint32_t 
tlli, uint8_t cause)
+{
+       struct osmo_gprs_llc_prim *llc_prim;
+       llc_prim = llc_prim_llgmm_alloc(OSMO_GPRS_LLC_LLGMM_TRIGGER, 
PRIM_OP_REQUEST, 0);
+       llc_prim->llgmm.tlli = tlli;
+       llc_prim->llgmm.trigger_req.cause = cause;
+       return llc_prim;
+}
+
+/* 7.2.1.4 LLGMM-SUSPEND.req (MS/SGSN): */
+struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_suspend_req(uint32_t 
tlli)
+{
+       struct osmo_gprs_llc_prim *llc_prim;
+       llc_prim = llc_prim_llgmm_alloc(OSMO_GPRS_LLC_LLGMM_SUSPEND, 
PRIM_OP_REQUEST, 0);
+       llc_prim->llgmm.tlli = tlli;
+       return llc_prim;
+}
+
+/* 7.2.1.5 LLGMM-RESUME.req (MS/SGSN):*/
+struct osmo_gprs_llc_prim *osmo_gprs_llc_prim_alloc_llgm_resume_req(uint32_t 
tlli)
+{
+       struct osmo_gprs_llc_prim *llc_prim;
+       llc_prim = llc_prim_llgmm_alloc(OSMO_GPRS_LLC_LLGMM_RESUME, 
PRIM_OP_REQUEST, 0);
+       llc_prim->llgmm.tlli = tlli;
+       return llc_prim;
+}
+
 /********************************
  * Handling from upper layers:
  ********************************/
@@ -246,6 +274,48 @@
        return rc;
 }

+/* 7.2.1.4 LLGMM-SUSPEND.req (MS/SGSN):*/
+static int llc_prim_handle_llgm_suspend_req(struct osmo_gprs_llc_prim 
*llc_prim)
+{
+       int rc = 0;
+       struct gprs_llc_llme *llme = 
gprs_llc_find_llme_by_tlli(llc_prim->llgmm.tlli);
+
+       if (!llme) {
+               LOGLLC(LOGL_NOTICE, "Rx %s: Unknown TLLI 0x%08x\n",
+                       osmo_gprs_llc_prim_name(llc_prim), 
llc_prim->llgmm.tlli);
+               rc = -ENOKEY;
+               goto ret_free;
+       }
+       LOGLLME(llme, LOGL_INFO, "%s\n", osmo_gprs_llc_prim_name(llc_prim));
+
+       llme->suspended = true;
+
+ret_free:
+       msgb_free(llc_prim->oph.msg);
+       return rc;
+}
+
+/* 7.2.1.5 LLGMM-RESUME.req (MS/SGSN):*/
+static int llc_prim_handle_llgm_resume_req(struct osmo_gprs_llc_prim *llc_prim)
+{
+       int rc = 0;
+       struct gprs_llc_llme *llme = 
gprs_llc_find_llme_by_tlli(llc_prim->llgmm.tlli);
+
+       if (!llme) {
+               LOGLLC(LOGL_NOTICE, "Rx %s: Unknown TLLI 0x%08x\n",
+                       osmo_gprs_llc_prim_name(llc_prim), 
llc_prim->llgmm.tlli);
+               rc = -ENOKEY;
+               goto ret_free;
+       }
+       LOGLLME(llme, LOGL_INFO, "%s\n", osmo_gprs_llc_prim_name(llc_prim));
+
+       llme->suspended = false;
+
+ret_free:
+       msgb_free(llc_prim->oph.msg);
+       return rc;
+}
+
 /* LLC higher layers push LLC primitive down to LLC layer: */
 int gprs_llc_prim_llgmm_upper_down(struct osmo_gprs_llc_prim *llc_prim)
 {
@@ -267,12 +337,12 @@
        case OSMO_PRIM(OSMO_GPRS_LLC_LLGMM_SUSPEND, PRIM_OP_REQUEST):
                OSMO_ASSERT(g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_MS ||
                            g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_SGSN);
-               rc = gprs_llc_prim_handle_unsupported(llc_prim);
+               rc = llc_prim_handle_llgm_suspend_req(llc_prim);
                break;
        case OSMO_PRIM(OSMO_GPRS_LLC_LLGMM_RESUME, PRIM_OP_REQUEST):
                OSMO_ASSERT(g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_MS ||
                            g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_SGSN);
-               rc = gprs_llc_prim_handle_unsupported(llc_prim);
+               rc = llc_prim_handle_llgm_resume_req(llc_prim);
                break;
        case OSMO_PRIM(OSMO_GPRS_LLC_LLGMM_IOV, PRIM_OP_REQUEST):
                OSMO_ASSERT(g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_SGSN);

--
To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/32959
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I890c7a4ace6fb8ca362ec41bd18e9c229191a587
Gerrit-Change-Number: 32959
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to