Skip to content

DIDWW phone.systems integration

Yeti-Switch can be used as a front-end for the DIDWW phone.systems cloud PBX platform. In this scenario one Yeti installation covers three roles at once:

  • Interconnection SBC - all calls between the carriers and the customer's cloud PBX traverse Yeti, so the operator keeps a single point for media handling, number translations, CLI policies, capacity control and CDR collection.
  • Billing system - the PBX seat itself is charged as a Service, while the traffic is rated by the usual Yeti rateplans and rates.
  • Provisioning system - when the Service is created, Yeti calls the phone.systems Operator API and builds the whole customer configuration on the PBX side: customer, incoming trunk, termination gateway and termination route. When the Service is deleted, everything is removed again.

The integration is multitenant: the relation is always one Service - one phone.systems account, so a single Yeti installation provisions accounts of different customers as well as several accounts of the same customer, for example a separate PBX per branch office or department. Every Service gets its own phone.systems customer, incoming trunk, gateway and route, and its own gateway on the Yeti side.

This document explains how to configure such an integration.

Architecture

Call flows after provisioning:

  • Inbound (PSTN --> Yeti --> PBX) - a carrier delivers a call for the customer's DID number to Yeti. Yeti authenticates and rates it as usual, and the routing sends the call to the Yeti Gateway that points to the customer's incoming trunk domain on phone.systems.
  • Outbound (PBX --> Yeti --> PSTN) - phone.systems sends the call from the customer's termination gateway to Yeti. Yeti authenticates it with a Customer Auth object and routes it to the carriers according to the routing plan.

Prerequisites

This part is out of scope of this document, you have to complete these steps yourself:

  1. An operator account on phone.systems with the Operator API enabled. See https://doc.telecom.center/introduction.html.
  2. Operator API credentials (HTTP Basic username/password) and the API endpoint, for example https://api.telecom.center for production or https://api.sandbox.telecom.center for sandbox.
  3. A working Yeti installation reachable by phone.systems for outbound calls (public SIP signalling address, and RTP addresses opened for the phone.systems media subnets).
  4. At least one Codec Group created in Yeti - the provisioner assigns a codec group to the gateway it creates automatically.

Service Type configuration

Create a Service Type with Provisioning Class set to Billing::Provisioning::PhoneSystems. The Operator API credentials and the default customer attributes are stored in its Variables field as JSON:

{
  "endpoint": "https://api.telecom.center",
  "username": "operator_api_user",
  "password": "operator_api_password",
  "attributes": {
    "name": "Default customer name",
    "language": "EN",
    "trm_mode": "operator_customer",
    "capacity_limit": 100,
    "sip_account_limit": 50
  }
}
endpoint

Required. Base URL of the phone.systems Operator API. Trailing slash is stripped automatically.

username, password

Required. HTTP Basic credentials of the Operator API.

attributes

Required. Default attributes of the customer object on the phone.systems side.

name
Required. Customer name shown in the phone.systems UI.
language
Language of the phone.systems UI: EN, RU, LT or LV.
trm_mode
Outbound call handling mode of the customer, it defines which termination gateways and routes are available to the customer: customer or operator_customer.
capacity_limit
Maximum number of simultaneous calls of the customer.
sip_account_limit
Maximum number of SIP accounts the customer may create.

WARNING

The Service Type variables are validated when the Service Type is saved. Invalid or incomplete JSON is rejected with a validation error, so an invalid configuration can not be stored.

You may also put the trunk and gateway templates (ps_incoming_trunk, ps_trm_gw, described below) into the Service Type variables - they will be used as defaults for every Service of this type.

Set the UI Type field of the Service Type to phone_systems so that your customers can open their PBX from the Customer Portal, see Customer Portal integration below.

Service configuration

Create a Service on the customer's Account and select the Service Type created above. Service Variables define the per-customer part of the configuration:

