lynxis lazus has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-sgsn/+/37866?usp=email )

 (

17 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted 
one.
 )Change subject: Implement correct Routing Area based paging
......................................................................

Implement correct Routing Area based paging

Previous the SGSN would not support multiple BSS within the
same routing area.
Add support paging of a whole routing area.

Change-Id: I181da9f656e394ccfcb8999021a5b7e13ca0419f
---
M include/osmocom/sgsn/gprs_bssgp.h
M include/osmocom/sgsn/gprs_routing_area.h
M src/sgsn/gprs_bssgp.c
M src/sgsn/gprs_routing_area.c
M src/sgsn/sgsn_libgtp.c
M src/sgsn/sgsn_vty.c
M tests/gprs_routing_area/gprs_routing_area_test.c
M tests/gprs_routing_area/gprs_routing_area_test.ok
8 files changed, 139 insertions(+), 18 deletions(-)

Approvals:
  daniel: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve




diff --git a/include/osmocom/sgsn/gprs_bssgp.h 
b/include/osmocom/sgsn/gprs_bssgp.h
index abfe9f1..e2faf38 100644
--- a/include/osmocom/sgsn/gprs_bssgp.h
+++ b/include/osmocom/sgsn/gprs_bssgp.h
@@ -11,5 +11,5 @@
 /* called by the bssgp layer to send NS PDUs */
 int sgsn_bssgp_dispatch_ns_unitdata_req_cb(void *ctx, struct msgb *msg);

-/* page a MS in its routing area */
-int sgsn_bssgp_page_ps_ra(struct sgsn_mm_ctx *mmctx);
+/* page a MS in a single cell */
+int sgsn_bssgp_page_ps_bvci(struct sgsn_mm_ctx *mmctx, uint16_t nsei, uint16_t 
bvci);
diff --git a/include/osmocom/sgsn/gprs_routing_area.h 
b/include/osmocom/sgsn/gprs_routing_area.h
index 34e29cb..caaed47 100644
--- a/include/osmocom/sgsn/gprs_routing_area.h
+++ b/include/osmocom/sgsn/gprs_routing_area.h
@@ -9,6 +9,7 @@
 #include <osmocom/gsm/gsm23003.h>

 struct sgsn_instance;
+struct sgsn_mm_ctx;

 struct sgsn_ra_global {
        /* list of struct sgsn_ra */
@@ -86,3 +87,6 @@
 typedef int (sgsn_ra_cb_t)(struct sgsn_ra_cell *ra_cell, void *cb_data);
 int sgsn_ra_foreach_cell(struct sgsn_ra *ra, sgsn_ra_cb_t *cb, void *cb_data);
 int sgsn_ra_foreach_cell2(struct osmo_routing_area_id *rai, sgsn_ra_cb_t *cb, 
void *cb_data);
+
+/* Page the whole routing area for this mmctx */
+int sgsn_ra_geran_page_ra(struct osmo_routing_area_id *ra_id, struct 
sgsn_mm_ctx *mmctx);
diff --git a/src/sgsn/gprs_bssgp.c b/src/sgsn/gprs_bssgp.c
index fd82b15..e738f0b 100644
--- a/src/sgsn/gprs_bssgp.c
+++ b/src/sgsn/gprs_bssgp.c
@@ -22,7 +22,6 @@
  */

 #include <osmocom/core/prim.h>
-#include <osmocom/core/rate_ctr.h>

 #include <osmocom/gprs/gprs_bssgp.h>
 #include <osmocom/gprs/gprs_ns2.h>
@@ -95,26 +94,20 @@
        return 0;
 }

-int sgsn_bssgp_page_ps_ra(struct sgsn_mm_ctx *mmctx)
+int sgsn_bssgp_page_ps_bvci(struct sgsn_mm_ctx *mmctx, uint16_t nsei, uint16_t 
bvci)
 {
        struct bssgp_paging_info pinfo;
-       int rc;
-
-       /* FIXME: page whole routing area, not only the last known cell */

        /* initiate PS PAGING procedure */
        memset(&pinfo, 0, sizeof(pinfo));
        pinfo.mode = BSSGP_PAGING_PS;
        pinfo.scope = BSSGP_PAGING_BVCI;
-       pinfo.bvci = mmctx->gb.bvci;
+       pinfo.bvci = bvci;
        pinfo.imsi = mmctx->imsi;
        pinfo.ptmsi = &mmctx->p_tmsi;
        pinfo.drx_params = mmctx->drx_parms;
        pinfo.qos[0] = 0; // FIXME
-       rc = bssgp_tx_paging(mmctx->gb.nsei, 0, &pinfo);
-       rate_ctr_inc(rate_ctr_group_get_ctr(mmctx->ctrg, GMM_CTR_PAGING_PS));
-
-       return rc;
+       return bssgp_tx_paging(nsei, 0, &pinfo);
 }

 /* called by the bssgp layer to send NS PDUs */
