1 /* 2 * gkclient.h 3 * 4 * Gatekeeper client protocol handler 5 * 6 * Open H323 Library 7 * 8 * Copyright (c) 1998-2001 Equivalence Pty. Ltd. 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.0 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS IS" 16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 17 * the License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * The Original Code is Open H323 Library. 21 * 22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 23 * 24 * Portions of this code were written with the assisance of funding from 25 * iFace, Inc. http://www.iface.com 26 * 27 * Contributor(s): ______________________________________. 28 * 29 * $Revision: 24178 $ 30 * $Author: rjongbloed $ 31 * $Date: 2010-04-05 19:10:56 -0500 (Mon, 05 Apr 2010) $ 32 */ 33 34 #ifndef OPAL_H323_GKCLIENT_H 35 #define OPAL_H323_GKCLIENT_H 36 37 #ifdef P_USE_PRAGMA 38 #pragma interface 39 #endif 40 41 #include <opal/buildopts.h> 42 43 #if OPAL_H323 44 45 #include <h323/h225ras.h> 46 #include <h323/h235auth.h> 47 48 #if OPAL_H460 49 class H460_FeatureSet; 50 #endif 51 52 class H323Connection; 53 class H225_ArrayOf_AliasAddress; 54 class H225_H323_UU_PDU; 55 class H225_AlternateGK; 56 class H225_ArrayOf_AlternateGK; 57 class H225_ArrayOf_ServiceControlSession; 58 class H225_FeatureSet; 59 60 61 /////////////////////////////////////////////////////////////////////////////// 62 63 /**This class embodies the H.225.0 RAS protocol to gatekeepers. 64 */ 65 class H323Gatekeeper : public H225_RAS 66 { 67 PCLASSINFO(H323Gatekeeper, H225_RAS); 68 public: 69 /**@name Construction */ 70 //@{ 71 /**Create a new gatekeeper. 72 */ 73 H323Gatekeeper( 74 H323EndPoint & endpoint, ///< Endpoint gatekeeper is associated with. 75 H323Transport * transport ///< Transport over which gatekeepers communicates. 76 ); 77 78 /**Destroy gatekeeper. 79 */ 80 ~H323Gatekeeper(); 81 //@} 82 83 /**@name Overrides from H323Transactor */ 84 //@{ 85 virtual PBoolean WriteTo( 86 H323TransactionPDU & pdu, 87 const H323TransportAddressArray & addresses, 88 PBoolean callback = true 89 ); 90 //@} 91 92 /**@name Overrides from H225_RAS */ 93 //@{ 94 PBoolean OnReceiveGatekeeperConfirm(const H225_GatekeeperConfirm & gcf); 95 PBoolean OnReceiveGatekeeperReject(const H225_GatekeeperReject & grj); 96 PBoolean OnReceiveRegistrationConfirm(const H225_RegistrationConfirm & rcf); 97 PBoolean OnReceiveRegistrationReject(const H225_RegistrationReject & rrj); 98 PBoolean OnReceiveUnregistrationRequest(const H225_UnregistrationRequest & urq); 99 PBoolean OnReceiveUnregistrationConfirm(const H225_UnregistrationConfirm & ucf); 100 PBoolean OnReceiveUnregistrationReject(const H225_UnregistrationReject & urj); 101 PBoolean OnReceiveAdmissionConfirm(const H225_AdmissionConfirm & acf); 102 PBoolean OnReceiveAdmissionReject(const H225_AdmissionReject & arj); 103 PBoolean OnReceiveDisengageRequest(const H225_DisengageRequest & drq); 104 PBoolean OnReceiveBandwidthConfirm(const H225_BandwidthConfirm & bcf); 105 PBoolean OnReceiveBandwidthRequest(const H225_BandwidthRequest & brq); 106 PBoolean OnReceiveInfoRequest(const H225_InfoRequest & irq); 107 PBoolean OnReceiveServiceControlIndication(const H225_ServiceControlIndication &); 108 void OnSendGatekeeperRequest(H225_GatekeeperRequest & grq); 109 void OnSendAdmissionRequest(H225_AdmissionRequest & arq); 110 PBoolean OnSendFeatureSet(unsigned, H225_FeatureSet & features) const; 111 void OnReceiveFeatureSet(unsigned, const H225_FeatureSet & features) const; 112 //@} 113 114 /**@name Protocol operations */ 115 //@{ 116 /**Discover a gatekeeper on the local network. 117 */ 118 PBoolean DiscoverAny(); 119 120 /**Discover a gatekeeper on the local network. 121 If the identifier string is empty then the first gatekeeper to respond 122 to a broadcast is used. 123 */ 124 PBoolean DiscoverByName( 125 const PString & identifier ///< Gatekeeper identifier to find 126 ); 127 128 /**Discover a gatekeeper on the local network. 129 If the address string is empty then the first gatekeeper to respond 130 to a broadcast is used. 131 */ 132 PBoolean DiscoverByAddress( 133 const H323TransportAddress & address ///< Address of gatekeeper. 134 ); 135 136 /**Discover a gatekeeper on the local network. 137 Combination of DiscoverByName() and DiscoverByAddress(). 138 */ 139 PBoolean DiscoverByNameAndAddress( 140 const PString & identifier, 141 const H323TransportAddress & address 142 ); 143 144 /**Register with gatekeeper. 145 */ 146 PBoolean RegistrationRequest( 147 PBoolean autoReregister = true, ///< Automatic register on unregister 148 PBoolean didGkDiscovery = false ///< discovery procedure was done right before 149 ); 150 151 /**Unregister with gatekeeper. 152 */ 153 PBoolean UnregistrationRequest( 154 int reason ///< Reason for unregistration 155 ); 156 157 /**Location request to gatekeeper. 158 */ 159 PBoolean LocationRequest( 160 const PString & alias, ///< Alias name we wish to find. 161 H323TransportAddress & address ///< Resultant transport address. 162 ); 163 164 /**Location request to gatekeeper. 165 */ 166 PBoolean LocationRequest( 167 const PStringList & aliases, ///< Alias names we wish to find. 168 H323TransportAddress & address ///< Resultant transport address. 169 ); 170 171 struct AdmissionResponse { 172 AdmissionResponse(); 173 174 unsigned rejectReason; /// Reject reason if returns false 175 176 PBoolean gatekeeperRouted; /// Flag for call is through gk 177 PINDEX endpointCount; /// Number of endpoints that can be returned 178 H323TransportAddress * transportAddress; /// Transport address or remote endpoint. 179 PBYTEArray * accessTokenData; /// iNow Gatekeeper Access Token data 180 181 H225_ArrayOf_AliasAddress * aliasAddresses; /// DestinationInfo to use in SETUP if not empty 182 H225_ArrayOf_AliasAddress * destExtraCallInfo; /// DestinationInfo to use in SETUP if not empty 183 }; 184 185 /**Admission request to gatekeeper. 186 */ 187 PBoolean AdmissionRequest( 188 H323Connection & connection, ///< Connection we wish to change. 189 AdmissionResponse & response, ///< Response parameters to ARQ 190 PBoolean ignorePreGrantedARQ = false ///< Flag to force ARQ to be sent 191 ); 192 193 /**Disengage request to gatekeeper. 194 */ 195 PBoolean DisengageRequest( 196 const H323Connection & connection, ///< Connection we wish admitted. 197 unsigned reason ///< Reason code for disengage 198 ); 199 200 /**Bandwidth request to gatekeeper. 201 */ 202 PBoolean BandwidthRequest( 203 H323Connection & connection, ///< Connection we wish to change. 204 unsigned requestedBandwidth ///< New bandwidth wanted in 0.1kbps 205 ); 206 207 /**Send an unsolicited info response to the gatekeeper. 208 */ 209 void InfoRequestResponse(); 210 211 /**Send an unsolicited info response to the gatekeeper. 212 */ 213 void InfoRequestResponse( 214 const H323Connection & connection ///< Connection to send info about 215 ); 216 217 /**Send an unsolicited info response to the gatekeeper. 218 */ 219 void InfoRequestResponse( 220 const H323Connection & connection, ///< Connection to send info about 221 const H225_H323_UU_PDU & pdu, ///< PDU that was sent or received 222 PBoolean sent ///< Flag for PDU was sent or received 223 ); 224 225 /**Handle incoming service control session information. 226 */ 227 virtual void OnServiceControlSessions( 228 const H225_ArrayOf_ServiceControlSession & serviceControl, 229 H323Connection * connection 230 ); 231 232 /** Handle terminal alias changes 233 */ 234 virtual void OnTerminalAliasChanged(); 235 //@} 236 237 /**@name Member variable access */ 238 //@{ 239 /**Determine if the endpoint has discovered the gatekeeper. 240 */ IsDiscoveryComplete()241 PBoolean IsDiscoveryComplete() const { return discoveryComplete; } 242 243 /**Determine if the endpoint is registered with the gatekeeper. 244 */ IsRegistered()245 PBoolean IsRegistered() const { return registrationFailReason == RegistrationSuccessful; } 246 247 enum RegistrationFailReasons { 248 RegistrationSuccessful, 249 UnregisteredLocally, 250 UnregisteredByGatekeeper, 251 GatekeeperLostRegistration, 252 InvalidListener, 253 DuplicateAlias, 254 SecurityDenied, 255 TransportError, 256 NumRegistrationFailReasons, 257 RegistrationRejectReasonMask = 0x8000 258 }; 259 /**Get the registration fail reason. 260 */ GetRegistrationFailReason()261 RegistrationFailReasons GetRegistrationFailReason() const { return registrationFailReason; } 262 263 /**Get the gatekeeper name. 264 The gets the name of the gatekeeper. It will be of the form id@address 265 where id is the gatekeeperIdentifier and address is the transport 266 address used. If the gatekeeperIdentifier is empty the '@' is not 267 included and only the transport is shown. The transport is minimised 268 also, with the type removed if IP is used and the :port removed if the 269 default port is used. 270 */ 271 PString GetName() const; 272 273 /** Get the endpoint identifier 274 */ GetEndpointIdentifier()275 const PString & GetEndpointIdentifier() const { return endpointIdentifier; } 276 277 /**Set the H.235 password in the gatekeeper. 278 If no username is present then it will default to the endpoint local 279 user name (ie first alias). 280 */ 281 void SetPassword( 282 const PString & password, ///< New password 283 const PString & username = PString() ///< Username for password 284 ); 285 286 /* 287 * Return the call signalling address for the gatekeeper (if present) 288 */ GetGatekeeperRouteAddress()289 H323TransportAddress GetGatekeeperRouteAddress() const 290 { return gkRouteAddress; } 291 //@} 292 293 294 protected: 295 bool StartGatekeeper(const H323TransportAddress & address); 296 virtual bool DiscoverGatekeeper(); 297 unsigned SetupGatekeeperRequest(H323RasPDU & request); 298 299 void Connect(const H323TransportAddress & address, const PString & gatekeeperIdentifier); 300 PDECLARE_NOTIFIER(PThread, H323Gatekeeper, MonitorMain); 301 PDECLARE_NOTIFIER(PTimer, H323Gatekeeper, TickleMonitor); 302 void RegistrationTimeToLive(); 303 304 void SetInfoRequestRate( 305 const PTimeInterval & rate 306 ); 307 void ClearInfoRequestRate(); 308 H225_InfoRequestResponse & BuildInfoRequestResponse( 309 H323RasPDU & response, 310 unsigned seqNum 311 ); 312 PBoolean SendUnsolicitedIRR( 313 H225_InfoRequestResponse & irr, 314 H323RasPDU & response 315 ); 316 317 void SetAlternates( 318 const H225_ArrayOf_AlternateGK & alts, 319 PBoolean permanent 320 ); 321 322 virtual PBoolean MakeRequest( 323 Request & request 324 ); 325 PBoolean MakeRequestWithReregister( 326 Request & request, 327 unsigned unregisteredTag 328 ); 329 330 virtual H323Transport * CreateTransport(PIPSocket::Address bindng = PIPSocket::GetDefaultIpAny(), WORD port = 0, PBoolean reuseAddr = false); 331 332 // Handling interface changes 333 void OnAddInterface(const PIPSocket::InterfaceEntry & entry, PINDEX priority); 334 void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry, PINDEX priority); 335 void UpdateConnectionStatus(); 336 bool SetListenerAddresses(H225_ArrayOf_TransportAddress & pdu); 337 338 // Gatekeeper registration state variables 339 PBoolean discoveryComplete; 340 PString endpointIdentifier; 341 RegistrationFailReasons registrationFailReason; 342 343 enum { 344 HighPriority = 80, 345 LowPriority = 40, 346 }; 347 class InterfaceMonitor : public PInterfaceMonitorClient 348 { 349 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient); 350 351 public: 352 InterfaceMonitor(H323Gatekeeper & gk, PINDEX priority); 353 354 protected: 355 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry); 356 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry); 357 358 H323Gatekeeper & gk; 359 }; 360 InterfaceMonitor highPriorityMonitor; 361 InterfaceMonitor lowPriorityMonitor; 362 363 class AlternateInfo : public PObject { 364 PCLASSINFO(AlternateInfo, PObject); 365 public: 366 AlternateInfo(H225_AlternateGK & alt); 367 ~AlternateInfo(); 368 Comparison Compare(const PObject & obj); 369 void PrintOn(ostream & strm) const; 370 371 H323TransportAddress rasAddress; 372 PString gatekeeperIdentifier; 373 unsigned priority; 374 enum { 375 NoRegistrationNeeded, 376 NeedToRegister, 377 Register, 378 IsRegistered, 379 RegistrationFailed 380 } registrationState; 381 382 private: 383 // Disable copy constructor and assignment AlternateInfo(const AlternateInfo & other)384 AlternateInfo(const AlternateInfo &other): PObject(other) { } 385 AlternateInfo & operator=(const AlternateInfo &) { return *this; } 386 }; 387 PSortedList<AlternateInfo> alternates; 388 PBoolean alternatePermanent; 389 PSemaphore requestMutex; 390 H235Authenticators authenticators; 391 392 enum { 393 RequireARQ, 394 PregrantARQ, 395 PreGkRoutedARQ 396 } pregrantMakeCall, pregrantAnswerCall; 397 H323TransportAddress gkRouteAddress; 398 399 // Gatekeeper operation variables 400 PBoolean autoReregister; 401 PBoolean reregisterNow; 402 PTimer timeToLive; 403 PBoolean requiresDiscovery; 404 PTimer infoRequestRate; 405 PBoolean willRespondToIRR; 406 PThread * monitor; 407 PBoolean monitorStop; 408 PSyncPoint monitorTickle; 409 410 PDictionary<POrdinalKey, H323ServiceControlSession> serviceControlSessions; 411 412 #if OPAL_H460 413 H460_FeatureSet * features; 414 #endif 415 416 }; 417 418 419 PLIST(H323GatekeeperList, H323Gatekeeper); 420 421 422 #endif // OPAL_H323 423 424 #endif // OPAL_H323_GKCLIENT_H 425 426 427 ///////////////////////////////////////////////////////////////////////////// 428