fixeria has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42364?usp=email )


Change subject: doc/manuals: add overview, document running and configuration
......................................................................

doc/manuals: add overview, document running and configuration

Change-Id: I4ceca069866d7191ef2b153af95a20cb522bffeb
Related: OS#6671
---
M README.md
A doc/manuals/Makefile
A doc/manuals/chapters/configuration.adoc
A doc/manuals/chapters/overview.adoc
A doc/manuals/chapters/running.adoc
A doc/manuals/osmo-s1gw-usermanual-docinfo.xml
A doc/manuals/osmo-s1gw-usermanual.adoc
7 files changed, 730 insertions(+), 38 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw 
refs/changes/64/42364/1

diff --git a/README.md b/README.md
index 5ff4589..d6a5299 100644
--- a/README.md
+++ b/README.md
@@ -54,8 +54,10 @@
 Documentation
 -------------

-Once the project reaches a usable milestone, we will be working on a
-user manual.  Stay tuned.
+The user manual source is in [`doc/manuals/`](doc/manuals/).  It covers
+installation, configuration, metrics, the REST API, and the interactive CLI.
+A pre-built PDF is published on the
+[Osmocom documentation server](https://ftp.osmocom.org/docs/osmo-s1gw).


 Contributing
@@ -113,54 +115,39 @@
 Installation
 ------------

-OsmoS1GW is built for common versions of Debian, Ubuntu and other 
distributions as a part of
-the [Osmocom binary 
packages](https://osmocom.org/projects/cellular-infrastructure/wiki/Binary_Packages).
-If you're not doing development, it is suggested to simply use those binary 
packages, rather
-than building from source.  Otherwise, you can invoke the `install` target:
+Osmocom provides binary packages for common Debian and Ubuntu releases via
+the [Osmocom binary package 
feed](https://osmocom.org/projects/cellular-infrastructure/wiki/Binary_Packages).
+Both a stable feed (tracking the latest release) and a nightly feed are
+available.  If you are not doing development, using the binary packages is
+the recommended approach.
+
+To build and install from source:

 ```
+$ make
 $ sudo make install
 ```

-This will install the following:
+`make install` deploys a complete ERTS release together with a convenience
+wrapper script and the interactive CLI tool:

-* `/usr/lib/osmo-s1gw` - complete OTP release package
-* `/usr/bin/osmo-s1gw` - convenience script for running `osmo-s1gw`
-* `/usr/bin/osmo-s1gw-cli` - interactive CLI for `osmo-s1gw`
-* `/lib/systemd/system/osmo-s1gw.service` - systemd unit file
-* `/etc/osmocom/osmo-s1gw.config` - the configuration file
+* `/usr/lib/osmo-s1gw` — complete OTP/ERTS release package
+* `/usr/bin/osmo-s1gw` — bootstrap script for starting the release
+* `/usr/bin/osmo-s1gw-cli` — interactive CLI tool
+* `/lib/systemd/system/osmo-s1gw.service` — systemd unit file
+* `/etc/osmocom/osmo-s1gw.config` — default configuration file

-The installation paths can be adjusted using `DESTDIR`, `LIBDIR`, `BINDIR`,
-`CONFDIR`, and `SYSTEMDUNITDIR` variables.
+Installation paths can be adjusted with `DESTDIR`, `LIBDIR`, `BINDIR`,
+`CONFDIR`, and `SYSTEMDUNITDIR`.  See the user manual for full details.


 Configuration
 -------------

-The default configuration can be found in
-[config/sys.config](config/sys.config).
-
-The existing parameters can be represented as follows:
-
-```
-  eNB              S1GW
-+-----+     +----------------+
-| ... | --> | s1gw_bind_addr |             MME
-+-----+     +----------------+     +-----------------+
-            |  mme_loc_addr  | --> |  mme_rem_addr   |
-            +----------------+     +-----------------+
-```
-
-* `s1gw_bind_addr` - S1GW bind address for incoming eNB connections
-* `mme_loc_addr` - local address for outgoing connections to the MME
-* `mme_rem_addr` - remote address for outgoing connections to the MME
-
-Logging can be configured in the `kernel` section:
-
-* `{logger_level, info}` - logging level (one of `emergency | alert |
-                           critical | error | warning | notice |
-                           info | debug`)
-* `#{formatter => { ... }` - logging formatting configuration
+The default configuration file is [`config/sys.config`](config/sys.config).
+For a full description of all available configuration parameters, see the
+Configuration chapter in the user manual
+([`doc/manuals/chapters/configuration.adoc`](doc/manuals/chapters/configuration.adoc)).


 REST interface
diff --git a/doc/manuals/Makefile b/doc/manuals/Makefile
new file mode 100644
index 0000000..b56e51d
--- /dev/null
+++ b/doc/manuals/Makefile
@@ -0,0 +1,16 @@
+OSMO_GSM_MANUALS_DIR ?= $(shell pkg-config osmo-gsm-manuals 
--variable=osmogsmmanualsdir 2>/dev/null)
+ifeq ($(OSMO_GSM_MANUALS_DIR),)
+$(error "osmo-gsm-manuals not found via pkg-config. Please install it.")
+endif
+
+# Without autotools, srcdir must be set explicitly so that 
Makefile.asciidoc.inc
+# can resolve {srcdir} in AsciiDoc include directives correctly.
+srcdir ?= $(CURDIR)
+
+ASCIIDOC = osmo-s1gw-usermanual.adoc
+include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
+
+osmo-s1gw-usermanual.pdf: $(wildcard chapters/*.adoc)
+
+OSMO_REPOSITORY = osmo-s1gw
+include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
diff --git a/doc/manuals/chapters/configuration.adoc 
b/doc/manuals/chapters/configuration.adoc
new file mode 100644
index 0000000..53e23e5
--- /dev/null
+++ b/doc/manuals/chapters/configuration.adoc
@@ -0,0 +1,304 @@
+[[configuration]]
+== Configuration
+
+OsmoS1GW is configured through an Erlang/OTP system configuration file.
+By default this file is `config/sys.config` in the source tree, or
+`/etc/osmocom/osmo-s1gw.config` after installation.  A different path
+can be supplied at start time via the `-c` option of the `osmo-s1gw`
+bootstrap script (see <<running_bootstrap_script>>) or via the `CONFIG`
+variable when using the project Makefile (see 
<<running_building_make_targets>>).
+
+The file uses Erlang term syntax.  The top level is a list of
+`{ApplicationName, [{Key, Value}, ...]}` tuples.  OsmoS1GW-specific
+parameters live under the `osmo_s1gw` application key.  Kernel
+parameters (logging) live under the standard `kernel` key, and metrics
+reporting parameters under the `exometer_core` key.
+
+[[config_sctp_server]]
+=== `sctp_server` — eNB-Facing SCTP Listener
+
+This section controls the SCTP socket on which OsmoS1GW listens for
+incoming connections from eNodeBs.
+
+----
+{sctp_server, #{
+    laddr => "127.0.1.1",  %% local bind address
+    lport => 36412,        %% local bind port (S1AP standard port)
+    sockopts => #{ }       %% optional socket options (see below)
+}}
+----
+
+`laddr`::
+  IP address to bind to.  Accepts a string in dotted-decimal (IPv4) or
+  colon-separated (IPv6) notation, or the atom `any` to bind to all
+  interfaces.  Default: `"127.0.1.1"`.
+
+`lport`::
+  TCP/SCTP port to listen on.  Default: `36412` (the IANA-assigned S1AP
+  port).
+
+`sockopts`::
+  An optional map of additional SCTP socket options:
++
+[options="header",cols="20,60,20"]
+|===
+| Option | Description | Default
+| `recbuf` | Receive buffer size in bytes | `65536`
+| `sndbuf` | Send buffer size in bytes | `65536`
+| `nodelay` | Disable Nagle algorithm (`true` to disable) | `true`
+|===
+
+[[config_mme_pool]]
+=== `mme_pool` — MME Pool Configuration
+
+The `mme_pool` key defines the list of MMEs that OsmoS1GW may connect to
+on behalf of connecting eNBs.  This is the recommended way to configure
+MME connectivity; it supports multiple MMEs and TAC-based selection.
+
+----
+{mme_pool, [
+    #{
+        name => "mme0",          %% unique name (required)
+        raddr => "192.168.2.10", %% MME IP address (required)
+        rport => 36412,          %% MME SCTP port (default: 36412)
+        laddr => any,            %% local bind address (default: any)
+        tac_list => []           %% allowed TACs (default: [] = all)
+    },
+    #{
+        name => "mme1",
+        raddr => "192.168.2.20",
+        tac_list => [100, 101, 102]
+    }
+]}
+----
+
+Each entry in the list is a map with the following fields:
+
+`name`::
+  A unique, human-readable string identifying this MME in log messages,
+  the REST API, and per-MME metrics.  Required.
+
+`raddr`::
+  The remote IP address of the MME.  Required.
+
+`rport`::
+  The remote SCTP port of the MME.  Default: `36412`.
+
+`laddr`::
+  The local IP address to bind to when connecting to this MME.  Accepts
+  a string or the atom `any`.  Default: `any`.
+
+`tac_list`::
+  A list of Tracking Area Codes (TACs) that this MME is willing to serve.
+  When an eNB connects and sends its S1 Setup Request, OsmoS1GW filters
+  the pool to MMEs whose `tac_list` is a superset of the eNB's
+  advertised TACs.  An empty list means the MME accepts all TACs.
+  Default: `[]`.
+
+MMEs can also be added and removed at run time via the REST API without
+restarting OsmoS1GW (see <<rest_mme>>).
+
+NOTE: The `mme_pool` key is mutually exclusive with the deprecated
+`sctp_client` key described in the next section.  If `mme_pool` is
+present, keys `laddr`, `raddr`, and `rport` from the `sctp_client`
+block are ignored.
+
+[[config_sctp_client]]
+=== `sctp_client` — Single MME (Deprecated)
+
+Prior to the introduction of MME pooling, the outbound MME connection was
+configured via the `sctp_client` section:
+
+----
+{sctp_client, #{
+    laddr => "127.0.2.1",  %% local bind address
+    raddr => "127.0.2.10", %% MME IP address
+    rport => 36412,        %% MME SCTP port
+    sockopts => #{ }       %% optional socket options (same as sctp_server)
+}}
+----
+
+When OsmoS1GW starts and finds no `mme_pool` key in the configuration,
+it automatically creates a single `"default"` MME pool entry from the
+`sctp_client` parameters and logs a deprecation warning.  This allows
+existing single-MME deployments to continue working without changes, but
+migration to `mme_pool` is strongly recommended.
+
+NOTE: The socket options (`sockopts`) from the `sctp_client` section are
+still used for the outbound SCTP socket regardless of whether `mme_pool`
+or `sctp_client` is used for MME addressing.
+
+[[config_pfcp]]
+=== PFCP — User Plane Function
+
+These parameters control the PFCP session between OsmoS1GW and the UPF.
+
+----
+{pfcp_loc_addr, "127.0.1.1"},  %% local address for PFCP (UDP)
+{pfcp_rem_addr, "127.0.1.2"},  %% remote address of the UPF
+
+%% Optional Network Instance IEs:
+%% {pfcp_net_inst_core,   "core-side"},
+%% {pfcp_net_inst_access, "radio-side"}
+----
+
+`pfcp_loc_addr`::
+  Local IP address on which OsmoS1GW listens for PFCP messages from the
+  UPF.  Default: `"127.0.1.1"`.
+
+`pfcp_rem_addr`::
+  Remote IP address of the UPF.  Default: `"127.0.1.2"`.
+
+`pfcp_net_inst_core`::
+  Value for the PFCP Network Instance IE on the core-network side of each
+  GTP-U session.  Omit if the UPF does not require Network Instance IEs.
+
+`pfcp_net_inst_access`::
+  Value for the PFCP Network Instance IE on the radio-access side of each
+  GTP-U session.  Omit if the UPF does not require Network Instance IEs.
+
+[[config_gtpu_kpi]]
+=== GTP-U KPI Reporting (Optional)
+
+OsmoS1GW can optionally poll nftables counters to derive per-eNB GTP-U
+traffic statistics and report them as exometer metrics.  This feature
+requires a matching nftables ruleset.
+
+----
+%% {gtpu_kpi_enable,     true},
+%% {gtpu_kpi_table_name, "osmo-s1gw"},
+%% {gtpu_kpi_ul_addr,    s1ap},
+%% {gtpu_kpi_dl_addr,    s1ap},
+%% {gtpu_kpi_interval,   3000}
+----
+
+`gtpu_kpi_enable`::
+  Set to `true` to enable the GTP-U KPI module.  Default: `false`.
+
+`gtpu_kpi_table_name`::
+  The nftables table name to read counters from.
+  Default: `"osmo-s1gw"`.
+
+`gtpu_kpi_ul_addr`::
+  Source of the uplink GTP-U address used to match nftables counters.
+  `s1ap` means learn the address from S1AP signalling; `sctp` means use
+  the eNB's SCTP source address.  Default: `s1ap`.
+
+`gtpu_kpi_dl_addr`::
+  Source of the downlink GTP-U address.  Same options as `gtpu_kpi_ul_addr`.
+  Default: `s1ap`.
+
+`gtpu_kpi_interval`::
+  How often (in milliseconds) to poll the nftables counters.
+  Default: `3000`.
+
+[[config_rest]]
+=== REST Interface
+
+----
+%% {rest_srv_port,       8080},
+%% {rest_srv_swagger_ui, true}
+----
+
+`rest_srv_port`::
+  TCP port on which the HTTP REST server listens.  Default: `8080`.
+
+`rest_srv_swagger_ui`::
+  Whether to serve the Swagger UI at `http://host:rest_srv_port/swagger`.
+  Default: `true`.
+
+[[config_kernel]]
+=== `kernel` — Logging
+
+OsmoS1GW uses the standard Erlang/OTP `logger` framework.  The `kernel`
+application section controls log levels and handlers.  See
+<<running_logging>> for a description of the log handlers configured by
+default.
+
+----
+{kernel, [
+    {logger_level, debug},
+    {logger, [
+        {handler, gsmtap, logger_gsmtap_h,
+         #{level => debug,
+           config => #{rem_addr => "127.0.0.1",
+                       app_name => "OsmoS1GW"}}},
+        {handler, default, logger_std_h,
+         #{level => info,
+           formatter => {logger_color_formatter, #{...}}}}
+    ]}
+]}
+----
+
+`logger_level`::
+  The global minimum log level.  Log records below this level are
+  discarded before reaching any handler.  Common values: `debug`,
+  `info`, `notice`, `warning`, `error`.
+
+For each handler in the `logger` list:
+
+`level`::
+  Handler-specific minimum log level.  Can be set independently per
+  handler to, for example, send only `warning` and above to the console
+  while sending all `debug` output over GSMTAP.
+
+`gsmtap` handler (`logger_gsmtap_h`)::
+  Sends log messages as GSMTAP frames over UDP.
++
+`rem_addr`::: Destination IP address.  Default: `"127.0.0.1"`.
+`app_name`::: Application name tag embedded in each GSMTAP frame.
+
+`default` handler (`logger_std_h`)::
+  Writes log lines to standard output.  When OsmoS1GW runs under systemd
+  this output is captured by the journal.
+
+[[config_exometer]]
+=== `exometer_core` — Metrics and StatsD Reporting
+
+OsmoS1GW uses the https://github.com/Feuerlabs/exometer_core[exometer_core]
+library for internal metrics (counters and gauges).  The `exometer_core`
+section configures reporters — processes that periodically push metric
+values to an external destination.
+
+The default configuration reports all counters and gauges to a StatsD
+server:
+
+----
+{exometer_core, [
+    {report, [
+        {reporters, [
+            {exometer_report_statsd, [
+                {hostname, "127.0.4.10"},
+                {port, 8125},
+                {prefix, "s1gw"},
+                {type_map, []}
+            ]}
+        ]},
+        {subscribers, [
+            {select, {[{ {['_'|'_'], counter, '_'}, [], ['$_']}],
+                       exometer_report_statsd, value, 1000, true,
+                       [{report_type, counter}]}},
+            {select, {[{ {['_'|'_'], gauge, '_'}, [], ['$_']}],
+                       exometer_report_statsd, value, 1000, true,
+                       [{report_type, gauge}]}}
+        ]}
+    ]}
+]}
+----
+
+`hostname`::
+  IP address or hostname of the StatsD server.
+
+`port`::
+  UDP port of the StatsD server.  Default: `8125`.
+
+`prefix`::
+  String prepended to all metric names as reported to StatsD.
+  Default: `"s1gw"`.
+
+The `subscribers` list uses exometer's `select` mechanism to
+automatically subscribe all counters and gauges to the StatsD reporter
+with a reporting interval of 1000 ms.  To disable StatsD reporting,
+comment out or remove the `exometer_report_statsd` reporter entry.
+
+// vim:set ts=4 sw=4 et:
diff --git a/doc/manuals/chapters/overview.adoc 
b/doc/manuals/chapters/overview.adoc
new file mode 100644
index 0000000..d8248ca
--- /dev/null
+++ b/doc/manuals/chapters/overview.adoc
@@ -0,0 +1,121 @@
+[[overview]]
+== Overview
+
+[[about]]
+=== About OsmoS1GW
+
+OsmoS1GW is an S1 Gateway for LTE (4G) networks, developed by
+https://www.sysmocom.de/[sysmocom].  It acts as a transparent proxy
+between eNodeBs (eNBs, i.e. radio base stations) and one or more MMEs
+(Mobility Management Entities), relaying S1AP signalling over SCTP/IP in
+both directions.
+
+In addition to S1AP proxying, OsmoS1GW manages GTP-U data plane tunnels
+(E-RABs / EPS bearers) by communicating with a co-located UPF (User
+Plane Function) via PFCP.  OsmoS1GW does not carry GTP-U traffic itself:
+GTP-U flows directly between the eNB and the UPF (access side), and
+between the UPF and the S-GW of the core network (core side).  OsmoS1GW
+only instructs the UPF — via PFCP Session Establishment, Modification,
+and Deletion procedures — to create, update, or tear down the
+corresponding forwarding rules.  It also rewrites the GTP-U TEID and
+Transport Layer Address (TLA) IEs inside S1AP messages so that eNBs send
+their GTP-U traffic to the UPF rather than directly to the core network.
+
+[[architecture]]
+=== Architecture
+
+The following diagram shows the high-level data flow through OsmoS1GW:
+
+----
+     S1AP/SCTP          S1AP/SCTP
+eNB <----------> S1GW <----------> MME (core)
+ ^                ^
+ |                |
+ |  GTP-U         | PFCP
+ |                |
+ |    GTP-U       V      GTP-U
+ +-------------> UPF <-----------> S-GW (core)
+----
+
+All S1AP messages are inspected by the gateway.  Most are forwarded
+unchanged; those that carry GTP-U endpoint information (E-RAB Setup,
+Modify, Release, Initial Context Setup, etc.) are rewritten so that the
+UPF's TLA/TEID is substituted for the core network's endpoint before
+forwarding to the eNB.  GTP-U traffic itself never passes through
+OsmoS1GW — it flows directly between the eNB and the UPF, and between
+the UPF and the S-GW.
+
+Internally, OsmoS1GW is structured as a set of Erlang/OTP processes:
+
+* *`sctp_server`* — Listens for incoming eNB SCTP connections and spawns
+  one `enb_proxy` instance per connection.
+* *`enb_proxy`* — One instance per connected eNB.  Manages the outbound
+  SCTP connection to the selected MME and drives the S1 Setup handshake.
+  Implements MME pooling and retry logic.
+* *`s1ap_proxy`* — Paired with each `enb_proxy`.  Inspects S1AP PDUs in
+  both directions and manages per-UE `erab_fsm` instances.
+* *`erab_fsm`* — One instance per active E-RAB.  Exchanges PFCP Session
+  Establishment/Modification/Deletion messages with the UPF and rewrites
+  GTP-U F-TEID IEs in S1AP messages.
+* *`pfcp_peer`* — Manages the PFCP association with the UPF (UDP-based),
+  including periodic heartbeat and SEID allocation.
+* *`mme_registry`* — Manages the pool of known MMEs.  MMEs can be
+  provisioned statically via the configuration file or dynamically via
+  the REST API.
+* *`enb_registry`* — Tracks all active eNB connections and their state.
+  Queryable via the REST API.
+* *`rest_server`* — OpenAPI-based HTTP REST interface for monitoring and
+  management.
+
+[[use_cases]]
+=== Use Cases
+
+[[use_case_isolated_networks]]
+==== Separated Core and Access Networks
+
+A common deployment scenario in private or industrial LTE networks is one
+where the core network (EPC) and the radio access network (RAN) reside in
+strictly separated IP domains with no direct routing between them — for
+example, a dedicated operations network for eNBs and a separate
+production network for the EPC.
+
+In this configuration, OsmoS1GW is deployed at the boundary between the
+two networks.  Each eNB connects to the gateway's access-facing SCTP
+listener, and the gateway in turn connects outward to the MME.  The eNBs
+never need a route to the core, and the EPC never needs a route to the
+radio access domain.
+
+----
+  +-----------+          +----------+          +-----+
+  |    eNB    |--S1AP/-->| OsmoS1GW |--S1AP/-->| MME |
+  | (RAN net) |   SCTP   | (border) |   SCTP   +-----+
+  +-----------+          +----------+
+        |                    | PFCP
+        |  GTP-U        +----+
+        +-------------->| UPF |-----> S-GW (EPC net)
+                        +-----+
+----
+
+The gateway acts as the sole point of contact between the two networks,
+providing a natural place to apply access control, logging, and
+monitoring.
+
+[[use_case_mme_pooling]]
+==== MME Pooling
+
+OsmoS1GW supports connecting multiple MMEs in a pool.  When an eNB
+connects and performs the S1 Setup procedure, the gateway selects an MME
+from the pool, establishes an SCTP connection to it, and forwards the S1
+Setup Request.  If the selected MME rejects the setup or is unreachable,
+the gateway automatically retries with the next candidate in the pool
+before returning a failure to the eNB.
+
+Pool members can be filtered by Tracking Area Code (TAC): each MME entry
+in the pool can carry an optional list of TACs it is willing to serve.
+The gateway uses the TAC list advertised by the eNB in the S1 Setup
+Request to restrict selection to compatible MMEs.
+
+MMEs can be configured statically in the configuration file or managed
+dynamically at run time via the REST API (see <<rest_mme>>).
+
+// vim:set ts=4 sw=4 et:
diff --git a/doc/manuals/chapters/running.adoc 
b/doc/manuals/chapters/running.adoc
new file mode 100644
index 0000000..743456f
--- /dev/null
+++ b/doc/manuals/chapters/running.adoc
@@ -0,0 +1,204 @@
+[[running]]
+== Running OsmoS1GW
+
+[[running_requirements]]
+=== Requirements
+
+OsmoS1GW requires:
+
+* Erlang/OTP 25 or later.
+* A Linux kernel with SCTP support (`sctp` kernel module).
+* A reachable UPF that speaks PFCP (e.g. 
https://osmocom.org/projects/osmo-upf[OsmoUPF]).
+* One or more reachable MMEs (e.g. 
https://github.com/open5gs/open5gs[Open5GS]).
+
+[[running_installation_options]]
+=== Installation Options
+
+[[running_binary_packages]]
+==== Official Osmocom Binary Packages
+
+Osmocom provides binary packages of OsmoS1GW for a variety of GNU/Linux
+distributions, primarily Debian based ones.  This is the recommended
+installation method for production deployments.
+
+Two package feeds are available:
+
+`latest`::
+  Contains the most recent tagged release of each program.
+  Suitable for production use.
+
+`nightly`::
+  Contains automatic nightly builds from the current master branch.
+  Useful for testing new features or bug fixes before they are formally 
released.
+
+For up-to-date instructions on how to add the Osmocom package repository
+for your distribution, see:
+https://osmocom.org/projects/cellular-infrastructure/wiki/Binary_Packages
+
+[[running_building]]
+==== Building from Source
+
+OsmoS1GW uses https://rebar3.org[rebar3] as its build tool, wrapped by a
+convenience `Makefile` in the project root.  To fetch dependencies and
+compile:
+
+----
+git clone https://gitea.osmocom.org/osmocom/osmo-s1gw.git
+cd osmo-s1gw
+make
+----
+
+[[running_building_make_targets]]
+===== Available Make Targets
+
+The following targets are available:
+
+`make` / `make build`::
+  Compile the application and all dependencies (default target).
+
+`make shell` / `make run`::
+  Compile and start OsmoS1GW in an interactive Erlang shell.  Intended
+  for development and local testing.  The config file used is controlled
+  by the `CONFIG` variable (default: `config/sys.config`).
+
+`make check`::
+  Run the EUnit test suite.  Additional arguments can be passed to the
+  test runner via the `EUNIT_ARGS` variable.
+
+`make analyze`::
+  Run Dialyzer static type analysis.
+
+`make release`::
+  Build a self-contained Erlang/OTP release package (includes the ERTS
+  runtime) under `_build/default/rel/osmo-s1gw/`.
+
+`make run-release`::
+  Build the release and immediately start it using the `osmo-s1gw.sh`
+  bootstrap script (see <<running_bootstrap_script>>).  The `CONFIG`
+  variable selects the config file.
+
+`make install`::
+  Build the release and install OsmoS1GW system-wide.  See
+  <<running_building_installation>> for details.
+
+`make clean`::
+  Remove all build artefacts.
+
+[[running_building_make_variables]]
+===== Make Variables
+
+The following variables customise the build and installation:
+
+[options="header",cols="25,50,25"]
+|===
+| Variable | Description | Default
+| `CONFIG` | Config file used by `make shell` and `make run-release` | 
`config/sys.config`
+| `EUNIT_ARGS` | Extra arguments forwarded to `rebar3 eunit` | (none)
+| `BINDIR` | Installation directory for executables | `/usr/bin`
+| `LIBDIR` | Installation directory for the release package | `/usr/lib`
+| `CONFDIR` | Installation directory for the config file | `/etc/osmocom`
+| `SYSTEMDUNITDIR` | Installation directory for the systemd unit | 
`/lib/systemd/system`
+| `DESTDIR` | Staging root prefix (for package builds) | (empty)
+|===
+
+[[running_building_installation]]
+===== Installation
+
+Running `make install` (typically as root, or with `DESTDIR` set for
+packaging) performs the following steps:
+
+* Copies the self-contained Erlang/OTP release to `$(LIBDIR)/osmo-s1gw`
+  (default: `/usr/lib/osmo-s1gw`).  This directory bundles the ERTS
+  runtime and all application code, so no separate Erlang installation is
+  required on the target system.
+* Installs the `osmo-s1gw.sh` bootstrap script (see
+  <<running_bootstrap_script>>) as `$(BINDIR)/osmo-s1gw`
+  (default: `/usr/bin/osmo-s1gw`).
+* Installs the `osmo-s1gw-cli.py` management CLI as
+  `$(BINDIR)/osmo-s1gw-cli` (default: `/usr/bin/osmo-s1gw-cli`).
+* Installs the example `config/sys.config` as
+  `$(CONFDIR)/osmo-s1gw.config` (default: `/etc/osmocom/osmo-s1gw.config`).
+* Installs the systemd unit file to `$(SYSTEMDUNITDIR)/osmo-s1gw.service`
+  (default: `/lib/systemd/system/osmo-s1gw.service`).
+
+[[running_options]]
+=== Running Options
+
+[[running_bootstrap_script]]
+==== The `osmo-s1gw` Bootstrap Script
+
+The installed `osmo-s1gw` executable is a POSIX shell script
+(`contrib/osmo-s1gw.sh`) that locates the bundled ERTS runtime inside
+the release package and launches `erlexec` with the correct boot, config,
+and node parameters.  It is the standard entry point both for systemd and
+for manual invocation.
+
+Usage:
+
+----
+osmo-s1gw [-s] [-r ROOTDIR] [-c CONFIG] [-C COOKIE] [-n NAME@HOST]
+----
+
+Options:
+
+`-r ROOTDIR`::
+  Path to the Erlang/OTP release root directory.
+  Default: `/usr/lib/osmo-s1gw`.
+
+`-c CONFIG`::
+  Path to the configuration file.
+  Default: `/etc/osmocom/osmo-s1gw.config`.
+
+`-C COOKIE`::
+  Erlang distribution cookie used for inter-node communication.
+  Default: `osmo-s1gw`.
+
+`-n NAME@HOST`::
+  Erlang node name.  Default: `osmo-s1gw@<hostname>`.
+
+`-s`::
+  Start with an interactive Erlang shell instead of running headless.
+  Useful for debugging on a deployed system.
+
+[[running_systemd]]
+==== Running Under systemd
+
+After installation, enable and start OsmoS1GW as a systemd service:
+
+----
+systemctl enable osmo-s1gw
+systemctl start osmo-s1gw
+----
+
+The unit file runs OsmoS1GW as the `osmocom` user and group and requests
+the `CAP_NET_ADMIN` capability (required for GTP-U KPI monitoring).
+The service is restarted automatically on failure with a 2-second delay.
+OsmoS1GW reads its configuration from `/etc/osmocom/osmo-s1gw.config`.
+
+To inspect the log output:
+
+----
+journalctl -u osmo-s1gw -f
+----
+
+[[running_logging]]
+=== Logging
+
+OsmoS1GW uses the standard Erlang/OTP `logger` framework.  Two log
+handlers are configured by default in `config/sys.config`:
+
+`default`::
+  Writes formatted log lines to standard output.  When running under
+  systemd this output is captured by the journal.  The log level is set
+  to `info` by default.
+
+`gsmtap`::
+  Sends log messages as GSMTAP frames over UDP to a configurable
+  destination (default: `127.0.0.1`).  These frames can be captured with
+  Wireshark and are tagged with the application name `OsmoS1GW`.
+
+The global minimum log level is controlled by the `logger_level` kernel
+parameter; individual handler levels can be overridden independently.
+See <<config_kernel>> for the relevant configuration section.
+
+// vim:set ts=4 sw=4 et:
diff --git a/doc/manuals/osmo-s1gw-usermanual-docinfo.xml 
b/doc/manuals/osmo-s1gw-usermanual-docinfo.xml
new file mode 100644
index 0000000..27fd2f3
--- /dev/null
+++ b/doc/manuals/osmo-s1gw-usermanual-docinfo.xml
@@ -0,0 +1,38 @@
+<revhistory>
+  <revision>
+    <revnumber>1</revnumber>
+    <date>March 2026</date>
+    <authorinitials>s</authorinitials>
+    <revremark>Initial version</revremark>
+  </revision>
+</revhistory>
+
+<authorgroup>
+  <author>
+    <firstname>sysmocom</firstname>
+    <surname>- s.f.m.c. GmbH</surname>
+    <email>[email protected]</email>
+  </author>
+</authorgroup>
+
+<copyright>
+  <year>2025-2026</year>
+  <holder>sysmocom - s.f.m.c. GmbH</holder>
+</copyright>
+
+<legalnotice>
+  <para>
+    Permission is granted to copy, distribute and/or modify this document
+    under the terms of the GNU Free Documentation License, Version 1.3 or
+    any later version published by the Free Software Foundation; with no
+    Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+    copy of the license is included in the section entitled "GNU Free
+    Documentation License".
+  </para>
+  <para>
+    The Asciidoc source code of this manual can be found at
+    <ulink url="https://gitea.osmocom.org/osmocom/osmo-s1gw";>
+      https://gitea.osmocom.org/osmocom/osmo-s1gw
+    </ulink>
+  </para>
+</legalnotice>
diff --git a/doc/manuals/osmo-s1gw-usermanual.adoc 
b/doc/manuals/osmo-s1gw-usermanual.adoc
new file mode 100644
index 0000000..13dcd4b
--- /dev/null
+++ b/doc/manuals/osmo-s1gw-usermanual.adoc
@@ -0,0 +1,22 @@
+OsmoS1GW User Manual
+====================
+:author: sysmocom - s.f.m.c. GmbH
+:toc:
+:numbered:
+:toclevels: 5
+:sectnumlevels: 5
+
+
+include::{commondir}/chapters/preface.adoc[]
+
+include::{srcdir}/chapters/overview.adoc[]
+
+include::{srcdir}/chapters/running.adoc[]
+
+include::{srcdir}/chapters/configuration.adoc[]
+
+include::{commondir}/chapters/glossary.adoc[]
+
+include::{commondir}/chapters/bibliography.adoc[]
+
+include::{commondir}/chapters/gfdl.adoc[]

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

Gerrit-MessageType: newchange
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: I4ceca069866d7191ef2b153af95a20cb522bffeb
Gerrit-Change-Number: 42364
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <[email protected]>

Reply via email to