diff --git a/src/sgsn/gprs_routing_area.c b/src/sgsn/gprs_routing_area.c
index 977caa2..67b15ae 100644
--- a/src/sgsn/gprs_routing_area.c
+++ b/src/sgsn/gprs_routing_area.c
@@ -22,11 +22,11 @@

 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/logging.h>
-#include <osmocom/sgsn/debug.h>
-
-
+#include <osmocom/core/rate_ctr.h>
 #include <osmocom/gsm/gsm48.h>
-
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_bssgp.h>
+#include <osmocom/sgsn/mmctx.h>
 #include <osmocom/sgsn/sgsn.h>

 #include <osmocom/sgsn/gprs_routing_area.h>
@@ -330,6 +330,28 @@
        return found ? 0 : -ENOENT;
 }

+int sgsn_ra_geran_page_ra(struct osmo_routing_area_id *ra_id, struct 
sgsn_mm_ctx *mmctx)
+{
+       struct sgsn_ra *ra;
+       struct sgsn_ra_cell *cell;
+       int ret = -ENOENT;
+
+       rate_ctr_inc(rate_ctr_group_get_ctr(mmctx->ctrg, GMM_CTR_PAGING_PS));
+
+       ra = sgsn_ra_get_ra(ra_id);
+       if (!ra)
+               return -ENOENT;
+
+       llist_for_each_entry(cell, &ra->cells, list) {
+               if (cell->ran_type == RA_TYPE_GERAN_Gb) {
+                       sgsn_bssgp_page_ps_bvci(mmctx, cell->u.geran.nsei, 
cell->u.geran.bvci);
+                       ret = 0;
+               }
+       }
+
+
+       return ret;
+}

 void sgsn_ra_init(struct sgsn_instance *inst)
 {
diff --git a/src/sgsn/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c
index faf0e7f..8eb77b0 100644
--- a/src/sgsn/sgsn_libgtp.c
+++ b/src/sgsn/sgsn_libgtp.c
@@ -47,6 +47,7 @@
 #include <osmocom/sgsn/sgsn.h>
 #include <osmocom/sgsn/gprs_ns.h>
 #include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_routing_area.h>
 #include <osmocom/sgsn/mmctx.h>
 #include <osmocom/sgsn/gprs_gmm.h>
 #include <osmocom/sgsn/gprs_sm.h>
@@ -864,7 +865,7 @@
                        LOGMMCTXP(LOGL_INFO, mm, "Paging MS in GMM state %s, MM 
state %s\n",
                                  osmo_fsm_inst_state_name(mm->gmm_fsm),
                                  
osmo_fsm_inst_state_name(mm->gb.mm_state_fsm));
-                       sgsn_bssgp_page_ps_ra(mm);
+                       sgsn_ra_geran_page_ra(&mm->ra, mm);

                        /* FIXME: queue the packet we received from GTP */
                        break;
diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c
index bcb8dc2..a7e8045 100644
--- a/src/sgsn/sgsn_vty.c
+++ b/src/sgsn/sgsn_vty.c
@@ -41,6 +41,7 @@
 #include <osmocom/sgsn/gprs_gmm.h>
 #include <osmocom/sgsn/gprs_bssgp.h>
 #include <osmocom/sgsn/mmctx.h>
+#include <osmocom/sgsn/gprs_routing_area.h>
 #include <osmocom/sgsn/gtp_ggsn.h>
 #include <osmocom/sgsn/gtp_mme.h>
 #include <osmocom/sgsn/vty.h>
@@ -1333,7 +1334,7 @@
                return CMD_WARNING;
        }

-       sgsn_bssgp_page_ps_ra(mm);
+       sgsn_ra_geran_page_ra(&mm->ra, mm);
        return CMD_SUCCESS;
 }

diff --git a/tests/gprs_routing_area/gprs_routing_area_test.c 
b/tests/gprs_routing_area/gprs_routing_area_test.c
index d879f39..e1aec0f 100644
--- a/tests/gprs_routing_area/gprs_routing_area_test.c
+++ b/tests/gprs_routing_area/gprs_routing_area_test.c
@@ -44,6 +44,17 @@
 void *tall_sgsn_ctx;
 struct sgsn_instance *sgsn;

