# Example ICCP/TASE.2 Server

A reference passive (server) endpoint that exposes a fully populated sample data
model and serves the standard ICCP services: discovery, read/write, dataset
management, device control, and Data Set Transfer Set (DSTS) reporting.

It is the server the [`client`](../client) and [`explorer`](../explorer)
examples connect to, and the peer used in the integration tests.

It serves **multiple clients concurrently** via `Endpoint.ServeClients`, which
accepts each incoming association, hands it a fresh endpoint, and runs a
per-connection `Server` (over one shared `DataModel`) in its own goroutine. Any
number of clients/explorers can connect at the same time. The background
simulation pushes updates through `DataModel.UpdateOnlineValueTS` so every
connected client sees them, and each client gets its own independent
transfer-set reporting.

## Run

```bash
tase2-server                 # listen on the standard port 102
tase2-server --port 10222    # listen on a non-privileged port
tase2-server --password test # require ACSE password authentication
tase2-server --num 10        # smaller model (10 points per type)
```

> Port **102** is the registered ISO-on-TCP / MMS port and is privileged: binding
> it needs root (`sudo`) or `CAP_NET_BIND_SERVICE`. Use `--port` with a high port
> to run and test without elevated privileges.

### Flags

| Flag | Default | Description |
|------|---------|-------------|
| `--port` | `102` | TCP port to listen on. |
| `--password` | `""` | If non-empty, every incoming association must present this ACSE authentication password; otherwise it is rejected with `authentication-failure`. Empty disables authentication. |
| `--num` | `100` | Number of instances created for each point type (12 indication types + 3 control types). |
| `--log-level` | `debug` | Log level: `silent`, `error`, `info`, `debug`. |

## What it exposes

- **Identity** - AP title `1.1.999.1` / AE qualifier `12`; vendor `TASE.2 Go
  Library`, model `Reference Server`, revision `1.0`. Conformance blocks
  CBB1 (basic periodic data), CBB2 (extended data sets), CBB5 (device control).
- **Domain `SUB_A`** with `--num` instances (default 100, named `_01..NN`) of
  each of **12 indication-point types** and **3 control-point types**:
  - Plain scalar indication points `State_NN`, `Discrete_NN`, `Real_NN`.
  - ICCP indication points (created via `AddDataPoint`): `ICCP_StateQ_NN`,
    `ICCP_RealQ_NN`, `ICCP_DiscreteQ_NN`, `ICCP_StateQTime_NN`,
    `ICCP_RealQTime_NN`, `ICCP_DiscreteQTime_NN`, `ICCP_StateExt_NN`,
    `ICCP_RealExt_NN`, `ICCP_DiscreteExt_NN`.
  - Control points `Command_NN` (cycling Direct / SBO / SBO-Enhanced device
    classes), `Setpoint_NN`, `Parameter_NN`.
- **DataSet `Sample_DataSet`** (VMD-scope): `{State_01, Discrete_01, Real_01,
  Real_02}`.
- **DSTransferSet `SUB_A/DSTrans`** pre-attached to `Sample_DataSet`, plus the
  conventional `Next_DSTransfer_Set` pointer.
- **Bilateral table** `BLT_CLIENT_1` admitting the client identity
  `1.1.999.2` / AE `12` to domain `SUB_A`.

A background simulation updates the indication points in batches every 2 seconds
(states flip, discretes random-walk, reals follow a sine wave, Extended types
bump their COV) and cycles quality through `good` -> `questionable` -> `invalid`,
so reads and reports show live, changing data.

## DSTransferSet reporting

When a client activates `SUB_A/DSTrans` (write its config fields then
`Status = true`), the server honors the configured flags:

- **Interval** + `DSConditionInterval` → periodic reports.
- **IntegrityCheck** + `DSConditionIntegrity` → full-snapshot reports.
- **RBE** + `DSConditionChange` → report only changed objects on change.
- **BufferTime** → batch change reports over a time window.
- **AllChangesReported** → report every intermediate change vs. only the latest.

## Connecting a client

The default identities already line up with the example client/explorer: the
server's local AP (`1.1.999.1`) is the client's `--remote-ap`, and the client's
local AP (`1.1.999.2`) is the identity the bilateral table admits. If you start
the server with `--password`, pass the same `--password` to the client/explorer.

See the [client](../client) and [explorer](../explorer) examples.
