Register

Prerequisites

  1. An OAuth 2.0 client
  2. A client access token

Overview

This API enables PBX/TAS (Private Branch Exchange/Telephony Application Server) providers to plug their (SIP-enabled) endpoint into the call path.

It enables a SIP integration between the platform core and a PBX/TAS for a given MSISDN.

Virtual SIP Registrations are used to alter default call behavior and involve PBX/TAS into the SIP signaling path. When using user tokens the registration created per single MSISDN linked to the OAuth 2.0 round trip, while when using client tokens the registration is created for the provided MSISDN in the request.

Required Scope

  • call.routing:write

The API

The API is implemented as a gRPC service described below.

There are two methods supported by this API:

  • UpsertRegistration
  • DeleteRegistration

To register a (PBX/TAS-bound) MSISDN with our core, use UpsertRegistration. The same method is used if you want to update an existing registration.

Use DeleteRegistration when an existing registration is no longer needed.

Messages

Both methods receive RegistrationRequest and return RegistrationResponse message.

  • RegistrationRequest is a structure containing the URI of the endpoint you host + some additional details related to the connected MSISDN.
  • RegistrationResponse is a simple structure conveying the status of method invocation (success/error)

See Sipbreakout API reference for more details.

Registration types

There are three types of registrations: Fork, Loop and Fallback. It is the registration type that decides how the calls will be handled by our core.

Fork/Loop

If a registration of one of these types is registered on an MSISDN, all the SIP signalling from/to that MSISDN will be replicated to the endpoint specified in the registration.

Loop vs Fork

  • Loop: leg 4 is created only after the call comes back as leg 3

    Please note that PBX/TAS is not obliged to create leg 3 as it can answer or reject leg 2 directly.

    Please note the following requirements for the SIP INVITE sent by the PBX/TAS on leg 3:

    • The Session-ID header must be propagated unchanged from leg 2 to leg 3.
    • The Max-Forwards header must be decremented and propagated from leg 2 to leg 3 as specified by RFC 2543.
  • Fork: legs 2 and 3 are created simultaneously.

    Typically, you use Fork/Loop to implement your logic during a call.

Loop MO/MT

For better control of the Loop logic, 2 subtypes of LOOP route type exists:

  • ROUTE_TYPE_LOOP_MO: Will loop a call only if direction of the call is mobile originating (outgoing call). This means any MT calls for a registration with this route type would not be looped to the sip uri in the registration. The use case for using this type would be for example: Call Center for outgoing calls

  • ROUTE_TYPE_LOOP_MT: Will loop a call only if direction of the call is mobile terminating (incoming call). This means any MO calls for a registration with this route type would not be looped to the sip uri in the registration. The use case for using this type would be for example: Business Phone Systems with BYOD policy (route incoming business calls to personal user devices)

INGRESS

ROUTE_TYPE_INGRESS allows PBX/TAS to place calls to MSISDN attached to the registration of that type. Regular calls to/from that MSISDN are not affected otherwise.

Fallback

The core will action upon a Fallback registration if and only if:

  • somebody calls the related MSISDN
  • the MSISDN is either busy or no answer detected within the timeout (30s)

In such case, the core will replicate the INVITE to the endpoint specified during the registration.

Typically, you use Fallback to implement the likes of voice mail, call forwarding etc.

Code Dependencies

<dependency>
  <groupId>com.wgtwo.api.v1.grpc</groupId>
  <artifactId>sipbreakout</artifactId>
  <version>1.10.1</version>
</dependency>

Code

If targeting production, you would need to add authentication to the sample code.


#!/usr/bin/env bash
grpcurl \
  -d '
  {
      "registration": {
          "mobileOriginatingPrefix": "11",
          "mobileTerminatingPrefix": "22",
          "sipUri": "sips:example.com:8888",
          "routeType": "ROUTE_TYPE_LOOP",
          "phoneNumber": {
            "e164": "+4799990000"
          }
      }
  }
  ' \
  sandbox.api.shamrock.wgtwo.com:443 \
  wgtwo.sipbreakout.v1.SipBreakoutService/UpsertRegistration

package com.example.sipbreakout

import com.wgtwo.api.v1.common.e164
import com.wgtwo.api.v1.sipbreakout.DeleteRegistrationRequest
import com.wgtwo.api.v1.sipbreakout.Registration
import com.wgtwo.api.v1.sipbreakout.RouteType
import com.wgtwo.api.v1.sipbreakout.SipBreakoutServiceGrpc
import com.wgtwo.api.v1.sipbreakout.UpsertRegistrationRequest
import io.grpc.ManagedChannelBuilder

fun main() {
    val channel = ManagedChannelBuilder.forAddress("sandbox.api.shamrock.wgtwo.com", 443).build()
    val stub = SipBreakoutServiceGrpc.newBlockingStub(channel)
    val registration = Registration.newBuilder().apply {
        sipUri = "sips:example.com:8888"
        mobileOriginatingPrefix = "11"
        mobileTerminatingPrefix = "22"
        routeType = RouteType.ROUTE_TYPE_LOOP
        phoneNumber = e164 {
            e164 = "+99991111"
        }
    }.build()

    val upsertRequest = UpsertRegistrationRequest.newBuilder()
        .setRegistration(registration)
        .build()
    println("upsert request:
$upsertRequest")
    val upsertResponse = stub.upsertRegistration(upsertRequest)
    println("upsert response:
$upsertResponse")

    val deleteRequest = DeleteRegistrationRequest.newBuilder()
        .setRegistration(registration)
        .build()
    println("delete request:
$deleteRequest")
    val deleteResponse = stub.deleteRegistration(deleteRequest)
    println("delete response:
$deleteResponse")
}

NOTE: If you want to use SRV DNS records, use the domain name without port number in sipUri, then make sure you have SRV records for _sip._tcp.yourdomain.com and _sips._tcp.yourdomain.com defined.

Example Results

Success

{
  "statusCode": "STATUS_CODE_OK"
}
status_code: STATUS_CODE_OK

Error

{
  "statusCode": "STATUS_CODE_NOT_ACCEPTABLE",
  "errorMessage": "Secure SIP domain name required"
}
statusCode: STATUS_CODE_NOT_ACCEPTABLE
errorMessage: Secure SIP domain name required

Read More