
/*-----------------------------------------------------------------------------------------------*/
/* signaling_api.h                                                                               */
/* copyright (c) innovaphone 2020                                                                */
/*                                                                                               */
/*-----------------------------------------------------------------------------------------------*/

#define CALL_ENDED_REASON_UNSPECIFIED           0
#define CALL_ENDED_REASON_FAILED                1
#define CALL_ENDED_REASON_REMOTE_ENDED          2
#define CALL_ENDED_REASON_UNANSWERED            3
#define CALL_ENDED_REASON_ANSWERED_ELSEWHERE    4
#define CALL_ENDED_REASON_DECLINED_ELSEWHERE    5
#define CALL_ENDED_REASON_USER_BUSY             6

#define CALL_ERROR_SUCCESS                  0
#define CALL_ERROR_UNSPECIFIED              1
#define CALL_ERROR_UNENTITLED               2
#define CALL_ERROR_DUPLICATE_UUID           3
#define CALL_ERROR_INCOMING_DO_NOT_DISTURB  4
#define CALL_ERROR_INCOMING_BLOCKED         5
#define CALL_ERROR_NO_PROVIDER              6
#define CALL_ERROR_UNKNOWN_UUID             7
#define CALL_ERROR_REQUEST_INVALID          8
#define CALL_ERROR_TOO_MANY_GROUPS          9

class SignalingMediaConfig {
public:
    SignalingMediaConfig(
        ISocketProvider * udpSocketProvider = 0,
        ISocketProvider * tcpSocketProvider = 0,
        class ISocketProvider * tlsSocketProvider = 0,
        class ISocketContext * socketContext = 0,
        word minPort = 0,
        word maxPort = 0,
        word minVideoPort = 0,
        word maxVideoPort = 0,
        const char * stunServers = 0,
        const char * turnServers = 0,
        const char * turnUsername = 0,
        const char * turnPassword = 0,
        enum MediaType media = AUDIO,
        bool stunSlow = 0,
        bool turnOnly = 0,
        bool iceNoHost = 0,
        bool recordRtpStream = false,
        int dropMediaTx = 0,
        int dropMediaRx = 0,
        const char * hostPbx = 0,
        bool noVpnAddresses = 0,
        const char * currentUserSip = 0,
        const char * recordingUrl = 0,
        bool isRecordingByDefaultOn = 0,
        bool recordExternalOnly = 0,
        const char * recordingUsername = 0,
        const char * recordingPassword = 0,
        const char * excludeInterfaces = 0);
    ~SignalingMediaConfig() {
        if (stunServers) free(stunServers);
        if (turnServers) free(turnServers);
        if (turnUsername) free(turnUsername);
        if (turnPassword) free(turnPassword);
        if (hostPbx) free(hostPbx);
        if (currentUserSip) free(currentUserSip);
        if (recordingUrl) free(recordingUrl);
        if (recordingUsername) free(recordingUsername);
        if (recordingPassword) free(recordingPassword);
        if (excludeInterfaces) free(excludeInterfaces);
    }

    ISocketProvider * udpSocketProvider;
    ISocketProvider * tcpSocketProvider;
    ISocketProvider * tlsSocketProvider;
    class ISocketContext * socketContext;
    word minPort;
    word maxPort;
    word minVideoPort;
    word maxVideoPort;
    char * stunServers;
    char * turnServers;
    char * turnUsername;
    char * turnPassword;
    enum MediaType media;
    bool stunSlow;
    bool turnOnly;
    bool iceNoHost;
    int dropMediaTx;
    int dropMediaRx;
    char * hostPbx;
    bool noVpnAddresses;
    char * currentUserSip;
    char * recordingUrl;
    bool isRecordingByDefaultOn;
    bool recordExternalOnly;
    char * recordingUsername;
    char * recordingPassword;
    bool recordRtpStream;
    char * excludeInterfaces;
};

class ISignalingService  {

public:
    static class ISignalingService * CreateSignaling(class IIoMux * const iomux, class ISocketProvider * localSocketProvider, class ISocketProvider * tcpSocketProvider, class ISocketProvider * tlsSocketProvider, IWebserverPluginProvider * const webserverPluginProvider, IAppWebsocketClientProvider * appWebsocketClientProvider, IMediaProvider * mediaProvider, SignalingMediaConfig * mediaConfig, IAudioIo * audioIo, IRingerIo * ringerIo, IVideoIo * videoIo, IAudioIo* remoteAudioIo, IRingerIo* remoteRingerIo, IVideoIo* remoteVideoIo, IMediaProvider* remoteMediaProvider, ISignalingRemote* remoteSignaling, AppServiceArgs * args);
    virtual ~ISignalingService() {};
    virtual void IAppStart(AppInstanceArgs * args) = 0;
    virtual class ISignaling * ICreateInstance(class USignaling * user, AppInstanceArgs * args) = 0;
    virtual class ISignaling * GetISignalingInstance() = 0;
};

class ISignaling : public AppInstance {
public:
    ISignaling(class USignaling * user, class AppService * appService, AppInstanceArgs * args);

    virtual void SetClient(const char * url, const char * sec, const char * phys, const char * app, const char * usr, const char * pwd, const char * domain, const char * appdomain, unsigned timeout, bool localInit) = 0;
    virtual void CloseClient() = 0;
    virtual void SetRegistration(const char * hw, const char * phys, unsigned timeout) = 0;
    virtual void RegistrationCheck() = 0;
    virtual void LookupInfo(const char* src, class json_io& msg, word base) = 0;
    virtual class IRTPTP * SetRTPTP4(class URTPTP * user, const char * sip, unsigned timeout) = 0;
    virtual class IRTPTP * SetRTPTP6(class URTPTP * user, const char * sip, unsigned timeout) = 0;
    virtual void StartRinging(const char * uuid) = 0;

