Interactive CLI
===============

[`osmo-s1gw-cli.py`](../contrib/osmo-s1gw-cli.py) is an interactive shell based on
Python's **cmd2** library.  This script serves as an alternative to the traditional
telnet/VTY interface found in many Osmocom projects.  It communicates with the main
process via the **REST interface**, allowing users to inspect and interact with
OsmoS1GW in a familiar CLI style.

Installation
------------

`osmo-s1gw-cli.py` has the following dependencies:

* [`cmd2`](https://pypi.org/project/cmd2/)
* [`tabulate`](https://pypi.org/project/tabulate/)

You can install them using **pip**:

```bash
pip install cmd2 tabulate
```

Or using your system's package manager (Debian/Ubuntu example):

```bash
sudo apt install python3-cmd2 python3-tabulate
```

Usage
-----

By default, `osmo-s1gw-cli.py` is sending HTTP requests to `http://localhost:8080`.
The hostname/address and port can be specified using command-line arguments:

```bash
./contrib/osmo-s1gw-cli.py --help
usage: osmo-s1gw-cli [-h] [-v] [-p PORT] [HOST]

Interactive CLI for OsmoS1GW

positional arguments:
  HOST             OsmoS1GW REST host/address (default: localhost)

options:
  -h, --help       show this help message and exit
  -v, --verbose    print debug logging
  -p, --port PORT  OsmoS1GW REST port (default: 8080)
```

Available commands can be listed by entering `help -v`:

```
Welcome to Interactive CLI for OsmoS1GW!
OsmoS1GW# help -v
...
```

Each command has its own detailed help, accessible with `help CMD`:

```
OsmoS1GW# help quit
Usage: quit [-h]

Exit this application

optional arguments:
  -h, --help  show this help message and exit
```

In addition to tab-completion, you can filter (`CMD | grep ...`) and/or
redirect (`CMD > FILE`) output of a command to a file.  For more details
on the available features and usage patterns, please refer to the
[cmd2 documentation](https://cmd2.readthedocs.io/en/stable/features/).

Commands
--------

Below is a list of currently supported commands and some examples.

### `fetch_openapi_spec`

Fetch the OpenAPI specification (JSON), dump as text.

### `metrics_list`

Get a list of metrics.

```
Usage: metrics_list [-h] [-t {all, counter, gauge}] [PATH]

Get a list of metrics

positional arguments:
  PATH                  Metric path

optional arguments:
  -h, --help            show this help message and exit
  -t, --type {all, counter, gauge}
                        Metric type (default: all)
```

Example: Obtaining PFCP association related metrics.

```
OsmoS1GW# metrics_list pfcp.assoc
| Name                          | Type    |   Value |
|-------------------------------|---------|---------|
| pfcp.assoc_setup_req.timeout  | counter |      21 |
| pfcp.assoc_setup_req.tx       | counter |      22 |
| pfcp.assoc_setup_resp.rx      | counter |       0 |
| pfcp.assoc_setup_resp.rx_ack  | counter |       0 |
| pfcp.assoc_setup_resp.rx_nack | counter |       0 |
| pfcp.associated               | gauge   |       0 |
```

Example: Obtaining all gauges.

```
OsmoS1GW# metrics_list --type gauge
| Name                             | Type   |   Value |
|----------------------------------|--------|---------|
| pfcp.associated                  | gauge  |       0 |
| s1ap.enb.num_sctp_connections    | gauge  |       0 |
| s1ap.proxy.uplink_packets_queued | gauge  |       0 |
```

### `pfcp_assoc_state`

Get the PFCP association state.

```
| Parameter                 | Value      |
|---------------------------|------------|
| State                     | connected  |
| Local address             | 127.0.3.1  |
| Remote address            | 127.0.3.10 |
| Local Recovery TimeStamp  | 3967211233 |
| Remote Recovery TimeStamp | 3965211123 |
```

### `pfcp_heartbeat`

Send a PFCP Heartbeat Request.

```
OsmoS1GW# pfcp_heartbeat
Heartbeat succeeded

OsmoS1GW# pfcp_heartbeat
Heartbeat failed: timeout
```

### `mme_list`

Get a list of registered MMEs.

```
Usage: mme_list [-h] [-S {none, name, laddr, raddr}] [--reverse]

Get a list of registered MMEs

optional arguments:
  -h, --help            show this help message and exit

Sorting options:
  -S, --sort-by {none, name, laddr, raddr}
                        Sort by (default: none)
  --reverse             Reverse order (default: False)
```

Example: getting a list of MMEs (not sorted by default).

```
OsmoS1GW# mme_list
| Name   | Local address   | Remote address/port   |
|--------|-----------------|-----------------------|
| mme0   | ::              | 127.0.2.10:36412      |
| mme1   | ::              | 127.0.2.20:36412      |
| mme2   | ::              | 127.0.2.30:36412      |
```

### `mme_add`

Add an MME to the pool.

```
Usage: mme_add -N NAME -ra RADDR [-h] [-la LADDR] [-rp RPORT]

Add an MME to the pool

required arguments:
  -N, --name NAME     MME name (example: mme0)
  -ra, --raddr RADDR  Remote address (example: 192.168.1.101)

optional arguments:
  -h, --help          show this help message and exit
  -la, --laddr LADDR  Local address (default: ::)
  -rp, --rport RPORT  Remote port (default: 36412)
```

Example: adding an MME with remote address "192.168.1.101".

```
OsmoS1GW# mme_add --name mme42 --raddr 192.168.1.101
```

### `mme_info`

Get information about a specific MME.

```
Usage: mme_info [-h] -N NAME

Get information about a specific MME

optional arguments:
  -h, --help       show this help message and exit

MME ID:
  -N, --name NAME  MME name (example: mme0)
```

Example: getting information about an MME with name "mme0".

```
OsmoS1GW# mme_info --name mme0
| Parameter           | Value            |
|---------------------|------------------|
| Name                | mme0             |
| Local address       | ::               |
| Remote address/port | 127.0.2.10:36412 |
```

### `mme_delete`

Delete an MME from the pool.

```
Usage: mme_delete [-h] -N NAME

Delete an MME from the pool

optional arguments:
  -h, --help       show this help message and exit

MME ID:
  -N, --name NAME  MME name (example: mme0)
```

Example: deleting an MME with name "mme0".

```
OsmoS1GW# mme_delete --name mme0
```

### `enb_list`

Get a list of eNB connections.

```
Usage: enb_list [-h]
                [-S {handle, pid, state, genb_id, uptime}] [--reverse]

Get a list of eNB connections

optional arguments:
  -h, --help            show this help message and exit

Sorting options:
  -S, --sort-by {handle, pid, state, genb_id, uptime}
                        Sort by (default: handle)
  --reverse             Reverse order (default: False)
```

Example: getting a list of eNBs (by default, sorted by handle).

```
OsmoS1GW# enb_list
|   eNB handle | PID       | Global-eNB-ID   | State     | eNB addr:port (aid)     | MME addr:port (aid)     |   Uptime (s) |   # E-RABs |
|--------------|-----------|-----------------|-----------|-------------------------|-------------------------|--------------|------------|
|            0 | <0.699.0> | 001-01-0        | connected | 127.0.1.10:56767 (5706) | 127.0.2.10:36412 (5707) |          418 |          0 |
|            1 | <0.701.0> | 001-01-1        | connected | 127.0.1.10:54140 (5710) | 127.0.2.10:36412 (5711) |           33 |          3 |
|            2 | <0.703.0> | 001-01-2        | connected | 127.0.1.10:34076 (5714) | 127.0.2.10:36412 (5715) |         3600 |         20 |
|            3 | <0.705.0> | 001-01-3        | connected | 127.0.1.10:46501 (5718) | 127.0.2.10:36412 (5719) |          869 |         13 |
|            4 | <0.707.0> | 001-01-4        | connected | 127.0.1.10:35610 (5722) | 127.0.2.10:36412 (5723) |           18 |          0 |
|            5 | <0.709.0> | 001-01-5        | connected | 127.0.1.10:37610 (5726) | 127.0.2.10:36412 (5727) |          933 |        129 |
|            6 | <0.711.0> | 001-01-6        | connected | 127.0.1.10:58447 (5730) | 127.0.2.10:36412 (5741) |          535 |          6 |
|            7 | <0.713.0> | 001-01-7        | connected | 127.0.1.10:35842 (5732) | 127.0.2.10:36412 (5743) |          736 |          8 |
|            8 | <0.715.0> | 001-01-8        | connected | 127.0.1.10:57362 (5734) | 127.0.2.10:36412 (5745) |          521 |         99 |
|            9 | <0.717.0> | 001-01-9        | connected | 127.0.1.10:50955 (5736) | 127.0.2.10:36412 (5747) |           33 |          1 |
```

### `enb_info`

Get information about a specific eNB.

```
Usage: enb_info [-h] (-H HANDLE | -P PID | -G GENBID |
                      --enb-sctp-aid AID |
                      --mme-sctp-aid AID)

Get information about a specific eNB

optional arguments:
  -h, --help           show this help message and exit

eNB ID:
  -H, --handle HANDLE  eNB handle (example: 0)
  -P, --pid PID        eNB process ID (example: 0.33.1)
  -G, --genbid GENBID  Global-eNB-ID (example: 262-42-1337)
  --enb-sctp-aid AID   eNB association identifier (example: 42)
  --mme-sctp-aid AID   MME association identifier (example: 42)
```

Example: Getting eNB information using a handle.

```
OsmoS1GW# enb_info -H8
| Parameter           | Value                   |
|---------------------|-------------------------|
| eNB handle          | 8                       |
| PID                 | <0.715.0>               |
| Global-eNB-ID       | 001-01-8                |
| State               | connected               |
| eNB addr:port (aid) | 127.0.1.10:57362 (5734) |
| MME addr:port (aid) | 127.0.2.10:36412 (5745) |
| Uptime (s)          | 521                     |
| # E-RABs            | 99                      |
```

Example: Getting eNB information using a pricess ID.

```
OsmoS1GW# enb_info --pid 0.715.0
| Parameter           | Value                   |
|---------------------|-------------------------|
| eNB handle          | 8                       |
| PID                 | <0.715.0>               |
| Global-eNB-ID       | 001-01-8                |
| State               | connected               |
| eNB addr:port (aid) | 127.0.1.10:57362 (5734) |
| MME addr:port (aid) | 127.0.2.10:36412 (5745) |
| Uptime (s)          | 521                     |
| # E-RABs            | 99                      |
```

Example: Unsuccessful outcome for an unknown/invalid Global-eNB-ID.

```
OsmoS1GW# enb_info -G 001-01-42
EXCEPTION of type 'HTTPError' occurred with message: HTTP Error 404: Not Found
To enable full traceback, run the following command: 'set debug true'

OsmoS1GW# enb_info -G 123456
EXCEPTION of type 'HTTPError' occurred with message: HTTP Error 400: Bad Request
To enable full traceback, run the following command: 'set debug true'
```

### `enb_delete`

Force disconnect an eNB.

```
Usage: enb_delete [-h] (-H HANDLE | -P PID | -G GENBID | --enb-sctp-aid AID | --mme-sctp-aid AID)

Force disconnect an eNB

optional arguments:
  -h, --help           show this help message and exit

eNB ID:
  -H, --handle HANDLE  eNB handle (example: 0)
  -P, --pid PID        eNB process ID (example: 0.33.1)
  -G, --genbid GENBID  Global-eNB-ID (example: 262-42-1337)
  --enb-sctp-aid AID   eNB association identifier (example: 42)
  --mme-sctp-aid AID   MME association identifier (example: 42)
```

### `enb_erab_list`

Get E-RAB list for a specific eNB.

```
Usage: enb_erab_list [-h] [-f]
                     [-S {pid, state, mme_ue_id, erab_id}] [--reverse]
                     (-H HANDLE | -P PID | -G GENBID | --enb-sctp-aid AID | --mme-sctp-aid AID)

Get E-RAB list for a specific eNB

optional arguments:
  -h, --help            show this help message and exit
  -f, --full            Print full table (more columns)

Sorting options:
  -S, --sort-by {pid, state, mme_ue_id, erab_id}
                        Sort by (default: pid)
  --reverse             Reverse order (default: False)

eNB ID:
  -H, --handle HANDLE   eNB handle (example: 0)
  -P, --pid PID         eNB process ID (example: 0.33.1)
  -G, --genbid GENBID   Global-eNB-ID (example: 262-42-1337)
  --enb-sctp-aid AID    eNB association identifier (example: 42)
  --mme-sctp-aid AID    MME association identifier (example: 42)
```

Example: Obtaining E-RAB list for an eNB with the given Global-eNB-ID.

```
OsmoS1GW# enb_erab_list -G 001-01-0
| PID       |   MME-UE-S1AP-ID |   E-RAB-ID | State      |
|-----------|------------------|------------|------------|
| <0.707.0> |             4242 |          0 | erab_setup |
| <0.708.0> |             4242 |          1 | erab_setup |
| <0.709.0> |             4242 |          2 | erab_setup |
```

### `erab_list`

Get E-RAB list for all eNBs.

```
Usage: erab_list [-h] [-f]
                 [-S {pid, state, mme_ue_id, erab_id}] [--reverse]

Get E-RAB list for all eNBs

optional arguments:
  -h, --help            show this help message and exit
  -f, --full            Print full table (more columns)

Sorting options:
  -S, --sort-by {pid, state, mme_ue_id, erab_id}
                        Sort by (default: pid)
  --reverse             Reverse order (default: False)
```

The output format is the same as produced by the `enb_erab_list` command.

### `erab_info`

Get information about a specific E-RAB.

```
Usage: erab_info -P PID [-h]

Get information about a specific E-RAB

required arguments:
  -P, --pid PID  E-RAB process ID (example: 0.33.1)

optional arguments:
  -h, --help     show this help message and exit

```

Example: Obtaining E-RAB info using process ID.

```
OsmoS1GW# erab_info -P 0.714.0
| Parameter      | Value                |
|----------------|----------------------|
| PID            | <0.714.0>            |
| MME-UE-S1AP-ID | 4242                 |
| E-RAB-ID       | 1                    |
| State          | erab_setup           |
| SEID (local)   | 0x0000000000000002   |
| SEID (remote)  | 0x5454434e2d330001   |
| U2C F-TEID     | 0x00010001@127.0.0.1 |
| C2U F-TEID     | 0x01010001@127.0.1.1 |
| A2U F-TEID     | 0x02020001@127.0.2.2 |
| U2A F-TEID     | 0x00020001@127.0.0.2 |
```

### `erab_delete`

Terminate an E-RAB FSM process.

```
Usage: erab_delete -P PID [-h]

Terminate an E-RAB FSM process

required arguments:
  -P, --pid PID  E-RAB process ID (example: 0.33.1)

optional arguments:
  -h, --help     show this help message and exit
```
