AppWebsocket

The AppWebsocket protocol is the base protocol for all app-related communication. It is used for websocket connections

It provides the following services:

Table of content

Basic message format

{
    "mt": string,
    "api": string,
    "src": string
}

The base message format consists of the three properties mt, api and src.

mt
The type of the message. These types are defined seperatly for each api if the service uses different api. For the base protocol of an service the api property is not used, in this case the definition of mt is done by the service, with the exception that there are some reserved values for mt for the AppWebsocket protocol itself (see below).
api
Used to address an specific api within an AppWebsocket session. A service (e.g. Messages), defines its own mt values, but on the same AppWebsocket connection also a standard protocol like PbxSignal shall be used. The messages related to this protocol are then marked with an api property of PbxSignal.
src
This property is used for the src mechanism. An AppWebsocket protocol has typically a server and a client side. The client sends requests and the server responds to these requests. If the client sets the src property in a request, server echoes back the src property in the responses to the request.
Another mechanism often used is the the client subscribes to some information with a request. To ackknowedge the subscription a response is sent with the same src property. When the subscription is active indication messages are sent from the server containing subscribed information. All these indication messages use the same src as the subscription message.
The Javascript AppWebsocket library supports the src mechanism to allow object local handling of specific responses or indications.

AppWebsocket Messages

Objects - recurring definitions

Message Flow

This sample message flow shows an example of a websocket connection to an app object on the PBX.

The app object assumed to have following sample configuration:

In the example following operations are performed:



AppWebsocket Login Sequence Diagramm

AppChallenge

{
    "mt": "AppChallenge"
}

With this message the client requests a challenge for the login. The challenge is a random string which is included in the digest calculation of the login together with shared secret (password) and other parameters. With this mechanism an an adequately random string, replay attacks are not possible.

AppChallengeResult

{
    "mt": "AppChallengeResult",
    "challenge": string
}

Returns the challenge to the client.

challenge
A random string with a maximum of 16 characters. Only non-control character with a single byte representation in UTF-8 shall be used. Innovaphone implementations only use 0-9.

AppLogin

{
    "mt": "AppLogin",
    "app": string,
    "domain": string,
    "sip": string,
    "guid": hexstring,
    "dn": string,
    "digest": hexstring,
    "pbxObj": string,
    "info": Info
}

The login message, which contains parameters, which are included in the digest calculation, so that they cannot be changed by an intermediate system.

app
The service as it is uniquely identified on the server system. For Apps communicating with their App Service, the name of the initially loaded HTML file (without the .htm file extension) is used. The App Service can use this property to define which operations are allowed on this session. This way by granting access to a given App to a user on the PBX, the user can only access what is defined for this App.
In case the login is done to a PBX API, which is assigned to an App Object, this property should contain the Name of the App object. The properties 'domain', 'sip', 'guid' or 'dn' need not to be set in this case.
domain
The domain of the logged in user, if available
sip
The sip user part of the logged in user, if available
guid
The GUID of the user, if available
dn
The display name of the user, if available
digest

The digest calculated to verify the knowledge of the shared secret. It is calculated as SHA256 hash over the string:

<app>:<domain>:<sip>:<guid>:<dn>:<info>:<challenge>:<password>

In case no Info parameter is provided as part of the AppLogin message the string for hash calculation should be following:

<app>:<domain>:<sip>:<guid>:<dn>:<challenge>:<password>

Following examples can be used as test vectors for your implementation of the digest calculation.

Example 1:
Password on the "pbxadminapi" app object is "pwd". No info object is provided.

{
    "app": "pbxadminapi",
    "digest": "a205299ed2ef2786c311e0be1b14db343f2cadd906a6ae7b564eee34bda5e9a1",
    "dn": "",
    "domain": "",
    "guid": "",
    "mt": "AppLogin",
    "sip": ""
}
String for digest calculation:
pbxadminapi:::::0123456789abcdef:pwd

Example 2:
Password on the "pbxadminapi" app object is "pwd". An empty info object is provided.

{
    "app": "pbxadminapi",
    "digest": "57b23fe824b9222a7ac879597cb509bcdc865a1bfeb057d9d12118cef0c3ba34",
    "dn": "",
    "domain": "",
    "guid": "",
    "info": {},
    "mt": "AppLogin",
    "sip": ""
}
String for digest calculation:
pbxadminapi:::::{}:0123456789abcdef:pwd

Example 3:
Password on the "pbxadminapi" app object is "pwd". An info object is provided.

