1 //////////////////////////////////////////////////////////////////
5 // Define RAS PDU for GNU Gatekeeper
6 // Avoid including large h225.h in RasSrv.h
8 // Copyright (c) Citron Network Inc. 2001-2003
10 // This work is published under the GNU Public License (GPL)
11 // see file COPYING for details.
12 // We also explicitely grant the right to link this code
13 // with the OpenH323 library.
15 // initial author: Chih-Wei Huang <cwhuang@linux.org.tw>
16 // initial version: 05/02/2003
18 //////////////////////////////////////////////////////////////////
21 #define RASPDU_H "@(#) $Id: RasPDU.h,v 1.10 2006/09/16 20:42:50 shorne Exp $"
31 class RegistrationTable;
34 class MulticastListener;
35 class CallSignalListener;
39 const unsigned MaxRasTag = H225_RasMessage::e_serviceControlResponse;
41 struct GatekeeperMessage {
43 H225_RasMessage m_recvRAS;
44 H225_RasMessage m_replyRAS;
45 PIPSocket::Address m_peerAddr;
47 PIPSocket::Address m_localAddr;
48 RasListener *m_socket;
50 unsigned GetTag() const { return m_recvRAS.GetTag(); }
51 const char *GetTagName() const;
52 bool Read(RasListener *);
56 class RasListener : public UDPSocket {
58 RasListener(const Address &, WORD);
61 GatekeeperMessage *ReadRas();
62 bool SendRas(const H225_RasMessage &, const Address &, WORD);
64 WORD GetSignalPort() const { return m_signalPort; }
65 void SetSignalPort(WORD pt) { m_signalPort = pt; }
67 Address GetLocalAddr(const Address &) const;
68 Address GetPhysicalAddr(const Address & addr) const;
69 H225_TransportAddress GetRasAddress(const Address &) const;
70 H225_TransportAddress GetCallSignalAddress(const Address &) const;
72 // new virtual function
73 // filter out unwanted message to the listener by returning false
74 virtual bool Filter(GatekeeperMessage *) const;
80 bool m_virtualInterface;
83 class RasMsg : public Task {
85 virtual ~RasMsg() { delete m_msg; } //PTRACE(1, "Delete " << m_msg->GetTagName()); }
87 // new virtual function
88 virtual bool Process() = 0;
90 virtual int GetSeqNum() const = 0;
91 virtual H225_NonStandardParameter *GetNonStandardParam() = 0;
93 // override from class Task
96 bool IsFrom(const PIPSocket::Address &, WORD) const;
97 void GetRecvAddress(PIPSocket::Address &, WORD &) const;
98 unsigned GetTag() const { return m_msg->GetTag(); }
99 const char *GetTagName() const { return m_msg->GetTagName(); }
101 void GetRasAddress(H225_TransportAddress &) const;
102 void GetCallSignalAddress(H225_TransportAddress &) const;
104 bool EqualTo(const RasMsg *) const;
105 bool operator==(const RasMsg & other) const { return EqualTo(&other); }
107 bool Reply() const { return m_msg->Reply(); }
109 GatekeeperMessage *operator->() { return m_msg; }
110 const GatekeeperMessage *operator->() const { return m_msg; }
113 static void Initialize();
114 static RegistrationTable *GetEndpointTbl()
115 { return EndpointTbl; };
116 static CallTable *GetCallTbl()
119 RasMsg(GatekeeperMessage *m) : m_msg(m) {}
120 RasMsg(const RasMsg &);
122 static bool PrintStatus(const PString &);
124 GatekeeperMessage *m_msg;
126 // just pointers to global singleton objects
127 // cache for faster access
129 static GkStatus *StatusPort;
130 static RegistrationTable *EndpointTbl;
131 static CallTable *CallTbl;
132 static RasServer *RasSrv;
136 class RasPDU : public RasMsg {
138 typedef RAS RasClass;
140 RasPDU(GatekeeperMessage *m) : RasMsg(m), request(m->m_recvRAS) {}
142 // override from class RasMsg
143 virtual bool Process() { return false; }
144 virtual int GetSeqNum() const { return request.m_requestSeqNum; }
145 virtual H225_NonStandardParameter *GetNonStandardParam();
147 operator RAS & () { return request; }
148 operator const RAS & () const { return request; }
150 H225_RasMessage & BuildConfirm();
151 H225_RasMessage & BuildReject(unsigned);
153 typedef Factory<RasMsg, unsigned>::Creator1<GatekeeperMessage *> RasCreator;
154 struct Creator : public RasCreator {
155 Creator() : RasCreator(RasInfo<RAS>::tag) {}
156 virtual RasMsg *operator()(GatekeeperMessage *m) const { return new RasPDU<RAS>(m); }
163 // abstract factory for listeners
166 typedef PIPSocket::Address Address;
168 GkInterface(const Address &);
169 virtual ~GkInterface();
171 // we can't call virtual functions in constructor
172 // so initialize here
173 virtual bool CreateListeners(RasServer *);
175 bool IsBoundTo(const Address *addr) const { return m_address == *addr; }
176 bool IsReachable(const Address *) const;
178 RasListener *GetRasListener() const { return m_rasListener; }
179 MulticastListener *GetMulticastListener() const { return m_multicastListener; }
180 CallSignalListener *GetCallSignalListener() const { return m_callSignalListener; }
181 StatusListener *GetStatusListener() const { return m_statusListener; }
183 WORD GetRasPort() const { return m_rasPort; }
184 WORD GetMulticastPort() const { return m_multicastPort; }
185 WORD GetSignalPort() const { return m_signalPort; }
186 WORD GetStatusPort() const { return m_statusPort; }
189 bool ValidateSocket(IPSocket *, WORD &);
191 template <class Listener> bool SetListener(WORD nport, WORD & oport, Listener *& listener, Listener *(GkInterface::*creator)())
193 if (!listener || !oport || oport != nport) {
197 listener = (this->*creator)();
198 if (ValidateSocket(listener, oport))
207 RasListener *m_rasListener;
208 MulticastListener *m_multicastListener;
209 CallSignalListener *m_callSignalListener;
210 StatusListener *m_statusListener;
211 WORD m_rasPort, m_multicastPort, m_signalPort, m_statusPort;
215 virtual RasListener *CreateRasListener();
216 virtual MulticastListener *CreateMulticastListener();
217 virtual CallSignalListener *CreateCallSignalListener();
218 virtual StatusListener *CreateStatusListener();
223 typedef PIPSocket::Address Address;
226 virtual ~RasHandler() {}
228 // new virtual function
230 // check if the message is the expected one
231 // default behavior: check if the tag is in m_tagArray
232 virtual bool IsExpected(const RasMsg *) const;
234 // process the RasMsg object
235 // the object must be deleted after processed
236 virtual void Process(RasMsg *) = 0;
238 // give the derived class an opportunity to create customized PDU
239 // default behavior: return the original one
240 // Note: call RasMsg::Release() if new one is created
241 virtual RasMsg *CreatePDU(RasMsg *ras) { return ras; }
244 virtual void Stop() {}
247 void AddFilter(unsigned);
252 // delete the object after running RasMsg::Exec()
253 static void ProcessRAS(RasMsg *);
255 bool m_tagArray[MaxRasTag + 1];
258 // encapsulate a gatekeeper request and reply
259 class RasRequester : public RasHandler {
261 RasRequester() { Init(); }
262 // note the H225_RasMessage object must have
263 // longer lifetime than this object
264 RasRequester(H225_RasMessage &);
265 RasRequester(H225_RasMessage &, const Address &);
268 WORD GetSeqNum() const { return m_seqNum; }
269 bool WaitForResponse(int);
272 // override from class RasHandler
273 virtual bool IsExpected(const RasMsg *) const;
274 virtual void Process(RasMsg *);
277 // new virtual function
278 virtual bool SendRequest(const Address &, WORD, int = 2);
279 virtual bool OnTimeout();
282 void AddReply(RasMsg *);
284 H225_RasMessage *m_request;
286 Address m_txAddr, m_loAddr;
289 int m_timeout, m_retry;
296 std::list<RasMsg *> m_queue;
297 std::list<RasMsg *>::iterator m_iterator;
301 class Requester : public RasRequester {
303 typedef typename RasInfo<RAS>::Tag Tag;
304 typedef typename RasInfo<RAS>::ConfirmTag ConfirmTag;
305 typedef typename RasInfo<RAS>::RejectTag RejectTag;
306 Requester(H225_RasMessage &, const Address &);
307 ~Requester() { this->m_rasSrv->UnregisterHandler(this); } // fix for GCC 3.4.2
311 Requester<RAS>::Requester(H225_RasMessage & obj_ras, const Address & ip) : RasRequester(obj_ras, ip)
313 obj_ras.SetTag(Tag());
315 ras.m_requestSeqNum = GetSeqNum();
316 AddFilter(ConfirmTag());
317 AddFilter(RejectTag());
318 this->m_rasSrv->RegisterHandler(this); // fix for GCC 3.4.2
321 /*****************************************************************
323 The template class let you to modify the default handler of a
324 given RAS message. Just explicitly specialize the Process method.
327 template<> bool HookedPDU<H225_RegistrationRequest>::Process()
329 do_something_before_process();
330 // call the default handler
331 bool result = m_opdu->Process();
332 do_something_after_process();
336 Then add a creator to hook the interested messages
338 HookedPDU<H225_RegistrationRequest>::Creator HookedRRQ;
340 Note the creator must be executed after RasServer::Run().
342 *****************************************************************/
345 class HookedPDU : public RasPDU<RAS> {
347 HookedPDU(GatekeeperMessage *m, RasMsg *p) : RasPDU<RAS>(m), m_opdu(p) {}
348 ~HookedPDU() { m_opdu->Release(); }
350 virtual bool Process() { return m_opdu->Process(); }
352 typedef typename RasPDU<RAS>::RasCreator RasCreator;
353 struct Creator : public RasPDU<RAS>::Creator {
354 Creator() { PAssert(this->m_old, "Error: Hook failed"); } // fix for GCC 3.4.2
355 virtual RasMsg *operator()(GatekeeperMessage *m) const
356 { return new HookedPDU<RAS>(m, dynamic_cast<RasCreator &>(*(this->m_old))(m)); } // fix for GCC 3.4.2