GPRS support in osmocom-bb
==========================
:author:	Pau Espin Pedrol <pespin@sysmocom.de>, Vadim Yanitskiy <vyanitskiy@sysmocom.de>
:copyright:	2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> (License: CC-BY-SA)
:backend:	slidy
:max-width:	54em

== Project Scope

* Introduced as part of link:https://osmocom.org/projects/baseband/wiki/MS-side_GPRS[MS-side GPRS] osmocom-bb project
* TODO: mention who sponsored the project, scope, etc.
* Open source GPRS implementation for OsmocomBB
* SDR GSM mobile phone (GPRS in calpyso not working/tested yet)

== Reminder: GPRS Stack

* L2 + L3: `modem`, _osmocom-bb/src/host/layer23/src/modem/_
* L1: `osmo-trx-ms-blade`, _osmo-trx/Transceiver52M/ms/_

image::gprs_stack.drawio.png[width="40%"]

== Block diagram

* Interfaces between layers "specified" in 3GPP specs

image::ardc_darc_gprs_arch.v5.png[width="50%"]

== libosmo-gprs: Introduction

[role="incremental"]
* Contains several .so, one per layer:
** libosmo-gprs-*: csn1, rlcmac, llc, sndcp, gmm, sm
** Helper libosmo-csn1
* Layer comunication through primitives
* Follows 3GPP "specified" interfaces as close as possible
* Each layer can be used independently
* App in charge of forwarding primitives between layers through callback hooks
* Support multiple concurrent subscribers

== libosmo-gprs-<layer>: Public API

[role="incremental"]

* _include/osmocom/gprs/<layer>/<layer>.h_:
[role="incremental"]
** `osmo_gprs_<layer>_init(cfg)`
** `osmo_gprs_<layer>_set_log_cat(enum logc, int num)`
*** Support multiple log categories
*** Dynamic mapping of log categories done by app
** Layer related public data types

* _include/osmocom/gprs/<layer>/<layer>_prim.h_:
[role="incremental"]
** `struct osmo_gprs_<layer>_<if>_prim`: Holds all primitives for each interface
** `struct osmo_gprs_<layer>_prim`: `osmo_prim_hdr` + `struct osmo_gprs_<layer>_<if>_prim`
** `osmo_gprs_<layer>_prim_alloc()`
** `osmo_gprs_<layer>_prim_set_{up,down}_cb()`
** `osmo_gprs_<layer>_{upper_down,lower_up}()`

* _include/osmocom/gprs/<layer>/<layer>_private.h_:
[role="incremental"]
* Private APIs and data types

== libosmo-gprs-sm

.SMREG:
[role="incremental"]
* Used by app directly to manage PDP Contexts
* eg. Tx PDP_ACTIVATE.req, Rx PDP_ACTIVATE.cnf

.GMMSM:
[role="incremental"]
* Trigger implicit attach/detach during PDP Context creation/deletion

== libosmo-gprs-gmm

.GMMSM:
[role="incremental"]
* Trigger implicit attach/detach during PDP Context creation/deletion

.GMMREG:
[role="incremental"]
* Explicit attach/detach by app
* SIM AUTH required towards app (Primitive osmocom specific)

.LL:
[role="incremental"]
* Rx/Tx GMM PDUs to LLC layer

.LLGMM:
[role="incremental"]
* LLC-SUSPEND, LLC-STATUS, TRIGGER (Cell Notification, READY timer)

.GMMRR:
[role="incremental"]
* Assing new negotiated TLLI to lower layers (RLC/MAC)
* Page indications
* LLC transmitted notifications (timers, counters)

== libosmo-gprs-sndcp

* Internal implementation ported from osmo-sgsn + heavy clean up

.SN:
[role="incremental"]
* Used by app to Tx/Rx user data (IP packets from tundev)
* App configures, negotiates SNDCP XIDs

.SNSM:
[role="incremental"]
* Coordination with GPRS SM layer
* eg. PDP Context was (de)activated

.LL:
[role="incremental"]
* Rx/Tx SNDCP PDUs to LLC layer

== libosmo-gprs-llc

* Internal implementation ported from osmo-sgsn + heavy clean up

