Yate
yatesig.h
00001 /*
00002  * yatesig.h
00003  * This file is part of the YATE Project http://YATE.null.ro
00004  *
00005  * Yet Another Signalling Stack - implements the support for SS7, ISDN and PSTN
00006  *
00007  * Yet Another Telephony Engine - a fully featured software PBX and IVR
00008  * Copyright (C) 2004-2006 Null Team
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00023  */
00024 
00025 #ifndef __YATESIG_H
00026 #define __YATESIG_H
00027 
00028 #include <yateclass.h>
00029 
00030 #ifdef _WINDOWS
00031 
00032 #ifdef LIBYSIG_EXPORTS
00033 #define YSIG_API __declspec(dllexport)
00034 #else
00035 #ifndef LIBYSIG_STATIC
00036 #define YSIG_API __declspec(dllimport)
00037 #endif
00038 #endif
00039 
00040 #endif /* _WINDOWS */
00041 
00042 #ifndef YSIG_API
00043 #define YSIG_API
00044 #endif
00045 
00049 namespace TelEngine {
00050 
00051 // Signalling classes
00052 class SignallingDumper;                  // A generic data dumper
00053 class SignallingDumpable;                // A component that can dump data
00054 class SignallingNotifier;                // A signalling notifier
00055 class SignallingTimer;                   // A signalling timer
00056 class SignallingCounter;                 // A signalling counter
00057 class SignallingFactory;                 // A signalling component factory
00058 class SignallingComponent;               // Abstract signalling component that can be managed by the engine
00059 class SignallingEngine;                  // Main signalling component holder
00060 class SignallingThreadPrivate;           // Engine private thread
00061 class SignallingMessage;                 // Abstract signalling message
00062 class SignallingCallControl;             // Abstract phone call signalling
00063 class SignallingCall;                    // Abstract single phone call
00064 class SignallingEvent;                   // A single signalling related event
00065 class SignallingCircuitEvent;            // A single signalling circuit related event
00066 class SignallingCircuit;                 // Abstract data circuit used by signalling
00067 class SignallingCircuitRange;            // A circuit range (set of circuits)
00068 class SignallingCircuitGroup;            // Group of data circuits used by signalling
00069 class SignallingCircuitSpan;             // A span in a circuit group
00070 class SignallingInterface;               // Abstract digital signalling interface (hardware access)
00071 class SignallingReceiver;                // Abstract Layer 2 packet data receiver
00072 struct SignallingFlags;                  // Description of parameter flags
00073 class SignallingUtils;                   // Library wide services and data provider
00074 class SignallingMessageTimer;            // A pending signalling message
00075 class SignallingMessageTimerList;        // A pending signalling message list
00076 // Analog lines
00077 class AnalogLine;                        // An analog line
00078 class AnalogLineEvent;                   // A single analog line related event
00079 class AnalogLineGroup;                   // A group of analog lines
00080 // SS7
00081 class SS7PointCode;                      // SS7 Code Point
00082 class SS7Label;                          // SS7 Routing Label
00083 class SS7MSU;                            // A block of data that holds a Message Signal Unit
00084 class SIGTRAN;                           // Abstract SIGTRAN component
00085 class SIGTransport;                      // Abstract transport for SIGTRAN
00086 class SIGAdaptation;                     // Abstract Adaptation style SIGTRAN
00087 class SIGAdaptClient;                    // Client side of adaptation (ASP)
00088 class SIGAdaptServer;                    // Server side of adaptation (SG)
00089 class SIGAdaptUser;                      // Abstract Adaptation User SIGTRAN
00090 class ASPUser;                           // Abstract SS7 ASP user interface
00091 class SCCP;                              // Abstract SS7 SCCP interface
00092 class GTT;                               // Abstract SCCP Global Title Translation interface
00093 class SCCPManagement;                    // Abstract SCCP Management interface
00094 class SCCPUser;                          // Abstract SS7 SCCP user interface
00095 class TCAPUser;                          // Abstract SS7 TCAP user interface
00096 class SS7L2User;                         // Abstract user of SS7 layer 2 (data link) message transfer part
00097 class SS7Layer2;                         // Abstract SS7 layer 2 (data link) message transfer part
00098 class SS7L3User;                         // Abstract user of SS7 layer 3 (network) message transfer part
00099 class SS7Layer3;                         // Abstract SS7 layer 3 (network) message transfer part
00100 class SS7Layer4;                         // Abstract SS7 layer 4 (application) protocol
00101 class SS7Route;                          // A SS7 MSU route
00102 class SS7Router;                         // Main router for SS7 message transfer and applications
00103 class SS7M2PA;                           // SIGTRAN MTP2 User Peer-to-Peer Adaptation Layer
00104 class SS7M2UA;                           // SIGTRAN MTP2 User Adaptation Layer
00105 class SS7M3UA;                           // SIGTRAN MTP3 User Adaptation Layer
00106 class SS7MTP2;                           // SS7 Layer 2 implementation on top of a hardware interface
00107 class SS7MTP3;                           // SS7 Layer 3 implementation on top of Layer 2
00108 class SS7MsgSNM;                         // SNM signalling message
00109 class SS7MsgMTN;                         // MTN signalling message
00110 class SS7MsgISUP;                        // ISUP signalling message
00111 class SS7MsgSCCP;                        // SCCP signalling message
00112 class SS7Management;                     // SS7 SNM implementation
00113 class SS7ISUPCall;                       // A SS7 ISUP call
00114 class SS7ISUP;                           // SS7 ISUP implementation
00115 class SS7BICC;                           // SS7 BICC implementation
00116 class SS7TUP;                            // SS7 TUP implementation
00117 class SS7SCCP;                           // SS7 SCCP implementation
00118 class SccpSubsystem;                     // Helper class to keep a SCCP subsystem
00119 class SccpLocalSubsystem;                // Helper class to keep s sccp local subsystem informations
00120 class SccpRemote;                        // Helper class to keep a remote sccp
00121 class SS7AnsiSccpManagement;             // SS7 SCCP management implementation for ANSI
00122 class SS7ItuSccpManagement;              // SS7 SCCP management implementation for ITU
00123 class SS7SUA;                            // SIGTRAN SCCP User Adaptation Layer
00124 class SS7ASP;                            // SS7 ASP implementation
00125 class SS7TCAPMessage;                    // SS7 TCAP message wrapper
00126 class SS7TCAPError;                      // SS7 TCAP errors
00127 class SS7TCAP;                           // SS7 TCAP implementation
00128 class SS7TCAPTransaction;                // SS7 TCAP transaction base class
00129 class SS7TCAPComponent;                  // SS7 TCAP component
00130 class SS7TCAPANSI;                       // SS7 ANSI TCAP implementation
00131 class SS7TCAPTransactionANSI;            // SS7 TCAP ANSI Transaction
00132 class SS7TCAPITU;                        // SS7 ITU TCAP implementation
00133 class SS7TCAPTransactionITU;             // SS7 TCAP ITU Transaction
00134 // ISDN
00135 class ISDNLayer2;                        // Abstract ISDN layer 2 (Q.921) message transport
00136 class ISDNLayer3;                        // Abstract ISDN layer 3 (Q.931) message transport
00137 class ISDNFrame;                         // An ISDN Q.921 frame
00138 class ISDNQ921;                          // ISDN Q.921 implementation on top of a hardware interface
00139 class ISDNQ921Passive;                   // Stateless ISDN Q.921 implementation on top of a hardware interface
00140 class ISDNQ921Management;                // ISDN Layer 2 BRI TEI management or PRI with D-channel(s) backup
00141 class ISDNIUA;                           // SIGTRAN ISDN Q.921 User Adaptation Layer
00142 class ISDNQ931IE;                        // A Q.931 ISDN Layer 3 message Information Element
00143 class ISDNQ931Message;                   // A Q.931 ISDN Layer 3 message
00144 class ISDNQ931IEData;                    // A Q.931 message IE data processor
00145 class ISDNQ931State;                     // Q.931 ISDN call and call controller state
00146 class ISDNQ931Call;                      // A Q.931 ISDN call
00147 class ISDNQ931CallMonitor;               // A Q.931 ISDN call monitor
00148 class ISDNQ931ParserData;                // Q.931 message parser data
00149 class ISDNQ931;                          // ISDN Q.931 implementation on top of Q.921
00150 class ISDNQ931Monitor;                   // ISDN Q.931 implementation on top of Q.921 of call controller monitor
00151 
00152 // Macro to create a factory that builds a component by class name
00153 #define YSIGFACTORY(clas) \
00154 class clas ## Factory : public SignallingFactory \
00155 { \
00156 protected: \
00157 virtual SignallingComponent* create(const String& type, const NamedList& name) \
00158     { return (type == #clas) ? new clas : 0; } \
00159 }; \
00160 static clas ## Factory s_ ## clas ## Factory
00161 
00162 // Macro to create a factory that calls a component's static create method
00163 #define YSIGFACTORY2(clas) \
00164 class clas ## Factory : public SignallingFactory \
00165 { \
00166 protected: \
00167 virtual SignallingComponent* create(const String& type, const NamedList& name) \
00168     { return clas::create(type,name); } \
00169 }; \
00170 static clas ## Factory s_ ## clas ## Factory
00171 
00172 // Macro to call the factory creation method and return the created component
00173 #define YSIGCREATE(type,name) (static_cast<type*>(SignallingFactory::buildInternal(#type,name)))
00174 
00179 class YSIG_API SignallingDumper
00180 {
00181 public:
00185     enum Type {
00186         Raw,
00187         Hexa,
00188         Hdlc,
00189         Q921,
00190         Q931,
00191         Mtp2,
00192         Mtp3,
00193         Sccp,
00194     };
00195 
00201     SignallingDumper(Type type = Hexa, bool network = false);
00202 
00206     ~SignallingDumper();
00207 
00212     inline Type type() const
00213         { return m_type; }
00214 
00219     inline bool network() const
00220         { return m_network; }
00221 
00226     bool active() const;
00227 
00231     void terminate();
00232 
00238     void setStream(Stream* stream = 0, bool writeHeader = true);
00239 
00248     bool dump(void* buf, unsigned int len, bool sent = false, int link = 0);
00249 
00257     inline bool dump(const DataBlock& data, bool sent = false, int link = 0)
00258         { return dump(data.data(),data.length(),sent,link); }
00259 
00270     static SignallingDumper* create(DebugEnabler* dbg, const char* filename, Type type,
00271         bool network = false, bool create = true, bool append = false);
00272 
00281     static SignallingDumper* create(Stream* stream, Type type, bool network = false, bool writeHeader = true);
00282 
00283 private:
00284     void head();
00285     Type m_type;
00286     bool m_network;
00287     Stream* m_output;
00288 };
00289 
00294 class YSIG_API SignallingDumpable
00295 {
00296 public:
00300     inline ~SignallingDumpable()
00301         { setDumper(); }
00302 
00303 protected:
00309     inline SignallingDumpable(SignallingDumper::Type type, bool network = false)
00310         : m_type(type), m_dumpNet(network), m_dumper(0)
00311         { }
00312 
00321     inline bool dump(void* buf, unsigned int len, bool sent = false, int link = 0)
00322         { return (m_dumper && m_dumper->dump(buf,len,sent,link)); }
00323 
00331     inline bool dump(const DataBlock& data, bool sent = false, int link = 0)
00332         { return dump(data.data(),data.length(),sent,link); }
00333 
00338     inline void setDumpNetwork(bool network)
00339         { m_dumpNet = network; }
00340 
00345     void setDumper(SignallingDumper* dumper = 0);
00346 
00354     bool setDumper(const String& name, bool create = true, bool append = false);
00355 
00362     bool control(NamedList& params, SignallingComponent* owner = 0);
00363 
00364 private:
00365     SignallingDumper::Type m_type;
00366     bool m_dumpNet;
00367     SignallingDumper* m_dumper;
00368 };
00369 
00375 class YSIG_API SignallingNotifier
00376 {
00377 public:
00381     virtual inline ~SignallingNotifier()
00382         { cleanup(); }
00387     virtual void notify(NamedList& notifs);
00391     virtual void cleanup();
00392 };
00393 
00398 class YSIG_API SignallingTimer
00399 {
00400 public:
00406     inline SignallingTimer(u_int64_t interval, u_int64_t time = 0)
00407         : m_interval(interval), m_timeout(0)
00408         { if (time) start(time); }
00409 
00414     inline void interval(u_int64_t value)
00415         { m_interval = value; }
00416 
00427     inline void interval(const NamedList& params, const char* param,
00428         unsigned int minVal, unsigned int defVal, bool allowDisable, bool sec = false) {
00429             m_interval = getInterval(params,param,minVal,defVal,0,allowDisable);
00430             if (sec)
00431                 m_interval *= 1000;
00432         }
00433 
00438     inline u_int64_t interval() const
00439         { return m_interval; }
00440 
00445     inline u_int64_t fireTime() const
00446         { return m_timeout; }
00447 
00452     inline void start(u_int64_t time = Time::msecNow())
00453         { if (m_interval) m_timeout = time + m_interval; }
00454 
00459     inline void fire(u_int64_t time = Time::msecNow())
00460         { m_timeout = time; }
00461 
00465     inline void stop()
00466         { m_timeout = 0; }
00467 
00472     inline bool started() const
00473         { return m_timeout > 0; }
00474 
00480     inline bool timeout(u_int64_t time = Time::msecNow()) const
00481         { return started() && (m_timeout < time); }
00482 
00493     static unsigned int getInterval(const NamedList& params, const char* param,
00494         unsigned int minVal, unsigned int defVal, unsigned int maxVal = 0,
00495         bool allowDisable = false);
00496 
00497 private:
00498     u_int64_t m_interval;                // Timer interval
00499     u_int64_t m_timeout;                 // Timeout value
00500 };
00501 
00506 class YSIG_API SignallingCounter
00507 {
00508 public:
00513     inline SignallingCounter(u_int32_t maxVal)
00514         : m_max(maxVal), m_count(0)
00515         { }
00516 
00521     inline void maxVal(u_int32_t value)
00522         { m_max = value; }
00523 
00528     inline u_int32_t maxVal() const
00529         { return m_max; }
00530 
00535     inline u_int32_t count() const
00536         { return m_count; }
00537 
00542     inline void reset(bool down = true)
00543         { m_count = down ? 0 : m_max; }
00544 
00549     inline bool inc()
00550     {
00551         if (full())
00552             return false;
00553         m_count++;
00554         return true;
00555     }
00556 
00561     inline bool dec()
00562     {
00563         if (empty())
00564             return false;
00565         m_count--;
00566         return true;
00567     }
00568 
00573     inline bool empty() const
00574         { return m_count == 0; }
00575 
00580     inline bool full() const
00581         { return m_count == maxVal(); }
00582 
00583 private:
00584     u_int32_t m_max;                     // Maximum counter value
00585     u_int32_t m_count;                   // Current counter value
00586 };
00587 
00592 class YSIG_API SignallingFactory : public GenObject
00593 {
00594 public:
00599     SignallingFactory(bool fallback = false);
00600 
00604     virtual ~SignallingFactory();
00605 
00612     static SignallingComponent* build(const String& type, const NamedList* name = 0);
00613 
00620     static void* buildInternal(const String& type, const NamedList* name);
00621 
00622 protected:
00629     virtual SignallingComponent* create(const String& type, const NamedList& name) = 0;
00630 };
00631 
00637 class YSIG_API SignallingComponent : public RefObject, public DebugEnabler
00638 {
00639     YCLASS(SignallingComponent,RefObject)
00640     friend class SignallingEngine;
00641 public:
00645     virtual ~SignallingComponent();
00646 
00651     virtual const String& toString() const;
00652 
00658     virtual bool initialize(const NamedList* config);
00659 
00665     virtual bool control(NamedList& params);
00666 
00672     virtual NamedList* controlCreate(const char* oper = 0);
00673 
00679     virtual bool controlExecute(NamedList* params);
00680 
00686     virtual void engine(SignallingEngine* eng);
00687 
00692     inline SignallingEngine* engine() const
00693         { return m_engine; }
00694 
00700     inline int debugLevel(int level)
00701         { return (level >= 0) ? DebugEnabler::debugLevel(level) : DebugEnabler::debugLevel(); }
00702 
00707     inline const String& componentType() const
00708         { return m_compType; }
00709 
00710 protected:
00716     SignallingComponent(const char* name = 0, const NamedList* params = 0);
00717 
00722     virtual void destroyed();
00723 
00729     void insert(SignallingComponent* component);
00730 
00737     virtual void detach();
00738 
00743     virtual void timerTick(const Time& when);
00744 
00749     void setName(const char* name);
00750 
00755     inline void setCompType(const char* type)
00756         { m_compType = type; }
00757 
00764     unsigned long tickSleep(unsigned long usec = 1000000) const;
00765 
00766 private:
00767     SignallingEngine* m_engine;
00768     String m_name;
00769     String m_compType;
00770 };
00771 
00777 class YSIG_API SignallingEngine : public DebugEnabler, public Mutex
00778 {
00779     friend class SignallingComponent;
00780     friend class SignallingThreadPrivate;
00781 public:
00786     SignallingEngine(const char* name = "signalling");
00787 
00791     virtual ~SignallingEngine();
00792 
00798     static SignallingEngine* self(bool create = false);
00799 
00804     void insert(SignallingComponent* component);
00805 
00810     void remove(SignallingComponent* component);
00811 
00817     bool remove(const String& name);
00818 
00824     SignallingComponent* find(const String& name);
00825 
00833     SignallingComponent* find(const String& name, const String& type, const SignallingComponent* start = 0);
00834 
00843     SignallingComponent* build(const String& type, const NamedList& params, bool init = false, bool ref = true);
00844 
00850     bool control(NamedList& params);
00851 
00857     bool find(const SignallingComponent* component);
00858 
00864     void notify(SignallingComponent* component, NamedList notifs);
00865 
00873     bool start(const char* name = "Sig Engine", Thread::Priority prio = Thread::Normal, unsigned long usec = 0);
00874 
00878     void stop();
00879 
00884     inline void setNotifier(SignallingNotifier* notifier)
00885         { m_notifier = notifier; }
00886 
00891     inline void removeNotifier(SignallingNotifier* notifier)
00892     {
00893         if (m_notifier == notifier)
00894             m_notifier = 0;
00895     }
00896 
00901     Thread* thread() const;
00902 
00909     unsigned long tickSleep(unsigned long usec = 1000000);
00910 
00915     inline unsigned long tickDefault() const
00916         { return m_usecSleep; }
00917 
00922     inline static long maxLockWait()
00923         { return s_maxLockWait; }
00924 
00929     static void maxLockWait(long maxWait);
00930 
00936     template <class Obj> static inline void destruct(Obj*& obj)
00937     {
00938         if (!obj)
00939             return;
00940         if (obj->engine())
00941             obj->engine()->remove(obj);
00942         TelEngine::destruct(obj);
00943     }
00944 
00945 protected:
00951     virtual unsigned long timerTick(const Time& when);
00952 
00956     ObjList m_components;
00957 
00958 private:
00959     SignallingThreadPrivate* m_thread;
00960     SignallingNotifier* m_notifier;
00961     unsigned long m_usecSleep;
00962     unsigned long m_tickSleep;
00963     static long s_maxLockWait;
00964 };
00965 
00970 class YSIG_API SignallingMessage : public RefObject
00971 {
00972     YCLASS(SignallingMessage,RefObject)
00973 public:
00978     inline SignallingMessage(const char* name = 0)
00979         : m_params(name)
00980         { }
00981 
00986     inline const char* name() const
00987         { return m_params.c_str(); }
00988 
00993     inline NamedList& params()
00994         { return m_params; }
00995 
01000     inline const NamedList& params() const
01001         { return m_params; }
01002 
01003 protected:
01007     NamedList m_params;
01008 };
01009 
01014 class YSIG_API SignallingCallControl : public Mutex
01015 {
01016     friend class SignallingCall;
01017     friend class SS7ISUPCall;
01018     friend class ISDNQ931Call;
01019     friend class ISDNQ931CallMonitor;
01020 public:
01021 
01025     enum MediaRequired {
01026         MediaNever,
01027         MediaAnswered,
01028         MediaRinging,
01029         MediaAlways
01030     };
01031 
01038     SignallingCallControl(const NamedList& params, const char* msgPrefix = 0);
01039 
01043     virtual ~SignallingCallControl();
01044 
01049     inline const String& location() const
01050         { return m_location; }
01051 
01055     inline void setExiting()
01056         { m_exiting = true; }
01057 
01062     inline bool exiting() const
01063         { return m_exiting; }
01064 
01069     inline bool verify()
01070     {
01071         Lock lock(this);
01072         if (!m_verifyEvent)
01073             return false;
01074         m_verifyEvent = false;
01075         return true;
01076     }
01077 
01082     inline MediaRequired mediaRequired() const
01083         { return m_mediaRequired; }
01084 
01090     inline const String& msgPrefix() const
01091         { return m_msgPrefix; }
01092 
01097     inline SignallingCircuitGroup* circuits() const
01098         { return m_circuits; }
01099 
01104     inline const ObjList& calls() const
01105         { return m_calls; }
01106 
01111     virtual const char* statusName() const = 0;
01112 
01121     SignallingCircuitGroup* attach(SignallingCircuitGroup* circuits);
01122 
01139     bool reserveCircuit(SignallingCircuit*& cic, const char* range = 0, int checkLock = -1,
01140         const String* list = 0, bool mandatory = true, bool reverseRestrict = false);
01141 
01149     bool releaseCircuit(SignallingCircuit*& cic, bool sync = false);
01150 
01158     bool releaseCircuit(unsigned int code, bool sync = false);
01159 
01164     virtual void cleanup(const char* reason = "net-out-of-order")
01165         { }
01166 
01172     virtual SignallingEvent* getEvent(const Time& when);
01173 
01180     virtual SignallingCall* call(SignallingMessage* msg, String& reason)
01181         { reason = "not-implemented"; return 0; }
01182 
01187     virtual void buildVerifyEvent(NamedList& params)
01188         { }
01189 
01190 protected:
01195     inline int strategy() const
01196         { return m_strategy; }
01197 
01205     virtual bool processEvent(SignallingEvent* event)
01206         { return false; }
01207 
01214     virtual SignallingEvent* processCircuitEvent(SignallingCircuitEvent*& event,
01215         SignallingCall* call = 0)
01216         { TelEngine::destruct(event); return 0; }
01217 
01221     void clearCalls();
01222 
01228     void removeCall(SignallingCall* call, bool del = false);
01229 
01236     void setVerify(bool restartTimer = false, bool fireNow = false, const Time* time = 0);
01237 
01241     ObjList m_calls;
01242 
01247     String m_msgPrefix;
01248 
01252     MediaRequired m_mediaRequired;
01253 
01258     bool m_verifyEvent;
01259 
01263     SignallingTimer m_verifyTimer;
01264 
01268     String m_location;
01269 
01273     static const TokenDict s_mediaRequired[];
01274 
01275 private:
01276     SignallingCircuitGroup* m_circuits;  // Circuit group
01277     int m_strategy;                      // Strategy to allocate circuits for outgoing calls
01278     bool m_exiting;                      // Call control is terminating. Generate a Disable event when no more calls
01279 };
01280 
01285 class YSIG_API SignallingCall : public RefObject, public Mutex
01286 {
01287 public:
01294     SignallingCall(SignallingCallControl* controller, bool outgoing, bool signalOnly = false);
01295 
01299     virtual ~SignallingCall();
01300 
01305     inline bool outgoing() const
01306         { return m_outgoing; }
01307 
01311     inline SignallingCallControl* controller() const
01312         { return m_controller; }
01313 
01318     inline void userdata(void* data)
01319         { m_private = data; }
01320 
01325     inline void* userdata() const
01326         { return m_private; }
01327 
01332     inline bool signalOnly() const
01333         { return m_signalOnly; }
01334 
01339     inline bool overlapDialing() const
01340         { return m_overlap; }
01341 
01347     virtual bool sendEvent(SignallingEvent* event)
01348         { return false; }
01349 
01356     virtual SignallingEvent* getEvent(const Time& when) = 0;
01357 
01364     virtual void eventTerminated(SignallingEvent* event);
01365 
01366 protected:
01372     void enqueue(SignallingMessage* msg);
01373 
01380     SignallingMessage* dequeue(bool remove = true);
01381 
01385     void clearQueue()
01386     {
01387         Lock lock(m_inMsgMutex);
01388         m_inMsg.clear();
01389     }
01390 
01394     SignallingEvent* m_lastEvent;
01395 
01399     bool m_overlap;
01400 
01401 private:
01402     SignallingCallControl* m_controller; // Call controller this call belongs to
01403     bool m_outgoing;                     // Call direction
01404     bool m_signalOnly;                   // Just signalling flag
01405     ObjList m_inMsg;                     // Incoming messages queue
01406     Mutex m_inMsgMutex;                  // Lock incoming messages queue
01407     void* m_private;                     // Private user data
01408 };
01409 
01414 class YSIG_API SignallingEvent
01415 {
01416 public:
01420     enum Type {
01421         Unknown = 0,
01422         Generic,
01423         // Call related
01424         NewCall,
01425         Accept,
01426         Connect,
01427         Complete,
01428         Progress,
01429         Ringing,
01430         Answer,
01431         Transfer,
01432         Suspend,
01433         Resume,
01434         Release,
01435         Info,
01436         // Non-call related
01437         Message,
01438         Facility,
01439         Circuit,
01440         // Controller related
01441         Enable,
01442         Disable,
01443         Reset,
01444         Verify,
01445     };
01446 
01453     SignallingEvent(Type type, SignallingMessage* message, SignallingCall* call);
01454 
01461     SignallingEvent(Type type, SignallingMessage* message, SignallingCallControl* controller = 0);
01462 
01468     SignallingEvent(SignallingCircuitEvent*& event, SignallingCall* call);
01469 
01473     virtual ~SignallingEvent();
01474 
01479     inline const char* name() const
01480         { return typeName(type()); }
01481 
01486     inline Type type() const
01487         { return m_type; }
01488 
01492     inline SignallingCall* call() const
01493         { return m_call; }
01494 
01498     inline SignallingMessage* message() const
01499         { return m_message; }
01500 
01504     inline SignallingCallControl* controller() const
01505         { return m_controller; }
01506 
01510     inline SignallingCircuitEvent* cicEvent() const
01511         { return m_cicEvent; }
01512 
01518     static inline const char* typeName(Type t)
01519         { return lookup(t,s_types,0); }
01520 
01525     bool sendEvent();
01526 
01527 private:
01528     Type m_type;
01529     SignallingMessage* m_message;
01530     SignallingCall* m_call;
01531     SignallingCallControl* m_controller;
01532     SignallingCircuitEvent* m_cicEvent;
01533     static const TokenDict s_types[];
01534 };
01535 
01540 class YSIG_API SignallingCircuitEvent : public NamedList
01541 {
01542 public:
01546     enum Type {
01547         Unknown      = 0,
01548         Dtmf         = 1,                // Transfer tones: param: tone
01549         GenericTone  = 2,                // Play or detect tones: param: tone
01550         // Analog line events
01551         Timeout      = 10,               // 
01552         Polarity     = 11,               // Line's polarity changed
01553         StartLine    = 15,               // Initialize FXO line
01554         LineStarted  = 16,               // FXO line initialized: send number
01555         DialComplete = 17,               // FXO line completed dialing the number
01556         OnHook       = 20,               // The hook is down
01557         OffHook      = 21,               // The hook is up
01558         RingBegin    = 22,               // Start ringing
01559         RingEnd      = 23,               // Stop ringing
01560         RingerOn     = 30,               // An FXS started the FXO's ringer
01561         RingerOff    = 31,               // An FXS stopped the FXO's ringer
01562         Wink         = 32,               // On hook momentarily
01563         Flash        = 33,               // Off hook momentarily
01564         PulseStart   = 40,               // Pulse dialing start
01565         PulseDigit   = 41,               // Transfer pulse digits: param: pulse
01566         // Remote circuit events
01567         Connect      = 50,               // Request connect
01568         Disconnect   = 51,               // Request disconnect
01569         Connected    = 52,               // Connected notification
01570         Disconnected = 53,               // Disconnected notification
01571         // Errors
01572         Alarm        = 100,              // Param: alarms (comma separated list of strings)
01573         NoAlarm      = 101,              // No more alarms
01574     };
01575 
01582     SignallingCircuitEvent(SignallingCircuit* cic, Type type, const char* name = 0);
01583 
01587     virtual ~SignallingCircuitEvent();
01588 
01593     inline Type type() const
01594         { return m_type; }
01595 
01600     inline SignallingCircuit* circuit()
01601         { return m_circuit; }
01602 
01607     bool sendEvent();
01608 
01609 private:
01610     SignallingCircuit* m_circuit;
01611     Type m_type;
01612 };
01613 
01618 class YSIG_API SignallingCircuit : public RefObject
01619 {
01620     YCLASS(SignallingCircuit,RefObject)
01621     friend class SignallingCircuitGroup;
01622     friend class SignallingCircuitEvent;
01623 public:
01627     enum Type {
01628         Unknown = 0,
01629         Local, // not really a circuit
01630         TDM,
01631         RTP,
01632         IAX,
01633     };
01634 
01638     enum Status {
01639         Missing = 0,
01640         Disabled,
01641         Idle,
01642         Reserved,
01643         Starting,
01644         Stopping,
01645         Special,
01646         Connected,
01647     };
01648 
01652     enum LockFlags {
01653         LockLocalHWFail       = 0x0001,  // Local side of the circuit is locked due to HW failure
01654         LockLocalMaint        = 0x0002,  // Local side of the circuit is locked for maintenance
01655         LockingHWFail         = 0x0004,  // Circuit (un)lock due to HW failure in progress
01656         LockingMaint          = 0x0008,  // Circuit (un)lock due to maintenance in progress
01657         LockLocalHWFailChg    = 0x0010,  // Local HW failure flag changed
01658         LockLocalMaintChg     = 0x0020,  // Local maintenance flag changed
01659         Resetting             = 0x0040,  // Circuit is beeing reset
01660         LockRemoteHWFail      = 0x0100,  // Remote side of the circuit is locked due to HW failure
01661         LockRemoteMaint       = 0x0200,  // Remote side of the circuit is locked for maintenance
01662         LockRemoteHWFailChg   = 0x1000,  // Remote HW failure flag changed
01663         LockRemoteMaintChg    = 0x2000,  // Remote maintenance flag changed
01664         // Masks used to test lock conditions
01665         LockLocal             = LockLocalHWFail | LockLocalMaint,
01666         LockRemote            = LockRemoteHWFail | LockRemoteMaint,
01667         LockLocked            = LockLocal | LockRemote,
01668         LockBusy              = LockingHWFail | LockingMaint | Resetting,
01669         LockLockedBusy        = LockLocked | LockBusy,
01670         LockLocalChg          = LockLocalHWFailChg | LockLocalMaintChg,
01671         LockRemoteChg         = LockRemoteHWFailChg | LockRemoteMaintChg,
01672         LockChanged           = LockLocalChg | LockRemoteChg,
01673     };
01674 
01678     virtual ~SignallingCircuit();
01679 
01686     virtual bool status(Status newStat, bool sync = false)
01687         { m_status = newStat; return true; }
01688 
01693     inline Type type() const
01694         { return m_type; }
01695 
01700     inline Status status() const
01701         { return m_status; }
01702 
01708     inline int locked(int flags = -1) const
01709         { return (m_lock & flags); }
01710 
01715     inline void setLock(int flags)
01716         { m_lock |= flags; }
01717 
01722     inline void resetLock(int flags)
01723         { m_lock &= ~flags; }
01724 
01731     virtual bool updateFormat(const char* format, int direction)
01732         { return false; }
01733 
01740     virtual bool setParam(const String& param, const String& value)
01741         { return false; }
01742 
01748     virtual bool setParams(const NamedList& params);
01749 
01756     virtual bool getParam(const String& param, String& value) const
01757         { return false; }
01758 
01765     virtual bool getBoolParam(const String& param, bool defValue = false) const
01766         { return defValue; }
01767 
01774     virtual int getIntParam(const String& param, int defValue = 0) const
01775         { return defValue; }
01776 
01783     virtual bool getParams(NamedList& params, const String& category = String::empty())
01784         { return false; }
01785 
01790     inline SignallingCircuitGroup* group()
01791         { return m_group; }
01792 
01797     inline SignallingCircuitSpan* span()
01798         { return m_span; }
01799 
01804     inline const SignallingCircuitGroup* group() const
01805         { return m_group; }
01806 
01811     inline const SignallingCircuitSpan* span() const
01812         { return m_span; }
01813 
01818     inline unsigned int code() const
01819         { return m_code; }
01820 
01825     inline bool available() const
01826         { return m_status == Idle; }
01827 
01832     inline bool connected() const
01833         { return m_status == Connected; }
01834 
01839     inline bool reserve()
01840         { return available() && status(Reserved,true); }
01841 
01847     inline bool connect(const char* format = 0)
01848         { updateFormat(format,0); return status(Connected,true); }
01849 
01854     inline bool disconnect()
01855         { return status() == Connected && status(Reserved,true); }
01856 
01861     inline bool disable()
01862         { return status(Disabled,true); }
01863 
01872     bool hwLock(bool set, bool remote, bool changed = false, bool setChanged = false);
01873 
01882     bool maintLock(bool set, bool remote, bool changed = false, bool setChanged = false);
01883 
01889     void addEvent(SignallingCircuitEvent* event);
01890 
01897     SignallingCircuitEvent* getEvent(const Time& when);
01898 
01905     virtual bool sendEvent(SignallingCircuitEvent::Type type, NamedList* params = 0);
01906 
01912     static const char* lookupType(int type);
01913 
01919     static const char* lookupStatus(int status);
01920 
01924     static const TokenDict s_lockNames[];
01925 
01926 protected:
01930     SignallingCircuit(Type type, unsigned int code, SignallingCircuitGroup* group = 0,
01931         SignallingCircuitSpan* span = 0);
01932 
01936     SignallingCircuit(Type type, unsigned int code, Status status,
01937         SignallingCircuitGroup* group = 0, SignallingCircuitSpan* span = 0);
01938 
01943     virtual void clearEvents();
01944 
01949     void eventTerminated(SignallingCircuitEvent* event);
01950 
01954     Mutex m_mutex;
01955 
01956 private:
01957     SignallingCircuitGroup* m_group;     // The group owning this circuit
01958     SignallingCircuitSpan* m_span;       // The span this circuit belongs to
01959     unsigned int m_code;                 // Circuit id
01960     Type m_type;                         // Circuit type (see enumeration)
01961     Status m_status;                     // Circuit local status
01962     int m_lock;                          // Circuit lock flags
01963     ObjList m_events;                    // In-band events
01964     SignallingCircuitEvent* m_lastEvent; // The last generated event
01965     bool m_noEvents;                     // No events pending, exit quickly
01966 };
01967 
01975 class YSIG_API SignallingCircuitRange : public String
01976 {
01977     YCLASS(SignallingCircuitRange,String)
01978     friend class SignallingCircuitGroup;
01979 public:
01986     SignallingCircuitRange(const String& rangeStr, const char* name = 0,
01987         int strategy = -1);
01988 
01992     virtual ~SignallingCircuitRange()
01993         { clear(); }
01994 
01999     inline unsigned int count() const
02000         { return m_count; }
02001 
02006     inline const unsigned int* range() const
02007         { return (const unsigned int*)m_range.data(); }
02008 
02015     unsigned int* copyRange(unsigned int& count) const;
02016 
02021     inline void clear() 
02022         { m_range.clear(); m_count = 0; }
02023 
02029     inline unsigned int operator[](unsigned int index)
02030         { return range()[index]; }
02031 
02037     inline bool set(const String& rangeStr)
02038     {
02039         clear();
02040         return add(rangeStr);
02041     }
02042 
02048     bool add(const String& rangeStr);
02049 
02055     void add(unsigned int* codes, unsigned int len);
02056 
02061     inline void add(unsigned int code)
02062         { add(&code,1); }
02063 
02069     void add(unsigned int first, unsigned int last);
02070 
02075     void remove(unsigned int code);
02076 
02082     bool find(unsigned int code);
02083 
02087     virtual void destruct()
02088     {
02089         clear();
02090         String::destruct();
02091     }
02092 
02093 protected:
02094     void updateLast();                   // Update last circuit code
02095 
02096     DataBlock m_range;                   // Array containing the circuit codes
02097     unsigned int m_count;                // The number of elements in the array
02098     unsigned int m_last;                 // Last (the greater) not used circuit code within this range
02099     int m_strategy;                      // Keep the strategy used to allocate circuits from this range
02100     unsigned int m_used;                 // Last used circuit code
02101 };
02102 
02107 class YSIG_API SignallingCircuitGroup : public SignallingComponent, public Mutex
02108 {
02109     YCLASS(SignallingCircuitGroup,SignallingComponent)
02110     friend class SignallingCircuit;
02111     friend class SignallingCallControl;
02112     friend class SS7ISUP;
02113     friend class ISDNQ931;
02114 public:
02118     enum Strategy {
02119         Other     = 0,
02120         // basic strategies
02121         Increment = 0x0001, // round-robin, up
02122         Decrement = 0x0002, // round-robin, down
02123         Lowest    = 0x0003, // pick first available
02124         Highest   = 0x0004, // pick last available
02125         Random    = 0x0005, // pick random circuit
02126         // even/odd strict select (glare avoidance)
02127         OnlyEven  = 0x1000,
02128         OnlyOdd   = 0x2000,
02129         // glare avoidance with fallback (to be able to use all circuits)
02130         Fallback  = 0x4000,
02131     };
02132 
02139     SignallingCircuitGroup(unsigned int base = 0, int strategy = Increment,
02140         const char* name = "circgroup");
02141 
02145     virtual ~SignallingCircuitGroup();
02146 
02151     inline unsigned int count() const
02152         { return m_circuits.count(); }
02153 
02158     inline unsigned int base() const
02159         { return m_base; }
02160 
02165     inline unsigned int last() const
02166         { return m_range.m_last; }
02167 
02172     inline int strategy() const
02173         { return m_range.m_strategy; }
02174 
02179     inline void setStrategy(int strategy)
02180         { Lock lock(this); m_range.m_strategy = strategy; }
02181 
02185     inline ObjList& circuits()
02186         { return m_circuits; }
02187 
02192     void getCicList(String& dest);
02193 
02199     bool insert(SignallingCircuit* circuit);
02200 
02205     void remove(SignallingCircuit* circuit);
02206 
02214     SignallingCircuitSpan* buildSpan(const String& name, unsigned int start = 0, NamedList* params = 0);
02215 
02221     bool insertSpan(SignallingCircuitSpan* span);
02222 
02230     void insertRange(SignallingCircuitSpan* span, const char* name,
02231         int strategy = -1);
02232 
02241     void insertRange(const String& range, const char* name,
02242         int strategy = -1);
02243 
02250     void removeSpan(SignallingCircuitSpan* span, bool delCics = true, bool delSpan = false);
02251 
02256     void removeSpanCircuits(SignallingCircuitSpan* span);
02257 
02264     SignallingCircuit* find(unsigned int cic, bool local = false);
02265 
02271     SignallingCircuitRange* findRange(const char* name);
02272 
02278     SignallingCircuit::Status status(unsigned int cic);
02279 
02287     bool status(unsigned int cic, SignallingCircuit::Status newStat, bool sync = false);
02288 
02296     SignallingCircuit* reserve(int checkLock = -1, int strategy = -1,
02297         SignallingCircuitRange* range = 0);
02298 
02310     SignallingCircuit* reserve(const String& list, bool mandatory,
02311         int checkLock = -1, int strategy = -1, SignallingCircuitRange* range = 0);
02312 
02319     inline bool release(SignallingCircuit* cic, bool sync = false)
02320         { return cic && cic->status(SignallingCircuit::Idle,sync); }
02321 
02328     static int str2strategy(const char* name, int def = Increment)
02329         { return lookup(name,s_strategy,def); }
02330 
02334     static const TokenDict s_strategy[];
02335 
02336 protected:
02340     virtual void destroyed()
02341     {
02342         clearAll();
02343         SignallingComponent::destroyed();
02344     }
02345 
02346 private:
02347     unsigned int advance(unsigned int n, int strategy, SignallingCircuitRange& range);
02348     void clearAll();
02349 
02350     ObjList m_circuits;                  // The circuits belonging to this group
02351     ObjList m_spans;                     // The spans belonging to this group
02352     ObjList m_ranges;                    // Additional circuit ranges
02353     SignallingCircuitRange m_range;      // Range containing all circuits belonging to this group
02354     unsigned int m_base;
02355 };
02356 
02361 class YSIG_API SignallingCircuitSpan : public SignallingComponent
02362 {
02363     YCLASS(SignallingCircuitSpan,SignallingComponent)
02364 public:
02368     virtual ~SignallingCircuitSpan();
02369 
02374     inline SignallingCircuitGroup* group() const
02375         { return m_group; }
02376 
02381     inline const String& id() const
02382         { return m_id; }
02383 
02388     inline unsigned int increment() const
02389         { return m_increment; }
02390 
02391 protected:
02397     SignallingCircuitSpan(const char* id = 0, SignallingCircuitGroup* group = 0);
02398 
02402     SignallingCircuitGroup* m_group;
02403 
02407     unsigned int m_increment;
02408 
02409 private:
02410     String m_id;                         // Span's id
02411 };
02412 
02417 class YSIG_API SignallingInterface : virtual public SignallingComponent
02418 {
02419     YCLASS(SignallingInterface,SignallingComponent)
02420     friend class SignallingReceiver;
02421 public:
02425     enum Operation {
02426         Specific  = 0,
02427         EnableTx  = 0x01,
02428         EnableRx  = 0x02,
02429         Enable    = 0x03,
02430         DisableTx = 0x04,
02431         DisableRx = 0x08,
02432         Disable   = 0x0c,
02433         FlushTx   = 0x10,
02434         FlushRx   = 0x20,
02435         Flush     = 0x30,
02436         QueryTx   = 0x40,
02437         QueryRx   = 0x80,
02438         Query     = 0xc0
02439     };
02440 
02444     enum Notification {
02445         LinkUp = 0,
02446         LinkDown,
02447         HardwareError,
02448         TxClockError,
02449         RxClockError,
02450         AlignError,
02451         CksumError,
02452         TxOversize,
02453         RxOversize,
02454         TxOverflow,
02455         RxOverflow,
02456         TxUnderrun,
02457         RxUnderrun,
02458     };
02459 
02463     enum PacketType {
02464         Unknown = 0,
02465         SS7Fisu,
02466         SS7Lssu,
02467         SS7Msu,
02468         Q921
02469     };
02470 
02474     inline SignallingInterface()
02475         : m_recvMutex(true,"SignallingInterface::recv"), m_receiver(0)
02476         { }
02477 
02481     virtual ~SignallingInterface();
02482 
02487     virtual void attach(SignallingReceiver* receiver);
02488 
02493     inline SignallingReceiver* receiver() const
02494         { return m_receiver; }
02495 
02505     virtual bool control(Operation oper, NamedList* params = 0);
02506 
02510     static const TokenDict s_notifName[];
02511 
02512 protected:
02521     virtual bool transmitPacket(const DataBlock& packet, bool repeat, PacketType type) = 0;
02522 
02528     bool receivedPacket(const DataBlock& packet);
02529 
02535     bool notify(Notification event);
02536 
02537 private:
02538     Mutex m_recvMutex;                   // Lock receiver pointer operations
02539     SignallingReceiver* m_receiver;
02540 };
02541 
02546 class YSIG_API SignallingReceiver : virtual public SignallingComponent
02547 {
02548     YCLASS(SignallingReceiver,SignallingComponent)
02549     friend class SignallingInterface;
02550 public:
02555     SignallingReceiver(const char* name = 0);
02556 
02560     virtual ~SignallingReceiver();
02561 
02567     virtual SignallingInterface* attach(SignallingInterface* iface);
02568 
02573     inline SignallingInterface* iface() const
02574         { return m_interface; }
02575 
02583     bool control(SignallingInterface::Operation oper, NamedList* params = 0);
02584 
02585 protected:
02594     bool transmitPacket(const DataBlock& packet, bool repeat,
02595         SignallingInterface::PacketType type = SignallingInterface::Unknown);
02596 
02601     virtual bool receivedPacket(const DataBlock& packet) = 0;
02602 
02608     virtual bool notify(SignallingInterface::Notification event);
02609 
02610 private:
02611     Mutex m_ifaceMutex;                  // Lock interface pointer operations
02612     SignallingInterface* m_interface;
02613 };
02614 
02615 
02620 struct SignallingFlags
02621 {
02625     unsigned int mask;
02626 
02630     unsigned int value;
02631 
02635     const char* name;
02636 };
02637 
02642 class YSIG_API SignallingUtils
02643 {
02644 public:
02649     static const TokenDict* codings();
02650 
02655     static const TokenDict* locations();
02656 
02668     static inline const TokenDict* dict(unsigned int index, unsigned char coding = 0)
02669     {
02670         if (index > 4)
02671             return 0;
02672         return (!coding ? s_dictCCITT[index] : 0);
02673     }
02674 
02681     static bool hasFlag(const String& flags, const char* flag);
02682 
02689     static bool appendFlag(String& flags, const char* flag);
02690 
02697     static bool removeFlag(String& flags, const char* flag);
02698 
02706     static bool hasFlag(const NamedList& list, const char* param, const char* flag);
02707 
02715     static bool appendFlag(NamedList& list, const char* param, const char* flag);
02716 
02724     static void addKeyword(NamedList& list, const char* param,
02725         const TokenDict* tokens, unsigned int val);
02726 
02736     static void dumpData(const SignallingComponent* comp, NamedList& list, const char* param,
02737         const unsigned char* buf, unsigned int len, char sep = ' ');
02738 
02751     static unsigned int dumpDataExt(const SignallingComponent* comp, NamedList& list, const char* param,
02752         const unsigned char* buf, unsigned int len, char sep = ' ');
02753 
02765     static bool decodeFlags(const SignallingComponent* comp, NamedList& list, const char* param,
02766         const SignallingFlags* flags, const unsigned char* buf, unsigned int len);
02767 
02778     static bool decodeCause(const SignallingComponent* comp, NamedList& list, const unsigned char* buf,
02779         unsigned int len, const char* prefix, bool isup);
02780 
02791     static bool decodeCaps(const SignallingComponent* comp, NamedList& list, const unsigned char* buf,
02792         unsigned int len, const char* prefix, bool isup);
02793 
02803     static void encodeFlags(const SignallingComponent* comp, int& dest, const String& flags,
02804         const TokenDict* dict);
02805 
02814     static unsigned int encodeFlags(const SignallingComponent* comp, const String& flags,
02815         const SignallingFlags* dict, const char* paramName = 0);
02816 
02828     static bool encodeCause(const SignallingComponent* comp, DataBlock& buf, const NamedList& params,
02829         const char* prefix, bool isup, bool fail = false);
02830 
02840     static bool encodeCaps(const SignallingComponent* comp, DataBlock& buf, const NamedList& params,
02841         const char* prefix, bool isup);
02842 
02855     static unsigned int* parseUIntArray(const String& source, unsigned int minVal, unsigned int maxVal,
02856         unsigned int& count, bool discardDup);
02857 
02858 private:
02859     static const TokenDict* s_dictCCITT[5];
02860 };
02861 
02866 class YSIG_API SignallingMessageTimer : public GenObject, public SignallingTimer
02867 {
02868 public:
02874     inline SignallingMessageTimer(u_int64_t interval, u_int64_t global = 0)
02875         : SignallingTimer(interval),
02876           m_globalTimer(global), m_msg(0)
02877         { }
02878 
02882     virtual ~SignallingMessageTimer()
02883         { TelEngine::destruct(m_msg); }
02884 
02889     inline SignallingMessage* message() const
02890         { return m_msg; }
02891 
02896     inline void message(SignallingMessage* msg)
02897         { m_msg = msg; }
02898 
02899 
02904     inline SignallingTimer& global()
02905         { return m_globalTimer; }
02906 
02911     inline const SignallingTimer& global() const
02912         { return m_globalTimer; }
02913 
02918     inline u_int64_t fireTime() const {
02919         if (!m_globalTimer.started() || m_globalTimer.fireTime() > SignallingTimer::fireTime())
02920             return SignallingTimer::fireTime();
02921         return m_globalTimer.fireTime();
02922     }
02923 
02924 protected:
02925     SignallingTimer m_globalTimer;
02926     SignallingMessage* m_msg;
02927 };
02928 
02934 class YSIG_API SignallingMessageTimerList : public ObjList
02935 {
02936 public:
02940     inline SignallingMessageTimerList()
02941         { }
02942 
02949     inline SignallingMessageTimer* add(u_int64_t interval, const Time& when = Time())
02950         { return interval ? add(new SignallingMessageTimer(interval),when) : 0; }
02951 
02958     SignallingMessageTimer* add(SignallingMessageTimer* m, const Time& when = Time());
02959 
02965     SignallingMessageTimer* timeout(const Time& when = Time());
02966 };
02967 
02973 class YSIG_API AnalogLine : public RefObject, public Mutex
02974 {
02975     YCLASS(AnalogLine,RefObject)
02976     friend class AnalogLineGroup;        // Reset group if destroyed before the line
02977 public:
02981     enum Type {
02982         FXO,                             // Telephone linked to an exchange
02983         FXS,                             // Telephone exchange linked to a telephone
02984         Recorder,                        // Passive FXO recording a 2 wire line
02985         Monitor,                         // Monitor (a pair of FXS/FXO lines)
02986         Unknown
02987     };
02988 
02992     enum State {
02993         OutOfService   = -1,             // Line is out of service
02994         Idle           = 0,              // Line is idle (on hook)
02995         Dialing        = 1,              // FXS line is waiting for the FXO to dial the number
02996         DialComplete   = 2,              // FXS line: got enough digits from the FXO to reach a destination
02997         Ringing        = 3,              // Line is ringing
02998         Answered       = 4,              // Line is answered
02999         CallEnded      = 5,              // FXS line: notify the FXO on call termination
03000         OutOfOrder     = 6,              // FXS line: notify the FXO that the hook is off after call ended notification
03001     };
03002 
03006     enum CallSetupInfo {
03007         After,                           // Send/detect call setup after the first ring
03008         Before,                          // Send/detect call setup before the first ring
03009         NoCallSetup                      // No call setup detect or send
03010     };
03011 
03019     AnalogLine(AnalogLineGroup* grp, unsigned int cic, const NamedList& params);
03020 
03024     virtual ~AnalogLine();
03025 
03030     inline Type type() const
03031         { return m_type; }
03032 
03037     inline State state() const
03038         { return m_state; }
03039 
03044     inline AnalogLineGroup* group()
03045         { return m_group; }
03046 
03051     inline AnalogLine* getPeer()
03052         { return m_peer; }
03053 
03059     void setPeer(AnalogLine* line = 0, bool sync = true);
03060 
03065     inline SignallingCircuit* circuit()
03066         { return m_circuit; }
03067 
03072     inline const char* address() const
03073         { return m_address; }
03074 
03079     inline bool outbandDtmf() const
03080         { return !m_inband; }
03081 
03086     inline bool answerOnPolarity() const
03087         { return m_answerOnPolarity; }
03088 
03093     inline bool hangupOnPolarity() const
03094         { return m_hangupOnPolarity; }
03095 
03100     inline bool polarityControl() const
03101         { return m_polarityControl; }
03102 
03107     inline CallSetupInfo callSetup() const
03108         { return m_callSetup; }
03109 
03114     inline u_int64_t callSetupTimeout() const
03115         { return m_callSetupTimeout; }
03116 
03121     inline u_int64_t noRingTimeout() const
03122         { return m_noRingTimeout; }
03123 
03128     inline u_int64_t alarmTimeout() const
03129         { return m_alarmTimeout; }
03130 
03135     inline u_int64_t delayDial() const
03136         { return m_delayDial; }
03137 
03142     inline void acceptPulseDigit(bool ok)
03143         { m_acceptPulseDigit = ok; }
03144 
03149     inline void* userdata() const
03150         { return m_private; }
03151 
03157     inline void userdata(void* data, bool sync = true)
03158     {
03159         Lock lock(this);
03160         m_private = data;
03161         if (sync && m_peer)
03162             m_peer->userdata(data,false);
03163     }
03164 
03169     virtual const String& toString() const
03170         { return m_address; }
03171 
03176     void resetEcho(bool train);
03177 
03182     inline bool resetCircuit()
03183         { return state() != OutOfService && m_circuit && m_circuit->reserve(); }
03184 
03191     inline bool setCircuitParam(const char* param, const char* value = 0)
03192         { return m_circuit && m_circuit->setParam(param,value); }
03193 
03199     bool connect(bool sync);
03200 
03206     bool disconnect(bool sync);
03207 
03214     bool sendEvent(SignallingCircuitEvent::Type type, NamedList* params = 0);
03215 
03223     inline bool sendEvent(SignallingCircuitEvent::Type type, State newState,
03224         NamedList* params = 0)
03225     {
03226         if (!sendEvent(type,params))
03227             return false;
03228         changeState(newState,false);
03229         return true;
03230     }
03231 
03237     virtual AnalogLineEvent* getEvent(const Time& when);
03238 
03244     virtual AnalogLineEvent* getMonitorEvent(const Time& when);
03245 
03250     virtual void checkTimeouts(const Time& when)
03251         { }
03252 
03259     bool changeState(State newState, bool sync = false);
03260 
03269     bool enable(bool ok, bool sync, bool connectNow = true);
03270 
03274     static const TokenDict* typeNames();
03275 
03279     static const TokenDict* stateNames();
03280 
03284     static const TokenDict* csNames();
03285 
03286 protected:
03290     virtual void destroyed();
03291 
03292 private:
03293     Type m_type;                               // Line type
03294     State m_state;                             // Line state
03295     bool m_inband;                             // Refuse to send DTMFs if they should be sent in band
03296     int m_echocancel;                          // Default echo canceller state (0: managed by the circuit, -1: off, 1: on)
03297     bool m_acceptPulseDigit;                   // Accept incoming pulse digits
03298     bool m_answerOnPolarity;                   // Answer on line polarity change
03299     bool m_hangupOnPolarity;                   // Hangup on line polarity change
03300     bool m_polarityControl;                    // Set line polarity flag
03301     CallSetupInfo m_callSetup;                 // Call setup management
03302     u_int64_t m_callSetupTimeout;              // FXO: timeout period for received call setup data before first ring
03303     u_int64_t m_noRingTimeout;                 // FXO: timeout period with no ring received on incoming calls
03304     u_int64_t m_alarmTimeout;                  // Timeout period to stay in alarms
03305     u_int64_t m_delayDial;                     // FXO: Time to delay sending number
03306     AnalogLineGroup* m_group;                  // The group owning this line
03307     SignallingCircuit* m_circuit;              // The circuit managed by this line
03308     String m_address;                          // Line address: group and circuit
03309     void* m_private;                           // Private data used by this line's user
03310     // Monitor data
03311     AnalogLine* m_peer;                        // This line's peer if any
03312     bool m_getPeerEvent;                       // Flag used to get events from peer
03313 };
03314 
03319 class YSIG_API AnalogLineEvent : public GenObject
03320 {
03321 public:
03327     AnalogLineEvent(AnalogLine* line, SignallingCircuitEvent* event)
03328         : m_line(0), m_event(event)
03329         { if (line && line->ref()) m_line = line; }
03330 
03334     virtual ~AnalogLineEvent()
03335     {
03336         TelEngine::destruct(m_line);
03337         TelEngine::destruct(m_event);
03338     }
03339 
03344     inline AnalogLine* line()
03345         { return m_line; }
03346 
03351     inline SignallingCircuitEvent* event()
03352         { return m_event; }
03353 
03357     virtual void destruct()
03358     {
03359         TelEngine::destruct(m_line);
03360         TelEngine::destruct(m_event);
03361         GenObject::destruct();
03362     }
03363 
03364 private:
03365     AnalogLine* m_line;
03366     SignallingCircuitEvent* m_event;
03367 };
03368 
03374 class YSIG_API AnalogLineGroup : public SignallingCircuitGroup
03375 {
03376     YCLASS(AnalogLineGroup,SignallingCircuitGroup)
03377 public:
03384     AnalogLineGroup(AnalogLine::Type type, const char* name, bool slave = false);
03385 
03392     AnalogLineGroup(const char* name, AnalogLineGroup* fxo);
03393 
03397     virtual ~AnalogLineGroup();
03398 
03403     inline AnalogLine::Type type() const
03404         { return m_type; }
03405 
03410     inline ObjList& lines()
03411         { return m_lines; }
03412 
03417     inline AnalogLineGroup* fxo()
03418         { return m_fxo; }
03419 
03424     inline bool slave()
03425         { return m_slave; }
03426 
03433     bool appendLine(AnalogLine* line, bool destructOnFail = true);
03434 
03439     void removeLine(unsigned int cic);
03440 
03445     void removeLine(AnalogLine* line);
03446 
03452     AnalogLine* findLine(unsigned int cic);
03453 
03459     AnalogLine* findLine(const String& address);
03460 
03466     virtual AnalogLineEvent* getEvent(const Time& when);
03467 
03468 protected:
03472     virtual void destroyed();
03473 
03477     ObjList m_lines;
03478 
03479 private:
03480     AnalogLine::Type m_type;             // Line type
03481     AnalogLineGroup* m_fxo;              // The group containing the FXO lines if this is a monitor
03482     bool m_slave;                        // True if this is an FXO group owned by an FXS one
03483 };
03484 
03489 class YSIG_API SS7PointCode : public GenObject
03490 {
03491     YCLASS(SS7PointCode,GenObject)
03492 public:
03496     enum Type {
03497         Other  = 0,
03498         ITU    = 1, // ITU-T Q.704
03499         ANSI   = 2, // ANSI T1.111.4
03500         ANSI8  = 3, // 8-bit SLS
03501         China  = 4, // GF 001-9001
03502         Japan  = 5, // JT-Q704, NTT-Q704
03503         Japan5 = 6, // 5-bit SLS
03504         // Do not change the next line, must be past last defined type
03505         DefinedTypes
03506     };
03507 
03514     inline SS7PointCode(unsigned char network = 0, unsigned char cluster = 0, unsigned char member = 0)
03515         : m_network(network), m_cluster(cluster), m_member(member)
03516         { }
03517 
03523     inline SS7PointCode(Type type, unsigned int packed)
03524         : m_network(0), m_cluster(0), m_member(0)
03525         { unpack(type,packed); }
03526 
03531     inline SS7PointCode(const SS7PointCode& original)
03532         : m_network(original.network()), m_cluster(original.cluster()), m_member(original.member())
03533         { }
03534 
03538     inline ~SS7PointCode()
03539         { }
03540 
03545     inline unsigned char network() const
03546         { return m_network; }
03547 
03552     inline unsigned char cluster() const
03553         { return m_cluster; }
03554 
03559     inline unsigned char member() const
03560         { return m_member; }
03561 
03568     inline void assign(unsigned char network, unsigned char cluster, unsigned char member)
03569         { m_network = network; m_cluster = cluster; m_member = member; }
03570 
03577     bool assign(const String& src, Type type = Other);
03578 
03587     bool assign(Type type, const unsigned char* src, int len = -1, unsigned char* spare = 0);
03588 
03593     inline SS7PointCode& operator=(const SS7PointCode& original)
03594         { assign(original.network(),original.cluster(),original.member()); return *this; }
03595 
03600     inline bool operator==(const SS7PointCode& original) const
03601         { return m_network == original.network() && m_cluster == original.cluster() && m_member == original.member(); }
03602 
03607     inline bool operator!=(const SS7PointCode& original) const
03608         { return m_network != original.network() || m_cluster != original.cluster() || m_member != original.member(); }
03609 
03614     bool compatible(Type type) const;
03615 
03621     unsigned int pack(Type type) const;
03622 
03629     bool unpack(Type type, unsigned int packed);
03630 
03638     bool store(Type type, unsigned char* dest, unsigned char spare = 0) const;
03639 
03645     static unsigned char size(Type type);
03646 
03652     static unsigned char length(Type type);
03653 
03659     static Type lookup(const char* text)
03660         { return (Type)TelEngine::lookup(text,s_names,(int)Other); }
03661 
03667     static const char* lookup(Type type)
03668         { return TelEngine::lookup((int)type,s_names); }
03669 
03670 private:
03671     static const TokenDict s_names[];    // Keep the strigns associated with point code type
03672     unsigned char m_network;
03673     unsigned char m_cluster;
03674     unsigned char m_member;
03675 };
03676 
03677 // The number of valid point code types
03678 #define YSS7_PCTYPE_COUNT (SS7PointCode::DefinedTypes-1)
03679 
03685 YSIG_API String& operator<<(String& str, const SS7PointCode& cp);
03686 
03691 class YSIG_API SS7Label
03692 {
03693 public:
03697     SS7Label();
03698 
03703     SS7Label(const SS7Label& original);
03704 
03711     SS7Label(const SS7Label& original, unsigned char sls, unsigned char spare = 0);
03712 
03721     SS7Label(SS7PointCode::Type type, const SS7PointCode& dpc,
03722         const SS7PointCode& opc, unsigned char sls, unsigned char spare = 0);
03723 
03732     SS7Label(SS7PointCode::Type type, unsigned int dpc,
03733         unsigned int opc, unsigned char sls, unsigned char spare = 0);
03734 
03740     SS7Label(SS7PointCode::Type type, const SS7MSU& msu);
03741 
03750     void assign(SS7PointCode::Type type, const SS7PointCode& dpc,
03751         const SS7PointCode& opc, unsigned char sls, unsigned char spare = 0);
03752 
03761     void assign(SS7PointCode::Type type, unsigned int dpc,
03762         unsigned int opc, unsigned char sls, unsigned char spare = 0);
03763 
03770     bool assign(SS7PointCode::Type type, const SS7MSU& msu);
03771 
03779     bool assign(SS7PointCode::Type type, const unsigned char* src, int len = -1);
03780 
03786     bool store(unsigned char* dest) const;
03787 
03792     bool compatible(SS7PointCode::Type type) const;
03793 
03798     inline SS7PointCode::Type type() const
03799         { return m_type; }
03800 
03805     inline const SS7PointCode& dpc() const
03806         { return m_dpc; }
03807 
03812     inline SS7PointCode& dpc()
03813         { return m_dpc; }
03814 
03819     inline const SS7PointCode& opc() const
03820         { return m_opc; }
03821 
03826     inline SS7PointCode& opc()
03827         { return m_opc; }
03828 
03833     inline unsigned char sls() const
03834         { return m_sls; }
03835 
03840     inline void setSls(unsigned char sls)
03841         { m_sls = sls; }
03842 
03847     inline unsigned char spare() const
03848         { return m_spare; }
03849 
03854     inline void setSpare(unsigned char spare)
03855         { m_spare = spare; }
03856 
03861     inline unsigned int length() const
03862         { return length(m_type); }
03863 
03869     static unsigned int length(SS7PointCode::Type type);
03870 
03875     inline unsigned char size() const
03876         { return size(m_type); }
03877 
03883     static unsigned char size(SS7PointCode::Type type);
03884 
03885 private:
03886     SS7PointCode::Type m_type;
03887     SS7PointCode m_dpc;
03888     SS7PointCode m_opc;
03889     unsigned char m_sls;
03890     unsigned char m_spare;
03891 };
03892 
03898 YSIG_API String& operator<<(String& str, const SS7Label& label);
03899 
03904 class YSIG_API SS7MSU : public DataBlock
03905 {
03906     YCLASS(SS7MSU,DataBlock)
03907 public:
03911     enum Services {
03912         // Signalling Network Management
03913         SNM   =  0,
03914         // Maintenance
03915         MTN   =  1,
03916         // Maintenance special
03917         MTNS  =  2,
03918         // Signalling Connection Control Part
03919         SCCP  =  3,
03920         // Telephone User Part
03921         TUP   =  4,
03922         // ISDN User Part
03923         ISUP  =  5,
03924         // Data User Part - call and circuit related
03925         DUP_C =  6,
03926         // Data User Part - facility messages
03927         DUP_F =  7,
03928         // MTP Testing User Part (reserved)
03929         MTP_T =  8,
03930         // Broadband ISDN User Part
03931         BISUP =  9,
03932         // Satellite ISDN User Part
03933         SISUP = 10,
03934         // AAL type2 Signaling
03935         AAL2  = 12,
03936         // Bearer Independent Call Control
03937         BICC  = 13,
03938         // Gateway Control Protocol
03939         GCP   = 14,
03940     };
03941 
03945     enum Priority {
03946         Regular  = 0x00,
03947         Special  = 0x10,
03948         Circuit  = 0x20,
03949         Facility = 0x30
03950     };
03951 
03955     enum NetIndicator {
03956         International      = 0x00,
03957         SpareInternational = 0x40,
03958         National           = 0x80,
03959         ReservedNational   = 0xc0
03960     };
03961 
03965     inline SS7MSU()
03966         { }
03967 
03972     inline SS7MSU(const SS7MSU& value)
03973         : DataBlock(value)
03974         { }
03975 
03980     inline SS7MSU(const DataBlock& value)
03981         : DataBlock(value)
03982         { }
03983 
03990     inline SS7MSU(void* value, unsigned int len, bool copyData = true)
03991         : DataBlock(value,len,copyData)
03992         { }
03993 
04001     SS7MSU(unsigned char sio, const SS7Label label, void* value = 0, unsigned int len = 0);
04002 
04011     SS7MSU(unsigned char sif, unsigned char ssf, const SS7Label label, void* value = 0, unsigned int len = 0);
04012 
04016     virtual ~SS7MSU();
04017 
04023     inline SS7MSU& operator=(const SS7MSU& value)
04024         { DataBlock::operator=(value); return *this; }
04025 
04031     inline SS7MSU& operator=(const DataBlock& value)
04032         { DataBlock::operator=(value); return *this; }
04033 
04038     bool valid() const;
04039 
04046     inline unsigned char* getData(unsigned int offs, unsigned int len = 1)
04047         { return (offs+len <= length()) ? offs + (unsigned char*)data() : 0; }
04048 
04055     inline const unsigned char* getData(unsigned int offs, unsigned int len = 1) const
04056         { return (offs+len <= length()) ? offs + (const unsigned char*)data() : 0; }
04057 
04064     inline unsigned char* getData(const SS7Label& label, unsigned int len = 1)
04065         { return getData(label.length()+1,len); }
04066 
04073     inline const unsigned char* getData(const SS7Label& label, unsigned int len = 1) const
04074         { return getData(label.length()+1,len); }
04075 
04080     inline int getSIO() const
04081         { return null() ? -1 : *(const unsigned char*)data(); }
04082 
04087     inline int getSIF() const
04088         { return null() ? -1 : 0x0f & *(const unsigned char*)data(); }
04089 
04094     inline int getSSF() const
04095         { return null() ? -1 : 0xf0 & *(const unsigned char*)data(); }
04096 
04101     inline int getPrio() const
04102         { return null() ? -1 : 0x30 & *(const unsigned char*)data(); }
04103 
04108     inline int getNI() const
04109         { return null() ? -1 : 0xc0 & *(const unsigned char*)data(); }
04110 
04115     const char* getServiceName() const;
04116 
04121     const char* getPriorityName() const;
04122 
04127     const char* getIndicatorName() const;
04128 
04135     static unsigned char getPriority(const char* name, unsigned char defVal = Regular);
04136 
04143     static unsigned char getNetIndicator(const char* name, unsigned char defVal = National);
04144 };
04145 
04150 class HandledMSU
04151 {
04152 public:
04153     enum Result {
04154         Rejected     =  0,
04155         Unequipped   =  1,
04156         Inaccessible =  2,
04157         // private used (non Q.704)
04158         Accepted     = 16,
04159         Failure      = 17,
04160         NoAddress    = 18,
04161         NoCircuit    = 19,
04162     };
04163 
04168     inline HandledMSU(Result result = Rejected)
04169         { m_result = result; }
04170 
04175     inline HandledMSU(bool success)
04176         { m_result = success ? Accepted : Failure; }
04177 
04182     inline HandledMSU(const HandledMSU& original)
04183         { m_result = original; }
04184 
04189     inline HandledMSU& operator=(Result result)
04190         { m_result = result; return *this; }
04191 
04196     inline HandledMSU& operator=(const HandledMSU& original)
04197         { m_result = original; return *this; }
04198 
04203     inline bool operator==(Result result)
04204         { return m_result == result; }
04205 
04210     inline bool operator==(const HandledMSU& result)
04211         { return m_result == result; }
04212 
04217     inline bool operator!=(Result result)
04218         { return m_result != result; }
04219 
04224     inline bool operator!=(const HandledMSU& result)
04225         { return m_result != result; }
04226 
04231     inline operator Result() const
04232         { return m_result; }
04233 
04238     inline bool ok() const
04239         { return Accepted == m_result; }
04240 
04245     inline unsigned char upu() const
04246         { return (Accepted > m_result) ? m_result : Rejected; }
04247 
04248 private:
04249     Result m_result;
04250 };
04251 
04256 class YSIG_API SIGTransport : public SignallingComponent
04257 {
04258     YCLASS(SIGTransport,SignallingComponent)
04259     friend class SIGTRAN;
04260 public:
04264     enum Transport {
04265         None = 0,
04266         Sctp,
04267         // All the following transports are not standard
04268         Tcp,
04269         Udp,
04270         Unix,
04271     };
04272 
04277      inline SIGTRAN* sigtran() const
04278         { return m_sigtran; }
04279 
04284     u_int32_t defPort() const;
04285 
04290     virtual bool reliable() const = 0;
04291 
04296     void notifyLayer(SignallingInterface::Notification status);
04297 
04303     virtual bool initialize(const NamedList* config)
04304         { return false;}
04305 
04311     virtual bool connected(int streamId) const = 0;
04312 
04317     void attach(SIGTRAN* sigtran);
04318 
04328     bool processMSG(unsigned char msgVersion, unsigned char msgClass,
04329         unsigned char msgType, const DataBlock& msg, int streamId) const;
04330 
04335     virtual void reconnect(bool force = false)
04336         { }
04337 
04338 protected:
04343     inline explicit SIGTransport(const char* name = 0)
04344         : SignallingComponent(name), m_sigtran(0)
04345         { }
04346 
04351     virtual void attached(bool hasUAL) = 0;
04352 
04362     virtual bool transmitMSG(unsigned char msgVersion, unsigned char msgClass,
04363         unsigned char msgType, const DataBlock& msg, int streamId = 0);
04364 
04372     virtual bool transmitMSG(const DataBlock& header, const DataBlock& msg, int streamId = 0) = 0;
04373 
04374 private:
04375     SIGTRAN* m_sigtran;
04376 };
04377 
04382 class YSIG_API SIGTRAN
04383 {
04384     friend class SIGTransport;
04385 public:
04389     enum MsgClass {
04390         // Management (IUA/M2UA/M3UA/SUA)
04391         MGMT  =  0,
04392         // Transfer (M3UA)
04393         TRAN  =  1,
04394         // SS7 Signalling Network Management (M3UA/SUA)
04395         SSNM  =  2,
04396         // ASP State Maintenance (IUA/M2UA/M3UA/SUA)
04397         ASPSM =  3,
04398         // ASP Traffic Maintenance (IUA/M2UA/M3UA/SUA)
04399         ASPTM =  4,
04400         // Q.921/Q.931 Boundary Primitives Transport (IUA)
04401         QPTM  =  5,
04402         // MTP2 User Adaptation (M2UA)
04403         MAUP  =  6,
04404         // Connectionless Messages (SUA)
04405         CLMSG =  7,
04406         // Connection-Oriented Messages (SUA)
04407         COMSG =  8,
04408         // Routing Key Management (M3UA/SUA)
04409         RKM   =  9,
04410         // Interface Identifier Management (M2UA)
04411         IIM   = 10,
04412         // M2PA Messages (M2PA)
04413         M2PA  = 11,
04414     };
04415 
04419     enum MsgMGMT {
04420         MgmtERR  =  0,
04421         MgmtNTFY =  1,
04422     };
04423 
04427     enum MsgSSNM {
04428         SsnmDUNA =  1, // Destination Unavailable
04429         SsnmDAVA =  2, // Destination Available
04430         SsnmDAUD =  3, // Destination State Audit
04431         SsnmSCON =  4, // Signalling Congestion
04432         SsnmDUPU =  5, // Destination User Part Unavailable
04433         SsnmDRST =  6, // Destination Restricted
04434     };
04435 
04439     enum MsgASPSM {
04440         AspsmUP       =  1,
04441         AspsmDOWN     =  2,
04442         AspsmBEAT     =  3,
04443         AspsmUP_ACK   =  4,
04444         AspsmDOWN_ACK =  5,
04445         AspsmBEAT_ACK =  6,
04446     };
04447 
04451     enum MsgASPTM {
04452         AsptmACTIVE       =  1,
04453         AsptmINACTIVE     =  2,
04454         AsptmACTIVE_ACK   =  3,
04455         AsptmINACTIVE_ACK =  4,
04456     };
04457 
04461     enum MsgRKM {
04462         RkmREG_REQ    =  1,
04463         RkmREG_RSP    =  2,
04464         RkmDEREG_REQ  =  3,
04465         RkmDEREG_RSP  =  4,
04466     };
04467 
04471     enum MsgIIM {
04472         IimREG_REQ    =  1,
04473         IimREG_RSP    =  2,
04474         IimDEREG_REQ  =  3,
04475         IimDEREG_RSP  =  4,
04476     };
04477 
04483     explicit SIGTRAN(u_int32_t payload = 0, u_int16_t port = 0);
04484 
04488     virtual ~SIGTRAN();
04489 
04494     virtual void attach(SIGTransport* trans);
04495 
04500     inline SIGTransport* transport() const
04501         { return m_trans; }
04502 
04507     inline u_int32_t payload() const
04508         { return m_payload; }
04509 
04514     inline u_int16_t defPort() const
04515         { return m_defPort; }
04516 
04522     bool connected(int streamId = 0) const;
04523 
04524     virtual void notifyLayer(SignallingInterface::Notification status)
04525         { }
04526 
04531     static const TokenDict* classNames();
04532 
04540     static const char* typeName(unsigned char msgClass, unsigned char msgType,
04541         const char* defValue = 0);
04542 
04552     bool transmitMSG(unsigned char msgVersion, unsigned char msgClass,
04553         unsigned char msgType, const DataBlock& msg, int streamId = 0) const;
04554 
04563     inline bool transmitMSG(unsigned char msgClass, unsigned char msgType,
04564         const DataBlock& msg, int streamId = 0) const
04565         { return transmitMSG(1,msgClass,msgType,msg,streamId); }
04566 
04572     bool restart(bool force);
04573 
04574 protected:
04584     virtual bool processMSG(unsigned char msgVersion, unsigned char msgClass,
04585         unsigned char msgType, const DataBlock& msg, int streamId) = 0;
04586 
04587 private:
04588     SIGTransport* m_trans;
04589     u_int32_t m_payload;
04590     u_int16_t m_defPort;
04591     mutable Mutex m_transMutex;
04592 };
04593 
04598 class YSIG_API SIGAdaptation : public SignallingComponent, public SIGTRAN, public Mutex
04599 {
04600     YCLASS(SIGAdaptation,SignallingComponent)
04601 public:
04605     enum TrafficMode {
04606         TrafficUnused    = 0,
04607         TrafficOverride  = 1,
04608         TrafficLoadShare = 2,
04609         TrafficBroadcast = 3,
04610     };
04611 
04615     virtual ~SIGAdaptation();
04616 
04621     virtual bool initialize(const NamedList* config);
04622 
04631     static bool nextTag(const DataBlock& data, int& offset, uint16_t& tag, uint16_t& length);
04632 
04641     static bool findTag(const DataBlock& data, int& offset, uint16_t tag, uint16_t& length);
04642 
04650     static bool getTag(const DataBlock& data, uint16_t tag, uint32_t& value);
04651 
04659     static bool getTag(const DataBlock& data, uint16_t tag, String& value);
04660 
04668     static bool getTag(const DataBlock& data, uint16_t tag, DataBlock& value);
04669 
04676     static void addTag(DataBlock& data, uint16_t tag, uint32_t value);
04677 
04684     static void addTag(DataBlock& data, uint16_t tag, const String& value);
04685 
04692     static void addTag(DataBlock& data, uint16_t tag, const DataBlock& value);
04693 
04694 protected:
04702     explicit SIGAdaptation(const char* name = 0, const NamedList* params = 0,
04703         u_int32_t payload = 0, u_int16_t port = 0);
04704 
04713     virtual bool processCommonMSG(unsigned char msgClass,
04714         unsigned char msgType, const DataBlock& msg, int streamId);
04715 
04723     virtual bool processMgmtMSG(unsigned char msgType, const DataBlock& msg, int streamId) = 0;
04724 
04732     virtual bool processAspsmMSG(unsigned char msgType, const DataBlock& msg, int streamId) = 0;
04733 
04741     virtual bool processAsptmMSG(unsigned char msgType, const DataBlock& msg, int streamId) = 0;
04742 };
04743 
04748 class YSIG_API SIGAdaptClient : public SIGAdaptation
04749 {
04750     friend class SIGAdaptUser;
04751     YCLASS(SIGAdaptClient,SIGAdaptation)
04752 public:
04756     enum AspState {
04757         AspDown = 0,
04758         AspUpRq,
04759         AspUp,
04760         AspActRq,
04761         AspActive
04762     };
04763 
04768     virtual void notifyLayer(SignallingInterface::Notification status);
04769 
04770 protected:
04778     explicit SIGAdaptClient(const char* name = 0, const NamedList* params = 0,
04779         u_int32_t payload = 0, u_int16_t port = 0);
04780 
04788     virtual bool processMgmtMSG(unsigned char msgType, const DataBlock& msg, int streamId);
04789 
04797     virtual bool processAspsmMSG(unsigned char msgType, const DataBlock& msg, int streamId);
04798 
04806     virtual bool processAsptmMSG(unsigned char msgType, const DataBlock& msg, int streamId);
04807 
04812     virtual void activeChange(bool active);
04813 
04818     inline bool aspUp() const
04819         { return m_state >= AspUp; }
04820 
04825     inline bool aspActive() const
04826         { return m_state >= AspActive; }
04827 
04832     bool activate();
04833 
04839     void setState(AspState state, bool notify = true);
04840 
04845     inline ObjList& users()
04846         { return m_users; }
04847 
04851     int32_t m_aspId;
04852 
04856     TrafficMode m_traffic;
04857 
04858 private:
04859     void attach(SIGAdaptUser* user);
04860     void detach(SIGAdaptUser* user);
04861     ObjList m_users;
04862     AspState m_state;
04863 };
04864 
04869 class YSIG_API SIGAdaptServer : public SIGAdaptation
04870 {
04871     YCLASS(SIGAdaptServer,SIGAdaptation)
04872 protected:
04880     inline explicit SIGAdaptServer(const char* name = 0, const NamedList* params = 0,
04881         u_int32_t payload = 0, u_int16_t port = 0)
04882         : SIGAdaptation(name,params,payload,port)
04883         { }
04884 
04892     virtual bool processMgmtMSG(unsigned char msgType, const DataBlock& msg, int streamId);
04893 
04901     virtual bool processAspsmMSG(unsigned char msgType, const DataBlock& msg, int streamId);
04902 
04910     virtual bool processAsptmMSG(unsigned char msgType, const DataBlock& msg, int streamId);
04911 };
04912 
04917 class YSIG_API SIGAdaptUser
04918 {
04919     friend class SIGAdaptClient;
04920 public:
04924     virtual ~SIGAdaptUser();
04925 
04926 protected:
04930     inline SIGAdaptUser()
04931         : m_autostart(false), m_adaptation(0)
04932         { }
04933 
04938     inline SIGAdaptClient* adaptation() const
04939         { return m_adaptation; }
04940 
04945     inline SIGTransport* transport() const
04946         { return m_adaptation ? m_adaptation->transport() : 0; }
04947 
04952     void adaptation(SIGAdaptClient* adapt);
04953 
04958     virtual void activeChange(bool active) = 0;
04959 
04964     inline bool activate()
04965         { return m_adaptation && m_adaptation->activate(); }
04966 
04971     inline bool aspUp() const
04972         { return m_adaptation && m_adaptation->aspUp(); }
04973 
04978     inline bool aspActive() const
04979         { return m_adaptation && m_adaptation->aspActive(); }
04980 
04984     bool m_autostart;
04985 
04986 private:
04987     SIGAdaptClient* m_adaptation;
04988 };
04989 
04994 class YSIG_API ASPUser
04995 {
04996 };
04997 
05002 class YSIG_API GTT : virtual public SignallingComponent
05003 {
05004 public:
05008     GTT(const NamedList& config);
05009 
05013     virtual ~GTT();
05014 
05021     virtual NamedList* routeGT(const NamedList& gt, const String& prefix);
05022 
05026     virtual bool initialize(const NamedList* config);
05027 
05032     virtual void attach(SCCP* sccp);
05033     
05039     virtual void updateTables(const NamedList& params)
05040         { }
05041 
05042 protected:
05043     virtual void destroyed();
05044 
05045 private:
05046     SCCP* m_sccp;
05047 
05048 };
05049 
05054 class YSIG_API SCCP : virtual public SignallingComponent
05055 {
05056     YCLASS(SCCP,SignallingComponent)
05057     friend class SCCPManagement;
05058 public:
05059 
05060     enum Type {                     // used in management status method                                 Flow
05061          CoordinateRequest         = 0, // Request that a subsystem to go oos (out of service)              (User->SCCP)
05062          CoordinateConfirm         = 1, // Confirmation that a subsystem can go oos                         (SCCP->User)
05063          CoordinateIndication      = 2, // Indication that a subsystem requires to go oos                   (SCCP->User)
05064          CoordinateResponse        = 3, // Response to a subsystem requires to go oos                       (User->SCCP)
05065          StatusIndication          = 4, // Indication form SCCP that a subsystem status has been changed    (SCCP->User)
05066          StatusRequest             = 5, // Indication from a user that a subsystem status has been changed  (User->SCCP)
05067          PointCodeStatusIndication = 6, // Indication to User that a point code is available / unavailable  (SCCP->User)
05068          TraficIndication          = 7, // ANSI only! Indication that a traffic mix has been detected       (SCCP->User).
05069          SubsystemStatus           = 8, // Request from sccp t users to find the status of a local subsystem
05070      };
05071 
05075     SCCP();
05076 
05080     virtual ~SCCP();
05081 
05102     virtual int sendMessage(DataBlock& data, const NamedList& params);
05103 
05110      virtual bool managementStatus(Type type, NamedList& params);
05111 
05116     virtual void attach(SCCPUser* user);
05117 
05122     virtual void detach(SCCPUser* user);
05123 
05128     virtual void attachGTT(GTT* gtt);
05129 
05134     static const TokenDict* notifTypes();
05135 
05136     virtual void updateTables(const NamedList& params)
05137         {
05138             Lock lock(m_translatorLocker);
05139             if (m_translator)
05140                 m_translator->updateTables(params);
05141         }
05142 protected:
05149     NamedList* translateGT(const NamedList& params, const String& prefix);
05150 
05158     HandledMSU pushMessage(DataBlock& data, NamedList& params, int ssn);
05159 
05167     HandledMSU notifyMessage(DataBlock& data, NamedList& params, int ssn);
05168 
05175     bool managementMessage(Type type, NamedList& params);
05176 
05181     virtual bool isEndpoint()
05182         { return false; }
05183 private:
05184     ObjList m_users;
05185     Mutex m_translatorLocker;
05186     Mutex m_usersLocker;
05187     GTT* m_translator;
05188 };
05189 
05190 class YSIG_API SubsystemStatusTest : public RefObject
05191 {
05192     YCLASS(SubsystemStatusTest,RefObject)
05193 public:
05198     inline SubsystemStatusTest(u_int32_t interval)
05199         : m_interval(interval), m_statusInfo(interval), m_remoteSccp(0), m_remoteSubsystem(0),
05200         m_markAllowed(false)
05201         { }
05202 
05206     virtual ~SubsystemStatusTest();
05207 
05214     bool startTest(SccpRemote* remoteSccp, SccpSubsystem* rSubsystem);
05215 
05220     inline SccpRemote* getRemote()
05221         { return m_remoteSccp; };
05222 
05227     inline bool timeout()
05228         { return m_statusInfo.started() && m_statusInfo.timeout(); }
05233     inline SccpSubsystem* getSubsystem()
05234         { return m_remoteSubsystem; }
05235 
05239     void restartTimer();
05240 
05244     inline bool markAllowed()
05245         { return m_markAllowed; }
05246 
05251     inline void setAllowed(bool allowed)
05252         { m_markAllowed = allowed; }
05253 private:
05254     u_int32_t m_interval;
05255     SignallingTimer m_statusInfo;
05256     SccpRemote* m_remoteSccp;
05257     SccpSubsystem* m_remoteSubsystem;
05258     bool m_markAllowed;
05259 };
05260 
05265 class YSIG_API SCCPUser : virtual public SignallingComponent
05266 {
05267     YCLASS(SCCPUser,SignallingComponent)
05268 public:
05272     SCCPUser(const NamedList& params);
05273 
05277     virtual ~SCCPUser();
05278 
05284     virtual bool initialize(const NamedList* config);
05285 
05293     virtual bool sendData(DataBlock& data, NamedList& params);
05294 
05301     virtual bool sccpNotify(SCCP::Type type, NamedList& params);
05302 
05309      virtual HandledMSU receivedData(DataBlock& data, NamedList& params);
05310 
05318      virtual HandledMSU notifyData(DataBlock& data, NamedList& params);
05319 
05326      virtual bool managementNotify(SCCP::Type type, NamedList& params);
05327 
05335     virtual void attach(SCCP* sccp);
05336 
05341     inline SCCP* sccp() const
05342         { return m_sccp; }
05343 
05344 protected:
05345     virtual void destroyed();
05346 
05347 private:
05348     SCCP* m_sccp;
05349     Mutex m_sccpMutex;
05350     int m_sls;
05351 };
05352 
05357 class YSIG_API TCAPUser : public SignallingComponent
05358 {
05359     YCLASS(TCAPUser,SignallingComponent)
05360     friend class SS7TCAP;
05361 public:
05362     TCAPUser(const char* name, const NamedList* params = 0)
05363       : SignallingComponent(name,params),
05364         m_tcap(0)
05365         {}
05369     virtual ~TCAPUser();
05370 
05375     virtual void attach(SS7TCAP* tcap);
05376 
05382     virtual bool tcapIndication(NamedList& params);
05383 
05388     inline SS7TCAP* tcap() const
05389         { return m_tcap; }
05390 
05397     virtual bool managementNotify(SCCP::Type type, NamedList& params);
05398 
05403     virtual int managementState();
05404 
05409     virtual void  destroyed();
05410 
05411 protected:
05412     inline void setTCAP(SS7TCAP* tcap)
05413     {
05414         Lock l(m_tcapMtx);
05415         m_tcap = tcap;
05416     }
05417 
05418 private:
05419     SS7TCAP* m_tcap;
05420     Mutex m_tcapMtx;
05421 };
05422 
05423 
05428 class YSIG_API SS7L2User : virtual public SignallingComponent
05429 {
05430     YCLASS(SS7L2User,SignallingComponent)
05431     friend class SS7Layer2;
05432 public:
05437     virtual void attach(SS7Layer2* link) = 0;
05438 
05443     virtual void detach(SS7Layer2* link) = 0;
05444 
05445 protected:
05453     virtual bool receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls) = 0;
05454 
05462     virtual bool recoveredMSU(const SS7MSU& msu, SS7Layer2* link, int sls) = 0;
05463 
05469     virtual void notify(SS7Layer2* link) = 0;
05470 };
05471 
05476 class YSIG_API SS7Layer2 : virtual public SignallingComponent
05477 {
05478     YCLASS(SS7Layer2,SignallingComponent)
05479     friend class SS7MTP3;
05480 public:
05484     enum LinkStatus {
05485         OutOfAlignment = 0,
05486         NormalAlignment = 1,
05487         EmergencyAlignment = 2,
05488         OutOfService = 3,
05489         ProcessorOutage = 4,
05490         Busy = 5,
05491         // short versions as defined by RFC
05492         O = OutOfAlignment,
05493         N = NormalAlignment,
05494         E = EmergencyAlignment,
05495         OS = OutOfService,
05496         PO = ProcessorOutage,
05497         B = Busy,
05498     };
05499 
05503     enum Operation {
05504         // take link out of service
05505         Pause  = 0x100,
05506         // start link operation, align if it needs to
05507         Resume = 0x200,
05508         // start link, force realignment
05509         Align  = 0x300,
05510         // get operational status
05511         Status = 0x400,
05512     };
05513 
05517     enum Inhibitions {
05518         // basic maintenance checks not performed
05519         Unchecked = 0x01,
05520         // management inactivation
05521         Inactive  = 0x02,
05522         // locally inhibited
05523         Local     = 0x04,
05524         // remotely inhibited
05525         Remote    = 0x08,
05526     };
05527 
05533     virtual bool transmitMSU(const SS7MSU& msu) = 0;
05534 
05539     virtual void recoverMSU(int sequence)
05540         { }
05541 
05546     virtual unsigned int status() const;
05547 
05554     virtual const char* statusName(unsigned int status, bool brief) const;
05555 
05561     inline const char* statusName(bool brief = false) const
05562         { return statusName(status(),brief); }
05563 
05568     virtual bool operational() const = 0;
05569 
05574     unsigned int upTime() const
05575         { return m_lastUp ? (Time::secNow() - m_lastUp) : 0; }
05576 
05581     void attach(SS7L2User* l2user);
05582 
05587     inline SS7L2User* user() const
05588         { return m_l2user; }
05589 
05594     inline int sls() const
05595         { return m_sls; }
05596 
05601     inline void sls(int linkSel)
05602         { if ((m_sls < 0) || !m_l2user) m_sls = linkSel; }
05603 
05608     inline int inhibited() const
05609         { return m_inhibited; }
05610 
05616     inline bool inhibited(int flags) const
05617         { return (m_inhibited & flags) != 0; }
05618 
05623     virtual unsigned int congestion()
05624         { return m_congestion; }
05625 
05630     virtual int getSequence()
05631         { return m_lastSeqRx; }
05632 
05641     virtual bool control(Operation oper, NamedList* params = 0);
05642 
05648     virtual bool control(NamedList& params);
05649 
05650 protected:
05654     inline SS7Layer2()
05655         : m_autoEmergency(true), m_lastSeqRx(-1), m_congestion(0),
05656           m_l2userMutex(true,"SS7Layer2::l2user"), m_l2user(0), m_sls(-1),
05657           m_checkTime(0), m_checkFail(0), m_inhibited(Unchecked), m_lastUp(0),
05658           m_notify(false)
05659         { }
05660 
05665     virtual void timerTick(const Time& when);
05666 
05672     inline bool receivedMSU(const SS7MSU& msu)
05673     {
05674         m_l2userMutex.lock();
05675         RefPointer<SS7L2User> tmp = m_l2user;
05676         m_l2userMutex.unlock();
05677         return tmp && tmp->receivedMSU(msu,this,m_sls);
05678     }
05679 
05685     inline bool recoveredMSU(const SS7MSU& msu)
05686     {
05687         m_l2userMutex.lock();
05688         RefPointer<SS7L2User> tmp = m_l2user;
05689         m_l2userMutex.unlock();
05690         return tmp && tmp->recoveredMSU(msu,this,m_sls);
05691     }
05692 
05697     void notify();
05698 
05705     bool inhibit(int setFlags, int clrFlags = 0);
05706 
05713     bool getEmergency(NamedList* params = 0, bool emg = false) const;
05714 
05718     bool m_autoEmergency;
05719 
05723     int m_lastSeqRx;
05724 
05728     unsigned int m_congestion;
05729 
05730 private:
05731     Mutex m_l2userMutex;
05732     SS7L2User* m_l2user;
05733     int m_sls;
05734     u_int64_t m_checkTime;
05735     int m_checkFail;
05736     int m_inhibited;
05737     u_int32_t m_lastUp;
05738     bool m_notify;                       // Notify on timer tick
05739 };
05740 
05746 class YSIG_API SS7Route : public RefObject, public Mutex
05747 {
05748     friend class SS7Layer3;
05749     friend class SS7Router;
05750 public:
05754     enum State {
05755         Unknown       = 0x80,
05756         // Standard route states
05757         Prohibited    = 0x01,
05758         Restricted    = 0x02,
05759         Congestion    = 0x04,
05760         Allowed       = 0x08,
05761         // Masks for typical combinations
05762         NotAllowed    = 0x77,
05763         NotCongested  = 0x78,
05764         NotRestricted = 0x7c,
05765         NotProhibited = 0x7e,
05766         KnownState    = 0x7f,
05767         AnyState      = 0xff
05768     };
05769 
05779     inline SS7Route(unsigned int packed, SS7PointCode::Type type,
05780             unsigned int priority = 0, unsigned int shift = 0,
05781             unsigned int maxDataLength = 272)
05782         : Mutex(true,"SS7Route"), m_packed(packed), m_type(type),
05783         m_priority(priority), m_shift(shift),m_maxDataLength(maxDataLength),
05784         m_state(Unknown),m_buffering(0), m_congCount(0),m_congBytes(0)
05785         { m_networks.setDelete(false); }
05786 
05791     inline SS7Route(const SS7Route& original)
05792         : Mutex(true,"SS7Route"), m_packed(original.packed()),
05793           m_type(original.m_type), m_priority(original.priority()),
05794           m_shift(original.shift()), m_maxDataLength(original.getMaxDataLength()),
05795           m_state(original.state()), m_buffering(0), m_congCount(0), m_congBytes(0)
05796         { m_networks.setDelete(false); }
05797 
05801     virtual ~SS7Route()
05802         { }
05803 
05808     State state() const
05809         { return m_state; }
05810 
05815     static const TokenDict* stateNames();
05816 
05821     const char* stateName() const
05822         { return lookup(m_state,stateNames()); }
05823 
05829     static const char* stateName(State state)
05830         { return lookup(state,stateNames()); }
05831 
05836     unsigned int priority() const
05837         { return m_priority; }
05838 
05843     unsigned int getMaxDataLength() const
05844         { return m_maxDataLength; }
05845 
05850     unsigned int packed() const
05851         { return m_packed; }
05852 
05857     unsigned int shift() const
05858         { return m_shift; }
05859 
05866     void attach(SS7Layer3* network, SS7PointCode::Type type);
05867 
05874     bool detach(SS7Layer3* network);
05875 
05881     bool hasNetwork(const SS7Layer3* network);
05882 
05888     bool hasNetwork(const SS7Layer3* network) const;
05889 
05895     bool operational(int sls = -1);
05896 
05908     int transmitMSU(const SS7Router* router, const SS7MSU& msu,
05909         const SS7Label& label, int sls, State states, const SS7Layer3* source = 0);
05910 
05915     bool congested();
05916 
05920     void reroute();
05921 
05922 private:
05923     int transmitInternal(const SS7Router* router, const SS7MSU& msu,
05924         const SS7Label& label, int sls, State states, const SS7Layer3* source);
05925     void rerouteCheck(u_int64_t when);
05926     void rerouteFlush();
05927     unsigned int m_packed;               // Packed destination point code
05928     SS7PointCode::Type m_type;           // The point code type
05929     unsigned int m_priority;             // Network priority for the given destination (used by SS7Layer3)
05930     unsigned int m_shift;                // SLS right shift when selecting linkset
05931     unsigned int m_maxDataLength;        // The maximum data length that can be transported on this route
05932     ObjList m_networks;                  // List of networks used to route to the given destination (used by SS7Router)
05933     State m_state;                       // State of the route
05934     u_int64_t m_buffering;               // Time when controlled rerouting ends
05935     ObjList m_reroute;                   // Controlled rerouting buffer
05936     unsigned int m_congCount;            // Congestion event count
05937     unsigned int m_congBytes;            // Congestion MSU bytes count
05938 };
05939 
05944 class YSIG_API SS7L3User : virtual public SignallingComponent
05945 {
05946     friend class SS7Layer3;
05947     friend class SS7Router;
05948 public:
05953     virtual void attach(SS7Layer3* network) = 0;
05954 
05955 protected:
05964     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls) = 0;
05965 
05974     virtual bool recoveredMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls)
05975         { return false; }
05976 
05986     virtual void receivedUPU(SS7PointCode::Type type, const SS7PointCode node,
05987         SS7MSU::Services part, unsigned char cause, const SS7Label& label, int sls)
05988         { }
05989 
05995     virtual void notify(SS7Layer3* link, int sls);
05996 
06003     virtual void routeStatusChanged(SS7PointCode::Type type, const SS7PointCode& node, SS7Route::State state)
06004         { }
06005 
06012     static ObjList* getNetRoutes(SS7Layer3* network, SS7PointCode::Type type);
06013 
06020     static const ObjList* getNetRoutes(const SS7Layer3* network, SS7PointCode::Type type);
06021 };
06022 
06027 class YSIG_API SS7Layer3 : virtual public SignallingComponent
06028 {
06029     YCLASS(SS7Layer3,SignallingComponent)
06030     friend class SS7L3User;
06031     friend class SS7Router;              // Access the data members to build the routing table
06032     friend class SS7Route;
06033 public:
06037     virtual ~SS7Layer3()
06038          { attach(0); }
06039 
06045     virtual bool initialize(const NamedList* config);
06046 
06054     virtual int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1) = 0;
06055 
06061     virtual bool operational(int sls = -1) const = 0;
06062 
06068     virtual int inhibited(int sls) const
06069         { return 0; }
06070 
06077     inline bool inhibited(int sls, int flags) const
06078         { return (inhibited(sls) & flags) != 0; }
06079 
06087     virtual bool inhibit(int sls, int setFlags, int clrFlags = 0)
06088         { return false; }
06089 
06096     inline bool inService(int sls, int ignore = 0)
06097         { return operational(sls) && !inhibited(sls,~ignore); }
06098 
06104     virtual unsigned int congestion(int sls)
06105         { return 0; }
06106 
06112     virtual int getSequence(int sls) const
06113         { return -1; }
06114 
06120     virtual void recoverMSU(int sls, int sequence)
06121         { }
06122 
06127     virtual bool restart()
06128         { return false; }
06129 
06135     void attach(SS7L3User* l3user);
06136 
06141     inline SS7L3User* user() const
06142         { return m_l3user; }
06143 
06149     SS7PointCode::Type type(unsigned char netType) const;
06150 
06156     void setType(SS7PointCode::Type type, unsigned char netType);
06157 
06162     void setType(SS7PointCode::Type type);
06163 
06169     bool hasType(SS7PointCode::Type pcType) const;
06170 
06177     virtual unsigned char getNI(SS7PointCode::Type pcType, unsigned char defNI) const;
06178 
06184     inline unsigned char getNI(SS7PointCode::Type pcType) const
06185         { return getNI(pcType,m_defNI); }
06186 
06191     inline unsigned char getNI() const
06192         { return m_defNI; }
06193 
06198     void setNI(unsigned char defNI);
06199 
06206     bool buildRoutes(const NamedList& params);
06207 
06215     unsigned int getRouteMaxLength(SS7PointCode::Type type, unsigned int packedPC);
06216 
06224     unsigned int getRoutePriority(SS7PointCode::Type type, unsigned int packedPC);
06225 
06233     inline unsigned int getRoutePriority(SS7PointCode::Type type, const SS7PointCode& dest)
06234         { return getRoutePriority(type,dest.pack(type)); }
06235 
06244     SS7Route::State getRouteState(SS7PointCode::Type type, unsigned int packedPC, bool checkAdjacent = false);
06245 
06254     inline SS7Route::State getRouteState(SS7PointCode::Type type, const SS7PointCode& dest, bool checkAdjacent = false)
06255         { return getRouteState(type,dest.pack(type),checkAdjacent); }
06256 
06263     virtual bool allowedTo(SS7PointCode::Type type, unsigned int packedPC) const
06264         { return true; }
06265 
06269     void printRoutes();
06270 
06276     inline unsigned int getLocal(SS7PointCode::Type type) const
06277         { return (type < SS7PointCode::DefinedTypes) ? m_local[type-1] : 0; }
06278 
06284     virtual unsigned int getDefaultLocal(SS7PointCode::Type type) const
06285         { return getLocal(type); }
06286 
06287 protected:
06292     SS7Layer3(SS7PointCode::Type type = SS7PointCode::Other);
06293 
06301     inline HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, int sls)
06302     {
06303         m_l3userMutex.lock();
06304         RefPointer<SS7L3User> tmp = m_l3user;
06305         m_l3userMutex.unlock();
06306         return tmp ? tmp->receivedMSU(msu,label,this,sls) : HandledMSU(HandledMSU::Unequipped);
06307     }
06308 
06316     inline bool recoveredMSU(const SS7MSU& msu, const SS7Label& label, int sls)
06317     {
06318         m_l3userMutex.lock();
06319         RefPointer<SS7L3User> tmp = m_l3user;
06320         m_l3userMutex.unlock();
06321         return tmp && tmp->recoveredMSU(msu,label,this,sls);
06322     }
06323 
06328     inline void notify(int sls = -1)
06329     {
06330         m_l3userMutex.lock();
06331         RefPointer<SS7L3User> tmp = m_l3user;
06332         m_l3userMutex.unlock();
06333         if (tmp)
06334             tmp->notify(this,sls);
06335     }
06336 
06342     virtual void linkChecked(int sls, bool remote)
06343         { }
06344 
06352     virtual bool maintenance(const SS7MSU& msu, const SS7Label& label, int sls);
06353 
06361     virtual bool management(const SS7MSU& msu, const SS7Label& label, int sls);
06362 
06371     virtual bool unavailable(const SS7MSU& msu, const SS7Label& label, int sls, unsigned char cause = 0);
06372 
06380     virtual bool prohibited(unsigned char ssf, const SS7Label& label, int sls);
06381 
06386     virtual bool responder() const
06387         { return true; }
06388 
06396     SS7Route* findRoute(SS7PointCode::Type type, unsigned int packed);
06397 
06403     inline ObjList* getRoutes(SS7PointCode::Type type)
06404         { return (type < SS7PointCode::DefinedTypes) ? &m_route[type-1] : 0; }
06405 
06411     inline const ObjList* getRoutes(SS7PointCode::Type type) const
06412         { return (type < SS7PointCode::DefinedTypes) ? &m_route[type-1] : 0; }
06413 
06415     Mutex m_routeMutex;
06416 
06418     ObjList m_route[YSS7_PCTYPE_COUNT];
06419 
06420 private:
06421     Mutex m_l3userMutex;                 // Mutex to lock L3 user pointer
06422     SS7L3User* m_l3user;
06423     SS7PointCode::Type m_cpType[4];      // Map incoming MSUs net indicators to point code type
06424                                          // or the routing table of a message router
06425     unsigned int m_local[YSS7_PCTYPE_COUNT];
06426     unsigned char m_defNI;               // Default Network Indicator
06427 };
06428 
06433 class YSIG_API SS7Layer4 : public SS7L3User
06434 {
06435 public:
06440     virtual void destroyed();
06441 
06447     virtual bool initialize(const NamedList* config);
06448 
06453     virtual void attach(SS7Layer3* network);
06454 
06459     inline SS7Layer3* network() const
06460         { return m_layer3; }
06461 
06466     inline unsigned char sio() const
06467         { return m_sio; }
06468 
06473     inline unsigned char sif() const
06474         { return m_sio & 0x0f; }
06475 
06480     inline unsigned char ssf() const
06481         { return m_sio & 0xf0; }
06482 
06487     inline unsigned char prio() const
06488         { return m_sio & 0x30; }
06489 
06494     inline unsigned char ni() const
06495         { return m_sio & 0xc0; }
06496 
06505     static unsigned char getSIO(const NamedList& params, unsigned char sif, unsigned char prio, unsigned char ni);
06506 
06514     static inline unsigned char getSIO(const NamedList& params, unsigned char sif, unsigned char ssf)
06515         { return getSIO(params,sif,ssf & 0x30,ssf & 0xc0); }
06516 
06523     static inline unsigned char getSIO(const NamedList& params, unsigned char sio)
06524         { return getSIO(params,sio & 0x0f,sio & 0x30,sio & 0xc0); }
06525 
06531     inline unsigned char getSIO(const NamedList& params) const
06532         { return getSIO(params,m_sio); }
06533 
06534 protected:
06540     SS7Layer4(unsigned char sio = SS7MSU::National, const NamedList* params = 0);
06541 
06549     inline int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1)
06550     {
06551         m_l3Mutex.lock();
06552         RefPointer<SS7Layer3> tmp = m_layer3;
06553         m_l3Mutex.unlock();
06554         return tmp ? tmp->transmitMSU(msu,label,sls) : -1;
06555     }
06556 
06560     unsigned char m_sio;
06561 
06562 private:
06563     Mutex m_l3Mutex;                     // Lock pointer use operations
06564     SS7Layer3* m_layer3;
06565 };
06566 
06572 class YSIG_API SS7Router : public SS7L3User, public SS7Layer3, public Mutex
06573 {
06574     YCLASS2(SS7Router,SS7L3User,SS7Layer3)
06575 public:
06579     enum Operation {
06580         // stop MTP operation, disable the router
06581         Pause     = 0x100,
06582         // start router, restart MTP if needed
06583         Resume    = 0x200,
06584         // forcibly execute MTP restart
06585         Restart   = 0x300,
06586         // get operational status
06587         Status    = 0x400,
06588         // forcibly advertise availability to adjacent routes
06589         Traffic   = 0x500,
06590         // forcibly advertise available routes
06591         Advertise = 0x600,
06592     };
06593 
06598     SS7Router(const NamedList& params);
06599 
06603     virtual ~SS7Router();
06604 
06610     virtual bool initialize(const NamedList* config);
06611 
06619     virtual int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1);
06620 
06626     virtual bool operational(int sls = -1) const;
06627 
06632     virtual bool restart();
06633 
06638     virtual void attach(SS7Layer3* network);
06639 
06644     virtual void detach(SS7Layer3* network);
06645 
06650     void attach(SS7Layer4* service);
06651 
06656     void detach(SS7Layer4* service);
06657 
06665     bool uninhibit(SS7Layer3* network, int sls, bool remote);
06666 
06675     bool inhibit(const SS7Label& link, int setFlags, int clrFlags = 0, bool notLast = false);
06676 
06683     bool inhibited(const SS7Label& link, int flags);
06684 
06690     int getSequence(const SS7Label& link);
06691 
06697     void recoverMSU(const SS7Label& link, int sequence);
06698 
06708     virtual void receivedUPU(SS7PointCode::Type type, const SS7PointCode node,
06709         SS7MSU::Services part, unsigned char cause, const SS7Label& label, int sls);
06710 
06715     inline bool transfer() const
06716         { return m_transfer; }
06717 
06722     inline bool transferring() const
06723         { return m_transfer || m_transferSilent; }
06724 
06729     inline bool starting() const
06730         { return !m_started; }
06731 
06736     inline SS7Management* getManagement() const
06737         { return m_mngmt; }
06738 
06745     virtual unsigned char getNI(SS7PointCode::Type pcType, unsigned char defNI) const;
06746 
06752     virtual unsigned int getDefaultLocal(SS7PointCode::Type type) const;
06753 
06754 protected:
06758     void clearView(const SS7Layer3* network);
06759 
06768     SS7Route::State getRouteView(SS7PointCode::Type type, unsigned int packedPC,
06769         unsigned int remotePC = 0, const SS7Layer3* network = 0);
06770 
06781     bool setRouteState(SS7PointCode::Type type, unsigned int packedPC, SS7Route::State state,
06782         unsigned int remotePC = 0, const SS7Layer3* network = 0);
06783 
06794     inline bool setRouteState(SS7PointCode::Type type, const SS7PointCode& dest, SS7Route::State state,
06795         unsigned int remotePC = 0, const SS7Layer3* network = 0)
06796         { return setRouteState(type,dest.pack(type),state,remotePC,network); }
06797 
06802     void loadLocalPC(const NamedList& params);
06803 
06808     virtual void timerTick(const Time& when);
06809 
06818     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
06819 
06825     void updateRoutes(SS7Layer3* network);
06826 
06833     void removeRoutes(SS7Layer3* network);
06834 
06840     void notifyRoutes(SS7Route::State states = SS7Route::AnyState, unsigned int onlyPC = 0);
06841 
06847     void notifyRoutes(SS7Route::State states, const SS7Layer3* network);
06848 
06859     virtual void routeChanged(const SS7Route* route, SS7PointCode::Type type,
06860         unsigned int remotePC = 0, const SS7Layer3* network = 0,
06861         unsigned int onlyPC = 0, bool forced = false);
06862 
06869     virtual void notify(SS7Layer3* network, int sls);
06870 
06876     virtual bool control(NamedList& params);
06877 
06881     virtual void destroyed();
06882 
06884     ObjList m_layer3;
06886     ObjList m_layer4;
06888     int m_changes;
06890     bool m_transfer;
06892     bool m_phase2;
06894     bool m_started;
06896     SignallingTimer m_restart;
06898     SignallingTimer m_isolate;
06899 
06900 private:
06901     void restart2();
06902     void disable();
06903     void sendRestart(const SS7Layer3* network = 0);
06904     void sendRestart(SS7PointCode::Type type, unsigned int packedPC);
06905     void silentAllow(const SS7Layer3* network = 0);
06906     void silentAllow(SS7PointCode::Type type, unsigned int packedPC);
06907     void checkRoutes(const SS7Layer3* noResume = 0);
06908     void clearRoutes(SS7Layer3* network, bool ok);
06909     void reroute(const SS7Layer3* network);
06910     void rerouteCheck(const Time& when);
06911     void rerouteFlush();
06912     bool setRouteSpecificState(SS7PointCode::Type type, unsigned int packedPC,
06913         unsigned int srcPC, SS7Route::State state, const SS7Layer3* changer = 0);
06914     inline bool setRouteSpecificState(SS7PointCode::Type type, const SS7PointCode& dest,
06915         const SS7PointCode&src, SS7Route::State state, const SS7Layer3* changer = 0)
06916         { return setRouteSpecificState(type,dest.pack(type),src.pack(type),state,changer); }
06917     void sendRouteTest();
06918     int routeMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls, SS7Route::State states);
06919     void buildView(SS7PointCode::Type type, ObjList& view, SS7Layer3* network);
06920     void buildViews();
06921     Mutex m_statsMutex;
06922     SignallingTimer m_trafficOk;
06923     SignallingTimer m_trafficSent;
06924     SignallingTimer m_routeTest;
06925     bool m_testRestricted;
06926     bool m_transferSilent;
06927     bool m_checkRoutes;
06928     bool m_autoAllowed;
06929     bool m_sendUnavail;
06930     bool m_sendProhibited;
06931     unsigned long m_rxMsu;
06932     unsigned long m_txMsu;
06933     unsigned long m_fwdMsu;
06934     unsigned long m_congestions;
06935     SS7Management* m_mngmt;
06936 };
06937 
06944 class YSIG_API SS7M2PA : public SS7Layer2, public SIGTRAN
06945 {
06946     YCLASS(SS7M2PA,SS7Layer2)
06947 public:
06948     enum m2paState {
06949         Alignment = 1,
06950         ProvingNormal = 2,
06951         ProvingEmergency = 3,
06952         Ready = 4,
06953         ProcessorOutage = 5,
06954         ProcessorRecovered = 6,
06955         Busy = 7,
06956         BusyEnded = 8,
06957         OutOfService = 9,
06958     };
06959 
06960     enum msgType {
06961         UserData = 1,
06962         LinkStatus = 2
06963     };
06964 
06965     enum sctpState {
06966         Idle,
06967         Associating,
06968         Established
06969     };
06970 
06971     enum M2PAOperations {
06972         Pause        = SS7Layer2::Pause,
06973         // start link operation, align if it needs to
06974         Resume       = SS7Layer2::Resume,
06975         // start link, force realignment
06976         Align        = SS7Layer2::Align,
06977         // get operational status
06978         Status       = SS7Layer2::Status,
06979         // restart transport layer
06980         TransRestart = 0x500
06981     };
06982 
06986     SS7M2PA(const NamedList& params);
06987 
06991     ~SS7M2PA();
06992 
06998     virtual bool initialize(const NamedList* config);
06999 
07005     virtual bool control(NamedList& params);
07006 
07015     virtual bool control(M2PAOperations oper, NamedList* params = 0);
07016 
07021     virtual unsigned int status() const;
07022 
07028     virtual bool transmitMSU(const SS7MSU& msu);
07029 
07034     virtual void notifyLayer(SignallingInterface::Notification status);
07035 
07040     virtual void recoverMSU(int sequence);
07041 
07048     bool decodeSeq(const DataBlock& data, u_int8_t msgType);
07049 
07055     void abortAlignment(const char* info = 0);
07056 
07061     void transmitLS(int streamId = 0);
07062 
07067     void setHeader(DataBlock& data);
07068 
07075     bool processLinkStatus(DataBlock& data, int streamId);
07076 
07083     bool processSLinkStatus(DataBlock& data, int streamId);
07084 
07089     void sendAck();
07090 
07096     bool removeFrame(u_int32_t bsn);
07097 
07103     bool nextBsn(u_int32_t bsn) const;
07104 
07110     static inline u_int32_t increment(u_int32_t& nr)
07111         { return (nr == 0xffffff) ? (nr = 0) : nr++; }
07112 
07118     static inline u_int32_t getNext(u_int32_t nr)
07119         { return (nr == 0xffffff) ? 0 : nr + 1; }
07120 
07121 protected:
07122 
07127     virtual void timerTick(const Time& when);
07128 
07134     virtual bool aligned() const;
07135 
07140     virtual bool operational() const;
07141 
07151     virtual bool processMSG(unsigned char msgVersion, unsigned char msgClass,
07152         unsigned char msgType, const DataBlock& msg, int streamId);
07153 
07158     void startAlignment(bool emergency = false);
07159 
07163      void retransData();
07164 
07165 private:
07166     void dumpMsg(u_int8_t version, u_int8_t mClass, u_int8_t type,
07167         const DataBlock& data, int stream, bool send);
07168     void setLocalStatus(unsigned int status);
07169     void setRemoteStatus(unsigned int status);
07170     u_int32_t m_seqNr;
07171     u_int32_t m_needToAck;
07172     u_int32_t m_lastAck;
07173     u_int32_t m_confCounter;
07174     u_int32_t m_maxUnack;
07175     u_int32_t m_maxQueueSize;
07176     unsigned int m_localStatus;
07177     unsigned int m_state;
07178     unsigned int m_remoteStatus;
07179     unsigned int m_transportState;
07180     Mutex m_mutex;
07181     ObjList m_ackList;
07182     SignallingTimer m_t1;
07183     SignallingTimer m_t2;
07184     SignallingTimer m_t3;
07185     SignallingTimer m_t4;
07186     SignallingTimer m_ackTimer;
07187     SignallingTimer m_confTimer;
07188     SignallingTimer m_oosTimer;
07189     SignallingTimer m_waitOosTimer;
07190     bool m_autostart;
07191     bool m_sequenced;
07192     bool m_dumpMsg;
07193 };
07194 
07199 class YSIG_API SS7M2UAClient : public SIGAdaptClient
07200 {
07201     YCLASS(SS7M2UAClient,SIGAdaptClient)
07202 public:
07206     inline SS7M2UAClient(const NamedList& params)
07207         : SIGAdaptClient(params.safe("SS7M2UAClient"),&params,2,2904)
07208         { }
07209     virtual bool processMSG(unsigned char msgVersion, unsigned char msgClass,
07210         unsigned char msgType, const DataBlock& msg, int streamId);
07211 };
07212 
07219 class YSIG_API SS7M2UA : public SS7Layer2, public SIGAdaptUser
07220 {
07221     friend class SS7M2UAClient;
07222     YCLASS(SS7M2UA,SS7Layer2)
07223 public:
07228     SS7M2UA(const NamedList& params);
07229 
07235     virtual bool initialize(const NamedList* config);
07236 
07245     virtual bool control(Operation oper, NamedList* params = 0);
07246 
07251     virtual unsigned int status() const;
07252 
07258     virtual bool transmitMSU(const SS7MSU& msu);
07259 
07264     virtual void recoverMSU(int sequence);
07265 
07270     virtual bool operational() const;
07271 
07276     virtual int getSequence();
07277 
07282     virtual void activeChange(bool active);
07283 
07288     inline int32_t iid() const
07289         { return m_iid; }
07290 
07291 protected:
07292     enum LinkState {
07293         LinkDown,
07294         LinkReq,
07295         LinkReqEmg,
07296         LinkUp,
07297         LinkUpEmg,
07298     };
07299 
07304     virtual void timerTick(const Time& when);
07305 
07306     SS7M2UAClient* client() const
07307         { return static_cast<SS7M2UAClient*>(adaptation()); }
07308     virtual bool processMGMT(unsigned char msgType, const DataBlock& msg, int streamId);
07309     virtual bool processMAUP(unsigned char msgType, const DataBlock& msg, int streamId);
07310     void postRetrieve();
07311     SignallingTimer m_retrieve;
07312     int32_t m_iid;
07313     int m_linkState;
07314     bool m_rpo;
07315     bool m_longSeq;
07316 };
07317 
07324 class YSIG_API SS7M3UA : public SS7Layer3, public SIGAdaptUser
07325 {
07326     YCLASS(SS7M3UA,SS7Layer3)
07327 };
07328 
07333 class YSIG_API SS7MTP2 : public SS7Layer2, public SignallingReceiver, public SignallingDumpable, public Mutex
07334 {
07335     YCLASS2(SS7MTP2,SS7Layer2,SignallingReceiver)
07336 public:
07340     enum ErrorCorrection {
07341         Basic,       // retransmits only based on sequence numbers
07342         Preventive,  // continuously retransmit unacknowledged packets
07343         Adaptive,    // switch to using preventive retransmission dynamically
07344     };
07345 
07351     SS7MTP2(const NamedList& params, unsigned int status = OutOfService);
07352 
07356     virtual ~SS7MTP2();
07357 
07363     virtual bool initialize(const NamedList* config);
07364 
07370     virtual bool transmitMSU(const SS7MSU& msu);
07371 
07376     virtual void recoverMSU(int sequence);
07377 
07382     virtual unsigned int status() const;
07383 
07389     virtual bool aligned() const;
07390 
07395     virtual bool operational() const;
07396 
07405     virtual bool control(Operation oper, NamedList* params = 0);
07406 
07412     virtual bool notify(SignallingInterface::Notification event);
07413 
07414 protected:
07418     virtual void destroyed()
07419     {
07420         SS7Layer2::attach(0);
07421         TelEngine::destruct(SignallingReceiver::attach(0));
07422         SignallingComponent::destroyed();
07423     }
07424 
07429     virtual void timerTick(const Time& when);
07430 
07435     virtual bool receivedPacket(const DataBlock& packet);
07436 
07440     virtual void processFISU();
07441 
07446     virtual void processLSSU(unsigned int status);
07447 
07453     bool transmitLSSU(unsigned int status);
07454 
07459     inline bool transmitLSSU()
07460         { return transmitLSSU(m_lStatus); }
07461 
07466     bool transmitFISU();
07467 
07472     void startAlignment(bool emergency = false);
07473 
07478     void abortAlignment(bool retry = true);
07479 
07484     bool startProving();
07485 
07486 private:
07487     virtual bool control(NamedList& params)
07488         { return SignallingDumpable::control(params,this) || SS7Layer2::control(params); }
07489     void unqueueAck(unsigned char bsn);
07490     bool txPacket(const DataBlock& packet, bool repeat, SignallingInterface::PacketType type = SignallingInterface::Unknown);
07491     void setLocalStatus(unsigned int status);
07492     void setRemoteStatus(unsigned int status);
07493     // sent but yet unacknowledged packets
07494     ObjList m_queue;
07495     // data link status (alignment) - desired, local and remote
07496     unsigned int m_status, m_lStatus, m_rStatus;
07497     // various interval period end
07498     u_int64_t m_interval;
07499     // time when resending packets
07500     u_int64_t m_resend;
07501     // time when aborting resending packets
07502     u_int64_t m_abort;
07503     // time when need to transmit next FISU/LSSU
07504     u_int64_t m_fillTime;
07505     // remote congestion indicator
07506     bool m_congestion;
07507     // backward and forward sequence numbers
07508     unsigned char m_bsn, m_fsn;
07509     // backward and forward indicator bits
07510     bool m_bib, m_fib;
07511     // last forward sequence number we sent a retransmission request
07512     unsigned char m_lastFsn;
07513     // last received backward sequence number
07514     unsigned char m_lastBsn;
07515     // last received backward indicator bit
07516     bool m_lastBib;
07517     // count of errors
07518     unsigned int m_errors;
07519     // maximum accepted errors
07520     unsigned int m_maxErrors;
07521     // packet resend interval
07522     unsigned int m_resendMs;
07523     // packet resend abort interval
07524     unsigned int m_abortMs;
07525     // FISU/LSSU soft resend interval
07526     unsigned int m_fillIntervalMs;
07527     // fill link with end-to-end FISU/LSSU
07528     bool m_fillLink;
07529     // automatically align on resume
07530     bool m_autostart;
07531     // flush MSUs after aligning
07532     bool m_flushMsus;
07533 };
07534 
07539 class YSIG_API SS7MTP3 : public SS7Layer3, public SS7L2User, public SignallingDumpable, public Mutex
07540 {
07541     YCLASS(SS7MTP3,SS7Layer3)
07542 public:
07546     enum Operation {
07547         // take linkset out of service
07548         Pause   = 0x100,
07549         // start linkset operation
07550         Resume  = 0x200,
07551         // force a MTP restart procedure
07552         Restart = 0x300,
07553         // get operational status
07554         Status  = 0x400,
07555     };
07556 
07561     SS7MTP3(const NamedList& params);
07562 
07566     virtual ~SS7MTP3();
07567 
07573     virtual bool initialize(const NamedList* config);
07574 
07582     virtual int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1);
07583 
07589     virtual bool operational(int sls = -1) const;
07590 
07596     virtual int inhibited(int sls) const;
07597 
07605     virtual bool inhibit(int sls, int setFlags, int clrFlags = 0);
07606 
07612     virtual unsigned int congestion(int sls);
07613 
07619     virtual int getSequence(int sls) const;
07620 
07626     virtual void recoverMSU(int sls, int sequence);
07627 
07635     virtual bool control(Operation oper, NamedList* params = 0);
07636 
07641     virtual void attach(SS7Layer2* link);
07642 
07647     virtual void detach(SS7Layer2* link);
07648 
07654     virtual bool control(NamedList& params);
07655 
07662     virtual bool allowedTo(SS7PointCode::Type type, unsigned int packedPC) const;
07663 
07668     inline unsigned int linksTotal() const
07669         { return m_total; }
07670 
07675     inline unsigned int linksChecked() const
07676         { return m_checked; }
07677 
07682     inline unsigned int linksActive() const
07683         { return m_active; }
07684 
07689     inline const ObjList* links() const
07690         { return &m_links; }
07691 
07692 protected:
07696     virtual void destroyed();
07697 
07702     virtual void timerTick(const Time& when);
07703 
07709     virtual void linkChecked(int sls, bool remote);
07710 
07715     virtual bool responder() const
07716         { return !m_inhibit; }
07717 
07725     virtual bool receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls);
07726 
07734     virtual bool recoveredMSU(const SS7MSU& msu, SS7Layer2* link, int sls);
07735 
07741     virtual void notify(SS7Layer2* link);
07742 
07747     unsigned int countLinks();
07748 
07749 private:
07750     ObjList m_links;
07751     // total links in linkset
07752     unsigned int m_total;
07753     // checked links in linkset
07754     unsigned int m_checked;
07755     // currently active links
07756     unsigned int m_active;
07757     // inhibited flag
07758     bool m_inhibit;
07759     // warn if all links are down
07760     bool m_warnDown;
07761     // check the links before placing them in service
07762     bool m_checklinks;
07763     // realign links that don't respond to test messages anymore
07764     bool m_forcealign;
07765     // maintenance check intervals (Q.707)
07766     u_int64_t m_checkT1;
07767     u_int64_t m_checkT2;
07768     // list of allowed point codes seen from this network
07769     unsigned int* m_allowed[YSS7_PCTYPE_COUNT];
07770 };
07771 
07776 class YSIG_API SS7MsgSNM : public SignallingMessage
07777 {
07778 public:
07782     enum Type {
07783         Unknown = 0,
07784         COO  = 0x11, // Changeover Order signal
07785         ECO  = 0x12, // Emergency Changeover Order signal
07786         RCT  = 0x13, // Route Set Congestion Test signal
07787         TFP  = 0x14, // Transfer Prohibited signal
07788         RST  = 0x15, // Route Set Test for prohibited destination
07789         RSP  = RST,  // Route Set Test for prohibited destination (ANSI)
07790         LIN  = 0x16, // Link Inhibit signal
07791         TRA  = 0x17, // Traffic Restart Allowed signal
07792         DLC  = 0x18, // Data Link Connection Order signal
07793         UPU  = 0x1a, // User Part Unavailable signal
07794         COA  = 0x21, // Changeover Acknowledgment signal
07795         ECA  = 0x22, // Emergency Changeover Acknowledgment signal
07796         TFC  = 0x23, // Transfer Controlled signal
07797         TCP  = 0x24, // Transfer Cluster Prohibited
07798         TFPA = TCP,  // Transfer Prohibited Acknowledgment (Yellow Book only)
07799         RSR  = 0x25, // Route Set Test for prohibited destination (national use)
07800         LUN  = 0x26, // Link Uninhibit signal
07801         TRW  = 0x27, // Traffic Restart Waiting (ANSI only)
07802         CSS  = 0x28, // Connection Successful signal
07803         XCO  = 0x31, // Extended Changeover Order signal
07804         TFR  = 0x34, // Transfer Restricted signal (national use)
07805         RCP  = 0x35, // Route Set Test for cluster-prohibited
07806         LIA  = 0x36, // Link Inhibit Acknowledgment signal
07807         CNS  = 0x38, // Connection Not Successful signal
07808         XCA  = 0x41, // Extended Changeover Acknowledgment signal
07809         TCR  = 0x44, // Transfer Cluster Restricted signal (ANSI only)
07810         RCR  = 0x45, // Route Set Test for cluster-restricted (ANSI only)
07811         LUA  = 0x46, // Link Uninhibit Acknowledgment signal
07812         CNP  = 0x48, // Connection Not Possible signal
07813         CBD  = 0x51, // Changeback Declaration signal
07814         TFA  = 0x54, // Transfer Allowed signal
07815         LID  = 0x56, // Link Inhibit Denied signal
07816         CBA  = 0x61, // Changeback Acknowledgment signal
07817         TCA  = 0x64, // Transfer Cluster Allowed
07818         TFAA = TCA,  // Transfer Allowed Acknowledgment (Yellow Book only)
07819         LFU  = 0x66, // Link Forced Uninhibit signal
07820         LLT  = 0x76, // Link Local Inhibit Test signal
07821         LLI  = LLT,  // Link Local Inhibit Test signal (ANSI)
07822         LRT  = 0x86, // Link Remote Inhibit Test signal
07823         LRI  = LRT,  // Link Remote Inhibit Test signal (ANSI)
07824     };
07825 
07829     enum Group {
07830         CHM = 0x01,  // Changeover and changeback
07831         ECM = 0x02,  // Emergency changeover
07832         FCM = 0x03,  // Transfer controlled and signalling route set congestion
07833         TFM = 0x04,  // Transfer prohibited/allowed/restricted
07834         RSM = 0x05,  // Signalling route/set/test
07835         MIM = 0x06,  // Management inhibit
07836         TRM = 0x07,  // Traffic restart allowed
07837         DLM = 0x08,  // Signalling data/link/connection
07838         UFC = 0x0a,  // User part flow control
07839     };
07840 
07845     SS7MsgSNM(unsigned char type);
07846 
07851     inline unsigned char type() const
07852         { return m_type; }
07853 
07858     inline unsigned char group() const
07859         { return m_type & 0x0f; }
07860 
07867     void toString(String& dest, const SS7Label& label, bool params) const;
07868 
07878     static SS7MsgSNM* parse(SS7Management* receiver, unsigned char type,
07879         SS7PointCode::Type pcType,
07880         const unsigned char* buf, unsigned int len);
07881 
07885     static const TokenDict* names();
07886 
07893     static inline const char* lookup(Type type, const char* defvalue = 0)
07894         { return TelEngine::lookup(type,names(),defvalue); }
07895 
07902     static inline Type lookup(const char* name, Type defvalue = Unknown)
07903         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
07904 
07905 private:
07906     unsigned char m_type;
07907 };
07908 
07913 class YSIG_API SS7MsgMTN
07914 {
07915 public:
07919     enum Type {
07920         Unknown = 0,
07921         SLTM = 0x11, // Signalling Link Test Message
07922         SLTA = 0x21, // Signalling Link Test Acknowledgment
07923     };
07924 
07925     static const TokenDict* names();
07926 
07933     static inline const char* lookup(Type type, const char* defvalue = 0)
07934         { return TelEngine::lookup(type,names(),defvalue); }
07935 
07942     static inline Type lookup(const char* name, Type defvalue = Unknown)
07943         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
07944 };
07945 
07950 class YSIG_API SS7MsgISUP : public SignallingMessage
07951 {
07952     YCLASS(SS7MsgISUP,SignallingMessage)
07953     friend class SS7ISUPCall;
07954 public:
07958     enum Type {
07959         Unknown = 0,
07960         IAM  = 0x01, // Initial Address Message
07961         SAM  = 0x02, // Subsequent Address Message
07962         INR  = 0x03, // Information Request (national use)
07963         INF  = 0x04, // Information (national use)
07964         COT  = 0x05, // Continuity
07965         ACM  = 0x06, // Address Complete Message
07966         CON  = 0x07, // Connect
07967         FOT  = 0x08, // Forward Transfer
07968         ANM  = 0x09, // Answer Message
07969         REL  = 0x0c, // Release Request
07970         SUS  = 0x0d, // Suspend
07971         RES  = 0x0e, // Resume
07972         RLC  = 0x10, // Release Complete
07973         CCR  = 0x11, // Continuity Check Request
07974         RSC  = 0x12, // Reset Circuit
07975         BLK  = 0x13, // Blocking
07976         UBL  = 0x14, // Unblocking
07977         BLA  = 0x15, // Blocking Acknowledgement
07978         UBA  = 0x16, // Unblocking Acknowledgement
07979         GRS  = 0x17, // Circuit Group Reset
07980         CGB  = 0x18, // Circuit Group Blocking
07981         CGU  = 0x19, // Circuit Group Unblocking
07982         CGA  = 0x1a, // Circuit Group Blocking Acknowledgement
07983         CGBA = CGA,
07984         CUA  = 0x1b, // Circuit Group Unblocking Acknowledgement
07985         CMR  = 0x1c, // Call Modification Request (ANSI only)
07986         CMC  = 0x1d, // Call Modification Completed (ANSI only)
07987         CMRJ = 0x1e, // Call Modification Rejected (ANSI only)
07988         FACR = 0x1f, // Facility Request
07989         FAA  = 0x20, // Facility Accepted
07990         FRJ  = 0x21, // Facility Reject
07991         FAD  = 0x22, // Facility Deactivated (ANSI only)
07992         FAI  = 0x23, // Facility Information (ANSI only)
07993         LPA  = 0x24, // Loopback Acknowledgement (national use)
07994         CSVR = 0x25, // CUG Selection and Validation Request (ANSI only)
07995         CSVS = 0x26, // CUG Selection and Validation Response (ANSI only)
07996         DRS  = 0x27, // Delayed Release (ANSI only)
07997         PAM  = 0x28, // Pass Along Message (national use)
07998         GRA  = 0x29, // Circuit Group Reset Acknowledgement
07999         CQM  = 0x2a, // Circuit Group Query (national use)
08000         CQR  = 0x2b, // Circuit Group Query Response (national use)
08001         CPR  = 0x2c, // Call Progress
08002         CPG  = CPR,
08003         USR  = 0x2d, // User-to-User Information
08004         UEC  = 0x2e, // Unequipped CIC (national use)
08005         UCIC = UEC,
08006         CNF  = 0x2f, // Confusion
08007         OLM  = 0x30, // Overload Message (national use)
08008         CRG  = 0x31, // Charge Information (national use and format, ITU only)
08009         NRM  = 0x32, // Network Resource Management
08010         FAC  = 0x33, // Facility (national use)
08011         UPT  = 0x34, // User Part Test
08012         UPA  = 0x35, // User Part Available
08013         IDR  = 0x36, // Identification Request (ITU only)
08014         IRS  = 0x37, // Identification Response (ITU only)
08015         SGM  = 0x38, // Segmentation
08016         LOP  = 0x40, // Loop Prevention
08017         APM  = 0x41, // Application Transport
08018         PRI  = 0x42, // Pre-Release Information
08019         SDN  = 0x43, // Subsequent Directory Number (national use)
08020         CRA  = 0xe9, // Circuit Reservation Acknowledgement (ANSI only)
08021         CRM  = 0xea, // Circuit Reservation (ANSI only)
08022         CVR  = 0xeb, // Circuit Validation Response (ANSI only)
08023         CVT  = 0xec, // Circuit Validation Test (ANSI only)
08024         EXM  = 0xed, // Exit Message (ANSI only)
08025         // Dummy, used for various purposes
08026         CtrlSave = 256  // control, save circuits
08027     };
08028 
08032     enum Parameters {
08033         EndOfParameters                = 0,
08034         CallReference                  = 0x01,
08035         TransmissionMediumRequirement  = 0x02,
08036         AccessTransport                = 0x03,
08037         CalledPartyNumber              = 0x04,
08038         SubsequentNumber               = 0x05,
08039         NatureOfConnectionIndicators   = 0x06,
08040         ForwardCallIndicators          = 0x07,
08041         OptionalForwardCallIndicators  = 0x08,
08042         CallingPartyCategory           = 0x09,
08043         CallingPartyNumber             = 0x0a,
08044         RedirectingNumber              = 0x0b,
08045         RedirectionNumber              = 0x0c,
08046         ConnectionRequest              = 0x0d,
08047         InformationRequestIndicators   = 0x0e,
08048         InformationIndicators          = 0x0f,
08049         ContinuityIndicators           = 0x10,
08050         BackwardCallIndicators         = 0x11,
08051         CauseIndicators                = 0x12,
08052         RedirectionInformation         = 0x13,
08053         GroupSupervisionTypeIndicator  = 0x15,
08054         RangeAndStatus                 = 0x16,
08055         CallModificationIndicators     = 0x17, // ANSI only
08056         FacilityIndicator              = 0x18,
08057         FacilityInformationIndicators  = 0x19, // ANSI only
08058         CUG_InterlockCode              = 0x1a,
08059         Index                          = 0x1b, // ANSI only
08060         CUG_CheckResponseIndicators    = 0x1c, // ANSI only
08061         UserServiceInformation         = 0x1d,
08062         SignallingPointCode            = 0x1e,
08063         UserToUserInformation          = 0x20,
08064         ConnectedNumber                = 0x21,
08065         SuspendResumeIndicators        = 0x22,
08066         TransitNetworkSelection        = 0x23,
08067         EventInformation               = 0x24,
08068         CircuitAssignmentMap           = 0x25, // ANSI only
08069         CircuitStateIndicator          = 0x26,
08070         AutomaticCongestionLevel       = 0x27,
08071         OriginalCalledNumber           = 0x28,
08072         OptionalBackwardCallIndicators = 0x29,
08073         UserToUserIndicators           = 0x2a,
08074         OriginationISCPointCode        = 0x2b, // ITU only
08075         GenericNotification            = 0x2c, // ITU only
08076         CallHistoryInformation         = 0x2d, // ITU only
08077         AccessDeliveryInformation      = 0x2e, // ITU only
08078         NetworkSpecificFacilities      = 0x2f, // ITU only
08079         UserServiceInformationPrime    = 0x30,
08080         PropagationDelayCounter        = 0x31, // ITU only
08081         RemoteOperations               = 0x32,
08082         ServiceActivation              = 0x33,
08083         UserTeleserviceInformation     = 0x34, // ITU only
08084         TransmissionMediumUsed         = 0x35,
08085         CallDiversionInformation       = 0x36, // ITU only
08086         EchoControlInformation         = 0x37, // ITU only
08087         MessageCompatInformation       = 0x38, // ITU only
08088         ParameterCompatInformation     = 0x39, // ITU only
08089         MLPP_Precedence                = 0x3a, // ITU name
08090         Precedence                     = MLPP_Precedence, // ANSI name
08091         MCID_RequestIndicator          = 0x3b, // ITU only
08092         MCID_ResponseIndicator         = 0x3c, // ITU only
08093         HopCounter                     = 0x3d,
08094         TransMediumRequirementPrime    = 0x3e, // ITU only
08095         LocationNumber                 = 0x3f, // ITU only
08096         RedirectionNumberRestriction   = 0x40, // ITU only
08097         FreephoneIndicators            = 0x41, // ITU only
08098         GenericReference               = 0x42, // ITU only
08099         CCSScallIndication             = 0x4b,
08100         ForwardGVNS                    = 0x4c,
08101         BackwardGVNS                   = 0x4d,
08102         RedirectCapability             = 0x4e, // National use
08103         RedirectCounter                = 0x77, // National use
08104         ApplicationTransport           = 0x78,
08105         CCNRpossibleIndicator          = 0x7a,
08106         PivotRoutingIndicators         = 0x7c,
08107         CalledDirectoryNumber          = 0x7d, // National use
08108         OriginalCalledINNumber         = 0x7f,
08109         CallingGeodeticLocation        = 0x81,
08110         HTR_Information                = 0x82,
08111         NetworkRoutingNumber           = 0x84, // National use
08112         QueryOnReleaseCapability       = 0x85, // Network option
08113         PivotStatus                    = 0x86, // National use
08114         PivotCounter                   = 0x87,
08115         PivotRoutingForwardInformation = 0x88,
08116         PivotRoutingBackInformation    = 0x89,
08117         RedirectStatus                 = 0x8a, // National use
08118         RedirectForwardInformation     = 0x8b, // National use
08119         RedirectBackwardInformation    = 0x8c, // National use
08120         NumberPortabilityInformation   = 0x8d, // Network option
08121         GenericNumber                  = 0xc0, // ITU name
08122         GenericAddress                 = GenericNumber, // ANSI name
08123         GenericDigits                  = 0xc1,
08124         OperatorServicesInformation    = 0xc2, // ANSI only
08125         Egress                         = 0xc3, // ANSI only
08126         Jurisdiction                   = 0xc4, // ANSI only
08127         CarrierIdentification          = 0xc5, // ANSI only
08128         BusinessGroup                  = 0xc6, // ANSI only
08129         GenericName                    = 0xc7, // ANSI only
08130         NotificationIndicator          = 0xe1, // ANSI only
08131         TransactionRequest             = 0xe3, // ANSI only
08132         CircuitGroupCharactIndicator   = 0xe5, // ANSI only
08133         CircuitValidationRespIndicator = 0xe6, // ANSI only
08134         OutgoingTrunkGroupNumber       = 0xe7, // ANSI only
08135         CircuitIdentificationName      = 0xe8, // ANSI only
08136         CommonLanguage                 = 0xe9, // ANSI only
08137         OriginatingLineInformation     = 0xea, // ANSI only
08138         ChargeNumber                   = 0xeb, // ANSI only
08139         ServiceCodeIndicator           = 0xec, // ANSI only
08140         SpecialProcessingRequest       = 0xed, // ANSI only
08141         CarrierSelectionInformation    = 0xee, // ANSI only
08142         NetworkTransport               = 0xef, // ANSI only
08143         NationalForwardCallIndicatorsLinkByLink = 0xf4, // UK-ISUP
08144         NationalInformationIndicators           = 0xf5, // UK-ISUP
08145         NationalInformationRequestIndicators    = 0xf6, // UK-ISUP
08146         CalledSubscribersTerminatingFacilMarks  = 0xf7, // UK-ISUP
08147         CallingSubscribersOriginatingFacilMarks = 0xf8, // UK-ISUP
08148         CallingSubscribersBasicServiceMarks     = 0xf9, // UK-ISUP
08149         CalledSubscribersBasicServiceMarks      = 0xfa, // UK-ISUP
08150         PartialCLI                              = 0xfb, // UK-ISUP
08151         LastDivertingLineIdentity               = 0xfc, // UK-ISUP
08152         PresentationNumber                      = 0xfd, // UK-ISUP
08153         NationalForwardCallIndicators           = 0xfe, // UK-ISUP
08154     };
08155 
08161     inline SS7MsgISUP(Type type, unsigned int cic)
08162         : SignallingMessage(lookup(type,"Unknown")), m_type(type), m_cic(cic)
08163         { }
08164 
08168     virtual ~SS7MsgISUP()
08169         { }
08170 
08175     inline Type type() const
08176         { return m_type; }
08177 
08182     inline unsigned int cic() const
08183         { return m_cic; }
08184 
08193     void toString(String& dest, const SS7Label& label, bool params,
08194         const void* raw = 0, unsigned int rawLen = 0) const;
08195 
08200     static const TokenDict* names();
08201 
08208     static inline const char* lookup(Type type, const char* defvalue = 0)
08209         { return TelEngine::lookup(type,names(),defvalue); }
08210 
08217     static inline Type lookup(const char* name, Type defvalue = Unknown)
08218         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
08219 
08220 private:
08221     Type m_type;                         // Message type
08222     unsigned int m_cic;                  // Source/destination Circuit Identification Code
08223 };
08224 
08229 class YSIG_API SS7Management : public SS7Layer4, public Mutex
08230 {
08231     YCLASS(SS7Management,SS7Layer4)
08232 public:
08236     SS7Management(const NamedList& params, unsigned char sio = SS7MSU::SNM|SS7MSU::National);
08237 
08238 protected:
08247     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
08248 
08256     bool inhibit(const SS7Label& link, int setFlags, int clrFlags = 0);
08257 
08264     bool inhibited(const SS7Label& link, int flags);
08265 
08271     void recover(const SS7Label& link, int sequence);
08272 
08279     virtual void notify(SS7Layer3* link, int sls);
08280 
08286     virtual bool control(NamedList& params);
08287 
08292     virtual void timerTick(const Time& when);
08293 
08294 private:
08295     bool postpone(SS7MSU* msu, const SS7Label& label, int txSls,
08296         u_int64_t interval, u_int64_t global = 0, bool force = false, const Time& when = Time());
08297     bool timeout(const SS7MSU& msu, const SS7Label& label, int txSls, bool final);
08298     bool timeout(SignallingMessageTimer& timer, bool final);
08299     SignallingMessageTimerList m_pending;
08300     bool m_changeMsgs;
08301     bool m_changeSets;
08302     bool m_neighbours;
08303 };
08304 
08309 class YSIG_API SS7Testing : public SS7Layer4, public Mutex
08310 {
08311     YCLASS(SS7Testing,SS7Layer4)
08312 public:
08316     inline SS7Testing(const NamedList& params, unsigned char sio = SS7MSU::MTP_T|SS7MSU::National)
08317         : SignallingComponent(params.safe("SS7Testing"),&params),
08318           SS7Layer4(sio,&params),
08319           Mutex(true,"SS7Testing"),
08320           m_timer(0), m_exp(0), m_seq(0), m_len(16), m_sharing(false)
08321         { }
08322 
08328     virtual bool initialize(const NamedList* config);
08329 
08335     virtual bool control(NamedList& params);
08336 
08337 protected:
08346     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
08347 
08354     virtual void notify(SS7Layer3* link, int sls);
08355 
08360     virtual void timerTick(const Time& when);
08361 
08362 private:
08363     bool sendTraffic();
08364     void setParams(const NamedList& params, bool setSeq = false);
08365     SignallingTimer m_timer;
08366     SS7Label m_lbl;
08367     u_int32_t m_exp;
08368     u_int32_t m_seq;
08369     u_int16_t m_len;
08370     bool m_sharing;
08371 };
08372 
08377 class YSIG_API SS7ISUPCall : public SignallingCall
08378 {
08379     friend class SS7ISUP;
08380 public:
08384     enum State {
08385         // NOTE: Keep the order of state values: the code relies on it
08386         Null      = 0,                   // No message exchanged
08387         Testing   = 1,                   // IAM but waiting for continuity check
08388         Setup     = 2,                   // IAM (initial address)
08389         Accepted  = 3,                   // ACM (address complete)
08390         Ringing   = 4,                   // CPM (call progress)
08391         Answered  = 5,                   // ANM (answer)
08392         Releasing = 6,                   // REL (release)
08393         Released  = 7                    // Call released, no message or events allowed
08394     };
08395 
08400     virtual ~SS7ISUPCall();
08401 
08406     inline State state() const
08407         { return m_state; }
08408 
08413     inline bool earlyState() const
08414         { return m_state <= Setup && !m_testCall; }
08415 
08420     inline const String& cicRange() const
08421         { return m_cicRange; }
08422 
08427     inline unsigned int id() const
08428         { return m_circuit ? m_circuit->code() : 0; }
08429 
08436     virtual SignallingEvent* getEvent(const Time& when);
08437 
08443     virtual bool sendEvent(SignallingEvent* event);
08444 
08452     inline void setTerminate(bool gracefully, const char* reason = 0,
08453         const char* diagnostic = 0, const char* location = 0)
08454     {
08455         Lock lock(this);
08456         m_terminate = true;
08457         m_gracefully = gracefully;
08458         setReason(reason,0,diagnostic,location);
08459     }
08460 
08466     virtual void* getObject(const String& name) const;
08467 
08468 protected:
08480     SS7ISUPCall(SS7ISUP* controller, SignallingCircuit* cic,
08481         const SS7PointCode& local, const SS7PointCode& remote, bool outgoing,
08482         int sls = -1, const char* range = 0, bool testCall = false);
08483 
08494     SignallingEvent* releaseComplete(bool final, SS7MsgISUP* msg = 0, const char* reason = 0,
08495         bool timeout = false);
08496 
08507     bool replaceCircuit(SignallingCircuit* circuit, SS7MsgISUP* msg = 0);
08508 
08514     void stopWaitSegment(bool discard);
08515 
08516 private:
08517     // Initialize/set IAM message parameters
08518     // @param msg Valid ISUP message
08519     // @param outgoing Message direction: true for outgoing
08520     // @param sigMsg Valid signalling message with parameters if outgoing
08521     bool copyParamIAM(SS7MsgISUP* msg, bool outgoing = false, SignallingMessage* sigMsg = 0);
08522     // If already releasing, set termination flag. Otherwise, send REL (Release) message
08523     // Set m_lastEvent if event is 0 (the method is called internally)
08524     // @param event Event with the parameters. 0 if release is started on some timeout
08525     // @param msg Received message to put in release event
08526     // @return Generated release event if any
08527     SignallingEvent* release(SignallingEvent* event = 0, SS7MsgISUP* msg = 0);
08528     // Set termination reason from message or parameter
08529     void setReason(const char* reason, SignallingMessage* msg, const char* diagnostic = 0,
08530         const char* location = 0);
08531     // Accept send/receive messages in current state based on call direction
08532     bool validMsgState(bool send, SS7MsgISUP::Type type, bool hasBkwCallInd = false);
08533     // Connect the reserved circuit. Return false if it fails. Return true if this call is a signalling only one
08534     bool connectCircuit(const char* special = 0);
08535     // Transmit the IAM message. Start IAM timer if not started
08536     bool transmitIAM();
08537     // Transmit SAM digits
08538     bool transmitSAM(const char* extra = 0);
08539     // (Re)transmit REL. Create and populate message if needed. Remember sls
08540     bool transmitREL(const NamedList* params = 0);
08541     // Check if the circuit needs continuity testing
08542     bool needsTesting(const SS7MsgISUP* msg);
08543     // Stop waiting for a SGM (Segmentation) message. Copy parameters to the pending segmented message if sgm is valid.
08544     // Change call state and set m_lastEvent
08545     // @param sgm Optional received SGM message with parameters to be added to the pending segmented message
08546     // @param timeout True if waiting timer timed out. Ignored if sgm is non null
08547     // @return m_lastEvent
08548     SignallingEvent* processSegmented(SS7MsgISUP* sgm = 0, bool timeout = false);
08549     // Transmit message. Set routing label's link if not already set
08550     inline bool transmitMessage(SS7MsgISUP* msg);
08551     // Get the ISUP call controller
08552     inline SS7ISUP* isup() const;
08553     // Set overlapped flag. Output a debug message
08554     void setOverlapped(bool on, bool numberComplete = true);
08555 
08556     State m_state;                       // Call state
08557     bool m_testCall;                     // Test only call
08558     SignallingCircuit* m_circuit;        // Circuit reserved for this call
08559     String m_cicRange;                   // The range used to re(alloc) a circuit
08560     SS7Label m_label;                    // The routing label for this call
08561     bool m_terminate;                    // Termination flag
08562     bool m_gracefully;                   // Terminate gracefully: send RLC
08563     bool m_circuitChanged;               // Circuit change flag
08564     bool m_circuitTesting;               // The circuit is tested for continuity
08565     bool m_inbandAvailable;              // Inband data is available
08566     String m_format;                     // Data format used by the circuit
08567     String m_reason;                     // Termination reason
08568     String m_diagnostic;                 // Termination diagnostic
08569     String m_location;                   // Termination location
08570     SS7MsgISUP* m_iamMsg;                // Message with the call parameters for outgoing calls
08571     SS7MsgISUP* m_sgmMsg;                // Pending received message with segmentation flag set
08572     SS7MsgISUP* m_relMsg;                // Release message preserved for retransmissions
08573     // Overlapped
08574     String m_samDigits;                  // SAM digits
08575     unsigned int m_sentSamDigits;        // The number of sent SAM digits
08576     // Timers
08577     SignallingTimer m_relTimer;          // Send release
08578     SignallingTimer m_iamTimer;          // Send initial address
08579     SignallingTimer m_sgmRecvTimer;      // Receive segmented message
08580     SignallingTimer m_contTimer;         // Continuity timer
08581     SignallingTimer m_anmTimer;          // T9 ACM -> ANM timer
08582 };
08583 
08588 class YSIG_API SS7ISUP : public SignallingCallControl, public SS7Layer4
08589 {
08590     YCLASS(SS7ISUP,SS7Layer4)
08591     friend class SS7ISUPCall;
08592 public:
08596     enum {
08597         SlsAuto    = -1,
08598         SlsLatest  = -2,
08599         SlsCircuit = -3,
08600         SlsDefault = -4
08601     };
08602 
08608     SS7ISUP(const NamedList& params, unsigned char sio = SS7MSU::ISUP|SS7MSU::National);
08609 
08613     virtual ~SS7ISUP();
08614 
08620     virtual bool initialize(const NamedList* config);
08621 
08626     virtual const char* statusName() const;
08627 
08632     virtual void attach(SS7Layer3* network);
08633 
08638     unsigned int cicLen() const
08639         { return m_cicLen; }
08640 
08645     const String& format() const
08646         { return m_format; }
08647 
08652     inline bool ignoreUnknownAddrSignals() const
08653         { return m_ignoreUnkDigits; }
08654 
08663     bool setPointCode(SS7PointCode* pc, bool def);
08664 
08671     unsigned int setPointCode(const NamedList& params);
08672 
08678     SS7PointCode* hasPointCode(const SS7PointCode& pc);
08679 
08685     inline bool handlesRemotePC(const SS7PointCode& pc) const
08686         { return !m_remotePoint || (pc == *m_remotePoint); }
08687 
08695     inline void setLabel(SS7Label& label, const SS7PointCode& opc, const SS7PointCode& dpc,
08696         unsigned char sls = 255)
08697         { label.assign(m_type,dpc,opc,sls); }
08698 
08704     inline void setDebug(bool printMsg, bool extendedDebug)
08705         { m_extendedDebug = ((m_printMsg = printMsg) && extendedDebug); }
08706 
08716     virtual SS7MSU* createMSU(SS7MsgISUP::Type type, unsigned char ssf,
08717         const SS7Label& label, unsigned int cic, const NamedList* params = 0) const;
08718 
08726     virtual SignallingCall* call(SignallingMessage* msg, String& reason);
08727 
08738     int transmitMessage(SS7MsgISUP* msg, const SS7Label& label, bool recvLbl, int sls = SlsDefault);
08739 
08745     virtual void cleanup(const char* reason = "net-out-of-order");
08746 
08752     virtual bool control(NamedList& params);
08753 
08763     bool decodeMessage(NamedList& msg, SS7MsgISUP::Type msgType, SS7PointCode::Type pcType,
08764         const unsigned char* paramPtr, unsigned int paramLen);
08765 
08776     bool encodeMessage(DataBlock& buf, SS7MsgISUP::Type msgType, SS7PointCode::Type pcType,
08777         const NamedList& params, unsigned int* cic = 0);
08778 
08788     bool processParamCompat(const NamedList& list, unsigned int cic, bool* callReleased = 0);
08789 
08790 protected:
08794     virtual void destroyed();
08795 
08800     virtual void timerTick(const Time& when);
08801 
08807     virtual void notify(SS7Layer3* link, int sls);
08808 
08818     SS7MSU* buildMSU(SS7MsgISUP::Type type, unsigned char sio,
08819         const SS7Label& label, unsigned int cic, const NamedList* params) const;
08820 
08829     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
08830 
08842     virtual bool processMSU(SS7MsgISUP::Type type, unsigned int cic,
08843         const unsigned char* paramPtr, unsigned int paramLen,
08844         const SS7Label& label, SS7Layer3* network, int sls);
08845 
08855     virtual void receivedUPU(SS7PointCode::Type type, const SS7PointCode node,
08856         SS7MSU::Services part, unsigned char cause, const SS7Label& label, int sls);
08857 
08864     virtual SignallingEvent* processCircuitEvent(SignallingCircuitEvent*& event,
08865         SignallingCall* call = 0);
08866 
08875     bool startCircuitReset(SignallingCircuit*& cic, const String& timer);
08876 
08880     unsigned int m_cicLen;
08881 
08882 private:
08883     // Process a received message that should be processed by a call
08884     // @param msg The received message
08885     // @param label The routing label of the received message
08886     // @param sls Signalling Link the message was received from
08887     void processCallMsg(SS7MsgISUP* msg, const SS7Label& label, int sls);
08888     // Process a received message that should be processed by this call controller
08889     // @param msg The received message
08890     // @param label The routing label of the received message
08891     // @param sls Signalling Link the message was received from
08892     void processControllerMsg(SS7MsgISUP* msg, const SS7Label& label, int sls);
08893     // Replace a call's circuit if checkCall is true
08894     // Clear lock flags of the circuit. Release currently reseting circuit if the code match
08895     // Return false if the given circuit doesn't exist
08896     bool resetCircuit(unsigned int cic, bool remote, bool checkCall);
08897     // Block/unblock a circuit side (local or remote)
08898     // Return false if the given circuit doesn't exist
08899     bool blockCircuit(unsigned int cic, bool block, bool remote, bool hwFail,
08900         bool changed, bool changedState, bool resetLocking = false);
08901     // Find a call by its circuit identification code
08902     // This method is not thread safe
08903     SS7ISUPCall* findCall(unsigned int cic);
08904     // Find a call by its circuit identification code
08905     // This method is thread safe
08906     inline void findCall(unsigned int cic, RefPointer<SS7ISUPCall>& call) {
08907             Lock mylock(this);
08908             call = findCall(cic);
08909         }
08910     // Send blocking/unblocking messages.
08911     // Restart the re-check timer if there is any (un)lockable, not sent cic
08912     // Return false if no request was sent
08913     bool sendLocalLock(const Time& when = Time());
08914     // Fill label from local/remote point codes
08915     // This method is thread safe
08916     // Return a true if local and remote point codes are valid
08917     bool setLabel(SS7Label& label, unsigned int cic);
08918     // Retrieve a pending message
08919     SignallingMessageTimer* findPendingMessage(SS7MsgISUP::Type type, unsigned int cic,
08920         bool remove = false);
08921     // Transmit a list of messages. Return true if at least 1 message was sent
08922     bool transmitMessages(ObjList& list);
08923     // Handle circuit(s) (un)block command
08924     bool handleCicBlockCommand(const NamedList& p, bool block);
08925     // Handle remote circuit(s) (un)block command
08926     bool handleCicBlockRemoteCommand(const NamedList& p, unsigned int* cics,
08927         unsigned int count, bool block);
08928     // Try to start single circuit (un)blocking. Set a pending operation on success 
08929     // @param force True to ignore resetting/(un)blocking flags of the circuit
08930     // Return built message to be sent on success
08931     SS7MsgISUP* buildCicBlock(SignallingCircuit* cic, bool block, bool force = false);
08932     // Replace circuit for outgoing calls in Setup state
08933     // Send REL/RSC before repeat attempt
08934     void replaceCircuit(unsigned int cic, const String& map, bool rel = true);
08935     // Handle circuit hw-fail block
08936     // Replace cics for outgoing calls. Terminate incoming
08937     void cicHwBlocked(unsigned int cic, const String& map);
08938 
08939     SS7PointCode::Type m_type;           // Point code type of this call controller
08940     ObjList m_pointCodes;                // Point codes serviced by this call controller
08941     SS7PointCode* m_defPoint;            // Default point code for outgoing calls
08942     SS7PointCode* m_remotePoint;         // Default remote point code for outgoing calls and maintenance
08943     unsigned char m_sls;                 // Last known valid SLS
08944     bool m_earlyAcm;                     // Accept progress/ringing in early ACM
08945     bool m_inn;                          // Routing to internal network number flag
08946     int m_defaultSls;                    // Default SLS to use in outbound calls
08947     unsigned int m_maxCalledDigits;      // Maximum digits allowed in Called Number in IAM
08948     String m_numPlan;                    // Numbering plan
08949     String m_numType;                    // Number type
08950     String m_numPresentation;            // Number presentation
08951     String m_numScreening;               // Number screening
08952     String m_callerCat;                  // Caller party category
08953     String m_format;                     // Default format
08954     String m_continuity;                 // Continuity test type
08955     bool m_confirmCCR;                   // Send LPA in response to CCR
08956     bool m_dropOnUnknown;                // Drop call in early state on unknown message
08957     bool m_ignoreGRSSingle;              // Ignore (drop) GRS with range 0 (1 circuit affected)
08958     bool m_ignoreCGBSingle;              // Ignore (drop) CGB with range 0 (1 circuit in map)
08959     bool m_ignoreCGUSingle;              // Ignore (drop) CGU with range 0 (1 circuit in map)
08960     bool m_duplicateCGB;                 // Send duplicate CGB messages (ANSI)
08961     bool m_ignoreUnkDigits;              // Check if the message parser should ignore unknown digits encoding
08962     bool m_l3LinkUp;                     // Flag indicating the availability of a Layer3 data link
08963     u_int64_t m_t1Interval;              // Q.764 T1 timer interval
08964     u_int64_t m_t5Interval;              // Q.764 T5 timer interval
08965     u_int64_t m_t9Interval;              // Q.764 T9 AMM/CON recv timer interval
08966     u_int64_t m_t12Interval;             // Q.764 T12 BLK timer interval
08967     u_int64_t m_t13Interval;             // Q.764 T13 BLK global timer interval
08968     u_int64_t m_t14Interval;             // Q.764 T14 UBL timer interval
08969     u_int64_t m_t15Interval;             // Q.764 T15 UBL global timer interval
08970     u_int64_t m_t16Interval;             // Q.764 T16 RSC timer interval
08971     u_int64_t m_t17Interval;             // Q.764 T17 timer interval
08972     u_int64_t m_t18Interval;             // Q.764 T18 CGB timer interval
08973     u_int64_t m_t19Interval;             // Q.764 T19 CGB global timer interval
08974     u_int64_t m_t20Interval;             // Q.764 T20 CGU timer interval
08975     u_int64_t m_t21Interval;             // Q.764 T21 CGU global timer interval
08976     SignallingMessageTimerList m_pending;// Pending messages (RSC ...)
08977     // Remote User Part test
08978     SignallingTimer m_uptTimer;          // Timer for UPT
08979     bool m_userPartAvail;                // Flag indicating the remote User Part availability
08980     SS7MsgISUP::Type m_uptMessage;       // Message used, may not be always UPT
08981     unsigned int m_uptCicCode;           // The circuit code sent with UPT
08982     int m_cicWarnLevel;                  // Wrong CIC warn level
08983     // Circuit reset
08984     SignallingTimer m_rscTimer;          // RSC message or idle timeout
08985     SignallingCircuit* m_rscCic;         // Circuit currently beeing reset
08986     u_int32_t m_rscInterval;             // Saved reset interval
08987     u_int32_t m_rscSpeedup;              // Circuits left for speedup
08988     // Blocking/unblocking circuits
08989     SignallingTimer m_lockTimer;         // Timer used to re-check local lock
08990     bool m_lockGroup;                    // Allow sending requests for a group
08991     // Debug flags
08992     bool m_printMsg;                     // Print messages to output
08993     bool m_extendedDebug;                // Extended debug flag
08994 };
08995 
09000 class YSIG_API SS7BICC : public SS7ISUP
09001 {
09002     YCLASS(SS7BICC,SS7ISUP)
09003 public:
09009     SS7BICC(const NamedList& params, unsigned char sio = SS7MSU::BICC|SS7MSU::National);
09010 
09015     virtual ~SS7BICC();
09016 
09017 protected:
09026     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
09027 };
09028 
09033 class YSIG_API SS7TUP : public SignallingCallControl, public SS7Layer4
09034 {
09035 public:
09041     SS7TUP(const NamedList& params, unsigned char sif = SS7MSU::TUP);
09042 
09047     virtual ~SS7TUP();
09048 };
09049 
09055 class YSIG_API SCCPManagement : public SignallingComponent , public Mutex
09056 {
09057     friend class SS7SCCP;
09058     friend class SccpLocalSubsystem; // Local Broadcast
09059     YCLASS(SCCPManagement,SignallingComponent)
09060 public:
09061     enum MsgType {
09062         SSA = 0x01,  // Subsystem-allowed
09063         SSP = 0x02,  // Subsystem-prohibited
09064         SST = 0x03,  // Subsystem-status-test
09065         SOR = 0x04,  // Subsystem-out-of-service-request
09066         SOG = 0x05,  // Subsystem-out-of-service-grant
09067         SSC = 0x06,  // SCCP/Subsystem-congested      (ITU  only)
09068         SBR = 0xfd,  // Subsystem-backup-routing      (ANSI only)
09069         SNR = 0xfe,  // Subsystem-normal-routing      (ANSI only)
09070         SRT = 0xff   // Subsystem-routing-status-test (ANSI only)
09071     };
09072 
09073     enum LocalBroadcast {
09074         UserOutOfService,
09075         UserInService,
09076         PCInaccessible,         // Signalling Point Inaccessible
09077         PCAccessible,           // Signalling Point Accessible
09078         SccpRemoteInaccessible,
09079         SccpRemoteAccessible,
09080         PCCongested,           // Signalling Point Congested
09081         SubsystemStatus        // Request send by sccp management to find if a ssn is available
09082     };
09083 
09084     enum SccpStates {
09085         Allowed = SS7Route::Allowed,
09086         Prohibited = SS7Route::Prohibited,
09087         Unknown = SS7Route::Unknown,
09088         WaitForGrant,
09089         IgnoreTests
09090     };
09091 
09095     SCCPManagement(const NamedList& params, SS7PointCode::Type type);
09096 
09100     virtual ~SCCPManagement();
09101 
09105     virtual bool initialize(const NamedList* config);
09106 
09112     virtual bool processMessage(SS7MsgSCCP* message);
09113 
09118     void attach(SS7SCCP* sccp);
09119 
09125     virtual void pointcodeStatus(SS7Layer3* link, bool operational);
09126 
09133     virtual void routeStatus(SS7PointCode::Type type, const SS7PointCode& node, SS7Route::State state);
09134 
09140     virtual void notify(SCCP::Type type, NamedList& params);
09141 
09146     virtual void routeFailure(SS7MsgSCCP* msg);
09147 
09153     virtual void subsystemFailure(SS7MsgSCCP* msg, const SS7Label& label);
09154 
09160     virtual void sccpUnavailable(const SS7PointCode& pointcode, unsigned char cause);
09161 
09167     void subsystemsStatus(String& dest,bool extended = true);
09168 
09174     void routeStatus(String& dest,bool extended = false);
09175 
09182     virtual void notifyConcerned(MsgType msg, unsigned char ssn, int smi);
09183 
09188     static const TokenDict* broadcastType();
09189 
09195     virtual void updateTables(SccpRemote* rsccp, SccpSubsystem* ssn = 0);
09196 
09203     virtual void printMessage(String& dest, MsgType type, const NamedList& params);
09204 
09210     static const char* stateName(SCCPManagement::SccpStates state)
09211         { return lookup(state,s_states); }
09212 protected:
09213 
09219     virtual void timerTick(const Time& when);
09220 
09221     inline SS7SCCP* sccp()
09222         { return m_sccp; }
09223 
09224     ObjList m_remoteSccp;
09225     ObjList m_statusTest;
09226     ObjList m_localSubsystems;
09227     ObjList m_concerned;
09228     SS7PointCode::Type m_pcType;
09229 
09234     inline u_int32_t getTestTimeout()
09235         { return m_testTimeout; }
09236 
09243     bool managementMessage(SCCP::Type type, NamedList& params);
09244 
09250     SccpLocalSubsystem* getLocalSubsystem(unsigned char ssn);
09251 
09257     SccpRemote* getRemoteSccp(int pointcode);
09258 
09265     virtual bool sendMessage(SCCPManagement::MsgType msgType, const NamedList& params) = 0;
09266 
09273     virtual void stopSst(SccpRemote* remoteSccp, SccpSubsystem* rSubsystem = 0, SccpSubsystem* less = 0);
09274 
09278     inline void stopSSTs()
09279         { Lock lock(this); m_statusTest.clear(); }
09280 
09286     virtual void startSst(SccpRemote* remoteSccp, SccpSubsystem* rSubsystem);
09287 
09291     void mtpEndRestart();
09292 
09303     void localBroadcast(SCCP::Type type, int pointcode, int sps, int rss = -1,
09304             int rl = -1, int ssn = -1, int ss = -1);
09305 
09312     bool sendSST(SccpRemote* remote, SccpSubsystem* sub);
09313 
09322     bool handleMessage(int msgType, unsigned char ssn, unsigned char smi, NamedList& params);
09323 
09329     virtual void manageSccpRemoteStatus(SccpRemote* rsccp, SS7Route::State newState)
09330         { }
09331 
09336     inline bool printMessagess()
09337         { return m_printMessages; }
09338 
09345     void handleCoordinateChanged(unsigned char ssn, int smi, const NamedList& params);
09346 
09353     void handleSog(unsigned char ssn, int pointcode);
09354 
09362     virtual void handleSubsystemStatus(SccpSubsystem* subsystem, bool allowed, SccpRemote* remote, int smi)
09363         { }
09364 
09369     inline u_int32_t getCoordTimeout()
09370         { return m_coordTimeout; }
09371 
09376     inline u_int32_t getIgnoreTestsInterval()
09377         { return m_ignoreStatusTestsInterval; }
09378 private:
09379     // Helper method to fill broadcast param list
09380     void putValue(NamedList& params,int val,const char* name, bool dict = false);
09381 
09382     SS7SCCP* m_sccp;
09383     NamedList m_unknownSubsystems;
09384     unsigned int m_subsystemFailure;    // Counter used in status to inform about the total number of packets received for a unknown ssn
09385     unsigned int m_routeFailure;
09386     u_int32_t m_testTimeout;
09387     u_int32_t m_coordTimeout;
09388     u_int32_t m_ignoreStatusTestsInterval;
09389     bool m_autoAppend;
09390     bool m_printMessages;
09391     static const TokenDict s_broadcastType[];
09392     static const TokenDict s_states[];
09393 };
09394 
09395 class YSIG_API SS7MsgSCCP : public SignallingMessage
09396 {
09397     YCLASS(SS7MsgSCCP,SignallingMessage)
09398 public:
09402     enum Type {
09403         Unknown = 0,
09404         CR     = 0x01, // Connection request
09405         CC     = 0x02, // Connection confirm
09406         CREF   = 0x03, // Connection refused
09407         RLSD   = 0x04, // Released
09408         RLC    = 0x05, // Release complete
09409         DT1    = 0x06, // Data form 1
09410         DT2    = 0x07, // Data form 2
09411         AK     = 0x08, // Data acknowledgement
09412         UDT    = 0x09, // Unitdata
09413         UDTS   = 0x0a, // Unitdata service
09414         ED     = 0x0b, // Expedited data
09415         EA     = 0x0c, // Expedited data acknowledgement
09416         RSR    = 0x0d, // Reset request
09417         RSC    = 0x0e, // Reset confirmation
09418         ERR    = 0x0f, // Protocol data unit error
09419         IT     = 0x10, // Inactivity test
09420         XUDT   = 0x11, // Extended unitdata
09421         XUDTS  = 0x12, // Extended unitdata service
09422         LUDT   = 0x13, // Long unitdata
09423         LUDTS  = 0x14, // Long unitdata service
09424     };
09425 
09426     enum Parameters {
09427         EndOfParameters                = 0,
09428         DestinationLocalReference      = 0x01,
09429         SourceLocalReference           = 0x02,
09430         CalledPartyAddress             = 0x03,
09431         CallingPartyAddress            = 0x04,
09432         ProtocolClass                  = 0x05,
09433         Segmenting                     = 0x06,
09434         ReceiveSequenceNumber          = 0x07,
09435         Sequencing                     = 0x08,
09436         Credit                         = 0x09,
09437         ReleaseCause                   = 0x0a,
09438         ReturnCause                    = 0x0b,
09439         ResetCause                     = 0x0c,
09440         ErrorCause                     = 0x0d,
09441         RefusalCause                   = 0x0e,
09442         Data                           = 0x0f,
09443         Segmentation                   = 0x10,
09444         HopCounter                     = 0x11,
09445         Importance                     = 0x12, // ITU only
09446         LongData                       = 0x13,
09447         MessageTypeInterworking        = 0xf8, // ANSI only
09448         INS                            = 0xf9, // ANSI only
09449         ISNI                           = 0xfa, // ANSI only
09450     };
09451 
09456     inline SS7MsgSCCP(Type type)
09457         : SignallingMessage(lookup(type,"Unknown")), m_type(type), m_data(0)
09458         { }
09459 
09467     virtual ~SS7MsgSCCP();
09468 
09473     inline Type type() const
09474         { return m_type; }
09475 
09480     inline void updateType(Type type)
09481         { m_type = type; params().assign(lookup(type,"Unknown")); }
09482 
09487     inline bool isLongDataMessage() const
09488         { return m_type == LUDT || m_type == LUDTS; }
09489 
09496     inline bool canBeUDT() const
09497         { return !(params().getParam(YSTRING("Importance")) ||
09498                     params().getParam(YSTRING("HopCounter"))); }
09499 
09508     void toString(String& dest, const SS7Label& label, bool params,
09509         const void* raw = 0, unsigned int rawLen = 0) const;
09510 
09515     static const TokenDict* names();
09516 
09523     static inline const char* lookup(Type type, const char* defvalue = 0)
09524         { return TelEngine::lookup(type,names(),defvalue); }
09525 
09532     static inline Type lookup(const char* name, Type defvalue = Unknown)
09533         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
09534 
09539     inline void setData(DataBlock* data)
09540         { m_data = data; }
09541 
09545     inline void removeData()
09546         { m_data = 0; }
09547         
09552     inline DataBlock* getData()
09553         { return m_data; }
09554 
09559     inline DataBlock* extractData()
09560         { 
09561             DataBlock* data = m_data;
09562             m_data = 0;
09563             return data;
09564         }
09565 
09566 private:
09567     Type m_type;                         // Message type
09568     DataBlock* m_data;                   // Message data NOTE: The message never owns the data
09569 };
09570 
09571 class YSIG_API SS7MsgSccpReassemble : public SS7MsgSCCP
09572 {
09573     YCLASS(SS7MsgSccpReassemble,SignallingMessage)
09574 public:
09575     enum Return {
09576         Rejected,
09577         Accepted,
09578         Error,
09579         Finished,
09580     };
09587     SS7MsgSccpReassemble(SS7MsgSCCP* msg, const SS7Label& label, unsigned int timeToLive);
09588 
09592     virtual ~SS7MsgSccpReassemble();
09593 
09600     bool canProcess(const SS7MsgSCCP* msg, const SS7Label& label);
09601 
09608     Return appendSegment(SS7MsgSCCP* msg, const SS7Label& label);
09609 
09614     inline bool timeout()
09615         { return m_timeout > 0 ? Time::msecNow() > m_timeout : false; }
09616 
09621     inline bool haveAllSegments()
09622         { return m_remainingSegments == 0; }
09623 private:
09624     SS7Label m_label;
09625     NamedList m_callingPartyAddress;
09626     u_int32_t m_segmentationLocalReference;
09627     u_int64_t m_timeout;
09628     unsigned char m_remainingSegments;
09629     unsigned int m_firstSgmDataLen;
09630 };
09631 
09632 class YSIG_API SccpSubsystem : public RefObject
09633 {
09634     YCLASS(SccpSubsystem,RefObject);
09635 public:
09641     inline SccpSubsystem(int ssn, SCCPManagement::SccpStates state = SCCPManagement::Allowed, unsigned char smi = 0)
09642         : m_ssn(ssn), m_smi(smi), m_state(state)
09643         { }
09644 
09645     virtual ~SccpSubsystem()
09646         { }
09647 
09652     inline unsigned char getSSN()
09653         { return m_ssn; }
09654 
09659     inline SCCPManagement::SccpStates getState()
09660         { return m_state; }
09661 
09666     inline void setState(SCCPManagement::SccpStates state)
09667         { m_state = state; }
09668 
09673     inline unsigned char getSmi()
09674         { return m_smi; }
09675 
09680     void dump(String& dest)
09681         {
09682             dest << "Subsystem: " << m_ssn << " , smi: " << m_smi;
09683             dest << ", state: " << SCCPManagement::stateName(m_state) << " ";
09684         }
09685 private:
09686     unsigned char m_ssn;
09687     unsigned char m_smi;
09688     SCCPManagement::SccpStates m_state;
09689 };
09690 
09691 class YSIG_API RemoteBackupSubsystem : public GenObject
09692 {
09693     YCLASS(RemoteBackupSubsystem,GenObject);
09694 public:
09695 
09702     RemoteBackupSubsystem(unsigned char ssn, int pointcode, bool wfg = false)
09703         : m_ssn(ssn), m_pointcode(pointcode), m_waitForGrant(wfg)
09704         { }
09705 
09706     virtual ~RemoteBackupSubsystem()
09707         { }
09708 
09715     inline bool equals(unsigned char ssn, int pointcode)
09716         { return m_pointcode == pointcode && m_ssn == ssn; }
09717 
09721     inline void permisionGranted()
09722         { m_waitForGrant = false; }
09723 
09728     inline bool waitingForGrant()
09729         { return m_waitForGrant; }
09730 
09731 private:
09732     unsigned char m_ssn;
09733     int m_pointcode;
09734     bool m_waitForGrant;
09735 };
09736 
09737 class YSIG_API SccpLocalSubsystem : public RefObject, public Mutex
09738 {
09739     YCLASS(SccpLocalSubsystem,RefObject);
09740 public:
09748     SccpLocalSubsystem(unsigned char ssn, u_int64_t coordInterval, u_int64_t istInterval, unsigned char smi = 0);
09749 
09753     virtual ~SccpLocalSubsystem();
09754 
09759     inline unsigned char getSSN()
09760         { return m_ssn; }
09761 
09766     inline void setState(SCCPManagement::SccpStates newState)
09767         { m_state = newState; }
09768 
09773     inline SCCPManagement::SccpStates getState()
09774         { return m_state; }
09775 
09779     inline void startCoord()
09780         { m_coordTimer.start(); }
09781 
09785     inline bool ignoreTests()
09786         { return m_ignoreTestsTimer.started(); }
09787 
09792     void setIgnoreTests(bool ignore);
09793 
09798     bool timeout();
09799 
09804     void manageTimeout(SCCPManagement* mgm);
09805 
09809     inline void stopCoordTimer()
09810         { m_coordTimer.stop(); }
09811         
09816     inline unsigned char getSmi()
09817         { return m_smi; }
09818 
09823     void dump(String& dest);
09824 
09831     bool receivedSOG(unsigned char ssn, int pointcode);
09832 
09836     inline void resetTimers()
09837         { m_coordTimer.stop(); m_ignoreTestsTimer.stop(); }
09841     inline void clearBackups()
09842         { m_backups.clear(); }
09843 
09848     inline void appendBackup(RemoteBackupSubsystem* backup)
09849         { m_backups.append(backup); }
09850 private:
09851     unsigned char m_ssn;
09852     unsigned char m_smi;
09853     SCCPManagement::SccpStates m_state;
09854     SignallingTimer m_coordTimer;
09855     SignallingTimer m_ignoreTestsTimer;
09856     ObjList m_backups;
09857     bool m_receivedAll;
09858 };
09859 
09863 class YSIG_API SccpRemote : public RefObject, public Mutex
09864 {
09865     YCLASS(SccpRemote,RefObject);
09866 public:
09871     SccpRemote(SS7PointCode::Type pcType);
09872 
09879     SccpRemote(unsigned int pointcode, SS7PointCode::Type pcType);
09880 
09884     virtual ~SccpRemote();
09885 
09892     bool initialize(const String& params);
09893 
09898     inline SCCPManagement::SccpStates getState()
09899         { return m_state; }
09900 
09906     SccpSubsystem* getSubsystem(int ssn);
09907 
09912     void setState(SCCPManagement::SccpStates state);
09913 
09918     inline const SS7PointCode& getPointCode()
09919         { return m_pointcode; }
09920 
09925     inline int getPackedPointcode()
09926         { return m_pointcode.pack(m_pointcodeType); }
09927 
09932     inline const char* getPointCodeType()
09933         { return SS7PointCode::lookup(m_pointcodeType); }
09934 
09940     void dump(String& dest, bool extended = false);
09941 
09948     bool changeSubsystemState(int ssn,SCCPManagement::SccpStates newState);
09949 
09954     inline ObjList& getSubsystems()
09955         { return m_subsystems; }
09956 
09961     inline void setCongestion(unsigned int cl)
09962         { m_congestionLevel = cl; }
09963 
09967     inline void resetCongestion()
09968         { m_congestionLevel = 0; }
09969 
09974     inline unsigned int getCongestion()
09975         { return m_congestionLevel; }
09976 private:
09977     SS7PointCode m_pointcode;
09978     SS7PointCode::Type m_pointcodeType;
09979     ObjList m_subsystems;
09980     SCCPManagement::SccpStates m_state;
09981     unsigned int m_congestionLevel;
09982 };
09983 
09984 class YSIG_API SS7AnsiSccpManagement : public SCCPManagement
09985 {
09986     YCLASS(SS7AnsiSccpManagement,SCCPManagement)
09987 public:
09988 
09992     inline SS7AnsiSccpManagement(const NamedList& params)
09993         : SCCPManagement(params,SS7PointCode::ANSI)
09994         { }
09995 
09996     virtual ~SS7AnsiSccpManagement();
09997 
10003     virtual bool processMessage(SS7MsgSCCP* message);
10004 
10011     virtual bool sendMessage(SCCPManagement::MsgType msgType, const NamedList& params);
10012 
10018     virtual void manageSccpRemoteStatus(SccpRemote* rsccp, SS7Route::State newState);
10019 
10027     virtual void handleSubsystemStatus(SccpSubsystem* subsystem, bool allowed, SccpRemote* remote, int smi);
10028 
10035     bool handleMessage(int msgType, NamedList& params);
10036 };
10037 
10038 class YSIG_API SS7ItuSccpManagement : public SCCPManagement
10039 {
10040     YCLASS(SS7ItuSccpManagement,SCCPManagement)
10041 public:
10042 
10046     SS7ItuSccpManagement(const NamedList& params);
10047 
10051     virtual ~SS7ItuSccpManagement()
10052         { }
10053 
10059     virtual bool processMessage(SS7MsgSCCP* message);
10060 
10067     virtual bool sendMessage(MsgType msgType, const NamedList& params);
10068 
10074     virtual void manageSccpRemoteStatus(SccpRemote* rsccp, SS7Route::State newState);
10075 
10082     bool handleMessage(int msgType, NamedList& params);
10083 
10091     virtual void handleSubsystemStatus(SccpSubsystem* subsystem, bool allowed, SccpRemote* remote, int smi);
10092 
10093 };
10094 
10098 class SS7SCCPDataSegment : public GenObject
10099 {
10100     YCLASS(SS7SCCPDataSegment,GenObject)
10101 public:
10107     inline SS7SCCPDataSegment(unsigned int index, unsigned int length)
10108         : m_length(length), m_index(index)
10109         {}
10110 
10114     virtual ~SS7SCCPDataSegment()
10115         {}
10116 
10122     inline void fillSegment(DataBlock& temp, const DataBlock& orig)
10123         { temp.assign(orig.data(m_index,m_length),m_length,false); }
10124 
10125 private:
10126     unsigned int m_length;
10127     unsigned int m_index;
10128 };
10129 
10134 class YSIG_API SS7SCCP : public SS7Layer4, public SCCP, public Mutex
10135 {
10136     YCLASS(SS7SCCP,SCCP)
10137     friend class SCCPManagement;
10138 public:
10139     enum ReturnCauses {
10140         NoTranslationAddressNature         = 0x00,
10141         NoTranslationSpecificAddress       = 0x01,
10142         SubsystemCongestion                = 0x02,
10143         SubsystemFailure                   = 0x03,
10144         UnequippedUser                     = 0x04,
10145         MtpFailure                         = 0x05,
10146         NetworkCongestion                  = 0x06,
10147         Unqualified                        = 0x07,
10148         ErrorInMessageTransport            = 0x08,
10149         ErrorInLocalProcessing             = 0x09,
10150         DestinationCanNotPerformReassembly = 0x0a,
10151         SccpFailure                        = 0x0b,
10152         HopCounterViolation                = 0x0c,
10153         SegmentationNotSupported           = 0x0d,
10154         SegmentationFailure                = 0x0e,
10155         // ANSI only
10156         MessageChangeFailure               = 0xf7,
10157         InvalidINSRoutingRequest           = 0xf8,
10158         InvalidISNIRoutingRequest          = 0xf9,
10159         UnauthorizedMessage                = 0xfa,
10160         MessageIncompatibility             = 0xfb,
10161         NotSupportedISNIRouting            = 0xfc,
10162         RedundantISNIConstrainedRouting    = 0xfd,
10163         ISNIIdentificationFailed           = 0xfe,
10164     };
10165 
10166     enum Control {
10167         Status                    = 0x01,
10168         FullStatus                = 0x02,
10169         EnableExtendedMonitoring  = 0x03,
10170         DisableExtendedMonitoring = 0x04,
10171         EnablePrintMsg            = 0x05,
10172         DisablePrintMsg           = 0x06,
10173     };
10177      SS7SCCP(const NamedList& config);
10178 
10182      ~SS7SCCP();
10183 
10189     virtual bool initialize(const NamedList* config);
10190 
10195     virtual void attach(SS7Layer3* network);
10196 
10204     int transmitMessage(SS7MsgSCCP* msg, bool local = false);
10205 
10212      virtual bool managementStatus(Type type, NamedList& params);
10213 
10220     virtual int sendMessage(DataBlock& data, const NamedList& params);
10221 
10230     virtual HandledMSU receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
10231 
10241     virtual void receivedUPU(SS7PointCode::Type type, const SS7PointCode node,
10242         SS7MSU::Services part, unsigned char cause, const SS7Label& label, int sls);
10243 
10244     virtual bool control(NamedList& params);
10245 
10253     int segmentMessage(SS7MsgSCCP* origMsg, const SS7Label& label, bool local);
10254 
10258      inline const bool ITU() const
10259         { return m_type == SS7PointCode::ITU; }
10260 
10265     inline bool ignoreUnknownAddrSignals() const
10266         { return m_ignoreUnkDigits; }
10267 
10273     virtual void notify(SS7Layer3* link, int sls);
10274 
10281     virtual void routeStatusChanged(SS7PointCode::Type type, const SS7PointCode& node, SS7Route::State state);
10286     inline unsigned int messagesSend()
10287         { return m_totalSent; }
10288 
10293     inline unsigned int messagesReceived()
10294         { return m_totalReceived; }
10295 
10300     inline unsigned int errors()
10301         { return m_errors; }
10302 
10307     inline unsigned int translations()
10308         { return m_totalGTTranslations; }
10309         
10314     inline const SS7PointCode* getLocalPointCode() const
10315         { return m_localPointCode; }
10316 
10321      inline SS7PointCode::Type getLocalPointCodeType()
10322         { return m_type; }
10323 
10328     inline int getPackedPointCode()
10329         { return m_localPointCode ? m_localPointCode->pack(m_type) : 0; }
10330 
10335     inline bool isLayer3Up()
10336         { return m_layer3Up; }
10337 protected:
10338 
10343     virtual void  destroyed();
10344 
10349     inline bool extendedMonitoring()
10350         { return m_extendedMonitoring; }
10351 
10356     virtual void timerTick(const Time& when);
10357 
10365     SS7MsgSccpReassemble::Return reassembleSegment(SS7MsgSCCP* segment, const SS7Label& label, SS7MsgSCCP*& msg);
10366 
10371     virtual bool isEndpoint()
10372         { return m_endpoint; }
10373 private:
10374     // Helper method to calculate sccp address length
10375     unsigned int getAddressLength(const NamedList& params, const String& prefix);
10376     // Helper method used to ajust HopCounter and Importance parameters
10377     void ajustMessageParams(NamedList& params, SS7MsgSCCP::Type type);
10378     // Obtain maximum data length for a UDT, XUDT and LUDT message
10379     void getMaxDataLen(const SS7MsgSCCP* msg, const SS7Label& label,
10380             unsigned int& udtLength, unsigned int& xudtLength, unsigned int& ludtLength);
10381     // Helper method to obtain data segments
10382     // NOTE The list must be destroyed
10383     ObjList* getDataSegments(unsigned int dataLength, unsigned int maxSegmentSize);
10384     // Helper method to print a SCCP message
10385     void printMessage(const SS7MSU* msu, const SS7MsgSCCP* msg, const SS7Label& label);
10386     // Helper method used to extract the pointcode from Calling/Called party address.
10387     // Also will call GT translate if there is no pointcode in called party address
10388     bool fillPointCode(SS7PointCode& pointcode, SS7MsgSCCP* msg, const String& prefix, const char* pCode, bool translate);
10389     // Helper method used to verify if the message is a connectionless data message
10390     inline bool isSCLCMessage(int msgType)
10391         { return msgType == SS7MsgSCCP::UDT || msgType == SS7MsgSCCP::XUDT || msgType == SS7MsgSCCP::LUDT; }
10392     // Helper method used to verify if the message is a connectionless service message
10393     inline bool isSCLCSMessage(int msgType)
10394         { return msgType == SS7MsgSCCP::UDTS || msgType == SS7MsgSCCP::XUDTS || msgType == SS7MsgSCCP::LUDTS; }
10395     bool isSCOCMsg(int msgType);
10396 
10397     bool fillLabelAndReason(String& dest, const SS7Label& label,const SS7MsgSCCP* msg);
10398     inline bool unknownPointCodeType()
10399         { return m_type != SS7PointCode::ITU && m_type != SS7PointCode::ANSI && m_type != SS7PointCode::ANSI8; }
10400     // Helper method used to verify if th importance level is in standard range
10401     int checkImportanceLevel(int msgType,int initialImportance);
10402     // Helper method used to verify if the optional parameters present in message are declared in standards
10403     void checkSCLCOptParams(SS7MsgSCCP* msg);
10404     // Helper method used to monitor service messages
10405     void archiveMessage(SS7MsgSCCP* msg);
10406     // Helper method used to dump service messages and error codes status
10407     void dumpArchive(String& msg, bool extended);
10408 
10409     bool processMSU(SS7MsgSCCP::Type type, const unsigned char* paramPtr, 
10410             unsigned int paramLen, const SS7Label& label, SS7Layer3* network, int sls);
10411 
10412     bool decodeMessage(SS7MsgSCCP* msg, SS7PointCode::Type pcType,
10413             const unsigned char* paramPtr, unsigned int paramLen);
10414 
10415     void returnMessage(SS7MsgSCCP* message, int error);
10416 
10417     static void switchAddresses(const NamedList& source, NamedList& dest);
10418     // Helper method to dump sccp status
10419     void printStatus(bool extended);
10420     void setNetworkUp(bool operational);
10421 
10422     SS7MSU* buildMSU(SS7MsgSCCP* msg, const SS7Label& label, bool checkLength = true) const;
10423     bool routeSCLCMessage(SS7MsgSCCP*& msg, const SS7Label& label);
10424     // Member data
10425     SS7PointCode::Type m_type;           // Point code type of this SCCP
10426     SS7PointCode* m_localPointCode;      // Local point code
10427     SCCPManagement* m_management;        // SCCP management
10428     ObjList m_reassembleList;            // List of sccp messages that are waiting to be reassembled
10429     u_int8_t m_hopCounter;               // Hop counter value
10430     NamedList m_msgReturnStatus;         // List with message return statistics
10431     u_int32_t m_segTimeout;              // Time in milliseconds for segmentation timeout
10432     bool m_ignoreUnkDigits;              // Check if GT digit parser of should ignore unknown digits encoding
10433     bool m_layer3Up;                     // Flag used to verify if the network is operational
10434     unsigned int m_maxUdtLength;         // The maximum length of data packet transported in a UDT message
10435     u_int32_t m_totalSent;               // Counter of the total number of SCCP messages sent
10436     u_int32_t m_totalReceived;           // The number of incoming sccp messages
10437     u_int32_t m_errors;                  // Counter of the number of messages that failed to be delivered
10438     u_int32_t m_totalGTTranslations;     // The number of GT translations made
10439     u_int32_t m_gttFailed;               // Number of global title that failed to be translated
10440     bool m_extendedMonitoring;           // Flag used to check if the monitoring is normal or extended
10441     const char* m_mgmName;               // The name of the sccp management section from ysigchan.conf
10442     // Debug flags
10443     bool m_printMsg;                     // Print messages to output
10444     bool m_extendedDebug;                // Extended debug flag
10445     bool m_endpoint;                     // Flag used to force message processing if the message have a ssn
10446 };
10447 
10454 class YSIG_API SS7SUA : public SIGAdaptUser, public SCCP
10455 {
10456 };
10457 
10462 class YSIG_API SS7TCAPMessage : public GenObject
10463 {
10464 public:
10471     inline SS7TCAPMessage(NamedList& params, DataBlock& data, bool notice = false)
10472         : m_msgParams(params), m_msgData(data), m_notice(notice)
10473         {}
10474 
10479     inline NamedList& msgParams()
10480         { return m_msgParams; }
10481 
10486     inline DataBlock& msgData()
10487         { return m_msgData; }
10488 
10493     inline bool& isNotice()
10494         { return m_notice; }
10495 
10496 private:
10497     NamedList m_msgParams;
10498     DataBlock m_msgData;
10499     bool m_notice;
10500 };
10501 
10506 class YSIG_API SS7TCAP : public SCCPUser
10507 {
10508     YCLASS(SS7TCAP,SCCPUser)
10509 public:
10513     enum TCAPType {
10514         UnknownTCAP,
10515         ITUTCAP,
10516         ANSITCAP,
10517     };
10518 
10522     enum TCAPUserCompActions {
10523         TC_Invoke         = 1,        // ITU-T Invoke primitive, ANSI InvokeLast - Request/Indication
10524         TC_ResultLast     = 2,        // ITU-T & ANSI ResultLast primitive - Request/Indication
10525         TC_U_Error        = 3,        // ITU-T & ANSI ReturnError primitive - Request/Indication
10526         TC_U_Reject       = 4,        // ITU-T & ANSI Reject primitive - Request/Indication, TC-user rejected the component
10527         TC_R_Reject       = 5,        // ITU-T & ANSI Reject primitive - Indication, Remote TC-user rejected the component
10528         TC_L_Reject       = 6,        // ITU-T & ANSI Reject primitive - Indication, local Component Sublayer rejected the component
10529         TC_InvokeNotLast  = 7,        // ANSI InvokeNotLast primitive - Request/Indication
10530         TC_ResultNotLast  = 8,        // ITU-T & ANSI ResultNotLast primitive - Request/Indication
10531         TC_L_Cancel       = 9,        // Local Cancel primitive - Indication, inform TC-user that an operation has timed out
10532         TC_U_Cancel       = 10,       // User Cancel primitive - Request, TC-user request cancellation of an operation
10533         TC_TimerReset     = 11,       // Timer Reset - Indication, allow TC-user to refresh an operation timer
10534     };
10535 
10539     enum TCAPUserTransActions {
10540         TC_Unknown         = 0,
10541         TC_Unidirectional  = 1,          // ITU-T & ANSI - Request/Indication, request Unidirectional message
10542         TC_Begin,                   // ITU-T - Request/Indication, begin a dialogue
10543         TC_QueryWithPerm,           // ANSI - Request/Indication, begin a dialogue with permission to end it
10544         TC_QueryWithoutPerm,        // ANSI - Request/Indication, begin a dialogue without permission to end it
10545         TC_Continue,                // ITU-T - Request/Indication, continue a dialogue
10546         TC_ConversationWithPerm,    // ANSI - Request/Indication, continue a dialogue with permission
10547         TC_ConversationWithoutPerm, // ANSI - Request/Indication, continue a dialogue without permission
10548         TC_End,                     // ITU-T -Request/Indication, end a dialogue
10549         TC_Response,                // ANSI - Request/Indication, end a dialogue
10550         TC_U_Abort,                 // ITU-T & ANSI - Request/Indication, abort a dialogue per user's request
10551         TC_P_Abort,                 // ITU-T & ANSI - Indication, notify the abort of a dialogue because of a protocol error
10552         TC_Notice,                  // ITU-T & ANSI - Indication, notify the TC-user that the network was unable to provide the requested service
10553     };
10554 
10558     enum TCAPComponentOperationClass {
10559         SuccessOrFailureReport    = 1,
10560         FailureOnlyReport         = 2,
10561         SuccessOnlyReport         = 3,
10562         NoReport                  = 4,
10563     };
10564 
10568     enum TCAPCounter {
10569         IncomingMsgs,
10570         OutgoingMsgs,
10571         DiscardedMsgs,
10572         NormalMsgs,
10573         AbnormalMsgs,
10574     };
10575 
10580     SS7TCAP(const NamedList& params);
10581 
10585     virtual ~SS7TCAP();
10586 
10592     virtual bool initialize(const NamedList* config);
10593 
10599     virtual bool sendData(DataBlock& data, NamedList& params);
10600 
10607     virtual HandledMSU receivedData(DataBlock& data, NamedList& params);
10608 
10616     virtual HandledMSU notifyData(DataBlock& data, NamedList& params);
10617 
10623     bool managementNotify(SCCP::Type type, NamedList& params);
10624 
10629     void attach(TCAPUser* user);
10630 
10635     void detach(TCAPUser* user);
10636 
10642     virtual SS7TCAPError userRequest(NamedList& requestParams);
10643 
10649     virtual HandledMSU processSCCPData(SS7TCAPMessage* sccpData);
10650 
10654     inline TCAPType tcapType()
10655         { return m_tcapType; }
10656 
10661     inline void setTCAPType(TCAPType type)
10662         { m_tcapType = type; }
10663 
10668     virtual void enqueue(SS7TCAPMessage* msg);
10669 
10674     virtual SS7TCAPMessage* dequeue();
10675 
10680     virtual const String allocTransactionID();
10681 
10686     void allocTransactionID(String& str);
10687 
10691     static const TokenDict s_tcapVersion[];
10692 
10696     static const TokenDict s_compPrimitives[];
10697 
10701     static const TokenDict s_transPrimitives[];
10702 
10706     static const TokenDict s_compOperClasses[];
10707 
10716     virtual SS7TCAPTransaction* buildTransaction(SS7TCAP::TCAPUserTransActions type, const String& transactID, NamedList& params,
10717         bool initLocal = true) = 0;
10718 
10724     SS7TCAPTransaction* getTransaction(const String& tid);
10725 
10730     void removeTransaction(SS7TCAPTransaction* tr);
10731 
10736     virtual void timerTick(const Time& when);
10737 
10743     virtual bool sendToUser(NamedList& params);
10744 
10750     virtual void buildSCCPData(NamedList& params, SS7TCAPTransaction* tr);
10751 
10756     virtual void status(NamedList& status);
10757 
10762     virtual void userStatus(NamedList& status);
10763 
10772     virtual HandledMSU handleError(SS7TCAPError& error, NamedList& params, DataBlock& data, SS7TCAPTransaction* tr = 0);
10773 
10778     inline void incCounter(TCAPCounter counterType)
10779     {
10780         switch (counterType) {
10781             case IncomingMsgs:
10782                 m_recvMsgs++;
10783                 break;
10784             case OutgoingMsgs:
10785                 m_sentMsgs++;
10786                 break;
10787             case DiscardedMsgs:
10788                 m_discardMsgs++;
10789                 break;
10790             case NormalMsgs:
10791                 m_normalMsgs++;
10792                 break;
10793             case AbnormalMsgs:
10794                 m_abnormalMsgs++;
10795                 break;
10796             default:
10797                 break;
10798         }
10799     }
10800 
10806     inline unsigned int count(TCAPCounter counterType)
10807     {
10808         switch (counterType) {
10809             case IncomingMsgs:
10810                 return m_recvMsgs;
10811             case OutgoingMsgs:
10812                 return m_sentMsgs;
10813             case DiscardedMsgs:
10814                 return m_discardMsgs;
10815             case NormalMsgs:
10816                 return m_normalMsgs;
10817             case AbnormalMsgs:
10818                 return m_abnormalMsgs;
10819             default:
10820                 break;
10821         }
10822         return 0;
10823     }
10824 
10830     static inline const char* lookupTransaction(int tr)
10831         { return lookup(tr,s_transPrimitives,"Unknown"); }
10832 
10838     static inline int lookupTransaction(const char* tr)
10839         { return lookup(tr,s_transPrimitives,TC_Unknown); }
10840 
10846     static inline const char* lookupComponent(int comp)
10847         { return lookup(comp,s_compPrimitives,"Unknown"); }
10848 
10854     static inline int lookupComponent(const char* comp)
10855         { return lookup(comp,s_compPrimitives,TC_Unknown); }
10856 
10857 protected:
10858     virtual SS7TCAPError decodeTransactionPart(NamedList& params, DataBlock& data) = 0;
10859     virtual void encodeTransactionPart(NamedList& params, DataBlock& data) = 0;
10860     // list of TCAP users attached to this TCAP instance
10861     ObjList m_users;
10862     Mutex m_usersMtx;
10863 
10864     // list of messages received from sublayer, waiting to be processed
10865     ObjList m_inQueue;
10866     Mutex m_inQueueMtx;
10867 
10868     unsigned int m_SSN;
10869     unsigned int m_defaultRemoteSSN;
10870     unsigned int m_defaultHopCounter;
10871     SS7PointCode m_defaultRemotePC;
10872     SS7PointCode::Type m_remoteTypePC;
10873     u_int64_t m_trTimeout;
10874 
10875     // list of current TCAP transactions
10876     Mutex m_transactionsMtx;
10877     ObjList m_transactions;
10878     // type of TCAP
10879     TCAPType m_tcapType;
10880 
10881     // counter for allocating transaction IDs
10882     u_int32_t m_idsPool;
10883 
10884     // counters
10885     unsigned int m_recvMsgs;
10886     unsigned int m_sentMsgs;
10887     unsigned int m_discardMsgs;
10888     unsigned int m_normalMsgs;
10889     unsigned int m_abnormalMsgs;
10890 };
10891 
10892 class YSIG_API SS7TCAPError
10893 {
10894 public:
10895     enum ErrorType {
10896         // P-AbortCause TransactionProblems
10897         Transact_UnrecognizedPackageType,     // named after the ANSI specification, equivalent to ITU-T UnrecongnizedMessageType P-AbortCause
10898         Transact_IncorrectTransactionPortion, // <==> ITU-T incorrectTrasactionPortion P-AbortCause
10899         Transact_BadlyStructuredTransaction,  // <==> ITU-T badlyFormattedTransactionPortion P-AbortCause
10900         Transact_UnassignedTransactionID,
10901         Transact_PermissionToReleaseProblem,  // HANDLING NOT DEFINED
10902         Transact_ResourceUnavailable,         // <==> ITU-T resourceLimitation P-AbortCause
10903 
10904         // P-AbortCause DialogProblem
10905         Dialog_UnrecognizedDialoguePortionID, // ANSI only
10906         Dialog_BadlyStructuredDialoguePortion,// ANSI only
10907         Dialog_MissingDialoguePortion,        // ANSI only
10908         Dialog_InconsistentDialoguePortion,   // ANSI only
10909         Dialog_Abnormal,                      // ITU only, indication only
10910 
10911         // GeneralProblem
10912         General_UnrecognizedComponentType,   // named after the ANSI specification, equivalent to ITU-T UnrecognizedComponent General Problem
10913         General_IncorrectComponentPortion,   // ANSI specification, equivalent to ITU-T MistypedComponent General Problem
10914         General_BadlyStructuredCompPortion,  // ANSI specification, equivalent to ITU-T BadlyStructuredComponent General Problem
10915         General_IncorrectComponentCoding,    // ANSI specification, no ITU-T equivalent
10916 
10917         // InvokeProblem
10918         Invoke_DuplicateInvokeID,           // ANSI & ITU-T specification
10919         Invoke_UnrecognizedOperationCode,   // ANSI specification, equivalent to ITU-T UnrecognizedOperation Invoke Problem
10920         Invoke_IncorrectParameter,          // ANSI specification, equivalent to ITU-T MistypedParameter Invoke Problem
10921         Invoke_UnrecognizedCorrelationID,   // ANSI specification, equivalent to ITU-T UnrecognizedLinkedID Invoke Problem
10922         Invoke_ResourceLimitation,          // ITU-T only
10923         Invoke_InitiatingRelease,           // ITU-T only
10924         Invoke_LinkedResponseUnexpected,    // ITU-T only
10925         Invoke_UnexpectedLinkedOperation,   // ITU-T only
10926 
10927         // ReturnResult
10928         Result_UnrecognizedInvokeID,        // ITU-T only
10929         Result_UnrecognisedCorrelationID,   // ANSI only
10930         Result_UnexpectedReturnResult,      // ANSI specification, equivalent to ITU-T ReturnResultUnexpected Result Problem
10931         Result_IncorrectParameter,          // ANSI specification, equivalent to ITU-T MistypedParameter Result Problem
10932 
10933         // ReturnError
10934         Error_UnrecognizedInvokeID,        // ITU-T only
10935         Error_UnrecognisedCorrelationID,   // ANSI only
10936         Error_UnexpectedReturnError,       // ANSI only
10937         Error_UnrecognisedError,           // ANSI & ITU-T
10938         Error_UnexpectedError,             // ANSI & ITU-T
10939         Error_IncorrectParameter,          // ANSI specification, equivalent to ITU-T MistypedParameter Return Error Problem
10940 
10941         Discard,
10942         NoError,
10943     };
10944 
10949     SS7TCAPError(SS7TCAP::TCAPType tcapType);
10950 
10956     SS7TCAPError(SS7TCAP::TCAPType tcapType, ErrorType error);
10957 
10961     ~SS7TCAPError();
10962 
10967     inline ErrorType error()
10968         { return m_error; }
10969 
10974     inline void setError(ErrorType error)
10975         { m_error = error; }
10976 
10981     const String errorName();
10982 
10987     u_int16_t errorCode();
10988 
10995     static int errorFromCode(SS7TCAP::TCAPType tcapType, u_int16_t code);
10996 
11003     static u_int16_t codeFromError(SS7TCAP::TCAPType tcapType, int err);
11004 
11008     static const TokenDict s_errorTypes[];
11009 
11010 private:
11011     SS7TCAP::TCAPType m_tcapType;
11012     ErrorType m_error;
11013 };
11014 
11019 class YSIG_API SS7TCAPTransaction : public GenObject, public Mutex
11020 {
11021 public:
11022     enum TransactionState {
11023         Idle                      = 0,
11024         PackageSent               = 1,
11025         PackageReceived           = 2,
11026         Active                    = 3,
11027     };
11028 
11029     enum TransactionTransmit {
11030         NoTransmit       = 0,
11031         PendingTransmit  = 256,
11032         Transmitted      = 521,
11033     };
11034 
11044     SS7TCAPTransaction(SS7TCAP* tcap, SS7TCAP::TCAPUserTransActions type, const String& transactID, NamedList& params,
11045         u_int64_t timeout, bool initLocal = true);
11046 
11050     ~SS7TCAPTransaction();
11051 
11058     virtual SS7TCAPError handleData(NamedList& params, DataBlock& data) = 0;
11059 
11067     virtual SS7TCAPError update(SS7TCAP::TCAPUserTransActions type, NamedList& params, bool updateByUser = true) = 0;
11068 
11075     virtual SS7TCAPError handleDialogPortion(NamedList& params,bool byUser = true) = 0;
11076 
11084     virtual SS7TCAPError buildComponentError(SS7TCAPError& error, NamedList& params, DataBlock& data);
11085 
11092     virtual SS7TCAPError handleComponents(NamedList& params, bool updateByUser = true);
11093 
11099     virtual void requestComponents(NamedList& params, DataBlock& data);
11100 
11105     virtual void transactionData(NamedList& params);
11106 
11112     virtual void requestContent(NamedList& params, DataBlock& data) = 0;
11113 
11117     virtual void checkComponents();
11118 
11123     inline void setTransactionType(SS7TCAP::TCAPUserTransActions type)
11124         { Lock l(this); m_type = type; }
11125 
11130     inline SS7TCAP::TCAPUserTransActions transactionType()
11131         { return m_type; }
11132 
11137     inline void setState(TransactionState state)
11138     {
11139         Lock l(this);
11140         m_state = state;
11141         // changing state automatically triggers a change in transmission state (except for Idle)
11142         if (state != Idle)
11143             m_transmit = PendingTransmit;
11144     }
11145 
11150     inline TransactionState transactionState()
11151         { return m_state; }
11152 
11157     void setTransmitState(TransactionTransmit state);
11158 
11163     inline TransactionTransmit transmitState()
11164         { return m_transmit; }
11165 
11170     inline SS7TCAP* tcap()
11171         { return m_tcap; }
11172 
11177     const String& toString() const
11178         { return m_localID; }
11179 
11184     inline void setUserName(const String& name)
11185         { m_userName = name; }
11186 
11191     const String& userName()
11192         { return m_userName; }
11193 
11198     inline bool basicEnd()
11199         { return m_basicEnd; }
11200 
11206     void addSCCPAddressing(NamedList& fillParams, bool local);
11207 
11212     inline bool endNow()
11213         { return m_endNow; }
11214 
11219     inline void endNow(bool endNow)
11220         { m_endNow = endNow; }
11221 
11226     inline bool timedOut()
11227         { return m_timeout.timeout(); }
11228 
11234     SS7TCAPComponent* findComponent(const String& id);
11235 
11239     virtual void updateToEnd();
11240 
11245     virtual void updateState(bool byUser = true) = 0;
11246 
11251     virtual void abnormalDialogInfo(NamedList& params);
11252 
11258     virtual SS7TCAPError decodeDialogPortion(NamedList& params, DataBlock& data) = 0;
11259 
11264     virtual void encodeDialogPortion(NamedList& params, DataBlock& data) = 0;
11265 
11271     virtual SS7TCAPError decodeComponents(NamedList& params, DataBlock& data) = 0;
11272 
11277     virtual void encodeComponents(NamedList& params, DataBlock& data) = 0;
11278 
11279 protected:
11280     SS7TCAP* m_tcap;
11281     SS7TCAP::TCAPType m_tcapType;
11282     String m_userName;
11283     String m_localID;
11284     String m_remoteID;
11285     SS7TCAP::TCAPUserTransActions m_type;
11286     TransactionState m_state;
11287     TransactionTransmit m_transmit;
11288 
11289     ObjList m_components;
11290 
11291     NamedList m_localSCCPAddr;
11292     NamedList m_remoteSCCPAddr;
11293 
11294     bool m_basicEnd; // basic or prearranged end (specified by user when sending a Response)
11295     bool m_endNow; // delete immediately after sending
11296     SignallingTimer m_timeout;
11297 };
11298 
11303 class YSIG_API SS7TCAPComponent : public GenObject
11304 {
11305 public:
11309     enum TCAPComponentState {
11310         Idle,
11311         OperationPending,
11312         OperationSent,
11313         WaitForReject,
11314     };
11315 
11323     SS7TCAPComponent(SS7TCAP::TCAPType type, SS7TCAPTransaction* trans, NamedList& params, unsigned int index);
11324 
11328     virtual ~SS7TCAPComponent();
11329 
11335     virtual void update(NamedList& params, unsigned int index);
11336 
11342     virtual void fill(unsigned int index, NamedList& fillIn);
11343 
11352     static SS7TCAPComponent* componentFromNamedList(SS7TCAP::TCAPType type, SS7TCAPTransaction* tr, NamedList& params, unsigned int index);
11353 
11358     void setTransaction(SS7TCAPTransaction* transact);
11359 
11363     SS7TCAPTransaction* transaction();
11364 
11369     inline void setType(SS7TCAP::TCAPUserCompActions type)
11370         { m_type = type; }
11371 
11375     inline SS7TCAP::TCAPUserCompActions type()
11376         { return m_type; }
11377 
11382     virtual void setInvokeID(String invokeID)
11383         { m_id = invokeID; }
11384 
11389     virtual const String&  toString () const
11390         { return m_id; }
11391 
11396     virtual const String&  correlationID() const
11397         { return m_corrID; }
11398 
11403     inline bool timedOut()
11404         { return m_opTimer.timeout(); }
11405 
11410     void setState(TCAPComponentState state);
11411 
11416     inline TCAPComponentState state()
11417         { return m_state; }
11418 
11424     void resetTimer(NamedList& params, unsigned int index);
11425 
11430     SS7TCAP::TCAPComponentOperationClass operationClass()
11431         { return m_opClass; }
11432 
11436     static const TokenDict s_compStates[];
11437 
11438 private:
11439     SS7TCAPTransaction* m_transact;
11440     SS7TCAP::TCAPUserCompActions m_type;
11441     TCAPComponentState m_state;
11442     String m_id;
11443     String m_corrID;
11444     SS7TCAP::TCAPComponentOperationClass m_opClass;
11445     SignallingTimer m_opTimer;
11446     SS7TCAPError m_error;
11447 };
11448 
11453 class YSIG_API SS7TCAPANSI : virtual public SS7TCAP
11454 {
11455     YCLASS(SS7TCAPANSI,SS7TCAP)
11456 public:
11457     enum TCAPTags {
11458         TransactionIDTag    = 0xc7,
11459         PCauseTag           = 0xd7,
11460         UserAbortPTag       = 0xd8 , // Primitive
11461         UserAbortCTag       = 0xf8,  // Constructor
11462     };
11463 
11464     enum TCAPDialogTags {
11465         DialogPortionTag         = 0xf9,
11466         ProtocolVersionTag       = 0xda,
11467         IntApplicationContextTag = 0xdb,
11468         OIDApplicationContextTag = 0xdc,
11469         UserInformationTag       = 0xfd,
11470         IntSecurityContextTag    = 0x80,
11471         OIDSecurityContextTag    = 0x81,
11472         ConfidentialityTag       = 0xa2,
11473     };
11474 
11475     enum UserInfoTags {
11476         DirectReferenceTag       = 0x06,
11477         DataDescriptorTag        = 0x07,
11478         ExternalTag              = 0x28,
11479         SingleASNTypePEncTag     = 0x80, // Primitive Single-ASN1-Type-Encoding
11480         SingleASNTypeCEncTag     = 0xa0, // Constructor Single-ASN1-Type-Encoding
11481         OctetAlignEncTag         = 0x81,
11482         ArbitraryEncTag          = 0x82,
11483     };
11484 
11485     enum ConfidentialityTags {
11486         IntConfidentialContextTag    = 0x80,
11487         OIDConfidentialContextTag    = 0x81,
11488     };
11489 
11490     enum TCAPComponentTags {
11491         ComponentPortionTag  = 0xe8,
11492         ComponentsIDsTag     = 0xcf,
11493         OperationNationalTag = 0xd0,
11494         OperationPrivateTag  = 0xd1,
11495         ErrorNationalTag     = 0xd3,
11496         ErrorPrivateTag      = 0xd4,
11497         ProblemCodeTag       = 0xd5,
11498         ParameterSetTag      = 0xf2,
11499         ParameterSeqTag      = 0x30,
11500     };
11501 
11506     SS7TCAPANSI(const NamedList& params);
11507 
11511     ~SS7TCAPANSI();
11512 
11521     virtual SS7TCAPTransaction* buildTransaction(SS7TCAP::TCAPUserTransActions type, const String& transactID, NamedList& params,
11522         bool initLocal = true);
11523 
11524 private:
11525     SS7TCAPError decodeTransactionPart(NamedList& params, DataBlock& data);
11526     void encodeTransactionPart(NamedList& params, DataBlock& data);
11527 };
11528 
11533 class YSIG_API SS7TCAPTransactionANSI : public SS7TCAPTransaction
11534 {
11535 public:
11536     enum TCAPANSIComponentType {
11537         CompUnknown         = 0x0,
11538         Local               = 0x1,
11539         InvokeLast          = 0xe9,
11540         ReturnResultLast    = 0xea,
11541         ReturnError         = 0xeb,
11542         Reject              = 0xec,
11543         InvokeNotLast       = 0xed,
11544         ReturnResultNotLast = 0xee,
11545     };
11546 
11547     enum ANSITransactionType {
11548         Unknown                         = 0x0,
11549         Unidirectional                  = 0xe1,
11550         QueryWithPermission             = 0xe2,
11551         QueryWithoutPermission          = 0xe3,
11552         Response                        = 0xe4,
11553         ConversationWithPermission      = 0xe5,
11554         ConversationWithoutPermission   = 0xe6,
11555         Abort                           = 0xf6,
11556     };
11557 
11567     SS7TCAPTransactionANSI(SS7TCAP* tcap, SS7TCAP::TCAPUserTransActions type, const String& transactID, NamedList& params,
11568         u_int64_t timeout, bool initLocal = true);
11569 
11573     ~SS7TCAPTransactionANSI();
11574 
11581     virtual SS7TCAPError handleData(NamedList& params, DataBlock& data);
11582 
11590     virtual SS7TCAPError update(SS7TCAP::TCAPUserTransActions type, NamedList& params, bool updateByUser = true);
11591 
11598     virtual SS7TCAPError handleDialogPortion(NamedList& params, bool byUser = true);
11599 
11606     static void encodePAbort(SS7TCAPTransaction* tr, NamedList& params, DataBlock& data);
11607 
11614     static SS7TCAPError decodePAbort(SS7TCAPTransaction* tr, NamedList& params, DataBlock& data);
11615 
11619     virtual void updateToEnd();
11620 
11625     virtual void updateState(bool byUser);
11626 
11632     virtual void requestContent(NamedList& params, DataBlock& data);
11633 
11637     static const TokenDict s_ansiTransactTypes[];
11638 
11639 private:
11640     SS7TCAPError decodeDialogPortion(NamedList& params, DataBlock& data);
11641     void encodeDialogPortion(NamedList& params, DataBlock& data);
11642     SS7TCAPError decodeComponents(NamedList& params, DataBlock& data);
11643     void encodeComponents(NamedList& params, DataBlock& data);
11644 
11645     SS7TCAP::TCAPUserTransActions m_prevType;
11646 };
11647 
11652 class YSIG_API SS7TCAPITU : virtual public SS7TCAP
11653 {
11654     YCLASS(SS7TCAPITU,SS7TCAP)
11655 public:
11656     enum TCAPTags {
11657         OriginatingIDTag    = 0x48,
11658         DestinationIDTag    = 0x49,
11659         PCauseTag           = 0x4a,
11660     };
11661 
11662     enum TCAPDialogTags {
11663         DialogPortionTag         = 0x6b,
11664         ProtocolVersionTag       = 0x80,
11665         ApplicationContextTag    = 0xa1,
11666         UserInformationTag       = 0xbe,
11667     };
11668 
11669     enum UserInfoTags {
11670         DirectReferenceTag       = 0x06,
11671         DataDescriptorTag        = 0x07,
11672         ExternalTag              = 0x28,
11673         SingleASNTypePEncTag     = 0x80, // Primitive Single-ASN1-Type-Encoding
11674         SingleASNTypeCEncTag     = 0xa0, // Constructor Single-ASN1-Type-Encoding
11675         OctetAlignEncTag         = 0x81,
11676         ArbitraryEncTag          = 0x82,
11677     };
11678 
11679     enum TCAPComponentTags {
11680         ComponentPortionTag  = 0x6c,
11681         LocalTag             = 0x02,
11682         LinkedIDTag          = 0x80,
11683         GlobalTag            = 0x06,
11684         ParameterSeqTag      = 0x30,
11685         ParameterSetTag      = 0x31,
11686     };
11687 
11692     SS7TCAPITU(const NamedList& params);
11693 
11697     ~SS7TCAPITU();
11698 
11707     virtual SS7TCAPTransaction* buildTransaction(SS7TCAP::TCAPUserTransActions type, const String& transactID, NamedList& params,
11708         bool initLocal = true);
11709 
11710 private:
11711     SS7TCAPError decodeTransactionPart(NamedList& params, DataBlock& data);
11712     void encodeTransactionPart(NamedList& params, DataBlock& data);
11713 };
11714 
11719 class YSIG_API SS7TCAPTransactionITU : public SS7TCAPTransaction
11720 {
11721 public:
11722     enum ITUComponentType {
11723         CompUnknown         = 0x0,
11724         Local               = 0x1,
11725         Invoke              = 0xa1,
11726         ReturnResultLast    = 0xa2,
11727         ReturnError         = 0xa3,
11728         Reject              = 0xa4,
11729         ReturnResultNotLast = 0xa7,
11730     };
11731 
11732     enum ITUTransactionType {
11733         Unknown                         = 0x0,
11734         Unidirectional                  = 0x61,
11735         Begin                           = 0x62,
11736         End                             = 0x64,
11737         Continue                        = 0x65,
11738         Abort                           = 0x67,
11739     };
11740 
11741     enum ITUDialogTags {
11742         AARQDialogTag               = 0x60,
11743         AAREDialogTag               = 0x61,
11744         ABRTDialogTag               = 0x64,
11745         ResultDiagnosticUserTag     = 0xa1,
11746         ResultDiagnosticProviderTag = 0xa2,
11747         ResultTag                   = 0xa2,
11748         ResultDiagnosticTag         = 0xa3,
11749     };
11750 
11751     enum ITUDialogValues {
11752         ResultAccepted                     = 0,
11753         ResultRejected                     = 1,
11754         DiagnosticUserNull                 = 0x10,
11755         DiagnosticUserNoReason             = 0x11,
11756         DiagnosticUserAppCtxtNotSupported  = 0x12,
11757         DiagnosticProviderNull             = 0x20,
11758         DiagnosticProviderNoReason         = 0x21,
11759         DiagnosticProviderNoCommonDialog   = 0x22,
11760         AbortSourceUser                    = 0x30,
11761         AbortSourceProvider                = 0x31,
11762     };
11763 
11773     SS7TCAPTransactionITU(SS7TCAP* tcap, SS7TCAP::TCAPUserTransActions type, const String& transactID, NamedList& params,
11774         u_int64_t timeout, bool initLocal = true);
11775 
11779     ~SS7TCAPTransactionITU();
11780 
11787     virtual SS7TCAPError handleData(NamedList& params, DataBlock& data);
11788 
11796     virtual SS7TCAPError update(SS7TCAP::TCAPUserTransActions type, NamedList& params, bool updateByUser = true);
11797 
11804     virtual SS7TCAPError handleDialogPortion(NamedList& params, bool byUser = true);
11805 
11812     static void encodePAbort(SS7TCAPTransaction* tr, NamedList& params, DataBlock& data);
11813 
11821     static SS7TCAPError decodePAbort(SS7TCAPTransaction* tr, NamedList& params, DataBlock& data);
11822 
11826     virtual void updateToEnd();
11827 
11832     inline bool dialogPresent()
11833         { return !(m_appCtxt.null()); }
11834 
11840     bool testForDialog(DataBlock& data);
11841 
11847     void encodeDialogPortion(NamedList& params, DataBlock& data);
11848 
11855     SS7TCAPError decodeDialogPortion(NamedList& params, DataBlock& data);
11856 
11861     void updateState(bool byUser = false);
11862 
11868     virtual void requestContent(NamedList& params, DataBlock& data);
11869 
11874     virtual void abnormalDialogInfo(NamedList& params);
11875 
11879     static const TokenDict s_dialogPDUs[];
11880 
11884     static const TokenDict s_resultPDUValues[];
11885 
11886 private:
11887     SS7TCAPError decodeComponents(NamedList& params, DataBlock& data);
11888     void encodeComponents(NamedList& params, DataBlock& data);
11889 
11890     String m_appCtxt;
11891 };
11892 
11893 // The following classes are ISDN, not SS7, but they use the same signalling
11894 //  interfaces so they will remain here
11895 
11900 class YSIG_API ISDNLayer2 : virtual public SignallingComponent
11901 {
11902     YCLASS(ISDNLayer2,SignallingComponent)
11903     friend class ISDNQ921Management;
11904 public:
11908     enum State {
11909         Released,                        // Multiple frame acknowledged not allowed
11910         WaitEstablish,                   // Wating to establish 'multiple frame acknowledged' mode
11911         Established,                     // Multiple frame acknowledged allowed
11912         WaitRelease,                     // Wating to release 'multiple frame acknowledged' mode
11913     };
11914 
11918     virtual ~ISDNLayer2();
11919 
11923     inline ISDNLayer3* layer3() const
11924         { return m_layer3; }
11925 
11930     inline State state() const
11931         { return m_state; }
11932 
11937     inline bool network() const
11938         { return m_network; }
11939 
11944     inline bool detectType() const
11945         { return m_detectType; }
11946 
11951     inline u_int8_t localSapi() const
11952         { return m_sapi; }
11953 
11958     inline u_int8_t localTei() const
11959         { return m_tei; }
11960 
11965     inline u_int32_t maxUserData() const
11966         { return m_maxUserData; }
11967 
11972     inline bool teiAssigned() const
11973         { return m_teiAssigned; }
11974 
11979     inline bool autoRestart() const
11980         { return m_autoRestart; }
11981 
11986     unsigned int upTime() const
11987         { return m_lastUp ? (Time::secNow() - m_lastUp) : 0; }
11988 
11998     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force)
11999         { return false; }
12000 
12009     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack)
12010         { return false; }
12011 
12016     virtual void cleanup() = 0;
12017 
12024     virtual void attach(ISDNLayer3* layer3);
12025 
12031     static inline const char* stateName(State s)
12032         { return lookup((int)s,m_states); }
12033 
12034 protected:
12042     ISDNLayer2(const NamedList& params, const char* name = 0, u_int8_t tei = 0);
12043 
12048     inline Mutex& l2Mutex()
12049         { return m_layerMutex; }
12050 
12059     void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout);
12060 
12069     void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout);
12070 
12081     void dataLinkState(u_int8_t tei, bool cmd, bool value);
12082 
12087     void idleTimeout();
12088 
12095     void receiveData(const DataBlock& data, u_int8_t tei);
12096 
12102     void teiAssigned(bool status);
12103 
12110     void changeState(State newState, const char* reason = 0);
12111 
12116     bool changeType();
12117 
12122     inline void autoRestart(bool restart)
12123         { m_autoRestart = restart; }
12124 
12129     inline void setRi(u_int16_t ri)
12130         { m_ri = ri; }
12131 
12137     ISDNFrame* parsePacket(const DataBlock& packet);
12138 
12139 private:
12140     ISDNLayer3* m_layer3;                // The attached Layer 3 interface
12141     Mutex m_layerMutex;                  // Layer 2 operations mutex
12142     Mutex m_layer3Mutex;                 // Control m_layer3 operations
12143     State m_state;                       // Layer's state
12144     bool m_network;                      // Network/CPE type of the interface
12145     bool m_detectType;                   // Detect interface type
12146     u_int8_t m_sapi;                     // SAPI value
12147     u_int8_t m_tei;                      // TEI value
12148     u_int16_t m_ri;                      // Reference number
12149     u_int32_t m_lastUp;                  // Time when the interface got up
12150     bool m_checked;                      // Flag to indicate if the layer was checked
12151     bool m_teiAssigned;                  // The TEI status
12152     bool m_autoRestart;                  // True to restart when released
12153     u_int32_t m_maxUserData;             // Maximum length of user data transported trough this layer
12154     unsigned int m_teiRefNumber;         // The Reference Number (Ri) carried by a TEI management frame
12155     static const TokenDict m_states[];   // Keep the string associated with each state
12156 };
12157 
12162 class YSIG_API ISDNLayer3 : virtual public SignallingComponent
12163 {
12164     YCLASS(ISDNLayer3,SignallingComponent)
12165 public:
12175     virtual void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2)
12176         { }
12177 
12187     virtual void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2)
12188         { }
12189 
12201     virtual void dataLinkState(u_int8_t tei, bool cmd, bool value, ISDNLayer2* layer2)
12202         { }
12203 
12209     virtual void idleTimeout(ISDNLayer2* layer2)
12210         { }
12211 
12219     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2) = 0;
12220 
12226     virtual ISDNLayer2* attach(ISDNLayer2* layer2)
12227         { return 0; }
12228 
12229 protected:
12235     inline ISDNLayer3(const char* name = 0)
12236         : SignallingComponent(name),
12237           m_layerMutex(true,"ISDNLayer3::layer")
12238         { }
12239 
12244     inline Mutex& l3Mutex()
12245         { return m_layerMutex; }
12246 
12247 private:
12248     Mutex m_layerMutex;                  // Layer 3 operations mutex
12249 };
12250 
12255 class YSIG_API ISDNFrame : public RefObject
12256 {
12257     friend class ISDNQ921;
12258     friend class ISDNQ921Management;
12259 public:
12263     enum Type {
12264         DISC = 1,                        // disconnect (command)
12265         DM = 2,                          // disconnected (response)
12266         FRMR = 3,                        // frame reject (response)
12267         I = 4,                           // information transfer (response)
12268         REJ = 5,                         // reject (command/response)
12269         RNR = 6,                         // receive not ready (command/response)
12270         RR = 7,                          // receive ready (command/response)
12271         SABME = 8,                       // set asynchronous balanced mode extended (command)
12272         UA = 9,                          // unnumbered acknoledgement (response)
12273         UI = 10,                         // unnumbered information (command)
12274         XID = 11,                        // exchange identification (command/response)
12275         // Note: Keep all errors greater then Invalid: The code relies on it
12276         Invalid = 100,
12277         ErrUnknownCR = 101,              // Error: Unknown command/response. Set by parser
12278         ErrHdrLength = 102,              // Error: Invalid header length. Set by parser
12279         ErrDataLength = 103,             // Error: Information field too long
12280         ErrRxSeqNo = 104,                // Error: Invalid receive sequence number
12281         ErrTxSeqNo = 105,                // Error: Invalid send sequence number
12282         ErrInvalidEA = 106,              // Error: Invalid 'extended address' bit(s). Set by parser
12283         ErrInvalidAddress = 107,         // Error: Invalid SAPI/TEI
12284         ErrUnsupported = 108,            // Error: Unsupported command. E.g. XID
12285         ErrInvalidCR = 109,              // Error: Invalid command/response flag
12286     };
12287 
12291     enum TeiManagement {
12292         TeiReq       = 1,                // TEI request (user to network)
12293         TeiAssigned  = 2,                // TEI assigned (network to user)
12294         TeiDenied    = 3,                // TEI denied (network to user)
12295         TeiCheckReq  = 4,                // TEI check request (network to user)
12296         TeiCheckRsp  = 5,                // TEI check response (user to network)
12297         TeiRemove    = 6,                // TEI remove (network to user)
12298         TeiVerify    = 7                 // TEI verify (user to network)
12299     };
12300 
12304     enum Category {
12305         Data,                            // I, UI
12306         Supervisory,                     // RR, RNR, REJ
12307         Unnumbered,                      // SABME, DISC, UA DM, FRMR XID
12308         Error
12309     };
12310 
12314     virtual ~ISDNFrame();
12315 
12320     inline Type type() const
12321         { return m_type; }
12322 
12327     inline Type error() const
12328         { return m_error; }
12329 
12334     inline Category category() const
12335         { return m_category; }
12336 
12341     inline bool command() const
12342         { return m_command; }
12343 
12348     inline u_int8_t sapi() const
12349         { return m_sapi; }
12350 
12355     inline u_int8_t tei() const
12356         { return m_tei; }
12357 
12362     inline bool poll() const
12363         { return m_poll; }
12364 
12369     inline u_int8_t ns() const
12370         { return m_ns; }
12371 
12376     inline u_int8_t nr() const
12377         { return m_nr; }
12378 
12383     inline u_int8_t headerLength() const
12384         { return m_headerLength; }
12385 
12390     inline u_int32_t dataLength() const
12391         { return m_dataLength; }
12392 
12397     inline const DataBlock& buffer() const
12398         { return m_buffer; }
12399 
12404     inline bool sent() const
12405         { return m_sent; }
12406 
12410     inline void sent(bool value)
12411         { m_sent = value; }
12412 
12417     inline const char* name() const
12418         { return typeName(type()); }
12419 
12425     void update(u_int8_t* ns = 0, u_int8_t* nr = 0);
12426 
12431     inline void getData(DataBlock& dest) const
12432         { dest.assign((u_int8_t*)m_buffer.data() + m_headerLength,m_dataLength); }
12433 
12439     void toString(String& dest, bool extendedDebug) const;
12440 
12445     bool checkTeiManagement() const;
12446 
12452     static u_int16_t getRi(const DataBlock& data);
12453 
12459     inline static u_int8_t getType(const DataBlock& data)
12460         { return static_cast<u_int8_t>(data.at(3,0)); }
12461 
12467     inline static u_int8_t getAi(const DataBlock& data)
12468         { return static_cast<u_int8_t>(data.at(4,0) >> 1); }
12469 
12470 
12477     static ISDNFrame* parse(const DataBlock& data, ISDNLayer2* receiver);
12478 
12487     static bool buildTeiManagement(DataBlock& data, u_int8_t type, u_int16_t ri,
12488         u_int8_t ai);
12489 
12496     static inline bool commandBit(bool network)
12497         { return network; }
12498 
12505     static inline bool responseBit(bool network)
12506         { return !network; }
12507 
12514     static inline bool isCommand(u_int8_t cr, bool sentByNetwork)
12515         { return cr ? sentByNetwork : !sentByNetwork; }
12516 
12522     static inline const char* typeName(Type type)
12523         { return lookup(type,s_types,"Invalid frame"); }
12524 
12528     static const TokenDict s_types[];
12529 
12530 protected:
12536     ISDNFrame(Type type = Invalid);
12537 
12551     ISDNFrame(Type type, bool command, bool senderNetwork,
12552         u_int8_t sapi, u_int8_t tei, bool pf, u_int8_t nr = 0);
12553 
12566     ISDNFrame(bool ack, bool senderNetwork, u_int8_t sapi, u_int8_t tei,
12567         bool pf, const DataBlock& data);
12568 
12569 private:
12570     Type m_type;                         // Frame type
12571     Type m_error;                        // Frame error type
12572     Category m_category;                 // Frame category
12573     // Address
12574     bool m_command;                      // Command/Response frame
12575     bool m_senderNetwork;                // True if the sender of this frame is the network side of the data link
12576     u_int8_t m_sapi;                     // SAPI value
12577     u_int8_t m_tei;                      // TEI value
12578     // Control
12579     bool m_poll;                         // Poll/Final flag
12580     u_int8_t m_ns;                       // N(S) value (when applicable): transmitter send sequence number
12581     u_int8_t m_nr;                       // N(R) value (when applicable): transmitter receive sequence number
12582     // Data
12583     u_int8_t m_headerLength;             // Header length
12584     u_int32_t m_dataLength;              // Data length
12585     DataBlock m_buffer;                  // Whole frame: header + data + FCS (frame check sequence = 2 bytes)
12586     // Outgoing frames only
12587     bool m_sent;                         // True if already sent
12588 };
12589 
12594 class YSIG_API ISDNQ921 : public ISDNLayer2, public SignallingReceiver, public SignallingDumpable
12595 {
12596     YCLASS2(ISDNQ921,ISDNLayer2,SignallingReceiver)
12597     friend class ISDNQ921Management;
12598 public:
12607     ISDNQ921(const NamedList& params, const char* name = 0, ISDNQ921Management* mgmt = 0, u_int8_t tei = 0);
12608 
12612     virtual ~ISDNQ921();
12613 
12619     virtual bool initialize(const NamedList* config);
12620 
12625     inline u_int64_t dataTimeout() const
12626         { return m_retransTimer.interval() * m_n200.maxVal(); }
12627 
12638     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force);
12639 
12649     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack);
12650 
12655     inline bool sendSabme()
12656         { return sendUFrame(ISDNFrame::SABME,true,true); }
12657 
12663     virtual void cleanup();
12664 
12670     inline void setDebug(bool printFrames, bool extendedDebug)
12671         { m_extendedDebug = ((m_printFrames = printFrames) && extendedDebug); }
12672 
12673 protected:
12677     virtual void destroyed()
12678     {
12679         ISDNLayer2::attach((ISDNLayer3*)0);
12680         TelEngine::destruct(SignallingReceiver::attach(0));
12681         SignallingComponent::destroyed();
12682     }
12683 
12689     virtual void timerTick(const Time& when);
12690 
12697     virtual bool receivedPacket(const DataBlock& packet);
12698 
12704     bool receivedFrame(ISDNFrame* frame);
12705 
12712     virtual bool notify(SignallingInterface::Notification event);
12713 
12718     void reset();
12719 
12720 private:
12721     virtual bool control(NamedList& params)
12722         { return SignallingDumpable::control(params,this); }
12723     // Acknoledge outgoing frames
12724     // @param frame The acknoledging frame
12725     bool ackOutgoingFrames(const ISDNFrame* frame);
12726     // Process a received I/UI frame
12727     // @param ack True for I frame, false for UI frame
12728     // @return True to send data to Layer 3
12729     bool processDataFrame(const ISDNFrame* frame, bool ack);
12730     // Process a received S frame
12731     // @return True to exit from timer recovery state
12732     bool processSFrame(const ISDNFrame* frame);
12733     // Process a received U frame
12734     // @param newState The new state if true is returned
12735     // @param confirmation True if the new state is Established or Released and
12736     //  this is a confirmation
12737     // @return True to change state
12738     bool processUFrame(const ISDNFrame* frame, State& newState,
12739         bool& confirmation);
12740     // Accept frame according to Q.921 5.8.5
12741     // Update counters.
12742     // If not accepted the frame is rejected or dropped
12743     // reject is set to true if the frame is rejected
12744     bool acceptFrame(ISDNFrame* frame, bool& reject);
12745     // Update rejected frames counter. Print message. Send FRMR (frame reject)
12746     void rejectFrame(const ISDNFrame* frame, const char* reason = 0);
12747     // Update dropped frames counter. Print message
12748     void dropFrame(const ISDNFrame* frame, const char* reason = 0);
12749     // Send S frames other then UI frames
12750     bool sendUFrame(ISDNFrame::Type type, bool command, bool pf,
12751         bool retrans = false);
12752     // Send U frames
12753     bool sendSFrame(ISDNFrame::Type type, bool command, bool pf);
12754     // Send a frame to remote peer
12755     // @param frame Frame to send
12756     // @return False if the operation failed
12757     bool sendFrame(const ISDNFrame* frame);
12758     // Send pending outgoing I frames
12759     // @param retrans: True   Send all transmission window
12760     //                 False  Send only the unsent frames in transmission window
12761     // @return True if a transmission took place
12762     bool sendOutgoingData(bool retrans = false);
12763     // Start/Stop T200. Stop/Start T203
12764     // If start is false reset N200 (retransmission counter)
12765     // @param start True to start. False to stop
12766     // @param t203 Start/don't start T203. Ignored if start is false
12767     // @param time Current time if known
12768     void timer(bool start, bool t203, u_int64_t time = 0);
12769 
12770     ISDNQ921Management* m_management;    // TEI management component
12771     // State variables
12772     bool m_remoteBusy;                   // Remote peer is busy: don't send any I frames
12773     bool m_timerRecovery;                // T200 expired
12774     bool m_rejectSent;                   // True if we've sent a REJ frame
12775     bool m_pendingDMSabme;               // True if we have a pending SABME on DM received
12776     bool m_lastPFBit;                    // Last P/F bit sent with an I or S frame
12777     u_int8_t m_vs;                       // Sequence number of the next transmitted I frame
12778     u_int8_t m_va;                       // Last ack'd I frame by remote peer
12779     u_int8_t m_vr;                       // Expected I frame sequence number
12780     // Timers and counters
12781     SignallingTimer m_retransTimer;      // T200: Retransmission interval
12782     SignallingTimer m_idleTimer;         // T203: Channel idle interval
12783     SignallingCounter m_window;          // Maximum/current number of pending outgoing I frames
12784     SignallingCounter m_n200;            // Maximum/current retransmission counter
12785     // Data
12786     ObjList m_outFrames;                 // Outgoing I frames queue
12787     // Statistics
12788     u_int32_t m_txFrames;                // The number of frames accepted by layer 1 to be transmitted
12789     u_int32_t m_txFailFrames;            // The number of frames not accepted by layer 1 to be transmitted
12790     u_int32_t m_rxFrames;                // The number of successfully parsed frames
12791     u_int32_t m_rxRejectedFrames;        // The number of rejected frames. Doesn't include dropped frames
12792     u_int32_t m_rxDroppedFrames;         // The number of dropped frames. Doesn't include rejected frames
12793     u_int32_t m_hwErrors;                // The number of hardware notifications
12794     // Debug flags
12795     bool m_printFrames;                  // Print frames to output
12796     bool m_extendedDebug;                // Extended debug flag
12797     // Flags used to avoid repetitive errors
12798     bool m_errorSend;                    // Send error
12799     bool m_errorReceive;                 // Receive error
12800 };
12801 
12809 class YSIG_API ISDNQ921Management : public ISDNLayer2, public ISDNLayer3, public SignallingReceiver, public SignallingDumpable
12810 {
12811     YCLASS3(ISDNQ921Management,ISDNLayer2,ISDNLayer3,SignallingReceiver)
12812 public:
12819     ISDNQ921Management(const NamedList& params, const char* name = 0, bool net = true);
12820 
12824     virtual ~ISDNQ921Management();
12825 
12831     virtual bool initialize(const NamedList* config);
12832 
12837     virtual void engine(SignallingEngine* eng);
12838 
12846     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force);
12847 
12855     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack);
12856 
12863     bool sendFrame(const ISDNFrame* frame, const ISDNQ921* q921 = 0);
12864 
12865 
12870     virtual void cleanup();
12871 
12881     virtual void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
12882 
12892     virtual void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
12893 
12905     virtual void dataLinkState(u_int8_t tei, bool cmd, bool value, ISDNLayer2* layer2);
12906 
12914     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2);
12915 
12916 protected:
12922     virtual void timerTick(const Time& when);
12923 
12930     virtual bool receivedPacket(const DataBlock& packet);
12931 
12937     virtual bool notify(SignallingInterface::Notification event);
12938 
12944     bool processTeiManagement(ISDNFrame* frame);
12945 
12955     bool sendTeiManagement(ISDNFrame::TeiManagement type, u_int16_t ri, u_int8_t ai, u_int8_t tei = 127, bool pf = false);
12956 
12968     void processTeiRequest(u_int16_t ri, u_int8_t ai, bool pf);
12969 
12974     void processTeiRemove(u_int8_t ai);
12975 
12982     void processTeiCheckRequest(u_int8_t ai, bool pf);
12983 
12989     void processTeiCheckResponse(u_int16_t ri, u_int8_t ai);
12990 
12996     void processTeiAssigned(u_int16_t ri, u_int8_t ai);
12997 
13002     void processTeiDenied(u_int16_t ri);
13003 
13009     void processTeiVerify(u_int8_t ai, bool pf);
13010 
13015     void sendTeiReq(u_int8_t tei);
13016 
13020     void sendTeiRemove();
13021 
13022 private:
13023     ISDNQ921* m_layer2[127];             // The list of Layer 2 objects attached to this Layer 3
13024     SignallingTimer m_teiManTimer;       // T202
13025     SignallingTimer m_teiTimer;          // T201
13026 };
13027 
13032 class YSIG_API ISDNQ921Passive : public ISDNLayer2, public SignallingReceiver, public SignallingDumpable
13033 {
13034     YCLASS2(ISDNQ921Passive,ISDNLayer2,SignallingReceiver)
13035 public:
13042     ISDNQ921Passive(const NamedList& params, const char* name = 0);
13043 
13047     virtual ~ISDNQ921Passive();
13048 
13054     virtual void cleanup();
13055 
13061     virtual bool initialize(const NamedList* config);
13062 
13068     inline void setDebug(bool printFrames, bool extendedDebug)
13069         { m_extendedDebug = ((m_printFrames = printFrames) && extendedDebug); }
13070 
13071 protected:
13075     virtual void destroyed()
13076     {
13077         ISDNLayer2::attach(0);
13078         TelEngine::destruct(SignallingReceiver::attach(0));
13079         SignallingComponent::destroyed();
13080     }
13081 
13087     virtual void timerTick(const Time& when);
13088 
13095     virtual bool receivedPacket(const DataBlock& packet);
13096 
13103     virtual bool notify(SignallingInterface::Notification event);
13104 
13105 private:
13106     virtual bool control(NamedList& params)
13107         { return SignallingDumpable::control(params,this); }
13108     // Filter received frames. Accept only frames that would generate a notification to the upper layer:
13109     // UI/I, and Valid SABME/DISC/UA/DM
13110     // On success, if frame is not a data one, prepare cmd and value to notify layer 3
13111     bool acceptFrame(ISDNFrame* frame, bool& cmd, bool& value);
13112     // Show debug message. Count dropped frames
13113     bool dropFrame(const ISDNFrame* frame, const char* reason = 0);
13114 
13115     bool m_checkLinkSide;                // Check if this is the correct side of the data link
13116     SignallingTimer m_idleTimer;         // Channel idle interval
13117     u_int8_t m_lastFrame;                // Transmitter send number of the last received frame
13118     u_int32_t m_rxFrames;                // The number of successfully parsed frames
13119     u_int32_t m_rxRejectedFrames;        // The number of rejected frames. Doesn't include dropped frames
13120     u_int32_t m_rxDroppedFrames;         // The number of dropped frames. Doesn't include rejected frames
13121     u_int32_t m_hwErrors;                // The number of hardware notifications
13122     bool m_printFrames;                  // Print frames to output
13123     bool m_extendedDebug;                // Extended debug flag
13124     bool m_errorReceive;                 // Receive error
13125 };
13126 
13131 class YSIG_API ISDNIUAClient : public SIGAdaptClient
13132 {
13133     YCLASS(ISDNIUAClient,SIGAdaptClient)
13134 public:
13138     inline ISDNIUAClient(const NamedList& params)
13139         : SIGAdaptClient(params.safe("ISDNIUAClient"),&params,1,9900)
13140         { }
13141 
13142     virtual bool processMSG(unsigned char msgVersion, unsigned char msgClass,
13143         unsigned char msgType, const DataBlock& msg, int streamId);
13144 };
13145 
13152 class YSIG_API ISDNIUA : public ISDNLayer2, public SIGAdaptUser
13153 {
13154     friend class ISDNIUAClient;
13155     YCLASS(ISDNIUA,ISDNLayer2)
13156 public:
13164     ISDNIUA(const NamedList& params, const char* name = 0, u_int8_t tei = 0);
13165 
13169     virtual ~ISDNIUA();
13170 
13176     virtual bool initialize(const NamedList* config);
13177 
13186     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force);
13187 
13195     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack);
13196 
13200     virtual void cleanup();
13201 
13206     virtual void activeChange(bool active);
13207 
13212     inline int32_t iid() const
13213         { return m_iid; }
13214 
13215 protected:
13216     ISDNIUAClient* client() const
13217         { return static_cast<ISDNIUAClient*>(adaptation()); }
13218     virtual bool processMGMT(unsigned char msgType, const DataBlock& msg, int streamId);
13219     virtual bool processQPTM(unsigned char msgType, const DataBlock& msg, int streamId);
13220     int32_t m_iid;
13221 };
13222 
13227 class YSIG_API ISDNQ931IE : public NamedList
13228 {
13229     friend class ISDNQ931Message;
13230 public:
13234     enum Type {
13235         // Fixed (1 byte) length information element
13236         Shift = 0x90,                    // Shift
13237         MoreData = 0xa0,                 // More data
13238         SendComplete = 0xa1,             // Sending complete
13239         Congestion = 0xb0,               // Congestion level
13240         Repeat = 0xd0,                   // Repeat indicator
13241         // Variable length information element
13242         Segmented = 0x00,                // Segmented message
13243         BearerCaps = 0x04,               // Bearer capability
13244         Cause = 0x08,                    // Cause
13245         CallIdentity = 0x10,             // Call identity
13246         CallState = 0x14,                // Call state
13247         ChannelID = 0x18,                // Channel identification
13248         Progress = 0x1e,                 // Progress indicator
13249         NetFacility = 0x20,              // Network-specific facilities
13250         Notification = 0x27,             // Notification indicator
13251         Display = 0x28,                  // Display
13252         DateTime = 0x29,                 // Date/time
13253         Keypad = 0x2c,                   // Keypad facility
13254         Signal = 0x34,                   // Signal
13255         ConnectedNo = 0x4c,              // Connected number (Q.951)
13256         CallingNo = 0x6c,                // Calling party number
13257         CallingSubAddr = 0x6d,           // Calling party subaddress
13258         CalledNo = 0x70,                 // Called party number
13259         CalledSubAddr = 0x71,            // Called party subaddress
13260         NetTransit = 0x78,               // Transit network selection
13261         Restart = 0x79,                  // Restart indicator
13262         LoLayerCompat = 0x7c,            // Low layer compatibility
13263         HiLayerCompat = 0x7d,            // High layer compatibility
13264         // Not used
13265         UserUser = 0x7e,                 // User-user
13266         Escape = 0x7f,                   // Escape for extension
13267     };
13268 
13274     ISDNQ931IE(u_int16_t type);
13275 
13279     virtual ~ISDNQ931IE();
13280 
13285     inline u_int8_t type() const
13286         { return (u_int8_t)m_type; }
13287 
13293     inline void addParamPrefix(const char* name, const char* value)
13294         { addParam(*this+"."+name,value); }
13295 
13303     void toString(String& dest, bool extendedDebug, const char* before = 0);
13304 
13311     static inline const char* typeName(int type, const char* defVal = 0)
13312         { return lookup(type,s_type,defVal); }
13313 
13317     static const TokenDict s_type[];
13318 
13322     DataBlock m_buffer;
13323 
13324 private:
13325     u_int16_t m_type;                    // IE type
13326 };
13327 
13332 class YSIG_API ISDNQ931Message : public SignallingMessage
13333 {
13334 public:
13338     enum Type {
13339         Alerting = 0x01,                 // ALERTING
13340         Proceeding = 0x02,               // CALL PROCEEDING
13341         Connect = 0x07,                  // CONNECT
13342         ConnectAck = 0x0f,               // CONNECT ACK
13343         Progress = 0x03,                 // PROGRESS
13344         Setup = 0x05,                    // SETUP
13345         SetupAck = 0x0d,                 // SETUP ACK
13346         Resume = 0x26,                   // RESUME
13347         ResumeAck = 0x2e,                // RESUME ACK
13348         ResumeRej = 0x22,                // RESUME REJECT
13349         Suspend = 0x25,                  // SUSPEND
13350         SuspendAck = 0x2d,               // SUSPEND ACK
13351         SuspendRej = 0x21,               // SUSPEND REJECT
13352         UserInfo = 0x20,                 // USER INFO
13353         Disconnect = 0x45,               // DISCONNECT
13354         Release = 0x4d,                  // RELEASE
13355         ReleaseComplete = 0x5a,          // RELEASE COMPLETE
13356         Restart = 0x46,                  // RESTART
13357         RestartAck = 0x4e,               // RESTART ACK
13358         Segment = 0x60,                  // SEGMENT
13359         CongestionCtrl = 0x79,           // CONGESTION CONTROL
13360         Info = 0x7b,                     // INFORMATION
13361         Notify = 0x6e,                   // NOTIFY
13362         Status = 0x7d,                   // STATUS
13363         StatusEnquiry = 0x75,            // STATUS ENQUIRY
13364     };
13365 
13374     ISDNQ931Message(Type type, bool initiator, u_int32_t callRef, u_int8_t callRefLen);
13375 
13381     ISDNQ931Message(Type type);
13382 
13389     ISDNQ931Message(Type type, ISDNQ931Call* call);
13390 
13394     virtual ~ISDNQ931Message();
13395 
13400     inline Type type() const
13401         { return m_type; }
13402 
13407     inline bool initiator() const
13408         { return m_initiator; }
13409 
13414     inline u_int32_t callRef() const
13415         { return m_callRef; }
13416 
13421     inline u_int8_t callRefLen() const
13422         { return m_callRefLen; }
13423 
13428     inline bool dummyCallRef() const
13429         { return m_dummy; }
13430 
13435     inline bool unknownMandatory() const
13436         { return m_unkMandatory; }
13437 
13441     inline void setUnknownMandatory()
13442         { m_unkMandatory = true; }
13443 
13448     inline ObjList* ieList()
13449         { return &m_ie; }
13450 
13457     ISDNQ931IE* getIE(ISDNQ931IE::Type type, ISDNQ931IE* base = 0);
13458 
13465     ISDNQ931IE* removeIE(ISDNQ931IE::Type type, ISDNQ931IE* base = 0);
13466 
13474     inline const char* getIEValue(ISDNQ931IE::Type type, const char* param,
13475         const char* defVal = 0)
13476     {
13477         ISDNQ931IE* ie = getIE(type);
13478         return (ie ? ie->getValue(param?param:ie->c_str(),defVal) : defVal);
13479     }
13480 
13488     inline ISDNQ931IE* appendIEValue(ISDNQ931IE::Type type, const char* param,
13489         const char* value)
13490     {
13491         ISDNQ931IE* ie = new ISDNQ931IE(type);
13492         ie->addParam(param?param:ie->c_str(),value);
13493         appendSafe(ie);
13494         return ie;
13495     }
13496 
13502     inline bool append(ISDNQ931IE* ie)
13503         { return 0 != m_ie.append(ie); }
13504 
13511     bool appendSafe(ISDNQ931IE* ie);
13512 
13520     void toString(String& dest, bool extendedDebug, const char* indent = 0) const;
13521 
13527     virtual void* getObject(const String& name) const;
13528 
13539     u_int8_t encode(ISDNQ931ParserData& parserData, ObjList& dest);
13540 
13550     static ISDNQ931Message* parse(ISDNQ931ParserData& parserData,
13551         const DataBlock& buffer, DataBlock* segData);
13552 
13558     static inline const char* typeName(int t)
13559         { return lookup(t,s_type,"Unknown"); }
13560 
13564     static const TokenDict s_type[];
13565 
13569     DataBlock m_buffer;
13570 
13571 private:
13572     Type m_type;                         // Message type
13573     bool m_initiator;                    // The call initiator flag: True: this is the initiator
13574     u_int32_t m_callRef;                 // The call reference
13575     u_int8_t m_callRefLen;               // The call reference length
13576     bool m_unkMandatory;                 // True if this message contains unknown mandatory IE(s)
13577     bool m_dummy;                        // True if this message has a dummy call reference
13578     ObjList m_ie;                        // IE list
13579 };
13580 
13585 class YSIG_API ISDNQ931IEData
13586 {
13587     friend class ISDNQ931Call;
13588     friend class ISDNQ931CallMonitor;
13589     friend class ISDNQ931;
13590     friend class ISDNQ931Monitor;
13591 private:
13592     // Constructor
13593     ISDNQ931IEData(bool bri = false);
13594     // Process received IEs
13595     // If add is true, append an IE to the message
13596     // If add is false, extract data from message. Set data to default values if IE is missing
13597     // @return False if the IE is missing when decoding or the IE wasn't added
13598     bool processBearerCaps(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13599     bool processCause(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13600     bool processDisplay(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13601     bool processKeypad(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13602     bool processChannelID(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13603     bool processProgress(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13604     bool processRestart(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13605     bool processNotification(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13606     bool processCalledNo(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13607     bool processCallingNo(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
13608 
13609     // IE parameters
13610     String m_display;                    // Display: The data
13611     String m_callerNo;                   // CallingNo: Number
13612     String m_callerType;                 // CallingNo: Number type
13613     String m_callerPlan;                 // CallingNo: Number plan
13614     String m_callerPres;                 // CallingNo: Number presentation
13615     String m_callerScreening;            // CallingNo: Number screening
13616     String m_calledNo;                   // CalledNo: Number
13617     String m_calledType;                 // CalledNo: Number type
13618     String m_calledPlan;                 // CalledNo: Number plan
13619     String m_transferCapability;         // BearerCaps: Transfer capability
13620     String m_transferMode;               // BearerCaps: Transfer mode
13621     String m_transferRate;               // BearerCaps: Transfer rate
13622     String m_format;                     // BearerCaps: Layer 1 protocol
13623     String m_reason;                     // Cause
13624     String m_keypad;                     // Keypad: 'keypad' parameter
13625     String m_progress;                   // Progress: Progress description
13626     String m_notification;               // Notify: Notification indicator
13627     bool m_bri;                          // ChannelID: BRI interface flag
13628     bool m_channelMandatory;             // ChannelID: Indicated channel is mandatory/preferred
13629     bool m_channelByNumber;              // ChannelID: m_channels contains a channel list or a slot map
13630     String m_channelType;                // ChannelID: Channel type
13631     String m_channelSelect;              // ChannelID: Channel select
13632     String m_channels;                   // ChannelID: Channel list or slot map
13633     String m_restart;                    // Restart: The class of restarting circuits
13634 };
13635 
13640 class YSIG_API ISDNQ931State
13641 {
13642 public:
13646     enum State {
13647         // Common state
13648         Null                    = 0x00,  // Null
13649         // Call states
13650         CallInitiated           = 0x01,  // Call initiated: sent SETUP
13651         OverlapSend             = 0x02,  // Overlap sending
13652         OutgoingProceeding      = 0x03,  // Outgoing call proceeding: received valid CALL PROCEEDING
13653         CallDelivered           = 0x04,  // Call delivered: received valid ALERTING
13654         CallPresent             = 0x06,  // Call present: received valid SETUP or recover from STATUS
13655         CallReceived            = 0x07,  // Call received: sent ALERTING or recover from STATUS
13656         ConnectReq              = 0x08,  // Connect request: sent/received valid CONNECT or recover from STATUS
13657         IncomingProceeding      = 0x09,  // Incoming call proceeding: sent CALL PROCEEDING or recover from STATUS
13658         Active                  = 0x0a,  // Active: sent/received valid CONNECT ACK
13659         DisconnectReq           = 0x0b,  // Disconnect request: sent DISCONNECT
13660         DisconnectIndication    = 0x0c,  // Disconnect indication: received valid DISCONNECT
13661         SuspendReq              = 0x0f,  // Suspend request
13662         ResumeReq               = 0x11,  // Resume reques
13663         ReleaseReq              = 0x13,  // Release request: sent/received valid RELEASE
13664         CallAbort               = 0x16,  // Call abort: received STATUS in Null state with remote not in Null state
13665         OverlapRecv             = 0x19,  // Overlap receiving
13666         // Call controller states
13667         RestartReq              = 0x3d,  // Restart request
13668         Restart                 = 0x3e,  // Restart
13669     };
13670 
13674    inline ISDNQ931State() : m_state(Null)
13675         { }
13676 
13681     inline State state() const
13682         { return m_state; }
13683 
13689     static const char* stateName(u_int8_t s)
13690         { return lookup(s,s_states,0); }
13691 
13695     static const TokenDict s_states[];
13696 
13697 protected:
13704     bool checkStateRecv(int type, bool* retrans);
13705 
13711     bool checkStateSend(int type);
13712 
13716     State m_state;
13717 
13718 };
13719 
13724 class YSIG_API ISDNQ931Call : public ISDNQ931State, public SignallingCall
13725 {
13726     friend class ISDNQ931;
13727 public:
13731     virtual ~ISDNQ931Call();
13732 
13737     inline u_int32_t callRef() const
13738         { return m_callRef; }
13739 
13744     inline u_int32_t callRefLen() const
13745         { return m_callRefLen; }
13746 
13751     inline u_int8_t callTei() const
13752         { return m_tei; }
13753 
13758     inline SignallingCircuit* circuit()
13759         { return m_circuit; }
13760 
13767     void setTerminate(bool destroy, const char* reason);
13768 
13775     virtual bool sendEvent(SignallingEvent* event);
13776 
13783     virtual SignallingEvent* getEvent(const Time& when);
13784 
13790     void dataLinkState(bool up);
13791 
13797     virtual void* getObject(const String& name) const;
13798 
13799 protected:
13808     ISDNQ931Call(ISDNQ931* controller, bool outgoing, u_int32_t callRef,
13809         u_int8_t callRefLen, u_int8_t tei = 0);
13810 
13819     SignallingEvent* releaseComplete(const char* reason = 0, const char* diag = 0);
13820 
13826     SignallingEvent* getCircuitEvent(const Time& when);
13827 
13828 private:
13829     // Reserve and connect a circuit. Change the reserved one if it must to
13830     bool reserveCircuit();
13831     // Process call when terminate flag is set. Check timeout
13832     // @param msg Optional message extracted from queue
13833     SignallingEvent* processTerminate(ISDNQ931Message* msg = 0);
13834     // Check timer(s)
13835     SignallingEvent* checkTimeout(u_int64_t time);
13836     // Check received messages for valid state
13837     // True to send status if not accepted
13838     bool checkMsgRecv(ISDNQ931Message* msg, bool status);
13839     // Process received messages
13840     // @param msg Valid ISDNQ931Message pointer
13841     SignallingEvent* processMsgAlerting(ISDNQ931Message* msg);
13842     SignallingEvent* processMsgCallProceeding(ISDNQ931Message* msg);
13843     SignallingEvent* processMsgConnect(ISDNQ931Message* msg);
13844     SignallingEvent* processMsgConnectAck(ISDNQ931Message* msg);
13845     SignallingEvent* processMsgDisconnect(ISDNQ931Message* msg);
13846     SignallingEvent* processMsgInfo(ISDNQ931Message* msg);
13847     SignallingEvent* processMsgNotify(ISDNQ931Message* msg);
13848     SignallingEvent* processMsgProgress(ISDNQ931Message* msg);
13849     SignallingEvent* processMsgRelease(ISDNQ931Message* msg);
13850     SignallingEvent* processMsgSetup(ISDNQ931Message* msg);
13851     SignallingEvent* processMsgSetupAck(ISDNQ931Message* msg);
13852     SignallingEvent* processMsgStatus(ISDNQ931Message* msg);
13853     SignallingEvent* processMsgStatusEnquiry(ISDNQ931Message* msg);
13854     // Send message
13855     // @param msg Pointer to SignallingMessage with parameters
13856     bool sendAlerting(SignallingMessage* sigMsg);
13857     bool sendCallProceeding(SignallingMessage* sigMsg);
13858     bool sendConnect(SignallingMessage* sigMsg);
13859     bool sendConnectAck(SignallingMessage* sigMsg);
13860     bool sendDisconnect(SignallingMessage* sigMsg);
13861     bool sendInfo(SignallingMessage* sigMsg);
13862     bool sendProgress(SignallingMessage* sigMsg);
13863     bool sendRelease(const char* reason = 0, SignallingMessage* sigMsg = 0);
13864     bool sendReleaseComplete(const char* reason = 0, const char* diag = 0, u_int8_t tei = 0);
13865     bool sendSetup(SignallingMessage* sigMsg);
13866     bool sendSuspendRej(const char* reason = 0, SignallingMessage* sigMsg = 0);
13867     bool sendSetupAck();
13868     // Errors on processing received messages
13869     // Missing mandatory IE
13870     // @param release True to send release complete and generate a release event
13871     SignallingEvent* errorNoIE(ISDNQ931Message* msg, ISDNQ931IE::Type type, bool release);
13872     SignallingEvent* errorWrongIE(ISDNQ931Message* msg, ISDNQ931IE::Type type, bool release);
13873     // Change call state
13874     void changeState(State newState);
13875     // Remove the call from controller's list
13876     void removeFromController();
13877     // Get the Q931 call controller
13878     inline ISDNQ931* q931();
13879 
13880     // Call data
13881     u_int32_t m_callRef;                 // Call reference
13882     u_int32_t m_callRefLen;              // Call reference length
13883     u_int8_t m_tei;                      // TEI used for the call
13884     SignallingCircuit* m_circuit;        // Circuit reserved for this call
13885     bool m_circuitChange;                // True if circuit changed
13886     bool m_channelIDSent;                // Incoming calls: ChannelID IE already sent
13887     bool m_rspBearerCaps;                // Incoming calls: Send BearerCaps IE in the first response
13888     bool m_inbandAvailable;              // Inband data is available
13889     bool m_net;                          // Flag indicating call is sent by a NT
13890     ISDNQ931IEData m_data;               // Data to process IEs
13891     ObjList m_inMsg;                     // Incoming message queue
13892     bool m_broadcast[127];               // TEIs that answered to PTMP SETUP
13893     // Timers
13894     SignallingTimer m_discTimer;         // T305: sending DISCONNECT
13895     SignallingTimer m_relTimer;          // T308: sending RELEASE
13896     SignallingTimer m_conTimer;          // T313: sending CONNECT
13897     SignallingTimer m_overlapSendTimer;  // T302 for overlapped sending
13898     SignallingTimer m_overlapRecvTimer;  // T304
13899     SignallingTimer m_retransSetupTimer; // T302 for setup retransmission (PTMP)
13900     // Termination
13901     bool m_terminate;                    // Terminate flag: send RELEASE
13902     bool m_destroy;                      // Destroy flag: call releaseComplete()
13903     bool m_destroyed;                    // Call destroyed flag
13904 };
13905 
13910 class YSIG_API ISDNQ931CallMonitor : public ISDNQ931State, public SignallingCall
13911 {
13912     friend class ISDNQ931Monitor;
13913 public:
13917     virtual ~ISDNQ931CallMonitor();
13918 
13923     inline bool netInit() const
13924         { return m_netInit; }
13925 
13932     virtual SignallingEvent* getEvent(const Time& when);
13933 
13939     void setTerminate(const char* reason);
13940 
13946     virtual void* getObject(const String& name) const;
13947 
13948 protected:
13955     ISDNQ931CallMonitor(ISDNQ931Monitor* controller, u_int32_t callRef, bool netInit);
13956 
13963     SignallingEvent* releaseComplete(const char* reason = 0);
13964 
13965 private:
13966     // Get an event from one of the reserved circuits
13967     SignallingEvent* getCircuitEvent(const Time& when);
13968     // Process received setup message
13969     SignallingEvent* processMsgSetup(ISDNQ931Message* msg);
13970     // Process received responses to setup message (Proceeding, Alerting, Connect)
13971     SignallingEvent* processMsgResponse(ISDNQ931Message* msg);
13972     // Process termination messages (Disconnect, Release, Release Complete)
13973     SignallingEvent* processMsgTerminate(ISDNQ931Message* msg);
13974     // Process INFORMATION messages to get tones
13975     SignallingEvent* processMsgInfo(ISDNQ931Message* msg);
13976     // Reserve/release the circuits
13977     bool reserveCircuit();
13978     void releaseCircuit();
13979     // Connect the caller's or called's circuit
13980     bool connectCircuit(bool caller);
13981     // Change call state
13982     void changeState(State newState);
13983     // Remove the call from controller's list
13984     void removeFromController();
13985     // Get the Q931Monitor call controller
13986     inline ISDNQ931Monitor* q931();
13987 
13988     u_int32_t m_callRef;                 // Call reference
13989     SignallingCircuit* m_callerCircuit;  // Circuit reserved for caller
13990     SignallingCircuit* m_calledCircuit;  // Circuit reserved for called
13991     SignallingCircuit* m_eventCircuit;   // Last circuit that generated an event
13992     bool m_netInit;                      // The call initiator is from the network side of the link
13993     bool m_circuitChange;                // True if circuit changed
13994     ISDNQ931IEData m_data;               // Data to process IEs
13995     bool m_terminate;                    // Terminate flag
13996     String m_terminator;                 // The name of the entity that terminated the call
13997     ObjList m_inMsg;                     // Incoming messages queue
13998 };
13999 
14004 class YSIG_API ISDNQ931ParserData
14005 {
14006 public:
14012     ISDNQ931ParserData(const NamedList& params, DebugEnabler* dbg = 0);
14013 
14019     inline bool flag(int mask)
14020         { return (0 != (m_flags & mask)); }
14021 
14022     DebugEnabler* m_dbg;                 // The debug enabler used for output
14023     u_int32_t m_maxMsgLen;               // Maximum length of outgoing messages (or message segments)
14024     int m_flags;                         // The current behaviour flags
14025     int m_flagsOrig;                     // The original behaviour flags
14026     u_int8_t m_maxDisplay;               // Max Display IE size
14027     bool m_allowSegment;                 // True if message segmentation is allowed
14028     u_int8_t m_maxSegments;              // Maximum allowed segments for outgoing messages
14029     bool m_extendedDebug;                // True to fill message/IE buffer
14030 };
14031 
14036 class YSIG_API ISDNQ931 : public SignallingCallControl, public SignallingDumpable, public ISDNLayer3
14037 {
14038     YCLASS(ISDNQ931,ISDNLayer3)
14039     friend class ISDNQ931Call;
14040 public:
14045     enum BehaviourFlags {
14046         // Append the progress indicator 'non-isdn-source' if present when
14047         // sending SETUP. If this flag is not set, the indicator will be
14048         // removed from the message
14049         SendNonIsdnSource = 0x00000001,
14050         // Ignore (don't send) the progress indicator 'non-isdn-destination'
14051         // if present when sending SETUP ACKNOWLEDGE or CONNECT
14052         IgnoreNonIsdnDest = 0x00000002,
14053         // Always set presentation='allowed' and screening='network-provided'
14054         // for Calling Party Number IE
14055         ForcePresNetProv = 0x00000004,
14056         // Translate '3.1khz-audio' transfer capability code 0x10 to/from 0x08
14057         Translate31kAudio = 0x00000008,
14058         // Send only transfer mode and rate when sending the Bearer Capability IE
14059         // with transfer capability 'udi' or 'rdi' (unrestricted/restricted
14060         // digital information)
14061         URDITransferCapsOnly = 0x00000010,
14062         // Don't send Layer 1 capabilities (data format) with the
14063         // Bearer Capability IE when in circuit switch mode
14064         NoLayer1Caps = 0x00000020,
14065         // Don't parse incoming IEs found after a temporary (non-locking) shift
14066         IgnoreNonLockedIE = 0x00000040,
14067         // Don't send the Display IE
14068         // This flag is internally set for EuroIsdnE1 type when the call
14069         // controller is the CPE side of the link
14070         NoDisplayIE = 0x00000080,
14071         // Don't append a charset byte 0xb1 before Display data
14072         NoDisplayCharset = 0x00000100,
14073         // Send a Sending Complete IE even if no overlap dialing
14074         ForceSendComplete = 0x00000200,
14075         // Don't change call state to Active instead of ConnectRequest after
14076         // sending CONNECT. This flag is internally set when the call
14077         // controller is the CPE side of the data link
14078         NoActiveOnConnect = 0x00000400,
14079         // Check the validity of the notification indicator when sending a NOTIFY message
14080         CheckNotifyInd = 0x00000800,
14081     };
14082 
14086     enum SwitchType {
14087         Unknown      = 0,
14088         // Standard Euro ISDN (CTR4, ETSI 300-102)
14089         EuroIsdnE1   = ForceSendComplete|CheckNotifyInd|NoDisplayCharset|URDITransferCapsOnly,
14090         // T1 Euro ISDN variant (ETSI 300-102)
14091         EuroIsdnT1   = ForceSendComplete|CheckNotifyInd,
14092         // National ISDN
14093         NationalIsdn = SendNonIsdnSource,
14094         // DMS 100
14095         Dms100       = ForcePresNetProv|IgnoreNonIsdnDest,
14096         // Lucent 5E
14097         Lucent5e     = IgnoreNonLockedIE,
14098         // AT&T 4ESS
14099         Att4ess      = ForcePresNetProv|IgnoreNonLockedIE|Translate31kAudio|NoLayer1Caps,
14100         // QSIG Switch
14101         QSIG         = NoActiveOnConnect|NoDisplayIE|NoDisplayCharset
14102     };
14103 
14110     ISDNQ931(const NamedList& params, const char* name = 0);
14111 
14116     virtual ~ISDNQ931();
14117 
14123     virtual bool initialize(const NamedList* config);
14124 
14129     virtual const char* statusName() const;
14130 
14135     inline const ISDNLayer2* layer2() const
14136         { return m_q921; }
14137 
14142     inline bool primaryRate() const
14143         { return m_primaryRate; }
14144 
14149     inline bool network() const
14150         { return m_q921 ? m_q921->network() : m_networkHint; }
14151 
14156     inline bool transferModeCircuit() const
14157         { return m_transferModeCircuit; }
14158 
14163     inline ISDNQ931ParserData& parserData()
14164         { return m_parserData; }
14165 
14170     inline const String& numPlan() const
14171         { return m_numPlan; }
14172 
14177     inline const String& numType() const
14178         { return m_numType; }
14179 
14184     inline const String& numPresentation() const
14185         { return m_numPresentation; }
14186 
14191     inline const String& numScreening() const
14192         { return m_numScreening; }
14193 
14198     inline const String& format() const
14199         { return m_format; }
14200 
14208     bool sendMessage(ISDNQ931Message* msg, u_int8_t tei, String* reason = 0);
14209 
14218     virtual void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
14219 
14228     virtual void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
14229 
14236     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2);
14237 
14244     virtual ISDNLayer2* attach(ISDNLayer2* q921);
14245 
14252     SignallingCall* call(SignallingMessage* msg, String& reason);
14253 
14259     bool restart(const char* circuits);
14260 
14270     inline bool sendStatus(ISDNQ931Call* call, const char* cause, u_int8_t tei = 0,
14271         const char* display = 0, const char* diagnostic = 0)
14272     {
14273         return call && sendStatus(cause,call->callRefLen(),call->callRef(),tei,
14274             call->outgoing(),call->state(),display,diagnostic);
14275     }
14276 
14288     inline bool sendRelease(ISDNQ931Call* call, bool release, const char* cause, u_int8_t tei = 0,
14289         const char* diag = 0, const char* display = 0, const char* signal = 0)
14290     {
14291         return call && sendRelease(release,call->callRefLen(),call->callRef(),tei,
14292             call->outgoing(),cause,diag,display,signal);
14293     }
14294 
14300     virtual void cleanup(const char* reason = "offline");
14301 
14308     void setInterval(SignallingTimer& timer, int id);
14309 
14313     void manageTimeout();
14314 
14320     inline void setDebug(bool printMsg, bool extendedDebug)
14321         { m_parserData.m_extendedDebug = m_extendedDebug =
14322             ((m_printMsg = printMsg) && extendedDebug); }
14323 
14327     static const TokenDict s_flags[];
14328 
14332     static const TokenDict s_swType[];
14333 
14334 protected:
14338     virtual void destroyed()
14339     {
14340         TelEngine::destruct(attach(0));
14341         TelEngine::destruct(SignallingCallControl::attach(0));
14342         ISDNLayer3::destroyed();
14343     }
14344 
14350     virtual void timerTick(const Time& when);
14351 
14359     ISDNQ931Call* findCall(u_int32_t callRef, bool outgoing, u_int8_t tei = 0);
14360 
14366     ISDNQ931Call* findCall(unsigned int circuit);
14367 
14373     void terminateCalls(ObjList* list, const char* reason);
14374 
14381     bool acceptNewCall(bool outgoing, String& reason);
14382 
14388     ISDNQ931Message* getMsg(const DataBlock& data);
14389 
14397     ISDNQ931Message* endReceiveSegment(const char* reason = 0);
14398 
14404     void processGlobalMsg(ISDNQ931Message* msg, u_int8_t tei = 0);
14405 
14411     void processMsgRestart(ISDNQ931Message* msg, u_int8_t tei = 0);
14412 
14418     void processInvalidMsg(ISDNQ931Message* msg, u_int8_t tei = 0);
14419 
14427     void sendRestart(u_int64_t time = Time::msecNow(), bool retrans = false);
14428 
14436     void endRestart(bool restart, u_int64_t time, bool timeout = false);
14437 
14450     bool sendStatus(const char* cause, u_int8_t callRefLen, u_int32_t callRef = 0,
14451         u_int8_t tei = 0, bool initiator = false, ISDNQ931Call::State state = ISDNQ931Call::Null,
14452         const char* display = 0, const char* diagnostic = 0);
14453 
14467     bool sendRelease(bool release, u_int8_t callRefLen, u_int32_t callRef, u_int8_t tei,
14468         bool initiator, const char* cause = 0, const char* diag = 0,
14469         const char* display = 0, const char* signal = 0);
14470 
14471 private:
14472     virtual bool control(NamedList& params)
14473         { return SignallingDumpable::control(params,this); }
14474     bool q921Up() const;                 // Check if layer 2 may be up
14475     ISDNLayer2* m_q921;                  // The attached layer 2
14476     bool m_q921Up;                       // Layer 2 state
14477     // Protocol data
14478     bool m_networkHint;                  // NET / CPE hint, layer 2 is authoritative
14479     bool m_primaryRate;                  // Primary/base rate support
14480     bool m_transferModeCircuit;          // Circuit switch/packet mode transfer
14481     u_int32_t m_callRef;                 // Current available call reference for outgoing calls
14482     u_int8_t m_callRefLen;               // Call reference length
14483     u_int32_t m_callRefMask;             // Call reference mask
14484     ISDNQ931ParserData m_parserData;     // Parser settings
14485     ISDNQ931IEData m_data;               // Process IEs
14486     // Timers & counters
14487     SignallingTimer m_l2DownTimer;       // T309: Layer 2 is down timeout
14488     SignallingTimer m_recvSgmTimer;      // T314: Receive segment timeout
14489     SignallingTimer m_syncCicTimer;      // T316: Restart individual circuit timeout
14490     SignallingCounter m_syncCicCounter;  // RESTART retransmission counter
14491     SignallingTimer m_callDiscTimer;     // Q931 call value (see ISDQ931Call)
14492     SignallingTimer m_callRelTimer;      // Q931 call value (see ISDQ931Call)
14493     SignallingTimer m_callConTimer;      // Q931 call value (see ISDQ931Call)
14494     // Default values
14495     String m_numPlan;                    // Numbering plan
14496     String m_numType;                    // Number type
14497     String m_numPresentation;            // Number presentation
14498     String m_numScreening;               // Number screening
14499     String m_format;                     // Data format
14500     String m_cpeNumber;                  // The number of the BRI CPE
14501     // Restart data
14502     SignallingCircuit* m_restartCic;     // Currently restarting circuit
14503     unsigned int m_lastRestart;          // Last restarted circuit's code
14504     SignallingTimer m_syncGroupTimer;    // Restarting circuit group interval
14505     // Message segmentation data
14506     DataBlock m_segmentData;             // Message segments buffer
14507     ISDNQ931Message* m_segmented;        // Segmented message
14508     u_int8_t m_remaining;                // Remaining segments
14509     // Debug
14510     bool m_printMsg;                     // True to print messages to output
14511     bool m_extendedDebug;                // Extended debug flag
14512     // Flags used to print error messages
14513     bool m_flagQ921Down;                 // Layer 2 is down period timed out
14514     bool m_flagQ921Invalid;              // Refusing to send message when Layer 2 is missing or down
14515 };
14516 
14521 class YSIG_API ISDNQ931Monitor : public SignallingCallControl, public ISDNLayer3
14522 {
14523     YCLASS(ISDNQ931Monitor,ISDNLayer3)
14524     friend class ISDNQ931CallMonitor;
14525 public:
14532     ISDNQ931Monitor(const NamedList& params, const char* name = 0);
14533 
14538     virtual ~ISDNQ931Monitor();
14539 
14545     virtual bool initialize(const NamedList* config);
14546 
14551     virtual const char* statusName() const;
14552 
14563     virtual void dataLinkState(u_int8_t tei, bool cmd, bool value, ISDNLayer2* layer2);
14564 
14569     virtual void idleTimeout(ISDNLayer2* layer2);
14570 
14577     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2);
14578 
14586     virtual ISDNQ921Passive* attach(ISDNQ921Passive* q921, bool net);
14587 
14595     virtual SignallingCircuitGroup* attach(SignallingCircuitGroup* circuits, bool net);
14596 
14602     inline ISDNQ921Passive* circuits(bool net) const
14603         { return net ? m_q921Net : m_q921Cpe; }
14604 
14610     inline void setDebug(bool printMsg, bool extendedDebug)
14611         { m_parserData.m_extendedDebug = m_extendedDebug =
14612             ((m_printMsg = printMsg) && extendedDebug); }
14613 
14619     virtual void cleanup(const char* reason = "offline")
14620         { terminateMonitor(0,reason); }
14621 
14628     void terminateMonitor(ISDNQ931CallMonitor* mon, const char* reason);
14629 
14630 protected:
14634     virtual void destroyed()
14635     {
14636         TelEngine::destruct(SignallingCallControl::attach(0));
14637         TelEngine::destruct(attach((ISDNQ921Passive*)0,true));
14638         TelEngine::destruct(attach((ISDNQ921Passive*)0,false));
14639         attach((SignallingCircuitGroup*)0,true);
14640         attach((SignallingCircuitGroup*)0,false);
14641         ISDNLayer3::destroyed();
14642     }
14643 
14649     virtual void timerTick(const Time& when);
14650 
14662     bool reserveCircuit(unsigned int code, bool netInit,
14663         SignallingCircuit** caller, SignallingCircuit** called);
14664 
14671     bool releaseCircuit(SignallingCircuit* circuit);
14672 
14678     void processMsgRestart(ISDNQ931Message* msg);
14679 
14680 private:
14681     // Find a call monitor by call reference or reserved circuit
14682     // @return Referenced call monitor pointer or 0 if not found
14683     ISDNQ931CallMonitor* findMonitor(unsigned int value, bool byCallRef);
14684     // Drop some messages. Return true if the message should be dropped
14685     bool dropMessage(const ISDNQ931Message* msg);
14686 
14687     ISDNQ921Passive* m_q921Net;          // Net side of the link
14688     ISDNQ921Passive* m_q921Cpe;          // CPE side of the link
14689     SignallingCircuitGroup* m_cicNet;    // Circuit group for the net side of the link
14690     SignallingCircuitGroup* m_cicCpe;    // Circuit group for the cpe side of the link
14691     ISDNQ931ParserData m_parserData;     // Parser settings
14692     ISDNQ931IEData m_data;               // Process IEs
14693     // Debug
14694     bool m_printMsg;                     // True to print messages to output
14695     bool m_extendedDebug;                // Extended debug flag
14696 };
14697 
14698 }
14699 
14700 #endif /* __YATESIG_H */
14701 
14702 /* vi: set ts=8 sw=4 sts=4 noet: */