Connect Library - Files

Connect.h

///
/// Copyright (c) 2019 AnyConnect Private Limited. All rights reserved.
/// Author(s): Palash Borhan
///

#ifndef API_CONNECT_H_
#define API_CONNECT_H_

#include "Access.h"
#include \<string>
#include \<memory>
#include \<functional>
#include \<vector>
#include \<utility>
#include \<cstdint>

namespace com {        /*!\< \namespace com */
namespace anyconnect { /*!\< \namespace anyconnect */
namespace connect {    /*!\< \namespace connect */

/*!
    * \brief Media Element Type
    * 
    * Defines properties of a media element. Default value is as media type disabled.
    * Contain attributes of a media type including IDs to access the specific component.
    * For audio/video, componentId vector will have two entry. One for the rest.
    */
struct MediaElementType
{
    MediaElementType ()
    : enable(false),
        lossless(false) {}
    bool enable;
    bool lossless;
    std::vector\<std::string> componentId;
};

/*!
    * \brief Session description of data and media types.
    *
    * Indicates enabled/disabled media types for a connected session.
    */
struct SessionDescription
{
    MediaElementType audio;
    MediaElementType video;
    MediaElementType data;
    MediaElementType control;
};

/*!
    * \brief Connection transition state.
    *
    * Indicates stopped/restarted/restart-failed/retrying state of a connected session.
    * STOPPED: Indicates a running session has been stopped, starts the timer internally to attempt recovery
    * RECOVERING: Indicates started recovering.
    * RESTARTED: restarted the stopped session
    * RESTART_FAILED: Failed to restart, either due to timeout or failed for some other region
    * RETRYING: Indicates an attempted session is failed and retrying to connect.
    */
enum ConnectionTransitionState{
    STOPPED = 0,
    RECOVERING,
    RESTARTED,
    RESTART_FAILED,
    RETRYING
};

/*!
    * \brief Connection description
    *
    * Connection details.
    * endpointUuid is the remote Endpoint identifier,
    * connectionUuid is the unique connection identifier for each connection,
    * sessionDescription contains the session media details.
    */
struct ConnectionDescription
{
    bool operator==(const ConnectionDescription& rhs) {
        return (connectionUuid.compare(rhs.connectionUuid) == 0);
    }
    bool initiator;
    std::string connectionType;
    std::string natType;
    com::anyconnect::access::Endpoint endpointUuid;
    std::string connectionUuid;
    SessionDescription sessionDescription;
};

/*!
    * \brief Connection transition details.
    * state indicates current state of connection (ConnectionTransitionState).
    * connectionUUID indicates which ongoing connection is in transition. This will hold the old connectionUuid in case of restart of a connection.
    * connectionDescription indicates resultant connection details.
    * - on stopped state, reflects ongoing connection details.
    * - on other state, may reflect the updated connection details.
    */
struct ConnectionTransitionDescription
{
    bool operator==(const ConnectionTransitionDescription& rhs) {
        return (connectionUuid.compare(rhs.connectionUuid) == 0);
    }
    ConnectionTransitionState state;
    std::string connectionUuid;
    ConnectionDescription connectionDescription;
};

/*
    * On Demand Media Relay Type
    * These are the types to indicate what the purpose of the data streaming to Media Service.
    */
enum MediaRelayType
{
    RECORDING,
    HLSSTREAMING
};

/*!
    * Handler function for connection description.
    */
typedef std::function\<void(const ConnectionDescription &connectionDescription)> ConnectionDescriptionHandler;

/*!
    * Handler function for MediaRelay state change.
    */
typedef std::function\<void(const bool &state, const ConnectionDescription &connectionDescription)> MediaRelayStateChangeHandler;

/*!
    * Handler function for On-Demand MediaRelay Signal. Indicates to enable or disable.
    */
typedef std::function\<void(const com::anyconnect::access::Endpoint &endpointId, const bool signal, const MediaRelayType mediaRelayType)> OnDemandMediaRelaySignalHandler;

/*!
    * Handler function for connection transition.
    */
typedef std::function\<void(const ConnectionTransitionDescription &connectionTransitionDescription)> ConnectionTransitionDescriptionHandler;

/*!
    * Handler function for boolean connection description.
    */
typedef std::function\<bool(const ConnectionDescription &connectionDescription)> bConnectionDescriptionHandler;

/*!
    * Handler function for Connection UUID.
    */
typedef std::function\<void(const std::string &connectionUuid)> ConnectionUuidHandler;

/*!
    * Handler function for received data.
    */
typedef std::function\<void(char* data, uint32_t length)> DataReceivedHandler;

/*!
    * Handler function for stopping Connect API session.
    */
typedef std::function\<void()> stopHandler;

/*!
    * Handler function to notify start of CONNECT.
    */
typedef std::function\<void()> startNotifier;

/*!
    * \brief Connect
    *                                                                      
    * Connect interface definition for the Connect object. The public
    * interface for this class includes setting and getting Access as well
    * as connection event handlers.
    */
class Connect
{
public:
    virtual ~Connect(){}

