1 /* 2 * 3 * Inter Asterisk Exchange 2 4 * 5 * Open Phone Abstraction Library (OPAL) 6 * 7 * Describes the IAX2 extension of the OpalEndpoint class. 8 * 9 * Copyright (c) 2005 Indranet Technologies Ltd. 10 * 11 * The contents of this file are subject to the Mozilla Public License 12 * Version 1.0 (the "License"); you may not use this file except in 13 * compliance with the License. You may obtain a copy of the License at 14 * http://www.mozilla.org/MPL/ 15 * 16 * Software distributed under the License is distributed on an "AS IS" 17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 18 * the License for the specific language governing rights and limitations 19 * under the License. 20 * 21 * The Original Code is Open Phone Abstraction Library. 22 * 23 * The Initial Developer of the Original Code is Indranet Technologies Ltd. 24 * 25 * The author of this code is Derek J Smithies 26 * 27 * $Revision: 24719 $ 28 * $Author: rjongbloed $ 29 * $Date: 2010-09-23 18:55:55 -0500 (Thu, 23 Sep 2010) $ 30 */ 31 32 #ifndef OPAL_IAX2_IAX2EP_H 33 #define OPAL_IAX2_IAX2EP_H 34 35 #ifndef _PTLIB_H 36 #include <ptlib.h> 37 #endif 38 39 #ifdef P_USE_PRAGMA 40 #pragma interface 41 #endif 42 43 #include <opal/buildopts.h> 44 45 #if OPAL_IAX2 46 47 #include <opal/endpoint.h> 48 #include <iax2/iax2con.h> 49 #include <iax2/processor.h> 50 #include <iax2/regprocessor.h> 51 #include <iax2/specialprocessor.h> 52 53 class IAX2Receiver; 54 class IAX2Transmit; 55 class IAX2Processor; 56 57 /** A class to take frames from the transmitter, and disperse them to 58 the appropriate IAX2Connection class. This class calls a method in 59 the IAX2EndPoint to do the dispersal. */ 60 class IAX2IncomingEthernetFrames : public PThread 61 { 62 PCLASSINFO(IAX2IncomingEthernetFrames, PThread); 63 public: 64 65 /**@name Constructors/destructors*/ 66 //@{ 67 /**Construct a distributor, to send packets on to the relevant connection */ 68 IAX2IncomingEthernetFrames(); 69 70 /**Destroy the distributor */ ~IAX2IncomingEthernetFrames()71 ~IAX2IncomingEthernetFrames() { } 72 73 /**@name general worker methods*/ 74 //@{ 75 /*The method which gets everythig to happen */ 76 virtual void Main(); 77 78 /**Set the endpoint variable */ 79 void Assign(IAX2EndPoint *ep); 80 81 /**Activate this thread to process all frames in the lists 82 */ ProcessList()83 void ProcessList() { activate.Signal(); } 84 85 /**Cause this thread to die immediately */ 86 void Terminate(); 87 88 //@} 89 protected: 90 /**Global variable which holds the application specific data */ 91 IAX2EndPoint *endpoint; 92 93 /**Flag to activate this thread*/ 94 PSyncPoint activate; 95 96 /**Flag to indicate if this receiver thread should keep listening for network data */ 97 PBoolean keepGoing; 98 }; 99 100 101 102 103 /** A class to manage global variables. There is one Endpoint per application. */ 104 class IAX2EndPoint : public OpalEndPoint 105 { 106 PCLASSINFO(IAX2EndPoint, OpalEndPoint); 107 public: 108 /**@name Construction */ 109 110 //@{ 111 /**Create the endpoint, and define local variables */ 112 IAX2EndPoint( 113 OpalManager & manager, 114 unsigned short port = 4569 115 ); 116 117 /**Destroy the endpoint, and all associated connections*/ 118 ~IAX2EndPoint(); 119 //@} 120 121 /**@name connection Connection handling */ 122 //@{ 123 /**Handle new incoming connection from listener. 124 125 The default behaviour does nothing. 126 */ 127 virtual PBoolean NewIncomingConnection( 128 OpalTransport * transport /// Transport connection came in on 129 ); 130 131 /**Set up a connection to a remote party. 132 This is called from the OpalManager::MakeConnection() function once 133 it has determined that this is the endpoint for the protocol. 134 135 The general form for this party parameter is: 136 137 [iax2:]{username@][transport$]address[/extension][+context] 138 139 where the various fields will have meanings specific to the endpoint 140 type. For example, with H.323 it could be "h323:Fred@site.com" which 141 indicates a user Fred at gatekeeper size.com. Whereas for the PSTN 142 endpoint it could be "pstn:5551234" which is to call 5551234 on the 143 first available PSTN line. 144 145 The proto field is optional when passed to a specific endpoint. If it 146 is present, however, it must agree with the endpoints protocol name or 147 false is returned. 148 149 This function usually returns almost immediately with the connection 150 continuing to occur in a new background thread. 151 152 If false is returned then the connection could not be established. For 153 example if a PSTN endpoint is used and the assiciated line is engaged 154 then it may return immediately. Returning a non-NULL value does not 155 mean that the connection will succeed, only that an attempt is being 156 made. 157 158 The default behaviour is pure. 159 */ 160 virtual PSafePtr<OpalConnection> MakeConnection( 161 OpalCall & call, ///< Owner of connection 162 const PString & party, ///< Remote party to call 163 void * userData = NULL, ///< Arbitrary data to pass to connection 164 unsigned int options = 0, ///< options to pass to connection 165 OpalConnection::StringOptions * stringOptions = NULL 166 ); 167 168 /**Create a connection for the IAX endpoint. 169 The default implementation is to create a IAX2Connection. 170 */ 171 virtual IAX2Connection * CreateConnection( 172 OpalCall & call, /// Owner of connection 173 const PString & token, /// token used to identify connection 174 void * userData, /// User data for connection 175 const PString & remoteParty, /// Url to call or is calling. 176 const PString & remotePartyName = PString::Empty() /// Name to call or is calling. 177 ); 178 //@} 179 180 /**@name worker Methods*/ 181 //@{ 182 /**Setup the Endpoint internval variables, which is called at program 183 startup.*/ 184 PBoolean Initialise(); 185 186 /**Handle a received IAX frame. This may be a mini frame or full frame */ 187 virtual void IncomingEthernetFrame (IAX2Frame *frame); 188 189 /**A simple test to report if the connection associated with this 190 frame is still alive. This test is used when transmitting the 191 frame. If the connection is gone, don't bother transmitting the 192 frame. There are exceptins to this rule, such as when a hangup 193 packet is sent (which is after the connections has died. */ 194 PBoolean ConectionForFrameIsAlive(IAX2Frame *f); 195 196 /**Request a new source call number, one that is different to 197 all other source call numbers for this program. 198 199 @return P_MAX_INDEX if there is no available call number, 200 or return a unique valid call number. 201 */ 202 PINDEX NextSrcCallNumber(IAX2Processor * processor); 203 204 /**Write the token of all connections in the connectionsActive 205 structure to the trace file */ 206 void ReportStoredConnections(); 207 208 /**Report the port in use for IAX calls */ ListenPortNumber()209 WORD ListenPortNumber() { return 4569; } 210 211 /**Pointer to the transmitter class, which is always valid*/ 212 IAX2Transmit *transmitter; 213 214 /**Pointer to the receiver class, which is always valid*/ 215 IAX2Receiver *receiver; 216 217 /**Report the local username*/ GetLocalUserName()218 PString GetLocalUserName() { return localUserName; } 219 220 /**Report the number used by the computer running this program*/ GetLocalNumber()221 PString GetLocalNumber() { return localNumber; } 222 223 /**Set the username to some value */ 224 void SetLocalUserName(PString newValue); 225 226 /**Set the local (on this host) number to some value */ 227 void SetLocalNumber(PString newValue); 228 229 /**Report the password*/ GetPassword()230 PString & GetPassword() { return password; } 231 232 /**Set the password to some value */ 233 void SetPassword(PString newValue); 234 235 /**It is possible that a retransmitted frame has been in the transmit queue, 236 and while sitting there that frames sending connection has died. Thus, 237 prior to transmission, call tis method. 238 239 @return True if a connection (which matches this Frame ) can be 240 found. */ 241 PBoolean ConnectionForFrameIsAlive(IAX2Frame *f); 242 243 /**Get out sequence number to use on status query frames*/ 244 PINDEX GetOutSequenceNumberForStatusQuery(); 245 246 /**We have an incoming call. Do we accept ? */ 247 void StartRinging(PString remoteCaller); 248 249 /**Handle new incoming connection from listener. 250 251 A return value of true indicates that the transport object should be 252 deleted by the caller. false indicates that something else (eg the 253 connection) has taken over responsibility for deleting the transport. 254 255 Well, that is true of Opal. In iax2, we do all the work of creating a new 256 connection etc. The transport arguement is ignore. In Iax2, this method 257 is void, as no value is returned. Further, in iax2, we process the 258 incoming frame. 259 */ 260 void NewIncomingConnection( 261 IAX2Frame *f /// Frame carrying the new request. 262 ); 263 264 /**A call back function whenever a connection is established. 265 This indicates that a connection to an endpoint was established. This 266 usually occurs after OnConnected() and indicates that the connection 267 is both connected and has media flowing. 268 */ 269 void OnEstablished( 270 OpalConnection & con 271 ); 272 273 /**Called whenever a connection instance is finished being used to 274 manage a call. We trap this callback to remove the connection 275 from this endpoints token table. Once we are done the token 276 table, we then call the generic OpalEndpoint::OnReleased 277 method. */ 278 virtual void OnReleased( 279 OpalConnection & connection ///< Connection that was established 280 ); 281 282 /**Get the data formats this endpoint is capable of operating. This 283 provides a list of media data format names that may be used by an 284 OpalMediaStream may be created by a connection from this endpoint. 285 286 Note that a specific connection may not actually support all of the 287 media formats returned here, but should return no more. 288 289 The default behaviour is pure. 290 */ 291 virtual OpalMediaFormatList GetMediaFormats() const; 292 293 /**Return the bitmask which specifies the possible codecs we support */ 294 PINDEX GetSupportedCodecs(OpalMediaFormatList & list); 295 296 /**Return the bitmask which specifies the preferred codec */ 297 PINDEX GetPreferredCodec(OpalMediaFormatList & list); 298 299 /**Get the frame size (bytes) and frame duration (ms) for compressed 300 data from this codec */ 301 void GetCodecLengths(PINDEX src, PINDEX &compressedBytes, PINDEX &duration); 302 303 /**enum of the components from a remote party address string 304 These fields are from the address, 305 306 [iax2:]{username@][transport$]address[/extension][+context] 307 */ 308 enum IAX2RemoteAddressFields { 309 protoIndex = 0, /*!< the protocol, or iax2: field */ 310 userIndex = 1, /*!< the username, or alias field */ 311 transportIndex = 2, /*!< the transport, or transport field */ 312 addressIndex = 3, /*!< the address, or 192.168.1.1 field */ 313 portIndex = 4, /*!< the port number */ 314 extensionIndex = 5, /*!< the extension, or "extension"" field */ 315 contextIndex = 6, /*!< the context, or "+context" field */ 316 maximumIndex = 7 /*!< the number of possible fields */ 317 }; 318 319 /**Given a remote party name of the format: 320 321 [proto:][alias@][transport$]address[/extension] 322 323 pull the string apart and get the components. The compoents are stored 324 in a PStringList, indexed by the enum RemoteAddressFields */ 325 static PStringArray DissectRemoteParty(const PString & other); 326 327 /**Pull frames off the incoming list, and pass on to the relevant 328 connection. If no matching connection found, delete the frame. 329 Repeat the process until no frames are left. */ 330 void ProcessReceivedEthernetFrames(); 331 332 /**Report on the frames in the current transmitter class, which are 333 pending transmission*/ 334 void ReportTransmitterLists(PString & answer, bool getFullReport = false); 335 336 /**Copy to the supplied OpalMediaList the media formats we support*/ 337 void CopyLocalMediaFormats(OpalMediaFormatList & list); 338 339 /**Register with a remote iax2 server. The host can either be a 340 hostname or ip address. The password is optional as some servers 341 may not require it to register. The requested refresh time is the 342 time that the registration should be refreshed in seconds. The time 343 must be more than 10 seconds.*/ 344 void Register( 345 const PString & host, 346 const PString & username, 347 const PString & password = PString::Empty(), 348 PINDEX requestedRefreshTime = 60 349 ); 350 351 enum RegisteredError { 352 RegisteredFailureUnknown 353 }; 354 355 /**This is a call back if an event related to registration occurs. 356 This callback should return as soon as possible.*/ 357 virtual void OnRegistered( 358 const PString & host, 359 const PString & userName, 360 PBoolean isFailure, 361 RegisteredError reason = RegisteredFailureUnknown); 362 363 /**Unregister from a registrar. This function is synchronous so it 364 will block.*/ 365 void Unregister( 366 const PString & host, 367 const PString & username); 368 369 enum UnregisteredError { 370 UnregisteredFailureUnknown 371 }; 372 373 /**This is a call back if an event related to unregistration occurs. 374 This callback should return as soon as possible. Generally even if 375 a failure occurs when unregistering it should be ignored because it 376 does not matter to much that it couldn't unregister.*/ 377 virtual void OnUnregistered( 378 const PString & host, 379 const PString & userName, 380 PBoolean isFailure, 381 UnregisteredError reason = UnregisteredFailureUnknown); 382 383 384 /**Check if an account is registered or being registered*/ 385 PBoolean IsRegistered(const PString & host, const PString & username); 386 387 /**Get the number of accounts that are being registered*/ 388 PINDEX GetRegistrationsCount(); 389 390 /**Builds a url*/ 391 PString BuildUrl( 392 const PString & host, 393 const PString & userName = PString::Empty(), 394 const PString & extension = PString::Empty(), 395 const PString & context = PString::Empty(), 396 const PString & transport = PString::Empty() 397 ); 398 399 /**Report if this iax2 endpoint class is correctly initialised */ InitialisedOK()400 PBoolean InitialisedOK() { return (transmitter != NULL) && (receiver != NULL); } 401 402 /**Report if there are frames (from the ethernet) waiting to be 403 processed */ EthernetFramesToBeProcessed()404 PBoolean EthernetFramesToBeProcessed() 405 { return packetsReadFromEthernet.GetSize() > 0; } 406 //@} 407 408 protected: 409 /**Thread which transfers frames from the Receiver to the 410 appropriate connection. It momentarily locks the connection 411 list, searches through, and then completes the trasnsfer. If need 412 be, this thread will create a new conneciton (to cope with a new 413 incoming call) and add the new connections to the internal 414 list. */ 415 IAX2IncomingEthernetFrames incomingFrameHandler; 416 417 /**List of iax2 packets which has been read from the ethernet, and 418 is to be sent to the matching IAX2Connection */ 419 IAX2FrameList packetsReadFromEthernet; 420 421 /**The socket on which all data is sent/received.*/ 422 PUDPSocket *sock; 423 424 /** The local port */ 425 unsigned short localPort; 426 427 /**Number of active calls */ 428 int callnumbs; 429 430 /** lock on access to call numbers variable */ 431 PMutex callNumbLock; 432 433 /**Time when a call was started */ 434 PTime callStartTime; 435 436 /**Name of this user, which is used as the IeCallingNumber */ 437 PString localUserName; 438 439 /**Number, as used by the computer on the host running this program*/ 440 PString localNumber; 441 442 /**Password for this user, which is used when processing an authentication request */ 443 PString password; 444 445 /**Counter to use for sending on status query frames */ 446 PINDEX statusQueryCounter; 447 448 /**Mutex for the statusQueryCounter */ 449 PMutex statusQueryMutex; 450 451 /**Pointer to the Processor class which handles special packets (eg lagrq) that have no 452 destination call to handle them. */ 453 IAX2SpecialProcessor * specialPacketHandler; 454 455 /**For the supplied IAX2Frame, pass it to a connection in the 456 connectionsActive structure. If no matching connection is found, return 457 false; 458 459 If a matching connections is found, give the frame to the 460 connection (for the connection to process) and return true; 461 */ 462 PBoolean ProcessInMatchingConnection(IAX2Frame *f); 463 464 /**For the supplied IAX2Frame, pass it to a connection in the 465 connectionsActive structure. We are told the token of the connection 466 that matches this particular frame. 467 468 469 @return true - this is the normal and expected outcome. 470 @return false - connection not found - say it died immediately 471 before this method was called */ 472 PBoolean ProcessFrameInConnection(IAX2Frame *f, const PString & token); 473 474 /**Take the supplied frame, and compare it with all the existing 475 connections. If any of the existing connections has a matching 476 dest call number, then put this frame to that connection. 477 478 Update the token translation dictionary if the supplied frame has 479 a valid connection token. */ 480 PBoolean ProcessInConnectionTestAll(IAX2Frame *f); 481 482 /**tokenTable is a hack to allow IAX2 to fit in with one of the 483 demands of the opal library. 484 485 Opal demands that at connection setup, we know the unique ID which 486 this call will use. 487 488 Since the unique ID is remote ip adress + remote's Source Call 489 number, this is unknown if we are initiating the 490 call. Consequently, this table is needed, as it provides a 491 translation between the initial (or psuedo) token and the 492 token that is later adopted */ 493 494 PStringToString tokenTable; 495 496 /**Threading mutex on the variable tokenTable. We can now safely 497 read/write to this table, with the minimum of interference between 498 threads. */ 499 PReadWriteMutex mutexTokenTable; 500 501 /**Thread safe counter which keeps track of the calls created by this endpoint. 502 This value is used when giving outgoing calls a unique ID */ 503 PAtomicInteger callsEstablished; 504 505 /**Local copy of the media types we can handle*/ 506 OpalMediaFormatList localMediaFormats; 507 508 /**A mutex to protect the registerProcessors collection*/ 509 PMutex regProcessorsMutex; 510 511 /**An array of register processors. These are created when 512 another class calls register and deleted when another class 513 calls unregister or class destructor is called. This collection 514 must be protected by the regProcessorsMutex*/ 515 PArrayObjects regProcessors; 516 517 }; 518 519 520 #endif // OPAL_IAX2 521 522 #endif // OPAL_IAX2_IAX2EP_H 523 524 /* The comment below is magic for those who use emacs to edit this file. 525 * With the comment below, the tab key does auto indent to 2 spaces. 526 * 527 * Local Variables: 528 * mode:c 529 * c-basic-offset:2 530 * End: 531 */ 532 533