home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.muug.mb.ca
/
2014.06.ftp.muug.mb.ca.tar
/
ftp.muug.mb.ca
/
pub
/
openh323.tar.gz
/
openh323.tar
/
openh323
/
src
/
h323pdu.cxx
< prev
next >
Wrap
Text File
|
2003-05-29
|
74KB
|
2,249 lines
/*
* h323pdu.cxx
*
* H.323 PDU definitions
*
* Open H323 Library
*
* Copyright (c) 1998-2000 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Open H323 Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions of this code were written with the assisance of funding from
* Vovida Networks, Inc. http://www.vovida.com.
*
* Contributor(s): ______________________________________.
*
* $Log: h323pdu.cxx,v $
* Revision 1.129 2003/05/29 09:19:52 rjongbloed
* Fixed minor problem with including DisplayName IE if localPartyName
* is blank, now does not include it, thanks Auri Vizgaitis
*
* Revision 1.128 2003/05/06 06:24:16 robertj
* Added continuous DTMF tone support (H.245 UserInputIndication - signalUpdate)
* as per header documentation, thanks Auri Vizgaitis
*
* Revision 1.127 2003/04/10 09:37:20 robertj
* Added some more functions for converting to alias addresses.
*
* Revision 1.126 2003/04/01 03:11:51 robertj
* Added function to get array of AliasAddress into PStringArray.
*
* Revision 1.125 2003/03/25 04:56:21 robertj
* Fixed issues to do with multiple inheritence in transaction reply cache.
*
* Revision 1.124 2003/03/20 01:51:12 robertj
* More abstraction of H.225 RAS and H.501 protocols transaction handling.
*
* Revision 1.123 2003/02/25 06:48:19 robertj
* More work on PDU transaction abstraction.
*
* Revision 1.122 2003/02/21 05:25:45 craigs
* Abstracted out underlying transports for use with peerelements
*
* Revision 1.121 2003/02/03 04:31:05 robertj
* Added special case for Cisco vendor field, they leave it rather incomplete,
*
* Revision 1.120 2003/01/26 02:57:58 craigs
* Fixed oops in last checkin
*
* Revision 1.119 2003/01/26 02:50:38 craigs
* Change so SETUP PDU uses conference and callIdentifier from H323Connection,
* rather than both doing seperately and then overwriting
*
* Revision 1.118 2002/11/28 04:41:48 robertj
* Added support for RAS ServiceControlIndication command.
*
* Revision 1.117 2002/11/27 06:54:57 robertj
* Added Service Control Session management as per Annex K/H.323 via RAS
* only at this stage.
* Added H.248 ASN and very primitive infrastructure for linking into the
* Service Control Session management system.
* Added basic infrastructure for Annex K/H.323 HTTP transport system.
* Added Call Credit Service Control to display account balances.
*
* Revision 1.116 2002/11/21 05:21:42 robertj
* Fixed bug where get lots of zeros at the end of some PDU's
*
* Revision 1.115 2002/11/21 04:15:36 robertj
* Added some changes to help interop with brain dead ASN decoders that do not
* know to ignore fields (eg greater than version 2) they do not understand.
*
* Revision 1.114 2002/11/13 04:38:17 robertj
* Added ability to get (and set) Q.931 release complete cause codes.
*
* Revision 1.113 2002/11/07 03:50:28 robertj
* Added extra "congested" Q.931 codes.
*
* Revision 1.112 2002/10/31 00:45:22 robertj
* Enhanced jitter buffer system so operates dynamically between minimum and
* maximum values. Altered API to assure app writers note the change!
*
* Revision 1.111 2002/10/08 13:08:21 robertj
* Changed for IPv6 support, thanks SΘbastien Josset.
*
* Revision 1.110 2002/08/14 01:07:22 robertj
* Added translation of Q.931 unallocated number release complete code to
* OpenH323 EndedByNoUser which is the nearest match.
*
* Revision 1.109 2002/08/12 05:38:24 robertj
* Changes to the RAS subsystem to support ability to make requests to client
* from gkserver without causing bottlenecks and race conditions.
*
* Revision 1.108 2002/08/05 10:03:47 robertj
* Cosmetic changes to normalise the usage of pragma interface/implementation.
*
* Revision 1.107 2002/08/05 05:17:41 robertj
* Fairly major modifications to support different authentication credentials
* in ARQ to the logged in ones on RRQ. For both client and server.
* Various other H.235 authentication bugs and anomalies fixed on the way.
*
* Revision 1.106 2002/07/31 02:25:04 robertj
* Fixed translation of some call end reasons for to Q.931 codes.
*
* Revision 1.105 2002/07/25 10:55:44 robertj
* Changes to allow more granularity in PDU dumps, hex output increasing
* with increasing trace level.
*
* Revision 1.104 2002/07/11 07:04:12 robertj
* Added build InfoRequest pdu type to RAS.
*
* Revision 1.103 2002/06/13 03:59:56 craigs
* Added codes to progress messages to allow inband audio before connect
*
* Revision 1.102 2002/05/29 03:55:21 robertj
* Added protocol version number checking infrastructure, primarily to improve
* interoperability with stacks that are unforgiving of new features.
*
* Revision 1.101 2002/05/29 00:03:19 robertj
* Fixed unsolicited IRR support in gk client and server,
* including support for IACK and INAK.
*
* Revision 1.100 2002/05/21 09:32:49 robertj
* Added ability to set multiple alias names ona connection by connection
* basis, defaults to endpoint list, thanks Artis Kugevics
*
* Revision 1.99 2002/05/07 03:18:15 robertj
* Added application info (name/version etc) into registered endpoint data.
*
* Revision 1.98 2002/05/03 09:18:49 robertj
* Added automatic retransmission of RAS responses to retried requests.
*
* Revision 1.97 2002/04/24 01:08:09 robertj
* Added output of RAS pdu sequence number to level 3 trace output.
*
* Revision 1.96 2002/03/27 06:04:43 robertj
* Added Temporary Failure end code for connection, an application may
* immediately retry the call if this occurs.
*
* Revision 1.95 2002/03/14 07:56:48 robertj
* Added ability to specify alias type in H323SetAliasAddress, if not specified
* then defaults to previous behaviour, thanks Nils Bokerman.
*
* Revision 1.94 2002/02/13 07:52:30 robertj
* Fixed missing parameters on Q.931 calling number, thanks Markus Rydh
*
* Revision 1.93 2002/02/01 01:48:45 robertj
* Some more fixes for T.120 channel establishment, more to do!
*
* Revision 1.92 2002/01/18 06:01:23 robertj
* Added some H323v4 functions (fastConnectRefused & TCS in SETUP)
*
* Revision 1.91 2001/12/15 07:10:59 robertj
* Added functions to get E.164 address from alias address or addresses.
*
* Revision 1.90 2001/12/14 08:36:36 robertj
* More implementation of T.38, thanks Adam Lazur
*
* Revision 1.89 2001/12/14 06:38:35 robertj
* Broke out conversion of Q.850 and H.225 release complete codes to
* OpenH323 call end reasons enum.
*
* Revision 1.88 2001/12/13 10:56:28 robertj
* Added build of request in progress pdu.
*
* Revision 1.87 2001/10/18 00:58:51 robertj
* Fixed problem with GetDestinationAlias() adding source aliases instead
* of the destination from the setup PDU, thanks Mikael Stolt.
*
* Revision 1.86 2001/10/09 06:55:26 robertj
* Fixed separating destCallSignalAddress fields with tabs in
* GetDestinationAlias() function, thanks Lee Kirchhoff
*
* Revision 1.85 2001/09/26 07:05:29 robertj
* Fixed incorrect tags in building some PDU's, thanks Chris Purvis.
*
* Revision 1.84 2001/09/14 00:08:20 robertj
* Optimised H323SetAliasAddress to use IsE164 function.
*
* Revision 1.83 2001/09/12 07:48:05 robertj
* Fixed various problems with tracing.
*
* Revision 1.82 2001/08/16 07:49:19 robertj
* Changed the H.450 support to be more extensible. Protocol handlers
* are now in separate classes instead of all in H323Connection.
*
* Revision 1.81 2001/08/10 11:03:52 robertj
* Major changes to H.235 support in RAS to support server.
*
* Revision 1.80 2001/08/06 03:08:56 robertj
* Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
*
* Revision 1.79 2001/06/14 06:25:16 robertj
* Added further H.225 PDU build functions.
* Moved some functionality from connection to PDU class.
*
* Revision 1.78 2001/06/14 00:45:21 robertj
* Added extra parameters for Q.931 fields, thanks Rani Assaf
*
* Revision 1.77 2001/06/05 03:14:41 robertj
* Upgraded H.225 ASN to v4 and H.245 ASN to v7.
*
* Revision 1.76 2001/05/30 23:34:54 robertj
* Added functions to send TCS=0 for transmitter side pause.
*
* Revision 1.75 2001/05/09 04:07:55 robertj
* Added more call end codes for busy and congested.
*
* Revision 1.74 2001/05/03 06:45:21 robertj
* Changed trace so dumps PDU if gets an error in decode.
*
* Revision 1.73 2001/04/11 03:01:29 robertj
* Added H.450.2 (call transfer), thanks a LOT to Graeme Reid & Norwood Systems
*
* Revision 1.72 2001/03/24 00:58:03 robertj
* Fixed MSVC warnings.
*
* Revision 1.71 2001/03/24 00:34:49 robertj
* Added read/write hook functions so don't have to duplicate code in
* H323RasH235PDU descendant class of H323RasPDU.
*
* Revision 1.70 2001/03/23 05:38:30 robertj
* Added PTRACE_IF to output trace if a conditional is TRUE.
*
* Revision 1.69 2001/03/02 06:59:59 robertj
* Enhanced the globally unique identifier class.
*
* Revision 1.68 2001/02/09 05:13:56 craigs
* Added pragma implementation to (hopefully) reduce the executable image size
* under Linux
*
* Revision 1.67 2001/01/18 06:04:46 robertj
* Bullet proofed code so local alias can not be empty string. This actually
* fixes an ASN PER encoding bug causing an assert.
*
* Revision 1.66 2000/10/12 05:11:54 robertj
* Added trace log if get transport error on writing PDU.
*
* Revision 1.65 2000/09/25 06:48:11 robertj
* Removed use of alias if there is no alias present, ie only have transport address.
*
* Revision 1.64 2000/09/22 01:35:51 robertj
* Added support for handling LID's that only do symmetric codecs.
*
* Revision 1.63 2000/09/20 01:50:22 craigs
* Added ability to set jitter buffer on a per-connection basis
*
* Revision 1.62 2000/09/05 01:16:20 robertj
* Added "security" call end reason code.
*
* Revision 1.61 2000/07/15 09:51:41 robertj
* Changed adding of Q.931 party numbers to only occur in SETUP.
*
* Revision 1.60 2000/07/13 12:29:49 robertj
* Added some more cause codes on release complete,
*
* Revision 1.59 2000/07/12 10:20:43 robertj
* Fixed incorrect tag code in H.245 ModeChange reject PDU.
*
* Revision 1.58 2000/07/09 15:21:11 robertj
* Changed reference to the word "field" to be more correct IE or "Information Element"
* Fixed return value of Q.931/H.225 PDU read so returns TRUE if no H.225 data in the
* User-User IE. Just flag it as empty and continue processing PDU's.
*
* Revision 1.57 2000/06/21 23:59:44 robertj
* Fixed copy/paste error setting Q.931 display name to incorrect value.
*
* Revision 1.56 2000/06/21 08:07:47 robertj
* Added cause/reason to release complete PDU, where relevent.
*
* Revision 1.55 2000/06/07 05:48:06 robertj
* Added call forwarding.
*
* Revision 1.54 2000/05/25 01:59:05 robertj
* Fixed bugs in calculation of GlLobally Uniqie ID according to DCE/H.225 rules.
*
* Revision 1.53 2000/05/23 11:32:37 robertj
* Rewrite of capability table to combine 2 structures into one and move functionality into that class
* allowing some normalisation of usage across several applications.
* Changed H323Connection so gets a copy of capabilities instead of using endponts, allows adjustments
* to be done depending on the remote client application.
*
* Revision 1.52 2000/05/15 08:38:59 robertj
* Removed addition of calling/called party number field in Q.931 if there isn't one.
*
* Revision 1.51 2000/05/09 12:19:31 robertj
* Added ability to get and set "distinctive ring" Q.931 functionality.
*
* Revision 1.50 2000/05/08 14:07:35 robertj
* Improved the provision and detection of calling and caller numbers, aliases and hostnames.
*
* Revision 1.49 2000/05/08 05:06:27 robertj
* Fixed bug in H.245 close logical channel timeout, thanks XuPeili.
*
* Revision 1.48 2000/05/02 04:32:27 robertj
* Fixed copyright notice comment.
*
* Revision 1.47 2000/04/14 17:29:43 robertj
* Fixed display of error message on timeout when timeouts are not errors.
*
* Revision 1.46 2000/04/10 20:39:18 robertj
* Added support for more sophisticated DTMF and hook flash user indication.
* Added function to extract E164 address from Q.931/H.225 PDU.
*
* Revision 1.45 2000/03/29 04:42:19 robertj
* Improved some trace logging messages.
*
* Revision 1.44 2000/03/25 02:01:07 robertj
* Added adjustable caller name on connection by connection basis.
*
* Revision 1.43 2000/03/21 01:08:10 robertj
* Fixed incorrect call reference code being used in originated call.
*
* Revision 1.42 2000/02/17 12:07:43 robertj
* Used ne wPWLib random number generator after finding major problem in MSVC rand().
*
* Revision 1.41 1999/12/23 22:47:09 robertj
* Added calling party number field.
*
* Revision 1.40 1999/12/11 02:21:00 robertj
* Added ability to have multiple aliases on local endpoint.
*
* Revision 1.39 1999/11/16 13:21:38 robertj
* Removed extraneous error trace when doing asynchronous answer call.
*
* Revision 1.38 1999/11/15 14:11:29 robertj
* Fixed trace output stream being put back after setting hex/fillchar modes.
*
* Revision 1.37 1999/11/10 23:30:20 robertj
* Fixed unexpected closing of transport on PDU read error.
*
* Revision 1.36 1999/11/01 00:48:31 robertj
* Added assert for illegal condition in capabilities, must have set if have table.
*
* Revision 1.35 1999/10/30 23:48:21 robertj
* Fixed incorrect PDU type for H225 RAS location request.
*
* Revision 1.34 1999/10/29 03:35:06 robertj
* Fixed setting of unique ID using fake MAC address from Win32 PPP device.
*
* Revision 1.33 1999/09/21 14:09:49 robertj
* Removed warnings when no tracing enabled.
*
* Revision 1.32 1999/09/10 09:03:01 robertj
* Used new GetInterfaceTable() function to get ethernet address for UniqueID
*
* Revision 1.31 1999/09/10 03:36:48 robertj
* Added simple Q.931 Status response to Q.931 Status Enquiry
*
* Revision 1.30 1999/08/31 12:34:19 robertj
* Added gatekeeper support.
*
* Revision 1.29 1999/08/31 11:37:30 robertj
* Fixed problem with apparently randomly losing signalling channel.
*
* Revision 1.28 1999/08/25 05:08:14 robertj
* File fission (critical mass reached).
*
* Revision 1.27 1999/08/13 06:34:38 robertj
* Fixed problem in CallPartyNumber Q.931 encoding.
* Added field name display to Q.931 protocol.
*
* Revision 1.26 1999/08/10 13:14:15 robertj
* Added Q.931 Called Number field if have "phone number" style destination addres.
*
* Revision 1.25 1999/08/10 11:38:03 robertj
* Changed population of setup UUIE destinationAddress if can be IA5 string.
*
* Revision 1.24 1999/07/26 05:10:30 robertj
* Fixed yet another race condition on connection termination.
*
* Revision 1.23 1999/07/16 14:03:52 robertj
* Fixed bug in Master/Slave negotiation that can cause looping.
*
* Revision 1.22 1999/07/16 06:15:59 robertj
* Corrected semantics for tunnelled master/slave determination in fast start.
*
* Revision 1.21 1999/07/16 02:15:30 robertj
* Fixed more tunneling problems.
*
* Revision 1.20 1999/07/15 14:45:36 robertj
* Added propagation of codec open error to shut down logical channel.
* Fixed control channel start up bug introduced with tunnelling.
*
* Revision 1.19 1999/07/15 09:08:04 robertj
* Added extra debugging for if have PDU decoding error.
*
* Revision 1.18 1999/07/15 09:04:31 robertj
* Fixed some fast start bugs
*
* Revision 1.17 1999/07/10 02:51:36 robertj
* Added mutexing in H245 procedures. Also fixed MSD state bug.
*
* Revision 1.16 1999/07/09 06:09:50 robertj
* Major implementation. An ENORMOUS amount of stuff added everywhere.
*
* Revision 1.15 1999/06/25 10:25:35 robertj
* Added maintentance of callIdentifier variable in H.225 channel.
*
* Revision 1.14 1999/06/22 13:45:40 robertj
* Fixed conferenceIdentifier generation algorithm to bas as in spec.
*
* Revision 1.13 1999/06/19 15:18:38 robertj
* Fixed bug in MasterSlaveDeterminationAck pdu has incorrect master/slave state.
*
* Revision 1.12 1999/06/14 15:08:40 robertj
* Added GSM codec class frame work (still no actual codec).
*
* Revision 1.11 1999/06/14 06:39:08 robertj
* Fixed problem with getting transmit flag to channel from PDU negotiator
*
* Revision 1.10 1999/06/14 05:15:56 robertj
* Changes for using RTP sessions correctly in H323 Logical Channel context
*
* Revision 1.9 1999/06/13 12:41:14 robertj
* Implement logical channel transmitter.
* Fixed H245 connect on receiving call.
*
* Revision 1.8 1999/06/09 05:26:19 robertj
* Major restructuring of classes.
*
* Revision 1.7 1999/06/06 06:06:36 robertj
* Changes for new ASN compiler and v2 protocol ASN files.
*
* Revision 1.6 1999/04/26 06:20:22 robertj
* Fixed bugs in protocol
*
* Revision 1.5 1999/04/26 06:14:47 craigs
* Initial implementation for RTP decoding and lots of stuff
* As a whole, these changes are called "First Noise"
*
* Revision 1.4 1999/02/23 11:04:28 robertj
* Added capability to make outgoing call.
*
* Revision 1.3 1999/02/06 09:23:39 robertj
* BeOS port
*
* Revision 1.2 1999/01/16 02:34:57 robertj
* GNU compiler compatibility.
*
* Revision 1.1 1999/01/16 01:30:54 robertj
* Initial revision
*
*/
#include <ptlib.h>
#ifdef __GNUC__
#pragma implementation "h323pdu.h"
#endif
#include "h323pdu.h"
#include "h323ep.h"
#include "h225ras.h"
#define new PNEW
const unsigned H225_ProtocolID[] = { 0,0,8,2250,0,H225_PROTOCOL_VERSION };
const unsigned H245_ProtocolID[] = { 0,0,8,245 ,0,H245_PROTOCOL_VERSION };
static const char E164NumberPrefix[] = "E164:";
static const char PrivatePartyPrefix[] = "Private:";
static const char DataPartyPrefix[] = "Data:";
static const char TelexPartyPrefix[] = "Telex:";
static const char NSPNumberPrefix[] = "NSP:";
///////////////////////////////////////////////////////////////////////////////
#if PTRACING
void H323TraceDumpPDU(const char * proto,
BOOL writing,
const PBYTEArray & rawData,
const PASN_Object & pdu,
const PASN_Choice & tags,
unsigned seqNum)
{
if (!PTrace::CanTrace(3))
return;
ostream & trace = PTrace::Begin(3, __FILE__, __LINE__);
trace << proto << '\t' << (writing ? "Send" : "Receiv") << "ing PDU:";
if (PTrace::CanTrace(4)) {
trace << "\n "
<< resetiosflags(ios::floatfield);
if (!PTrace::CanTrace(5))
trace << setiosflags(ios::fixed); // Will truncate hex dumps to 32 bytes
trace << setprecision(2) << pdu
<< resetiosflags(ios::floatfield);
if (PTrace::CanTrace(6))
trace << "\nRaw PDU:\n"
<< hex << setfill('0')
<< setprecision(2) << rawData
<< dec << setfill(' ');
}
else {
trace << ' ' << tags.GetTagName();
PASN_Object & next = tags.GetObject();
if (next.IsDescendant(PASN_Choice::Class()))
trace << ' ' << ((PASN_Choice &)next).GetTagName();
if (seqNum > 0)
trace << ' ' << seqNum;
}
trace << PTrace::End;
}
#endif
///////////////////////////////////////////////////////////////////////////////
void H323SetAliasAddresses(const H323TransportAddressArray & addresses, H225_ArrayOf_AliasAddress & aliases)
{
aliases.SetSize(addresses.GetSize());
for (PINDEX i = 0; i < addresses.GetSize(); i++)
H323SetAliasAddress(addresses[i], aliases[i]);
}
void H323SetAliasAddresses(const PStringArray & names,
H225_ArrayOf_AliasAddress & aliases,
int tag)
{
aliases.SetSize(names.GetSize());
for (PINDEX i = 0; i < names.GetSize(); i++)
H323SetAliasAddress(names[i], aliases[i], tag);
}
void H323SetAliasAddresses(const PStringList & names,
H225_ArrayOf_AliasAddress & aliases,
int tag)
{
aliases.SetSize(names.GetSize());
for (PINDEX i = 0; i < names.GetSize(); i++)
H323SetAliasAddress(names[i], aliases[i], tag);
}
static BOOL IsE164(const PString & str)
{
return !str && strspn(str, "1234567890*#") == strlen(str);
}
void H323SetAliasAddress(const H323TransportAddress & address, H225_AliasAddress & alias)
{
alias.SetTag(H225_AliasAddress::e_transportID);
address.SetPDU(alias);
}
void H323SetAliasAddress(const PString & name, H225_AliasAddress & alias, int tag)
{
// See if explicitly specified the alias type, otherwise guess it from
// the string, if all digits then assume an e164 address.
if (tag < 0)
tag = IsE164(name) ? H225_AliasAddress::e_dialedDigits : H225_AliasAddress::e_h323_ID;
alias.SetTag(tag);
switch (alias.GetTag()) {
case H225_AliasAddress::e_dialedDigits :
case H225_AliasAddress::e_url_ID :
case H225_AliasAddress::e_email_ID :
(PASN_IA5String &)alias = name;
break;
case H225_AliasAddress::e_h323_ID :
(PASN_BMPString &)alias = name;
break;
case H225_AliasAddress::e_transportID :
{
H323TransportAddress addr = name;
addr.SetPDU(alias);
break;
}
case H225_AliasAddress::e_partyNumber :
{
H225_PartyNumber & party = alias;
if (strncmp(name, E164NumberPrefix, sizeof(E164NumberPrefix)-1) == 0) {
party.SetTag(H225_PartyNumber::e_e164Number);
H225_PublicPartyNumber & number = party;
number.m_publicNumberDigits = name.Mid(sizeof(E164NumberPrefix)-1);
}
else if (strncmp(name, PrivatePartyPrefix, sizeof(PrivatePartyPrefix)-1) == 0) {
party.SetTag(H225_PartyNumber::e_privateNumber);
H225_PrivatePartyNumber & number = party;
number.m_privateNumberDigits = name.Mid(sizeof(PrivatePartyPrefix)-1);
}
else if (strncmp(name, DataPartyPrefix, sizeof(DataPartyPrefix)-1) == 0) {
party.SetTag(H225_PartyNumber::e_dataPartyNumber);
(H225_NumberDigits &)party = name.Mid(sizeof(DataPartyPrefix)-1);
}
else if (strncmp(name, TelexPartyPrefix, sizeof(TelexPartyPrefix)-1) == 0) {
party.SetTag(H225_PartyNumber::e_telexPartyNumber);
(H225_NumberDigits &)party = name.Mid(sizeof(TelexPartyPrefix)-1);
}
else if (strncmp(name, NSPNumberPrefix, sizeof(NSPNumberPrefix)-1) == 0) {
party.SetTag(H225_PartyNumber::e_nationalStandardPartyNumber);
(H225_NumberDigits &)party = name.Mid(sizeof(NSPNumberPrefix)-1);
}
}
default :
break;
}
}
/////////////////////////////////////////////////////////////////////////////
PStringArray H323GetAliasAddressStrings(const H225_ArrayOf_AliasAddress & aliases)
{
PStringArray strings(aliases.GetSize());
for (PINDEX i = 0; i < aliases.GetSize(); i++)
strings[i] = H323GetAliasAddressString(aliases[i]);
return strings;
}
PString H323GetAliasAddressString(const H225_AliasAddress & alias)
{
switch (alias.GetTag()) {
case H225_AliasAddress::e_dialedDigits :
case H225_AliasAddress::e_url_ID :
case H225_AliasAddress::e_email_ID :
return (const PASN_IA5String &)alias;
case H225_AliasAddress::e_h323_ID :
return (const PASN_BMPString &)alias;
case H225_AliasAddress::e_transportID :
return H323TransportAddress(alias);
case H225_AliasAddress::e_partyNumber :
{
const H225_PartyNumber & party = alias;
switch (party.GetTag()) {
case H225_PartyNumber::e_e164Number :
{
const H225_PublicPartyNumber & number = party;
return E164NumberPrefix + (PString)number.m_publicNumberDigits;
}
case H225_PartyNumber::e_privateNumber :
{
const H225_PrivatePartyNumber & number = party;
return PrivatePartyPrefix + (PString)number.m_privateNumberDigits;
}
case H225_PartyNumber::e_dataPartyNumber :
return DataPartyPrefix + (PString)(const H225_NumberDigits &)party;
case H225_PartyNumber::e_telexPartyNumber :
return TelexPartyPrefix + (PString)(const H225_NumberDigits &)party;
case H225_PartyNumber::e_nationalStandardPartyNumber :
return NSPNumberPrefix + (PString)(const H225_NumberDigits &)party;
}
break;
}
default :
break;
}
return PString();
}
PString H323GetAliasAddressE164(const H225_AliasAddress & alias)
{
PString str = H323GetAliasAddressString(alias);
if (IsE164(str))
return str;
return PString();
}
PString H323GetAliasAddressE164(const H225_ArrayOf_AliasAddress & aliases)
{
for (PINDEX i = 0; i < aliases.GetSize(); i++) {
PString alias = H323GetAliasAddressE164(aliases[i]);
if (!alias)
return alias;
}
return PString();
}
///////////////////////////////////////////////////////////////////////////////
PString H323GetApplicationInfo(const H225_VendorIdentifier & vendor)
{
PStringStream str;
PString product = vendor.m_productId.AsString();
PString version = vendor.m_versionId.AsString();
// Special case, Cisco IOS does not put in the product and version fields
if (vendor.m_vendor.m_t35CountryCode == 181 &&
vendor.m_vendor.m_t35Extension == 0 &&
vendor.m_vendor.m_manufacturerCode == 18) {
if (product.IsEmpty())
product = "Cisco IOS";
if (version.IsEmpty())
version = "12.2";
}
str << product << '\t' << version << '\t' << vendor.m_vendor.m_t35CountryCode;
if (vendor.m_vendor.m_t35Extension != 0)
str << '.' << vendor.m_vendor.m_t35Extension;
str << '/' << vendor.m_vendor.m_manufacturerCode;
str.MakeMinimumSize();
return str;
}
///////////////////////////////////////////////////////////////////////////////
H323SignalPDU::H323SignalPDU()
{
}
static unsigned SetH225Version(const H323Connection & connection,
H225_ProtocolIdentifier & protocolIdentifier)
{
unsigned version = connection.GetSignallingVersion();
protocolIdentifier.SetValue(psprintf("0.0.8.2250.0.%u", version));
return version;
}
H225_Setup_UUIE & H323SignalPDU::BuildSetup(const H323Connection & connection,
const H323TransportAddress & destAddr)
{
H323EndPoint & endpoint = connection.GetEndPoint();
q931pdu.BuildSetup(connection.GetCallReference());
SetQ931Fields(connection, TRUE);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_setup);
H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
if (SetH225Version(connection, setup.m_protocolIdentifier) < 3) {
setup.RemoveOptionalField(H225_Setup_UUIE::e_multipleCalls);
setup.RemoveOptionalField(H225_Setup_UUIE::e_maintainConnection);
}
setup.IncludeOptionalField(H225_Setup_UUIE::e_sourceAddress);
H323SetAliasAddresses(endpoint.GetAliasNames(), setup.m_sourceAddress);
setup.m_conferenceID = connection.GetConferenceIdentifier();
setup.m_conferenceGoal.SetTag(H225_Setup_UUIE_conferenceGoal::e_create);
setup.m_callType.SetTag(H225_CallType::e_pointToPoint);
setup.m_callIdentifier.m_guid = connection.GetCallIdentifier();
setup.m_mediaWaitForConnect = FALSE;
setup.m_canOverlapSend = FALSE;
if (!destAddr) {
setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress);
destAddr.SetPDU(setup.m_destCallSignalAddress);
}
PString destAlias = connection.GetRemotePartyName();
if (!destAlias && destAlias != destAddr) {
setup.IncludeOptionalField(H225_Setup_UUIE::e_destinationAddress);
setup.m_destinationAddress.SetSize(1);
// Try and encode it as a phone number
H323SetAliasAddress(destAlias, setup.m_destinationAddress[0]);
if (setup.m_destinationAddress[0].GetTag() == H225_AliasAddress::e_dialedDigits)
q931pdu.SetCalledPartyNumber(destAlias);
}
endpoint.SetEndpointTypeInfo(setup.m_sourceInfo);
return setup;
}
H225_CallProceeding_UUIE &
H323SignalPDU::BuildCallProceeding(const H323Connection & connection)
{
q931pdu.BuildCallProceeding(connection.GetCallReference());
SetQ931Fields(connection);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_callProceeding);
H225_CallProceeding_UUIE & proceeding = m_h323_uu_pdu.m_h323_message_body;
if (SetH225Version(connection, proceeding.m_protocolIdentifier) < 3) {
proceeding.RemoveOptionalField(H225_CallProceeding_UUIE::e_multipleCalls);
proceeding.RemoveOptionalField(H225_CallProceeding_UUIE::e_maintainConnection);
}
proceeding.m_callIdentifier.m_guid = connection.GetCallIdentifier();
connection.GetEndPoint().SetEndpointTypeInfo(proceeding.m_destinationInfo);
return proceeding;
}
H225_Connect_UUIE & H323SignalPDU::BuildConnect(const H323Connection & connection)
{
q931pdu.BuildConnect(connection.GetCallReference());
SetQ931Fields(connection);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_connect);
H225_Connect_UUIE & connect = m_h323_uu_pdu.m_h323_message_body;
if (SetH225Version(connection, connect.m_protocolIdentifier) < 3) {
connect.RemoveOptionalField(H225_Connect_UUIE::e_multipleCalls);
connect.RemoveOptionalField(H225_Connect_UUIE::e_maintainConnection);
}
connect.m_callIdentifier.m_guid = connection.GetCallIdentifier();
connect.m_conferenceID = connection.GetConferenceIdentifier();
connection.GetEndPoint().SetEndpointTypeInfo(connect.m_destinationInfo);
return connect;
}
H225_Connect_UUIE & H323SignalPDU::BuildConnect(const H323Connection & connection,
const PIPSocket::Address & h245Address,
WORD port)
{
H225_Connect_UUIE & connect = BuildConnect(connection);
// indicate we are including the optional H245 address in the PDU
connect.IncludeOptionalField(H225_Connect_UUIE::e_h245Address);
// convert IP address into the correct H245 type
H323TransportAddress transAddr(h245Address, port);
transAddr.SetPDU(connect.m_h245Address);
return connect;
}
H225_Alerting_UUIE & H323SignalPDU::BuildAlerting(const H323Connection & connection)
{
q931pdu.BuildAlerting(connection.GetCallReference());
SetQ931Fields(connection);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_alerting);
H225_Alerting_UUIE & alerting = m_h323_uu_pdu.m_h323_message_body;
if (SetH225Version(connection, alerting.m_protocolIdentifier) < 3) {
alerting.RemoveOptionalField(H225_Alerting_UUIE::e_multipleCalls);
alerting.RemoveOptionalField(H225_Alerting_UUIE::e_maintainConnection);
}
alerting.m_callIdentifier.m_guid = connection.GetCallIdentifier();
connection.GetEndPoint().SetEndpointTypeInfo(alerting.m_destinationInfo);
return alerting;
}
H225_Information_UUIE & H323SignalPDU::BuildInformation(const H323Connection & connection)
{
q931pdu.BuildInformation(connection.GetCallReference(), connection.HadAnsweredCall());
SetQ931Fields(connection);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_information);
H225_Information_UUIE & information = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, information.m_protocolIdentifier);
information.m_callIdentifier.m_guid = connection.GetCallIdentifier();
return information;
}
H323Connection::CallEndReason H323TranslateToCallEndReason(Q931::CauseValues cause,
const H225_ReleaseCompleteReason & reason)
{
switch (cause) {
case Q931::ErrorInCauseIE :
switch (reason.GetTag()) {
case H225_ReleaseCompleteReason::e_noBandwidth :
return H323Connection::EndedByNoBandwidth;
case H225_ReleaseCompleteReason::e_gatekeeperResources :
case H225_ReleaseCompleteReason::e_gatewayResources :
case H225_ReleaseCompleteReason::e_adaptiveBusy :
return H323Connection::EndedByRemoteCongestion;
case H225_ReleaseCompleteReason::e_unreachableDestination :
return H323Connection::EndedByUnreachable;
case H225_ReleaseCompleteReason::e_calledPartyNotRegistered :
return H323Connection::EndedByNoUser;
case H225_ReleaseCompleteReason::e_callerNotRegistered:
return H323Connection::EndedByGatekeeper;
case H225_ReleaseCompleteReason::e_securityDenied:
return H323Connection::EndedBySecurityDenial;
case H225_ReleaseCompleteReason::e_newConnectionNeeded:
return H323Connection::EndedByTemporaryFailure;
}
// Do next case
case Q931::UnknownCauseIE :
return H323Connection::EndedByRefusal;
case Q931::NormalCallClearing :
return H323Connection::EndedByRemoteUser;
case Q931::UserBusy :
return H323Connection::EndedByRemoteBusy;
case Q931::Congestion :
case Q931::NoCircuitChannelAvailable :
case Q931::RequestedCircuitNotAvailable :
case Q931::ResourceUnavailable :
return H323Connection::EndedByRemoteCongestion;
case Q931::NoResponse :
case Q931::NoAnswer :
return H323Connection::EndedByNoAnswer;
case Q931::NoRouteToNetwork :
case Q931::ChannelUnacceptable :
return H323Connection::EndedByUnreachable;
case Q931::UnallocatedNumber :
case Q931::NoRouteToDestination :
case Q931::SubscriberAbsent :
return H323Connection::EndedByNoUser;
case Q931::Redirection :
return H323Connection::EndedByCallForwarded;
case Q931::DestinationOutOfOrder :
return H323Connection::EndedByConnectFail;
case Q931::TemporaryFailure :
return H323Connection::EndedByTemporaryFailure;
default:
return H323Connection::EndedByQ931Cause;
}
}
Q931::CauseValues H323TranslateFromCallEndReason(const H323Connection & connection,
H225_ReleaseCompleteReason & reason)
{
static int const ReasonCodes[H323Connection::NumCallEndReasons] = {
Q931::NormalCallClearing, /// EndedByLocalUser, Local endpoint application cleared call
Q931::UserBusy, /// EndedByNoAccept, Local endpoint did not accept call
Q931::CallRejected, /// EndedByAnswerDenied, Local endpoint declined to answer call
Q931::NormalCallClearing, /// EndedByRemoteUser, Remote endpoint application cleared call
-H225_ReleaseCompleteReason::e_destinationRejection, /// EndedByRefusal, Remote endpoint refused call
Q931::NoAnswer, /// EndedByNoAnswer, Remote endpoint did not answer in required time
Q931::NormalCallClearing, /// EndedByCallerAbort, Remote endpoint stopped calling
-H225_ReleaseCompleteReason::e_undefinedReason, /// EndedByTransportFail, Transport error cleared call
-H225_ReleaseCompleteReason::e_unreachableDestination, /// EndedByConnectFail, Transport connection failed to establish call
-H225_ReleaseCompleteReason::e_gatekeeperResources, /// EndedByGatekeeper, Gatekeeper has cleared call
-H225_ReleaseCompleteReason::e_calledPartyNotRegistered,/// EndedByNoUser, Call failed as could not find user (in GK)
-H225_ReleaseCompleteReason::e_noBandwidth, /// EndedByNoBandwidth, Call failed as could not get enough bandwidth
-H225_ReleaseCompleteReason::e_undefinedReason, /// EndedByCapabilityExchange,Could not find common capabilities
-H225_ReleaseCompleteReason::e_facilityCallDeflection, /// EndedByCallForwarded, Call was forwarded using FACILITY message
-H225_ReleaseCompleteReason::e_securityDenied, /// EndedBySecurityDenial, Call failed a security check and was ended
Q931::UserBusy, /// EndedByLocalBusy, Local endpoint busy
Q931::Congestion, /// EndedByLocalCongestion, Local endpoint congested
Q931::UserBusy, /// EndedByRemoteBusy, Remote endpoint busy
Q931::Congestion, /// EndedByRemoteCongestion, Remote endpoint congested
Q931::NoRouteToDestination, /// EndedByUnreachable, Could not reach the remote party
Q931::InvalidCallReference, /// EndedByNoEndPoint, The remote party is not running an endpoint
Q931::DestinationOutOfOrder, /// EndedByHostOffline, The remote party host off line
Q931::TemporaryFailure, /// EndedByTemporaryFailure The remote failed temporarily app may retry
Q931::UnknownCauseIE, /// EndedByQ931Cause, The remote ended the call with unmapped Q.931 cause code
Q931::NormalUnspecified, /// EndedByDurationLimit, Call cleared due to an enforced duration limit
};
int code = ReasonCodes[connection.GetCallEndReason()];
if (code == Q931::UnknownCauseIE)
return (Q931::CauseValues)connection.GetCallEndReason();
if (code >= 0)
return (Q931::CauseValues)code;
reason.SetTag(-code);
return Q931::ErrorInCauseIE;
}
H225_ReleaseComplete_UUIE &
H323SignalPDU::BuildReleaseComplete(const H323Connection & connection)
{
q931pdu.BuildReleaseComplete(connection.GetCallReference(), connection.HadAnsweredCall());
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_releaseComplete);
H225_ReleaseComplete_UUIE & release = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, release.m_protocolIdentifier);
release.m_callIdentifier.m_guid = connection.GetCallIdentifier();
Q931::CauseValues cause = H323TranslateFromCallEndReason(connection, release.m_reason);
if (cause != Q931::ErrorInCauseIE)
q931pdu.SetCause(cause);
else
release.IncludeOptionalField(H225_ReleaseComplete_UUIE::e_reason);
return release;
}
H225_Facility_UUIE * H323SignalPDU::BuildFacility(const H323Connection & connection,
BOOL empty)
{
q931pdu.BuildFacility(connection.GetCallReference(), connection.HadAnsweredCall());
if (empty) {
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
return NULL;
}
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_facility);
H225_Facility_UUIE & fac = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, fac.m_protocolIdentifier);
fac.IncludeOptionalField(H225_Facility_UUIE::e_callIdentifier);
fac.m_callIdentifier.m_guid = connection.GetCallIdentifier();
return &fac;
}
H225_Progress_UUIE & H323SignalPDU::BuildProgress(const H323Connection & connection)
{
q931pdu.BuildProgress(connection.GetCallReference(), connection.HadAnsweredCall(), Q931::ProgressInbandInformationAvailable);
SetQ931Fields(connection);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_progress);
H225_Progress_UUIE & progress = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, progress.m_protocolIdentifier);
progress.m_callIdentifier.m_guid = connection.GetCallIdentifier();
connection.GetEndPoint().SetEndpointTypeInfo(progress.m_destinationInfo);
return progress;
}
H225_Status_UUIE & H323SignalPDU::BuildStatus(const H323Connection & connection)
{
q931pdu.BuildStatus(connection.GetCallReference(), connection.HadAnsweredCall());
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_status);
H225_Status_UUIE & status = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, status.m_protocolIdentifier);
status.m_callIdentifier.m_guid = connection.GetCallIdentifier();
return status;
}
H225_StatusInquiry_UUIE & H323SignalPDU::BuildStatusInquiry(const H323Connection & connection)
{
q931pdu.BuildStatusEnquiry(connection.GetCallReference(), connection.HadAnsweredCall());
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_statusInquiry);
H225_StatusInquiry_UUIE & inquiry = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, inquiry.m_protocolIdentifier);
inquiry.m_callIdentifier.m_guid = connection.GetCallIdentifier();
return inquiry;
}
H225_SetupAcknowledge_UUIE & H323SignalPDU::BuildSetupAcknowledge(const H323Connection & connection)
{
q931pdu.BuildSetupAcknowledge(connection.GetCallReference());
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_setupAcknowledge);
H225_SetupAcknowledge_UUIE & setupAck = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, setupAck.m_protocolIdentifier);
setupAck.m_callIdentifier.m_guid = connection.GetCallIdentifier();
return setupAck;
}
H225_Notify_UUIE & H323SignalPDU::BuildNotify(const H323Connection & connection)
{
q931pdu.BuildNotify(connection.GetCallReference(), connection.HadAnsweredCall());
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_notify);
H225_Notify_UUIE & notify = m_h323_uu_pdu.m_h323_message_body;
SetH225Version(connection, notify.m_protocolIdentifier);
notify.m_callIdentifier.m_guid = connection.GetCallIdentifier();
return notify;
}
void H323SignalPDU::BuildQ931()
{
// Encode the H225 PDu into the Q931 PDU as User-User data
PPER_Stream strm;
Encode(strm);
strm.CompleteEncoding();
q931pdu.SetIE(Q931::UserUserIE, strm);
}
void H323SignalPDU::PrintOn(ostream & strm) const
{
int indent = strm.precision() + 2;
strm << "{\n"
<< setw(indent+10) << "q931pdu = " << setprecision(indent) << q931pdu << '\n'
<< setw(indent+10) << "h225pdu = " << setprecision(indent);
H225_H323_UserInformation::PrintOn(strm);
strm << '\n'
<< setw(indent-1) << "}";
}
BOOL H323SignalPDU::Read(H323Transport & transport)
{
PBYTEArray rawData;
if (!transport.ReadPDU(rawData)) {
PTRACE_IF(1, transport.GetErrorCode(PChannel::LastReadError) != PChannel::Timeout,
"H225\tRead error (" << transport.GetErrorNumber(PChannel::LastReadError)
<< "): " << transport.GetErrorText(PChannel::LastReadError));
return FALSE;
}
if (!q931pdu.Decode(rawData)) {
PTRACE(1, "H225\tParse error of Q931 PDU:\n" << hex << setfill('0')
<< setprecision(2) << rawData
<< dec << setfill(' '));
return FALSE;
}
if (!q931pdu.HasIE(Q931::UserUserIE)) {
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
PTRACE(1, "H225\tNo Q931 User-User Information Element,"
"\nRaw PDU:\n" << hex << setfill('0')
<< setprecision(2) << rawData
<< dec << setfill(' ') <<
"\nQ.931 PDU:\n " << setprecision(2) << q931pdu);
return TRUE;
}
PPER_Stream strm = q931pdu.GetIE(Q931::UserUserIE);
if (!Decode(strm)) {
PTRACE(1, "H225\tRead error: PER decode failure in Q.931 User-User Information Element,"
"\nRaw PDU:\n" << hex << setfill('0')
<< setprecision(2) << rawData
<< dec << setfill(' ') <<
"\nQ.931 PDU:\n " << setprecision(2) << q931pdu <<
"\nPartial PDU:\n " << setprecision(2) << *this);
m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
return TRUE;
}
H323TraceDumpPDU("H225", FALSE, rawData, *this, m_h323_uu_pdu.m_h323_message_body, 0);
return TRUE;
}
BOOL H323SignalPDU::Write(H323Transport & transport)
{
if (!q931pdu.HasIE(Q931::UserUserIE) && m_h323_uu_pdu.m_h323_message_body.IsValid())
BuildQ931();
PBYTEArray rawData;
if (!q931pdu.Encode(rawData))
return FALSE;
H323TraceDumpPDU("H225", TRUE, rawData, *this, m_h323_uu_pdu.m_h323_message_body, 0);
if (transport.WritePDU(rawData))
return TRUE;
PTRACE(1, "H225\tWrite PDU failed ("
<< transport.GetErrorNumber(PChannel::LastWriteError)
<< "): " << transport.GetErrorText(PChannel::LastWriteError));
return FALSE;
}
PString H323SignalPDU::GetSourceAliases(const H323Transport * transport) const
{
PString remoteHostName;
if (transport != NULL)
remoteHostName = transport->GetRemoteAddress().GetHostName();
PString displayName = GetQ931().GetDisplayName();
PStringStream aliases;
if (displayName != remoteHostName)
aliases << displayName;
if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
if (remoteHostName.IsEmpty() &&
setup.HasOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress)) {
H323TransportAddress remoteAddress(setup.m_sourceCallSignalAddress);
remoteHostName = remoteAddress.GetHostName();
}
if (setup.m_sourceAddress.GetSize() > 0) {
BOOL needParen = !aliases.IsEmpty();
BOOL needComma = FALSE;
for (PINDEX i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
PString alias = H323GetAliasAddressString(setup.m_sourceAddress[i]);
if (alias != displayName && alias != remoteHostName) {
if (needComma)
aliases << ", ";
else if (needParen)
aliases << " (";
aliases << alias;
needComma = TRUE;
}
}
if (needParen && needComma)
aliases << ')';
}
}
if (aliases.IsEmpty())
return remoteHostName;
aliases << " [" << remoteHostName << ']';
aliases.MakeMinimumSize();
return aliases;
}
PString H323SignalPDU::GetDestinationAlias(BOOL firstAliasOnly) const
{
PStringStream aliases;
PString number;
if (GetQ931().GetCalledPartyNumber(number)) {
if (firstAliasOnly)
return number;
aliases << number;
}
if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
if (setup.m_destinationAddress.GetSize() > 0) {
if (firstAliasOnly)
return H323GetAliasAddressString(setup.m_destinationAddress[0]);
for (PINDEX i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
if (!aliases.IsEmpty())
aliases << '\t';
aliases << H323GetAliasAddressString(setup.m_destinationAddress[i]);
}
}
if (setup.HasOptionalField(H225_Setup_UUIE::e_destCallSignalAddress)) {
if (!aliases.IsEmpty())
aliases << '\t';
aliases << H323TransportAddress(setup.m_destCallSignalAddress);
}
}
aliases.MakeMinimumSize();
return aliases;
}
BOOL H323SignalPDU::GetSourceE164(PString & number) const
{
if (GetQ931().GetCallingPartyNumber(number))
return TRUE;
if (m_h323_uu_pdu.m_h323_message_body.GetTag() != H225_H323_UU_PDU_h323_message_body::e_setup)
return FALSE;
const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
if (!setup.HasOptionalField(H225_Setup_UUIE::e_sourceAddress))
return FALSE;
PINDEX i;
for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
if (setup.m_sourceAddress[i].GetTag() == H225_AliasAddress::e_dialedDigits) {
number = (PASN_IA5String &)setup.m_sourceAddress[i];
return TRUE;
}
}
for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
PString str = H323GetAliasAddressString(setup.m_sourceAddress[i]);
if (IsE164(str)) {
number = str;
return TRUE;
}
}
return FALSE;
}
BOOL H323SignalPDU::GetDestinationE164(PString & number) const
{
if (GetQ931().GetCalledPartyNumber(number))
return TRUE;
if (m_h323_uu_pdu.m_h323_message_body.GetTag() != H225_H323_UU_PDU_h323_message_body::e_setup)
return FALSE;
const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
if (!setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress))
return FALSE;
PINDEX i;
for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
if (setup.m_destinationAddress[i].GetTag() == H225_AliasAddress::e_dialedDigits) {
number = (PASN_IA5String &)setup.m_destinationAddress[i];
return TRUE;
}
}
for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
PString str = H323GetAliasAddressString(setup.m_destinationAddress[i]);
if (IsE164(str)) {
number = str;
return TRUE;
}
}
return FALSE;
}
unsigned H323SignalPDU::GetDistinctiveRing() const
{
Q931::SignalInfo sig = GetQ931().GetSignalInfo();
if (sig < Q931::SignalAlertingPattern0 || sig > Q931::SignalAlertingPattern7)
return 0;
return sig - Q931::SignalAlertingPattern0;
}
void H323SignalPDU::SetQ931Fields(const H323Connection & connection,
BOOL insertPartyNumbers,
unsigned plan,
unsigned type,
int presentation,
int screening)
{
PINDEX i;
const PStringList & aliases = connection.GetLocalAliasNames();
PString number;
PString localName = connection.GetLocalPartyName();
if (IsE164(localName)) {
number = localName;
for (i = 0; i < aliases.GetSize(); i++) {
if (!IsE164(aliases[i])) {
q931pdu.SetDisplayName(aliases[i]);
break;
}
}
}
else {
if (!localName)
q931pdu.SetDisplayName(localName);
for (i = 0; i < aliases.GetSize(); i++) {
if (IsE164(aliases[i])) {
number = aliases[i];
break;
}
}
}
if (insertPartyNumbers) {
PString otherNumber = connection.GetRemotePartyNumber();
if (otherNumber.IsEmpty()) {
PString otherName = connection.GetRemotePartyName();
if (IsE164(otherName))
otherNumber = otherName;
}
if (connection.HadAnsweredCall()) {
if (!number)
q931pdu.SetCalledPartyNumber(number, plan, type);
if (!otherNumber)
q931pdu.SetCallingPartyNumber(otherNumber, plan, type, presentation, screening);
}
else {
if (!number)
q931pdu.SetCallingPartyNumber(number, plan, type, presentation, screening);
if (!otherNumber)
q931pdu.SetCalledPartyNumber(otherNumber, plan, type);
}
}
unsigned ring = connection.GetDistinctiveRing();
if (ring != 0)
q931pdu.SetSignalInfo((Q931::SignalInfo)(ring + Q931::SignalAlertingPattern0));
}
/////////////////////////////////////////////////////////////////////////////
H245_RequestMessage & H323ControlPDU::Build(H245_RequestMessage::Choices request)
{
SetTag(e_request);
H245_RequestMessage & msg = *this;
msg.SetTag(request);
return msg;
}
H245_ResponseMessage & H323ControlPDU::Build(H245_ResponseMessage::Choices response)
{
SetTag(e_response);
H245_ResponseMessage & resp = *this;
resp.SetTag(response);
return resp;
}
H245_CommandMessage & H323ControlPDU::Build(H245_CommandMessage::Choices command)
{
SetTag(e_command);
H245_CommandMessage & cmd = *this;
cmd.SetTag(command);
return cmd;
}
H245_IndicationMessage & H323ControlPDU::Build(H245_IndicationMessage::Choices indication)
{
SetTag(e_indication);
H245_IndicationMessage & ind = *this;
ind.SetTag(indication);
return ind;
}
H245_MasterSlaveDetermination &
H323ControlPDU::BuildMasterSlaveDetermination(unsigned terminalType,
unsigned statusDeterminationNumber)
{
H245_MasterSlaveDetermination & msd = Build(H245_RequestMessage::e_masterSlaveDetermination);
msd.m_terminalType = terminalType;
msd.m_statusDeterminationNumber = statusDeterminationNumber;
return msd;
}
H245_MasterSlaveDeterminationAck &
H323ControlPDU::BuildMasterSlaveDeterminationAck(BOOL isMaster)
{
H245_MasterSlaveDeterminationAck & msda = Build(H245_ResponseMessage::e_masterSlaveDeterminationAck);
msda.m_decision.SetTag(isMaster
? H245_MasterSlaveDeterminationAck_decision::e_slave
: H245_MasterSlaveDeterminationAck_decision::e_master);
return msda;
}
H245_MasterSlaveDeterminationReject &
H323ControlPDU::BuildMasterSlaveDeterminationReject(unsigned cause)
{
H245_MasterSlaveDeterminationReject & msdr = Build(H245_ResponseMessage::e_masterSlaveDeterminationReject);
msdr.m_cause.SetTag(cause);
return msdr;
}
H245_TerminalCapabilitySet &
H323ControlPDU::BuildTerminalCapabilitySet(const H323Connection & connection,
unsigned sequenceNumber,
BOOL empty)
{
H245_TerminalCapabilitySet & cap = Build(H245_RequestMessage::e_terminalCapabilitySet);
cap.m_sequenceNumber = sequenceNumber;
cap.m_protocolIdentifier.SetValue(H245_ProtocolID, PARRAYSIZE(H245_ProtocolID));
if (empty)
return cap;
cap.IncludeOptionalField(H245_TerminalCapabilitySet::e_multiplexCapability);
cap.m_multiplexCapability.SetTag(H245_MultiplexCapability::e_h2250Capability);
H245_H2250Capability & h225_0 = cap.m_multiplexCapability;
h225_0.m_maximumAudioDelayJitter = connection.GetMaxAudioJitterDelay();
h225_0.m_receiveMultipointCapability.m_mediaDistributionCapability.SetSize(1);
h225_0.m_transmitMultipointCapability.m_mediaDistributionCapability.SetSize(1);
h225_0.m_receiveAndTransmitMultipointCapability.m_mediaDistributionCapability.SetSize(1);
h225_0.m_t120DynamicPortCapability = TRUE;
// Set the table of capabilities
connection.GetLocalCapabilities().BuildPDU(connection, cap);
return cap;
}
H245_TerminalCapabilitySetAck &
H323ControlPDU::BuildTerminalCapabilitySetAck(unsigned sequenceNumber)
{
H245_TerminalCapabilitySetAck & cap = Build(H245_ResponseMessage::e_terminalCapabilitySetAck);
cap.m_sequenceNumber = sequenceNumber;
return cap;
}
H245_TerminalCapabilitySetReject &
H323ControlPDU::BuildTerminalCapabilitySetReject(unsigned sequenceNumber,
unsigned cause)
{
H245_TerminalCapabilitySetReject & cap = Build(H245_ResponseMessage::e_terminalCapabilitySetReject);
cap.m_sequenceNumber = sequenceNumber;
cap.m_cause.SetTag(cause);
return cap;
}
H245_OpenLogicalChannel &
H323ControlPDU::BuildOpenLogicalChannel(unsigned forwardLogicalChannelNumber)
{
H245_OpenLogicalChannel & open = Build(H245_RequestMessage::e_openLogicalChannel);
open.m_forwardLogicalChannelNumber = forwardLogicalChannelNumber;
return open;
}
H245_RequestChannelClose &
H323ControlPDU::BuildRequestChannelClose(unsigned channelNumber,
unsigned reason)
{
H245_RequestChannelClose & rcc = Build(H245_RequestMessage::e_requestChannelClose);
rcc.m_forwardLogicalChannelNumber = channelNumber;
rcc.IncludeOptionalField(H245_RequestChannelClose::e_reason);
rcc.m_reason.SetTag(reason);
return rcc;
}
H245_CloseLogicalChannel &
H323ControlPDU::BuildCloseLogicalChannel(unsigned channelNumber)
{
H245_CloseLogicalChannel & clc = Build(H245_RequestMessage::e_closeLogicalChannel);
clc.m_forwardLogicalChannelNumber = channelNumber;
clc.m_source.SetTag(H245_CloseLogicalChannel_source::e_lcse);
return clc;
}
H245_OpenLogicalChannelAck &
H323ControlPDU::BuildOpenLogicalChannelAck(unsigned channelNumber)
{
H245_OpenLogicalChannelAck & ack = Build(H245_ResponseMessage::e_openLogicalChannelAck);
ack.m_forwardLogicalChannelNumber = channelNumber;
return ack;
}
H245_OpenLogicalChannelReject &
H323ControlPDU::BuildOpenLogicalChannelReject(unsigned channelNumber,
unsigned cause)
{
H245_OpenLogicalChannelReject & reject = Build(H245_ResponseMessage::e_openLogicalChannelReject);
reject.m_forwardLogicalChannelNumber = channelNumber;
reject.m_cause.SetTag(cause);
return reject;
}
H245_OpenLogicalChannelConfirm &
H323ControlPDU::BuildOpenLogicalChannelConfirm(unsigned channelNumber)
{
H245_OpenLogicalChannelConfirm & chan = Build(H245_IndicationMessage::e_openLogicalChannelConfirm);
chan.m_forwardLogicalChannelNumber = channelNumber;
return chan;
}
H245_CloseLogicalChannelAck &
H323ControlPDU::BuildCloseLogicalChannelAck(unsigned channelNumber)
{
H245_CloseLogicalChannelAck & chan = Build(H245_ResponseMessage::e_closeLogicalChannelAck);
chan.m_forwardLogicalChannelNumber = channelNumber;
return chan;
}
H245_RequestChannelCloseAck &
H323ControlPDU::BuildRequestChannelCloseAck(unsigned channelNumber)
{
H245_RequestChannelCloseAck & rcca = Build(H245_ResponseMessage::e_requestChannelCloseAck);
rcca.m_forwardLogicalChannelNumber = channelNumber;
return rcca;
}
H245_RequestChannelCloseReject &
H323ControlPDU::BuildRequestChannelCloseReject(unsigned channelNumber)
{
H245_RequestChannelCloseReject & rccr = Build(H245_ResponseMessage::e_requestChannelCloseReject);
rccr.m_forwardLogicalChannelNumber = channelNumber;
return rccr;
}
H245_RequestChannelCloseRelease &
H323ControlPDU::BuildRequestChannelCloseRelease(unsigned channelNumber)
{
H245_RequestChannelCloseRelease & rccr = Build(H245_IndicationMessage::e_requestChannelCloseRelease);
rccr.m_forwardLogicalChannelNumber = channelNumber;
return rccr;
}
H245_RequestMode & H323ControlPDU::BuildRequestMode(unsigned sequenceNumber)
{
H245_RequestMode & rm = Build(H245_RequestMessage::e_requestMode);
rm.m_sequenceNumber = sequenceNumber;
return rm;
}
H245_RequestModeAck & H323ControlPDU::BuildRequestModeAck(unsigned sequenceNumber,
unsigned response)
{
H245_RequestModeAck & ack = Build(H245_ResponseMessage::e_requestModeAck);
ack.m_sequenceNumber = sequenceNumber;
ack.m_response.SetTag(response);
return ack;
}
H245_RequestModeReject & H323ControlPDU::BuildRequestModeReject(unsigned sequenceNumber,
unsigned cause)
{
H245_RequestModeReject & reject = Build(H245_ResponseMessage::e_requestModeReject);
reject.m_sequenceNumber = sequenceNumber;
reject.m_cause.SetTag(cause);
return reject;
}
H245_RoundTripDelayRequest &
H323ControlPDU::BuildRoundTripDelayRequest(unsigned sequenceNumber)
{
H245_RoundTripDelayRequest & req = Build(H245_RequestMessage::e_roundTripDelayRequest);
req.m_sequenceNumber = sequenceNumber;
return req;
}
H245_RoundTripDelayResponse &
H323ControlPDU::BuildRoundTripDelayResponse(unsigned sequenceNumber)
{
H245_RoundTripDelayResponse & resp = Build(H245_ResponseMessage::e_roundTripDelayResponse);
resp.m_sequenceNumber = sequenceNumber;
return resp;
}
H245_UserInputIndication &
H323ControlPDU::BuildUserInputIndication(const PString & value)
{
H245_UserInputIndication & ind = Build(H245_IndicationMessage::e_userInput);
ind.SetTag(H245_UserInputIndication::e_alphanumeric);
(PASN_GeneralString &)ind = value;
return ind;
}
H245_UserInputIndication & H323ControlPDU::BuildUserInputIndication(char tone,
unsigned duration,
unsigned logicalChannel,
unsigned rtpTimestamp)
{
H245_UserInputIndication & ind = Build(H245_IndicationMessage::e_userInput);
if (tone != ' ') {
ind.SetTag(H245_UserInputIndication::e_signal);
H245_UserInputIndication_signal & sig = ind;
sig.m_signalType.SetValue(tone);
if (duration > 0) {
sig.IncludeOptionalField(H245_UserInputIndication_signal::e_duration);
sig.m_duration = duration;
}
if (logicalChannel > 0) {
sig.IncludeOptionalField(H245_UserInputIndication_signal::e_rtp);
sig.m_rtp.m_logicalChannelNumber = logicalChannel;
sig.m_rtp.m_timestamp = rtpTimestamp;
}
}
else {
ind.SetTag(H245_UserInputIndication::e_signalUpdate);
H245_UserInputIndication_signalUpdate & sig = ind;
sig.m_duration = duration;
if (logicalChannel > 0) {
sig.IncludeOptionalField(H245_UserInputIndication_signalUpdate::e_rtp);
sig.m_rtp.m_logicalChannelNumber = logicalChannel;
}
}
return ind;
}
H245_FunctionNotUnderstood &
H323ControlPDU::BuildFunctionNotUnderstood(const H323ControlPDU & pdu)
{
H245_FunctionNotUnderstood & fnu = Build(H245_IndicationMessage::e_functionNotUnderstood);
switch (pdu.GetTag()) {
case H245_MultimediaSystemControlMessage::e_request :
fnu.SetTag(H245_FunctionNotUnderstood::e_request);
(H245_RequestMessage &)fnu = (const H245_RequestMessage &)pdu;
break;
case H245_MultimediaSystemControlMessage::e_response :
fnu.SetTag(H245_FunctionNotUnderstood::e_response);
(H245_ResponseMessage &)fnu = (const H245_ResponseMessage &)pdu;
break;
case H245_MultimediaSystemControlMessage::e_command :
fnu.SetTag(H245_FunctionNotUnderstood::e_command);
(H245_CommandMessage &)fnu = (const H245_CommandMessage &)pdu;
break;
}
return fnu;
}
H245_EndSessionCommand & H323ControlPDU::BuildEndSessionCommand(unsigned reason)
{
H245_EndSessionCommand & end = Build(H245_CommandMessage::e_endSessionCommand);
end.SetTag(reason);
return end;
}
/////////////////////////////////////////////////////////////////////////////
H323RasPDU::H323RasPDU()
{
}
H323RasPDU::H323RasPDU(const H235Authenticators & auth)
: H323TransactionPDU(auth)
{
}
PObject * H323RasPDU::Clone() const
{
return new H323RasPDU(*this);
}
PASN_Object & H323RasPDU::GetPDU()
{
return *this;
}
PASN_Choice & H323RasPDU::GetChoice()
{
return *this;
}
const PASN_Object & H323RasPDU::GetPDU() const
{
return *this;
}
const PASN_Choice & H323RasPDU::GetChoice() const
{
return *this;
}
unsigned H323RasPDU::GetSequenceNumber() const
{
switch (GetTag()) {
case H225_RasMessage::e_gatekeeperRequest :
return ((const H225_GatekeeperRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_gatekeeperConfirm :
return ((const H225_GatekeeperConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_gatekeeperReject :
return ((const H225_GatekeeperReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_registrationRequest :
return ((const H225_RegistrationRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_registrationConfirm :
return ((const H225_RegistrationConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_registrationReject :
return ((const H225_RegistrationReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_unregistrationRequest :
return ((const H225_UnregistrationRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_unregistrationConfirm :
return ((const H225_UnregistrationConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_unregistrationReject :
return ((const H225_UnregistrationReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_admissionRequest :
return ((const H225_AdmissionRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_admissionConfirm :
return ((const H225_AdmissionConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_admissionReject :
return ((const H225_AdmissionReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_bandwidthRequest :
return ((const H225_BandwidthRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_bandwidthConfirm :
return ((const H225_BandwidthConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_bandwidthReject :
return ((const H225_BandwidthReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_disengageRequest :
return ((const H225_DisengageRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_disengageConfirm :
return ((const H225_DisengageConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_disengageReject :
return ((const H225_DisengageReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_locationRequest :
return ((const H225_LocationRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_locationConfirm :
return ((const H225_LocationConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_locationReject :
return ((const H225_LocationReject &)*this).m_requestSeqNum;
case H225_RasMessage::e_infoRequest :
return ((const H225_InfoRequest &)*this).m_requestSeqNum;
case H225_RasMessage::e_infoRequestResponse :
return ((const H225_InfoRequestResponse &)*this).m_requestSeqNum;
case H225_RasMessage::e_nonStandardMessage :
return ((const H225_NonStandardMessage &)*this).m_requestSeqNum;
case H225_RasMessage::e_unknownMessageResponse :
return ((const H225_UnknownMessageResponse &)*this).m_requestSeqNum;
case H225_RasMessage::e_requestInProgress :
return ((const H225_RequestInProgress &)*this).m_requestSeqNum;
case H225_RasMessage::e_resourcesAvailableIndicate :
return ((const H225_ResourcesAvailableIndicate &)*this).m_requestSeqNum;
case H225_RasMessage::e_resourcesAvailableConfirm :
return ((const H225_ResourcesAvailableConfirm &)*this).m_requestSeqNum;
case H225_RasMessage::e_infoRequestAck :
return ((const H225_InfoRequestAck &)*this).m_requestSeqNum;
case H225_RasMessage::e_infoRequestNak :
return ((const H225_InfoRequestNak &)*this).m_requestSeqNum;
case H225_RasMessage::e_serviceControlIndication :
return ((const H225_ServiceControlIndication &)*this).m_requestSeqNum;
case H225_RasMessage::e_serviceControlResponse :
return ((const H225_ServiceControlResponse &)*this).m_requestSeqNum;
default :
return 0;
}
}
unsigned H323RasPDU::GetRequestInProgressDelay() const
{
if (GetTag() != H225_RasMessage::e_requestInProgress)
return 0;
return ((const H225_RequestInProgress &)*this).m_delay;
}
#if PTRACING
const char * H323RasPDU::GetProtocolName() const
{
return "H225RAS";
}
#endif
H323TransactionPDU * H323RasPDU::ClonePDU() const
{
return new H323RasPDU(*this);
}
void H323RasPDU::DeletePDU()
{
delete this;
}
H225_GatekeeperRequest & H323RasPDU::BuildGatekeeperRequest(unsigned seqNum)
{
SetTag(e_gatekeeperRequest);
H225_GatekeeperRequest & grq = *this;
grq.m_requestSeqNum = seqNum;
grq.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
return grq;
}
H225_GatekeeperConfirm & H323RasPDU::BuildGatekeeperConfirm(unsigned seqNum)
{
SetTag(e_gatekeeperConfirm);
H225_GatekeeperConfirm & gcf = *this;
gcf.m_requestSeqNum = seqNum;
gcf.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
return gcf;
}
H225_GatekeeperReject & H323RasPDU::BuildGatekeeperReject(unsigned seqNum, unsigned reason)
{
SetTag(e_gatekeeperReject);
H225_GatekeeperReject & grj = *this;
grj.m_requestSeqNum = seqNum;
grj.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
grj.m_rejectReason.SetTag(reason);
return grj;
}
H225_RegistrationRequest & H323RasPDU::BuildRegistrationRequest(unsigned seqNum)
{
SetTag(e_registrationRequest);
H225_RegistrationRequest & rrq = *this;
rrq.m_requestSeqNum = seqNum;
rrq.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
return rrq;
}
H225_RegistrationConfirm & H323RasPDU::BuildRegistrationConfirm(unsigned seqNum)
{
SetTag(e_registrationConfirm);
H225_RegistrationConfirm & rcf = *this;
rcf.m_requestSeqNum = seqNum;
rcf.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
return rcf;
}
H225_RegistrationReject & H323RasPDU::BuildRegistrationReject(unsigned seqNum, unsigned reason)
{
SetTag(e_registrationReject);
H225_RegistrationReject & rrj = *this;
rrj.m_requestSeqNum = seqNum;
rrj.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
rrj.m_rejectReason.SetTag(reason);
return rrj;
}
H225_UnregistrationRequest & H323RasPDU::BuildUnregistrationRequest(unsigned seqNum)
{
SetTag(e_unregistrationRequest);
H225_UnregistrationRequest & urq = *this;
urq.m_requestSeqNum = seqNum;
return urq;
}
H225_UnregistrationConfirm & H323RasPDU::BuildUnregistrationConfirm(unsigned seqNum)
{
SetTag(e_unregistrationConfirm);
H225_UnregistrationConfirm & ucf = *this;
ucf.m_requestSeqNum = seqNum;
return ucf;
}
H225_UnregistrationReject & H323RasPDU::BuildUnregistrationReject(unsigned seqNum, unsigned reason)
{
SetTag(e_unregistrationReject);
H225_UnregistrationReject & urj = *this;
urj.m_requestSeqNum = seqNum;
urj.m_rejectReason.SetTag(reason);
return urj;
}
H225_LocationRequest & H323RasPDU::BuildLocationRequest(unsigned seqNum)
{
SetTag(e_locationRequest);
H225_LocationRequest & lrq = *this;
lrq.m_requestSeqNum = seqNum;
return lrq;
}
H225_LocationConfirm & H323RasPDU::BuildLocationConfirm(unsigned seqNum)
{
SetTag(e_locationConfirm);
H225_LocationConfirm & lcf = *this;
lcf.m_requestSeqNum = seqNum;
return lcf;
}
H225_LocationReject & H323RasPDU::BuildLocationReject(unsigned seqNum, unsigned reason)
{
SetTag(e_locationReject);
H225_LocationReject & lrj = *this;
lrj.m_requestSeqNum = seqNum;
lrj.m_rejectReason.SetTag(reason);
return lrj;
}
H225_AdmissionRequest & H323RasPDU::BuildAdmissionRequest(unsigned seqNum)
{
SetTag(e_admissionRequest);
H225_AdmissionRequest & arq = *this;
arq.m_requestSeqNum = seqNum;
return arq;
}
H225_AdmissionConfirm & H323RasPDU::BuildAdmissionConfirm(unsigned seqNum)
{
SetTag(e_admissionConfirm);
H225_AdmissionConfirm & acf = *this;
acf.m_requestSeqNum = seqNum;
return acf;
}
H225_AdmissionReject & H323RasPDU::BuildAdmissionReject(unsigned seqNum, unsigned reason)
{
SetTag(e_admissionReject);
H225_AdmissionReject & arj = *this;
arj.m_requestSeqNum = seqNum;
arj.m_rejectReason.SetTag(reason);
return arj;
}
H225_DisengageRequest & H323RasPDU::BuildDisengageRequest(unsigned seqNum)
{
SetTag(e_disengageRequest);
H225_DisengageRequest & drq = *this;
drq.m_requestSeqNum = seqNum;
return drq;
}
H225_DisengageConfirm & H323RasPDU::BuildDisengageConfirm(unsigned seqNum)
{
SetTag(e_disengageConfirm);
H225_DisengageConfirm & dcf = *this;
dcf.m_requestSeqNum = seqNum;
return dcf;
}
H225_DisengageReject & H323RasPDU::BuildDisengageReject(unsigned seqNum, unsigned reason)
{
SetTag(e_disengageReject);
H225_DisengageReject & drj = *this;
drj.m_requestSeqNum = seqNum;
drj.m_rejectReason.SetTag(reason);
return drj;
}
H225_BandwidthRequest & H323RasPDU::BuildBandwidthRequest(unsigned seqNum)
{
SetTag(e_bandwidthRequest);
H225_BandwidthRequest & brq = *this;
brq.m_requestSeqNum = seqNum;
return brq;
}
H225_BandwidthConfirm & H323RasPDU::BuildBandwidthConfirm(unsigned seqNum, unsigned bandWidth)
{
SetTag(e_bandwidthConfirm);
H225_BandwidthConfirm & bcf = *this;
bcf.m_requestSeqNum = seqNum;
bcf.m_bandWidth = bandWidth;
return bcf;
}
H225_BandwidthReject & H323RasPDU::BuildBandwidthReject(unsigned seqNum, unsigned reason)
{
SetTag(e_bandwidthReject);
H225_BandwidthReject & brj = *this;
brj.m_requestSeqNum = seqNum;
brj.m_rejectReason.SetTag(reason);
return brj;
}
H225_InfoRequest & H323RasPDU::BuildInfoRequest(unsigned seqNum,
unsigned callRef,
const OpalGloballyUniqueID * id)
{
SetTag(e_infoRequest);
H225_InfoRequest & irq = *this;
irq.m_requestSeqNum = seqNum;
irq.m_callReferenceValue = callRef;
if (callRef != 0 && id != NULL)
irq.m_callIdentifier.m_guid = *id;
return irq;
}
H225_InfoRequestResponse & H323RasPDU::BuildInfoRequestResponse(unsigned seqNum)
{
SetTag(e_infoRequestResponse);
H225_InfoRequestResponse & irr = *this;
irr.m_requestSeqNum = seqNum;
return irr;
}
H225_InfoRequestAck & H323RasPDU::BuildInfoRequestAck(unsigned seqNum)
{
SetTag(e_infoRequestAck);
H225_InfoRequestAck & iack = *this;
iack.m_requestSeqNum = seqNum;
return iack;
}
H225_InfoRequestNak & H323RasPDU::BuildInfoRequestNak(unsigned seqNum, unsigned reason)
{
SetTag(e_infoRequestNak);
H225_InfoRequestNak & inak = *this;
inak.m_requestSeqNum = seqNum;
inak.m_nakReason.SetTag(reason);
return inak;
}
H225_UnknownMessageResponse & H323RasPDU::BuildUnknownMessageResponse(unsigned seqNum)
{
SetTag(e_unknownMessageResponse);
H225_UnknownMessageResponse & umr = *this;
umr.m_requestSeqNum = seqNum;
return umr;
}
H225_RequestInProgress & H323RasPDU::BuildRequestInProgress(unsigned seqNum, unsigned delay)
{
SetTag(e_requestInProgress);
H225_RequestInProgress & rip = *this;
rip.m_requestSeqNum = seqNum;
rip.m_delay = delay;
return rip;
}
H225_ServiceControlIndication & H323RasPDU::BuildServiceControlIndication(unsigned seqNum, const OpalGloballyUniqueID * id)
{
SetTag(e_serviceControlIndication);
H225_ServiceControlIndication & sci = *this;
sci.m_requestSeqNum = seqNum;
if (id != NULL && !id->IsNULL()) {
sci.IncludeOptionalField(H225_ServiceControlIndication::e_callSpecific);
sci.m_callSpecific.m_callIdentifier.m_guid = *id;
}
return sci;
}
H225_ServiceControlResponse & H323RasPDU::BuildServiceControlResponse(unsigned seqNum)
{
SetTag(e_serviceControlResponse);
H225_ServiceControlResponse & scr = *this;
scr.m_requestSeqNum = seqNum;
return scr;
}
/////////////////////////////////////////////////////////////////////////////