---
id: messaging--ussd-server
title: "Ussd server"
summary: "Implements a USSD application over SMPP: receives USSD requests from the SMSC/USSD gateway, emits them to the flow, and sends back the response messages the flow produces. Use it to build USSD menus (e.g. `*123#`)."
audience: user
keywords: "start, request, response, host, localendpointip, port, addressrange, systemid, password, systemtype, enquirelinkinterval, generaltimeout, sourceaddressnpi, sourceaddresston, destinationaddressnpi, destinationaddresston, datacodingtype"
---
# Ussd server

Implements a USSD application over SMPP: receives USSD requests from the SMSC/USSD gateway, emits them to the flow, and sends back the response messages the flow produces. Use it to build USSD menus (e.g. `*123#`).

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Start | start | - | Opens the SMPP session. Called by the system when the flow starts if it is not connected. |
| Request | output | `Viaducta.Plugins.Smpp.Types.UssdMessage` | One message per incoming USSD request. |
| Response | input | `Viaducta.Plugins.Smpp.Types.UssdMessage` | Connect the component that produces the answer; every message received here is sent to the gateway. |

`UssdMessage`: `Operation` (USSD service operation, int), `MessageText`, `Sender`, `Receiver`.

`Operation` values: `0` PSSD_INDICATION, `1` PSSR_INDICATION, `2` USSR_REQUEST, `3` USSN_REQUEST, `16` PSSD_RESPONSE, `17` PSSR_RESPONSE, `18` USSR_CONFIRM, `19` USSN_CONFIRM, `34` USER_EXIT.

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `Host` | string (required) | `localhost` | SMSC / USSD gateway host. |
| `LocalEndpointIp` | string | `Any` | Local IP to bind the socket to. |
| `Port` | integer 1-65535 | `10000` | Gateway port. |
| `AddressRange` | string, max 41 chars | empty | ESME address range (e.g. the service code). |
| `SystemId` | string, max 32 chars | empty | SMPP `system_id`. |
| `Password` | password | empty | SMPP password. |
| `SystemType` | string | `ESME` | SMPP `system_type`. |
| `EnquireLinkInterval` | integer seconds, max 60 | `5` | Keep-alive interval. |
| `GeneralTimeout` | integer seconds, max 300 | `5` | Response timeout. |
| `SourceAddressNpi` | dropdown: `0` Unknown, `1` ISDN, `3` Data, `4` Telex, `6` LandMobile, `8` National, `9` Private, `10` ERMES, `14` Internet | `8` | Numbering plan of the response `Sender`. |
| `SourceAddressTon` | dropdown: `0` Unknown, `1` International, `2` National, `3` NetworkSpecific, `4` SubscriberNumber, `5` Alphanumeric, `6` Abbreviated | `3` | Type of number of the response `Sender`. |
| `DestinationAddressNpi` | dropdown, as `SourceAddressNpi` | `1` | Numbering plan of the response `Receiver`. |
| `DestinationAddressTon` | dropdown, as `SourceAddressTon` | `1` | Type of number of the response `Receiver`. |
| `DataCodingType` | dropdown: `0` SMSCDefault, `1` IA5_ASCII, `3` Latin1, `8` UCS2, ... (same list as Sms transmitter) | `0` | Encoding of the response text. |

## Behaviour

- On `Start` the plugin binds as transceiver with SMPP 3.4 and starts reading; the flow keeps running.
- Each incoming `deliver_sm` / `data_sm` becomes a `UssdMessage` (`Operation` from the `ussd_service_op` parameter, `0` if missing) with new metadata on `Request`.
- Every message arriving on `Response` is sent as `submit_sm` with service type `USSD` and `ussd_service_op` = `Operation`. A rejected submit is logged as an error.

## Notes

- There is no session handling: build the response yourself. Swap the addresses (`Receiver` = request `Sender`, `Sender` = request `Receiver`) and choose the operation: typically `17` (PSSR_RESPONSE) to answer and end, `2` (USSR_REQUEST) to show a menu and wait for the next input. Keep menu state yourself (e.g. keyed by the subscriber number).
- Messages sent to `Response` before the session is open fail.
- Errors in the read loop and in downstream components are swallowed silently.
- Ports above 32767 are not handled correctly (converted to a 16-bit signed number).
- Use an expression setting (`=Secrets.UssdPassword`) for `Password`.

## Example

```json
{ "Host": "ussdgw.example.com", "Port": 2775, "SystemId": "ussdapp", "Password": "=Secrets.UssdPassword", "AddressRange": "\\*123#", "DataCodingType": 0 }
```

**Ussd server** (Request) → C# script (build menu, swap addresses, `Operation` = 2 or 17) → **Ussd server** (Response)
