Projects
osmocom:master
osmo-sgsn
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 68
View file
commit_6213201b951d12dd4de7cf9399622b93555b0db2.txt
Deleted
View file
commit_72283a1686281d0304d63642b3917ea396b58100.txt
Added
View file
osmo-sgsn_1.12.0.16.62132.dsc -> osmo-sgsn_1.12.0.19.7228.dsc
Changed
@@ -2,7 +2,7 @@ Source: osmo-sgsn Binary: osmo-sgsn, osmo-sgsn-dbg, osmo-gtphub, osmo-gtphub-dbg, osmo-sgsn-doc Architecture: any all -Version: 1.12.0.16.62132 +Version: 1.12.0.19.7228 Maintainer: Osmocom team <openbsc@lists.osmocom.org> Homepage: https://projects.osmocom.org/projects/osmo-sgsn Standards-Version: 3.9.8 @@ -16,8 +16,8 @@ osmo-sgsn-dbg deb debug extra arch=any osmo-sgsn-doc deb doc optional arch=all Checksums-Sha1: - 372c35916e2932590e58f4334cf093e216ddef3b 232488 osmo-sgsn_1.12.0.16.62132.tar.xz + 93d0ca06e9469bd3924a290e6115397002f7d7e4 236020 osmo-sgsn_1.12.0.19.7228.tar.xz Checksums-Sha256: - ad4ed26cbd6e59e972ca77a29a3353c85aff2aaf5a9d674dcb77339fdced141b 232488 osmo-sgsn_1.12.0.16.62132.tar.xz + b78db692c815deac9102a4e8601b29a18b0f929d1743f9037d3f7b7f3a169afc 236020 osmo-sgsn_1.12.0.19.7228.tar.xz Files: - a4305ceb21c673357a102445a2261ced 232488 osmo-sgsn_1.12.0.16.62132.tar.xz + 48ff896431ef427170eeab4c3ed3a072 236020 osmo-sgsn_1.12.0.19.7228.tar.xz
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/.tarball-version -> osmo-sgsn_1.12.0.19.7228.tar.xz/.tarball-version
Changed
@@ -1 +1 @@ -1.12.0.16-62132 +1.12.0.19-7228
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/configure.ac -> osmo-sgsn_1.12.0.19.7228.tar.xz/configure.ac
Changed
@@ -243,6 +243,7 @@ tests/Makefile tests/atlocal tests/gprs/Makefile + tests/gprs_routing_area/Makefile tests/sgsn/Makefile tests/gtphub/Makefile tests/xid/Makefile
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/debian/changelog -> osmo-sgsn_1.12.0.19.7228.tar.xz/debian/changelog
Changed
@@ -1,8 +1,8 @@ -osmo-sgsn (1.12.0.16.62132) unstable; urgency=medium +osmo-sgsn (1.12.0.19.7228) unstable; urgency=medium * Automatically generated changelog entry for building the Osmocom master feed - -- Osmocom OBS scripts <info@osmocom.org> Wed, 16 Oct 2024 18:15:16 +0000 + -- Osmocom OBS scripts <info@osmocom.org> Tue, 29 Oct 2024 19:00:25 +0000 osmo-sgsn (1.12.0) unstable; urgency=medium
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/include/osmocom/sgsn/Makefile.am -> osmo-sgsn_1.12.0.19.7228.tar.xz/include/osmocom/sgsn/Makefile.am
Changed
@@ -14,6 +14,7 @@ gprs_llc.h \ gprs_llc_xid.h \ gprs_ranap.h \ + gprs_routing_area.h \ gprs_sm.h \ gprs_sndcp_comp.h \ gprs_sndcp_dcomp.h \
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/include/osmocom/sgsn/debug.h -> osmo-sgsn_1.12.0.19.7228.tar.xz/include/osmocom/sgsn/debug.h
Changed
@@ -27,6 +27,7 @@ DGTP, DOBJ, DRIM, + DRA, /* Routing Area handling */ Debug_LastEntry, };
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/include/osmocom/sgsn/gprs_bssgp.h -> osmo-sgsn_1.12.0.19.7228.tar.xz/include/osmocom/sgsn/gprs_bssgp.h
Changed
@@ -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);
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/include/osmocom/sgsn/gprs_gmm.h -> osmo-sgsn_1.12.0.19.7228.tar.xz/include/osmocom/sgsn/gprs_gmm.h
Changed
@@ -45,7 +45,7 @@ uint8_t gmm_cause); int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm); -int gprs_gmm_attach_req_ies(struct msgb *a, struct msgb *b); +int gprs_gmm_msg_cmp(struct msgb *a, struct msgb *b); int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); /* TODO: move extract_subscr_* when gsm48_gmm_authorize() got removed */
View file
osmo-sgsn_1.12.0.19.7228.tar.xz/include/osmocom/sgsn/gprs_routing_area.h
Added
@@ -0,0 +1,92 @@ +/*! \file gprs_routing_area.h */ + +#pragma once + +#include <stdbool.h> +#include <stdint.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/gsm/gsm23003.h> + +struct sgsn_instance; +struct sgsn_mm_ctx; + +struct sgsn_ra_global { + /* list of struct sgsn_ra */ + struct llist_head ra_list; +}; + +struct sgsn_ra { + /* Entry in sgsn_ra_global->ra_list */ + struct llist_head list; + + struct osmo_routing_area_id rai; + /* cells contains a list of sgsn_ra_cells which are alive */ + struct llist_head cells; +}; + +enum sgsn_ra_ran_type { + RA_TYPE_GERAN_Gb, + RA_TYPE_UTRAN_Iu, +}; + +struct sgsn_ra_cell { + /* Entry in sgsn_ra->cells */ + struct llist_head list; + + /*! link back to the parent */ + struct sgsn_ra *ra; + + enum sgsn_ra_ran_type ran_type; + + uint16_t cell_id; + union { + struct { + uint16_t nsei; + uint16_t bvci; + } geran; + struct { + /* TODO: unused */ + uint16_t rncid; + uint16_t sac; + } utran; + } u; +}; + +void sgsn_ra_init(struct sgsn_instance *inst); + +struct sgsn_ra *sgsn_ra_alloc(const struct osmo_routing_area_id *rai); +void sgsn_ra_free(struct sgsn_ra *ra); +struct sgsn_ra_cell *sgsn_ra_cell_alloc_geran(struct sgsn_ra *ra, uint16_t cell_id, uint16_t nsei, uint16_t bvci); +void sgsn_ra_cell_free(struct sgsn_ra_cell *cell); + +/* Called by BSSGP layer to inform about a reset on a BVCI */ +int sgsn_ra_bvc_reset_ind(uint16_t nsei, uint16_t bvci, struct osmo_cell_global_id_ps *cgi_ps); +/* FIXME: handle BVC BLOCK/UNBLOCK/UNAVAILABLE */ +/* Called by NS-VC layer to inform about an unavailable NSEI (and all BVCI on them) */ +int sgsn_ra_nsei_failure_ind(uint16_t nsei); + +struct sgsn_ra_cell *sgsn_ra_get_cell_by_cgi_ps(const struct osmo_cell_global_id_ps *cgi_ps); +struct sgsn_ra_cell *sgsn_ra_get_cell_by_lai(const struct osmo_location_area_id *lai, uint16_t cell_id); +struct sgsn_ra_cell *sgsn_ra_get_cell_by_cgi(const struct osmo_cell_global_id *cgi); +struct sgsn_ra_cell *sgsn_ra_get_cell_by_ra(const struct sgsn_ra *ra, uint16_t cell_id); +struct sgsn_ra_cell *sgsn_ra_get_cell_by_gb(uint16_t nsei, uint16_t bvci); +struct sgsn_ra *sgsn_ra_get_ra(const struct osmo_routing_area_id *ra_id); + + +/* + * return value for callbacks. + * STOP: stop calling the callback for the remaining cells, sgsn_ra_foreach_ra() returns 0 + * CONT: continue to call the callback for remaining cells + * ABORT: stop calling the callback for the remaining cells, sgsn_ra_foreach_ra() returns -1 + */ +#define SGSN_RA_CB_STOP 1 +#define SGSN_RA_CB_CONT 0 +#define SGSN_RA_CB_ERROR -1 + +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);
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/include/osmocom/sgsn/sgsn.h -> osmo-sgsn_1.12.0.19.7228.tar.xz/include/osmocom/sgsn/sgsn.h
Changed
@@ -152,6 +152,9 @@ ares_channel ares_channel; struct ares_addr_node *ares_servers; + /* Routing areas */ + struct sgsn_ra_global *routing_area; + struct rate_ctr_group *rate_ctrs; struct llist_head apn_list; /* list of struct sgsn_apn_ctx */
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/Makefile.am -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/Makefile.am
Changed
@@ -47,6 +47,7 @@ gprs_gmm_fsm.c \ gprs_mm_state_gb_fsm.c \ gprs_ns.c \ + gprs_routing_area.c \ gprs_sm.c \ gprs_sndcp.c \ gprs_sndcp_comp.c \
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/gprs_bssgp.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/gprs_bssgp.c
Changed
@@ -20,8 +20,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ + #include <osmocom/core/prim.h> -#include <osmocom/core/rate_ctr.h> #include <osmocom/gprs/gprs_bssgp.h> #include <osmocom/gprs/gprs_ns2.h> @@ -30,9 +30,26 @@ #include <osmocom/sgsn/gprs_llc.h> #include <osmocom/sgsn/gprs_gmm.h> +#include <osmocom/sgsn/gprs_routing_area.h> #include <osmocom/sgsn/sgsn_rim.h> #include <osmocom/sgsn/mmctx.h> +#include <osmocom/sgsn/debug.h> + +static int bssgp_nm_bvc_reset_ind(struct osmo_bssgp_prim *bp) +{ + struct osmo_cell_global_id_ps cgi_ps = {}; + + if (!bp->tp) + return -EINVAL; + + if (!TLVP_PRES_LEN(bp->tp, BSSGP_IE_CELL_ID, 8)) + return -EINVAL; + + bssgp_parse_cell_id2(&cgi_ps.rai, &cgi_ps.cell_identity, TLVP_VAL(bp->tp, BSSGP_IE_CELL_ID), 8); + return sgsn_ra_bvc_reset_ind(bp->nsei, bp->bvci, &cgi_ps); +} + /* call-back function for the BSSGP protocol */ int sgsn_bssgp_rx_prim(struct osmo_prim_hdr *oph) { @@ -58,6 +75,18 @@ } break; case SAP_BSSGP_NM: + switch (oph->primitive) { + case PRIM_NM_BVC_RESET: + if (oph->operation == PRIM_OP_INDICATION) + bssgp_nm_bvc_reset_ind(bp); + break; + case PRIM_NM_BVC_BLOCK: + case PRIM_NM_BVC_UNBLOCK: + case PRIM_NM_STATUS: + case PRIM_NM_LLC_DISCARDED: + break; + } + break; case SAP_BSSGP_RIM: return sgsn_rim_rx_from_gb(bp, oph->msg); @@ -65,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.qos0 = 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 */
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/gprs_gmm.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/gprs_gmm.c
Changed
@@ -1429,25 +1429,18 @@ return 0; } -/* Checks if two attach request contain the IEs and IE values +/* Checks if two GMM are the same (required diffing Attach Requests/RAU Requests * return 0 if equal - * return -1 if error - * return 1 if unequal - * - * Only do a simple memcmp for now. */ -int gprs_gmm_attach_req_ies(struct msgb *a, struct msgb *b) +int gprs_gmm_msg_cmp(struct msgb *a, struct msgb *b) { struct gsm48_hdr *gh_a = (struct gsm48_hdr *) msgb_gmmh(a); struct gsm48_hdr *gh_b = (struct gsm48_hdr *) msgb_gmmh(b); -#define GMM_ATTACH_REQ_LEN 26 + if (msgb_l3len(a) != msgb_l3len(b)) + return 2; - /* there is the LLC FCS behind */ - if (msgb_l3len(a) < GMM_ATTACH_REQ_LEN || msgb_l3len(b) < GMM_ATTACH_REQ_LEN) - return -1; - - return !!memcmp(gh_a, gh_b, GMM_ATTACH_REQ_LEN); + return memcmp(gh_a, gh_b, msgb_l3len(a)); } /* 3GPP TS 24.008 ยง 4.7.4.1 / 9.4.5.2 MO Detach request */
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/gprs_gmm_attach.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/gprs_gmm_attach.c
Changed
@@ -385,7 +385,7 @@ /* 04.08 4.7.3.1.6 d) Abnormal Case * Only do action if Req IEs differs. */ if (ctx->gmm_att_req.attach_req && - gprs_gmm_attach_req_ies(new_attach_req, ctx->gmm_att_req.attach_req)) { + gprs_gmm_msg_cmp(new_attach_req, ctx->gmm_att_req.attach_req)) { osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0); st_init(fi, event, data); }
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/gprs_ns.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/gprs_ns.c
Changed
@@ -28,6 +28,7 @@ #include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gprs/gprs_bssgp_bss.h> #include <osmocom/sgsn/gprs_llc.h> +#include <osmocom/sgsn/gprs_routing_area.h> #include "config.h" @@ -52,6 +53,7 @@ break; case GPRS_NS2_AFF_CAUSE_FAILURE: LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became unavailable\n", nsp->nsei); + sgsn_ra_nsei_failure_ind(nsp->nsei); break; default: LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
View file
osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/gprs_routing_area.c
Added
@@ -0,0 +1,362 @@ +/* SGSN Routing Area for 2G */ + +/* (C) 2024 sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * Author: Alexander Couzens <lynxis@fe80.eu> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/logging.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> + +static void _sgsn_ra_cell_free(struct sgsn_ra_cell *cell, bool drop_empty_ra) +{ + struct sgsn_ra *ra; + + if (!cell) + return; + + llist_del(&cell->list); + /* to prevent double free of the Cell when freeing a Routing Area */ + if (!drop_empty_ra) { + talloc_free(cell); + return; + } + + ra = cell->ra; + talloc_free(cell); + + if (llist_empty(&ra->cells)) + sgsn_ra_free(ra); +} + +void sgsn_ra_cell_free(struct sgsn_ra_cell *cell) +{ + _sgsn_ra_cell_free(cell, true); +} + +void sgsn_ra_free(struct sgsn_ra *ra) +{ + struct sgsn_ra_cell *cell, *cell2; + + if (!ra) + return; + + llist_for_each_entry_safe(cell, cell2, &ra->cells, list) { + _sgsn_ra_cell_free(cell, false); + } + + llist_del(&ra->list); + talloc_free(ra); +} + +struct sgsn_ra *sgsn_ra_alloc(const struct osmo_routing_area_id *rai) +{ + struct sgsn_ra *ra; + ra = talloc_zero(sgsn->routing_area, struct sgsn_ra); + if (!ra) + return NULL; + + INIT_LLIST_HEAD(&ra->cells); + ra->rai = *rai; + llist_add(&ra->list, &sgsn->routing_area->ra_list); + return ra; +} + +struct sgsn_ra_cell *sgsn_ra_cell_alloc_geran(struct sgsn_ra *ra, uint16_t cell_id, uint16_t nsei, uint16_t bvci) +{ + struct sgsn_ra_cell *cell; + + cell = talloc_zero(ra, struct sgsn_ra_cell); + if (!cell) + return NULL; + + cell->ra = ra; + cell->cell_id = cell_id; + cell->ran_type = RA_TYPE_GERAN_Gb; + cell->u.geran.bvci = bvci; + cell->u.geran.nsei = nsei; + + llist_add(&cell->list, &ra->cells); + + return cell; +} + +struct sgsn_ra *sgsn_ra_get_ra(const struct osmo_routing_area_id *ra_id) +{ + struct sgsn_ra *ra; + + llist_for_each_entry(ra, &sgsn->routing_area->ra_list, list) + if (osmo_rai_cmp(&ra->rai, ra_id) == 0) + return ra; + + return NULL; +} + +struct sgsn_ra_cell *sgsn_ra_get_cell_by_gb(uint16_t nsei, uint16_t bvci) +{ + struct sgsn_ra *ra; + struct sgsn_ra_cell *cell; + + /* BVCI = 0 is invalid, only valid for signalling within the BSSGP, not for a single cell */ + if (bvci == 0) + return NULL; + + llist_for_each_entry(ra, &sgsn->routing_area->ra_list, list) { + llist_for_each_entry(cell, &ra->cells, list) { + if (cell->ran_type != RA_TYPE_GERAN_Gb) + continue; + + if (cell->u.geran.bvci == bvci && cell->u.geran.nsei == nsei) + return cell; + } + } + + return NULL; +} + +int sgsn_ra_foreach_cell(struct sgsn_ra *ra, sgsn_ra_cb_t *cb, void *cb_data) +{ + struct sgsn_ra_cell *cell, *tmp; + int ret = -ENOENT; + + OSMO_ASSERT(cb); + + llist_for_each_entry_safe(cell, tmp, &ra->cells, list) { + ret = cb(cell, cb_data); + switch (ret) { + case SGSN_RA_CB_CONT: + continue; + case SGSN_RA_CB_STOP: + return 0; + case SGSN_RA_CB_ERROR: + return -1; + default: + OSMO_ASSERT(0); + } + } + + return ret; +} + +int sgsn_ra_foreach_cell2(struct osmo_routing_area_id *ra_id, sgsn_ra_cb_t *cb, void *cb_data) +{ + struct sgsn_ra *ra; + OSMO_ASSERT(ra_id); + OSMO_ASSERT(cb); + + ra = sgsn_ra_get_ra(ra_id); + if (!ra) + return -ENOENT; + + return sgsn_ra_foreach_cell(ra, cb, cb_data); +} + +struct sgsn_ra_cell *sgsn_ra_get_cell_by_ra(const struct sgsn_ra *ra, uint16_t cell_id) +{ + struct sgsn_ra_cell *cell; + + llist_for_each_entry(cell, &ra->cells, list) { + if (cell->cell_id == cell_id) + return cell; + } + + return NULL; +} + +struct sgsn_ra_cell *sgsn_ra_get_cell_by_lai(const struct osmo_location_area_id *lai, uint16_t cell_id) +{ + struct sgsn_ra *ra; + struct sgsn_ra_cell *cell; + + /* This is a little bit in-efficient. A more performance way, but more complex would + * adding a llist for LAC on top of the routing areas */ + llist_for_each_entry(ra, &sgsn->routing_area->ra_list, list) { + if (osmo_lai_cmp(&ra->rai.lac, lai) != 0) + continue; + + llist_for_each_entry(cell, &ra->cells, list) { + if (cell->cell_id == cell_id) + return cell; + } + } + + return NULL; +} + +/*! Return the cell by searching for the RA, when found, search the cell within the RA + * + * \param cgi_ps + * \return the cell or NULL if not found + */ +struct sgsn_ra_cell *sgsn_ra_get_cell_by_cgi_ps(const struct osmo_cell_global_id_ps *cgi_ps) +{ + struct sgsn_ra *ra; + + OSMO_ASSERT(cgi_ps); + + ra = sgsn_ra_get_ra(&cgi_ps->rai); + if (!ra) + return NULL; + + return sgsn_ra_get_cell_by_ra(ra, cgi_ps->cell_identity); +} + +struct sgsn_ra_cell *sgsn_ra_get_cell_by_cgi(const struct osmo_cell_global_id *cgi) +{ + OSMO_ASSERT(cgi); + + return sgsn_ra_get_cell_by_lai(&cgi->lai, cgi->cell_identity); +} + +/*! Callback from the BSSGP layer on NM RESET IND + * + * \param nsei + * \param bvci + * \param cgi_ps + * \return 0 on success or -ENOMEM + */ +int sgsn_ra_bvc_reset_ind(uint16_t nsei, uint16_t bvci, struct osmo_cell_global_id_ps *cgi_ps) +{ + struct sgsn_ra *ra; + struct sgsn_ra_cell *cell; + bool ra_created = false; + OSMO_ASSERT(cgi_ps); + + /* TODO: do we have to move all MS to GMM IDLE state when this happens for a alive cell which got reseted? */ + ra = sgsn_ra_get_ra(&cgi_ps->rai); + if (!ra) { + ra = sgsn_ra_alloc(&cgi_ps->rai); + if (!ra) + return -ENOMEM; + ra_created = true; + } + + if (!ra_created) { + cell = sgsn_ra_get_cell_by_ra(ra, cgi_ps->cell_identity); + if (cell && cell->ran_type == RA_TYPE_GERAN_Gb) { + /* Cell already exist, update NSEI/BVCI */ + if (cell->u.geran.bvci != bvci || cell->u.geran.nsei != nsei) { + LOGP(DRA, LOGL_INFO, "GERAN Cell changed DLCI. Old: nsei/bvci %05u/%05u New: nsei/bvci %05u/%05u\n", + cell->u.geran.nsei, cell->u.geran.bvci, nsei, bvci); + cell->u.geran.bvci = bvci; + cell->u.geran.nsei = nsei; + } + return 0; + } + + if (cell && cell->ran_type != RA_TYPE_GERAN_Gb) { + /* How can we have here a RA change? Must be a configuration error. */ + LOGP(DRA, LOGL_INFO, "CGI %s: RAN change detected to GERAN!", osmo_cgi_ps_name(cgi_ps)); + _sgsn_ra_cell_free(cell, false); + cell = NULL; + } + + if (!cell) { + char old_ra32; + char new_ra32; + /* check for the same cell id within the location area. The cell id is also unique for the cell within the LAC + * This should only happen when a Cell is changing routing areas */ + cell = sgsn_ra_get_cell_by_lai(&cgi_ps->rai.lac, cgi_ps->cell_identity); + if (cell) { + LOGP(DRA, LOGL_INFO, "CGI %s: changed Routing Area. Old: %s, New: %s\n", + osmo_cgi_ps_name(cgi_ps), + osmo_rai_name2_buf(old_ra, sizeof(old_ra), &cell->ra->rai), + osmo_rai_name2_buf(new_ra, sizeof(new_ra), &cgi_ps->rai)); + + OSMO_ASSERT(cell->ra != ra); + + /* the old RA is definitive not our ra! Drop the old ra */ + _sgsn_ra_cell_free(cell, true); + cell = NULL; + } + } + } + + cell = sgsn_ra_cell_alloc_geran(ra, cgi_ps->cell_identity, nsei, bvci); + if (!cell) + return -ENOMEM; + + LOGP(DRA, LOGL_INFO, "New cell registered %s via nsei/bvci %05u/%05u\n", osmo_cgi_ps_name(cgi_ps), nsei, bvci); + + return 0; +} + +/* FIXME: call it on BSSGP BLOCK + unavailable with BVCI */ +int sgsn_ra_nsei_failure_ind(uint16_t nsei) +{ + struct sgsn_ra *ra, *ra2; + struct sgsn_ra_cell *cell, *cell2; + bool found = false; + + llist_for_each_entry_safe(ra, ra2, &sgsn->routing_area->ra_list, list) { + llist_for_each_entry_safe(cell, cell2, &ra->cells, list) { + if (cell->ran_type != RA_TYPE_GERAN_Gb) + continue; + + if (cell->u.geran.nsei == nsei) { + found = true; + _sgsn_ra_cell_free(cell, false); + } + } + + if (llist_empty(&ra->cells)) + sgsn_ra_free(ra); + + } + + 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) +{ + inst->routing_area = talloc_zero(inst, struct sgsn_ra_global); + OSMO_ASSERT(inst->routing_area); + + INIT_LLIST_HEAD(&inst->routing_area->ra_list); +}
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/sgsn.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/sgsn.c
Changed
@@ -55,6 +55,7 @@ #include <osmocom/sgsn/gtp_ggsn.h> #include <osmocom/sgsn/gtp.h> #include <osmocom/sgsn/pdpctx.h> +#include <osmocom/sgsn/gprs_routing_area.h> #include <pdp.h> @@ -189,6 +190,7 @@ /* These are mostly setting up stuff not related to VTY cfg, so they can be set up here: */ sgsn_auth_init(inst); sgsn_cdr_init(inst); + sgsn_ra_init(inst); return inst; }
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/sgsn_libgtp.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/sgsn_libgtp.c
Changed
@@ -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;
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/sgsn_main.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/sgsn_main.c
Changed
@@ -64,6 +64,7 @@ #include <osmocom/sgsn/gprs_ranap.h> #include <osmocom/sgsn/gprs_ns.h> #include <osmocom/sgsn/gprs_bssgp.h> +#include <osmocom/sgsn/gprs_routing_area.h> #include <osmocom/sgsn/gprs_subscriber.h> #include <osmocom/sgsn/gtp.h> @@ -348,6 +349,11 @@ .description = "RAN Information Management (RIM)", .enabled = 1, .loglevel = LOGL_NOTICE, }, + DRA = { + .name = "DRA", + .description = "Routing Area", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; static const struct log_info gprs_log_info = {
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/src/sgsn/sgsn_vty.c -> osmo-sgsn_1.12.0.19.7228.tar.xz/src/sgsn/sgsn_vty.c
Changed
@@ -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; }
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/tests/Makefile.am -> osmo-sgsn_1.12.0.19.7228.tar.xz/tests/Makefile.am
Changed
@@ -1,6 +1,7 @@ SUBDIRS = \ gprs \ gtphub \ + gprs_routing_area \ sgsn \ xid \ sndcp_xid \
View file
osmo-sgsn_1.12.0.19.7228.tar.xz/tests/gprs_routing_area
Added
+(directory)
View file
osmo-sgsn_1.12.0.19.7228.tar.xz/tests/gprs_routing_area/Makefile.am
Added
@@ -0,0 +1,93 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGSUPCLIENT_CFLAGS) \ + $(LIBCARES_CFLAGS) \ + $(LIBGTP_CFLAGS) \ + $(NULL) +if BUILD_IU +AM_CFLAGS += \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(NULL) +endif + +AM_LDFLAGS = -no-install + +EXTRA_DIST = \ + gprs_routing_area_test.ok \ + $(NULL) + +check_PROGRAMS = \ + gprs_routing_area_test \ + $(NULL) + +gprs_routing_area_test_SOURCES = \ + gprs_routing_area_test.c \ + $(NULL) + +gprs_routing_area_test_LDADD = \ + $(top_builddir)/src/sgsn/apn.o \ + $(top_builddir)/src/sgsn/gprs_bssgp.o \ + $(top_builddir)/src/sgsn/gprs_llc.o \ + $(top_builddir)/src/sgsn/gprs_ns.o \ + $(top_builddir)/src/sgsn/gprs_sndcp.o \ + $(top_builddir)/src/sgsn/gprs_gmm_attach.o \ + $(top_builddir)/src/sgsn/gprs_gmm.o \ + $(top_builddir)/src/sgsn/gprs_gmm_fsm.o \ + $(top_builddir)/src/sgsn/gprs_mm_state_gb_fsm.o \ + $(top_builddir)/src/sgsn/gprs_routing_area.o \ + $(top_builddir)/src/sgsn/gtp_ggsn.o \ + $(top_builddir)/src/sgsn/gtp_mme.o \ + $(top_builddir)/src/sgsn/mmctx.o \ + $(top_builddir)/src/sgsn/pdpctx.o \ + $(top_builddir)/src/sgsn/sgsn.o \ + $(top_builddir)/src/sgsn/sgsn_cdr.o \ + $(top_builddir)/src/sgsn/sgsn_ctrl.o \ + $(top_builddir)/src/sgsn/sgsn_vty.o \ + $(top_builddir)/src/sgsn/sgsn_libgtp.o \ + $(top_builddir)/src/sgsn/sgsn_auth.o \ + $(top_builddir)/src/sgsn/gprs_subscriber.o \ + $(top_builddir)/src/sgsn/gprs_llc_xid.o \ + $(top_builddir)/src/sgsn/gprs_sndcp_xid.o \ + $(top_builddir)/src/sgsn/slhc.o \ + $(top_builddir)/src/sgsn/gprs_sm.o \ + $(top_builddir)/src/sgsn/gprs_sndcp_comp.o \ + $(top_builddir)/src/sgsn/gprs_sndcp_pcomp.o \ + $(top_builddir)/src/sgsn/v42bis.o \ + $(top_builddir)/src/sgsn/gprs_sndcp_dcomp.o \ + $(top_builddir)/src/sgsn/sgsn_rim.o \ + $(top_builddir)/src/gprs/gprs_utils.o \ + $(top_builddir)/src/gprs/gprs_llc_parse.o \ + $(top_builddir)/src/gprs/crc24.o \ + $(top_builddir)/src/gprs/sgsn_ares.o \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOGB_LIBS) \ + $(LIBOSMOGSUPCLIENT_LIBS) \ + $(LIBCARES_LIBS) \ + $(LIBGTP_LIBS) \ + -lrt \ + -lm \ + $(NULL) + +if BUILD_IU +gprs_routing_area_test_LDADD += \ + $(top_builddir)/src/sgsn/gprs_ranap.o \ + $(top_builddir)/src/sgsn/gprs_mm_state_iu_fsm.o \ + $(LIBOSMORANAP_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBASN1C_LIBS) \ + $(NULL) +endif
View file
osmo-sgsn_1.12.0.19.7228.tar.xz/tests/gprs_routing_area/gprs_routing_area_test.c
Added
@@ -0,0 +1,503 @@ +/* Test the SGSN routing ares */ +/* + * (C) 2024 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * Author: Alexander Couzens <lynxis@fe80.eu> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/core/application.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/rate_ctr.h> +#include <osmocom/core/utils.h> +#include <osmocom/gsm/apn.h> +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/gsup.h> +#include <osmocom/gprs/gprs_bssgp.h> +#include <osmocom/vty/vty.h> + +#include <osmocom/gsupclient/gsup_client.h> + +#include <osmocom/sgsn/gprs_llc.h> +#include <osmocom/sgsn/mmctx.h> +#include <osmocom/sgsn/sgsn.h> +#include <osmocom/sgsn/gprs_gmm.h> +#include <osmocom/sgsn/debug.h> +#include <osmocom/sgsn/gprs_routing_area.h> + +#include <stdio.h> + + +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_paging4; + +static void cleanup_test(void) +{ + TALLOC_FREE(sgsn); +} + +/* Create RA, free RA */ +static void test_routing_area_create(void) +{ + struct sgsn_ra *ra; + struct osmo_routing_area_id raid = { + .lac = { + .plmn = { .mcc = 262, .mnc = 42, .mnc_3_digits = false }, + .lac = 23 + }, + .rac = 42 + }; + + printf("Testing Routing Area create/free\n"); + + sgsn = sgsn_instance_alloc(tall_sgsn_ctx); + ra = sgsn_ra_alloc(&raid); + OSMO_ASSERT(ra); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + sgsn_ra_free(ra); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + /* Cleanup */ + cleanup_test(); +} + +static void test_routing_area_free_empty(void) +{ + + struct sgsn_ra *ra; + struct sgsn_ra_cell *cell_a; + struct osmo_routing_area_id raid = { + .lac = { + .plmn = { .mcc = 262, .mnc = 42, .mnc_3_digits = false }, + .lac = 24 + }, + .rac = 43 + }; + + uint16_t cell_id = 9999; + uint16_t nsei = 2, bvci = 3; + + printf("Testing Routing Area create/free\n"); + + sgsn = sgsn_instance_alloc(tall_sgsn_ctx); + ra = sgsn_ra_alloc(&raid); + OSMO_ASSERT(ra); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + cell_a = sgsn_ra_cell_alloc_geran(ra, cell_id, nsei, bvci); + OSMO_ASSERT(cell_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + OSMO_ASSERT(llist_count(&ra->cells) == 1); + + sgsn_ra_free(ra); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + ra = sgsn_ra_alloc(&raid); + OSMO_ASSERT(ra); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + cell_a = sgsn_ra_cell_alloc_geran(ra, cell_id, nsei, bvci); + OSMO_ASSERT(cell_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + OSMO_ASSERT(llist_count(&ra->cells) == 1); + + sgsn_ra_free(ra); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + cleanup_test(); +} + +/* Create RA, use different find functiosn, free RA */ +static void test_routing_area_find(void) +{ + struct sgsn_ra *ra_a, *ra_b; + struct sgsn_ra_cell *cell_a, *cell_b; + 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, cell_id_not_found = 44; + struct osmo_cell_global_id_ps cgi_ps = { + .rai = ra_id, + .cell_identity = cell_id, + }; + struct osmo_cell_global_id cgi = { + .lai = ra_id.lac, + .cell_identity = cell_id + }; + + uint16_t nsei = 2, bvci = 3; + + printf("Testing Routing Area find\n"); + + sgsn = sgsn_instance_alloc(tall_sgsn_ctx); + ra_a = sgsn_ra_alloc(&ra_id); + OSMO_ASSERT(ra_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + ra_b = sgsn_ra_get_ra(&ra_id); + OSMO_ASSERT(ra_a == ra_b); + + cell_a = sgsn_ra_cell_alloc_geran(ra_a, cell_id, nsei, bvci); + OSMO_ASSERT(cell_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + cell_b = sgsn_ra_get_cell_by_cgi_ps(&cgi_ps); + OSMO_ASSERT(cell_b); + OSMO_ASSERT(cell_b == cell_a); + + cell_b = sgsn_ra_get_cell_by_ra(ra_a, cgi.cell_identity); + OSMO_ASSERT(cell_b); + OSMO_ASSERT(cell_b == cell_a); + + cell_b = sgsn_ra_get_cell_by_cgi(&cgi); + OSMO_ASSERT(cell_b); + OSMO_ASSERT(cell_b == cell_a); + + cell_b = sgsn_ra_get_cell_by_lai(&cgi.lai, cgi.cell_identity); + OSMO_ASSERT(cell_b); + OSMO_ASSERT(cell_b == cell_a); + + sgsn_ra_free(ra_a); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + /* try to search for a cell id which isn't present */ + cgi.cell_identity = cell_id_not_found; + cgi_ps.cell_identity = cell_id_not_found; + + ra_a = sgsn_ra_alloc(&ra_id); + OSMO_ASSERT(ra_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + cell_a = sgsn_ra_cell_alloc_geran(ra_a, cell_id, nsei, bvci); + OSMO_ASSERT(cell_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + cell_b = sgsn_ra_get_cell_by_cgi_ps(&cgi_ps); + OSMO_ASSERT(!cell_b); + + cell_b = sgsn_ra_get_cell_by_ra(ra_a, cgi_ps.cell_identity); + OSMO_ASSERT(!cell_b); + + cell_b = sgsn_ra_get_cell_by_cgi(&cgi); + OSMO_ASSERT(!cell_b); + + cell_b = sgsn_ra_get_cell_by_lai(&cgi.lai, cgi.cell_identity); + OSMO_ASSERT(!cell_b); + + /* try to find for a different RAC */ + cgi_ps.rai.rac = 45; + ra_id.rac = 46; + + cell_b = sgsn_ra_get_cell_by_cgi_ps(&cgi_ps); + OSMO_ASSERT(!cell_b); + + ra_b = sgsn_ra_get_ra(&ra_id); + OSMO_ASSERT(!ra_b); + + /* try to find for different LAC */ + cgi.lai.lac = 46; + cell_b = sgsn_ra_get_cell_by_cgi(&cgi); + OSMO_ASSERT(!cell_b); + + sgsn_ra_free(ra_a); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + cleanup_test(); +} + +static void test_routing_area_reset_ind(void) +{ + struct sgsn_ra *ra_a; + struct sgsn_ra_cell *cell_a, *cell_b; + 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, + }; + struct osmo_cell_global_id cgi = { + .lai = ra_id.lac, + .cell_identity = cell_id + }; + + uint16_t nsei = 2, bvci = 3; + int rc; + + printf("Testing Routing Area BSSGP BVC RESET IND\n"); + + sgsn = sgsn_instance_alloc(tall_sgsn_ctx); + ra_a = sgsn_ra_alloc(&ra_id); + OSMO_ASSERT(ra_a); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + OSMO_ASSERT(llist_count(&ra_a->cells) == 0); + + rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(llist_count(&ra_a->cells) == 1); + + cell_a = sgsn_ra_get_cell_by_cgi(&cgi); + OSMO_ASSERT(cell_a); + + rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps); + OSMO_ASSERT(rc == 0); + + cell_b = sgsn_ra_get_cell_by_cgi(&cgi); + OSMO_ASSERT(cell_b); + OSMO_ASSERT(cell_a == cell_b); + + sgsn_ra_free(ra_a); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1); + + ra_a = sgsn_ra_get_ra(&cgi_ps.rai); + sgsn_ra_free(ra_a); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + cleanup_test(); +} + +void test_routing_area_nsei_free(void) +{ + struct sgsn_ra *ra_a; + 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 nsei failure\n"); + + sgsn = sgsn_instance_alloc(tall_sgsn_ctx); + + rc = sgsn_ra_bvc_reset_ind(nsei, bvci, &cgi_ps); + OSMO_ASSERT(rc == 0); + + ra_a = sgsn_ra_get_ra(&cgi_ps.rai); + OSMO_ASSERT(llist_count(&ra_a->cells) == 1); + + rc = sgsn_ra_nsei_failure_ind(nsei); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + rc = sgsn_ra_nsei_failure_ind(nsei); + OSMO_ASSERT(rc == -ENOENT); + OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list)); + + 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_pagingi; + 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_pagingi; + 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_paging0.bvci = bvci; + g_paging0.nsei = nsei; + g_paging0.valid = true; + g_paging0.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_paging1.bvci = bvci+1; + g_paging1.nsei = nsei; + g_paging1.valid = true; + g_paging1.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", + .description = "Layer3 Mobility Management (MM)", + .color = "\0331;33m", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, + DPAG = { + .name = "DPAG", + .description = "Paging Subsystem", + .color = "\0331;38m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + DREF = { + .name = "DREF", + .description = "Reference Counting", + .enabled = 0, .loglevel = LOGL_NOTICE, + }, + DGPRS = { + .name = "DGPRS", + .description = "GPRS Packet Service", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, + DLLC = { + .name = "DLLC", + .description = "GPRS Logical Link Control Protocol (LLC)", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, + DRA = { + .name = "DRA", + .description = "Routing Area", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static struct log_info info = { + .cat = gprs_categories, + .num_cat = ARRAY_SIZE(gprs_categories), +}; + +static struct vty_app_info vty_info = { + .name = "testSGSN", +}; + +int main(int argc, char **argv) +{ + void *osmo_sgsn_ctx; + void *msgb_ctx; + + osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn"); + osmo_init_logging2(osmo_sgsn_ctx, &info); + tall_sgsn_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "sgsn"); + msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0); + + vty_init(&vty_info); + + test_routing_area_create(); + test_routing_area_find(); + 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); + OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1); + OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 1); + return 0; +} + + +/* stubs */ +struct osmo_prim_hdr; +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + abort(); +}
View file
osmo-sgsn_1.12.0.19.7228.tar.xz/tests/gprs_routing_area/gprs_routing_area_test.ok
Added
@@ -0,0 +1,7 @@ +Testing Routing Area create/free +Testing Routing Area find +Testing Routing Area create/free +Testing Routing Area BSSGP BVC RESET IND +Testing Routing Area nsei failure +Testing Routing Area paging +Done
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/tests/sgsn/Makefile.am -> osmo-sgsn_1.12.0.19.7228.tar.xz/tests/sgsn/Makefile.am
Changed
@@ -60,6 +60,7 @@ $(top_builddir)/src/sgsn/gprs_gmm.o \ $(top_builddir)/src/sgsn/gprs_gmm_fsm.o \ $(top_builddir)/src/sgsn/gprs_mm_state_gb_fsm.o \ + $(top_builddir)/src/sgsn/gprs_routing_area.o \ $(top_builddir)/src/sgsn/gtp_ggsn.o \ $(top_builddir)/src/sgsn/gtp_mme.o \ $(top_builddir)/src/sgsn/mmctx.o \
View file
osmo-sgsn_1.12.0.16.62132.tar.xz/tests/testsuite.at -> osmo-sgsn_1.12.0.19.7228.tar.xz/tests/testsuite.at
Changed
@@ -14,6 +14,13 @@ AT_CHECK($abs_top_builddir/tests/sgsn/sgsn_test, , expout, ignore) AT_CLEANUP +AT_SETUP(gprs_routing_area) +AT_KEYWORDS(gprs_routing_area) +AT_CHECK(test "$enable_gprs_routing_area_test" != no || exit 77) +cat $abs_srcdir/gprs_routing_area/gprs_routing_area_test.ok > expout +AT_CHECK($abs_top_builddir/tests/gprs_routing_area/gprs_routing_area_test, , expout, ignore) +AT_CLEANUP + AT_SETUP(gtphub) AT_KEYWORDS(gtphub) AT_CHECK(test "$enable_gtphub_test" != no || exit 77)
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.