Reference12r1:Concept myPBX Toolbox: Difference between revisions

From innovaphone wiki
Jump to navigation Jump to search
Line 43: Line 43:
== innovaphone.pbxwebsocket.Connection ==
== innovaphone.pbxwebsocket.Connection ==
Used to create a connection to the PBX for calls and presence subscription.
Used to create a connection to the PBX for calls and presence subscription.
The ''WebRtcEndpoint'' is derived from the ''Connection'' described above.  As such, all interfaces defined for those are also available, plus some more.


=== Includes ===
=== Includes ===

Revision as of 15:15, 4 October 2017

The myPBX toolbox is a set of Java Script files that can be used for integrating functionality of the innovaphone PBX into arbitrary web sites.

Supported features

  • Presence monitoring
  • Outgoing WebRTC calls with audio, video and application sharing

Requirements

Download
Web site
  • The needed JavaScript files of the libraries have to be included in the web site
PBX
  • User object with password for login and a WebRTC device
  • Call filters for that user object
  • Valid STUN/TURN configuration
The TURN credentials are transferred in clear text to the browser. This is by design of the WebRTC clients. 
To avoid disclosure of credentials matching for other services define additional username/password combination on the TURN server that is used by WebRTC clients only.
Licenses
  • myPBX license
  • Video license (for video telephony)
  • Application Sharing license (for viewing shared applications)
  • WebRTC channel license (per WebRTC call)