+struct paging_exp {
+       uint16_t nsei;
+       uint16_t bvci;
+       /* paged when we send one paging request */
+       bool paged;
+       /* valid when this entry contains valid data */
+       bool valid;
+};
+
+struct paging_exp g_paging[4];
+
 static void cleanup_test(void)
 {
        TALLOC_FREE(sgsn);
@@ -326,6 +337,93 @@
        cleanup_test();
 }

+/* BSSGP Paging RA */
+int bssgp_tx_paging(uint16_t nsei, uint16_t _bvci,
+                   struct bssgp_paging_info *pinfo)
+{
+       bool found = false;
+
+       OSMO_ASSERT(pinfo);
+       fprintf(stderr, "Tx paging for nsei %05u / bvci %05u\n", nsei, 
pinfo->bvci);
+       /* match against list of expect pagings */
+       for (int i = 0; i < ARRAY_SIZE(g_paging); i++) {
+               struct paging_exp *exp = &g_paging[i];
+               if (exp->paged || !exp->valid)
+                       continue;
+
+               if (exp->nsei == nsei && exp->bvci == pinfo->bvci) {
+                       exp->paged = true;
+                       found = true;
+                       break;
+               }
+       }
+
+       OSMO_ASSERT(found);
+       return 0;
+}
+
+static void check_paging(void)
+{
+       for (int i = 0; i < ARRAY_SIZE(g_paging); i++) {
+               struct paging_exp *exp = &g_paging[i];
+               if (!exp->valid)
+                       continue;
+               OSMO_ASSERT(exp->paged)
+       }
+}
+
+void test_routing_area_paging(void)
+{
+       struct sgsn_mm_ctx *mmctx;
+       struct osmo_routing_area_id ra_id = {
+               .lac = {
+                       .plmn = { .mcc = 262, .mnc = 42, .mnc_3_digits = false 
},
+                       .lac = 24
+               },
+               .rac = 43
+       };
+
+       uint16_t cell_id = 9999;
+       struct osmo_cell_global_id_ps cgi_ps = {
+               .rai = ra_id,
+               .cell_identity = cell_id,
+       };
+
+       uint16_t nsei = 2, bvci = 3;
+       int rc;
+
+       printf("Testing Routing Area paging\n");
+
+       sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
+
+       memset(g_paging, 0, sizeof(g_paging));
+       g_paging[0].bvci = bvci;
+       g_paging[0].nsei = nsei;
+       g_paging[0].valid = true;
+       g_paging[0].paged = false;
+
+       rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps);
+       OSMO_ASSERT(rc == 0);
+
+       cgi_ps.cell_identity++;
+       rc = sgsn_ra_bvc_reset_ind(nsei, bvci+1, &cgi_ps);
+       OSMO_ASSERT(rc == 0);
+
+       g_paging[1].bvci = bvci+1;
+       g_paging[1].nsei = nsei;
+       g_paging[1].valid = true;
+       g_paging[1].paged = false;
+
+       mmctx = sgsn_mm_ctx_alloc_gb(0xc0001234, &ra_id);
+
+       sgsn_ra_geran_page_ra(&ra_id, mmctx);
+       check_paging();
+
+       sgsn_mm_ctx_cleanup_free(mmctx);
+
+       cleanup_test();
+}
+
 static struct log_info_cat gprs_categories[] = {
        [DMM] = {
                .name = "DMM",
@@ -387,6 +485,7 @@
        test_routing_area_free_empty();
        test_routing_area_reset_ind();
        test_routing_area_nsei_free();
+       test_routing_area_paging();
        printf("Done\n");

        talloc_report_full(osmo_sgsn_ctx, stderr);
diff --git a/tests/gprs_routing_area/gprs_routing_area_test.ok 
b/tests/gprs_routing_area/gprs_routing_area_test.ok
index dccbb5e..78cee7e 100644
--- a/tests/gprs_routing_area/gprs_routing_area_test.ok
+++ b/tests/gprs_routing_area/gprs_routing_area_test.ok
@@ -3,4 +3,5 @@
 Testing Routing Area create/free
 Testing Routing Area BSSGP BVC RESET IND
 Testing Routing Area nsei failure
+Testing Routing Area paging
 Done

--
To view, visit https://gerrit.osmocom.org/c/osmo-sgsn/+/37866?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: I181da9f656e394ccfcb8999021a5b7e13ca0419f
Gerrit-Change-Number: 37866
Gerrit-PatchSet: 18
Gerrit-Owner: lynxis lazus <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: lynxis lazus <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-CC: fixeria <[email protected]>

Reply via email to