{
  "attributes": {
    "name": "ACME Ltd",
    "language": "EN",
    "trm_mode": "operator_customer",
    "capacity_limit": 10,
    "sip_account_limit": 5
  },
  "ps_incoming_trunk": {
    "transport_protocol": "UDP",
    "codecs": ["PCMA", "PCMU", "g729", "telephone-event"],
    "destination_field": "RURI_USERPART"
  },
  "ps_trm_gw": {
    "host": "sip.example.com",
    "port": 5060,
    "authorization_name": "acme_ltd",
    "authorization_password": "secret_password",
    "codecs": ["PCMA", "PCMU", "g729", "telephone-event"]
  }
}
attributes

Required. Attributes of the customer created on the phone.systems side. Only name is mandatory. These values are sent as-is, the Service Type attributes are not merged into them - always specify the full set of attributes you need here.

ps_incoming_trunk

Attributes of the incoming trunk created on the phone.systems side. The trunk name is generated by Yeti and can not be overridden.

transport_protocol
UDP or TCP. Defaults to UDP.
codecs
Allowed codecs: g729, G722, GSM, PCMA, PCMU, OPUS, telephone-event.
destination_field
Defines where phone.systems takes the called DID number from: RURI_USERPART (default) or TO_USERPART. It must match the way Yeti sends the number to the trunk.
ps_trm_gw

Attributes of the termination gateway created on the phone.systems side, this is the gateway the customer PBX uses to send calls to Yeti. The gateway name is generated by Yeti and can not be overridden. Useful attributes are host, port, codecs, authorization_name, authorization_password, network_protocol and the number rewrite rules (src_rewrite_rule/src_rewrite_result, dst_rewrite_rule/dst_rewrite_result).

WARNING

Always define ps_trm_gw explicitly. If it is omitted, the provisioner falls back to host: sip.yeti-switch.org with a randomly generated authorization_name/authorization_password pair. Those random credentials are stored only on the phone.systems side, so you will not be able to set the matching incoming auth credentials on the Yeti gateway and outbound calls of this customer will fail authentication.

The authorization_name also has to be unique across the whole Yeti installation - Yeti identifies the calling gateway by the SIP authentication username, so two services sharing one authorization_name make the outbound authentication ambiguous.

endpoint, username, password

Optional. Override the Operator API connection settings of the Service Type for this particular Service.

Provisioning workflow

Everything happens synchronously while the Service is being saved, so any API error is reported right in the Yeti web interface and the Service is not created.

  1. Customer is created on phone.systems with the attributes from the Service variables. The Service id in Yeti and the customer id on phone.systems are kept identical.

  2. Incoming trunk named gw-<service UUID> is created and linked to the customer. phone.systems generates a unique domain for it, this domain is where Yeti has to send inbound calls.

  3. Termination gateway named gw-<service UUID> is created and linked to the customer - this is how the PBX reaches Yeti.

  4. Yeti Gateway named ps-<service id> is created with:

    • Host - the incoming trunk domain returned in step 2
    • Contractor - the contractor that owns the Service Account
    • Enabled - yes
    • Codec Group - the first codec group found in the database

    WARNING

    The codec group is picked automatically and is not configurable. Review the created gateway and adjust the codec group, transport, capacity and other parameters to match the codec set you configured in ps_incoming_trunk.

  5. Termination route named gw-<service UUID> is created on phone.systems, linking the customer to the termination gateway from step 3.

Deprovisioning

Deleting the Service deletes the customer on phone.systems, and the incoming trunk, termination gateway and termination route are removed together with it as dependent objects. The Yeti gateway ps-<service id> is deleted as well.

INFO

If the customer no longer exists on the phone.systems side, the web interface shows the warning "The Customer already deleted from the Phone Systems server" and deletes the Yeti Service anyway.

Yeti-side configuration

The provisioner creates the gateway only. The routing and authentication objects around it are not generated automatically and have to be configured by the operator.

Outbound calls from the PBX

