AppWebsocket

The appwebsocket library contains a class AppWebsocket, which can be used as base class for a session object allocated for incoming websocket connections. This class handles the authentication protocol using the myPBX authentication. It relates to the innovaphone.appwebsocket.js library on the client side. There are member functions for sending and receiving messages.

Protocol

JSON messages are used on this interface. There are some common properties, which are defined by the this library already, which is documented as AppWebsocket

APIs

The library uses the mechanism defined by json_api.h to plug-in code to implement a specific API, which is addressed by the "api" property. Any App may use or provide APIs. These are documented in the context of these Apps. There are also libraries using this API mechanism (e.g. Replication).

File information

Filecommon/lib/appwebsocket.h

Classes AppWebsocket

Examples Publishing app information
Publishing service information

Classes

AppWebsocket

class AppWebsocket : public UWebsocket, public IJsonApiConnection {

    ...

public:
    AppWebsocket(IWebserverPlugin * plugin, class IInstanceLog * const log, class JsonApiContext * jsonApiContext = 0);
    ~AppWebsocket();

    virtual char * AppWebsocketPassword() { return 0; };
    virtual char * AppWebsocketPassword(const char * domain) { return NULL; };
    virtual const char * AppWebsocketInstanceDomain() { return NULL; };
    virtual void AppWebsocketMessage(class json_io & msg, word base, const char * mt, const char * src) = 0;
    virtual void AppWebsocketBinaryMessage(void * buffer, int len) { };
    virtual void AppWebsocketAppInfo(const char * app, class json_io & msg, word base) { }
    virtual void AppWebsocketServiceInfo(const char * app, class json_io & msg, word base) { }
    virtual const char * AppWebsocketDeviceAppType(const char * app) { return 0; }
    virtual void AppWebsocketLogin(class json_io & msg, word info) { };
    virtual bool AppWebsocketConnectComplete(class json_io & msg, word info) { return true; }
    virtual void AppWebsocketClosed() = 0;
    virtual bool AppWebsocketApiPermission(const char * api) { return true; }
    virtual void AppWebsocketSendResult() = 0;
    virtual void AppWebsocketCheckLogin(const char * src, const char * app, const char * challenge, const char * digest) { AppWebsocketCheckLoginComplete(src, app, challenge, digest, AppWebsocketPassword()); };

    bool AppWebsocketLoginComplete(const char * password, char * key = 0, unsigned keyLen = 0);
    void AppWebsocketCheckLoginComplete(const char * src, const char * app, const char * challenge, const char * digest, const char * password);
    void AppWebsocketMessageComplete();
    void AppWebsocketMessageSend(class json_io & msg, char * buffer);
    void AppWebsocketMessageSendText(const char * buffer);
    void AppWebsocketMessageSendBinary(char * buffer, int len);
    void AppWebsocketClose();

    void AppWebsocketEncrypt(const char * seed, const char * data, char * out, size_t outLen);
    void AppWebsocketDecrypt(const char * seed, const char * data, char * out, size_t outLen);
    void AppWebsocketHash(const char * seed, const char * data, char * out, size_t outLen);

    bool AppWebsocketIsEncryptedConnection() { return websocket->IsEncryptedConnection(); };

    void RegisterJsonApi(class JsonApi * api) override;
    void UnRegisterJsonApi(class JsonApi * api) override;
    void JsonApiMessage(class json_io & msg, char * buffer) override;
    void JsonApiMessageComplete() override;
    bool JsonApiPermission(const char * api) override { return AppWebsocketApiPermission(api); };

    char * domain;
    char * sip;
    char * guid;
    char * dn;
    char * app;
    char key[65];
};

Base class for incoming AppWebsocket sessions. It provides public functions which may be called by the application and virtual function, which may be overridden for the signaling of events on the protocol.

virtual AppWebsocket
Contructor used to initialize the class.

Parameters

IWebserverPlugin * plugin The IWebserverPlugin object passed in the WebserverWebsocketListenResult function.
class IInstanceLog * const log The log is used to log dependent of the log flag LOG_APP_WEBSOCKET.
class JsonApiContext * jsonApiContext Optional parameter, needed if other libraries, based on the JsonApi mechanism are used (e.g. config.h).
virtual AppWebsocketPassword (overloaded)
Called by the library to read the shared secret, which is part of the App instance configuration.

