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