The credentials the PBX uses to authenticate on Yeti are stored on the Gateway object, not on the Customer Auth. On the ps-<service id> gateway set:

Incoming Auth Username, Incoming Auth Password
The authorization_name and authorization_password values from ps_trm_gw - the same credentials that were provisioned into the customer's termination gateway on the phone.systems side.

WARNING

The provisioner does not populate these two fields, it only creates the gateway with the name, contractor, host and codec group. Fill them in manually after the Service is created, otherwise the Customer Auth below can not be saved with Require Incoming Auth enabled.

Then create a Customer Auth for the customer with:

Gateway
The ps-<service id> gateway - its incoming auth credentials are the ones Yeti will validate.
Require Incoming Auth
Should be YES so that Yeti challenges the calls coming from the PBX. Alternatively leave it NO and authenticate by the phone.systems signalling IP addresses instead.
Account
The Account the Service belongs to, so both the PBX seat fee and the outbound traffic are charged to the same account.
Routing Plan, Rateplan
As usual - they define the destinations available to this customer and their prices.

Inbound calls to the PBX

Route the customer's DID numbers to the ps-<service id> gateway by creating a Dialpeer per DID number or per number range, with this gateway and the Prefix matching the DID. The dialpeer has to be reachable from the routing plan used by the originating carrier's Customer Auth.

Make sure the number format Yeti sends matches the destination_field setting of the incoming trunk - with the default RURI_USERPART phone.systems looks the DID up in the R-URI user part. Use numbers translations on the gateway if the carrier delivers the number in a different format.

DID numbers on the phone.systems side

Provisioning of the DID numbers into the customer's phone.systems account is a separate operation. The numbers are pushed with the Operator API call POST /api/rest/public/operator/available_did_numbers, where the number attribute holds the DID and the customer relationship holds the id of the customer created by the provisioner - which is the same value as the Yeti Service id.

WARNING

The Billing::Provisioning::PhoneSystems provisioner itself does not create DID numbers - it only creates the customer, the trunks and the routes. Add the numbers to the customer either from the phone.systems operator UI or with your own Operator API integration, and route them in Yeti as described above.

Once the number is present in the customer's account, the customer assigns it to a call flow, SIP account or ring group in the phone.systems UI.

Customer Portal integration

The Customer Portal is the single place where your customer works with the service. There they see everything Yeti holds about them - CDRs and CDR exports, invoices, payments and transactions, origination and termination statistics, active calls, rates and rateplans - and from the same portal they open their phone.systems account, without a separate phone.systems login and password.

To enable this, set the UI Type field of the Service Type to phone_systems:

phone_systems

WARNING

The value must be exactly phone_systems. With any other value, or with an empty UI Type, the service is listed in the Customer Portal as a regular service and the sign-in button is not displayed.

After that, on the Services page of the Customer Portal every service of this type gets a Sign in button in the Actions column, with the "redirect to phone.systems" tooltip. Clicking it signs the customer in to the phone.systems account that was provisioned for this particular service, and opens the phone.systems UI in a new browser tab. From there the customer manages their own PBX: SIP accounts, call flows, ring groups, voicemail and the DID numbers you provisioned into their account.

The sign-in works per service, so a customer that has several PBX services sees a separate button for each of them, each one leading to its own phone.systems account. A customer can only sign in to the services of their own accounts.

Troubleshooting

  • Provisioning errors returned by the Operator API are shown as a validation error of the Service in the web interface, with the detail field of the API error as the message. The Service is not created in that case.
  • Every provisioning request is written to the Yeti web application log, so failed payloads can be inspected there.
  • A Service can not be created if its Service Type variables do not pass validation - check endpoint, username, password and attributes.name first.
  • If inbound calls fail on the phone.systems side while Yeti reports the call as answered by the gateway, verify that the number Yeti sends matches the trunk destination_field and that the DID number is added and enabled in the customer's phone.systems account.