Using Relay Mesh

Learn how to implement the optional Relay Mesh REST API for custom integration use cases.
Table of Contents

Introduction

Blue Jeans Relay Mesh is an integration mechanism for the on-premise component of the Blue Jeans Relay ecosystem. For most common hardware Endpoints, the Listener Service executes commands using a Control Protocol native to the Endpoint type, and Relay Mesh is not needed. For unusual Endpoints and for atypical use cases where a greater level of local control is required, however, Relay Mesh is available in place of using an Endpoint native Control Protocol.

Relay Mesh is implemented as a REST service, but instead of a client making REST calls to a Blue Jeans service, instead the Listener Service will make REST calls outbound to a REST service implemented by the integrator. These REST calls are made in place of native hardware Endpoint commands, and it is left to the implementer to decide what the end result of receiving the calls should be.

Configuring Endpoints to use Relay Mesh

To use Mesh for an Endpoint instead of a native Control Protocol, first select the Control Protocol “Relay Mesh.” Once you select “Relay Mesh” a new text field will appear called “Mesh Base URI.” This is the URI for your implementation of the Mesh REST service. It must be reachable from your Listener Service. Using https instead of http is strongly encouraged so that credentials are protected on the network.

By varying the Mesh Base URI, it is possible to host different control strategies on the same server if desired. For example, https://MyRestService.mycompany/mesh/Ryberg1000 and https://MyRestService.mycompany/mesh/Volterator could be used as Base URIs for different REST implementations that understand how to control Ryberg1000 and Volterator Endpoint types respectively.

It is also possible to make decisions internally about how to control Endpoints based on the payloads and query params of the requests. (See below.)

The hostname remains the hostname of the Endpoint (not the Mesh service) and the username and password are similarly those for the Endpoint. The credentials will be passed to the Mesh Base URI via Basic Auth.

Implementing the Mesh API

For a fully-functional sample Mesh server, see bluejeans/relay-mesh-tandberg-1000-classic. You can examine the code to learn about the Mesh protocol by example and use it as a starting point for implementing your own Mesh server.

REST calls are made from the Listener Service using POST or GET. For POST methods, the payload is a JSON representation of the Endpoint object (see our API Documentation for Endpoints). An API version is provided in the X-bjn-mesh-version header. The ID for the resource in the request is the Endpoint’s hostname. In the above example, the REST calls will all begin with https://MyRestService.mycompany/mesh/10.0.2.33. Do not append the hostname to the URI yourself; the Listener Service will do this for you.

When credentials are wrong, return a 403 status code. If calls are successful, return a 2xx family status. For error conditions, return a 500-level status with a meaningful message in the payload (which will be logged by the Listener Service for your inspection).

It is strongly encouraged when using JSON parsers to ignore unknown attributes, as new fields may be added to Endpoint objects in the future.

All of the REST methods should be implemented for a correctly-functioning Relay Mesh deployment. If you cannot implement some of the methods, make sure your capabilities method reflects this.

Capabilities Method

This method lets Relay know which methods and features your Endpoint supports, so user interfaces can hide the buttons of unsupported functions.

The full list of capabilities is shown in the following example.

GET /10.0.2.33/capabilities?port=443&name=Interocitor&customData.intensifier=11 HTTP/1.1 X-bjn-mesh-version: 1 Authorization: Basic c3dvcmRmaXNoOnR4YnVyb2Nrcw== HTTP/1.1 200 OK Content-Type: application/json { "JOIN": true, "HANGUP": true, "STATUS": true, "MUTE_MICROPHONE": true, "CALENDAR_PUSH": true, "PAIRING_CODE_PUSH": true, "CONTACT_LIST_PUSH": true }

(Endpoint entity documentation)

The Endpoint’s port (if specified) and name are included as query params. In addition, if you have specified any custom data associated to the Endpoint, those key-value pairs are included as query params. The expected response is a JSON object with boolean key-value pairs for each of the capabilities, where the key is the capability name and the value is true if your Mesh server and Endpoint support the given capability, and false otherwise. If a capability is omitted from the response, Relay will assume that the capability is unsupported.

Status Method

This method indicates whether the Endpoint is currently engaged in a call and if its microphone is muted. It will be called periodically by the Listener Service, and it will also be called prior to executing a join.

GET /10.0.2.33/status?port=443&name=Interocitor&customData.intensifier=11 HTTP/1.1 X-bjn-mesh-version: 1 Authorization: Basic c3dvcmRmaXNoOnR4YnVyb2Nrcw== HTTP/1.1 200 OK Content-Type: application/json { "callActive": true, "microphoneMuted": false }

(Endpoint entity documentation)

The Endpoint’s port (if specified) and name are included as query params. In addition, if you have specified any custom data associated to the Endpoint, those key-value pairs are included as query params. The expected response is a small JSON object with scalar values for callActive and microphoneMuted, each with the value true or false.

Join Method

Join is called when an Endpoint should be made to dial either the IVR or a specific meeting with or without a passcode. The dialString and bridgeAddress query params are always present. meetingId and passcode are present only when they are used (both will be absent when a call is being sent to the IVR).