{
    "app": "pbxadminapi",
    "digest": "96db3c3f657230c2b68194becc6d2a77f05de9f79f01fc81e9ca0fb196b10d9d",
    "dn": "",
    "domain": "",
    "guid": "",
    "info": {
        "cn": "Test User"
    },
    "mt": "AppLogin",
    "sip": ""
}
String for digest calculation:
pbxadminapi:::::{"cn":"Test User"}:0123456789abcdef:pwd

Example 4:
Password on the "pbxadminapi" app object is "pwd". An info object is provided. The parameters for dn, domain, guid and sip are provieded.

{
    "app": "innovaphone-users",
    "digest": "ef1b811ffaa8f9255c39c653d8fb26b4687b2d8c4d9ac91b4821bff6bae3ff44",
    "dn": "Administrator User",
    "domain": "example.com",
    "guid": "0123456789abcdef0123456789abcdef",
    "info": {
        "appobj": "users",
        "apps": [
            {
                "name": "users"
            },
            {
                "name": "profile"
            }
        ],
        "appurl": "https://1.2.3.4/example.com/usersapp/innovaphone-users",
        "unlicensed": true
    },
    "mt": "AppLogin",
    "pbxObj": "users",
    "sip": "administrator"
}
String for digest calculation:
innovaphone-users:example.com:administrator:0123456789abcdef0123456789abcdef:Administrator User:{"appobj":"users","apps":[{"name":"users"},{"name":"profile"}],"appurl":"https://1.2.3.4/example.com/usersapp/innovaphone-users","unlicensed":true}:0123456789abcdef:pwd

pbxObj
Used for some Apis on the PBX to address a PBX Object. Not included in the digest calculation
info
An optional JSON Object with additional information. For the digest calculation this must be JSON encoded without any unnecessary white space and no unnecessary escaping. This is the encoding done by the json_io library of the SDK, by the Javascript JSON.stringify function or by a PHP function json_encode($input, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)

AppLoginResult

{
    "mt": "AppLoginResult",
    "ok": bool
}

Response to AppLogin. If the login was successful, the property ok is present with a value of true;

CheckBuild

{
    "mt": "CheckBuild",
    "url": string
}

Used to verify that the App loaded in the browser has the current version. A mismatch can happen when the App is loaded from a cache on the client side.

url
The complete URL of the initial App HTML file. The server checks for a build number included in the path as last component before the filename. If no build number is present, or the build number does not match the local build number, the url is modified for the current build and sent back. To check if a build number is present, the last path component is chech if it only contains 0-9, a-f or A-F. If it is a build number the build number in the path is replaced by the current build number. If no build number is present, the build number is inserted.

CheckBuildResult

{
    "mt": "CheckBuildResult",
    "url": string
}

Used to send back the current URL.

AppInfo

{
    "mt": "AppInfo",
    "app": string
}

After login to an App Service, this message is used to request more information. The PBX uses this message for api information stored at the App Object in the PBX. This way the myApps client knows the Apis availabe and can load the App when the Api is requested by another App

app
The App identified by the name of the initially loaded html file.

AppInfoResult

{
    "mt": "AppInfo",
    "info": AppInfo
}

An Json object with information about the App Service is returned

app
The App identified by the name of the initially loaded html file.

Objects

Info
{
    "appobj": string,
    "appdn": string,
    "appurl": string,
    "cn": string",
    "unlicensed": bool,
    "lics": unsigned,
    "apps": [App,...]"
}

The info object is generated by the PBX when the App is requesting a login for an App Service. It contains more information about the user.

appobj
The sip/h323 id of the App Object in the PBX which grants the access
appdn
The display name of the App Object in the PBX which grants the access
appdn
The URL configured at the App Object in the PBX which grants the access. This can be used to determine the URL under which the app services is accessible.
cn
The cn (Long Name) of the user logging in
unlicensed
Present and true if the App is running in an unlicensed mode.
lics
The number of service licenses that are assigned to the app instance. This value would be typically evaluated on the AppWebsocket connection from the App Object in the PBX to the App Instance.
apps
Array of Apps to which this user has granted access
App
{
    "name": string
}
Info about the App.
name
The sip/h323 identifier of the App Object
AppInfo
{
    "hidden": bool,
    "apis": object
}

Info about the App Service

hidden
If present and true, this App is loaded hidden by the client, when one of its APIs is requested. Hidden means that no user interface is displayed and the App does not show up on the task bar.
apis
An object containing object properties for each API provided by the App. The name of the property is the unique name of the API (e.g. com.innovaphone.manager:{}). The content of this object is available in myApps in the api model in a property named as the provider of the api.