Return value

The app instance password. If null is returned, the function AppWebsocketLogin is called to start assynchronous athentication.
virtual AppWebsocketPassword (overloaded)
Called by the library to read another domain dependent shared secret, if the first shared secret failed.

Parameters

const char * domain The domain name.

Return value

The domain password, if defined. If null is returned, the function AppWebsocketLogin is called to start assynchronous athentication.
virtual AppWebsocketInstanceDomain
Called by the library to read the App Instance domain. It is sent within the AppLoginResult message as property "domain".

Return value

The domain name of the instance.
virtual AppWebsocketConnectComplete
Will be called after the connection / authentication process had been completed and with that the AppWebsocket connection had been established. The default implementation is just an empty function, which returns true

Return value

The application should return true to indicate, that it is ready to receive messages. If false is returned, a call to AppWebsocketMessageComplete() is needed to receive messages.
virtual AppWebsocketMessage
Called by the library on received messages. The message is json decoded.

Parameters

class json_io & msg The message as JSON data structure.
word base indicates the location of message inside the JSON structure
const char * src The "src" member of the message. This should be sent back with any response. It is used on the Javascript side to route the message to the object, which sent the request.
virtual AppWebsocketBinaryMessage
Called by the library on received binary messages.

Parameters

void * buffer The message.
int len The length of the message.
const char * src The "src" member of the message. This should be sent back with any response. It is used on the Javascript side to route the message to the object, which sent the request.
virtual AppWebsocketMessageComplete
Function to be called to acknowledge the last message. Unless this function is called no further message is received.
virtual AppWebsocketMessageSend
Function which can be called to send a message. buffer should be a buffer big enough to hold the complete message. It is used only during the call to this function.

Parameters

class json_io & msg The message as JSON data structure.
char * buffer A buffer that shall be used for encoding the message. Must be big enough to contain the whole message.
virtual AppWebsocketSendResult
Called by the library when the message is sent. The App should not send further messages unless this call is received, if the App wants to have flow control for bulk data. If flow control on application level is done, this function needs not to be implemented.
AppWebsocketClose
Can be called to request closing of the websocket connection
virtual AppWebsocketClosed
Called when the websocket connection is closed. It can be used to delete the App session (e.g. delete this).
virtual AppWebsocketAppInfo
Called by the library to get information of the specified app. This includes for example if the app is hidden and which client APIs are provided by the app. The application is supposed to encode a JSON structure containing the information.

Parameters

const char * app The name of the app for which the information is requested.
class json_io & msg A JSON structure to put the information.
word base The position inside the JSON structure where to put the information.

Information that can be published in the JSON

hidden true if the app is an API provider without a UI. Hidden apps are run in the background without displaying them to the user.
presence true if the app instance provides presence for badge counts on the AppWebsocket connection using the PbxSignal API.
apis An object that should contain an object for each client API that is provided by the app. Please see the Example.
virtual AppWebsocketServiceInfo
Called by the library to get information about the websocket services of a certain app instance. The application is supposed to encode a JSON structure containing the information.

Parameters

const char * app The name of the app for which the information is requested.
class json_io & msg A JSON structure to put the information.
word base The position inside the JSON structure where to put the information.
virtual AppWebsocketDeviceAppType
Called by the library to get information about the device app type. This happens when an AppInfo message is received.

Parameters

const char * app The name of the app for which the information is requested.

Return Value

A string, which is sent as "deviceapp" property in the AppInfoResult message.
virtual AppWebsocketLogin
Called by the library if null is returned on AppWebsocketPassword, so that the Login can be handled assynchronously in the application

Parameters

class json_io & msg Json data which contains the AppLogin message
word info Handle of the info object inside the AppLogin message.

Return Value

A string, which is sent as "deviceapp" property in the AppInfoResult message.
virtual AppWebsocketApiPermission
Called by the library when the function JsonApiPermission is called by an JsonApi implementation, so that the application can check if the use of the Api is allowed in the context of this session.

Parameters

const char * api The Api id.

Return Value