    /*!
        * Definition of a shared pointer to Connect
        */
    typedef std::shared_ptr\<Connect> Ptr;

    /*!
        * Initiates a connection offer using provided session description to the Endpoint.
        *
        * \param[in] endpointUuid - Remote endpoint to connect to
        * \param[in] sessionDescription - Session details and function pointer to get Connection description.
        * \param[in] callback - Callback handler function for connection description.
        * ConnectionDescriptionHandler will provide the detail properties of the offered connection.
        *
        * \return bool, true on success.
        */
    virtual bool offerConnection(const com::anyconnect::access::Endpoint &endpointUuid, const SessionDescription &sessionDescription, ConnectionDescriptionHandler callback) = 0;

    /*!
        * Initiates a MediaRelay request using provided state to the Endpoint.
        * This is to be done from the app side.
        *
        * \param[in] endpointUuid - Remote endpoint ID to start the On-Demand MediaRelay
        * \param[in] state - indicates if it needs to start MediaRelay or stop it.
        * \return bool, true on success.
        */
    virtual bool signalOnDemandMediaRelayState(const com::anyconnect::access::Endpoint &endpointUuid, const bool enable) = 0;

    /*!
        * Event handler when MediaRelay state is changed.
        * Camera will keep listening to this.
        *
        * This must be registered to be notified for MediaRelay state change.
        */
    virtual void onMediaRelayStateChange(MediaRelayStateChangeHandler callback) = 0;

    /*!
        * Event handler when On-Demand MediaRelay signal is received.
        * Camera will keep listening to this.
        *
        * This must be registered to be notified for on-demand MediaRelay request from the app.
        */
    virtual void onOnDemandMediaRelaySignal(OnDemandMediaRelaySignalHandler callback) = 0;

    /*!
        * This is to enable MediaRelay from the camera end upon some motion detection or event based in the camera.
        *
        * \param[in] sessionId - ID of the MediaRelay session. ID would be choosen by the API caller.
        * \param[in] mediaRelayType - Media Relay type
        * \param[in] state - indicates if it needs to start MediaRelay or stop it.
        *
        * \return bool, true on success.
        */
    virtual bool setMediaRelayState(std::string sessionId, const MediaRelayType mediaRelayType, const bool state, std::string inputSource, uint32_t referenceTime, uint32_t actionTime, uint32_t duration) = 0;
    /*!
        * \brief onConnectionEstablished
        *
        * Event handler when offerer/answerer endpoint accepts the connection.
        * Called for both the offerer and answerer.
        *
        * \param[in] callback - Callback handler function for connection description.
        * ConnectionDescriptionHandler will provide the detail properties of the established connection.
        *
        * This must be registered to be notified for any successful connection.
        * Recommended to register before starting Connect object.
        */
    virtual void onConnectionEstablished(ConnectionDescriptionHandler callback) = 0;

    /*!
        * \brief onConnectionOffered
        *
        * Event handler when answerer receives a connection offer from offerer endpoint.
        * \param[in] callback - Callback handler function for connection description.
        *
        * ConnectionDescriptionHandler will provide the detail properties of the offered connection.
        * The implementation of the callback should return true to accept an offered connection,
        * false to decline.
        *
        * This must be registered to be notified for any connection attempt from offerer end.
        * Recommended to register before starting Connect object.
        */
    virtual void onConnectionOffered(bConnectionDescriptionHandler callback) = 0;

    /*!
        * \brief onConnectionClosed
        *
        * Event handler when connection gets closed implicitly.
        *
        * \param[in] callback - Callback handler for the Connection UUID.
        * ConnectionUuidHandler will have the corresponding connection uuid.
        *
        * This must be registered to be notified for any implicit connection close.
        * Recommended to register before starting Connect object.
        */
    virtual void onConnectionClosed(ConnectionUuidHandler callback) = 0;

    /*!
        * \brief onConnectionChange
        *
        * Event handler when connection's underlying transport has either stopped or restarted.
        *
        * \param[in] callback - Callback handler function for connection description.
        * ConnectionTransitionDescriptionHandler will provide the detail properties of the corresponding connection.
        *
        * This must be registered to be notified for any changes to an existing connected session.
        * Recommended to register before starting Connect object.
        */
    virtual void onConnectionChange(ConnectionTransitionDescriptionHandler callback) = 0;

    /*!
        * \brief Send
        *
        * Send data to remote connected Endpoint.
        *
        * \param[in] connectionUuid - Connection unique universal identifier. 
        * \param[in] componentId - Component identifier.
        *            Use intended MediaElement component type from MediaElementType
        * \param[in] data - Data payload.
        * \param[in] length - Payload length.
        *
        * \return int32_t number of bytes sent.
        * returns the size of successfully sent data.
        * -1 indicates failure.
        */
    virtual int32_t send(const std::string &connectionUuid, const std::string &componentId, const char* data, uint32_t length) = 0;

