blob: d6bd25f9d0bc47fb5edb097cb15b6f6126fc06c9 [file] [log] [blame]
Pau Espin Pedrol7a74ae42022-12-23 16:33:17 +01001/* GPRS BSSGP protocol implementation as per 3GPP TS 08.18 */
2
3/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2010 by On-Waves
5 * (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
6 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23#include <osmocom/core/prim.h>
24#include <osmocom/core/rate_ctr.h>
25
26#include <osmocom/gprs/gprs_bssgp.h>
27#include <osmocom/gprs/gprs_ns2.h>
28
29#include <osmocom/sgsn/gprs_llc.h>
30#include <osmocom/sgsn/gprs_gmm.h>
31#include <osmocom/sgsn/sgsn_rim.h>
32
33/* call-back function for the BSSGP protocol */
34int sgsn_bssgp_rx_prim(struct osmo_prim_hdr *oph)
35{
36 struct osmo_bssgp_prim *bp;
37 bp = container_of(oph, struct osmo_bssgp_prim, oph);
38
39 switch (oph->sap) {
40 case SAP_BSSGP_LL:
41 switch (oph->primitive) {
42 case PRIM_BSSGP_UL_UD:
43 return gprs_llc_rcvmsg(oph->msg, bp->tp);
44 }
45 break;
46 case SAP_BSSGP_GMM:
47 switch (oph->primitive) {
48 case PRIM_BSSGP_GMM_SUSPEND:
49 return gprs_gmm_rx_suspend(bp->ra_id, bp->tlli);
50 case PRIM_BSSGP_GMM_RESUME:
51 return gprs_gmm_rx_resume(bp->ra_id, bp->tlli,
52 bp->u.resume.suspend_ref);
53 }
54 break;
55 case SAP_BSSGP_NM:
56 break;
57 case SAP_BSSGP_RIM:
58 return sgsn_rim_rx_from_gb(bp, oph->msg);
59 }
60 return 0;
61}
62
63int sgsn_bssgp_page_ps_ra(struct sgsn_mm_ctx *mmctx)
64{
65 struct bssgp_paging_info pinfo;
66 int rc;
67
68 /* FIXME: page whole routing area, not only the last known cell */
69
70 /* initiate PS PAGING procedure */
71 memset(&pinfo, 0, sizeof(pinfo));
72 pinfo.mode = BSSGP_PAGING_PS;
73 pinfo.scope = BSSGP_PAGING_BVCI;
74 pinfo.bvci = mmctx->gb.bvci;
75 pinfo.imsi = mmctx->imsi;
76 pinfo.ptmsi = &mmctx->p_tmsi;
77 pinfo.drx_params = mmctx->drx_parms;
78 pinfo.qos[0] = 0; // FIXME
79 rc = bssgp_tx_paging(mmctx->gb.nsei, 0, &pinfo);
80 rate_ctr_inc(rate_ctr_group_get_ctr(mmctx->ctrg, GMM_CTR_PAGING_PS));
81
82 return rc;
83}
84
85/* called by the bssgp layer to send NS PDUs */
86int sgsn_bssgp_dispatch_ns_unitdata_req_cb(void *ctx, struct msgb *msg)
87{
88 struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx;
89 struct osmo_gprs_ns2_prim nsp = {};
90 nsp.nsei = msgb_nsei(msg);
91 nsp.bvci = msgb_bvci(msg);
92 osmo_prim_init(&nsp.oph, SAP_NS, GPRS_NS2_PRIM_UNIT_DATA, PRIM_OP_REQUEST, msg);
93 return gprs_ns2_recv_prim(nsi, &nsp.oph);
94}