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