    virtual void PhoneStartCallAction(const char * uuid, const char * number, const char * name, bool video, bool sendingComplete) = 0;
    virtual void PhoneAnswerCallAction(const char * uuid) = 0;
    virtual void PhoneEndCallAction(const char * uuid, int call_error) = 0;
    virtual void PhoneDialNumber(const char *number, const char *name, const char * dn, bool videoMode, bool sendingComplete, bool numOffset = true) = 0;
    virtual void PhoneHoldCallAction(const char * uuid) = 0;
    virtual void PhoneRetrieveCallAction(const char * uuid) = 0;
    virtual void PhoneSetMutedCallAction(const char * uuid, bool muted) = 0;
    virtual void PhoneAudioRouteChanged(const char * uuid, const char * deviceId) = 0;
    virtual void PhonePlayDtmfCallAction(const char * uuid, const char * digits) = 0;
    virtual void PhoneStartRinging(const char* uuid) = 0;
    virtual void PhoneCheckIncomingCall(const char* uuid) = 0;

    virtual void SetExcludeInterfaces(const char * excludeInf) = 0;
    virtual void SetNoVpnAddresses(bool noVpnAddresses) = 0;
    virtual void SetCurrentUserSip(const char * sip) = 0;
    virtual void SetRecordingParameters(const char* url, bool pbx, bool forceUrl, bool isRecordingByDefaultOn, bool forceDefaultOn, bool recordExternalOnly, bool forceExternalOnly) = 0;
    virtual void SetSignalingUser(class USignaling* user) = 0;
    virtual void SetWorkingPath(const char * path) = 0;

    virtual int NumActiveCalls() = 0;
};

class USignaling {
public:
    virtual void SignalingClosing(class ISignaling *signaling) = 0;
    virtual void ClientState(bool up, bool localInit) = 0;
    virtual void SaveCredentials(const char* url, const char* sec, const char* phys, const char* app, const char* usr, const char* pwd, const char * domain, const char * appdomain, unsigned timeout) = 0;
    virtual void SaveRegistration(const char* hw, const char* phys, unsigned timeout) = 0;
    virtual void RegistrationState(bool up) = 0;
    virtual void UserSession(bool up) = 0;
    virtual void SetDnd(bool dnd) = 0;
    virtual void SendEvent(int code, char* error, char* src) = 0;
    virtual bool UseRemoteClientServices() = 0;
    virtual bool UseRemoteServices() = 0;
    virtual void SoftphoneAppWindowTitle(const char* title) = 0;
    virtual void BringWindowToForeground() = 0;
    virtual bool HasCredentials() = 0;
    virtual void StartSoftphoneApp() = 0;

    virtual void SelectRingtone(const char* ringtoneId) = 0;
    virtual void ReportNewIncomingCall(const char* uuid, const char* number, int offset, const char* sip, const char* name, const char* diverting, const char* called,
                                       bool hasVideo, bool supportsDTMF, bool supportsHolding, bool supportsGrouping, bool supportsUngrouping) = 0;
    virtual void ReportCallEnded(const char* uuid, int reason, bool ignoreCallkit = false, const char* reconnectUuid = nullptr) = 0;
    virtual void ReportMissedCall(const char* uuid, const char* number, int offset, const char* sip, const char* name, int reason) = 0;
    virtual void ReportCallHold(const char * uuid) = 0;
    virtual void ReportCallRetrieve(const char * uuid) = 0;
    virtual void ReportCallConnected(const char * uuid, bool connected, const char* number, int offset, const char* sip, const char* name, const char* diverting, const char* called,
                                     bool hasVideo, bool supportsDTMF, bool supportsHolding, bool supportsGrouping, bool supportsUngrouping, bool ignoreCallkit = false) = 0;
    virtual void RequestStartCall(const char * uuid, const char * number, const char * name, bool video, bool sendingComplete) = 0;
    virtual void RequestStartRinging(const char* uuid) = 0;
    virtual void ReportOutgoingCallAlerting(const char *uuid, const char * name, const char * sip, const char * num, int numOffset, bool ignoreCallkit = false) = 0;
    virtual void ReportNameIdentification(const char* uuid, const char* number, const char* sip, const char* name, const char* diverting, const char* called,
                                          bool hasVideo, bool supportsDTMF, bool supportsHolding, bool supportsGrouping, bool supportsUngrouping, bool ignoreCallkit) = 0;
    virtual void Lookup(const char * src, const char* number, const char* prefixIntl, const char* prefixNtl, const char* prefixExt, const char* country, const char* area, const char* subscriber) = 0;
};

class IRTPTP {
public:
    virtual void Send(void * buf, size_t len) = 0;
};

class URTPTP {
public:
    virtual void RTPTPState(bool up) = 0;
    virtual void RTPTPRecv(void * buf, size_t len) = 0;
};

class ISignalingConfig {
public:
    virtual void SetExcludeInterfaces(const char * excludeInf) = 0;
    virtual void SetNoVpnAddresses(bool noVpnAddresses) = 0;
    virtual void SetCurrentUserSip(const char * sip) = 0;
    virtual void SetRecordingParameters(const char* url, bool forceUrl, bool isRecordingByDefaultOn, bool forceDefaultOn, bool recordExternalOnly, bool forceExternalOnly) = 0;
};

