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 SignallingTimer;                   // A signalling timer
00055 class SignallingCounter;                 // A signalling counter
00056 class SignallingFactory;                 // A signalling component factory
00057 class SignallingComponent;               // Abstract signalling component that can be managed by the engine
00058 class SignallingEngine;                  // Main signalling component holder
00059 class SignallingThreadPrivate;           // Engine private thread
00060 class SignallingMessage;                 // Abstract signalling message
00061 class SignallingCallControl;             // Abstract phone call signalling
00062 class SignallingCall;                    // Abstract single phone call
00063 class SignallingEvent;                   // A single signalling related event
00064 class SignallingCircuitEvent;            // A single signalling circuit related event
00065 class SignallingCircuit;                 // Abstract data circuit used by signalling
00066 class SignallingCircuitRange;            // A circuit range (set of circuits)
00067 class SignallingCircuitGroup;            // Group of data circuits used by signalling
00068 class SignallingCircuitSpan;             // A span in a circuit group
00069 class SignallingInterface;               // Abstract digital signalling interface (hardware access)
00070 class SignallingReceiver;                // Abstract Layer 2 packet data receiver
00071 struct SignallingFlags;                  // Description of parameter flags
00072 class SignallingUtils;                   // Library wide services and data provider
00073 // Analog lines
00074 class AnalogLine;                        // An analog line
00075 class AnalogLineEvent;                   // A single analog line related event
00076 class AnalogLineGroup;                   // A group of analog lines
00077 // SS7
00078 class SS7PointCode;                      // SS7 Code Point
00079 class SS7Label;                          // SS7 Routing Label
00080 class SS7MSU;                            // A block of data that holds a Message Signal Unit
00081 class SIGTRAN;                           // Abstract SIGTRAN component
00082 class SIGTransport;                      // Abstract transport for SIGTRAN
00083 class ASPUser;                           // Abstract SS7 ASP user interface
00084 class SCCP;                              // Abstract SS7 SCCP interface
00085 class SCCPUser;                          // Abstract SS7 SCCP user interface
00086 class TCAPUser;                          // Abstract SS7 TCAP user interface
00087 class SS7L2User;                         // Abstract user of SS7 layer 2 (data link) message transfer part
00088 class SS7Layer2;                         // Abstract SS7 layer 2 (data link) message transfer part
00089 class SS7L3User;                         // Abstract user of SS7 layer 3 (network) message transfer part
00090 class SS7Layer3;                         // Abstract SS7 layer 3 (network) message transfer part
00091 class SS7Layer4;                         // Abstract SS7 layer 4 (application) protocol
00092 class SS7Route;                          // A SS7 MSU route
00093 class SS7Router;                         // Main router for SS7 message transfer and applications
00094 class SS7M2PA;                           // SIGTRAN MTP2 User Peer-to-Peer Adaptation Layer
00095 class SS7M2UA;                           // SIGTRAN MTP2 User Adaptation Layer
00096 class SS7M3UA;                           // SIGTRAN MTP3 User Adaptation Layer
00097 class SS7MTP2;                           // SS7 Layer 2 implementation on top of a hardware interface
00098 class SS7MTP3;                           // SS7 Layer 3 implementation on top of Layer 2
00099 class SS7MsgSNM;                         // SNM signalling message
00100 class SS7MsgMTN;                         // MTN signalling message
00101 class SS7MsgISUP;                        // ISUP signalling message
00102 class SS7Management;                     // SS7 SNM implementation
00103 class SS7Maintenance;                    // SS7 MTN implementation
00104 class SS7ISUPCall;                       // A SS7 ISUP call
00105 class SS7ISUP;                           // SS7 ISUP implementation
00106 class SS7BICC;                           // SS7 BICC implementation
00107 class SS7TUP;                            // SS7 TUP implementation
00108 class SS7SCCP;                           // SS7 SCCP implementation
00109 class SS7SUA;                            // SIGTRAN SCCP User Adaptation Layer
00110 class SS7ASP;                            // SS7 ASP implementation
00111 class SS7TCAP;                           // SS7 TCAP implementation
00112 // ISDN
00113 class ISDNLayer2;                        // Abstract ISDN layer 2 (Q.921) message transport
00114 class ISDNLayer3;                        // Abstract ISDN layer 3 (Q.931) message transport
00115 class ISDNFrame;                         // An ISDN Q.921 frame
00116 class ISDNQ921;                          // ISDN Q.921 implementation on top of a hardware interface
00117 class ISDNQ921Passive;                   // Stateless ISDN Q.921 implementation on top of a hardware interface
00118 class ISDNQ921Management;                // ISDN Layer 2 BRI TEI management or PRI with D-channel(s) backup
00119 class ISDNIUA;                           // SIGTRAN ISDN Q.921 User Adaptation Layer
00120 class ISDNQ931IE;                        // A Q.931 ISDN Layer 3 message Information Element
00121 class ISDNQ931Message;                   // A Q.931 ISDN Layer 3 message
00122 class ISDNQ931IEData;                    // A Q.931 message IE data processor
00123 class ISDNQ931State;                     // Q.931 ISDN call and call controller state
00124 class ISDNQ931Call;                      // A Q.931 ISDN call
00125 class ISDNQ931CallMonitor;               // A Q.931 ISDN call monitor
00126 class ISDNQ931ParserData;                // Q.931 message parser data
00127 class ISDNQ931;                          // ISDN Q.931 implementation on top of Q.921
00128 class ISDNQ931Monitor;                   // ISDN Q.931 implementation on top of Q.921 of call controller monitor
00129 
00130 // Macro to create a factory that builds a component by class name
00131 #define YSIGFACTORY(clas) \
00132 class clas ## Factory : public SignallingFactory \
00133 { \
00134 protected: \
00135 virtual SignallingComponent* create(const String& type, const NamedList& name) \
00136     { return (type == #clas) ? new clas : 0; } \
00137 }; \
00138 static clas ## Factory s_ ## clas ## Factory
00139 
00140 // Macro to create a factory that calls a component's static create method
00141 #define YSIGFACTORY2(clas) \
00142 class clas ## Factory : public SignallingFactory \
00143 { \
00144 protected: \
00145 virtual SignallingComponent* create(const String& type, const NamedList& name) \
00146     { return clas::create(type,name); } \
00147 }; \
00148 static clas ## Factory s_ ## clas ## Factory
00149 
00150 // Macro to call the factory creation method and return the created component
00151 #define YSIGCREATE(type,name) (static_cast<type*>(SignallingFactory::buildInternal(#type,name)))
00152 
00157 class YSIG_API SignallingDumper
00158 {
00159 public:
00163     enum Type {
00164         Raw,
00165         Hexa,
00166         Hdlc,
00167         Q921,
00168         Q931,
00169         Mtp2,
00170         Mtp3,
00171         Sccp,
00172     };
00173 
00179     SignallingDumper(Type type = Hexa, bool network = false);
00180 
00184     ~SignallingDumper();
00185 
00190     inline Type type() const
00191         { return m_type; }
00192 
00197     inline bool network() const
00198         { return m_network; }
00199 
00204     bool active() const;
00205 
00209     void terminate();
00210 
00216     void setStream(Stream* stream = 0, bool writeHeader = true);
00217 
00226     bool dump(void* buf, unsigned int len, bool sent = false, int link = 0);
00227 
00235     inline bool dump(const DataBlock& data, bool sent = false, int link = 0)
00236         { return dump(data.data(),data.length(),sent,link); }
00237 
00248     static SignallingDumper* create(DebugEnabler* dbg, const char* filename, Type type,
00249         bool network = false, bool create = true, bool append = false);
00250 
00259     static SignallingDumper* create(Stream* stream, Type type, bool network = false, bool writeHeader = true);
00260 
00261 private:
00262     void head();
00263     Type m_type;
00264     bool m_network;
00265     Stream* m_output;
00266 };
00267 
00272 class YSIG_API SignallingDumpable
00273 {
00274 public:
00278     inline ~SignallingDumpable()
00279         { setDumper(); }
00280 
00281 protected:
00287     inline SignallingDumpable(SignallingDumper::Type type, bool network = false)
00288         : m_type(type), m_dumpNet(network), m_dumper(0)
00289         { }
00290 
00299     inline bool dump(void* buf, unsigned int len, bool sent = false, int link = 0)
00300         { return (m_dumper && m_dumper->dump(buf,len,sent,link)); }
00301 
00309     inline bool dump(const DataBlock& data, bool sent = false, int link = 0)
00310         { return dump(data.data(),data.length(),sent,link); }
00311 
00316     inline void setDumpNetwork(bool network)
00317         { m_dumpNet = network; }
00318 
00323     void setDumper(SignallingDumper* dumper = 0);
00324 
00332     bool setDumper(const String& name, bool create = true, bool append = false);
00333 
00340     bool control(NamedList& params, SignallingComponent* owner = 0);
00341 
00342 private:
00343     SignallingDumper::Type m_type;
00344     bool m_dumpNet;
00345     SignallingDumper* m_dumper;
00346 };
00347 
00352 class YSIG_API SignallingTimer
00353 {
00354 public:
00360     inline SignallingTimer(u_int64_t interval, u_int64_t time = 0)
00361         : m_interval(interval), m_timeout(0)
00362         { if (time) start(time); }
00363 
00368     inline void interval(u_int64_t value)
00369         { m_interval = value; }
00370 
00381     inline void interval(const NamedList& params, const char* param,
00382         unsigned int minVal, unsigned int defVal, bool allowDisable, bool sec = false)
00383     {
00384         m_interval = (u_int64_t)params.getIntValue(param,defVal);
00385         if (m_interval) {
00386             if (m_interval < minVal)
00387                 m_interval = minVal;
00388         }
00389         else if (!allowDisable)
00390             m_interval = minVal;
00391         if (sec)
00392             m_interval *= 1000;
00393     }
00394 
00399     inline u_int64_t interval() const
00400         { return m_interval; }
00401 
00406     inline void start(u_int64_t time = Time::msecNow())
00407         { if (m_interval) m_timeout = time + m_interval; }
00408 
00412     inline void stop()
00413         { m_timeout = 0; }
00414 
00419     inline bool started()
00420         { return m_timeout > 0; }
00421 
00427     inline bool timeout(u_int64_t time = Time::msecNow())
00428         { return started() && (m_timeout < time); }
00429 
00430 private:
00431     u_int64_t m_interval;                // Timer interval
00432     u_int64_t m_timeout;                 // Timeout value
00433 };
00434 
00439 class YSIG_API SignallingCounter
00440 {
00441 public:
00446     inline SignallingCounter(u_int32_t maxVal)
00447         : m_max(maxVal), m_count(0)
00448         { }
00449 
00454     inline void maxVal(u_int32_t value)
00455         { m_max = value; }
00456 
00461     inline u_int32_t maxVal() const
00462         { return m_max; }
00463 
00468     inline u_int32_t count() const
00469         { return m_count; }
00470 
00475     inline void reset(bool down = true)
00476         { m_count = down ? 0 : m_max; }
00477 
00482     inline bool inc()
00483     {
00484         if (full())
00485             return false;
00486         m_count++;
00487         return true;
00488     }
00489 
00494     inline bool dec()
00495     {
00496         if (empty())
00497             return false;
00498         m_count--;
00499         return true;
00500     }
00501 
00506     inline bool empty() const
00507         { return m_count == 0; }
00508 
00513     inline bool full() const
00514         { return m_count == maxVal(); }
00515 
00516 private:
00517     u_int32_t m_max;                     // Maximum counter value
00518     u_int32_t m_count;                   // Current counter value
00519 };
00520 
00525 class YSIG_API SignallingFactory : public GenObject
00526 {
00527 public:
00532     SignallingFactory(bool fallback = false);
00533 
00537     virtual ~SignallingFactory();
00538 
00545     static SignallingComponent* build(const String& type, const NamedList* name = 0);
00546 
00553     static void* buildInternal(const String& type, const NamedList* name);
00554 
00555 protected:
00562     virtual SignallingComponent* create(const String& type, const NamedList& name) = 0;
00563 };
00564 
00570 class YSIG_API SignallingComponent : public RefObject, public DebugEnabler
00571 {
00572     YCLASS(SignallingComponent,RefObject)
00573     friend class SignallingEngine;
00574 public:
00578     virtual ~SignallingComponent();
00579 
00584     virtual const String& toString() const;
00585 
00591     virtual bool initialize(const NamedList* config);
00592 
00598     virtual bool control(NamedList& params);
00599 
00605     virtual void engine(SignallingEngine* eng);
00606 
00611     inline SignallingEngine* engine() const
00612         { return m_engine; }
00613 
00619     inline int debugLevel(int level)
00620         { return (level >= 0) ? DebugEnabler::debugLevel(level) : DebugEnabler::debugLevel(); }
00621 
00622 protected:
00628     SignallingComponent(const char* name = 0, const NamedList* params = 0);
00629 
00634     void destroyed();
00635 
00641     void insert(SignallingComponent* component);
00642 
00649     virtual void detach();
00650 
00655     virtual void timerTick(const Time& when);
00656 
00661     void setName(const char* name);
00662 
00669     unsigned long tickSleep(unsigned long usec = 1000000) const;
00670 
00671 private:
00672     SignallingEngine* m_engine;
00673     String m_name;
00674 };
00675 
00681 class YSIG_API SignallingEngine : public DebugEnabler, public Mutex
00682 {
00683     friend class SignallingComponent;
00684     friend class SignallingThreadPrivate;
00685 public:
00690     SignallingEngine(const char* name = "signalling");
00691 
00695     virtual ~SignallingEngine();
00696 
00701     void insert(SignallingComponent* component);
00702 
00707     void remove(SignallingComponent* component);
00708 
00714     bool remove(const String& name);
00715 
00721     SignallingComponent* find(const String& name);
00722 
00730     SignallingComponent* find(const String& name, const String& type, const SignallingComponent* start = 0);
00731 
00739     SignallingComponent* build(const String& type, const NamedList& params, bool init = false);
00740 
00746     bool control(NamedList& params);
00747 
00753     bool find(const SignallingComponent* component);
00754 
00762     bool start(const char* name = "Sig Engine", Thread::Priority prio = Thread::Normal, unsigned long usec = 0);
00763 
00767     void stop();
00768 
00773     Thread* thread() const;
00774 
00781     unsigned long tickSleep(unsigned long usec = 1000000);
00782 
00787     inline unsigned long tickDefault() const
00788         { return m_usecSleep; }
00789 
00795     template <class Obj> static inline void destruct(Obj*& obj)
00796     {
00797         if (!obj)
00798             return;
00799         if (obj->engine())
00800             obj->engine()->remove(obj);
00801         TelEngine::destruct(obj);
00802     }
00803 
00804 protected:
00810     virtual unsigned long timerTick(const Time& when);
00811 
00815     ObjList m_components;
00816 
00817 private:
00818     SignallingThreadPrivate* m_thread;
00819     bool m_listChanged;
00820     unsigned long m_usecSleep;
00821     unsigned long m_tickSleep;
00822 };
00823 
00828 class YSIG_API SignallingMessage : public RefObject
00829 {
00830     YCLASS(SignallingMessage,RefObject)
00831 public:
00836     inline SignallingMessage(const char* name = 0)
00837         : m_params(name)
00838         { }
00839 
00844     inline const char* name() const
00845         { return m_params.c_str(); }
00846 
00851     inline NamedList& params()
00852         { return m_params; }
00853 
00854 protected:
00858     NamedList m_params;
00859 };
00860 
00865 class YSIG_API SignallingCallControl : public Mutex
00866 {
00867     friend class SignallingCall;
00868     friend class SS7ISUPCall;
00869     friend class ISDNQ931Call;
00870     friend class ISDNQ931CallMonitor;
00871 public:
00878     SignallingCallControl(const NamedList& params, const char* msgPrefix = 0);
00879 
00883     virtual ~SignallingCallControl();
00884 
00888     inline void setExiting()
00889         { m_exiting = true; }
00890 
00895     inline bool exiting() const
00896         { return m_exiting; }
00897 
00902     inline bool verify()
00903     {
00904         Lock lock(this);
00905         if (!m_verifyEvent)
00906             return false;
00907         m_verifyEvent = false;
00908         return true;
00909     }
00910 
00916     inline const String& msgPrefix() const
00917         { return m_msgPrefix; }
00918 
00923     inline SignallingCircuitGroup* circuits() const
00924         { return m_circuits; }
00925 
00930     inline const ObjList& calls() const
00931         { return m_calls; }
00932 
00941     SignallingCircuitGroup* attach(SignallingCircuitGroup* circuits);
00942 
00959     bool reserveCircuit(SignallingCircuit*& cic, const char* range = 0, int checkLock = -1,
00960         const String* list = 0, bool mandatory = true, bool reverseRestrict = false);
00961 
00969     bool releaseCircuit(SignallingCircuit*& cic, bool sync = false);
00970 
00978     bool releaseCircuit(unsigned int code, bool sync = false);
00979 
00984     virtual void cleanup(const char* reason = "offline")
00985         { }
00986 
00992     virtual SignallingEvent* getEvent(const Time& when);
00993 
01000     virtual SignallingCall* call(SignallingMessage* msg, String& reason)
01001         { reason = "not-implemented"; return 0; }
01002 
01007     virtual void buildVerifyEvent(NamedList& params)
01008         { }
01009 
01010 protected:
01015     inline int strategy() const
01016         { return m_strategy; }
01017 
01025     virtual bool processEvent(SignallingEvent* event)
01026         { return false; }
01027 
01034     virtual SignallingEvent* processCircuitEvent(SignallingCircuitEvent*& event,
01035         SignallingCall* call = 0)
01036         { TelEngine::destruct(event); return 0; }
01037 
01041     void clearCalls();
01042 
01048     void removeCall(SignallingCall* call, bool del = false);
01049 
01053     ObjList m_calls;
01054 
01059     String m_msgPrefix;
01060 
01065     bool m_verifyEvent;
01066 
01070     SignallingTimer m_verifyTimer;
01071 
01072 private:
01073     SignallingCircuitGroup* m_circuits;  // Circuit group
01074     int m_strategy;                      // Strategy to allocate circuits for outgoing calls
01075     bool m_exiting;                      // Call control is terminating. Generate a Disable event when no more calls
01076 };
01077 
01082 class YSIG_API SignallingCall : public RefObject, public Mutex
01083 {
01084 public:
01091     SignallingCall(SignallingCallControl* controller, bool outgoing, bool signalOnly = false);
01092 
01096     virtual ~SignallingCall();
01097 
01102     inline bool outgoing() const
01103         { return m_outgoing; }
01104 
01108     inline SignallingCallControl* controller() const
01109         { return m_controller; }
01110 
01115     inline void userdata(void* data)
01116         { m_private = data; }
01117 
01122     inline void* userdata() const
01123         { return m_private; }
01124 
01129     inline bool signalOnly() const
01130         { return m_signalOnly; }
01131 
01137     virtual bool sendEvent(SignallingEvent* event)
01138         { return false; }
01139 
01146     virtual SignallingEvent* getEvent(const Time& when) = 0;
01147 
01154     virtual void eventTerminated(SignallingEvent* event);
01155 
01156 protected:
01162     void enqueue(SignallingMessage* msg);
01163 
01170     SignallingMessage* dequeue(bool remove = true);
01171 
01175     void clearQueue()
01176     {
01177         Lock lock(m_inMsgMutex);
01178         m_inMsg.clear();
01179     }
01180 
01184     SignallingEvent* m_lastEvent;
01185 
01186 private:
01187     SignallingCallControl* m_controller; // Call controller this call belongs to
01188     bool m_outgoing;                     // Call direction
01189     bool m_signalOnly;                   // Just signalling flag
01190     ObjList m_inMsg;                     // Incoming messages queue
01191     Mutex m_inMsgMutex;                  // Lock incoming messages queue
01192     void* m_private;                     // Private user data
01193 };
01194 
01199 class YSIG_API SignallingEvent
01200 {
01201 public:
01205     enum Type {
01206         Unknown = 0,
01207         Generic,
01208         // Call related
01209         NewCall,
01210         Accept,
01211         Connect,
01212         Complete,
01213         Progress,
01214         Ringing,
01215         Answer,
01216         Transfer,
01217         Suspend,
01218         Resume,
01219         Release,
01220         Info,
01221         // Non-call related
01222         Message,
01223         Facility,
01224         Circuit,
01225         // Controller related
01226         Enable,
01227         Disable,
01228         Reset,
01229         Verify,
01230     };
01231 
01238     SignallingEvent(Type type, SignallingMessage* message, SignallingCall* call);
01239 
01246     SignallingEvent(Type type, SignallingMessage* message, SignallingCallControl* controller = 0);
01247 
01253     SignallingEvent(SignallingCircuitEvent*& event, SignallingCall* call);
01254 
01258     virtual ~SignallingEvent();
01259 
01264     inline const char* name() const
01265         { return typeName(type()); }
01266 
01271     inline Type type() const
01272         { return m_type; }
01273 
01277     inline SignallingCall* call() const
01278         { return m_call; }
01279 
01283     inline SignallingMessage* message() const
01284         { return m_message; }
01285 
01289     inline SignallingCallControl* controller() const
01290         { return m_controller; }
01291 
01295     inline SignallingCircuitEvent* cicEvent() const
01296         { return m_cicEvent; }
01297 
01303     static inline const char* typeName(Type t)
01304         { return lookup(t,s_types,0); }
01305 
01310     bool sendEvent();
01311 
01312 private:
01313     Type m_type;
01314     SignallingMessage* m_message;
01315     SignallingCall* m_call;
01316     SignallingCallControl* m_controller;
01317     SignallingCircuitEvent* m_cicEvent;
01318     static TokenDict s_types[];
01319 };
01320 
01325 class YSIG_API SignallingCircuitEvent : public NamedList
01326 {
01327 public:
01331     enum Type {
01332         Unknown      = 0,
01333         Dtmf         = 1,                // Transfer tones: param: tone
01334         // Analog line events
01335         Timeout      = 10,               // 
01336         Polarity     = 11,               // Line's polarity changed
01337         StartLine    = 15,               // Initialize FXO line
01338         LineStarted  = 16,               // FXO line initialized: send number
01339         DialComplete = 17,               // FXO line completed dialing the number
01340         OnHook       = 20,               // The hook is down
01341         OffHook      = 21,               // The hook is up
01342         RingBegin    = 22,               // Start ringing
01343         RingEnd      = 23,               // Stop ringing
01344         RingerOn     = 30,               // An FXS started the FXO's ringer
01345         RingerOff    = 31,               // An FXS stopped the FXO's ringer
01346         Wink         = 32,               // On hook momentarily
01347         Flash        = 33,               // Off hook momentarily
01348         PulseStart   = 40,               // Pulse dialing start
01349         PulseDigit   = 41,               // Transfer pulse digits: param: pulse
01350         // Remote circuit events
01351         Connect      = 50,               // Request connect
01352         Disconnect   = 51,               // Request disconnect
01353         Connected    = 52,               // Connected notification
01354         Disconnected = 53,               // Disconnected notification
01355         // Errors
01356         Alarm        = 100,              // Param: alarms (comma separated list of strings)
01357         NoAlarm      = 101,              // No more alarms
01358     };
01359 
01366     SignallingCircuitEvent(SignallingCircuit* cic, Type type, const char* name = 0);
01367 
01371     virtual ~SignallingCircuitEvent();
01372 
01377     inline Type type() const
01378         { return m_type; }
01379 
01384     inline SignallingCircuit* circuit()
01385         { return m_circuit; }
01386 
01391     bool sendEvent();
01392 
01393 private:
01394     SignallingCircuit* m_circuit;
01395     Type m_type;
01396 };
01397 
01402 class YSIG_API SignallingCircuit : public RefObject
01403 {
01404     YCLASS(SignallingCircuit,RefObject)
01405     friend class SignallingCircuitGroup;
01406     friend class SignallingCircuitEvent;
01407 public:
01411     enum Type {
01412         Unknown = 0,
01413         Local, // not really a circuit
01414         TDM,
01415         RTP,
01416         IAX,
01417     };
01418 
01422     enum Status {
01423         Missing = 0,
01424         Disabled,
01425         Idle,
01426         Reserved,
01427         Starting,
01428         Stopping,
01429         Connected,
01430     };
01431 
01435     enum LockFlags {
01436         LockLocalHWFail       = 0x0001,  // Local side of the circuit is locked due to HW failure
01437         LockLocalMaint        = 0x0002,  // Local side of the circuit is locked for maintenance
01438         LockLocalHWFailChg    = 0x0010,  // Local HW failure flag changed
01439         LockLocalMaintChg     = 0x0020,  // Local maintenance flag changed
01440         LockRemoteHWFail      = 0x0100,  // Remote side of the circuit is locked due to HW failure
01441         LockRemoteMaint       = 0x0200,  // Remote side of the circuit is locked for maintenance
01442         LockRemoteHWFailChg   = 0x1000,  // Remote HW failure flag changed
01443         LockRemoteMaintChg    = 0x2000,  // Remote maintenance flag changed
01444         // Masks used to test lock conditions
01445         LockLocal             = LockLocalHWFail | LockLocalMaint,
01446         LockRemote            = LockRemoteHWFail | LockRemoteMaint,
01447         LockLocked            = LockLocal | LockRemote,
01448         LockLocalChg          = LockLocalHWFailChg | LockLocalMaintChg,
01449         LockRemoteChg         = LockRemoteHWFailChg | LockRemoteMaintChg,
01450         LockChanged           = LockLocalChg | LockRemoteChg,
01451     };
01452 
01456     virtual ~SignallingCircuit();
01457 
01464     virtual bool status(Status newStat, bool sync = false)
01465         { m_status = newStat; return true; }
01466 
01471     inline Type type() const
01472         { return m_type; }
01473 
01478     inline Status status() const
01479         { return m_status; }
01480 
01486     inline int locked(int flags = -1) const
01487         { return (m_lock & flags); }
01488 
01493     inline void setLock(int flags)
01494         { m_lock |= flags; }
01495 
01500     inline void resetLock(int flags)
01501         { m_lock &= ~flags; }
01502 
01509     virtual bool updateFormat(const char* format, int direction)
01510         { return false; }
01511 
01518     virtual bool setParam(const String& param, const String& value)
01519         { return false; }
01520 
01526     virtual bool setParams(const NamedList& params);
01527 
01534     virtual bool getParam(const String& param, String& value) const
01535         { return false; }
01536 
01543     virtual bool getBoolParam(const String& param, bool defValue = false) const
01544         { return defValue; }
01545 
01552     virtual int getIntParam(const String& param, int defValue = 0) const
01553         { return defValue; }
01554 
01561     virtual bool getParams(NamedList& params, const String& category = String::empty())
01562         { return false; }
01563 
01568     inline SignallingCircuitGroup* group()
01569         { return m_group; }
01570 
01575     inline SignallingCircuitSpan* span()
01576         { return m_span; }
01577 
01582     inline const SignallingCircuitGroup* group() const
01583         { return m_group; }
01584 
01589     inline const SignallingCircuitSpan* span() const
01590         { return m_span; }
01591 
01596     inline unsigned int code() const
01597         { return m_code; }
01598 
01603     inline bool available() const
01604         { return m_status == Idle; }
01605 
01610     inline bool connected() const
01611         { return m_status == Connected; }
01612 
01617     inline bool reserve()
01618         { return available() && status(Reserved,true); }
01619 
01625     inline bool connect(const char* format = 0)
01626         { updateFormat(format,0); return status(Connected,true); }
01627 
01632     inline bool disconnect()
01633         { return status() == Connected && status(Reserved,true); }
01634 
01639     inline bool disable()
01640         { return status(Disabled,true); }
01641 
01650     bool hwLock(bool set, bool remote, bool changed = false, bool setChanged = false);
01651 
01660     bool maintLock(bool set, bool remote, bool changed = false, bool setChanged = false);
01661 
01667     void addEvent(SignallingCircuitEvent* event);
01668 
01675     SignallingCircuitEvent* getEvent(const Time& when);
01676 
01683     virtual bool sendEvent(SignallingCircuitEvent::Type type, NamedList* params = 0);
01684 
01690     static const char* lookupType(int type);
01691 
01697     static const char* lookupStatus(int status);
01698 
01702     static TokenDict s_lockNames[];
01703 
01704 protected:
01708     SignallingCircuit(Type type, unsigned int code, SignallingCircuitGroup* group = 0,
01709         SignallingCircuitSpan* span = 0);
01710 
01714     SignallingCircuit(Type type, unsigned int code, Status status,
01715         SignallingCircuitGroup* group = 0, SignallingCircuitSpan* span = 0);
01716 
01721     virtual void clearEvents();
01722 
01727     void eventTerminated(SignallingCircuitEvent* event);
01728 
01732     Mutex m_mutex;
01733 
01734 private:
01735     SignallingCircuitGroup* m_group;     // The group owning this circuit
01736     SignallingCircuitSpan* m_span;       // The span this circuit belongs to
01737     unsigned int m_code;                 // Circuit id
01738     Type m_type;                         // Circuit type (see enumeration)
01739     Status m_status;                     // Circuit local status
01740     int m_lock;                          // Circuit lock flags
01741     ObjList m_events;                    // In-band events
01742     SignallingCircuitEvent* m_lastEvent; // The last generated event
01743     bool m_noEvents;                     // No events pending, exit quickly
01744 };
01745 
01753 class YSIG_API SignallingCircuitRange : public String
01754 {
01755     YCLASS(SignallingCircuitRange,String)
01756     friend class SignallingCircuitGroup;
01757 public:
01764     SignallingCircuitRange(const String& rangeStr, const char* name = 0,
01765         int strategy = -1);
01766 
01770     virtual ~SignallingCircuitRange()
01771         { clear(); }
01772 
01777     inline unsigned int count() const
01778         { return m_count; }
01779 
01784     inline const unsigned int* range() const
01785         { return (const unsigned int*)m_range.data(); }
01786 
01791     inline void clear() 
01792         { m_range.clear(); m_count = 0; }
01793 
01799     inline unsigned int operator[](unsigned int index)
01800         { return range()[index]; }
01801 
01807     inline bool set(const String& rangeStr)
01808     {
01809         clear();
01810         return add(rangeStr);
01811     }
01812 
01818     bool add(const String& rangeStr);
01819 
01825     void add(unsigned int* codes, unsigned int len);
01826 
01831     inline void add(unsigned int code)
01832         { add(&code,1); }
01833 
01839     void add(unsigned int first, unsigned int last);
01840 
01845     void remove(unsigned int code);
01846 
01852     bool find(unsigned int code);
01853 
01857     virtual void destruct()
01858     {
01859         clear();
01860         String::destruct();
01861     }
01862 
01863 protected:
01864     void updateLast();                   // Update last circuit code
01865 
01866     DataBlock m_range;                   // Array containing the circuit codes
01867     unsigned int m_count;                // The number of elements in the array
01868     unsigned int m_last;                 // Last (the greater) not used circuit code within this range
01869     int m_strategy;                      // Keep the strategy used to allocate circuits from this range
01870     unsigned int m_used;                 // Last used circuit code
01871 };
01872 
01877 class YSIG_API SignallingCircuitGroup : public SignallingComponent, public Mutex
01878 {
01879     YCLASS(SignallingCircuitGroup,SignallingComponent)
01880     friend class SignallingCircuit;
01881     friend class SignallingCallControl;
01882     friend class SS7ISUP;
01883     friend class ISDNQ931;
01884 public:
01888     enum Strategy {
01889         Other     = 0,
01890         // basic strategies
01891         Increment = 0x0001, // round-robin, up
01892         Decrement = 0x0002, // round-robin, down
01893         Lowest    = 0x0003, // pick first available
01894         Highest   = 0x0004, // pick last available
01895         Random    = 0x0005, // pick random circuit
01896         // even/odd strict select (glare avoidance)
01897         OnlyEven  = 0x1000,
01898         OnlyOdd   = 0x2000,
01899         // glare avoidance with fallback (to be able to use all circuits)
01900         Fallback  = 0x4000,
01901     };
01902 
01909     SignallingCircuitGroup(unsigned int base = 0, int strategy = Increment,
01910         const char* name = "circgroup");
01911 
01915     virtual ~SignallingCircuitGroup();
01916 
01921     inline unsigned int count() const
01922         { return m_circuits.count(); }
01923 
01928     inline unsigned int base() const
01929         { return m_base; }
01930 
01935     inline unsigned int last() const
01936         { return m_range.m_last; }
01937 
01942     inline int strategy() const
01943         { return m_range.m_strategy; }
01944 
01949     inline void setStrategy(int strategy)
01950         { Lock lock(this); m_range.m_strategy = strategy; }
01951 
01955     inline ObjList& circuits()
01956         { return m_circuits; }
01957 
01962     void getCicList(String& dest);
01963 
01969     bool insert(SignallingCircuit* circuit);
01970 
01975     void remove(SignallingCircuit* circuit);
01976 
01984     SignallingCircuitSpan* buildSpan(const String& name, unsigned int start = 0, NamedList* params = 0);
01985 
01991     bool insertSpan(SignallingCircuitSpan* span);
01992 
02000     void insertRange(SignallingCircuitSpan* span, const char* name,
02001         int strategy = -1);
02002 
02011     void insertRange(const String& range, const char* name,
02012         int strategy = -1);
02013 
02020     void removeSpan(SignallingCircuitSpan* span, bool delCics = true, bool delSpan = false);
02021 
02026     void removeSpanCircuits(SignallingCircuitSpan* span);
02027 
02034     SignallingCircuit* find(unsigned int cic, bool local = false);
02035 
02041     SignallingCircuitRange* findRange(const char* name);
02042 
02048     SignallingCircuit::Status status(unsigned int cic);
02049 
02057     bool status(unsigned int cic, SignallingCircuit::Status newStat, bool sync = false);
02058 
02066     SignallingCircuit* reserve(int checkLock = -1, int strategy = -1,
02067         SignallingCircuitRange* range = 0);
02068 
02080     SignallingCircuit* reserve(const String& list, bool mandatory,
02081         int checkLock = -1, int strategy = -1, SignallingCircuitRange* range = 0);
02082 
02089     inline bool release(SignallingCircuit* cic, bool sync = false)
02090         { return cic && cic->status(SignallingCircuit::Idle,sync); }
02091 
02098     static int str2strategy(const char* name, int def = Increment)
02099         { return lookup(name,s_strategy,def); }
02100 
02104     static TokenDict s_strategy[];
02105 
02106 protected:
02110     virtual void destroyed()
02111     {
02112         clearAll();
02113         SignallingComponent::destroyed();
02114     }
02115 
02116 private:
02117     unsigned int advance(unsigned int n, int strategy, SignallingCircuitRange& range);
02118     void clearAll();
02119 
02120     ObjList m_circuits;                  // The circuits belonging to this group
02121     ObjList m_spans;                     // The spans belonging to this group
02122     ObjList m_ranges;                    // Additional circuit ranges
02123     SignallingCircuitRange m_range;      // Range containing all circuits belonging to this group
02124     unsigned int m_base;
02125 };
02126 
02131 class YSIG_API SignallingCircuitSpan : public SignallingComponent
02132 {
02133     YCLASS(SignallingCircuitSpan,SignallingComponent)
02134 public:
02138     virtual ~SignallingCircuitSpan();
02139 
02144     inline SignallingCircuitGroup* group() const
02145         { return m_group; }
02146 
02151     inline const String& id() const
02152         { return m_id; }
02153 
02158     inline unsigned int increment() const
02159         { return m_increment; }
02160 
02161 protected:
02167     SignallingCircuitSpan(const char* id = 0, SignallingCircuitGroup* group = 0);
02168 
02172     SignallingCircuitGroup* m_group;
02173 
02177     unsigned int m_increment;
02178 
02179 private:
02180     String m_id;                         // Span's id
02181 };
02182 
02187 class YSIG_API SignallingInterface : virtual public SignallingComponent
02188 {
02189     YCLASS(SignallingInterface,SignallingComponent)
02190     friend class SignallingReceiver;
02191 public:
02195     enum Operation {
02196         Specific  = 0,
02197         EnableTx  = 0x01,
02198         EnableRx  = 0x02,
02199         Enable    = 0x03,
02200         DisableTx = 0x04,
02201         DisableRx = 0x08,
02202         Disable   = 0x0c,
02203         FlushTx   = 0x10,
02204         FlushRx   = 0x20,
02205         Flush     = 0x30,
02206         QueryTx   = 0x40,
02207         QueryRx   = 0x80,
02208         Query     = 0xc0
02209     };
02210 
02214     enum Notification {
02215         LinkUp = 0,
02216         LinkDown,
02217         HardwareError,
02218         TxClockError,
02219         RxClockError,
02220         AlignError,
02221         CksumError,
02222         TxOversize,
02223         RxOversize,
02224         TxOverflow,
02225         RxOverflow,
02226         TxUnderrun,
02227         RxUnderrun,
02228     };
02229 
02233     enum PacketType {
02234         Unknown = 0,
02235         SS7Fisu,
02236         SS7Lssu,
02237         SS7Msu,
02238         Q921
02239     };
02240 
02244     inline SignallingInterface()
02245         : m_recvMutex(true,"SignallingInterface::recv"), m_receiver(0)
02246         { }
02247 
02251     virtual ~SignallingInterface();
02252 
02257     virtual void attach(SignallingReceiver* receiver);
02258 
02263     inline SignallingReceiver* receiver() const
02264         { return m_receiver; }
02265 
02275     virtual bool control(Operation oper, NamedList* params = 0);
02276 
02280     static TokenDict s_notifName[];
02281 
02282 protected:
02291     virtual bool transmitPacket(const DataBlock& packet, bool repeat, PacketType type) = 0;
02292 
02298     bool receivedPacket(const DataBlock& packet);
02299 
02305     bool notify(Notification event);
02306 
02307 private:
02308     Mutex m_recvMutex;                   // Lock receiver pointer operations
02309     SignallingReceiver* m_receiver;
02310 };
02311 
02316 class YSIG_API SignallingReceiver : virtual public SignallingComponent
02317 {
02318     YCLASS(SignallingReceiver,SignallingComponent)
02319     friend class SignallingInterface;
02320 public:
02325     SignallingReceiver(const char* name = 0);
02326 
02330     virtual ~SignallingReceiver();
02331 
02337     virtual SignallingInterface* attach(SignallingInterface* iface);
02338 
02343     inline SignallingInterface* iface() const
02344         { return m_interface; }
02345 
02353     bool control(SignallingInterface::Operation oper, NamedList* params = 0);
02354 
02355 protected:
02364     bool transmitPacket(const DataBlock& packet, bool repeat,
02365         SignallingInterface::PacketType type = SignallingInterface::Unknown);
02366 
02371     virtual bool receivedPacket(const DataBlock& packet) = 0;
02372 
02378     virtual bool notify(SignallingInterface::Notification event);
02379 
02380 private:
02381     Mutex m_ifaceMutex;                  // Lock interface pointer operations
02382     SignallingInterface* m_interface;
02383 };
02384 
02385 
02390 struct SignallingFlags
02391 {
02395     unsigned int mask;
02396 
02400     unsigned int value;
02401 
02405     const char* name;
02406 };
02407 
02412 class YSIG_API SignallingUtils
02413 {
02414 public:
02419     static const TokenDict* codings();
02420 
02425     static const TokenDict* locations();
02426 
02438     static inline const TokenDict* dict(unsigned int index, unsigned char coding = 0)
02439     {
02440         if (index > 4)
02441             return 0;
02442         return (!coding ? s_dictCCITT[index] : 0);
02443     }
02444 
02452     static bool hasFlag(const NamedList& list, const char* param, const char* flag);
02453 
02460     static bool removeFlag(String& flags, const char* flag);
02461 
02469     static void addKeyword(NamedList& list, const char* param,
02470         const TokenDict* tokens, unsigned int val);
02471 
02481     static void dumpData(const SignallingComponent* comp, NamedList& list, const char* param,
02482         const unsigned char* buf, unsigned int len, char sep = ' ');
02483 
02496     static unsigned int dumpDataExt(const SignallingComponent* comp, NamedList& list, const char* param,
02497         const unsigned char* buf, unsigned int len, char sep = ' ');
02498 
02510     static bool decodeFlags(const SignallingComponent* comp, NamedList& list, const char* param,
02511         const SignallingFlags* flags, const unsigned char* buf, unsigned int len);
02512 
02523     static bool decodeCause(const SignallingComponent* comp, NamedList& list, const unsigned char* buf,
02524         unsigned int len, const char* prefix, bool isup);
02525 
02536     static bool decodeCaps(const SignallingComponent* comp, NamedList& list, const unsigned char* buf,
02537         unsigned int len, const char* prefix, bool isup);
02538 
02548     static void encodeFlags(const SignallingComponent* comp, int& dest, const String& flags,
02549         TokenDict* dict);
02550 
02562     static bool encodeCause(const SignallingComponent* comp, DataBlock& buf, const NamedList& params,
02563         const char* prefix, bool isup, bool fail = false);
02564 
02574     static bool encodeCaps(const SignallingComponent* comp, DataBlock& buf, const NamedList& params,
02575         const char* prefix, bool isup);
02576 
02589     static unsigned int* parseUIntArray(const String& source, unsigned int minVal, unsigned int maxVal,
02590         unsigned int& count, bool discardDup);
02591 
02592 private:
02593     static TokenDict* s_dictCCITT[5];
02594 };
02595 
02601 class YSIG_API AnalogLine : public RefObject, public Mutex
02602 {
02603     YCLASS(AnalogLine,RefObject)
02604     friend class AnalogLineGroup;        // Reset group if destroyed before the line
02605 public:
02609     enum Type {
02610         FXO,                             // Telephone linked to an exchange
02611         FXS,                             // Telephone exchange linked to a telephone
02612         Recorder,                        // Passive FXO recording a 2 wire line
02613         Monitor,                         // Monitor (a pair of FXS/FXO lines)
02614         Unknown
02615     };
02616 
02620     enum State {
02621         OutOfService   = -1,             // Line is out of service
02622         Idle           = 0,              // Line is idle (on hook)
02623         Dialing        = 1,              // FXS line is waiting for the FXO to dial the number
02624         DialComplete   = 2,              // FXS line: got enough digits from the FXO to reach a destination
02625         Ringing        = 3,              // Line is ringing
02626         Answered       = 4,              // Line is answered
02627         CallEnded      = 5,              // FXS line: notify the FXO on call termination
02628         OutOfOrder     = 6,              // FXS line: notify the FXO that the hook is off after call ended notification
02629     };
02630 
02634     enum CallSetupInfo {
02635         After,                           // Send/detect call setup after the first ring
02636         Before,                          // Send/detect call setup before the first ring
02637         NoCallSetup                      // No call setup detect or send
02638     };
02639 
02647     AnalogLine(AnalogLineGroup* grp, unsigned int cic, const NamedList& params);
02648 
02652     virtual ~AnalogLine();
02653 
02658     inline Type type() const
02659         { return m_type; }
02660 
02665     inline State state() const
02666         { return m_state; }
02667 
02672     inline AnalogLineGroup* group()
02673         { return m_group; }
02674 
02679     inline AnalogLine* getPeer()
02680         { return m_peer; }
02681 
02687     void setPeer(AnalogLine* line = 0, bool sync = true);
02688 
02693     inline SignallingCircuit* circuit()
02694         { return m_circuit; }
02695 
02700     inline const char* address() const
02701         { return m_address; }
02702 
02707     inline bool outbandDtmf() const
02708         { return !m_inband; }
02709 
02714     inline bool answerOnPolarity() const
02715         { return m_answerOnPolarity; }
02716 
02721     inline bool hangupOnPolarity() const
02722         { return m_hangupOnPolarity; }
02723 
02728     inline bool polarityControl() const
02729         { return m_polarityControl; }
02730 
02735     inline CallSetupInfo callSetup() const
02736         { return m_callSetup; }
02737 
02742     inline u_int64_t callSetupTimeout() const
02743         { return m_callSetupTimeout; }
02744 
02749     inline u_int64_t noRingTimeout() const
02750         { return m_noRingTimeout; }
02751 
02756     inline u_int64_t alarmTimeout() const
02757         { return m_alarmTimeout; }
02758 
02763     inline u_int64_t delayDial() const
02764         { return m_delayDial; }
02765 
02770     inline void acceptPulseDigit(bool ok)
02771         { m_acceptPulseDigit = ok; }
02772 
02777     inline void* userdata() const
02778         { return m_private; }
02779 
02785     inline void userdata(void* data, bool sync = true)
02786     {
02787         Lock lock(this);
02788         m_private = data;
02789         if (sync && m_peer)
02790             m_peer->userdata(data,false);
02791     }
02792 
02797     virtual const String& toString() const
02798         { return m_address; }
02799 
02804     void resetEcho(bool train);
02805 
02810     inline bool resetCircuit()
02811         { return state() != OutOfService && m_circuit && m_circuit->reserve(); }
02812 
02819     inline bool setCircuitParam(const char* param, const char* value = 0)
02820         { return m_circuit && m_circuit->setParam(param,value); }
02821 
02827     bool connect(bool sync);
02828 
02834     bool disconnect(bool sync);
02835 
02842     bool sendEvent(SignallingCircuitEvent::Type type, NamedList* params = 0);
02843 
02851     inline bool sendEvent(SignallingCircuitEvent::Type type, State newState,
02852         NamedList* params = 0)
02853     {
02854         if (!sendEvent(type,params))
02855             return false;
02856         changeState(newState,false);
02857         return true;
02858     }
02859 
02865     virtual AnalogLineEvent* getEvent(const Time& when);
02866 
02872     virtual AnalogLineEvent* getMonitorEvent(const Time& when);
02873 
02878     virtual void checkTimeouts(const Time& when)
02879         { }
02880 
02887     bool changeState(State newState, bool sync = false);
02888 
02897     bool enable(bool ok, bool sync, bool connectNow = true);
02898 
02902     static const TokenDict* typeNames();
02903 
02907     static const TokenDict* stateNames();
02908 
02912     static const TokenDict* csNames();
02913 
02914 protected:
02918     virtual void destroyed();
02919 
02920 private:
02921     Type m_type;                               // Line type
02922     State m_state;                             // Line state
02923     bool m_inband;                             // Refuse to send DTMFs if they should be sent in band
02924     int m_echocancel;                          // Default echo canceller state (0: managed by the circuit, -1: off, 1: on)
02925     bool m_acceptPulseDigit;                   // Accept incoming pulse digits
02926     bool m_answerOnPolarity;                   // Answer on line polarity change
02927     bool m_hangupOnPolarity;                   // Hangup on line polarity change
02928     bool m_polarityControl;                    // Set line polarity flag
02929     CallSetupInfo m_callSetup;                 // Call setup management
02930     u_int64_t m_callSetupTimeout;              // FXO: timeout period for received call setup data before first ring
02931     u_int64_t m_noRingTimeout;                 // FXO: timeout period with no ring received on incoming calls
02932     u_int64_t m_alarmTimeout;                  // Timeout period to stay in alarms
02933     u_int64_t m_delayDial;                     // FXO: Time to delay sending number
02934     AnalogLineGroup* m_group;                  // The group owning this line
02935     SignallingCircuit* m_circuit;              // The circuit managed by this line
02936     String m_address;                          // Line address: group and circuit
02937     void* m_private;                           // Private data used by this line's user
02938     // Monitor data
02939     AnalogLine* m_peer;                        // This line's peer if any
02940     bool m_getPeerEvent;                       // Flag used to get events from peer
02941 };
02942 
02947 class YSIG_API AnalogLineEvent : public GenObject
02948 {
02949 public:
02955     AnalogLineEvent(AnalogLine* line, SignallingCircuitEvent* event)
02956         : m_line(0), m_event(event)
02957         { if (line && line->ref()) m_line = line; }
02958 
02962     virtual ~AnalogLineEvent()
02963     {
02964         TelEngine::destruct(m_line);
02965         TelEngine::destruct(m_event);
02966     }
02967 
02972     inline AnalogLine* line()
02973         { return m_line; }
02974 
02979     inline SignallingCircuitEvent* event()
02980         { return m_event; }
02981 
02985     virtual void destruct()
02986     {
02987         TelEngine::destruct(m_line);
02988         TelEngine::destruct(m_event);
02989         GenObject::destruct();
02990     }
02991 
02992 private:
02993     AnalogLine* m_line;
02994     SignallingCircuitEvent* m_event;
02995 };
02996 
03002 class YSIG_API AnalogLineGroup : public SignallingCircuitGroup
03003 {
03004     YCLASS(AnalogLineGroup,SignallingCircuitGroup)
03005 public:
03012     AnalogLineGroup(AnalogLine::Type type, const char* name, bool slave = false);
03013 
03020     AnalogLineGroup(const char* name, AnalogLineGroup* fxo);
03021 
03025     virtual ~AnalogLineGroup();
03026 
03031     inline AnalogLine::Type type() const
03032         { return m_type; }
03033 
03038     inline ObjList& lines()
03039         { return m_lines; }
03040 
03045     inline AnalogLineGroup* fxo()
03046         { return m_fxo; }
03047 
03052     inline bool slave()
03053         { return m_slave; }
03054 
03061     bool appendLine(AnalogLine* line, bool destructOnFail = true);
03062 
03067     void removeLine(unsigned int cic);
03068 
03073     void removeLine(AnalogLine* line);
03074 
03080     AnalogLine* findLine(unsigned int cic);
03081 
03087     AnalogLine* findLine(const String& address);
03088 
03094     virtual AnalogLineEvent* getEvent(const Time& when);
03095 
03096 protected:
03100     virtual void destroyed();
03101 
03105     ObjList m_lines;
03106 
03107 private:
03108     AnalogLine::Type m_type;             // Line type
03109     AnalogLineGroup* m_fxo;              // The group containing the FXO lines if this is a monitor
03110     bool m_slave;                        // True if this is an FXO group owned by an FXS one
03111 };
03112 
03117 class YSIG_API SS7PointCode : public GenObject
03118 {
03119 public:
03123     enum Type {
03124         Other  = 0,
03125         ITU    = 1, // ITU-T Q.704
03126         ANSI   = 2, // ANSI T1.111.4
03127         ANSI8  = 3, // 8-bit SLS
03128         China  = 4, // GF 001-9001
03129         Japan  = 5, // JT-Q704, NTT-Q704
03130         Japan5 = 6, // 5-bit SLS
03131         // Do not change the next line, must be past last defined type
03132         DefinedTypes
03133     };
03134 
03141     inline SS7PointCode(unsigned char network = 0, unsigned char cluster = 0, unsigned char member = 0)
03142         : m_network(network), m_cluster(cluster), m_member(member)
03143         { }
03144 
03150     inline SS7PointCode(Type type, unsigned int packed)
03151         : m_network(0), m_cluster(0), m_member(0)
03152         { unpack(type,packed); }
03153 
03158     inline SS7PointCode(const SS7PointCode& original)
03159         : m_network(original.network()), m_cluster(original.cluster()), m_member(original.member())
03160         { }
03161 
03165     inline ~SS7PointCode()
03166         { }
03167 
03172     inline unsigned char network() const
03173         { return m_network; }
03174 
03179     inline unsigned char cluster() const
03180         { return m_cluster; }
03181 
03186     inline unsigned char member() const
03187         { return m_member; }
03188 
03195     inline void assign(unsigned char network, unsigned char cluster, unsigned char member)
03196         { m_network = network; m_cluster = cluster; m_member = member; }
03197 
03204     bool assign(const String& src, Type type = Other);
03205 
03214     bool assign(Type type, const unsigned char* src, int len = -1, unsigned char* spare = 0);
03215 
03220     inline SS7PointCode& operator=(const SS7PointCode& original)
03221         { assign(original.network(),original.cluster(),original.member()); return *this; }
03222 
03227     inline bool operator==(const SS7PointCode& original) const
03228         { return m_network == original.network() && m_cluster == original.cluster() && m_member == original.member(); }
03229 
03234     bool compatible(Type type) const;
03235 
03241     unsigned int pack(Type type) const;
03242 
03249     bool unpack(Type type, unsigned int packed);
03250 
03258     bool store(Type type, unsigned char* dest, unsigned char spare = 0) const;
03259 
03265     static unsigned char size(Type type);
03266 
03272     static unsigned char length(Type type);
03273 
03279     static Type lookup(const char* text)
03280         { return (Type)TelEngine::lookup(text,s_names,(int)Other); }
03281 
03287     static const char* lookup(Type type)
03288         { return TelEngine::lookup((int)type,s_names); }
03289 
03290 private:
03291     static TokenDict s_names[];          // Keep the strigns associated with point code type
03292     unsigned char m_network;
03293     unsigned char m_cluster;
03294     unsigned char m_member;
03295 };
03296 
03297 // The number of valid point code types
03298 #define YSS7_PCTYPE_COUNT (SS7PointCode::DefinedTypes-1)
03299 
03305 YSIG_API String& operator<<(String& str, const SS7PointCode& cp);
03306 
03311 class YSIG_API SS7Label
03312 {
03313 public:
03317     SS7Label();
03318 
03323     SS7Label(const SS7Label& original);
03324 
03331     SS7Label(const SS7Label& original, unsigned char sls, unsigned char spare = 0);
03332 
03341     SS7Label(SS7PointCode::Type type, const SS7PointCode& dpc,
03342         const SS7PointCode& opc, unsigned char sls, unsigned char spare = 0);
03343 
03352     SS7Label(SS7PointCode::Type type, unsigned int dpc,
03353         unsigned int opc, unsigned char sls, unsigned char spare = 0);
03354 
03360     SS7Label(SS7PointCode::Type type, const SS7MSU& msu);
03361 
03370     void assign(SS7PointCode::Type type, const SS7PointCode& dpc,
03371         const SS7PointCode& opc, unsigned char sls, unsigned char spare = 0);
03372 
03381     void assign(SS7PointCode::Type type, unsigned int dpc,
03382         unsigned int opc, unsigned char sls, unsigned char spare = 0);
03383 
03390     bool assign(SS7PointCode::Type type, const SS7MSU& msu);
03391 
03399     bool assign(SS7PointCode::Type type, const unsigned char* src, int len = -1);
03400 
03406     bool store(unsigned char* dest) const;
03407 
03412     bool compatible(SS7PointCode::Type type) const;
03413 
03418     inline SS7PointCode::Type type() const
03419         { return m_type; }
03420 
03425     inline const SS7PointCode& dpc() const
03426         { return m_dpc; }
03427 
03432     inline SS7PointCode& dpc()
03433         { return m_dpc; }
03434 
03439     inline const SS7PointCode& opc() const
03440         { return m_opc; }
03441 
03446     inline SS7PointCode& opc()
03447         { return m_opc; }
03448 
03453     inline unsigned char sls() const
03454         { return m_sls; }
03455 
03460     inline void setSls(unsigned char sls)
03461         { m_sls = sls; }
03462 
03467     inline unsigned char spare() const
03468         { return m_spare; }
03469 
03474     inline void setSpare(unsigned char spare)
03475         { m_spare = spare; }
03476 
03481     inline unsigned int length() const
03482         { return length(m_type); }
03483 
03489     static unsigned int length(SS7PointCode::Type type);
03490 
03495     inline unsigned char size() const
03496         { return size(m_type); }
03497 
03503     static unsigned char size(SS7PointCode::Type type);
03504 
03505 private:
03506     SS7PointCode::Type m_type;
03507     SS7PointCode m_dpc;
03508     SS7PointCode m_opc;
03509     unsigned char m_sls;
03510     unsigned char m_spare;
03511 };
03512 
03518 YSIG_API String& operator<<(String& str, const SS7Label& label);
03519 
03524 class YSIG_API SS7MSU : public DataBlock
03525 {
03526     YCLASS(SS7MSU,DataBlock)
03527 public:
03531     enum Services {
03532         // Signalling Network Management
03533         SNM   =  0,
03534         // Maintenance
03535         MTN   =  1,
03536         // Maintenance special
03537         MTNS  =  2,
03538         // Signalling Connection Control Part
03539         SCCP  =  3,
03540         // Telephone User Part
03541         TUP   =  4,
03542         // ISDN User Part
03543         ISUP  =  5,
03544         // Data User Part - call and circuit related
03545         DUP_C =  6,
03546         // Data User Part - facility messages
03547         DUP_F =  7,
03548         // MTP Testing User Part (reserved)
03549         MTP_T =  8,
03550         // Broadband ISDN User Part
03551         BISUP =  9,
03552         // Satellite ISDN User Part
03553         SISUP = 10,
03554         // AAL type2 Signaling
03555         AAL2  = 12,
03556         // Bearer Independent Call Control
03557         BICC  = 13,
03558         // Gateway Control Protocol
03559         GCP   = 14,
03560     };
03561 
03565     enum Priority {
03566         Regular  = 0x00,
03567         Special  = 0x10,
03568         Circuit  = 0x20,
03569         Facility = 0x30
03570     };
03571 
03575     enum NetIndicator {
03576         International      = 0x00,
03577         SpareInternational = 0x40,
03578         National           = 0x80,
03579         ReservedNational   = 0xc0
03580     };
03581 
03585     inline SS7MSU()
03586         { }
03587 
03592     inline SS7MSU(const SS7MSU& value)
03593         : DataBlock(value)
03594         { }
03595 
03600     inline SS7MSU(const DataBlock& value)
03601         : DataBlock(value)
03602         { }
03603 
03610     inline SS7MSU(void* value, unsigned int len, bool copyData = true)
03611         : DataBlock(value,len,copyData)
03612         { }
03613 
03621     SS7MSU(unsigned char sio, const SS7Label label, void* value = 0, unsigned int len = 0);
03622 
03631     SS7MSU(unsigned char sif, unsigned char ssf, const SS7Label label, void* value = 0, unsigned int len = 0);
03632 
03636     virtual ~SS7MSU();
03637 
03643     inline SS7MSU& operator=(const SS7MSU& value)
03644         { DataBlock::operator=(value); return *this; }
03645 
03651     inline SS7MSU& operator=(const DataBlock& value)
03652         { DataBlock::operator=(value); return *this; }
03653 
03658     bool valid() const;
03659 
03666     inline unsigned char* getData(unsigned int offs, unsigned int len = 1)
03667         { return (offs+len <= length()) ? offs + (unsigned char*)data() : 0; }
03668 
03675     inline const unsigned char* getData(unsigned int offs, unsigned int len = 1) const
03676         { return (offs+len <= length()) ? offs + (const unsigned char*)data() : 0; }
03677 
03684     inline unsigned char* getData(const SS7Label& label, unsigned int len = 1)
03685         { return getData(label.length()+1,len); }
03686 
03693     inline const unsigned char* getData(const SS7Label& label, unsigned int len = 1) const
03694         { return getData(label.length()+1,len); }
03695 
03700     inline int getSIO() const
03701         { return null() ? -1 : *(const unsigned char*)data(); }
03702 
03707     inline int getSIF() const
03708         { return null() ? -1 : 0x0f & *(const unsigned char*)data(); }
03709 
03714     inline int getSSF() const
03715         { return null() ? -1 : 0xf0 & *(const unsigned char*)data(); }
03716 
03721     inline int getPrio() const
03722         { return null() ? -1 : 0x30 & *(const unsigned char*)data(); }
03723 
03728     inline int getNI() const
03729         { return null() ? -1 : 0xc0 & *(const unsigned char*)data(); }
03730 
03735     const char* getServiceName() const;
03736 
03741     const char* getPriorityName() const;
03742 
03747     const char* getIndicatorName() const;
03748 
03755     static unsigned char getPriority(const char* name, unsigned char defVal = Regular);
03756 
03763     static unsigned char getNetIndicator(const char* name, unsigned char defVal = National);
03764 };
03765 
03770 class YSIG_API SIGTransport : public SignallingComponent
03771 {
03772     YCLASS(SIGTransport,SignallingComponent)
03773     friend class SIGTRAN;
03774 public:
03778     enum Transport {
03779         None = 0,
03780         Sctp,
03781         // All the following transports are not standard
03782         Tcp,
03783         Udp,
03784         Unix,
03785     };
03786 
03791     inline SIGTRAN* sigtran() const
03792         { return m_sigtran; }
03793 
03799     virtual bool connected(int streamId) const = 0;
03800 
03801 protected:
03806     inline SIGTransport(const char* name = 0)
03807         : SignallingComponent(name), m_sigtran(0)
03808         { }
03809 
03814     void attach(SIGTRAN* sigtran);
03815 
03820     virtual void attached(bool hasUAL) = 0;
03821 
03831     bool processMSG(unsigned char msgVersion, unsigned char msgClass,
03832         unsigned char msgType, const DataBlock& msg, int streamId) const;
03833 
03843     virtual bool transmitMSG(unsigned char msgVersion, unsigned char msgClass,
03844         unsigned char msgType, const DataBlock& msg, int streamId = 0);
03845 
03853     virtual bool transmitMSG(const DataBlock& header, const DataBlock& msg, int streamId = 0) = 0;
03854 
03855 private:
03856     SIGTRAN* m_sigtran;
03857 };
03858 
03863 class YSIG_API SIGTRAN
03864 {
03865     friend class SIGTransport;
03866 public:
03870     enum MsgClass {
03871         // Management (IUA/M2UA/M3UA/SUA)
03872         MGMT  =  0,
03873         // Transfer (M3UA)
03874         TRAN  =  1,
03875         // SS7 Signalling Network Management (M3UA/SUA)
03876         SSNM  =  2,
03877         // ASP State Maintenance (IUA/M2UA/M3UA/SUA)
03878         ASPSM =  3,
03879         // ASP Traffic Maintenance (IUA/M2UA/M3UA/SUA)
03880         ASPTM =  4,
03881         // Q.921/Q.931 Boundary Primitives Transport (IUA)
03882         QPTM  =  5,
03883         // MTP2 User Adaptation (M2UA)
03884         MAUP  =  6,
03885         // Connectionless Messages (SUA)
03886         CLMSG =  7,
03887         // Connection-Oriented Messages (SUA)
03888         COMSG =  8,
03889         // Routing Key Management (M3UA)
03890         RKM   =  9,
03891         // Interface Identifier Management (M2UA)
03892         IIM   = 10,
03893         // M2PA Messages (M2PA)
03894         M2PA  = 11,
03895     };
03896 
03900     SIGTRAN();
03901 
03905     virtual ~SIGTRAN();
03906 
03911     virtual void attach(SIGTransport* trans);
03912 
03917     inline SIGTransport* transport() const
03918         { return m_trans; }
03919 
03925     bool connected(int streamId = 0) const;
03926 
03931     static const TokenDict* classNames();
03932 
03933 protected:
03943     virtual bool processMSG(unsigned char msgVersion, unsigned char msgClass,
03944         unsigned char msgType, const DataBlock& msg, int streamId) = 0;
03945 
03955     bool transmitMSG(unsigned char msgVersion, unsigned char msgClass,
03956         unsigned char msgType, const DataBlock& msg, int streamId = 0) const;
03957 
03958 private:
03959     SIGTransport* m_trans;
03960     mutable Mutex m_transMutex;
03961 };
03962 
03967 class YSIG_API ASPUser
03968 {
03969 };
03970 
03975 class YSIG_API SCCP
03976 {
03977 public:
03981     virtual ~SCCP();
03982 
03987     virtual void attach(SCCPUser* user);
03988 
03989 protected:
03990     ObjList m_users;
03991 };
03992 
03997 class YSIG_API SCCPUser
03998 {
03999 public:
04003     virtual ~SCCPUser();
04004 
04009     virtual void attach(SCCP* sccp);
04010 
04015     inline SCCP* sccp() const
04016         { return m_sccp; }
04017 
04018 private:
04019     SCCP* m_sccp;
04020 };
04021 
04026 class YSIG_API TCAPUser
04027 {
04028 public:
04032     virtual ~TCAPUser();
04033 
04038     virtual void attach(SS7TCAP* tcap);
04039 
04044     inline SS7TCAP* tcap() const
04045         { return m_tcap; }
04046 
04047 private:
04048     SS7TCAP* m_tcap;
04049 };
04050 
04055 class YSIG_API SS7L2User : virtual public SignallingComponent
04056 {
04057     YCLASS(SS7L2User,SignallingComponent)
04058     friend class SS7Layer2;
04059 public:
04064     virtual void attach(SS7Layer2* link) = 0;
04065 
04070     virtual void detach(SS7Layer2* link) = 0;
04071 
04072 protected:
04080     virtual bool receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls) = 0;
04081 
04087     virtual void notify(SS7Layer2* link) = 0;
04088 };
04089 
04094 class YSIG_API SS7Layer2 : virtual public SignallingComponent
04095 {
04096     YCLASS(SS7Layer2,SignallingComponent)
04097 public:
04101     enum LinkStatus {
04102         OutOfAlignment = 0,
04103         NormalAlignment = 1,
04104         EmergencyAlignment = 2,
04105         OutOfService = 3,
04106         ProcessorOutage = 4,
04107         Busy = 5,
04108         // short versions as defined by RFC
04109         O = OutOfAlignment,
04110         N = NormalAlignment,
04111         E = EmergencyAlignment,
04112         OS = OutOfService,
04113         PO = ProcessorOutage,
04114         B = Busy,
04115     };
04116 
04120     enum Operation {
04121         // take link out of service
04122         Pause  = 0x100,
04123         // start link operation, align if it needs to
04124         Resume = 0x200,
04125         // start link, force realignment
04126         Align  = 0x300,
04127         // get operational status
04128         Status = 0x400,
04129     };
04130 
04136     virtual bool transmitMSU(const SS7MSU& msu) = 0;
04137 
04142     virtual ObjList* recoverMSU();
04143 
04148     virtual unsigned int status() const;
04149 
04156     virtual const char* statusName(unsigned int status, bool brief) const;
04157 
04163     inline const char* statusName(bool brief = false) const
04164         { return statusName(status(),brief); }
04165 
04170     virtual bool operational() const = 0;
04171 
04176     void attach(SS7L2User* l2user);
04177 
04182     inline SS7L2User* user() const
04183         { return m_l2user; }
04184 
04189     inline int sls() const
04190         { return m_sls; }
04191 
04196     inline void sls(int linkSel)
04197         { if ((m_sls < 0) || !m_l2user) m_sls = linkSel; }
04198 
04207     virtual bool control(Operation oper, NamedList* params = 0);
04208 
04214     virtual bool control(NamedList& params);
04215 
04216 protected:
04220     inline SS7Layer2()
04221         : m_l2userMutex(true,"SS7Layer2::l2user"), m_l2user(0), m_sls(-1)
04222         { }
04223 
04229     inline bool receivedMSU(const SS7MSU& msu)
04230     {
04231         m_l2userMutex.lock();
04232         RefPointer<SS7L2User> tmp = m_l2user;
04233         m_l2userMutex.unlock();
04234         return tmp && tmp->receivedMSU(msu,this,m_sls);
04235     }
04236 
04240     inline void notify()
04241     {
04242         m_l2userMutex.lock();
04243         RefPointer<SS7L2User> tmp = m_l2user;
04244         m_l2userMutex.unlock();
04245         if (tmp)
04246             tmp->notify(this);
04247     }
04248 
04249 private:
04250     Mutex m_l2userMutex;
04251     SS7L2User* m_l2user;
04252     int m_sls;
04253 };
04254 
04259 class YSIG_API SS7L3User : virtual public SignallingComponent
04260 {
04261     friend class SS7Layer3;
04262     friend class SS7Router;
04263 public:
04268     virtual void attach(SS7Layer3* network) = 0;
04269 
04270 protected:
04279     virtual bool receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls) = 0;
04280 
04286     virtual void notify(SS7Layer3* link, int sls);
04287 };
04288 
04293 class YSIG_API SS7Layer3 : virtual public SignallingComponent
04294 {
04295     YCLASS(SS7Layer3,SignallingComponent)
04296     friend class SS7Router;              // Access the data members to build the routing table
04297 public:
04301     virtual ~SS7Layer3()
04302          { attach(0); }
04303 
04311     virtual int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1) = 0;
04312 
04318     virtual bool operational(int sls = -1) const = 0;
04319 
04325     void attach(SS7L3User* l3user);
04326 
04331     inline SS7L3User* user() const
04332         { return m_l3user; }
04333 
04339     SS7PointCode::Type type(unsigned char netType) const;
04340 
04346     void setType(SS7PointCode::Type type, unsigned char netType);
04347 
04352     void setType(SS7PointCode::Type type);
04353 
04360     bool buildRoutes(const NamedList& params);
04361 
04369     unsigned int getRoutePriority(SS7PointCode::Type type, unsigned int packedPC);
04370 
04374     void printRoutes();
04375 
04376 protected:
04381     inline SS7Layer3(SS7PointCode::Type type = SS7PointCode::Other)
04382         : SignallingComponent("SS7Layer3"),
04383           m_l3userMutex(true,"SS7Layer3::l3user"),
04384           m_l3user(0),
04385           m_routeMutex(true,"SS7Layer3::route")
04386         { setType(type); }
04387 
04395     inline bool receivedMSU(const SS7MSU& msu, const SS7Label& label, int sls)
04396     {
04397         m_l3userMutex.lock();
04398         RefPointer<SS7L3User> tmp = m_l3user;
04399         m_l3userMutex.unlock();
04400         return tmp && tmp->receivedMSU(msu,label,this,sls);
04401     }
04402 
04407     inline void notify(int sls = -1)
04408     {
04409         m_l3userMutex.lock();
04410         RefPointer<SS7L3User> tmp = m_l3user;
04411         m_l3userMutex.unlock();
04412         if (tmp)
04413             tmp->notify(this,sls);
04414     }
04415 
04423     virtual bool maintenance(const SS7MSU& msu, const SS7Label& label, int sls);
04424 
04432     virtual bool management(const SS7MSU& msu, const SS7Label& label, int sls);
04433 
04442     virtual bool unavailable(const SS7MSU& msu, const SS7Label& label, int sls, unsigned char cause = 0);
04443 
04451     SS7Route* findRoute(SS7PointCode::Type type, unsigned int packed);
04452 
04458     void updateRoutes(SS7Layer3* network);
04459 
04466     void removeRoutes(SS7Layer3* network);
04467 
04468 private:
04469     Mutex m_l3userMutex;                 // Mutex to lock L3 user pointer
04470     SS7L3User* m_l3user;
04471     SS7PointCode::Type m_cpType[4];      // Map incoming MSUs net indicators to point code type
04472     Mutex m_routeMutex;                  // Mutex to lock routing list operations
04473     ObjList m_route[YSS7_PCTYPE_COUNT];  // Outgoing point codes serviced by a network (for each point code type)
04474                                          // or the routing table of a message router
04475 };
04476 
04481 class YSIG_API SS7Layer4 : public SS7L3User
04482 {
04483 public:
04488     virtual void attach(SS7Layer3* network);
04489 
04494     inline SS7Layer3* network() const
04495         { return m_layer3; }
04496 
04497 protected:
04501     SS7Layer4();
04502 
04510     inline int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1)
04511     {
04512         m_l3Mutex.lock();
04513         RefPointer<SS7Layer3> tmp = m_layer3;
04514         m_l3Mutex.unlock();
04515         return tmp ? tmp->transmitMSU(msu,label,sls) : -1;
04516     }
04517 
04518 private:
04519     Mutex m_l3Mutex;                     // Lock pointer use operations
04520     SS7Layer3* m_layer3;
04521 };
04522 
04528 class YSIG_API SS7Route : public RefObject, public Mutex
04529 {
04530     friend class SS7Layer3;
04531 public:
04537     inline SS7Route(unsigned int packed, unsigned int priority = 0)
04538         : Mutex(true,"SS7Route"),
04539           m_packed(packed), m_priority(priority), m_changes(0)
04540         { m_networks.setDelete(false); }
04541 
04545     virtual ~SS7Route()
04546         { }
04547 
04554     void attach(SS7Layer3* network, SS7PointCode::Type type);
04555 
04562     bool detach(SS7Layer3* network);
04563 
04573     int transmitMSU(const SS7Router* router, const SS7MSU& msu, const SS7Label& label, int sls);
04574 
04575 private:
04576     unsigned int m_packed;               // Packed destination point code
04577     unsigned int m_priority;             // Network priority for the given destination (used by SS7Layer3)
04578     ObjList m_networks;                  // List of networks used to route to the given destination (used by SS7Router)
04579     int m_changes;                       // Counter used to spot changes in the list
04580 };
04581 
04587 class YSIG_API SS7Router : public SS7L3User, public SS7Layer3, public Mutex
04588 {
04589     YCLASS2(SS7Router,SS7L3User,SS7Layer3)
04590 public:
04595     SS7Router(const NamedList& params);
04596 
04602     virtual bool initialize(const NamedList* config);
04603 
04611     virtual int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1);
04612 
04618     virtual bool operational(int sls = -1) const;
04619 
04624     virtual void attach(SS7Layer3* network);
04625 
04630     virtual void detach(SS7Layer3* network);
04631 
04636     void attach(SS7Layer4* service);
04637 
04642     void detach(SS7Layer4* service);
04643 
04644 protected:
04653     virtual bool receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
04654 
04661     virtual void notify(SS7Layer3* network, int sls);
04662 
04664     ObjList m_layer3;
04666     ObjList m_layer4;
04668     int m_changes;
04669 };
04670 
04677 class YSIG_API SS7M2PA : public SS7Layer2, public SIGTRAN
04678 {
04679 };
04680 
04687 class YSIG_API SS7M2UA : public SS7Layer2, public SIGTRAN
04688 {
04689 };
04690 
04697 class YSIG_API SS7M3UA : public SS7Layer3, public SIGTRAN
04698 {
04699 };
04700 
04705 class YSIG_API SS7MTP2 : public SS7Layer2, public SignallingReceiver, public SignallingDumpable, public Mutex
04706 {
04707     YCLASS2(SS7MTP2,SS7Layer2,SignallingReceiver)
04708 public:
04712     enum ErrorCorrection {
04713         Basic,       // retransmits only based on sequence numbers
04714         Preventive,  // continuously retransmit unacknowledged packets
04715         Adaptive,    // switch to using preventive retransmission dynamically
04716     };
04717 
04723     SS7MTP2(const NamedList& params, unsigned int status = OutOfService);
04724 
04728     virtual ~SS7MTP2();
04729 
04735     virtual bool initialize(const NamedList* config);
04736 
04742     virtual bool transmitMSU(const SS7MSU& msu);
04743 
04748     virtual ObjList* recoverMSU();
04749 
04754     virtual unsigned int status() const;
04755 
04761     virtual bool aligned() const;
04762 
04767     virtual bool operational() const;
04768 
04777     virtual bool control(Operation oper, NamedList* params = 0);
04778 
04784     virtual bool notify(SignallingInterface::Notification event);
04785 
04786 protected:
04790     virtual void destroyed()
04791     {
04792         SS7Layer2::attach(0);
04793         TelEngine::destruct(SignallingReceiver::attach(0));
04794         SignallingComponent::destroyed();
04795     }
04796 
04801     virtual void timerTick(const Time& when);
04802 
04807     virtual bool receivedPacket(const DataBlock& packet);
04808 
04812     virtual void processFISU();
04813 
04818     virtual void processLSSU(unsigned int status);
04819 
04825     bool transmitLSSU(unsigned int status);
04826 
04831     inline bool transmitLSSU()
04832         { return transmitLSSU(m_lStatus); }
04833 
04838     bool transmitFISU();
04839 
04844     void startAlignment(bool emergency = false);
04845 
04849     void abortAlignment();
04850 
04855     bool startProving();
04856 
04857 private:
04858     virtual bool control(NamedList& params)
04859         { return SignallingDumpable::control(params,this) || SS7Layer2::control(params); }
04860     void unqueueAck(unsigned char bsn);
04861     bool txPacket(const DataBlock& packet, bool repeat, SignallingInterface::PacketType type = SignallingInterface::Unknown);
04862     void setLocalStatus(unsigned int status);
04863     void setRemoteStatus(unsigned int status);
04864     // sent but yet unacknowledged packets
04865     ObjList m_queue;
04866     // data link status (alignment) - desired, local and remote
04867     unsigned int m_status, m_lStatus, m_rStatus;
04868     // various interval period end
04869     u_int64_t m_interval;
04870     // time when resending packets
04871     u_int64_t m_resend;
04872     // time when aborting resending packets
04873     u_int64_t m_abort;
04874     // time when need to transmit next FISU/LSSU
04875     u_int64_t m_fillTime;
04876     // remote congestion indicator
04877     bool m_congestion;
04878     // backward and forward sequence numbers
04879     unsigned char m_bsn, m_fsn;
04880     // backward and forward indicator bits
04881     bool m_bib, m_fib;
04882     // last forward sequence number we sent a retransmission request
04883     unsigned char m_lastFsn;
04884     // last received backward sequence number
04885     unsigned char m_lastBsn;
04886     // last received backward indicator bit
04887     bool m_lastBib;
04888     // count of errors
04889     int m_errors;
04890     // packet resend interval
04891     unsigned int m_resendMs;
04892     // packet resend abort interval
04893     unsigned int m_abortMs;
04894     // FISU/LSSU soft resend interval
04895     unsigned int m_fillIntervalMs;
04896     // fill link with end-to-end FISU/LSSU
04897     bool m_fillLink;
04898 };
04899 
04904 class YSIG_API SS7MTP3 : public SS7Layer3, public SS7L2User, public SignallingDumpable, public Mutex
04905 {
04906     YCLASS(SS7MTP3,SS7Layer3)
04907 public:
04911     enum Operation {
04912         // take linkset out of service
04913         Pause  = 0x100,
04914         // start linkset operation
04915         Resume = 0x200,
04916         // get operational status
04917         Status = 0x400,
04918     };
04919 
04924     SS7MTP3(const NamedList& params);
04925 
04929     virtual ~SS7MTP3();
04930 
04936     virtual bool initialize(const NamedList* config);
04937 
04945     virtual int transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls = -1);
04946 
04952     virtual bool operational(int sls = -1) const;
04953 
04961     virtual bool control(Operation oper, NamedList* params = 0);
04962 
04967     virtual void attach(SS7Layer2* link);
04968 
04973     virtual void detach(SS7Layer2* link);
04974 
04980     virtual bool control(NamedList& params);
04981 
04986     inline unsigned int linksTotal() const
04987         { return m_total; }
04988 
04993     inline unsigned int linksActive() const
04994         { return m_active; }
04995 
04996 protected:
05000     virtual void destroyed();
05001 
05009     virtual bool receivedMSU(const SS7MSU& msu, SS7Layer2* link, int sls);
05010 
05016     virtual void notify(SS7Layer2* link);
05017 
05022     unsigned int countLinks();
05023 
05024 private:
05025     ObjList m_links;
05026     // total links in linkset
05027     unsigned int m_total;
05028     // currently active links
05029     unsigned int m_active;
05030     // inhibited flag
05031     bool m_inhibit;
05032 };
05033 
05038 class YSIG_API SS7MsgSNM : public SignallingMessage
05039 {
05040 public:
05044     enum Type {
05045         Unknown = 0,
05046         COO  = 0x11, // Changeover Order signal
05047         ECO  = 0x12, // Emergency Changeover Order signal
05048         RCT  = 0x13, // Route Set Congestion Test signal
05049         TFP  = 0x14, // Transfer Prohibited signal
05050         RST  = 0x15, // Route Set Test for prohibited destination
05051         RSP  = RST,  // Route Set Test for prohibited destination (ANSI)
05052         LIN  = 0x16, // Link Inhibit signal
05053         TRA  = 0x17, // Traffic Restart Allowed signal
05054         DLC  = 0x18, // Data Link Connection Order signal
05055         UPU  = 0x1a, // User Part Unavailable signal
05056         COA  = 0x21, // Changeover Acknowledgment signal
05057         ECA  = 0x22, // Emergency Changeover Acknowledgment signal
05058         TFC  = 0x23, // Transfer Controlled signal
05059         TCP  = 0x24, // Transfer Cluster Prohibited
05060         TFPA = TCP,  // Transfer Prohibited Acknowledgment (Yellow Book only)
05061         RSR  = 0x25, // Route Set Test for prohibited destination (national use)
05062         LUN  = 0x26, // Link Uninhibit signal
05063         TRW  = 0x27, // Traffic Restart Waiting (ANSI only)
05064         CSS  = 0x28, // Connection Successful signal
05065         TFR  = 0x34, // Transfer Restricted signal (national use)
05066         RCP  = 0x35, // Route Set Test for cluster-prohibited
05067         LIA  = 0x36, // Link Inhibit Acknowledgment signal
05068         CNS  = 0x38, // Connection Not Successful signal
05069         TCR  = 0x44, // Transfer Cluster Restricted signal (ANSI only)
05070         RCR  = 0x45, // Route Set Test for cluster-restricted (ANSI only)
05071         LUA  = 0x46, // Link Uninhibit Acknowledgment signal
05072         CNP  = 0x48, // Connection Not Possible signal
05073         CBD  = 0x51, // Changeback Declaration signal
05074         TFA  = 0x54, // Transfer Allowed signal
05075         LID  = 0x56, // Link Inhibit Denied signal
05076         CBA  = 0x61, // Changeback Acknowledgment signal
05077         TCA  = 0x64, // Transfer Cluster Allowed
05078         TFAA = TCA,  // Transfer Allowed Acknowledgment (Yellow Book only)
05079         LFU  = 0x66, // Link Forced Uninhibit signal
05080         LLT  = 0x76, // Link Local Inhibit Test signal
05081         LLI  = LLT,  // Link Local Inhibit Test signal (ANSI)
05082         LRT  = 0x86, // Link Remote Inhibit Test signal
05083         LRI  = LRT,  // Link Remote Inhibit Test signal (ANSI)
05084     };
05085 
05089     enum Group {
05090         CHM = 0x01,  // Changeover and changeback
05091         ECM = 0x02,  // Emergency changeover
05092         FCM = 0x03,  // Tranfer controlled and signalling route set congestion
05093         TFM = 0x04,  // Tranfer prohibited/allowed/restricted
05094         RSM = 0x05,  // Signalling route/set/test
05095         MIM = 0x06,  // Management inhibit
05096         TRM = 0x07,  // Traffic restart allowed
05097         DLM = 0x08,  // Signalling data/link/connection
05098         UFC = 0x0a,  // User part flow control
05099     };
05100 
05105     SS7MsgSNM(unsigned char type);
05106 
05111     inline unsigned char type() const
05112         { return m_type; }
05113 
05118     inline unsigned char group() const
05119         { return m_type & 0x0f; }
05120 
05127     void toString(String& dest, const SS7Label& label, bool params) const;
05128 
05138     static SS7MsgSNM* parse(SS7Management* receiver, unsigned char type,
05139         SS7PointCode::Type pcType,
05140         const unsigned char* buf, unsigned int len);
05141 
05145     static const TokenDict* names();
05146 
05153     static inline const char* lookup(Type type, const char* defvalue = 0)
05154         { return TelEngine::lookup(type,names(),defvalue); }
05155 
05162     static inline Type lookup(const char* name, Type defvalue = Unknown)
05163         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
05164 
05165 private:
05166     unsigned char m_type;
05167 };
05168 
05173 class YSIG_API SS7MsgMTN
05174 {
05175 public:
05179     enum Type {
05180         Unknown = 0,
05181         SLTM = 0x11, // Signalling Link Test Message
05182         SLTA = 0x21, // Signalling Link Test Acknowledgment
05183     };
05184 
05185     static const TokenDict* names();
05186 
05193     static inline const char* lookup(Type type, const char* defvalue = 0)
05194         { return TelEngine::lookup(type,names(),defvalue); }
05195 
05202     static inline Type lookup(const char* name, Type defvalue = Unknown)
05203         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
05204 };
05205 
05210 class YSIG_API SS7MsgISUP : public SignallingMessage
05211 {
05212     YCLASS(SS7MsgISUP,SignallingMessage)
05213     friend class SS7ISUPCall;
05214 public:
05218     enum Type {
05219         Unknown = 0,
05220         IAM  = 0x01, // Initial Address Message
05221         SAM  = 0x02, // Subsequent Address Message
05222         INR  = 0x03, // Information Request (national use)
05223         INF  = 0x04, // Information (national use)
05224         COT  = 0x05, // Continuity
05225         ACM  = 0x06, // Address Complete Message
05226         CON  = 0x07, // Connect
05227         FOT  = 0x08, // Forward Transfer
05228         ANM  = 0x09, // Answer Message
05229         REL  = 0x0c, // Release Request
05230         SUS  = 0x0d, // Suspend
05231         RES  = 0x0e, // Resume
05232         RLC  = 0x10, // Release Complete
05233         CCR  = 0x11, // Continuity Check Request
05234         RSC  = 0x12, // Reset Circuit
05235         BLK  = 0x13, // Blocking
05236         UBL  = 0x14, // Unblocking
05237         BLA  = 0x15, // Blocking Acknowledgement
05238         UBA  = 0x16, // Unblocking Acknowledgement
05239         GRS  = 0x17, // Circuit Group Reset
05240         CGB  = 0x18, // Circuit Group Blocking
05241         CGU  = 0x19, // Circuit Group Unblocking
05242         CGA  = 0x1a, // Circuit Group Blocking Acknowledgement
05243         CGBA = CGA,
05244         CUA  = 0x1b, // Circuit Group Unblocking Acknowledgement
05245         CMR  = 0x1c, // Call Modification Request (ANSI only)
05246         CMC  = 0x1d, // Call Modification Completed (ANSI only)
05247         CMRJ = 0x1e, // Call Modification Rejected (ANSI only)
05248         FACR = 0x1f, // Facility Request
05249         FAA  = 0x20, // Facility Accepted
05250         FRJ  = 0x21, // Facility Reject
05251         FAD  = 0x22, // Facility Deactivated (ANSI only)
05252         FAI  = 0x23, // Facility Information (ANSI only)
05253         LPA  = 0x24, // Loopback Acknowledgement (national use)
05254         CSVR = 0x25, // CUG Selection and Validation Request (ANSI only)
05255         CSVS = 0x26, // CUG Selection and Validation Response (ANSI only)
05256         DRS  = 0x27, // Delayed Release (ANSI only)
05257         PAM  = 0x28, // Pass Along Message (national use)
05258         GRA  = 0x29, // Circuit Group Reset Acknowledgement
05259         CQM  = 0x2a, // Circuit Group Query (national use)
05260         CQR  = 0x2b, // Circuit Group Query Response (national use)
05261         CPR  = 0x2c, // Call Progress
05262         CPG  = CPR,
05263         USR  = 0x2d, // User-to-User Information
05264         UEC  = 0x2e, // Unequipped CIC (national use)
05265         UCIC = UEC,
05266         CNF  = 0x2f, // Confusion
05267         OLM  = 0x30, // Overload Message (national use)
05268         CRG  = 0x31, // Charge Information (national use and format, ITU only)
05269         NRM  = 0x32, // Network Resource Management
05270         FAC  = 0x33, // Facility (national use)
05271         UPT  = 0x34, // User Part Test
05272         UPA  = 0x35, // User Part Available
05273         IDR  = 0x36, // Identification Request (ITU only)
05274         IRS  = 0x37, // Identification Response (ITU only)
05275         SGM  = 0x38, // Segmentation
05276         LOP  = 0x40, // Loop Prevention
05277         APM  = 0x41, // Application Transport
05278         PRI  = 0x42, // Pre-Release Information
05279         SDN  = 0x43, // Subsequent Directory Number (national use)
05280         CRA  = 0xe9, // Circuit Reservation Acknowledgement (ANSI only)
05281         CRM  = 0xea, // Circuit Reservation (ANSI only)
05282         CVR  = 0xeb, // Circuit Validation Response (ANSI only)
05283         CVT  = 0xec, // Circuit Validation Test (ANSI only)
05284         EXM  = 0xed, // Exit Message (ANSI only)
05285     };
05286 
05290     enum Parameters {
05291         EndOfParameters                = 0,
05292         CallReference                  = 0x01,
05293         TransmissionMediumRequirement  = 0x02,
05294         AccessTransport                = 0x03,
05295         CalledPartyNumber              = 0x04,
05296         SubsequentNumber               = 0x05,
05297         NatureOfConnectionIndicators   = 0x06,
05298         ForwardCallIndicators          = 0x07,
05299         OptionalForwardCallIndicators  = 0x08,
05300         CallingPartyCategory           = 0x09,
05301         CallingPartyNumber             = 0x0a,
05302         RedirectingNumber              = 0x0b,
05303         RedirectionNumber              = 0x0c,
05304         ConnectionRequest              = 0x0d,
05305         InformationRequestIndicators   = 0x0e,
05306         InformationIndicators          = 0x0f,
05307         ContinuityIndicators           = 0x10,
05308         BackwardCallIndicators         = 0x11,
05309         CauseIndicators                = 0x12,
05310         RedirectionInformation         = 0x13,
05311         GroupSupervisionTypeIndicator  = 0x15,
05312         RangeAndStatus                 = 0x16,
05313         CallModificationIndicators     = 0x17, // ANSI only
05314         FacilityIndicator              = 0x18,
05315         FacilityInformationIndicators  = 0x19, // ANSI only
05316         CUG_InterlockCode              = 0x1a,
05317         Index                          = 0x1b, // ANSI only
05318         CUG_CheckResponseIndicators    = 0x1c, // ANSI only
05319         UserServiceInformation         = 0x1d,
05320         SignallingPointCode            = 0x1e,
05321         UserToUserInformation          = 0x20,
05322         ConnectedNumber                = 0x21,
05323         SuspendResumeIndicators        = 0x22,
05324         TransitNetworkSelection        = 0x23,
05325         EventInformation               = 0x24,
05326         CircuitAssignmentMap           = 0x25, // ANSI only
05327         CircuitStateIndicator          = 0x26,
05328         AutomaticCongestionLevel       = 0x27,
05329         OriginalCalledNumber           = 0x28,
05330         OptionalBackwardCallIndicators = 0x29,
05331         UserToUserIndicators           = 0x2a,
05332         OriginationISCPointCode        = 0x2b, // ITU only
05333         GenericNotification            = 0x2c, // ITU only
05334         CallHistoryInformation         = 0x2d, // ITU only
05335         AccessDeliveryInformation      = 0x2e, // ITU only
05336         NetworkSpecificFacilities      = 0x2f, // ITU only
05337         UserServiceInformationPrime    = 0x30,
05338         PropagationDelayCounter        = 0x31, // ITU only
05339         RemoteOperations               = 0x32,
05340         ServiceActivation              = 0x33,
05341         UserTeleserviceInformation     = 0x34, // ITU only
05342         TransmissionMediumUsed         = 0x35,
05343         CallDiversionInformation       = 0x36, // ITU only
05344         EchoControlInformation         = 0x37, // ITU only
05345         MessageCompatInformation       = 0x38, // ITU only
05346         ParameterCompatInformation     = 0x39, // ITU only
05347         MLPP_Precedence                = 0x3a, // ITU name
05348         Precedence                     = MLPP_Precedence, // ANSI name
05349         MCID_RequestIndicator          = 0x3b, // ITU only
05350         MCID_ResponseIndicator         = 0x3c, // ITU only
05351         HopCounter                     = 0x3d,
05352         TransMediumRequirementPrime    = 0x3e, // ITU only
05353         LocationNumber                 = 0x3f, // ITU only
05354         RedirectionNumberRestriction   = 0x40, // ITU only
05355         FreephoneIndicators            = 0x41, // ITU only
05356         GenericReference               = 0x42, // ITU only
05357         ApplicationTransport           = 0x78,
05358         GenericNumber                  = 0xc0, // ITU name
05359         GenericAddress                 = GenericNumber, // ANSI name
05360         GenericDigits                  = 0xc1,
05361         OperatorServicesInformation    = 0xc2, // ANSI only
05362         Egress                         = 0xc3, // ANSI only
05363         Jurisdiction                   = 0xc4, // ANSI only
05364         CarrierIdentification          = 0xc5, // ANSI only
05365         BusinessGroup                  = 0xc6, // ANSI only
05366         GenericName                    = 0xc7, // ANSI only
05367         NotificationIndicator          = 0xe1, // ANSI only
05368         TransactionRequest             = 0xe3, // ANSI only
05369         CircuitGroupCharactIndicator   = 0xe5, // ANSI only
05370         CircuitValidationRespIndicator = 0xe6, // ANSI only
05371         OutgoingTrunkGroupNumber       = 0xe7, // ANSI only
05372         CircuitIdentificationName      = 0xe8, // ANSI only
05373         CommonLanguage                 = 0xe9, // ANSI only
05374         OriginatingLineInformation     = 0xea, // ANSI only
05375         ChargeNumber                   = 0xeb, // ANSI only
05376         ServiceCodeIndicator           = 0xec, // ANSI only
05377         SpecialProcessingRequest       = 0xed, // ANSI only
05378         CarrierSelectionInformation    = 0xee, // ANSI only
05379         NetworkTransport               = 0xef, // ANSI only
05380     };
05381 
05387     inline SS7MsgISUP(Type type, unsigned int cic)
05388         : SignallingMessage(lookup(type,"Unknown")), m_type(type), m_cic(cic)
05389         { }
05390 
05394     virtual ~SS7MsgISUP()
05395         { }
05396 
05401     inline Type type() const
05402         { return m_type; }
05403 
05408     inline unsigned int cic() const
05409         { return m_cic; }
05410 
05419     void toString(String& dest, const SS7Label& label, bool params,
05420         const void* raw = 0, unsigned int rawLen = 0) const;
05421 
05426     static const TokenDict* names();
05427 
05434     static inline const char* lookup(Type type, const char* defvalue = 0)
05435         { return TelEngine::lookup(type,names(),defvalue); }
05436 
05443     static inline Type lookup(const char* name, Type defvalue = Unknown)
05444         { return static_cast<Type>(TelEngine::lookup(name,names(),defvalue)); }
05445 
05446 private:
05447     Type m_type;                         // Message type
05448     unsigned int m_cic;                  // Source/destination Circuit Identification Code
05449 };
05450 
05455 class YSIG_API SS7Management : public SS7Layer4
05456 {
05457     YCLASS(SS7Management,SS7Layer4)
05458 public:
05462     inline SS7Management(const NamedList& params)
05463         : SignallingComponent(params.safe("SS7Management"),&params)
05464         { }
05465 
05466 protected:
05475     virtual bool receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
05476 
05483     virtual void notify(SS7Layer3* link, int sls);
05484 };
05485 
05490 class YSIG_API SS7Maintenance : public SS7Layer4
05491 {
05492     YCLASS(SS7Maintenance,SS7Layer4)
05493 public:
05497     inline SS7Maintenance(const NamedList& params)
05498         : SignallingComponent(params.safe("SS7Maintenance"),&params)
05499         { }
05500 
05501 protected:
05510     virtual bool receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
05511 
05518     virtual void notify(SS7Layer3* link, int sls);
05519 };
05520 
05525 class YSIG_API SS7ISUPCall : public SignallingCall
05526 {
05527     friend class SS7ISUP;
05528 public:
05532     enum State {
05533         // NOTE: Keep the order of state values: the code relies on it
05534         Null      = 0,                   // No message exchanged
05535         Setup     = 1,                   // IAM (initial address)
05536         Accepted  = 2,                   // ACM (address complete)
05537         Ringing   = 3,                   // CPM (call progress)
05538         Answered  = 4,                   // ANM (answer)
05539         Releasing = 5,                   // REL (release)
05540         Released  = 6                    // Call released, no message or events allowed
05541     };
05542 
05547     virtual ~SS7ISUPCall();
05548 
05553     inline State state() const
05554         { return m_state; }
05555 
05560     inline const String& cicRange() const
05561         { return m_cicRange; }
05562 
05567     inline unsigned int id() const
05568         { return m_circuit ? m_circuit->code() : 0; }
05569 
05576     virtual SignallingEvent* getEvent(const Time& when);
05577 
05583     virtual bool sendEvent(SignallingEvent* event);
05584 
05590     inline void setTerminate(bool gracefully, const char* reason = 0)
05591     {
05592         Lock lock(this);
05593         m_terminate = true;
05594         m_gracefully = gracefully;
05595         setReason(reason,0);
05596     }
05597 
05603     virtual void* getObject(const String& name) const;
05604 
05605 protected:
05616     SS7ISUPCall(SS7ISUP* controller, SignallingCircuit* cic,
05617         const SS7PointCode& local, const SS7PointCode& remote, bool outgoing,
05618         int sls = -1, const char* range = 0);
05619 
05629     SignallingEvent* releaseComplete(bool final, SS7MsgISUP* msg = 0, const char* reason = 0);
05630 
05640     bool replaceCircuit(SignallingCircuit* circuit);
05641 
05647     void stopWaitSegment(bool discard);
05648 
05649 private:
05650     // Initialize/set IAM message parameters
05651     // @param msg Valid ISUP message
05652     // @param outgoing Message direction: true for outgoing
05653     // @param sigMsg Valid signalling message with parameters if outgoing
05654     bool copyParamIAM(SS7MsgISUP* msg, bool outgoing = false, SignallingMessage* sigMsg = 0);
05655     // If already releasing, set termination flag. Otherwise, send REL (Release) message
05656     // @param event Event with the parameters. 0 if release is started on some timeout
05657     // @return True if the message was pushed down the protocol stack
05658     bool release(SignallingEvent* event = 0);
05659     // Set termination reason from message or parameter
05660     void setReason(const char* reason, SignallingMessage* msg);
05661     // Accept send/receive messages in current state based on call direction
05662     bool validMsgState(bool send, SS7MsgISUP::Type type);
05663     // Connect the reserved circuit. Return false if it fails. Return true if this call is a signalling only one
05664     bool connectCircuit();
05665     // Transmit the IAM message. Start IAM timer if not started
05666     bool transmitIAM();
05667     // Stop waiting for a SGM (Segmentation) message. Copy parameters to the pending segmented message if sgm is valid.
05668     // Change call state and set m_lastEvent
05669     // @param sgm Optional received SGM message with parameters to be added to the pending segmented message
05670     // @param timeout True if waiting timer timed out. Ignored if sgm is non null
05671     // @return m_lastEvent
05672     SignallingEvent* processSegmented(SS7MsgISUP* sgm = 0, bool timeout = false);
05673     // Transmit message. Set routing label's link if not already set
05674     inline bool transmitMessage(SS7MsgISUP* msg);
05675     // Get the ISUP call controller
05676     inline SS7ISUP* isup();
05677 
05678     State m_state;                       // Call state
05679     SignallingCircuit* m_circuit;        // Circuit reserved for this call
05680     String m_cicRange;                   // The range used to re(alloc) a circuit
05681     SS7Label m_label;                    // The routing label for this call
05682     bool m_terminate;                    // Termination flag
05683     bool m_gracefully;                   // Terminate gracefully: send RLC
05684     bool m_circuitChanged;               // circuit change flag
05685     String m_format;                     // Data format used by the circuit
05686     String m_reason;                     // Termination reason
05687     SS7MsgISUP* m_iamMsg;                // Message with the call parameters for outgoing calls
05688     SS7MsgISUP* m_sgmMsg;                // Pending received message with segmentation flag set
05689     // Timers
05690     SignallingTimer m_relTimer;          // Send release
05691     SignallingTimer m_iamTimer;          // Send initial address
05692     SignallingTimer m_sgmRecvTimer;      // Receive segmented message
05693 };
05694 
05699 class YSIG_API SS7ISUP : public SignallingCallControl, public SS7Layer4
05700 {
05701     YCLASS(SS7ISUP,SS7Layer4)
05702     friend class SS7ISUPCall;
05703 public:
05708     SS7ISUP(const NamedList& params);
05709 
05713     virtual ~SS7ISUP();
05714 
05720     virtual bool initialize(const NamedList* config);
05721 
05726     unsigned int cicLen() const
05727         { return m_cicLen; }
05728 
05733     const String& format() const
05734         { return m_format; }
05735 
05744     bool setPointCode(SS7PointCode* pc, bool def);
05745 
05752     unsigned int setPointCode(const NamedList& params);
05753 
05759     SS7PointCode* hasPointCode(const SS7PointCode& pc);
05760 
05768     inline void setLabel(SS7Label& label, const SS7PointCode& opc, const SS7PointCode& dpc,
05769         unsigned char sls = 255)
05770         { label.assign(m_type,dpc,opc,sls); }
05771 
05777     inline void setDebug(bool printMsg, bool extendedDebug)
05778         { m_extendedDebug = ((m_printMsg = printMsg) && extendedDebug); }
05779 
05789     virtual SS7MSU* createMSU(SS7MsgISUP::Type type, unsigned char ssf,
05790         const SS7Label& label, unsigned int cic, const NamedList* params = 0) const;
05791 
05799     virtual SignallingCall* call(SignallingMessage* msg, String& reason);
05800 
05811     int transmitMessage(SS7MsgISUP* msg, const SS7Label& label, bool recvLbl, int sls = -1);
05812 
05818     virtual void cleanup(const char* reason = "offline");
05819 
05829     bool decodeMessage(NamedList& msg, SS7MsgISUP::Type msgType, SS7PointCode::Type pcType,
05830         const unsigned char* paramPtr, unsigned int paramLen);
05831 
05842     bool encodeMessage(DataBlock& buf, SS7MsgISUP::Type msgType, SS7PointCode::Type pcType,
05843         const NamedList& params, unsigned int* cic = 0);
05844 
05845 protected:
05849     virtual void destroyed();
05850 
05855     virtual void timerTick(const Time& when);
05856 
05862     virtual void notify(SS7Layer3* link, int sls);
05863 
05873     SS7MSU* buildMSU(SS7MsgISUP::Type type, unsigned char sio,
05874         const SS7Label& label, unsigned int cic, const NamedList* params) const;
05875 
05884     virtual bool receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
05885 
05897     virtual bool processMSU(SS7MsgISUP::Type type, unsigned int cic,
05898         const unsigned char* paramPtr, unsigned int paramLen,
05899         const SS7Label& label, SS7Layer3* network, int sls);
05900 
05907     virtual SignallingEvent* processCircuitEvent(SignallingCircuitEvent*& event,
05908         SignallingCall* call = 0);
05909 
05913     unsigned int m_cicLen;
05914 
05915 private:
05916     // Process a received message that should be processed by a call
05917     // @param msg The received message
05918     // @param label The routing label of the received message
05919     // @param sls Signalling Link the message was received from
05920     void processCallMsg(SS7MsgISUP* msg, const SS7Label& label, int sls);
05921     // Process a received message that should be processed by this call controller
05922     // @param msg The received message
05923     // @param label The routing label of the received message
05924     // @param sls Signalling Link the message was received from
05925     void processControllerMsg(SS7MsgISUP* msg, const SS7Label& label, int sls);
05926     // Replace a call's circuit if checkCall is true
05927     // Clear lock flags of the circuit. Release currently reseting circuit if the code match
05928     // Return false if the given circuit doesn't exist
05929     bool resetCircuit(unsigned int cic, bool remote, bool checkCall);
05930     // Block/unblock a circuit side (local or remote)
05931     // Return false if the given circuit doesn't exist
05932     bool blockCircuit(unsigned int cic, bool block, bool remote, bool hwFail,
05933         bool changed, bool changedState);
05934     // Find a call by its circuit identification code
05935     SS7ISUPCall* findCall(unsigned int cic);
05936     // Send blocking/unblocking messages
05937     // Return false if no request was sent
05938     bool sendLocalLock(u_int64_t when = Time::msecNow());
05939 
05940     SS7PointCode::Type m_type;           // Point code type of this call controller
05941     ObjList m_pointCodes;                // Point codes serviced by this call controller
05942     SS7PointCode* m_defPoint;            // Default point code for outgoing calls
05943     SS7PointCode* m_remotePoint;         // Default remote point code for outgoing calls and maintenance
05944     unsigned char m_priossf;             // MSU priority + Subservice field
05945     unsigned char m_sls;                 // Last known valid SLS
05946     bool m_earlyAcm;                     // Accept progress/ringing in early ACM
05947     bool m_inn;                          // Routing to internal network number flag
05948     String m_numPlan;                    // Numbering plan
05949     String m_numType;                    // Number type
05950     String m_numPresentation;            // Number presentation
05951     String m_numScreening;               // Number screening
05952     String m_callerCat;                  // Caller party category
05953     String m_format;                     // Default format
05954     bool m_l3LinkUp;                     // Flag indicating the availability of a Layer3 data link
05955     // Remote User Part test
05956     SignallingTimer m_uptTimer;          // Timer for UPT
05957     bool m_userPartAvail;                // Flag indicating the remote User Part availability
05958     unsigned int m_uptCicCode;           // The circuit code sent with UPT
05959     // Circuit reset
05960     SignallingTimer m_rscTimer;          // RSC message or idle timeout
05961     SignallingCircuit* m_rscCic;         // Circuit currently beeing reset
05962     // Blocking/unblocking circuits
05963     SignallingTimer m_lockTimer;         // Request timeout
05964     bool m_lockGroup;                    // Allow sending requests for a group
05965     bool m_lockNeed;                     // Flag used to signal that there are circuits whose lock state changed
05966     bool m_hwFailReq;                    // HW failure/maintenance block/unblock sent
05967     bool m_blockReq;                     // Block/unblock req. sent
05968     unsigned int m_lockCicCode;          // Current (un)blocking cic code
05969     String m_lockMap;                    // The sent circuit map (contains 1 element for single circuit request)
05970     // Debug flags
05971     bool m_printMsg;                     // Print messages to output
05972     bool m_extendedDebug;                // Extended debug flag
05973 };
05974 
05979 class YSIG_API SS7BICC : public SS7ISUP
05980 {
05981     YCLASS(SS7BICC,SS7ISUP)
05982 public:
05987     SS7BICC(const NamedList& params);
05988 
05993     virtual ~SS7BICC();
05994 
06004     virtual SS7MSU* createMSU(SS7MsgISUP::Type type, unsigned char ssf,
06005         const SS7Label& label, unsigned int cic, const NamedList* params = 0) const;
06006 
06007 protected:
06016     virtual bool receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3* network, int sls);
06017 };
06018 
06023 class YSIG_API SS7TUP : public SignallingCallControl, public SS7Layer4
06024 {
06025 public:
06026     SS7TUP(const NamedList& params);
06027     virtual ~SS7TUP();
06028 };
06029 
06034 class YSIG_API SS7SCCP : public SS7Layer4, public SCCP
06035 {
06036 };
06037 
06044 class YSIG_API SS7SUA : public SIGTRAN, public SCCP
06045 {
06046 };
06047 
06052 class YSIG_API SS7ASP : public SCCPUser, virtual public SignallingComponent
06053 {
06054 protected:
06055     ObjList m_sccps;
06056 };
06057 
06062 class YSIG_API SS7TCAP : public ASPUser, virtual public SignallingComponent
06063 {
06068     void attach(TCAPUser* user);
06069 
06070 protected:
06071     ObjList m_users;
06072 };
06073 
06074 // The following classes are ISDN, not SS7, but they use the same signalling
06075 //  interfaces so they will remain here
06076 
06081 class YSIG_API ISDNLayer2 : virtual public SignallingComponent
06082 {
06083     YCLASS(ISDNLayer2,SignallingComponent)
06084     friend class ISDNQ921Management;
06085 public:
06089     enum State {
06090         Released,                        // Multiple frame acknowledged not allowed
06091         WaitEstablish,                   // Wating to establish 'multiple frame acknowledged' mode
06092         Established,                     // Multiple frame acknowledged allowed
06093         WaitRelease,                     // Wating to release 'multiple frame acknowledged' mode
06094     };
06095 
06099     virtual ~ISDNLayer2();
06100 
06104     inline ISDNLayer3* layer3() const
06105         { return m_layer3; }
06106 
06111     inline State state() const
06112         { return m_state; }
06113 
06118     inline bool network() const
06119         { return m_network; }
06120 
06125     inline bool detectType() const
06126         { return m_detectType; }
06127 
06132     inline u_int8_t localSapi() const
06133         { return m_sapi; }
06134 
06139     inline u_int8_t localTei() const
06140         { return m_tei; }
06141 
06146     inline u_int32_t maxUserData() const
06147         { return m_maxUserData; }
06148 
06153     inline bool teiAssigned() const
06154         { return m_teiAssigned; }
06155 
06160     inline bool autoRestart() const
06161         { return m_autoRestart; }
06162 
06172     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force)
06173         { return false; }
06174 
06183     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack)
06184         { return false; }
06185 
06190     virtual void cleanup() = 0;
06191 
06198     virtual void attach(ISDNLayer3* layer3);
06199 
06205     static inline const char* stateName(State s)
06206         { return lookup((int)s,m_states); }
06207 
06208 protected:
06216     ISDNLayer2(const NamedList& params, const char* name = 0, u_int8_t tei = 0);
06217 
06222     inline Mutex& l2Mutex()
06223         { return m_layerMutex; }
06224 
06233     void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout);
06234 
06243     void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout);
06244 
06255     void dataLinkState(u_int8_t tei, bool cmd, bool value);
06256 
06261     void idleTimeout();
06262 
06269     void receiveData(const DataBlock& data, u_int8_t tei);
06270 
06276     void teiAssigned(bool status);
06277 
06284     void changeState(State newState, const char* reason = 0);
06285 
06290     bool changeType();
06291 
06296     inline void autoRestart(bool restart)
06297         { m_autoRestart = restart; }
06298 
06303     inline void setRi(u_int16_t ri)
06304         { m_ri = ri; }
06305 
06311     ISDNFrame* parsePacket(const DataBlock& packet);
06312 
06313 private:
06314     ISDNLayer3* m_layer3;                // The attached Layer 3 interface
06315     Mutex m_layerMutex;                  // Layer 2 operations mutex
06316     Mutex m_layer3Mutex;                 // Control m_layer3 operations
06317     State m_state;                       // Layer's state
06318     bool m_network;                      // Network/CPE type of the interface
06319     bool m_detectType;                   // Detect interface type
06320     u_int8_t m_sapi;                     // SAPI value
06321     u_int8_t m_tei;                      // TEI value
06322     u_int16_t m_ri;                      // Reference number
06323     bool m_checked;                      // Flag to indicate if the layer was checked
06324     bool m_teiAssigned;                  // The TEI status
06325     bool m_autoRestart;                  // True to restart when released
06326     u_int32_t m_maxUserData;             // Maximum length of user data transported trough this layer
06327     unsigned int m_teiRefNumber;         // The Reference Number (Ri) carried by a TEI management frame
06328     static TokenDict m_states[];         // Keep the string associated with each state
06329 };
06330 
06335 class YSIG_API ISDNLayer3 : virtual public SignallingComponent
06336 {
06337     YCLASS(ISDNLayer3,SignallingComponent)
06338 public:
06348     virtual void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2)
06349         { }
06350 
06360     virtual void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2)
06361         { }
06362 
06374     virtual void dataLinkState(u_int8_t tei, bool cmd, bool value, ISDNLayer2* layer2)
06375         { }
06376 
06382     virtual void idleTimeout(ISDNLayer2* layer2)
06383         { }
06384 
06392     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2) = 0;
06393 
06399     virtual ISDNLayer2* attach(ISDNLayer2* layer2)
06400         { return 0; }
06401 
06402 protected:
06408     inline ISDNLayer3(const char* name = 0)
06409         : SignallingComponent(name),
06410           m_layerMutex(true,"ISDNLayer3::layer")
06411         { }
06412 
06417     inline Mutex& l3Mutex()
06418         { return m_layerMutex; }
06419 
06420 private:
06421     Mutex m_layerMutex;                  // Layer 3 operations mutex
06422 };
06423 
06428 class YSIG_API ISDNFrame : public RefObject
06429 {
06430     friend class ISDNQ921;
06431     friend class ISDNQ921Management;
06432 public:
06436     enum Type {
06437         DISC = 1,                        // disconnect (command)
06438         DM = 2,                          // disconnected (response)
06439         FRMR = 3,                        // frame reject (response)
06440         I = 4,                           // information transfer (response)
06441         REJ = 5,                         // reject (command/response)
06442         RNR = 6,                         // receive not ready (command/response)
06443         RR = 7,                          // receive ready (command/response)
06444         SABME = 8,                       // set asynchronous balanced mode extended (command)
06445         UA = 9,                          // unnumbered acknoledgement (response)
06446         UI = 10,                         // unnumbered information (command)
06447         XID = 11,                        // exchange identification (command/response)
06448         // Note: Keep all errors greater then Invalid: The code relies on it
06449         Invalid = 100,
06450         ErrUnknownCR = 101,              // Error: Unknown command/response. Set by parser
06451         ErrHdrLength = 102,              // Error: Invalid header length. Set by parser
06452         ErrDataLength = 103,             // Error: Information field too long
06453         ErrRxSeqNo = 104,                // Error: Invalid receive sequence number
06454         ErrTxSeqNo = 105,                // Error: Invalid send sequence number
06455         ErrInvalidEA = 106,              // Error: Invalid 'extended address' bit(s). Set by parser
06456         ErrInvalidAddress = 107,         // Error: Invalid SAPI/TEI
06457         ErrUnsupported = 108,            // Error: Unsupported command. E.g. XID
06458         ErrInvalidCR = 109,              // Error: Invalid command/response flag
06459     };
06460 
06464     enum TeiManagement {
06465         TeiReq       = 1,                // TEI request (user to network)
06466         TeiAssigned  = 2,                // TEI assigned (network to user)
06467         TeiDenied    = 3,                // TEI denied (network to user)
06468         TeiCheckReq  = 4,                // TEI check request (network to user)
06469         TeiCheckRsp  = 5,                // TEI check response (user to network)
06470         TeiRemove    = 6,                // TEI remove (network to user)
06471         TeiVerify    = 7                 // TEI verify (user to network)
06472     };
06473 
06477     enum Category {
06478         Data,                            // I, UI
06479         Supervisory,                     // RR, RNR, REJ
06480         Unnumbered,                      // SABME, DISC, UA DM, FRMR XID
06481         Error
06482     };
06483 
06487     virtual ~ISDNFrame();
06488 
06493     inline Type type() const
06494         { return m_type; }
06495 
06500     inline Type error() const
06501         { return m_error; }
06502 
06507     inline Category category() const
06508         { return m_category; }
06509 
06514     inline bool command() const
06515         { return m_command; }
06516 
06521     inline u_int8_t sapi() const
06522         { return m_sapi; }
06523 
06528     inline u_int8_t tei() const
06529         { return m_tei; }
06530 
06535     inline bool poll() const
06536         { return m_poll; }
06537 
06542     inline u_int8_t ns() const
06543         { return m_ns; }
06544 
06549     inline u_int8_t nr() const
06550         { return m_nr; }
06551 
06556     inline u_int8_t headerLength() const
06557         { return m_headerLength; }
06558 
06563     inline u_int32_t dataLength() const
06564         { return m_dataLength; }
06565 
06570     inline const DataBlock& buffer() const
06571         { return m_buffer; }
06572 
06577     inline bool sent() const
06578         { return m_sent; }
06579 
06583     inline void sent(bool value)
06584         { m_sent = value; }
06585 
06590     inline const char* name() const
06591         { return typeName(type()); }
06592 
06598     void update(u_int8_t* ns = 0, u_int8_t* nr = 0);
06599 
06604     inline void getData(DataBlock& dest) const
06605         { dest.assign((u_int8_t*)m_buffer.data() + m_headerLength,m_dataLength); }
06606 
06612     void toString(String& dest, bool extendedDebug) const;
06613 
06618     bool checkTeiManagement() const;
06619 
06625     static u_int16_t getRi(const DataBlock& data);
06626 
06632     inline static u_int8_t getType(const DataBlock& data)
06633         { return static_cast<u_int8_t>(data.at(3,0)); }
06634 
06640     inline static u_int8_t getAi(const DataBlock& data)
06641         { return static_cast<u_int8_t>(data.at(4,0) >> 1); }
06642 
06643 
06650     static ISDNFrame* parse(const DataBlock& data, ISDNLayer2* receiver);
06651 
06660     static bool buildTeiManagement(DataBlock& data, u_int8_t type, u_int16_t ri,
06661         u_int8_t ai);
06662 
06669     static inline bool commandBit(bool network)
06670         { return network; }
06671 
06678     static inline bool responseBit(bool network)
06679         { return !network; }
06680 
06687     static inline bool isCommand(u_int8_t cr, bool sentByNetwork)
06688         { return cr ? sentByNetwork : !sentByNetwork; }
06689 
06695     static inline const char* typeName(Type type)
06696         { return lookup(type,s_types,"Invalid frame"); }
06697 
06701     static TokenDict s_types[];
06702 
06703 protected:
06709     ISDNFrame(Type type = Invalid);
06710 
06724     ISDNFrame(Type type, bool command, bool senderNetwork,
06725         u_int8_t sapi, u_int8_t tei, bool pf, u_int8_t nr = 0);
06726 
06739     ISDNFrame(bool ack, bool senderNetwork, u_int8_t sapi, u_int8_t tei,
06740         bool pf, const DataBlock& data);
06741 
06742 private:
06743     Type m_type;                         // Frame type
06744     Type m_error;                        // Frame error type
06745     Category m_category;                 // Frame category
06746     // Address
06747     bool m_command;                      // Command/Response frame
06748     bool m_senderNetwork;                // True if the sender of this frame is the network side of the data link
06749     u_int8_t m_sapi;                     // SAPI value
06750     u_int8_t m_tei;                      // TEI value
06751     // Control
06752     bool m_poll;                         // Poll/Final flag
06753     u_int8_t m_ns;                       // N(S) value (when applicable): transmitter send sequence number
06754     u_int8_t m_nr;                       // N(R) value (when applicable): transmitter receive sequence number
06755     // Data
06756     u_int8_t m_headerLength;             // Header length
06757     u_int32_t m_dataLength;              // Data length
06758     DataBlock m_buffer;                  // Whole frame: header + data + FCS (frame check sequence = 2 bytes)
06759     // Outgoing frames only
06760     bool m_sent;                         // True if already sent
06761 };
06762 
06767 class YSIG_API ISDNQ921 : public ISDNLayer2, public SignallingReceiver, public SignallingDumpable
06768 {
06769     YCLASS2(ISDNQ921,ISDNLayer2,SignallingReceiver)
06770     friend class ISDNQ921Management;
06771 public:
06780     ISDNQ921(const NamedList& params, const char* name = 0, ISDNQ921Management* mgmt = 0, u_int8_t tei = 0);
06781 
06785     virtual ~ISDNQ921();
06786 
06792     virtual bool initialize(const NamedList* config);
06793 
06798     inline u_int64_t dataTimeout() const
06799         { return m_retransTimer.interval() * m_n200.maxVal(); }
06800 
06811     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force);
06812 
06822     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack);
06823 
06828     inline bool sendSabme()
06829         { return sendUFrame(ISDNFrame::SABME,true,true); }
06830 
06836     virtual void cleanup();
06837 
06843     inline void setDebug(bool printFrames, bool extendedDebug)
06844         { m_extendedDebug = ((m_printFrames = printFrames) && extendedDebug); }
06845 
06846 protected:
06850     virtual void destroyed()
06851     {
06852         ISDNLayer2::attach((ISDNLayer3*)0);
06853         TelEngine::destruct(SignallingReceiver::attach(0));
06854         SignallingComponent::destroyed();
06855     }
06856 
06862     virtual void timerTick(const Time& when);
06863 
06870     virtual bool receivedPacket(const DataBlock& packet);
06871 
06877     bool receivedFrame(ISDNFrame* frame);
06878 
06885     virtual bool notify(SignallingInterface::Notification event);
06886 
06891     void reset();
06892 
06893 private:
06894     virtual bool control(NamedList& params)
06895         { return SignallingDumpable::control(params,this); }
06896     // Acknoledge outgoing frames
06897     // @param frame The acknoledging frame
06898     bool ackOutgoingFrames(const ISDNFrame* frame);
06899     // Process a received I/UI frame
06900     // @param ack True for I frame, false for UI frame
06901     // @return True to send data to Layer 3
06902     bool processDataFrame(const ISDNFrame* frame, bool ack);
06903     // Process a received S frame
06904     // @return True to exit from timer recovery state
06905     bool processSFrame(const ISDNFrame* frame);
06906     // Process a received U frame
06907     // @param newState The new state if true is returned
06908     // @param confirmation True if the new state is Established or Released and
06909     //  this is a confirmation
06910     // @return True to change state
06911     bool processUFrame(const ISDNFrame* frame, State& newState,
06912         bool& confirmation);
06913     // Accept frame according to Q.921 5.8.5
06914     // Update counters.
06915     // If not accepted the frame is rejected or dropped
06916     // reject is set to true if the frame is rejected
06917     bool acceptFrame(ISDNFrame* frame, bool& reject);
06918     // Update rejected frames counter. Print message. Send FRMR (frame reject)
06919     void rejectFrame(const ISDNFrame* frame, const char* reason = 0);
06920     // Update dropped frames counter. Print message
06921     void dropFrame(const ISDNFrame* frame, const char* reason = 0);
06922     // Send S frames other then UI frames
06923     bool sendUFrame(ISDNFrame::Type type, bool command, bool pf,
06924         bool retrans = false);
06925     // Send U frames
06926     bool sendSFrame(ISDNFrame::Type type, bool command, bool pf);
06927     // Send a frame to remote peer
06928     // @param frame Frame to send
06929     // @return False if the operation failed
06930     bool sendFrame(const ISDNFrame* frame);
06931     // Send pending outgoing I frames
06932     // @param retrans: True   Send all transmission window
06933     //                 False  Send only the unsent frames in transmission window
06934     // @return True if a transmission took place
06935     bool sendOutgoingData(bool retrans = false);
06936     // Start/Stop T200. Stop/Start T203
06937     // If start is false reset N200 (retransmission counter)
06938     // @param start True to start. False to stop
06939     // @param t203 Start/don't start T203. Ignored if start is false
06940     // @param time Current time if known
06941     void timer(bool start, bool t203, u_int64_t time = 0);
06942 
06943     ISDNQ921Management* m_management;    // TEI management component
06944     // State variables
06945     bool m_remoteBusy;                   // Remote peer is busy: don't send any I frames
06946     bool m_timerRecovery;                // T200 expired
06947     bool m_rejectSent;                   // True if we've sent a REJ frame
06948     bool m_pendingDMSabme;               // True if we have a pending SABME on DM received
06949     bool m_lastPFBit;                    // Last P/F bit sent with an I or S frame
06950     u_int8_t m_vs;                       // Sequence number of the next transmitted I frame
06951     u_int8_t m_va;                       // Last ack'd I frame by remote peer
06952     u_int8_t m_vr;                       // Expected I frame sequence number
06953     // Timers and counters
06954     SignallingTimer m_retransTimer;      // T200: Retransmission interval
06955     SignallingTimer m_idleTimer;         // T203: Channel idle interval
06956     SignallingCounter m_window;          // Maximum/current number of pending outgoing I frames
06957     SignallingCounter m_n200;            // Maximum/current retransmission counter
06958     // Data
06959     ObjList m_outFrames;                 // Outgoing I frames queue
06960     // Statistics
06961     u_int32_t m_txFrames;                // The number of frames accepted by layer 1 to be transmitted
06962     u_int32_t m_txFailFrames;            // The number of frames not accepted by layer 1 to be transmitted
06963     u_int32_t m_rxFrames;                // The number of succesfully parsed frames
06964     u_int32_t m_rxRejectedFrames;        // The number of rejected frames. Doesn't include dropped frames
06965     u_int32_t m_rxDroppedFrames;         // The number of dropped frames. Doesn't include rejected frames
06966     u_int32_t m_hwErrors;                // The number of hardware notifications
06967     // Debug flags
06968     bool m_printFrames;                  // Print frames to output
06969     bool m_extendedDebug;                // Extended debug flag
06970     // Flags used to avoid repetitive errors
06971     bool m_errorSend;                    // Send error
06972     bool m_errorReceive;                 // Receive error
06973 };
06974 
06982 class YSIG_API ISDNQ921Management : public ISDNLayer2, public ISDNLayer3, public SignallingReceiver, public SignallingDumpable
06983 {
06984     YCLASS3(ISDNQ921Management,ISDNLayer2,ISDNLayer3,SignallingReceiver)
06985 public:
06992     ISDNQ921Management(const NamedList& params, const char* name = 0, bool net = true);
06993 
06997     virtual ~ISDNQ921Management();
06998 
07004     virtual bool initialize(const NamedList* config);
07005 
07010     virtual void engine(SignallingEngine* eng);
07011 
07019     virtual bool multipleFrame(u_int8_t tei, bool establish, bool force);
07020 
07028     virtual bool sendData(const DataBlock& data, u_int8_t tei, bool ack);
07029 
07036     bool sendFrame(const ISDNFrame* frame, const ISDNQ921* q921 = 0);
07037 
07038 
07043     virtual void cleanup();
07044 
07054     virtual void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
07055 
07065     virtual void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
07066 
07078     virtual void dataLinkState(u_int8_t tei, bool cmd, bool value, ISDNLayer2* layer2);
07079 
07087     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2);
07088 
07089 protected:
07095     virtual void timerTick(const Time& when);
07096 
07103     virtual bool receivedPacket(const DataBlock& packet);
07104 
07110     virtual bool notify(SignallingInterface::Notification event);
07111 
07117     bool processTeiManagement(ISDNFrame* frame);
07118 
07128     bool sendTeiManagement(ISDNFrame::TeiManagement type, u_int16_t ri, u_int8_t ai, u_int8_t tei = 127, bool pf = false);
07129 
07141     void processTeiRequest(u_int16_t ri, u_int8_t ai, bool pf);
07142 
07147     void processTeiRemove(u_int8_t ai);
07148 
07155     void processTeiCheckRequest(u_int8_t ai, bool pf);
07156 
07162     void processTeiCheckResponse(u_int16_t ri, u_int8_t ai);
07163 
07169     void processTeiAssigned(u_int16_t ri, u_int8_t ai);
07170 
07175     void processTeiDenied(u_int16_t ri);
07176 
07182     void processTeiVerify(u_int8_t ai, bool pf);
07183 
07188     void sendTeiReq(u_int8_t tei);
07189 
07193     void sendTeiRemove();
07194 
07195 private:
07196     ISDNQ921* m_layer2[127];             // The list of Layer 2 objects attached to this Layer 3
07197     SignallingTimer m_teiManTimer;       // T202
07198     SignallingTimer m_teiTimer;          // T201
07199 };
07200 
07205 class YSIG_API ISDNQ921Passive : public ISDNLayer2, public SignallingReceiver, public SignallingDumpable
07206 {
07207     YCLASS2(ISDNQ921Passive,ISDNLayer2,SignallingReceiver)
07208 public:
07215     ISDNQ921Passive(const NamedList& params, const char* name = 0);
07216 
07220     virtual ~ISDNQ921Passive();
07221 
07227     virtual void cleanup();
07228 
07234     virtual bool initialize(const NamedList* config);
07235 
07241     inline void setDebug(bool printFrames, bool extendedDebug)
07242         { m_extendedDebug = ((m_printFrames = printFrames) && extendedDebug); }
07243 
07244 protected:
07248     virtual void destroyed()
07249     {
07250         ISDNLayer2::attach(0);
07251         TelEngine::destruct(SignallingReceiver::attach(0));
07252         SignallingComponent::destroyed();
07253     }
07254 
07260     virtual void timerTick(const Time& when);
07261 
07268     virtual bool receivedPacket(const DataBlock& packet);
07269 
07276     virtual bool notify(SignallingInterface::Notification event);
07277 
07278 private:
07279     virtual bool control(NamedList& params)
07280         { return SignallingDumpable::control(params,this); }
07281     // Filter received frames. Accept only frames that would generate a notification to the upper layer:
07282     // UI/I, and Valid SABME/DISC/UA/DM
07283     // On success, if frame is not a data one, prepare cmd and value to notify layer 3
07284     bool acceptFrame(ISDNFrame* frame, bool& cmd, bool& value);
07285     // Show debug message. Count dropped frames
07286     bool dropFrame(const ISDNFrame* frame, const char* reason = 0);
07287 
07288     bool m_checkLinkSide;                // Check if this is the correct side of the data link
07289     SignallingTimer m_idleTimer;         // Channel idle interval
07290     u_int8_t m_lastFrame;                // Transmitter send number of the last received frame
07291     u_int32_t m_rxFrames;                // The number of succesfully parsed frames
07292     u_int32_t m_rxRejectedFrames;        // The number of rejected frames. Doesn't include dropped frames
07293     u_int32_t m_rxDroppedFrames;         // The number of dropped frames. Doesn't include rejected frames
07294     u_int32_t m_hwErrors;                // The number of hardware notifications
07295     bool m_printFrames;                  // Print frames to output
07296     bool m_extendedDebug;                // Extended debug flag
07297     bool m_errorReceive;                 // Receive error
07298 };
07299 
07306 class YSIG_API ISDNIUA : public ISDNLayer2, public SIGTRAN
07307 {
07308     YCLASS(ISDNIUA,ISDNLayer2)
07309 protected:
07316     inline ISDNIUA(const NamedList& params, const char* name = 0)
07317         : ISDNLayer2(params,name)
07318         { }
07319 
07323     virtual ~ISDNIUA()
07324         { }
07325 };
07326 
07331 class YSIG_API ISDNQ931IE : public NamedList
07332 {
07333     friend class ISDNQ931Message;
07334 public:
07338     enum Type {
07339         // Fixed (1 byte) length information element
07340         Shift = 0x90,                    // Shift
07341         MoreData = 0xa0,                 // More data
07342         SendComplete = 0xa1,             // Sending complete
07343         Congestion = 0xb0,               // Congestion level
07344         Repeat = 0xd0,                   // Repeat indicator
07345         // Variable length information element
07346         Segmented = 0x00,                // Segmented message
07347         BearerCaps = 0x04,               // Bearer capability
07348         Cause = 0x08,                    // Cause
07349         CallIdentity = 0x10,             // Call identity
07350         CallState = 0x14,                // Call state
07351         ChannelID = 0x18,                // Channel identification
07352         Progress = 0x1e,                 // Progress indicator
07353         NetFacility = 0x20,              // Network-specific facilities
07354         Notification = 0x27,             // Notification indicator
07355         Display = 0x28,                  // Display
07356         DateTime = 0x29,                 // Date/time
07357         Keypad = 0x2c,                   // Keypad facility
07358         Signal = 0x34,                   // Signal
07359         ConnectedNo = 0x4c,              // Connected number (Q.951)
07360         CallingNo = 0x6c,                // Calling party number
07361         CallingSubAddr = 0x6d,           // Calling party subaddress
07362         CalledNo = 0x70,                 // Called party number
07363         CalledSubAddr = 0x71,            // Called party subaddress
07364         NetTransit = 0x78,               // Transit network selection
07365         Restart = 0x79,                  // Restart indicator
07366         LoLayerCompat = 0x7c,            // Low layer compatibility
07367         HiLayerCompat = 0x7d,            // High layer compatibility
07368         // Not used
07369         UserUser = 0x7e,                 // User-user
07370         Escape = 0x7f,                   // Escape for extension
07371     };
07372 
07378     ISDNQ931IE(u_int16_t type);
07379 
07383     virtual ~ISDNQ931IE();
07384 
07389     inline u_int8_t type() const
07390         { return (u_int8_t)m_type; }
07391 
07397     inline void addParamPrefix(const char* name, const char* value)
07398         { addParam(*this+"."+name,value); }
07399 
07407     void toString(String& dest, bool extendedDebug, const char* before = 0);
07408 
07415     static inline const char* typeName(int type, const char* defVal = 0)
07416         { return lookup(type,s_type,defVal); }
07417 
07421     static TokenDict s_type[];
07422 
07426     DataBlock m_buffer;
07427 
07428 private:
07429     u_int16_t m_type;                    // IE type
07430 };
07431 
07436 class YSIG_API ISDNQ931Message : public SignallingMessage
07437 {
07438 public:
07442     enum Type {
07443         Alerting = 0x01,                 // ALERTING
07444         Proceeding = 0x02,               // CALL PROCEEDING
07445         Connect = 0x07,                  // CONNECT
07446         ConnectAck = 0x0f,               // CONNECT ACK
07447         Progress = 0x03,                 // PROGRESS
07448         Setup = 0x05,                    // SETUP
07449         SetupAck = 0x0d,                 // SETUP ACK
07450         Resume = 0x26,                   // RESUME
07451         ResumeAck = 0x2e,                // RESUME ACK
07452         ResumeRej = 0x22,                // RESUME REJECT
07453         Suspend = 0x25,                  // SUSPEND
07454         SuspendAck = 0x2d,               // SUSPEND ACK
07455         SuspendRej = 0x21,               // SUSPEND REJECT
07456         UserInfo = 0x20,                 // USER INFO
07457         Disconnect = 0x45,               // DISCONNECT
07458         Release = 0x4d,                  // RELEASE
07459         ReleaseComplete = 0x5a,          // RELEASE COMPLETE
07460         Restart = 0x46,                  // RESTART
07461         RestartAck = 0x4e,               // RESTART ACK
07462         Segment = 0x60,                  // SEGMENT
07463         CongestionCtrl = 0x79,           // CONGESTION CONTROL
07464         Info = 0x7b,                     // INFORMATION
07465         Notify = 0x6e,                   // NOTIFY
07466         Status = 0x7d,                   // STATUS
07467         StatusEnquiry = 0x75,            // STATUS ENQUIRY
07468     };
07469 
07478     ISDNQ931Message(Type type, bool initiator, u_int32_t callRef, u_int8_t callRefLen);
07479 
07485     ISDNQ931Message(Type type);
07486 
07493     ISDNQ931Message(Type type, ISDNQ931Call* call);
07494 
07498     virtual ~ISDNQ931Message();
07499 
07504     inline Type type() const
07505         { return m_type; }
07506 
07511     inline bool initiator() const
07512         { return m_initiator; }
07513 
07518     inline u_int32_t callRef() const
07519         { return m_callRef; }
07520 
07525     inline u_int8_t callRefLen() const
07526         { return m_callRefLen; }
07527 
07532     inline bool dummyCallRef() const
07533         { return m_dummy; }
07534 
07539     inline bool unknownMandatory() const
07540         { return m_unkMandatory; }
07541 
07545     inline void setUnknownMandatory()
07546         { m_unkMandatory = true; }
07547 
07552     inline ObjList* ieList()
07553         { return &m_ie; }
07554 
07561     ISDNQ931IE* getIE(ISDNQ931IE::Type type, ISDNQ931IE* base = 0);
07562 
07569     ISDNQ931IE* removeIE(ISDNQ931IE::Type type, ISDNQ931IE* base = 0);
07570 
07578     inline const char* getIEValue(ISDNQ931IE::Type type, const char* param,
07579         const char* defVal = 0)
07580     {
07581         ISDNQ931IE* ie = getIE(type);
07582         return (ie ? ie->getValue(param?param:ie->c_str(),defVal) : defVal);
07583     }
07584 
07592     inline ISDNQ931IE* appendIEValue(ISDNQ931IE::Type type, const char* param,
07593         const char* value)
07594     {
07595         ISDNQ931IE* ie = new ISDNQ931IE(type);
07596         ie->addParam(param?param:ie->c_str(),value);
07597         appendSafe(ie);
07598         return ie;
07599     }
07600 
07606     inline bool append(ISDNQ931IE* ie)
07607         { return 0 != m_ie.append(ie); }
07608 
07615     bool appendSafe(ISDNQ931IE* ie);
07616 
07624     void toString(String& dest, bool extendedDebug, const char* indent = 0) const;
07625 
07631     virtual void* getObject(const String& name) const;
07632 
07643     u_int8_t encode(ISDNQ931ParserData& parserData, ObjList& dest);
07644 
07654     static ISDNQ931Message* parse(ISDNQ931ParserData& parserData,
07655         const DataBlock& buffer, DataBlock* segData);
07656 
07662     static inline const char* typeName(int t)
07663         { return lookup(t,s_type,"Unknown"); }
07664 
07668     static TokenDict s_type[];
07669 
07673     DataBlock m_buffer;
07674 
07675 private:
07676     Type m_type;                         // Message type
07677     bool m_initiator;                    // The call initiator flag: True: this is the initiator
07678     u_int32_t m_callRef;                 // The call reference
07679     u_int8_t m_callRefLen;               // The call reference length
07680     bool m_unkMandatory;                 // True if this message contains unknown mandatory IE(s)
07681     bool m_dummy;                        // True if this message has a dummy call reference
07682     ObjList m_ie;                        // IE list
07683 };
07684 
07689 class YSIG_API ISDNQ931IEData
07690 {
07691     friend class ISDNQ931Call;
07692     friend class ISDNQ931CallMonitor;
07693     friend class ISDNQ931;
07694     friend class ISDNQ931Monitor;
07695 private:
07696     // Constructor
07697     ISDNQ931IEData(bool bri = false);
07698     // Process received IEs
07699     // If add is true, append an IE to the message
07700     // If add is false, extract data from message. Set data to default values if IE is missing
07701     // @return False if the IE is missing when decoding or the IE wasn't added
07702     bool processBearerCaps(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07703     bool processCause(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07704     bool processDisplay(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07705     bool processKeypad(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07706     bool processChannelID(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07707     bool processProgress(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07708     bool processRestart(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07709     bool processNotification(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07710     bool processCalledNo(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07711     bool processCallingNo(ISDNQ931Message* msg, bool add, ISDNQ931ParserData* data = 0);
07712 
07713     // IE parameters
07714     String m_display;                    // Display: The data
07715     String m_callerNo;                   // CallingNo: Number
07716     String m_callerType;                 // CallingNo: Number type
07717     String m_callerPlan;                 // CallingNo: Number plan
07718     String m_callerPres;                 // CallingNo: Number presentation
07719     String m_callerScreening;            // CallingNo: Number screening
07720     String m_calledNo;                   // CalledNo: Number
07721     String m_calledType;                 // CalledNo: Number type
07722     String m_calledPlan;                 // CalledNo: Number plan
07723     String m_transferCapability;         // BearerCaps: Transfer capability
07724     String m_transferMode;               // BearerCaps: Transfer mode
07725     String m_transferRate;               // BearerCaps: Transfer rate
07726     String m_format;                     // BearerCaps: Layer 1 protocol
07727     String m_reason;                     // Cause
07728     String m_keypad;                     // Keypad: 'keypad' parameter
07729     String m_progress;                   // Progress: Progress description
07730     String m_notification;               // Notify: Notification indicator
07731     bool m_bri;                          // ChannelID: BRI interface flag
07732     bool m_channelMandatory;             // ChannelID: Indicated channel is mandatory/preferred
07733     bool m_channelByNumber;              // ChannelID: m_channels contains a channel list or a slot map
07734     String m_channelType;                // ChannelID: Channel type
07735     String m_channelSelect;              // ChannelID: Channel select
07736     String m_channels;                   // ChannelID: Channel list or slot map
07737     String m_restart;                    // Restart: The class of restarting circuits
07738 };
07739 
07744 class YSIG_API ISDNQ931State
07745 {
07746 public:
07750     enum State {
07751         // Common state
07752         Null                    = 0x00,  // Null
07753         // Call states
07754         CallInitiated           = 0x01,  // Call initiated: sent SETUP
07755         OverlapSend             = 0x02,  // Overlap sending
07756         OutgoingProceeding      = 0x03,  // Outgoing call proceeding: received valid CALL PROCEEDING
07757         CallDelivered           = 0x04,  // Call delivered: received valid ALERTING
07758         CallPresent             = 0x06,  // Call present: received valid SETUP or recover from STATUS
07759         CallReceived            = 0x07,  // Call received: sent ALERTING or recover from STATUS
07760         ConnectReq              = 0x08,  // Connect request: sent/received valid CONNECT or recover from STATUS
07761         IncomingProceeding      = 0x09,  // Incoming call proceeding: sent CALL PROCEEDING or recover from STATUS
07762         Active                  = 0x0a,  // Active: sent/received valid CONNECT ACK
07763         DisconnectReq           = 0x0b,  // Disconnect request: sent DISCONNECT
07764         DisconnectIndication    = 0x0c,  // Disconnect indication: received valid DISCONNECT
07765         SuspendReq              = 0x0f,  // Suspend request
07766         ResumeReq               = 0x11,  // Resume reques
07767         ReleaseReq              = 0x13,  // Release request: sent/received valid RELEASE
07768         CallAbort               = 0x16,  // Call abort: received STATUS in Null state with remote not in Null state
07769         OverlapRecv             = 0x19,  // Overlap receiving
07770         // Call controller states
07771         RestartReq              = 0x3d,  // Restart request
07772         Restart                 = 0x3e,  // Restart
07773     };
07774 
07778    inline ISDNQ931State() : m_state(Null)
07779         { }
07780 
07785     inline State state() const
07786         { return m_state; }
07787 
07793     static const char* stateName(u_int8_t s)
07794         { return lookup(s,s_states,0); }
07795 
07799     static TokenDict s_states[];
07800 
07801 protected:
07808     bool checkStateRecv(int type, bool* retrans);
07809 
07815     bool checkStateSend(int type);
07816 
07820     State m_state;
07821 
07822 };
07823 
07828 class YSIG_API ISDNQ931Call : public ISDNQ931State, public SignallingCall
07829 {
07830     friend class ISDNQ931;
07831 public:
07835     virtual ~ISDNQ931Call();
07836 
07841     inline u_int32_t callRef() const
07842         { return m_callRef; }
07843 
07848     inline u_int32_t callRefLen() const
07849         { return m_callRefLen; }
07850 
07855     inline u_int8_t callTei() const
07856         { return m_tei; }
07857 
07862     inline SignallingCircuit* circuit()
07863         { return m_circuit; }
07864 
07871     void setTerminate(bool destroy, const char* reason);
07872 
07879     virtual bool sendEvent(SignallingEvent* event);
07880 
07887     virtual SignallingEvent* getEvent(const Time& when);
07888 
07894     void dataLinkState(bool up);
07895 
07901     virtual void* getObject(const String& name) const;
07902 
07903 protected:
07912     ISDNQ931Call(ISDNQ931* controller, bool outgoing, u_int32_t callRef,
07913         u_int8_t callRefLen, u_int8_t tei = 0);
07914 
07923     SignallingEvent* releaseComplete(const char* reason = 0, const char* diag = 0);
07924 
07930     SignallingEvent* getCircuitEvent(const Time& when);
07931 
07932 private:
07933     // Reserve and connect a circuit. Change the reserved one if it must to
07934     bool reserveCircuit();
07935     // Process call when terminate flag is set. Check timeout
07936     // @param msg Optional message extracted from queue
07937     SignallingEvent* processTerminate(ISDNQ931Message* msg = 0);
07938     // Check timer(s)
07939     SignallingEvent* checkTimeout(u_int64_t time);
07940     // Check received messages for valid state
07941     // True to send status if not accepted
07942     bool checkMsgRecv(ISDNQ931Message* msg, bool status);
07943     // Process received messages
07944     // @param msg Valid ISDNQ931Message pointer
07945     SignallingEvent* processMsgAlerting(ISDNQ931Message* msg);
07946     SignallingEvent* processMsgCallProceeding(ISDNQ931Message* msg);
07947     SignallingEvent* processMsgConnect(ISDNQ931Message* msg);
07948     SignallingEvent* processMsgConnectAck(ISDNQ931Message* msg);
07949     SignallingEvent* processMsgDisconnect(ISDNQ931Message* msg);
07950     SignallingEvent* processMsgInfo(ISDNQ931Message* msg);
07951     SignallingEvent* processMsgNotify(ISDNQ931Message* msg);
07952     SignallingEvent* processMsgProgress(ISDNQ931Message* msg);
07953     SignallingEvent* processMsgRelease(ISDNQ931Message* msg);
07954     SignallingEvent* processMsgSetup(ISDNQ931Message* msg);
07955     SignallingEvent* processMsgSetupAck(ISDNQ931Message* msg);
07956     SignallingEvent* processMsgStatus(ISDNQ931Message* msg);
07957     SignallingEvent* processMsgStatusEnquiry(ISDNQ931Message* msg);
07958     // Send message
07959     // @param msg Pointer to SignallingMessage with parameters
07960     bool sendAlerting(SignallingMessage* sigMsg);
07961     bool sendCallProceeding(SignallingMessage* sigMsg);
07962     bool sendConnect(SignallingMessage* sigMsg);
07963     bool sendConnectAck(SignallingMessage* sigMsg);
07964     bool sendDisconnect(SignallingMessage* sigMsg);
07965     bool sendInfo(SignallingMessage* sigMsg);
07966     bool sendProgress(SignallingMessage* sigMsg);
07967     bool sendRelease(const char* reason = 0, SignallingMessage* sigMsg = 0);
07968     bool sendReleaseComplete(const char* reason = 0, const char* diag = 0, u_int8_t tei = 0);
07969     bool sendSetup(SignallingMessage* sigMsg);
07970     bool sendSuspendRej(const char* reason = 0, SignallingMessage* sigMsg = 0);
07971     bool sendSetupAck();
07972     // Errors on processing received messages
07973     // Missing mandatory IE
07974     // @param release True to send release complete and generate a release event
07975     SignallingEvent* errorNoIE(ISDNQ931Message* msg, ISDNQ931IE::Type type, bool release);
07976     SignallingEvent* errorWrongIE(ISDNQ931Message* msg, ISDNQ931IE::Type type, bool release);
07977     // Change call state
07978     void changeState(State newState);
07979     // Remove the call from controller's list
07980     void removeFromController();
07981     // Get the Q931 call controller
07982     inline ISDNQ931* q931();
07983 
07984     // Call data
07985     u_int32_t m_callRef;                 // Call reference
07986     u_int32_t m_callRefLen;              // Call reference length
07987     u_int8_t m_tei;                      // TEI used for the call
07988     SignallingCircuit* m_circuit;        // Circuit reserved for this call
07989     bool m_overlap;                      // Call is using overlapped sending
07990     bool m_circuitChange;                // True if circuit changed
07991     bool m_channelIDSent;                // Incoming calls: ChannelID IE already sent
07992     bool m_rspBearerCaps;                // Incoming calls: Send BearerCaps IE in the first response
07993     bool m_net;                          // Flag indicating call is sent by a NT
07994     ISDNQ931IEData m_data;               // Data to process IEs
07995     ObjList m_inMsg;                     // Incoming message queue
07996     bool m_broadcast[127];               // TEIs that answered to PTMP SETUP
07997     // Timers
07998     SignallingTimer m_discTimer;         // T305: sending DISCONNECT
07999     SignallingTimer m_relTimer;          // T308: sending RELEASE
08000     SignallingTimer m_conTimer;          // T313: sending CONNECT
08001     SignallingTimer m_overlapSendTimer;  // T302 for overlapped sending
08002     SignallingTimer m_overlapRecvTimer;  // T304
08003     SignallingTimer m_retransSetupTimer; // T302 for setup retransmission (PTMP)
08004     // Termination
08005     bool m_terminate;                    // Terminate flag: send RELEASE
08006     bool m_destroy;                      // Destroy flag: call releaseComplete()
08007     bool m_destroyed;                    // Call destroyed flag
08008 };
08009 
08014 class YSIG_API ISDNQ931CallMonitor : public ISDNQ931State, public SignallingCall
08015 {
08016     friend class ISDNQ931Monitor;
08017 public:
08021     virtual ~ISDNQ931CallMonitor();
08022 
08027     inline bool netInit() const
08028         { return m_netInit; }
08029 
08036     virtual SignallingEvent* getEvent(const Time& when);
08037 
08043     void setTerminate(const char* reason);
08044 
08050     virtual void* getObject(const String& name) const;
08051 
08052 protected:
08059     ISDNQ931CallMonitor(ISDNQ931Monitor* controller, u_int32_t callRef, bool netInit);
08060 
08067     SignallingEvent* releaseComplete(const char* reason = 0);
08068 
08069 private:
08070     // Get an event from one of the reserved circuits
08071     SignallingEvent* getCircuitEvent(const Time& when);
08072     // Process received setup message
08073     SignallingEvent* processMsgSetup(ISDNQ931Message* msg);
08074     // Process received responses to setup message (Proceeding, Alerting, Connect)
08075     SignallingEvent* processMsgResponse(ISDNQ931Message* msg);
08076     // Process termination messages (Disconnect, Release, Release Complete)
08077     SignallingEvent* processMsgTerminate(ISDNQ931Message* msg);
08078     // Process INFORMATION messages to get tones
08079     SignallingEvent* processMsgInfo(ISDNQ931Message* msg);
08080     // Reserve/release the circuits
08081     bool reserveCircuit();
08082     void releaseCircuit();
08083     // Connect the caller's or called's circuit
08084     bool connectCircuit(bool caller);
08085     // Change call state
08086     void changeState(State newState);
08087     // Remove the call from controller's list
08088     void removeFromController();
08089     // Get the Q931Monitor call controller
08090     inline ISDNQ931Monitor* q931();
08091 
08092     u_int32_t m_callRef;                 // Call reference
08093     SignallingCircuit* m_callerCircuit;  // Circuit reserved for caller
08094     SignallingCircuit* m_calledCircuit;  // Circuit reserved for called
08095     SignallingCircuit* m_eventCircuit;   // Last circuit that generated an event
08096     bool m_netInit;                      // The call initiator is from the network side of the link
08097     bool m_circuitChange;                // True if circuit changed
08098     ISDNQ931IEData m_data;               // Data to process IEs
08099     bool m_terminate;                    // Terminate flag
08100     String m_terminator;                 // The name of the entity that terminated the call
08101     ObjList m_inMsg;                     // Incoming messages queue
08102 };
08103 
08108 class YSIG_API ISDNQ931ParserData
08109 {
08110 public:
08116     ISDNQ931ParserData(const NamedList& params, DebugEnabler* dbg = 0);
08117 
08123     inline bool flag(int mask)
08124         { return (0 != (m_flags & mask)); }
08125 
08126     DebugEnabler* m_dbg;                 // The debug enabler used for output
08127     u_int32_t m_maxMsgLen;               // Maximum length of outgoing messages (or message segments)
08128     int m_flags;                         // The current behaviour flags
08129     int m_flagsOrig;                     // The original behaviour flags
08130     u_int8_t m_maxDisplay;               // Max Display IE size
08131     bool m_allowSegment;                 // True if message segmentation is allowed
08132     u_int8_t m_maxSegments;              // Maximum allowed segments for outgoing messages
08133     bool m_extendedDebug;                // True to fill message/IE buffer
08134 };
08135 
08140 class YSIG_API ISDNQ931 : public SignallingCallControl, public SignallingDumpable, public ISDNLayer3
08141 {
08142     YCLASS(ISDNQ931,ISDNLayer3)
08143     friend class ISDNQ931Call;
08144 public:
08149     enum BehaviourFlags {
08150         // Append the progress indicator 'non-isdn-source' if present when
08151         // sending SETUP. If this flag is not set, the indicator will be
08152         // removed from the message
08153         SendNonIsdnSource = 0x00000001,
08154         // Ignore (don't send) the progress indicator 'non-isdn-destination'
08155         // if present when sending SETUP ACKNOWLEDGE or CONNECT
08156         IgnoreNonIsdnDest = 0x00000002,
08157         // Always set presentation='allowed' and screening='network-provided'
08158         // for Calling Party Number IE
08159         ForcePresNetProv = 0x00000004,
08160         // Translate '3.1khz-audio' transfer capability code 0x10 to/from 0x08
08161         Translate31kAudio = 0x00000008,
08162         // Send only tranfer mode and rate when sending the Bearer Capability IE
08163         // with transfer capability 'udi' or 'rdi' (unrestricted/restricted
08164         // digital information)
08165         URDITransferCapsOnly = 0x00000010,
08166         // Don't send Layer 1 capabilities (data format) with the
08167         // Bearer Capability IE when in circuit switch mode
08168         NoLayer1Caps = 0x00000020,
08169         // Don't parse incoming IEs found after a temporary (non-locking) shift
08170         IgnoreNonLockedIE = 0x00000040,
08171         // Don't send the Display IE
08172         // This flag is internally set for EuroIsdnE1 type when the call
08173         // controller is the CPE side of the link
08174         NoDisplayIE = 0x00000080,
08175         // Don't append a charset byte 0xb1 before Display data
08176         NoDisplayCharset = 0x00000100,
08177         // Send a Sending Complete IE even if no overlap dialing
08178         ForceSendComplete = 0x00000200,
08179         // Don't change call state to Active instead of ConnectRequest after
08180         // sending CONNECT. This flag is internally set when the call
08181         // controller is the CPE side of the data link
08182         NoActiveOnConnect = 0x00000400,
08183         // Check the validity of the notification indicator when sending a NOTIFY message
08184         CheckNotifyInd = 0x00000800,
08185     };
08186 
08190     enum SwitchType {
08191         Unknown      = 0,
08192         // Standard Euro ISDN (CTR4, ETSI 300-102)
08193         EuroIsdnE1   = ForceSendComplete|CheckNotifyInd|NoDisplayCharset|URDITransferCapsOnly,
08194         // T1 Euro ISDN variant (ETSI 300-102)
08195         EuroIsdnT1   = ForceSendComplete|CheckNotifyInd,
08196         // National ISDN
08197         NationalIsdn = SendNonIsdnSource,
08198         // DMS 100
08199         Dms100       = ForcePresNetProv|IgnoreNonIsdnDest,
08200         // Lucent 5E
08201         Lucent5e     = IgnoreNonLockedIE,
08202         // AT&T 4ESS
08203         Att4ess      = ForcePresNetProv|IgnoreNonLockedIE|Translate31kAudio|NoLayer1Caps,
08204         // QSIG Switch
08205         QSIG         = NoActiveOnConnect|NoDisplayIE|NoDisplayCharset
08206     };
08207 
08214     ISDNQ931(const NamedList& params, const char* name = 0);
08215 
08220     virtual ~ISDNQ931();
08221 
08227     virtual bool initialize(const NamedList* config);
08228 
08233     inline const ISDNLayer2* layer2() const
08234         { return m_q921; }
08235 
08240     inline bool primaryRate() const
08241         { return m_primaryRate; }
08242 
08247     inline bool network() const
08248         { return m_q921 ? m_q921->network() : m_networkHint; }
08249 
08254     inline bool transferModeCircuit() const
08255         { return m_transferModeCircuit; }
08256 
08261     inline ISDNQ931ParserData& parserData()
08262         { return m_parserData; }
08263 
08268     inline const String& numPlan() const
08269         { return m_numPlan; }
08270 
08275     inline const String& numType() const
08276         { return m_numType; }
08277 
08282     inline const String& numPresentation() const
08283         { return m_numPresentation; }
08284 
08289     inline const String& numScreening() const
08290         { return m_numScreening; }
08291 
08296     inline const String& format() const
08297         { return m_format; }
08298 
08306     bool sendMessage(ISDNQ931Message* msg, u_int8_t tei, String* reason = 0);
08307 
08316     virtual void multipleFrameEstablished(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
08317 
08326     virtual void multipleFrameReleased(u_int8_t tei, bool confirm, bool timeout, ISDNLayer2* layer2);
08327 
08334     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2);
08335 
08342     virtual ISDNLayer2* attach(ISDNLayer2* q921);
08343 
08350     SignallingCall* call(SignallingMessage* msg, String& reason);
08351 
08357     bool restart(const char* circuits);
08358 
08368     inline bool sendStatus(ISDNQ931Call* call, const char* cause, u_int8_t tei = 0,
08369         const char* display = 0, const char* diagnostic = 0)
08370     {
08371         return call && sendStatus(cause,call->callRefLen(),call->callRef(),tei,
08372             call->outgoing(),call->state(),display,diagnostic);
08373     }
08374 
08386     inline bool sendRelease(ISDNQ931Call* call, bool release, const char* cause, u_int8_t tei = 0,
08387         const char* diag = 0, const char* display = 0, const char* signal = 0)
08388     {
08389         return call && sendRelease(release,call->callRefLen(),call->callRef(),tei,
08390             call->outgoing(),cause,diag,display,signal);
08391     }
08392 
08398     virtual void cleanup(const char* reason = "offline");
08399 
08406     void setInterval(SignallingTimer& timer, int id);
08407 
08411     void manageTimeout();
08412 
08418     inline void setDebug(bool printMsg, bool extendedDebug)
08419         { m_parserData.m_extendedDebug = m_extendedDebug =
08420             ((m_printMsg = printMsg) && extendedDebug); }
08421 
08425     static TokenDict s_flags[];
08426 
08430     static TokenDict s_swType[];
08431 
08432 protected:
08436     virtual void destroyed()
08437     {
08438         TelEngine::destruct(attach(0));
08439         TelEngine::destruct(SignallingCallControl::attach(0));
08440         ISDNLayer3::destroyed();
08441     }
08442 
08448     virtual void timerTick(const Time& when);
08449 
08457     ISDNQ931Call* findCall(u_int32_t callRef, bool outgoing, u_int8_t tei = 0);
08458 
08464     ISDNQ931Call* findCall(unsigned int circuit);
08465 
08471     void terminateCalls(ObjList* list, const char* reason);
08472 
08479     bool acceptNewCall(bool outgoing, String& reason);
08480 
08486     ISDNQ931Message* getMsg(const DataBlock& data);
08487 
08495     ISDNQ931Message* endReceiveSegment(const char* reason = 0);
08496 
08502     void processGlobalMsg(ISDNQ931Message* msg, u_int8_t tei = 0);
08503 
08509     void processMsgRestart(ISDNQ931Message* msg, u_int8_t tei = 0);
08510 
08516     void processInvalidMsg(ISDNQ931Message* msg, u_int8_t tei = 0);
08517 
08525     void sendRestart(u_int64_t time = Time::msecNow(), bool retrans = false);
08526 
08534     void endRestart(bool restart, u_int64_t time, bool timeout = false);
08535 
08548     bool sendStatus(const char* cause, u_int8_t callRefLen, u_int32_t callRef = 0,
08549         u_int8_t tei = 0, bool initiator = false, ISDNQ931Call::State state = ISDNQ931Call::Null,
08550         const char* display = 0, const char* diagnostic = 0);
08551 
08565     bool sendRelease(bool release, u_int8_t callRefLen, u_int32_t callRef, u_int8_t tei,
08566         bool initiator, const char* cause = 0, const char* diag = 0,
08567         const char* display = 0, const char* signal = 0);
08568 
08569 private:
08570     virtual bool control(NamedList& params)
08571         { return SignallingDumpable::control(params,this); }
08572     bool q921Up() const;                 // Check if layer 2 may be up
08573     ISDNLayer2* m_q921;                  // The attached layer 2
08574     bool m_q921Up;                       // Layer 2 state
08575     // Protocol data
08576     bool m_networkHint;                  // NET / CPE hint, layer 2 is authoritative
08577     bool m_primaryRate;                  // Primary/base rate support
08578     bool m_transferModeCircuit;          // Circuit switch/packet mode transfer
08579     u_int32_t m_callRef;                 // Current available call reference for outgoing calls
08580     u_int8_t m_callRefLen;               // Call reference length
08581     u_int32_t m_callRefMask;             // Call reference mask
08582     ISDNQ931ParserData m_parserData;     // Parser settings
08583     ISDNQ931IEData m_data;               // Process IEs
08584     // Timers & counters
08585     SignallingTimer m_l2DownTimer;       // T309: Layer 2 is down timeout
08586     SignallingTimer m_recvSgmTimer;      // T314: Receive segment timeout
08587     SignallingTimer m_syncCicTimer;      // T316: Restart individual circuit timeout
08588     SignallingCounter m_syncCicCounter;  // RESTART retransmission counter
08589     SignallingTimer m_callDiscTimer;     // Q931 call value (see ISDQ931Call)
08590     SignallingTimer m_callRelTimer;      // Q931 call value (see ISDQ931Call)
08591     SignallingTimer m_callConTimer;      // Q931 call value (see ISDQ931Call)
08592     // Default values
08593     String m_numPlan;                    // Numbering plan
08594     String m_numType;                    // Number type
08595     String m_numPresentation;            // Number presentation
08596     String m_numScreening;               // Number screening
08597     String m_format;                     // Data format
08598     String m_cpeNumber;                  // The number of the BRI CPE
08599     // Restart data
08600     SignallingCircuit* m_restartCic;     // Currently restarting circuit
08601     unsigned int m_lastRestart;          // Last restarted circuit's code
08602     SignallingTimer m_syncGroupTimer;    // Restarting circuit group interval
08603     // Message segmentation data
08604     DataBlock m_segmentData;             // Message segments buffer
08605     ISDNQ931Message* m_segmented;        // Segmented message
08606     u_int8_t m_remaining;                // Remaining segments
08607     // Debug
08608     bool m_printMsg;                     // True to print messages to output
08609     bool m_extendedDebug;                // Extended debug flag
08610     // Flags used to print error messages
08611     bool m_flagQ921Down;                 // Layer 2 is down period timed out
08612     bool m_flagQ921Invalid;              // Refusing to send message when Layer 2 is missing or down
08613 };
08614 
08619 class YSIG_API ISDNQ931Monitor : public SignallingCallControl, public ISDNLayer3
08620 {
08621     YCLASS(ISDNQ931Monitor,ISDNLayer3)
08622     friend class ISDNQ931CallMonitor;
08623 public:
08630     ISDNQ931Monitor(const NamedList& params, const char* name = 0);
08631 
08636     virtual ~ISDNQ931Monitor();
08637 
08643     virtual bool initialize(const NamedList* config);
08644 
08655     virtual void dataLinkState(u_int8_t tei, bool cmd, bool value, ISDNLayer2* layer2);
08656 
08661     virtual void idleTimeout(ISDNLayer2* layer2);
08662 
08669     virtual void receiveData(const DataBlock& data, u_int8_t tei, ISDNLayer2* layer2);
08670 
08678     virtual ISDNQ921Passive* attach(ISDNQ921Passive* q921, bool net);
08679 
08687     virtual SignallingCircuitGroup* attach(SignallingCircuitGroup* circuits, bool net);
08688 
08694     inline ISDNQ921Passive* circuits(bool net) const
08695         { return net ? m_q921Net : m_q921Cpe; }
08696 
08702     inline void setDebug(bool printMsg, bool extendedDebug)
08703         { m_parserData.m_extendedDebug = m_extendedDebug =
08704             ((m_printMsg = printMsg) && extendedDebug); }
08705 
08711     virtual void cleanup(const char* reason = "offline")
08712         { terminateMonitor(0,reason); }
08713 
08720     void terminateMonitor(ISDNQ931CallMonitor* mon, const char* reason);
08721 
08722 protected:
08726     virtual void destroyed()
08727     {
08728         TelEngine::destruct(SignallingCallControl::attach(0));
08729         TelEngine::destruct(attach((ISDNQ921Passive*)0,true));
08730         TelEngine::destruct(attach((ISDNQ921Passive*)0,false));
08731         attach((SignallingCircuitGroup*)0,true);
08732         attach((SignallingCircuitGroup*)0,false);
08733         ISDNLayer3::destroyed();
08734     }
08735 
08741     virtual void timerTick(const Time& when);
08742 
08754     bool reserveCircuit(unsigned int code, bool netInit,
08755         SignallingCircuit** caller, SignallingCircuit** called);
08756 
08763     bool releaseCircuit(SignallingCircuit* circuit);
08764 
08770     void processMsgRestart(ISDNQ931Message* msg);
08771 
08772 private:
08773     // Find a call monitor by call reference or reserved circuit
08774     // @return Referenced call monitor pointer or 0 if not found
08775     ISDNQ931CallMonitor* findMonitor(unsigned int value, bool byCallRef);
08776     // Drop some messages. Return true if the message should be dropped
08777     bool dropMessage(const ISDNQ931Message* msg);
08778 
08779     ISDNQ921Passive* m_q921Net;          // Net side of the link
08780     ISDNQ921Passive* m_q921Cpe;          // CPE side of the link
08781     SignallingCircuitGroup* m_cicNet;    // Circuit group for the net side of the link
08782     SignallingCircuitGroup* m_cicCpe;    // Circuit group for the cpe side of the link
08783     ISDNQ931ParserData m_parserData;     // Parser settings
08784     ISDNQ931IEData m_data;               // Process IEs
08785     // Debug
08786     bool m_printMsg;                     // True to print messages to output
08787     bool m_extendedDebug;                // Extended debug flag
08788 };
08789 
08790 }
08791 
08792 #endif /* __YATESIG_H */
08793 
08794 /* vi: set ts=8 sw=4 sts=4 noet: */