//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / SW
//
//File: swswitch.h
//
//Version: $Revision: 1.29 $
//
//State: $State: Exp $
//
//Date: $Date: 1999/03/02 14:47:21 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Pärnänen
//
//Description:
//      Switch is an object that provides an access point for the
//      switch and its resources. Switch is implemented as a singleton
//      object that access to the resources are available for all objects.
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 

#ifndef __SW_SWITCH_H__
#define __SW_SWITCH_H__

#include <typeinfo>
#include <string>
#include <map>

#include "pf/conduit.h"
#include "pf/types.h"

#include "iface/swif/swconnectiface.h"
#include "common/ss7configure.h"
#include "swconfigimpl.h"
#include "swportfactory.h"
#include "swatmfcf.h"

class pfStorage;
class swPort;
class swUNIlink;
class swNNIlink;
class saalUNIlink;
class saalNNIlink;
class mtp3Protocol;
class uniMode;
class uniProtocol;
class bisupProtocol;
class ieConnectionIdentifier;
class swFabricCallback;

//
//Class: swSwitch
//

class swSwitch : public swConnectIface
{
    public:
        // singleton
        static swSwitch *instance(void);
        static void initSwitch(void);

        // destructor
        virtual ~swSwitch(void);

        //
        // General static methods used by objects in sw module
        //
        static pfUlong buildLinkIdentifier(pfUlong portNumber_, 
                                           pfUlong linkNumber_);
        static pfUlong parseLinkNumber(pfUlong linkIdentifier_);
        static pfUlong parsePortNumber(pfUlong linkIdentifier_);

        // Reserve methods for special VPI/VCI
        pfUlong reserveSignalingVPI(pfUlong linkIdentifier_) const;
        pfUlong reserveSignalingVCI(pfUlong linkIdentifier_) const;

        pfUlong reserveIlmiVPI(pfUlong linkIdentifier_) const;
        pfUlong reserveIlmiVCI(pfUlong linkIdentifier_) const;

        // system variables
        pfUlong getPointCode(void) const;
        void setNetPrefix(const string &netPrefix_);
        string getNetPrefix(void) const;
        void setSwitchName(const string& switchName_);
        void setSwitchType(pfUlong switchType_);
        void setFirmwareVersionNumber(pfUlong versionNumber_);

        void setAddress(pfUlong linkIdentifier_, const string &address_);

        // port management
        void addPort(pfUlong portNumber_, const string &portType_);
        void removePort(pfUlong portNumber_);
        swPort *findPort(pfUlong portNumber_) const;

        // prototypes
        pfConduit getUNIprototype(void) const;
        pfConduit getNNIprototype(void) const;

        // Clones
        swUNIlink *createUNIlink(pfUlong linkIdentifier_);
        swNNIlink *createNNIlink(pfUlong linkIdentifier_,
                                 pfUlong destinationPointCode_);
        
        saalUNIlink *createSAALUNIlink(pfUlong linkIdentifier_,
                                       pfUlong vpi_,
                                       pfUlong vci_);
        saalNNIlink *createSAALNNIlink(pfUlong linkIdentifier_,
                                       pfUlong vpi_,
                                       pfUlong vci_);

        void startNNIlink(pfConduit &nsscfProxy_);

        // MTP3
        void setSS7stack(void);
        virtual void addMTP3Routes(pfUlong beginPointCode_,
                                   pfUlong endPointCode_,
                                   pfUlong portNumber_,
                                   pfUlong linkNumber_);
        void connectSAALtoMTP3(pfUlong linkIdentifier_, 
                               pfConduit &saalConduit_);
        void connectBISUPtoMTP3(pfUlong linkIdentifier_,
                                pfConduit &niProxy_);

        // ConnectIface
        virtual void connect(ieConnectionIdentifier *input_,
                             ieConnectionIdentifier *output_,
                             bool bidirection_,
                             pfConduit &callback_);
        
        virtual pfUlong connect(ieConnectionIdentifier *input_,
                                ieConnectionIdentifier *output_,
                                bool bidirection_,
                                swFabricCallback *callback_);
        
        virtual void disconnect(ieConnectionIdentifier *input_,
                                ieConnectionIdentifier *output_,
                                bool bidirection_);

        // Connect methods called by CC
        void connect(const pfStorage &setup_,
                     pfUlong inputLinkIdentifier_,
                     pfConduit &callback_);
        
        void connect(const pfStorage &setup_, 
                     ieConnectionInfo *input_,
                     pfConduit &callback_);
        
        void disconnect(ieConnectionInfo *input_,
                        ieConnectionInfo *output_,
                        bool multiPoint_);
        
    private:
        // constructor
        swSwitch(void);

        void initFCF(void);
        void readConfigFile(void);
        void initSS7(void);
        void connectMTP3User(pfUlong identifier_, pfConduit &proxy_);


    private:
        // singleton
        static swSwitch *_only;

        // typedefs
        typedef map<pfUlong, swPort*, less<pfUlong> > mapType;
        typedef mapType::iterator mapIterType;
        typedef mapType::const_iterator mapConstIterType;
        
        // attributes
        string _netPrefix;
        string _switchName;
        pfUlong _switchType;
        pfUlong _versionNumber;

        // port
        mapType _portMap;
        swPortFactory _portFactory;

        // prototypes
        swUNIlink *_uniLink;
        swNNIlink *_nniLink;

        saalUNIlink *_uniSAALlink;
        saalNNIlink *_nniSAALlink;

        // SS7
        ss7Configure _ss7Configure;
        pfConduit _tcapProxy;
        pfConduit _sccpProxy;
        mtp3Protocol *_mtp3;
        pfConduit _mtp3Proxy;

        pfConduit _userMuxProxy;
        pfConduit _aalMuxProxy;
        pfConduit _niMuxProxy;

        uniProtocol *_uni;
        pfConduit _uniProxy;
        bisupProtocol *_bisup;
        pfConduit _bisupProxy;

        // config interface
        swConfigImpl _config;

        swATMFCF _atmFCF;
};

#endif // __SW_SWITCH_H__