    /*!
        * \brief Event handler for incoming data.
        *
        * Event handler for incoming data.
        *
        * \param[in] connectionUuid - Connection unique universal identifier.
        * \param[in] componentId - Component identifier.
        * \param[in] callback - Callback function handler for received data.
        * DataReceivedHandler will have the received data and corresponding length.
        *
        * This must be registered to receive any incoming data from the connected peer Endpoint.
        * Register this callback for each components of a connection.
        * Can be registered upon receiving onConnectionEstablished callback both offerer & answerer end.
        * OR upon receiving onConnectionOffered for answerer end
        *    upon receiving callback of offerConnection for offerer end.
        */
    virtual void onDataReceived(const std::string &connectionUuid, const std::string &componentId, DataReceivedHandler callback) = 0;

    /*!
        * \brief Close an existing connection.
        *
        * Close an existing connection. If the provided connectionuuid is invalid then API returns false.
        *
        * \param[in] connectionUuid - Connection unique universal identifier.
        */
    virtual bool closeConnection(const std::string &connectionUuid) = 0;

    /*!
        * \brief Retrieve active connection list.
        *
        * Retrieve active connection list.
        *
        * \param[out] connections - Connection list represented as a vector of com::anyconnect::connect::ConnectionDescription
        *
        * \return uint32_t number of active connections.
        */
    virtual uint32_t getActiveConnectionList(std::vector\<ConnectionDescription> &connections) = 0;

    /*!
        * \brief Starts the Connect Library and keeps running.
        *
        * \param[in] callback - com::anyconnect::connect::startNotifier function invoked when
        * Connect has configured and running.
        * Starts the connect Library and keeps running.
        * Must be invoked after creating the connect object through builder to be able to use any Connect object.
        */
    virtual void start(startNotifier callback) = 0;

    /*!
        * \brief Begin stopping Connect object.
        *
        * \param[in] callback - com::anyconnect::connect::stopHandler function invoked when
        * Connect has fully stopped. No callbacks will be invoked after stopHandler is called.
        *
        * stop releases all the resources allocated to Connect object.
        * Invoking start following a stop will not resume the Connect. Connect needs to be rebuild and start again.
        */
    virtual void stop(stopHandler callback) = 0;

    /*!
        * \brief Returns a pointer to an Access object
        *
        * \return Access object.
        */
    virtual com::anyconnect::access::Access::Ptr getAccess() const = 0;
};

/*!
    * \brief ConnectBuilder builds a Connect object. 
    *
    * ConnectBuilder builds a Connect object. It will return to
    * the caller an object which implements the Connect interface.
    */
class ConnectBuilder
{
private:
    com::anyconnect::access::Access::Ptr access;

    /*!
        * \brief Reconnection waiting time due to network change.
        *
        * Default value is 15 seconds (15,000 milliseconds) for reconnection waiting time due to network change.
        * To override this value use setMaxNetworkChangeTime.
        * To disable, configure as 0, meaning that loss of network results in immediate close of connection.
        */
    std::uint32_t maxNetworkWaitTime;

    ConnectBuilder(const ConnectBuilder &rhs) = delete;

public:
    ConnectBuilder();

    /*!
        * \brief Set Access object.
        *
        * Set Access object.
        * Mandatory value to be configured to build a Connect object.
        * Invalid Access object will result as failure to build Connect.
        *
        * \param[in] access - AnyConnect Access object.
        */
    void setAccess(com::anyconnect::access::Access::Ptr access) { this->access = access; }

    /*!
        * \brief Get Access object.
        *
        * \return Access object.
        */
    com::anyconnect::access::Access::Ptr getAccess() const { return access; }

    /*!
        * \brief Set the max network change time.
        *
        * Set the time that Connect will keep a connection open without an underlying path
        * to get to the endpoint. (For example, if this value is greater than the time it takes
        * to move from WiFi to Cellular, then the connection will not close.) The default value
        * is 15,000ms.
        *
        * \param[in] msTime - Time to wait for a new network path in milliseconds.
        */
    void setMaxNetworkChangeTime(uint32_t msTime) {maxNetworkWaitTime = msTime;}

    /*!
        * \brief Get the max network change time.
        *
        * Get the max time that Connect will keep a connection open without an underlying
        * path to reach the endpoint.
        *
        * \return uint32_t - Time to wait in milliseconds.
        */
    uint32_t getMaxNetworkChangeTime() const {return maxNetworkWaitTime;}

    /*!
        * \brief Build Connect object and return Connect pointer.
        *
        * build() will return to the caller a Connect
        * object that contains the set properties.  There
        * are required properties that must be set and this method
        * will throw an exception if required properties
        * are not set.
        *
        * \return a shared pointer to a Connect object.
        */
    Connect::Ptr build();
};

} //api
} //anyconnect
} //com

#endif // API_CONNECT_H_