.LL:
[role="incremental"]
* Forward GMM/SNDCP PDUs to/from upper layers
* LLE (per SAPI)

.LLGMM:
[role="incremental"]
* Already covered in previous slide (LLC-SUSPEND/STATUS/TRIGGER)
* LLME (shared among all SAPIs)

.GRR: (MS role)
[role="incremental"]
* Tx/Rx LLC frames to/from RLC/MAC

.BSSGP: (SGSN role)
[role="incremental"]
* Tx/Rx LLC frames to/from BSSGP

== libosmo-gprs-rlcmac

* Some parts of the implementation ported from osmo-pcu + heavy clean up

.GRR:
[role="incremental"]
* Forward LLC frames to/from upper layers (LLC)

.GMMRR:
[role="incremental"]
* Assing new negotiated TLLI to lower layers (RLC/MAC)
* Page indications
* LLC transmitted notifications (timers, counters)

.L1CTL:
[role="incremental"]
* Tx RACH.req
* Rx CCCH_DATA.ind
* Configure PDCH in lower layers (l1gprs scheduler)
* Configure TBFs in PDCH
* PDCH_DATA.req/cnf, PDCH_RTS.ind

== `modem` Application

[role="incremental"]
* Takes care of CS management (cell sync, etc.)
* Manages SM and MM state through `SMREG` and `GMMREG` primitive interfaces
* Manages the tundev for each APN
* Provides callbacks to forward primitives:
** Between the different libosmo-gprs-* libs
** To/from L1CTL provider (unix socket, `trxcon` + `osmo-trx-ms-blade`)

== Example: `modem` establishing a PDP Context

[role="incremental"]
. _modem_: Configure APNs (VTY)
. _modem_: Modem syncs to cell (CCCH)
. _modem -> SM_: SMREG-PDP_ACT.req
. _SM -> GMM_: GMMSM-ESTABLISH.req
. _GMM -> LLC_: LL-UNITDATA.req(GMMAttachReq)
. _LLC -> RLC/MAC_: GRR-UNITDATA.req(llc_frame[GMMAttachReq])
. _RLC/MAC_ needs a TBF to transmit data
[role="incremental"]
.. _RLC/MAC -> L1CTL_: L1CTL-RACH.req
.. _L1CTL -> RLC/MAC_: L1CTL-CCCH_DATA.ind(ImmAss[ts, fn, usf, tfi])
.. _RLC/MAC -> L1CTL_: L1CTL-PDCH_EST.req
.. _RLC/MAC -> L1CTL_: L1CTL-CFG_UL_TBF.req
.. _L1CTL -> RLC/MAC_: L1CTL-PDCH_RTS.ind(fn, ts, usf)
. _RLC/MAC -> L1CTL_: L1CTL-PDCH_DATA.req(rlc_blk[llc_frame[GMMAttachReq]])
. _L1CTL -> RLC/MAC_: L1CTL-PDCH_DATA.ind(rlc_blk[llc_frame[GMMAttachAcc]])
. _RLC/MAC -> LLC_: GRR-UNIT_DATA.req(llc_frame[GMMAttachAcc])
. _LLC -> GMM_: LL-UNIT_DATA.req(GMMAttachAcc)
. _GMM -> SM_: GMMSM-UNITDATA.req(SM-ActivatePDPContextReq)
. ...

== L1CTL

* TODO:
* libtrxcon
* l1gprs
* osmo-trx-lms


== Future work

* libosmo-gprs:
** Cleanup API: No need 1 alloc API per primitive+operation type
** Declare its API stable

* libosmo-gprs-rlcmac:
** Support TBFs with >1 TS
** Support EGPRS
** Tons of other features missing

* osmo-sgsn:
** WIP: Port to libosmo-gprs-{llc,sndcp}, link:https://osmocom.org/issues/5853[OS#5853] (branch `pespin/libosmo-gprs`)

== Know more

* link:https://osmocom.org/projects/baseband/wiki/MS-side_GPRS[MS-side GPRS]
* link:https://osmocom.org/projects/libosmo-gprs[libosmo-gprs Redmine Project]