Return true to allow the use of the Api.
virtual AppWebsocketCheckLogin
Called by the library when the message AppCheckLogin is received. This can be used to check if a login is valid. The PBX Manager uses this function to verify if the passwords stored in App objects are valid. The default implementation calls AppWebsocketCheckLoginComplete with AppWebsocketPassword, so that this check works in case the AppWebsocketPassword function is used for the password.

Parameters

const char * src The src property as received
const char * appapp The app propery as received
const char * challenge The challenge property as received
const char * digest The digest propery as received
virtual AppWebsocketLoginComplete
Called by the application to complete a login process started with the AppWebsocketLogin call

Parameters

const char * password The password used to check the login
char * key Optional buffer to copy the session key into.
unsigned keyLen Length of the key buffer.
virtual AppWebsocketCheckLoginComplete
Called by the application to complete a check login process started with the AppWebsocketCheckLogin call

Parameters

const char * src The src as received in AppWebsocketCheckLogin
const char * app The app as received in AppWebsocketCheckLogin
const char * challenge The challenge as received in AppWebsocketCheckLogin
const char * digest The digest as received in AppWebsocketCheckLogin
const char * password The password to be used for the check
virtual AppWebsocketMessageSendText
Can be used to send a plain text message

Parameters

const char * buffer Zero terminated string which is sent
virtual AppWebsocketMessageSendBinary
Can be used to send a binary message

Parameters

char * buffer Buffer containing the binary message.
int len Length of the message in bytes.
AppWebsocketEncrypt
Can be used to encrypt a text send on the AppWebsocket connection, using the session key

Parameters

const char * seedseed Seed, which can be used so that the result of the encryption is different even if the data is the same.
const char * data Buffer containing the data to be encrypted as zero terminated string
char * out Buffer for the encrypted output as hex string.
size_t outLen Length of the buffer for the output. Must be 2 times the length of the data string.
AppWebsocketDecrypt
Can be used to dencrypt a text send on the AppWebsocket connection, using the session key

Parameters

const char * seedseed Seed, which can be used so that the result of the encryption is different even if the data is the same.
const char * data Buffer containing the hex string of encryped data
char * out Buffer for the decrypted output
size_t outLen Length of the buffer for the output. Must be half the length of the data string.
AppWebsocketHash
Calculate a SHA256 hash using the session key

Parameters

const char * seedseed Seed, which can be used so that the result of the encryption is different even if the data is the same.
const char * data Buffer containing a zero terminated string over which the hash shall be calculated
char * out Buffer for the hash
size_t outLen Length of the buffer for the output. Must be 64 bytes, 2* HASH_SIZE_SHA256
AppWebsocketIsEncryptedConnection
Returns true if a TLS connection is used
RegisterJsonApi
Used by an Api implementation to register the Api to the session. Needed to receive messages with the matching "api" property. This is usually called when the Api implementation is called with JsonApiRequested, when a new api value is received

Parameters

class JsonApi * api The class for the Api implementation
UnRegisterJsonApi
Used by an Api implementation to unregister the Api from the session.

Parameters

class JsonApi * api The class for the Api implementation
JsonApiMessage
Used by a JsonApi implementation to send a message

Parameters

class json_io & msg The message to be sent
char * buffer buffer big enough to contain the message
JsonApiMessageComplete
Used by a JsonApi implementation to acknowledge a received message so that the next message is received
JsonApiPermission
Used by a JsonApi implementation to check if the use of the Api is allowed for this session

Parameters

const char * The name of the api.

Return value

Return true to allow the use of the Api.

Code Examples

Publishing app information

void MySession::AppWebsocketAppInfo(const char * app, class json_io & msg, word base)
{
    if (!strcmp(app, "my-searchprovider")) {
        // general app info
        msg.add_bool(base, "hidden", true); // app is hidden
        msg.add_bool(base, "presence", true); // app provides presence (badge counts)
        
        // apis
        word apis = msg.add_object(base, "apis");
        word search = msg.add_object(apis, "com.innovaphone.search");
        word info = msg.add_object(search, "info");
        msg.add_string(info, "someattr", "somevalue");
    }
}

Publishing service information

void MySession::AppWebsocketServiceInfo(const char * app, class json_io & msg, word base)
{
    if (!strcmp(app, "my-channels-service")) {
        word apis = msg.add_object(base, "apis");
        msg.add_object(apis, "com.innovaphone.channels");
    }
}