POST /10.0.2.33/join?dialString=111.0000@bjn.vc&meetingId=111&passcode=0000&bridgeAddress=bjn.vc HTTP/1.1 X-bjn-mesh-version: 1 Authorization: Basic c3dvcmRmaXNoOnR4YnVyb2Nrcw== Content-Type: application/json { "name": "Interocitor", "hostname": "10.0.2.33", "listenerServiceId": "527ca8e2776a7e02dd2e15fe", "controlProtocol": "MESH", "port": null, "signalingProtocol": null, "dialStyle": null, "addressStyle": null, "calendarId": null, "calendarType": null }HTTP/1.1 200 OK

(Endpoint entity documentation)

In this example, the Endpoint with the hostname 10.0.2.33 should be controlled to join a meeting using the dial string 111.0000@bjn.vc. Additionally, the meeting ID and passcode are provided (111 and 0000 respectively) and the bridge address is provided separately as bjn.vc. The Endpoint entity is JSON encoded and provided in the payload, and the Basic auth for the Endpoint is included in the HTTP headers.

Once an Endpoint has successfully been instructed to join a call, return a 2xx-family status; or, if the Endpoint produces an error, return an error status (e.g., 403 if the credentials presented fail authentication, 503 if the Endpoint returns an unrecoverable error, etc).

The service should return a status code after the necessary instructions have been delivered. It should not wait for the call to actually be completed. Call completion will be determined by subsequent calls to status.

Mute/Unmute Microphone Methods

These methods are called when an Endpoint should mute or unmute its microphone.

The URL path will end with /mutemicrophone if the Endpoint should mute, and /unmutemicrophone if it should unmute.

As with join, return the appropriate status code after the instructions have been delivered to the Endpoint. If the Endpoint is already in the desired mute state such that the Endpoint returns an error, still return a 2xx-family status. Return a 403 for authentication failures and a 5xx family status for other Endpoint communication errors.

POST /10.0.2.33/mutemicrophone HTTP/1.1 X-bjn-mesh-version: 1 Authorization: Basic c3dvcmRmaXNoOnR4YnVyb2Nrcw== Content-Type: application/json { "name": "Interocitor", "hostname": "10.0.2.33", "listenerServiceId": "527ca8e2776a7e02dd2e15fe", "controlProtocol": "MESH", "port": null, "signalingProtocol": null, "dialStyle": null, "addressStyle": null, "calendarId": null, "calendarType": null }HTTP/1.1 200 OK

(Endpoint entity documentation)

Hangup Method

This method is called when an Endpoint should disconnect from the current call. Relay generally prefers a "hangup all" hangup to hanging up a particular call instance.

As with join, return the appropriate status code after the instructions have been delivered to the Endpoint. Hangup completion will be determined by subsequent requests to status. If the Endpoint is already hung up such that the Endpoint returns an error, still return a 2xx-family status. Return a 403 for authentication failures and a 5xx family status for other Endpoint communication errors.

POST /10.0.2.33/hangup HTTP/1.1 X-bjn-mesh-version: 1 Authorization: Basic c3dvcmRmaXNoOnR4YnVyb2Nrcw== Content-Type: application/json { "name": "Interocitor", "hostname": "10.0.2.33", "listenerServiceId": "527ca8e2776a7e02dd2e15fe", "controlProtocol": "MESH", "port": null, "signalingProtocol": null, "dialStyle": null, "addressStyle": null, "calendarId": null, "calendarType": null }HTTP/1.1 200 OK

(Endpoint entity documentation)

Meetings Method

This method is called when the list of meetings for an Endpoint has changed, in response to changes to the Endpoint configuration, and at regular intervals, if Calendar Push has been enabled in the Endpoint configuration in Relay.

As with other methods, return a 2xx response if the meeting push was understood. Return a 403 for authentication failures and a 5xx family status for other errors.

PUT /10.0.2.33/meetings HTTP/1.1 X-bjn-mesh-version: 1 Authorization: Basic c3dvcmRmaXNoOnR4YnVyb2Nrcw== Content-Type: application/json { "endpoint": { "id": "53a37bbce4b048c61532bcfa", "name": "Interocitor", "hostname": "10.0.2.33", "port": null, "listenerServiceId": "527ca8e2776a7e02dd2e15fe", "controlProtocol": "MESH", "port": null, "signalingProtocol": null, "dialStyle": null, "addressStyle": null, "calendarId": null, "calendarType": null }, "meetings": [ { "calendarEventId": "b2zrh447acz9usr1sww964ah94", "calendarType": null, "meetingId": "111", "passcode": "0000", "title": "Discuss Handbags", "description": null, "organizer": "Interocitor", "startTime": 1446080400000, "endTime": 1446084000000, "endpointIds": [ "53a37bbce4b048c61532bcfa" ], "cluster": null, "meetingType": "MEETME", "meetingVisibility": "VISIBLE", "id": "56316c08e4b049ebe8dabaa8" } ] }HTTP/1.1 200 OK

(Endpoint entity documentation, Meeting entity documentation)