Note: The WebRTC channel license must be activated on each indiviual PBX by configuring a number of "Max WebRTC calls".
Network
  • The PBX service (https://pbx.sample.domain/PBX0/WEBSOCKET) must be accessible from the public internet (NAT port forwarding or reverse proxy).
Certificates
  • The caller (more precisely, the web browser used by the user accessing your web site) will create a websocket TLS connection to your PBX, so it needs to trust the PBX's (https://pbx.sample.domain) certificate. As the web site probably shall be usable by any client out there on the internet, you can not control the calling browsers certificate trust list. You therefore must install a valid certificate created by a well-known certificate authority on your PBX.

Authentication

For connecting the credentials of a PBX user account is needed. The credentials can be hard coded in the Java Script code (not recommended) or they can be stored on the web server that hosts the application (recommended).

A typical flow for the second method would be like follows.

  1. The PBX chooses the server parameters (realm, sessionId, serverNonce) and sends it to the Application
  2. The callback onAuthenticate(realm, sessionId, serverNonce) is called.
  3. The Application sends the parameters to the web server.
  4. The Webserver chooses the client parameters (username, clientNonce) and calculated the login digest and sends it back to the application.
  5. The application calls the setAuthentication(username, clientNonce, digest) function.
  6. The PBX accepts the login.

Reference

innovaphone.pbxwebsocket.Connection

Used to create a connection to the PBX for calls and presence subscription.

Includes

The following files have to be included in the html file in order to use the WebRTC endpoint.

  • innovaphone.common.crypto.js
  • innovaphone.pbxwebsocket.Connection.js

Constructor

new Connection(url, username, password)
url
The URL of the PBX websocket service (e.g. wss://xxx/PBX0/WEBSOCKET/websocket)
username
The username of the PBX user object.
password
The password of the PBX user object.
you can set the following members to define callback functions provided by your web page:
connection.onconnected
called when the call is connected
connection.onerror
called on error
connection.onclosed
called when the call is closed
connection.onendpointpresence
called when a subscribed users' presence information changes

Methods

function close()
Disconnects from the PBX.
function setAuthentication(username, clientNonce, digest)
Sets the client parameters of the authentication and the calculated digest.
username
The H323 id of the user object
clientNonce
A random number
digest
sha256("innovaphonePbxWebsocket:ClientAuth:" + realm + ":" + sessionId + ":" + username + ":" + password + ":" + clientNonce + ":" + serverNonce)
function sendSubscribeEndpoint(name, number)
Starts presence monitoring for a given endpoint specifyed by name or number.
name
The URI or H.323 id
number
The phone number
function sendUnsubscribeEndpoint(name, number)
Stops presence monitoring for a given endpoint specifyed by name or number.
name
The URI or H.323 id
number
The phone number

The methods for WebRTC calls are not described here. Use innovaphone.pbxwebsocket.WebRtcEndpoint.js instead.

Callbacks

function onauthenticate(realm, sessionId, serverNonce)
This callback is used for authenting users when the web page shall not be aware of the user password. Set connection.onauthenticate to get a callback during login process. The login hash can then be calculated on the webserver and be given back using function setAuthentication.
function onconnected(userInfo)
Called when the connection has been successfully established.
userInfo
An object containing informmation about the connected user.
function onerror(error)
Called when the connection could not be established or an other error occurred.
error
A string containing an error message.
function onclosed()
Called if the connection was closed.
function onendpointpresence(name, number, phoneStatus, imStatus, activity, note)
Called if the presence of a subscribed endpoint has changed.
name
The URI or H.323 id
number
The phone number
phoneStatus
Tells if a phone is registered, open or closed.
imStatus
Tells if a chat client is registered, open or closed.
activity
Presence activity away, busy, lunch, vacation, busy, dnd, on-the-phone
note
Presence note

The callbacks for WebRTC calls are not described here. Use innovaphone.pbxwebsocket.WebRtcEndpoint.js instead.

Example

The following example connects to the PBX and does presence monitoring for the user with the H.323 ID "target".

   <script type="text/javascript" src="innovaphone.common.crypto.js"></script>
   <script type="text/javascript" src="innovaphone.pbxwebsocket.Connection.js"></script>
   <script type="text/javascript">
      
       // dependencies
       var Connection = innovaphone.pbxwebsocket.Connection;
      
       // private
       var connection = null;
       var config = {
           url: "ws://192.168.0.1/PBX0/WEBSOCKET/websocket",
           username: "user",
           password: "password"
       };
      
       // callbacks
       function onConnected(userInfo) {
           console.log("Connected: " + JSON.stringify(userInfo));
           connection.sendSubscribeEndpoint("target", null);
       }
       
       function onError(error) {
           console.log("Error: " + error);
       }
       
       function onClosed() {
           console.log("Closed");
       }
       
       function close() {
           if (connection) connection.close();
           connection = null;
       }
       
       function onEndpointPresence(name, number, phoneStatus, imStatus, activity, note) {
           console.log("EndpointPresence: activity=" + activity + " note=" + note);
       }
      
       // main function
       function start() {
           if (connection) connection.close();
           connection = new Connection(config.url, config.username, config.password);
           connection.onconnected = onConnected;
           connection.onerror = onError;
           connection.onclosed = onClosed;
           connection.onendpointpresence = onEndpointPresence;
       }
      
   </script>

innovaphone.pbxwebsocket.WebRtcEndpoint

This file contains a WebRTC endpoint implementation that can be used for adding WebRTC calls to a web page. For that the credentials of a user object on the PBX is needed. Visitors of the web page will use that user object for making phone calls.

In some browsers like Chrome WebRTC only works on HTTPS pages. So it is mandatory to use HTTPS and WSS on your page.

Includes

The following files have to be included in the html file in order to use the WebRTC endpoint.

  • innovaphone.common.crypto.js
  • innovaphone.pbxwebsocket.Connection.js
  • innovaphone.pbxwebsocket.ToneGenerator.js
  • innovaphone.pbxwebsocket.WebRtcEndpoint.js

If you want to use application sharing the following files must also be included:

  • innovaphone.applicationSharing.jpeg.js
  • innovaphone.applicationSharing.zlib.js
  • innovaphone.applicationSharing.png.js
  • innovaphone.applicationSharing.main.js

Additionally the MP3 files containing the ring tones and ring back tones are needed on the web server in the same directory as the javascript files.

Compatibility check

You can test if the browser supports WebRTC by checking the bool innovaphone.pbxwebsocket.WebRtc.supported.

Constructor

new WebRtcEndpoint(url, username, password, device, physicalLocation, regContext, onLog, onCall)
url
The URL of the PBX websocket service (e.g. ws://10.0.0.1/PBX0/WEBSOCKET/websocket)
username
The username of the PBX user object.
password
The password of the PBX user object.
device
The device ID that shall be used for making calls.
physicalLocation
The physical location of the user (optional).
regContext
A numeric value that will be used for identifying the registration in the PBX (optional).
logFunction
A callback function that is called for logging debug info (optional).
onCall
A callback function that is called when calls are added, updated or removed. Applications that want to use call control have to specify this callback function. Applications that don't should give null. (optional)
onAuthenticate
An optional callback function. If set it is called with the parameters (realm, sessionId, serverNonce). Applications should calculate the login hash using these parameters and the username and password and call setAuthentication.

Methods

function close()
Closes the WebRTC endpoint and disconnects from the PBX.
function initCall(name, number, video, sharing)
Starts a phone call. This is only possible if the application supplied an onCall callback to the constructor.
name
The URI (e.g. Name in the PBX User object) to be called (optional, supply name or number).
number
The phone number to be called (optional, supply name or number).
video
Set to true for starting a video call (optional).
sharing
Set to true for starting an application sharing call (optional).
function connectCall(id)
Connects a call.
id
The ID of the call.
function dtmfCall(id, digits)
Sends dtmf digits to a connected call.
id
The ID of the call.
digits
A string containing DTMF digits (0-9,*,#,A,B,C,D).
function clearCall(id)
Terminates a call.
id
The ID of the call (optional). If no ID is supplied, all calls are terminated.
function attachVideo(local, remote)
Attaches HTML video elements to the WebRTC endpoints. The endpoint will use them to playback video. Applications can both attach before or during a video call. Also attaching multiple video elements for a single call is possible. The application should mute the video elements (muted="muted") in order to avoid playback of audio.
local
The HTML video element for playback of the local webcam image (optional, may be null).
remote
The HTML video element for playback of the remote video image (optional, may be null).
function detachVideo(local, remote)
Detaches HTML video elements that have previously attached. This will stop the playback on the supplied elements.
local
The HTML video element to be detached (optional, may be null).
remote
The HTML video element to be detached (optional, may be null).
function attachSharing(sharingDiv, createAppCallback, removeAppCallback, resizeCalback)
Attaches a DIV element to the WebRTC endpoints. The endpoint will allocate inside this element a canvas object where the application sharing data will be displayed. This DIV element must have as style position:relative, otherwise the mouse will not be displayed correctly. Since more than one application could be shared, the javascript application has to provide a callback to be informed that a new application arrived and another callback to be informed that an application is not anymore shared. Both callbacks should received an id as argument. Another callback will be provided in case the shared application changes its resolution. It is also possible that the JS application receives data from different participants, for instance during a conference. That is why this sender_id is also needed.
createAppCallback
createAppCallback(sender_id, id, name). This callback also receives the name of the new application.
removeAppCallback
removeAppCallback(sender_id, id).
resizeCallback
resizeCallback().
function detachSharing()
Detaches elements that were previously attached.
function sharingEvent(type, data)
The endpoint provides an interface to send events to the application sharing class.
changeDisplaySender
This event is used to switch between the users which are sharing something. Useful in a conference. type is equal to changeDisplaySender and data should be the id of the sender. This id is the one provided in the create application callback.
changeDisplayApp
This event is used to switch inside the canvas object between applications being shared. type is equal to changeDisplayApp and data should be the id of the application to be displayed. This id is the one provided in the create application callback.
fitToElement
This event adjusts the application being shared to the size of the DIV element provided with the attachSharing function. type is equal to fitToElement and data should be true if the application should be adjusted to the canvas element or false otherwise (original size).
requestControl
This event allows the client to request control (mouse, keyboard) over the shared applications. The sharing party still must accept this request before the client gets the control. type is equal to requestControl and data should be null.
function setAuthentication(username, clientNonce, digest)
Sets the client parameters of the authentication and the calculated digest.
username
The H323 id of the user object
clientNonce
A random number
digest
sha256("innovaphonePbxWebsocket:ClientAuth:" + realm + ":" + sessionId + ":" + username + ":" + password + ":" + clientNonce + ":" + serverNonce)

Callbacks

function onLog(text)
Should write the supplied text to the log of the application.
function onCall(event, call)
Is called when the state of calls of this WebRTC endpoint changes.
event
A string that can be added, updated and removed.
call
The call object containing the current info about the call.
id
The numeric id of the call.
dir
The direction of the call (in or out).
state
The state of the call (idle, calling, incomplete, complete, alerting, connected, disconnecting, disconnected, parked).
hold
true, if the call is on hold (optional).
name
The URI of the remote party (optional).
number
The phone number of the remote party (optional).
video
true, if video is active (optional).
sharing
true, if application sharing is active (optional).
cause
The cause code (optional).

Example

   <script type="text/javascript" src="innovaphone.common.crypto.js"></script>
   <script type="text/javascript" src="innovaphone.pbxwebsocket.Connection.js"></script>
   <script type="text/javascript" src="innovaphone.pbxwebsocket.ToneGenerator.js"></script>
   <script type="text/javascript" src="innovaphone.applicationSharing.jpeg.js"></script>
   <script type="text/javascript" src="innovaphone.applicationSharing.zlib.js"></script>
   <script type="text/javascript" src="innovaphone.applicationSharing.png.js"></script>
   <script type="text/javascript" src="innovaphone.applicationSharing.main.js"></script>
   <script type="text/javascript" src="innovaphone.pbxwebsocket.WebRtcEndpoint.js"></script>
   <script type="text/javascript">
       
       // dependencies
       var WebRtcEndpoint = innovaphone.pbxwebsocket.WebRtc.Endpoint;
      
       var endpoint = null;
       var config = {
           url: "wss://192.168.0.1/PBX0/WEBSOCKET/websocket",
           username: "user",
           password: "password",
           device: "user-webrtc",
           physicalLocation: null,
           regContext: "0"
       };
      
       function logFunction(text) {
           console.log("WebRTC demo: " + text);
       }
      
       function onCall(event, call) {
           if (call.dir == "in") {
               if (endpoint) endpoint.clearCall(call.id);
           }
           console.log("Call " + event + ": " + JSON.stringify(call));
       }
      
       function initCall(name, number, video, sharing) {
           if (endpoint) endpoint.initCall(name, number, video, sharing);
       }
      
       function clearAllCalls() {
           if (endpoint) endpoint.clearCall();
       }
      
       function close() {
           if (endpoint) {
               endpoint.detachVideo(document.getElementById("video-local"), document.getElementById("video-remote"));
               endpoint.detachSharing();
               endpoint.close();
           }
           endpoint = null;
       }
      
       function resizeCanvas() {
       }
      
       function createNewApplication(sender_id, id, name) {
           var new_app = document.createElement("input"); 
           new_app.setAttribute("id", "appSharing_" + sender_id + "_" + id);
           new_app.setAttribute("value", name);
           new_app.setAttribute("type", "button");
           new_app.onclick = function () { changeDisplayApp(id); };
           getElementById("sharing-local").appendChild(new_app);
       }
      
       function changeDisplayApp(id) {
           var s_app_id = String(id);               // id == appSharing_x_y where x is the sender and y the application, both are numbers, 0, 1, 2, ..
           var a_app_id = s_app_id.split("_");      // a_app_id is an array with three elements.
           instanceConference.endpoint.sharingEvent('changeDisplaySender', a_app_id[1]);
           instanceConference.endpoint.sharingEvent('changeDisplayApp', a_app_id[2]);
       }
      
       function removeApplication(sender_id, id) {
           var input_b = document.getElementById("appSharing_" + sender_id + "_" + id);
           if(input_b) getElementById("sharing-local").removeChild(input_b);
       }
      
       function start() {
           if (endpoint) endpoint.close();
           endpoint = new WebRtcEndpoint(config.url, config.username, config.password, config.device, config.physicalLocation, config.regContext, logFunction, onCall);
           endpoint.attachVideo(document.getElementById("video-local"), document.getElementById("video-remote"));
           endpoint.attachSharing(document.getElementById("sharing-local"), createNewApplication, removeApplication, resizeCanvas);
       }

   </script>