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 >
Text File  |  2003-05-29  |  74KB  |  2,249 lines

  1. /*
  2.  * h323pdu.cxx
  3.  *
  4.  * H.323 PDU definitions
  5.  *
  6.  * Open H323 Library
  7.  *
  8.  * Copyright (c) 1998-2000 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.  * Vovida Networks, Inc. http://www.vovida.com.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: h323pdu.cxx,v $
  30.  * Revision 1.129  2003/05/29 09:19:52  rjongbloed
  31.  * Fixed minor problem with including DisplayName IE if localPartyName
  32.  *   is blank, now does not include it, thanks Auri Vizgaitis
  33.  *
  34.  * Revision 1.128  2003/05/06 06:24:16  robertj
  35.  * Added continuous DTMF tone support (H.245 UserInputIndication - signalUpdate)
  36.  *   as per header documentation, thanks Auri Vizgaitis
  37.  *
  38.  * Revision 1.127  2003/04/10 09:37:20  robertj
  39.  * Added some more functions for converting to alias addresses.
  40.  *
  41.  * Revision 1.126  2003/04/01 03:11:51  robertj
  42.  * Added function to get array of AliasAddress into PStringArray.
  43.  *
  44.  * Revision 1.125  2003/03/25 04:56:21  robertj
  45.  * Fixed issues to do with multiple inheritence in transaction reply cache.
  46.  *
  47.  * Revision 1.124  2003/03/20 01:51:12  robertj
  48.  * More abstraction of H.225 RAS and H.501 protocols transaction handling.
  49.  *
  50.  * Revision 1.123  2003/02/25 06:48:19  robertj
  51.  * More work on PDU transaction abstraction.
  52.  *
  53.  * Revision 1.122  2003/02/21 05:25:45  craigs
  54.  * Abstracted out underlying transports for use with peerelements
  55.  *
  56.  * Revision 1.121  2003/02/03 04:31:05  robertj
  57.  * Added special case for Cisco vendor field, they leave it rather incomplete,
  58.  *
  59.  * Revision 1.120  2003/01/26 02:57:58  craigs
  60.  * Fixed oops in last checkin
  61.  *
  62.  * Revision 1.119  2003/01/26 02:50:38  craigs
  63.  * Change so SETUP PDU uses conference and callIdentifier from H323Connection,
  64.  * rather than both doing seperately and then overwriting
  65.  *
  66.  * Revision 1.118  2002/11/28 04:41:48  robertj
  67.  * Added support for RAS ServiceControlIndication command.
  68.  *
  69.  * Revision 1.117  2002/11/27 06:54:57  robertj
  70.  * Added Service Control Session management as per Annex K/H.323 via RAS
  71.  *   only at this stage.
  72.  * Added H.248 ASN and very primitive infrastructure for linking into the
  73.  *   Service Control Session management system.
  74.  * Added basic infrastructure for Annex K/H.323 HTTP transport system.
  75.  * Added Call Credit Service Control to display account balances.
  76.  *
  77.  * Revision 1.116  2002/11/21 05:21:42  robertj
  78.  * Fixed bug where get lots of zeros at the end of some PDU's
  79.  *
  80.  * Revision 1.115  2002/11/21 04:15:36  robertj
  81.  * Added some changes to help interop with brain dead ASN decoders that do not
  82.  *   know to ignore fields (eg greater than version 2) they do not understand.
  83.  *
  84.  * Revision 1.114  2002/11/13 04:38:17  robertj
  85.  * Added ability to get (and set) Q.931 release complete cause codes.
  86.  *
  87.  * Revision 1.113  2002/11/07 03:50:28  robertj
  88.  * Added extra "congested" Q.931 codes.
  89.  *
  90.  * Revision 1.112  2002/10/31 00:45:22  robertj
  91.  * Enhanced jitter buffer system so operates dynamically between minimum and
  92.  *   maximum values. Altered API to assure app writers note the change!
  93.  *
  94.  * Revision 1.111  2002/10/08 13:08:21  robertj
  95.  * Changed for IPv6 support, thanks SΘbastien Josset.
  96.  *
  97.  * Revision 1.110  2002/08/14 01:07:22  robertj
  98.  * Added translation of Q.931 unallocated number release complete code to
  99.  *   OpenH323 EndedByNoUser which is the nearest match.
  100.  *
  101.  * Revision 1.109  2002/08/12 05:38:24  robertj
  102.  * Changes to the RAS subsystem to support ability to make requests to client
  103.  *   from gkserver without causing bottlenecks and race conditions.
  104.  *
  105.  * Revision 1.108  2002/08/05 10:03:47  robertj
  106.  * Cosmetic changes to normalise the usage of pragma interface/implementation.
  107.  *
  108.  * Revision 1.107  2002/08/05 05:17:41  robertj
  109.  * Fairly major modifications to support different authentication credentials
  110.  *   in ARQ to the logged in ones on RRQ. For both client and server.
  111.  * Various other H.235 authentication bugs and anomalies fixed on the way.
  112.  *
  113.  * Revision 1.106  2002/07/31 02:25:04  robertj
  114.  * Fixed translation of some call end reasons for to Q.931 codes.
  115.  *
  116.  * Revision 1.105  2002/07/25 10:55:44  robertj
  117.  * Changes to allow more granularity in PDU dumps, hex output increasing
  118.  *   with increasing trace level.
  119.  *
  120.  * Revision 1.104  2002/07/11 07:04:12  robertj
  121.  * Added build InfoRequest pdu type to RAS.
  122.  *
  123.  * Revision 1.103  2002/06/13 03:59:56  craigs
  124.  * Added codes to progress messages to allow inband audio before connect
  125.  *
  126.  * Revision 1.102  2002/05/29 03:55:21  robertj
  127.  * Added protocol version number checking infrastructure, primarily to improve
  128.  *   interoperability with stacks that are unforgiving of new features.
  129.  *
  130.  * Revision 1.101  2002/05/29 00:03:19  robertj
  131.  * Fixed unsolicited IRR support in gk client and server,
  132.  *   including support for IACK and INAK.
  133.  *
  134.  * Revision 1.100  2002/05/21 09:32:49  robertj
  135.  * Added ability to set multiple alias names ona  connection by connection
  136.  *   basis, defaults to endpoint list, thanks Artis Kugevics
  137.  *
  138.  * Revision 1.99  2002/05/07 03:18:15  robertj
  139.  * Added application info (name/version etc) into registered endpoint data.
  140.  *
  141.  * Revision 1.98  2002/05/03 09:18:49  robertj
  142.  * Added automatic retransmission of RAS responses to retried requests.
  143.  *
  144.  * Revision 1.97  2002/04/24 01:08:09  robertj
  145.  * Added output of RAS pdu sequence number to level 3 trace output.
  146.  *
  147.  * Revision 1.96  2002/03/27 06:04:43  robertj
  148.  * Added Temporary Failure end code for connection, an application may
  149.  *   immediately retry the call if this occurs.
  150.  *
  151.  * Revision 1.95  2002/03/14 07:56:48  robertj
  152.  * Added ability to specify alias type in H323SetAliasAddress, if not specified
  153.  *   then defaults to previous behaviour, thanks Nils Bokerman.
  154.  *
  155.  * Revision 1.94  2002/02/13 07:52:30  robertj
  156.  * Fixed missing parameters on Q.931 calling number, thanks Markus Rydh
  157.  *
  158.  * Revision 1.93  2002/02/01 01:48:45  robertj
  159.  * Some more fixes for T.120 channel establishment, more to do!
  160.  *
  161.  * Revision 1.92  2002/01/18 06:01:23  robertj
  162.  * Added some H323v4 functions (fastConnectRefused & TCS in SETUP)
  163.  *
  164.  * Revision 1.91  2001/12/15 07:10:59  robertj
  165.  * Added functions to get E.164 address from alias address or addresses.
  166.  *
  167.  * Revision 1.90  2001/12/14 08:36:36  robertj
  168.  * More implementation of T.38, thanks Adam Lazur
  169.  *
  170.  * Revision 1.89  2001/12/14 06:38:35  robertj
  171.  * Broke out conversion of Q.850 and H.225 release complete codes to
  172.  *   OpenH323 call end reasons enum.
  173.  *
  174.  * Revision 1.88  2001/12/13 10:56:28  robertj
  175.  * Added build of request in progress pdu.
  176.  *
  177.  * Revision 1.87  2001/10/18 00:58:51  robertj
  178.  * Fixed problem with GetDestinationAlias() adding source aliases instead
  179.  *   of the destination from the setup PDU, thanks Mikael Stolt.
  180.  *
  181.  * Revision 1.86  2001/10/09 06:55:26  robertj
  182.  * Fixed separating destCallSignalAddress fields with tabs in
  183.  *    GetDestinationAlias() function, thanks Lee Kirchhoff
  184.  *
  185.  * Revision 1.85  2001/09/26 07:05:29  robertj
  186.  * Fixed incorrect tags in building some PDU's, thanks Chris Purvis.
  187.  *
  188.  * Revision 1.84  2001/09/14 00:08:20  robertj
  189.  * Optimised H323SetAliasAddress to use IsE164 function.
  190.  *
  191.  * Revision 1.83  2001/09/12 07:48:05  robertj
  192.  * Fixed various problems with tracing.
  193.  *
  194.  * Revision 1.82  2001/08/16 07:49:19  robertj
  195.  * Changed the H.450 support to be more extensible. Protocol handlers
  196.  *   are now in separate classes instead of all in H323Connection.
  197.  *
  198.  * Revision 1.81  2001/08/10 11:03:52  robertj
  199.  * Major changes to H.235 support in RAS to support server.
  200.  *
  201.  * Revision 1.80  2001/08/06 03:08:56  robertj
  202.  * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
  203.  *
  204.  * Revision 1.79  2001/06/14 06:25:16  robertj
  205.  * Added further H.225 PDU build functions.
  206.  * Moved some functionality from connection to PDU class.
  207.  *
  208.  * Revision 1.78  2001/06/14 00:45:21  robertj
  209.  * Added extra parameters for Q.931 fields, thanks Rani Assaf
  210.  *
  211.  * Revision 1.77  2001/06/05 03:14:41  robertj
  212.  * Upgraded H.225 ASN to v4 and H.245 ASN to v7.
  213.  *
  214.  * Revision 1.76  2001/05/30 23:34:54  robertj
  215.  * Added functions to send TCS=0 for transmitter side pause.
  216.  *
  217.  * Revision 1.75  2001/05/09 04:07:55  robertj
  218.  * Added more call end codes for busy and congested.
  219.  *
  220.  * Revision 1.74  2001/05/03 06:45:21  robertj
  221.  * Changed trace so dumps PDU if gets an error in decode.
  222.  *
  223.  * Revision 1.73  2001/04/11 03:01:29  robertj
  224.  * Added H.450.2 (call transfer), thanks a LOT to Graeme Reid & Norwood Systems
  225.  *
  226.  * Revision 1.72  2001/03/24 00:58:03  robertj
  227.  * Fixed MSVC warnings.
  228.  *
  229.  * Revision 1.71  2001/03/24 00:34:49  robertj
  230.  * Added read/write hook functions so don't have to duplicate code in
  231.  *    H323RasH235PDU descendant class of H323RasPDU.
  232.  *
  233.  * Revision 1.70  2001/03/23 05:38:30  robertj
  234.  * Added PTRACE_IF to output trace if a conditional is TRUE.
  235.  *
  236.  * Revision 1.69  2001/03/02 06:59:59  robertj
  237.  * Enhanced the globally unique identifier class.
  238.  *
  239.  * Revision 1.68  2001/02/09 05:13:56  craigs
  240.  * Added pragma implementation to (hopefully) reduce the executable image size
  241.  * under Linux
  242.  *
  243.  * Revision 1.67  2001/01/18 06:04:46  robertj
  244.  * Bullet proofed code so local alias can not be empty string. This actually
  245.  *   fixes an ASN PER encoding bug causing an assert.
  246.  *
  247.  * Revision 1.66  2000/10/12 05:11:54  robertj
  248.  * Added trace log if get transport error on writing PDU.
  249.  *
  250.  * Revision 1.65  2000/09/25 06:48:11  robertj
  251.  * Removed use of alias if there is no alias present, ie only have transport address.
  252.  *
  253.  * Revision 1.64  2000/09/22 01:35:51  robertj
  254.  * Added support for handling LID's that only do symmetric codecs.
  255.  *
  256.  * Revision 1.63  2000/09/20 01:50:22  craigs
  257.  * Added ability to set jitter buffer on a per-connection basis
  258.  *
  259.  * Revision 1.62  2000/09/05 01:16:20  robertj
  260.  * Added "security" call end reason code.
  261.  *
  262.  * Revision 1.61  2000/07/15 09:51:41  robertj
  263.  * Changed adding of Q.931 party numbers to only occur in SETUP.
  264.  *
  265.  * Revision 1.60  2000/07/13 12:29:49  robertj
  266.  * Added some more cause codes on release complete,
  267.  *
  268.  * Revision 1.59  2000/07/12 10:20:43  robertj
  269.  * Fixed incorrect tag code in H.245 ModeChange reject PDU.
  270.  *
  271.  * Revision 1.58  2000/07/09 15:21:11  robertj
  272.  * Changed reference to the word "field" to be more correct IE or "Information Element"
  273.  * Fixed return value of Q.931/H.225 PDU read so returns TRUE if no H.225 data in the
  274.  *     User-User IE. Just flag it as empty and continue processing PDU's.
  275.  *
  276.  * Revision 1.57  2000/06/21 23:59:44  robertj
  277.  * Fixed copy/paste error setting Q.931 display name to incorrect value.
  278.  *
  279.  * Revision 1.56  2000/06/21 08:07:47  robertj
  280.  * Added cause/reason to release complete PDU, where relevent.
  281.  *
  282.  * Revision 1.55  2000/06/07 05:48:06  robertj
  283.  * Added call forwarding.
  284.  *
  285.  * Revision 1.54  2000/05/25 01:59:05  robertj
  286.  * Fixed bugs in calculation of GlLobally Uniqie ID according to DCE/H.225 rules.
  287.  *
  288.  * Revision 1.53  2000/05/23 11:32:37  robertj
  289.  * Rewrite of capability table to combine 2 structures into one and move functionality into that class
  290.  *    allowing some normalisation of usage across several applications.
  291.  * Changed H323Connection so gets a copy of capabilities instead of using endponts, allows adjustments
  292.  *    to be done depending on the remote client application.
  293.  *
  294.  * Revision 1.52  2000/05/15 08:38:59  robertj
  295.  * Removed addition of calling/called party number field in Q.931 if there isn't one.
  296.  *
  297.  * Revision 1.51  2000/05/09 12:19:31  robertj
  298.  * Added ability to get and set "distinctive ring" Q.931 functionality.
  299.  *
  300.  * Revision 1.50  2000/05/08 14:07:35  robertj
  301.  * Improved the provision and detection of calling and caller numbers, aliases and hostnames.
  302.  *
  303.  * Revision 1.49  2000/05/08 05:06:27  robertj
  304.  * Fixed bug in H.245 close logical channel timeout, thanks XuPeili.
  305.  *
  306.  * Revision 1.48  2000/05/02 04:32:27  robertj
  307.  * Fixed copyright notice comment.
  308.  *
  309.  * Revision 1.47  2000/04/14 17:29:43  robertj
  310.  * Fixed display of error message on timeout when timeouts are not errors.
  311.  *
  312.  * Revision 1.46  2000/04/10 20:39:18  robertj
  313.  * Added support for more sophisticated DTMF and hook flash user indication.
  314.  * Added function to extract E164 address from Q.931/H.225 PDU.
  315.  *
  316.  * Revision 1.45  2000/03/29 04:42:19  robertj
  317.  * Improved some trace logging messages.
  318.  *
  319.  * Revision 1.44  2000/03/25 02:01:07  robertj
  320.  * Added adjustable caller name on connection by connection basis.
  321.  *
  322.  * Revision 1.43  2000/03/21 01:08:10  robertj
  323.  * Fixed incorrect call reference code being used in originated call.
  324.  *
  325.  * Revision 1.42  2000/02/17 12:07:43  robertj
  326.  * Used ne wPWLib random number generator after finding major problem in MSVC rand().
  327.  *
  328.  * Revision 1.41  1999/12/23 22:47:09  robertj
  329.  * Added calling party number field.
  330.  *
  331.  * Revision 1.40  1999/12/11 02:21:00  robertj
  332.  * Added ability to have multiple aliases on local endpoint.
  333.  *
  334.  * Revision 1.39  1999/11/16 13:21:38  robertj
  335.  * Removed extraneous error trace when doing asynchronous answer call.
  336.  *
  337.  * Revision 1.38  1999/11/15 14:11:29  robertj
  338.  * Fixed trace output stream being put back after setting hex/fillchar modes.
  339.  *
  340.  * Revision 1.37  1999/11/10 23:30:20  robertj
  341.  * Fixed unexpected closing of transport on PDU read error.
  342.  *
  343.  * Revision 1.36  1999/11/01 00:48:31  robertj
  344.  * Added assert for illegal condition in capabilities, must have set if have table.
  345.  *
  346.  * Revision 1.35  1999/10/30 23:48:21  robertj
  347.  * Fixed incorrect PDU type for H225 RAS location request.
  348.  *
  349.  * Revision 1.34  1999/10/29 03:35:06  robertj
  350.  * Fixed setting of unique ID using fake MAC address from Win32 PPP device.
  351.  *
  352.  * Revision 1.33  1999/09/21 14:09:49  robertj
  353.  * Removed warnings when no tracing enabled.
  354.  *
  355.  * Revision 1.32  1999/09/10 09:03:01  robertj
  356.  * Used new GetInterfaceTable() function to get ethernet address for UniqueID
  357.  *
  358.  * Revision 1.31  1999/09/10 03:36:48  robertj
  359.  * Added simple Q.931 Status response to Q.931 Status Enquiry
  360.  *
  361.  * Revision 1.30  1999/08/31 12:34:19  robertj
  362.  * Added gatekeeper support.
  363.  *
  364.  * Revision 1.29  1999/08/31 11:37:30  robertj
  365.  * Fixed problem with apparently randomly losing signalling channel.
  366.  *
  367.  * Revision 1.28  1999/08/25 05:08:14  robertj
  368.  * File fission (critical mass reached).
  369.  *
  370.  * Revision 1.27  1999/08/13 06:34:38  robertj
  371.  * Fixed problem in CallPartyNumber Q.931 encoding.
  372.  * Added field name display to Q.931 protocol.
  373.  *
  374.  * Revision 1.26  1999/08/10 13:14:15  robertj
  375.  * Added Q.931 Called Number field if have "phone number" style destination addres.
  376.  *
  377.  * Revision 1.25  1999/08/10 11:38:03  robertj
  378.  * Changed population of setup UUIE destinationAddress if can be IA5 string.
  379.  *
  380.  * Revision 1.24  1999/07/26 05:10:30  robertj
  381.  * Fixed yet another race condition on connection termination.
  382.  *
  383.  * Revision 1.23  1999/07/16 14:03:52  robertj
  384.  * Fixed bug in Master/Slave negotiation that can cause looping.
  385.  *
  386.  * Revision 1.22  1999/07/16 06:15:59  robertj
  387.  * Corrected semantics for tunnelled master/slave determination in fast start.
  388.  *
  389.  * Revision 1.21  1999/07/16 02:15:30  robertj
  390.  * Fixed more tunneling problems.
  391.  *
  392.  * Revision 1.20  1999/07/15 14:45:36  robertj
  393.  * Added propagation of codec open error to shut down logical channel.
  394.  * Fixed control channel start up bug introduced with tunnelling.
  395.  *
  396.  * Revision 1.19  1999/07/15 09:08:04  robertj
  397.  * Added extra debugging for if have PDU decoding error.
  398.  *
  399.  * Revision 1.18  1999/07/15 09:04:31  robertj
  400.  * Fixed some fast start bugs
  401.  *
  402.  * Revision 1.17  1999/07/10 02:51:36  robertj
  403.  * Added mutexing in H245 procedures. Also fixed MSD state bug.
  404.  *
  405.  * Revision 1.16  1999/07/09 06:09:50  robertj
  406.  * Major implementation. An ENORMOUS amount of stuff added everywhere.
  407.  *
  408.  * Revision 1.15  1999/06/25 10:25:35  robertj
  409.  * Added maintentance of callIdentifier variable in H.225 channel.
  410.  *
  411.  * Revision 1.14  1999/06/22 13:45:40  robertj
  412.  * Fixed conferenceIdentifier generation algorithm to bas as in spec.
  413.  *
  414.  * Revision 1.13  1999/06/19 15:18:38  robertj
  415.  * Fixed bug in MasterSlaveDeterminationAck pdu has incorrect master/slave state.
  416.  *
  417.  * Revision 1.12  1999/06/14 15:08:40  robertj
  418.  * Added GSM codec class frame work (still no actual codec).
  419.  *
  420.  * Revision 1.11  1999/06/14 06:39:08  robertj
  421.  * Fixed problem with getting transmit flag to channel from PDU negotiator
  422.  *
  423.  * Revision 1.10  1999/06/14 05:15:56  robertj
  424.  * Changes for using RTP sessions correctly in H323 Logical Channel context
  425.  *
  426.  * Revision 1.9  1999/06/13 12:41:14  robertj
  427.  * Implement logical channel transmitter.
  428.  * Fixed H245 connect on receiving call.
  429.  *
  430.  * Revision 1.8  1999/06/09 05:26:19  robertj
  431.  * Major restructuring of classes.
  432.  *
  433.  * Revision 1.7  1999/06/06 06:06:36  robertj
  434.  * Changes for new ASN compiler and v2 protocol ASN files.
  435.  *
  436.  * Revision 1.6  1999/04/26 06:20:22  robertj
  437.  * Fixed bugs in protocol
  438.  *
  439.  * Revision 1.5  1999/04/26 06:14:47  craigs
  440.  * Initial implementation for RTP decoding and lots of stuff
  441.  * As a whole, these changes are called "First Noise"
  442.  *
  443.  * Revision 1.4  1999/02/23 11:04:28  robertj
  444.  * Added capability to make outgoing call.
  445.  *
  446.  * Revision 1.3  1999/02/06 09:23:39  robertj
  447.  * BeOS port
  448.  *
  449.  * Revision 1.2  1999/01/16 02:34:57  robertj
  450.  * GNU compiler compatibility.
  451.  *
  452.  * Revision 1.1  1999/01/16 01:30:54  robertj
  453.  * Initial revision
  454.  *
  455.  */
  456.  
  457. #include <ptlib.h>
  458.  
  459. #ifdef __GNUC__
  460. #pragma implementation "h323pdu.h"
  461. #endif
  462.  
  463. #include "h323pdu.h"
  464.  
  465. #include "h323ep.h"
  466. #include "h225ras.h"
  467.  
  468.  
  469. #define new PNEW
  470.  
  471. const unsigned H225_ProtocolID[] = { 0,0,8,2250,0,H225_PROTOCOL_VERSION };
  472. const unsigned H245_ProtocolID[] = { 0,0,8,245 ,0,H245_PROTOCOL_VERSION };
  473.  
  474. static const char E164NumberPrefix[] = "E164:";
  475. static const char PrivatePartyPrefix[] = "Private:";
  476. static const char DataPartyPrefix[] = "Data:";
  477. static const char TelexPartyPrefix[] = "Telex:";
  478. static const char NSPNumberPrefix[] = "NSP:";
  479.  
  480.  
  481. ///////////////////////////////////////////////////////////////////////////////
  482.  
  483. #if PTRACING
  484. void H323TraceDumpPDU(const char * proto,
  485.                       BOOL writing,
  486.                       const PBYTEArray & rawData,
  487.                       const PASN_Object & pdu,
  488.                       const PASN_Choice & tags,
  489.                       unsigned seqNum)
  490. {
  491.   if (!PTrace::CanTrace(3))
  492.     return;
  493.  
  494.   ostream & trace = PTrace::Begin(3, __FILE__, __LINE__);
  495.   trace << proto << '\t' << (writing ? "Send" : "Receiv") << "ing PDU:";
  496.  
  497.   if (PTrace::CanTrace(4)) {
  498.     trace << "\n  "
  499.           << resetiosflags(ios::floatfield);
  500.  
  501.     if (!PTrace::CanTrace(5))
  502.       trace << setiosflags(ios::fixed); // Will truncate hex dumps to 32 bytes
  503.  
  504.     trace << setprecision(2) << pdu
  505.           << resetiosflags(ios::floatfield);
  506.  
  507.     if (PTrace::CanTrace(6))
  508.       trace << "\nRaw PDU:\n"
  509.             << hex << setfill('0')
  510.             << setprecision(2) << rawData
  511.             << dec << setfill(' ');
  512.   }
  513.   else {
  514.     trace << ' ' << tags.GetTagName();
  515.     PASN_Object & next = tags.GetObject();
  516.     if (next.IsDescendant(PASN_Choice::Class()))
  517.       trace << ' ' << ((PASN_Choice &)next).GetTagName();
  518.     if (seqNum > 0)
  519.       trace << ' ' << seqNum;
  520.   }
  521.  
  522.   trace << PTrace::End;
  523. }
  524. #endif
  525.  
  526.  
  527. ///////////////////////////////////////////////////////////////////////////////
  528.  
  529. void H323SetAliasAddresses(const H323TransportAddressArray & addresses, H225_ArrayOf_AliasAddress & aliases)
  530. {
  531.   aliases.SetSize(addresses.GetSize());
  532.   for (PINDEX i = 0; i < addresses.GetSize(); i++)
  533.     H323SetAliasAddress(addresses[i], aliases[i]);
  534. }
  535.  
  536.  
  537. void H323SetAliasAddresses(const PStringArray & names,
  538.                            H225_ArrayOf_AliasAddress & aliases,
  539.                            int tag)
  540. {
  541.   aliases.SetSize(names.GetSize());
  542.   for (PINDEX i = 0; i < names.GetSize(); i++)
  543.     H323SetAliasAddress(names[i], aliases[i], tag);
  544. }
  545.  
  546.  
  547. void H323SetAliasAddresses(const PStringList & names,
  548.                            H225_ArrayOf_AliasAddress & aliases,
  549.                            int tag)
  550. {
  551.   aliases.SetSize(names.GetSize());
  552.   for (PINDEX i = 0; i < names.GetSize(); i++)
  553.     H323SetAliasAddress(names[i], aliases[i], tag);
  554. }
  555.  
  556.  
  557. static BOOL IsE164(const PString & str)
  558. {
  559.   return !str && strspn(str, "1234567890*#") == strlen(str);
  560. }
  561.  
  562.  
  563. void H323SetAliasAddress(const H323TransportAddress & address, H225_AliasAddress & alias)
  564. {
  565.   alias.SetTag(H225_AliasAddress::e_transportID);
  566.   address.SetPDU(alias);
  567. }
  568.  
  569.  
  570. void H323SetAliasAddress(const PString & name, H225_AliasAddress & alias, int tag)
  571. {
  572.   // See if explicitly specified the alias type, otherwise guess it from
  573.   // the string, if all digits then assume an e164 address.
  574.   if (tag < 0)
  575.     tag = IsE164(name) ? H225_AliasAddress::e_dialedDigits : H225_AliasAddress::e_h323_ID;
  576.  
  577.   alias.SetTag(tag);
  578.   switch (alias.GetTag()) {
  579.     case H225_AliasAddress::e_dialedDigits :
  580.     case H225_AliasAddress::e_url_ID :
  581.     case H225_AliasAddress::e_email_ID :
  582.       (PASN_IA5String &)alias = name;
  583.       break;
  584.  
  585.     case H225_AliasAddress::e_h323_ID :
  586.       (PASN_BMPString &)alias = name;
  587.       break;
  588.  
  589.     case H225_AliasAddress::e_transportID :
  590.     {
  591.       H323TransportAddress addr = name;
  592.       addr.SetPDU(alias);
  593.       break;
  594.     }
  595.     case H225_AliasAddress::e_partyNumber :
  596.     {
  597.       H225_PartyNumber & party = alias;
  598.       if (strncmp(name, E164NumberPrefix, sizeof(E164NumberPrefix)-1) == 0) {
  599.         party.SetTag(H225_PartyNumber::e_e164Number);
  600.         H225_PublicPartyNumber & number = party;
  601.         number.m_publicNumberDigits = name.Mid(sizeof(E164NumberPrefix)-1);
  602.       }
  603.       else if (strncmp(name, PrivatePartyPrefix, sizeof(PrivatePartyPrefix)-1) == 0) {
  604.         party.SetTag(H225_PartyNumber::e_privateNumber);
  605.         H225_PrivatePartyNumber & number = party;
  606.         number.m_privateNumberDigits = name.Mid(sizeof(PrivatePartyPrefix)-1);
  607.       }
  608.       else if (strncmp(name, DataPartyPrefix, sizeof(DataPartyPrefix)-1) == 0) {
  609.         party.SetTag(H225_PartyNumber::e_dataPartyNumber);
  610.         (H225_NumberDigits &)party = name.Mid(sizeof(DataPartyPrefix)-1);
  611.       }
  612.       else if (strncmp(name, TelexPartyPrefix, sizeof(TelexPartyPrefix)-1) == 0) {
  613.         party.SetTag(H225_PartyNumber::e_telexPartyNumber);
  614.         (H225_NumberDigits &)party = name.Mid(sizeof(TelexPartyPrefix)-1);
  615.       }
  616.       else if (strncmp(name, NSPNumberPrefix, sizeof(NSPNumberPrefix)-1) == 0) {
  617.         party.SetTag(H225_PartyNumber::e_nationalStandardPartyNumber);
  618.         (H225_NumberDigits &)party = name.Mid(sizeof(NSPNumberPrefix)-1);
  619.       }
  620.     }
  621.  
  622.     default :
  623.       break;
  624.   }
  625. }
  626.  
  627.  
  628. /////////////////////////////////////////////////////////////////////////////
  629.  
  630. PStringArray H323GetAliasAddressStrings(const H225_ArrayOf_AliasAddress & aliases)
  631. {
  632.   PStringArray strings(aliases.GetSize());
  633.  
  634.   for (PINDEX i = 0; i < aliases.GetSize(); i++)
  635.     strings[i] = H323GetAliasAddressString(aliases[i]);
  636.  
  637.   return strings;
  638. }
  639.  
  640.  
  641. PString H323GetAliasAddressString(const H225_AliasAddress & alias)
  642. {
  643.   switch (alias.GetTag()) {
  644.     case H225_AliasAddress::e_dialedDigits :
  645.     case H225_AliasAddress::e_url_ID :
  646.     case H225_AliasAddress::e_email_ID :
  647.       return (const PASN_IA5String &)alias;
  648.  
  649.     case H225_AliasAddress::e_h323_ID :
  650.       return (const PASN_BMPString &)alias;
  651.  
  652.     case H225_AliasAddress::e_transportID :
  653.       return H323TransportAddress(alias);
  654.  
  655.     case H225_AliasAddress::e_partyNumber :
  656.     {
  657.       const H225_PartyNumber & party = alias;
  658.       switch (party.GetTag()) {
  659.         case H225_PartyNumber::e_e164Number :
  660.         {
  661.           const H225_PublicPartyNumber & number = party;
  662.           return E164NumberPrefix + (PString)number.m_publicNumberDigits;
  663.         }
  664.  
  665.         case H225_PartyNumber::e_privateNumber :
  666.         {
  667.           const H225_PrivatePartyNumber & number = party;
  668.           return PrivatePartyPrefix + (PString)number.m_privateNumberDigits;
  669.         }
  670.  
  671.         case H225_PartyNumber::e_dataPartyNumber :
  672.           return DataPartyPrefix + (PString)(const H225_NumberDigits &)party;
  673.  
  674.         case H225_PartyNumber::e_telexPartyNumber :
  675.           return TelexPartyPrefix + (PString)(const H225_NumberDigits &)party;
  676.  
  677.         case H225_PartyNumber::e_nationalStandardPartyNumber :
  678.           return NSPNumberPrefix + (PString)(const H225_NumberDigits &)party;
  679.       }
  680.       break;
  681.     }
  682.  
  683.     default :
  684.       break;
  685.   }
  686.  
  687.   return PString();
  688. }
  689.  
  690.  
  691. PString H323GetAliasAddressE164(const H225_AliasAddress & alias)
  692. {
  693.   PString str = H323GetAliasAddressString(alias);
  694.   if (IsE164(str))
  695.     return str;
  696.  
  697.   return PString();
  698. }
  699.  
  700.  
  701. PString H323GetAliasAddressE164(const H225_ArrayOf_AliasAddress & aliases)
  702. {
  703.   for (PINDEX i = 0; i < aliases.GetSize(); i++) {
  704.     PString alias = H323GetAliasAddressE164(aliases[i]);
  705.     if (!alias)
  706.       return alias;
  707.   }
  708.  
  709.   return PString();
  710. }
  711.  
  712.  
  713. ///////////////////////////////////////////////////////////////////////////////
  714.  
  715. PString H323GetApplicationInfo(const H225_VendorIdentifier & vendor)
  716. {
  717.   PStringStream str;
  718.  
  719.   PString product = vendor.m_productId.AsString();
  720.   PString version = vendor.m_versionId.AsString();
  721.  
  722.   // Special case, Cisco IOS does not put in the product and version fields
  723.   if (vendor.m_vendor.m_t35CountryCode == 181 &&
  724.       vendor.m_vendor.m_t35Extension == 0 &&
  725.       vendor.m_vendor.m_manufacturerCode == 18) {
  726.     if (product.IsEmpty())
  727.       product = "Cisco IOS";
  728.     if (version.IsEmpty())
  729.       version = "12.2";
  730.   }
  731.  
  732.   str << product << '\t' << version << '\t' << vendor.m_vendor.m_t35CountryCode;
  733.   if (vendor.m_vendor.m_t35Extension != 0)
  734.     str << '.' << vendor.m_vendor.m_t35Extension;
  735.   str << '/' << vendor.m_vendor.m_manufacturerCode;
  736.  
  737.   str.MakeMinimumSize();
  738.   return str;
  739. }
  740.  
  741.  
  742. ///////////////////////////////////////////////////////////////////////////////
  743.  
  744. H323SignalPDU::H323SignalPDU()
  745. {
  746. }
  747.  
  748.  
  749. static unsigned SetH225Version(const H323Connection & connection,
  750.                                H225_ProtocolIdentifier & protocolIdentifier)
  751. {
  752.   unsigned version = connection.GetSignallingVersion();
  753.   protocolIdentifier.SetValue(psprintf("0.0.8.2250.0.%u", version));
  754.   return version;
  755. }
  756.  
  757.  
  758. H225_Setup_UUIE & H323SignalPDU::BuildSetup(const H323Connection & connection,
  759.                                             const H323TransportAddress & destAddr)
  760. {
  761.   H323EndPoint & endpoint = connection.GetEndPoint();
  762.  
  763.   q931pdu.BuildSetup(connection.GetCallReference());
  764.   SetQ931Fields(connection, TRUE);
  765.  
  766.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_setup);
  767.   H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
  768.  
  769.   if (SetH225Version(connection, setup.m_protocolIdentifier) < 3) {
  770.     setup.RemoveOptionalField(H225_Setup_UUIE::e_multipleCalls);
  771.     setup.RemoveOptionalField(H225_Setup_UUIE::e_maintainConnection);
  772.   }
  773.  
  774.   setup.IncludeOptionalField(H225_Setup_UUIE::e_sourceAddress);
  775.   H323SetAliasAddresses(endpoint.GetAliasNames(), setup.m_sourceAddress);
  776.  
  777.   setup.m_conferenceID = connection.GetConferenceIdentifier();
  778.   setup.m_conferenceGoal.SetTag(H225_Setup_UUIE_conferenceGoal::e_create);
  779.   setup.m_callType.SetTag(H225_CallType::e_pointToPoint);
  780.  
  781.   setup.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  782.   setup.m_mediaWaitForConnect = FALSE;
  783.   setup.m_canOverlapSend = FALSE;
  784.  
  785.   if (!destAddr) {
  786.     setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress);
  787.     destAddr.SetPDU(setup.m_destCallSignalAddress);
  788.   }
  789.  
  790.   PString destAlias = connection.GetRemotePartyName();
  791.   if (!destAlias && destAlias != destAddr) {
  792.     setup.IncludeOptionalField(H225_Setup_UUIE::e_destinationAddress);
  793.     setup.m_destinationAddress.SetSize(1);
  794.  
  795.     // Try and encode it as a phone number
  796.     H323SetAliasAddress(destAlias, setup.m_destinationAddress[0]);
  797.     if (setup.m_destinationAddress[0].GetTag() == H225_AliasAddress::e_dialedDigits)
  798.       q931pdu.SetCalledPartyNumber(destAlias);
  799.   }
  800.  
  801.   endpoint.SetEndpointTypeInfo(setup.m_sourceInfo);
  802.  
  803.   return setup;
  804. }
  805.  
  806.  
  807. H225_CallProceeding_UUIE &
  808.         H323SignalPDU::BuildCallProceeding(const H323Connection & connection)
  809. {
  810.   q931pdu.BuildCallProceeding(connection.GetCallReference());
  811.   SetQ931Fields(connection);
  812.  
  813.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_callProceeding);
  814.   H225_CallProceeding_UUIE & proceeding = m_h323_uu_pdu.m_h323_message_body;
  815.  
  816.   if (SetH225Version(connection, proceeding.m_protocolIdentifier) < 3) {
  817.     proceeding.RemoveOptionalField(H225_CallProceeding_UUIE::e_multipleCalls);
  818.     proceeding.RemoveOptionalField(H225_CallProceeding_UUIE::e_maintainConnection);
  819.   }
  820.  
  821.   proceeding.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  822.   connection.GetEndPoint().SetEndpointTypeInfo(proceeding.m_destinationInfo);
  823.  
  824.   return proceeding;
  825. }
  826.  
  827.  
  828. H225_Connect_UUIE & H323SignalPDU::BuildConnect(const H323Connection & connection)
  829. {
  830.   q931pdu.BuildConnect(connection.GetCallReference());
  831.   SetQ931Fields(connection);
  832.  
  833.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_connect);
  834.   H225_Connect_UUIE & connect = m_h323_uu_pdu.m_h323_message_body;
  835.  
  836.   if (SetH225Version(connection, connect.m_protocolIdentifier) < 3) {
  837.     connect.RemoveOptionalField(H225_Connect_UUIE::e_multipleCalls);
  838.     connect.RemoveOptionalField(H225_Connect_UUIE::e_maintainConnection);
  839.   }
  840.   connect.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  841.   connect.m_conferenceID = connection.GetConferenceIdentifier();
  842.  
  843.   connection.GetEndPoint().SetEndpointTypeInfo(connect.m_destinationInfo);
  844.  
  845.   return connect;
  846. }
  847.  
  848.  
  849. H225_Connect_UUIE & H323SignalPDU::BuildConnect(const H323Connection & connection,
  850.                                                 const PIPSocket::Address & h245Address,
  851.                                                 WORD port)
  852. {
  853.   H225_Connect_UUIE & connect = BuildConnect(connection);
  854.  
  855.   // indicate we are including the optional H245 address in the PDU
  856.   connect.IncludeOptionalField(H225_Connect_UUIE::e_h245Address);
  857.  
  858.   // convert IP address into the correct H245 type
  859.   H323TransportAddress transAddr(h245Address, port);
  860.   transAddr.SetPDU(connect.m_h245Address);
  861.  
  862.   return connect;
  863. }
  864.  
  865.  
  866. H225_Alerting_UUIE & H323SignalPDU::BuildAlerting(const H323Connection & connection)
  867. {
  868.   q931pdu.BuildAlerting(connection.GetCallReference());
  869.   SetQ931Fields(connection);
  870.  
  871.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_alerting);
  872.   H225_Alerting_UUIE & alerting = m_h323_uu_pdu.m_h323_message_body;
  873.  
  874.   if (SetH225Version(connection, alerting.m_protocolIdentifier) < 3) {
  875.     alerting.RemoveOptionalField(H225_Alerting_UUIE::e_multipleCalls);
  876.     alerting.RemoveOptionalField(H225_Alerting_UUIE::e_maintainConnection);
  877.   }
  878.  
  879.   alerting.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  880.   connection.GetEndPoint().SetEndpointTypeInfo(alerting.m_destinationInfo);
  881.  
  882.   return alerting;
  883. }
  884.  
  885.  
  886. H225_Information_UUIE & H323SignalPDU::BuildInformation(const H323Connection & connection)
  887. {
  888.   q931pdu.BuildInformation(connection.GetCallReference(), connection.HadAnsweredCall());
  889.   SetQ931Fields(connection);
  890.  
  891.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_information);
  892.   H225_Information_UUIE & information = m_h323_uu_pdu.m_h323_message_body;
  893.  
  894.   SetH225Version(connection, information.m_protocolIdentifier);
  895.   information.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  896.  
  897.   return information;
  898. }
  899.  
  900.  
  901. H323Connection::CallEndReason H323TranslateToCallEndReason(Q931::CauseValues cause,
  902.                                                            const H225_ReleaseCompleteReason & reason)
  903. {
  904.   switch (cause) {
  905.     case Q931::ErrorInCauseIE :
  906.       switch (reason.GetTag()) {
  907.         case H225_ReleaseCompleteReason::e_noBandwidth :
  908.           return H323Connection::EndedByNoBandwidth;
  909.  
  910.         case H225_ReleaseCompleteReason::e_gatekeeperResources :
  911.         case H225_ReleaseCompleteReason::e_gatewayResources :
  912.         case H225_ReleaseCompleteReason::e_adaptiveBusy :
  913.           return H323Connection::EndedByRemoteCongestion;
  914.  
  915.         case H225_ReleaseCompleteReason::e_unreachableDestination :
  916.           return H323Connection::EndedByUnreachable;
  917.  
  918.         case H225_ReleaseCompleteReason::e_calledPartyNotRegistered :
  919.           return H323Connection::EndedByNoUser;
  920.  
  921.         case H225_ReleaseCompleteReason::e_callerNotRegistered:
  922.           return H323Connection::EndedByGatekeeper;
  923.  
  924.         case H225_ReleaseCompleteReason::e_securityDenied:
  925.           return H323Connection::EndedBySecurityDenial;
  926.  
  927.         case H225_ReleaseCompleteReason::e_newConnectionNeeded:
  928.           return H323Connection::EndedByTemporaryFailure;
  929.       }
  930.       // Do next case
  931.  
  932.     case Q931::UnknownCauseIE :
  933.       return H323Connection::EndedByRefusal;
  934.  
  935.     case Q931::NormalCallClearing :
  936.       return H323Connection::EndedByRemoteUser;
  937.  
  938.     case Q931::UserBusy :
  939.       return H323Connection::EndedByRemoteBusy;
  940.  
  941.     case Q931::Congestion :
  942.     case Q931::NoCircuitChannelAvailable :
  943.     case Q931::RequestedCircuitNotAvailable :
  944.     case Q931::ResourceUnavailable :
  945.       return H323Connection::EndedByRemoteCongestion;
  946.  
  947.     case Q931::NoResponse :
  948.     case Q931::NoAnswer :
  949.       return H323Connection::EndedByNoAnswer;
  950.  
  951.     case Q931::NoRouteToNetwork :
  952.     case Q931::ChannelUnacceptable :
  953.       return H323Connection::EndedByUnreachable;
  954.  
  955.     case Q931::UnallocatedNumber :
  956.     case Q931::NoRouteToDestination :
  957.     case Q931::SubscriberAbsent :
  958.       return H323Connection::EndedByNoUser;
  959.  
  960.     case Q931::Redirection :
  961.       return H323Connection::EndedByCallForwarded;
  962.  
  963.     case Q931::DestinationOutOfOrder :
  964.       return H323Connection::EndedByConnectFail;
  965.  
  966.     case Q931::TemporaryFailure :
  967.       return H323Connection::EndedByTemporaryFailure;
  968.  
  969.     default:
  970.       return H323Connection::EndedByQ931Cause;
  971.   }
  972. }
  973.  
  974.  
  975. Q931::CauseValues H323TranslateFromCallEndReason(const H323Connection & connection,
  976.                                                  H225_ReleaseCompleteReason & reason)
  977. {
  978.   static int const ReasonCodes[H323Connection::NumCallEndReasons] = {
  979.     Q931::NormalCallClearing,                               /// EndedByLocalUser,         Local endpoint application cleared call
  980.     Q931::UserBusy,                                         /// EndedByNoAccept,          Local endpoint did not accept call
  981.     Q931::CallRejected,                                     /// EndedByAnswerDenied,      Local endpoint declined to answer call
  982.     Q931::NormalCallClearing,                               /// EndedByRemoteUser,        Remote endpoint application cleared call
  983.     -H225_ReleaseCompleteReason::e_destinationRejection,    /// EndedByRefusal,           Remote endpoint refused call
  984.     Q931::NoAnswer,                                         /// EndedByNoAnswer,          Remote endpoint did not answer in required time
  985.     Q931::NormalCallClearing,                               /// EndedByCallerAbort,       Remote endpoint stopped calling
  986.     -H225_ReleaseCompleteReason::e_undefinedReason,         /// EndedByTransportFail,     Transport error cleared call
  987.     -H225_ReleaseCompleteReason::e_unreachableDestination,  /// EndedByConnectFail,       Transport connection failed to establish call
  988.     -H225_ReleaseCompleteReason::e_gatekeeperResources,     /// EndedByGatekeeper,        Gatekeeper has cleared call
  989.     -H225_ReleaseCompleteReason::e_calledPartyNotRegistered,/// EndedByNoUser,            Call failed as could not find user (in GK)
  990.     -H225_ReleaseCompleteReason::e_noBandwidth,             /// EndedByNoBandwidth,       Call failed as could not get enough bandwidth
  991.     -H225_ReleaseCompleteReason::e_undefinedReason,         /// EndedByCapabilityExchange,Could not find common capabilities
  992.     -H225_ReleaseCompleteReason::e_facilityCallDeflection,  /// EndedByCallForwarded,     Call was forwarded using FACILITY message
  993.     -H225_ReleaseCompleteReason::e_securityDenied,          /// EndedBySecurityDenial,    Call failed a security check and was ended
  994.     Q931::UserBusy,                                         /// EndedByLocalBusy,         Local endpoint busy
  995.     Q931::Congestion,                                       /// EndedByLocalCongestion,   Local endpoint congested
  996.     Q931::UserBusy,                                         /// EndedByRemoteBusy,        Remote endpoint busy
  997.     Q931::Congestion,                                       /// EndedByRemoteCongestion,  Remote endpoint congested
  998.     Q931::NoRouteToDestination,                             /// EndedByUnreachable,       Could not reach the remote party
  999.     Q931::InvalidCallReference,                             /// EndedByNoEndPoint,        The remote party is not running an endpoint
  1000.     Q931::DestinationOutOfOrder,                            /// EndedByHostOffline,       The remote party host off line
  1001.     Q931::TemporaryFailure,                                 /// EndedByTemporaryFailure   The remote failed temporarily app may retry
  1002.     Q931::UnknownCauseIE,                                   /// EndedByQ931Cause,         The remote ended the call with unmapped Q.931 cause code
  1003.     Q931::NormalUnspecified,                                /// EndedByDurationLimit,     Call cleared due to an enforced duration limit
  1004.   };
  1005.  
  1006.   int code = ReasonCodes[connection.GetCallEndReason()];
  1007.   if (code == Q931::UnknownCauseIE)
  1008.     return (Q931::CauseValues)connection.GetCallEndReason();
  1009.   if (code >= 0)
  1010.     return (Q931::CauseValues)code;
  1011.  
  1012.   reason.SetTag(-code);
  1013.   return Q931::ErrorInCauseIE;
  1014. }
  1015.  
  1016.  
  1017. H225_ReleaseComplete_UUIE &
  1018.         H323SignalPDU::BuildReleaseComplete(const H323Connection & connection)
  1019. {
  1020.   q931pdu.BuildReleaseComplete(connection.GetCallReference(), connection.HadAnsweredCall());
  1021.  
  1022.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_releaseComplete);
  1023.  
  1024.   H225_ReleaseComplete_UUIE & release = m_h323_uu_pdu.m_h323_message_body;
  1025.  
  1026.   SetH225Version(connection, release.m_protocolIdentifier);
  1027.   release.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1028.  
  1029.   Q931::CauseValues cause = H323TranslateFromCallEndReason(connection, release.m_reason);
  1030.   if (cause != Q931::ErrorInCauseIE)
  1031.     q931pdu.SetCause(cause);
  1032.   else
  1033.     release.IncludeOptionalField(H225_ReleaseComplete_UUIE::e_reason);
  1034.  
  1035.   return release;
  1036. }
  1037.  
  1038.  
  1039. H225_Facility_UUIE * H323SignalPDU::BuildFacility(const H323Connection & connection,
  1040.                                                   BOOL empty)
  1041. {
  1042.   q931pdu.BuildFacility(connection.GetCallReference(), connection.HadAnsweredCall());
  1043.   if (empty) {
  1044.     m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
  1045.     return NULL;
  1046.   }
  1047.  
  1048.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_facility);
  1049.   H225_Facility_UUIE & fac = m_h323_uu_pdu.m_h323_message_body;
  1050.  
  1051.   SetH225Version(connection, fac.m_protocolIdentifier);
  1052.   fac.IncludeOptionalField(H225_Facility_UUIE::e_callIdentifier);
  1053.   fac.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1054.  
  1055.   return &fac;
  1056. }
  1057.  
  1058.  
  1059. H225_Progress_UUIE & H323SignalPDU::BuildProgress(const H323Connection & connection)
  1060. {
  1061.   q931pdu.BuildProgress(connection.GetCallReference(), connection.HadAnsweredCall(), Q931::ProgressInbandInformationAvailable);
  1062.   SetQ931Fields(connection);
  1063.  
  1064.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_progress);
  1065.   H225_Progress_UUIE & progress = m_h323_uu_pdu.m_h323_message_body;
  1066.  
  1067.   SetH225Version(connection, progress.m_protocolIdentifier);
  1068.   progress.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1069.   connection.GetEndPoint().SetEndpointTypeInfo(progress.m_destinationInfo);
  1070.  
  1071.   return progress;
  1072. }
  1073.  
  1074.  
  1075. H225_Status_UUIE & H323SignalPDU::BuildStatus(const H323Connection & connection)
  1076. {
  1077.   q931pdu.BuildStatus(connection.GetCallReference(), connection.HadAnsweredCall());
  1078.  
  1079.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_status);
  1080.   H225_Status_UUIE & status = m_h323_uu_pdu.m_h323_message_body;
  1081.  
  1082.   SetH225Version(connection, status.m_protocolIdentifier);
  1083.   status.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1084.  
  1085.   return status;
  1086. }
  1087.  
  1088.  
  1089. H225_StatusInquiry_UUIE & H323SignalPDU::BuildStatusInquiry(const H323Connection & connection)
  1090. {
  1091.   q931pdu.BuildStatusEnquiry(connection.GetCallReference(), connection.HadAnsweredCall());
  1092.  
  1093.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_statusInquiry);
  1094.   H225_StatusInquiry_UUIE & inquiry = m_h323_uu_pdu.m_h323_message_body;
  1095.  
  1096.   SetH225Version(connection, inquiry.m_protocolIdentifier);
  1097.   inquiry.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1098.  
  1099.   return inquiry;
  1100. }
  1101.  
  1102.  
  1103. H225_SetupAcknowledge_UUIE & H323SignalPDU::BuildSetupAcknowledge(const H323Connection & connection)
  1104. {
  1105.   q931pdu.BuildSetupAcknowledge(connection.GetCallReference());
  1106.  
  1107.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_setupAcknowledge);
  1108.   H225_SetupAcknowledge_UUIE & setupAck = m_h323_uu_pdu.m_h323_message_body;
  1109.  
  1110.   SetH225Version(connection, setupAck.m_protocolIdentifier);
  1111.   setupAck.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1112.  
  1113.   return setupAck;
  1114. }
  1115.  
  1116.  
  1117. H225_Notify_UUIE & H323SignalPDU::BuildNotify(const H323Connection & connection)
  1118. {
  1119.   q931pdu.BuildNotify(connection.GetCallReference(), connection.HadAnsweredCall());
  1120.  
  1121.   m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_notify);
  1122.   H225_Notify_UUIE & notify = m_h323_uu_pdu.m_h323_message_body;
  1123.  
  1124.   SetH225Version(connection, notify.m_protocolIdentifier);
  1125.   notify.m_callIdentifier.m_guid = connection.GetCallIdentifier();
  1126.  
  1127.   return notify;
  1128. }
  1129.  
  1130.  
  1131. void H323SignalPDU::BuildQ931()
  1132. {
  1133.   // Encode the H225 PDu into the Q931 PDU as User-User data
  1134.   PPER_Stream strm;
  1135.   Encode(strm);
  1136.   strm.CompleteEncoding();
  1137.   q931pdu.SetIE(Q931::UserUserIE, strm);
  1138. }
  1139.  
  1140.  
  1141. void H323SignalPDU::PrintOn(ostream & strm) const
  1142. {
  1143.   int indent = strm.precision() + 2;
  1144.   strm << "{\n"
  1145.        << setw(indent+10) << "q931pdu = " << setprecision(indent) << q931pdu << '\n'
  1146.        << setw(indent+10) << "h225pdu = " << setprecision(indent);
  1147.   H225_H323_UserInformation::PrintOn(strm);
  1148.   strm << '\n'
  1149.        << setw(indent-1) << "}";
  1150. }
  1151.  
  1152.  
  1153. BOOL H323SignalPDU::Read(H323Transport & transport)
  1154. {
  1155.   PBYTEArray rawData;
  1156.   if (!transport.ReadPDU(rawData)) {
  1157.     PTRACE_IF(1, transport.GetErrorCode(PChannel::LastReadError) != PChannel::Timeout,
  1158.               "H225\tRead error (" << transport.GetErrorNumber(PChannel::LastReadError)
  1159.               << "): " << transport.GetErrorText(PChannel::LastReadError));
  1160.     return FALSE;
  1161.   }
  1162.  
  1163.   if (!q931pdu.Decode(rawData)) {
  1164.     PTRACE(1, "H225\tParse error of Q931 PDU:\n" << hex << setfill('0')
  1165.                                                  << setprecision(2) << rawData
  1166.                                                  << dec << setfill(' '));
  1167.     return FALSE;
  1168.   }
  1169.  
  1170.   if (!q931pdu.HasIE(Q931::UserUserIE)) {
  1171.     m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
  1172.     PTRACE(1, "H225\tNo Q931 User-User Information Element,"
  1173.               "\nRaw PDU:\n" << hex << setfill('0')
  1174.                              << setprecision(2) << rawData
  1175.                              << dec << setfill(' ') <<
  1176.               "\nQ.931 PDU:\n  " << setprecision(2) << q931pdu);
  1177.     return TRUE;
  1178.   }
  1179.  
  1180.   PPER_Stream strm = q931pdu.GetIE(Q931::UserUserIE);
  1181.   if (!Decode(strm)) {
  1182.     PTRACE(1, "H225\tRead error: PER decode failure in Q.931 User-User Information Element,"
  1183.               "\nRaw PDU:\n" << hex << setfill('0')
  1184.                              << setprecision(2) << rawData
  1185.                              << dec << setfill(' ') <<
  1186.               "\nQ.931 PDU:\n  " << setprecision(2) << q931pdu <<
  1187.               "\nPartial PDU:\n  " << setprecision(2) << *this);
  1188.     m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
  1189.     return TRUE;
  1190.   }
  1191.  
  1192.   H323TraceDumpPDU("H225", FALSE, rawData, *this, m_h323_uu_pdu.m_h323_message_body, 0);
  1193.   return TRUE;
  1194. }
  1195.  
  1196.  
  1197. BOOL H323SignalPDU::Write(H323Transport & transport)
  1198. {
  1199.   if (!q931pdu.HasIE(Q931::UserUserIE) && m_h323_uu_pdu.m_h323_message_body.IsValid())
  1200.     BuildQ931();
  1201.  
  1202.   PBYTEArray rawData;
  1203.   if (!q931pdu.Encode(rawData))
  1204.     return FALSE;
  1205.  
  1206.   H323TraceDumpPDU("H225", TRUE, rawData, *this, m_h323_uu_pdu.m_h323_message_body, 0);
  1207.  
  1208.   if (transport.WritePDU(rawData))
  1209.     return TRUE;
  1210.  
  1211.   PTRACE(1, "H225\tWrite PDU failed ("
  1212.          << transport.GetErrorNumber(PChannel::LastWriteError)
  1213.          << "): " << transport.GetErrorText(PChannel::LastWriteError));
  1214.   return FALSE;
  1215. }
  1216.  
  1217.  
  1218. PString H323SignalPDU::GetSourceAliases(const H323Transport * transport) const
  1219. {
  1220.   PString remoteHostName;
  1221.   
  1222.   if (transport != NULL)
  1223.     remoteHostName = transport->GetRemoteAddress().GetHostName();
  1224.  
  1225.   PString displayName = GetQ931().GetDisplayName();
  1226.  
  1227.   PStringStream aliases;
  1228.   if (displayName != remoteHostName)
  1229.     aliases << displayName;
  1230.  
  1231.   if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
  1232.     const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
  1233.  
  1234.     if (remoteHostName.IsEmpty() &&
  1235.         setup.HasOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress)) {
  1236.       H323TransportAddress remoteAddress(setup.m_sourceCallSignalAddress);
  1237.       remoteHostName = remoteAddress.GetHostName();
  1238.     }
  1239.  
  1240.     if (setup.m_sourceAddress.GetSize() > 0) {
  1241.       BOOL needParen = !aliases.IsEmpty();
  1242.       BOOL needComma = FALSE;
  1243.       for (PINDEX i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
  1244.         PString alias = H323GetAliasAddressString(setup.m_sourceAddress[i]);
  1245.         if (alias != displayName && alias != remoteHostName) {
  1246.           if (needComma)
  1247.             aliases << ", ";
  1248.           else if (needParen)
  1249.             aliases << " (";
  1250.           aliases << alias;
  1251.           needComma = TRUE;
  1252.         }
  1253.       }
  1254.       if (needParen && needComma)
  1255.         aliases << ')';
  1256.     }
  1257.   }
  1258.  
  1259.   if (aliases.IsEmpty())
  1260.     return remoteHostName;
  1261.  
  1262.   aliases << " [" << remoteHostName << ']';
  1263.   aliases.MakeMinimumSize();
  1264.   return aliases;
  1265. }
  1266.  
  1267.  
  1268. PString H323SignalPDU::GetDestinationAlias(BOOL firstAliasOnly) const
  1269. {
  1270.   PStringStream aliases;
  1271.  
  1272.   PString number;
  1273.   if (GetQ931().GetCalledPartyNumber(number)) {
  1274.     if (firstAliasOnly)
  1275.       return number;
  1276.     aliases << number;
  1277.   }
  1278.  
  1279.   if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
  1280.     const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
  1281.     if (setup.m_destinationAddress.GetSize() > 0) {
  1282.       if (firstAliasOnly)
  1283.         return H323GetAliasAddressString(setup.m_destinationAddress[0]);
  1284.  
  1285.       for (PINDEX i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
  1286.         if (!aliases.IsEmpty())
  1287.           aliases << '\t';
  1288.         aliases << H323GetAliasAddressString(setup.m_destinationAddress[i]);
  1289.       }
  1290.     }
  1291.  
  1292.     if (setup.HasOptionalField(H225_Setup_UUIE::e_destCallSignalAddress)) {
  1293.       if (!aliases.IsEmpty())
  1294.         aliases << '\t';
  1295.       aliases << H323TransportAddress(setup.m_destCallSignalAddress);
  1296.     }
  1297.   }
  1298.  
  1299.   aliases.MakeMinimumSize();
  1300.   return aliases;
  1301. }
  1302.  
  1303.  
  1304. BOOL H323SignalPDU::GetSourceE164(PString & number) const
  1305. {
  1306.   if (GetQ931().GetCallingPartyNumber(number))
  1307.     return TRUE;
  1308.  
  1309.   if (m_h323_uu_pdu.m_h323_message_body.GetTag() != H225_H323_UU_PDU_h323_message_body::e_setup)
  1310.     return FALSE;
  1311.  
  1312.   const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
  1313.   if (!setup.HasOptionalField(H225_Setup_UUIE::e_sourceAddress))
  1314.     return FALSE;
  1315.  
  1316.   PINDEX i;
  1317.   for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
  1318.     if (setup.m_sourceAddress[i].GetTag() == H225_AliasAddress::e_dialedDigits) {
  1319.       number = (PASN_IA5String &)setup.m_sourceAddress[i];
  1320.       return TRUE;
  1321.     }
  1322.   }
  1323.  
  1324.   for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
  1325.     PString str = H323GetAliasAddressString(setup.m_sourceAddress[i]);
  1326.     if (IsE164(str)) {
  1327.       number = str;
  1328.       return TRUE;
  1329.     }
  1330.   }
  1331.  
  1332.   return FALSE;
  1333. }
  1334.  
  1335.  
  1336. BOOL H323SignalPDU::GetDestinationE164(PString & number) const
  1337. {
  1338.   if (GetQ931().GetCalledPartyNumber(number))
  1339.     return TRUE;
  1340.  
  1341.   if (m_h323_uu_pdu.m_h323_message_body.GetTag() != H225_H323_UU_PDU_h323_message_body::e_setup)
  1342.     return FALSE;
  1343.  
  1344.   const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
  1345.   if (!setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress))
  1346.     return FALSE;
  1347.  
  1348.   PINDEX i;
  1349.   for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
  1350.     if (setup.m_destinationAddress[i].GetTag() == H225_AliasAddress::e_dialedDigits) {
  1351.       number = (PASN_IA5String &)setup.m_destinationAddress[i];
  1352.       return TRUE;
  1353.     }
  1354.   }
  1355.  
  1356.   for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
  1357.     PString str = H323GetAliasAddressString(setup.m_destinationAddress[i]);
  1358.     if (IsE164(str)) {
  1359.       number = str;
  1360.       return TRUE;
  1361.     }
  1362.   }
  1363.  
  1364.   return FALSE;
  1365. }
  1366.  
  1367.  
  1368. unsigned H323SignalPDU::GetDistinctiveRing() const
  1369. {
  1370.   Q931::SignalInfo sig = GetQ931().GetSignalInfo();
  1371.   if (sig < Q931::SignalAlertingPattern0 || sig > Q931::SignalAlertingPattern7)
  1372.     return 0;
  1373.  
  1374.   return sig - Q931::SignalAlertingPattern0;
  1375. }
  1376.  
  1377.  
  1378. void H323SignalPDU::SetQ931Fields(const H323Connection & connection,
  1379.                                   BOOL insertPartyNumbers,
  1380.                                   unsigned plan,
  1381.                                   unsigned type,
  1382.                                   int presentation,
  1383.                                   int screening)
  1384. {
  1385.   PINDEX i;
  1386.   const PStringList & aliases = connection.GetLocalAliasNames();
  1387.  
  1388.   PString number;
  1389.   PString localName = connection.GetLocalPartyName();
  1390.   if (IsE164(localName)) {
  1391.     number = localName;
  1392.     for (i = 0; i < aliases.GetSize(); i++) {
  1393.       if (!IsE164(aliases[i])) {
  1394.         q931pdu.SetDisplayName(aliases[i]);
  1395.         break;
  1396.       }
  1397.     }
  1398.   }
  1399.   else {
  1400.     if (!localName)
  1401.       q931pdu.SetDisplayName(localName);
  1402.     for (i = 0; i < aliases.GetSize(); i++) {
  1403.       if (IsE164(aliases[i])) {
  1404.         number = aliases[i];
  1405.         break;
  1406.       }
  1407.     }
  1408.   }
  1409.  
  1410.   if (insertPartyNumbers) {
  1411.     PString otherNumber = connection.GetRemotePartyNumber();
  1412.     if (otherNumber.IsEmpty()) {
  1413.       PString otherName = connection.GetRemotePartyName();
  1414.       if (IsE164(otherName))
  1415.         otherNumber = otherName;
  1416.     }
  1417.  
  1418.     if (connection.HadAnsweredCall()) {
  1419.       if (!number)
  1420.         q931pdu.SetCalledPartyNumber(number, plan, type);
  1421.       if (!otherNumber)
  1422.         q931pdu.SetCallingPartyNumber(otherNumber, plan, type, presentation, screening);
  1423.     }
  1424.     else {
  1425.       if (!number)
  1426.         q931pdu.SetCallingPartyNumber(number, plan, type, presentation, screening);
  1427.       if (!otherNumber)
  1428.         q931pdu.SetCalledPartyNumber(otherNumber, plan, type);
  1429.     }
  1430.   }
  1431.  
  1432.   unsigned ring = connection.GetDistinctiveRing();
  1433.   if (ring != 0)
  1434.     q931pdu.SetSignalInfo((Q931::SignalInfo)(ring + Q931::SignalAlertingPattern0));
  1435. }
  1436.  
  1437.  
  1438. /////////////////////////////////////////////////////////////////////////////
  1439.  
  1440. H245_RequestMessage & H323ControlPDU::Build(H245_RequestMessage::Choices request)
  1441. {
  1442.   SetTag(e_request);
  1443.   H245_RequestMessage & msg = *this;
  1444.   msg.SetTag(request);
  1445.   return msg;
  1446. }
  1447.  
  1448.  
  1449. H245_ResponseMessage & H323ControlPDU::Build(H245_ResponseMessage::Choices response)
  1450. {
  1451.   SetTag(e_response);
  1452.   H245_ResponseMessage & resp = *this;
  1453.   resp.SetTag(response);
  1454.   return resp;
  1455. }
  1456.  
  1457.  
  1458. H245_CommandMessage & H323ControlPDU::Build(H245_CommandMessage::Choices command)
  1459. {
  1460.   SetTag(e_command);
  1461.   H245_CommandMessage & cmd = *this;
  1462.   cmd.SetTag(command);
  1463.   return cmd;
  1464. }
  1465.  
  1466.  
  1467. H245_IndicationMessage & H323ControlPDU::Build(H245_IndicationMessage::Choices indication)
  1468. {
  1469.   SetTag(e_indication);
  1470.   H245_IndicationMessage & ind = *this;
  1471.   ind.SetTag(indication);
  1472.   return ind;
  1473. }
  1474.  
  1475.  
  1476. H245_MasterSlaveDetermination & 
  1477.       H323ControlPDU::BuildMasterSlaveDetermination(unsigned terminalType,
  1478.                                                     unsigned statusDeterminationNumber)
  1479. {
  1480.   H245_MasterSlaveDetermination & msd = Build(H245_RequestMessage::e_masterSlaveDetermination);
  1481.   msd.m_terminalType = terminalType;
  1482.   msd.m_statusDeterminationNumber = statusDeterminationNumber;
  1483.   return msd;
  1484. }
  1485.  
  1486.  
  1487. H245_MasterSlaveDeterminationAck &
  1488.       H323ControlPDU::BuildMasterSlaveDeterminationAck(BOOL isMaster)
  1489. {
  1490.   H245_MasterSlaveDeterminationAck & msda = Build(H245_ResponseMessage::e_masterSlaveDeterminationAck);
  1491.   msda.m_decision.SetTag(isMaster
  1492.                             ? H245_MasterSlaveDeterminationAck_decision::e_slave
  1493.                             : H245_MasterSlaveDeterminationAck_decision::e_master);
  1494.   return msda;
  1495. }
  1496.  
  1497.  
  1498. H245_MasterSlaveDeterminationReject &
  1499.       H323ControlPDU::BuildMasterSlaveDeterminationReject(unsigned cause)
  1500. {
  1501.   H245_MasterSlaveDeterminationReject & msdr = Build(H245_ResponseMessage::e_masterSlaveDeterminationReject);
  1502.   msdr.m_cause.SetTag(cause);
  1503.   return msdr;
  1504. }
  1505.  
  1506.  
  1507. H245_TerminalCapabilitySet &
  1508.       H323ControlPDU::BuildTerminalCapabilitySet(const H323Connection & connection,
  1509.                                                  unsigned sequenceNumber,
  1510.                                                  BOOL empty)
  1511. {
  1512.   H245_TerminalCapabilitySet & cap = Build(H245_RequestMessage::e_terminalCapabilitySet);
  1513.  
  1514.   cap.m_sequenceNumber = sequenceNumber;
  1515.   cap.m_protocolIdentifier.SetValue(H245_ProtocolID, PARRAYSIZE(H245_ProtocolID));
  1516.  
  1517.   if (empty)
  1518.     return cap;
  1519.  
  1520.   cap.IncludeOptionalField(H245_TerminalCapabilitySet::e_multiplexCapability);
  1521.   cap.m_multiplexCapability.SetTag(H245_MultiplexCapability::e_h2250Capability);
  1522.   H245_H2250Capability & h225_0 = cap.m_multiplexCapability;
  1523.   h225_0.m_maximumAudioDelayJitter = connection.GetMaxAudioJitterDelay();
  1524.   h225_0.m_receiveMultipointCapability.m_mediaDistributionCapability.SetSize(1);
  1525.   h225_0.m_transmitMultipointCapability.m_mediaDistributionCapability.SetSize(1);
  1526.   h225_0.m_receiveAndTransmitMultipointCapability.m_mediaDistributionCapability.SetSize(1);
  1527.   h225_0.m_t120DynamicPortCapability = TRUE;
  1528.  
  1529.   // Set the table of capabilities
  1530.   connection.GetLocalCapabilities().BuildPDU(connection, cap);
  1531.  
  1532.   return cap;
  1533. }
  1534.  
  1535.  
  1536. H245_TerminalCapabilitySetAck &
  1537.       H323ControlPDU::BuildTerminalCapabilitySetAck(unsigned sequenceNumber)
  1538. {
  1539.   H245_TerminalCapabilitySetAck & cap = Build(H245_ResponseMessage::e_terminalCapabilitySetAck);
  1540.   cap.m_sequenceNumber = sequenceNumber;
  1541.   return cap;
  1542. }
  1543.  
  1544.  
  1545. H245_TerminalCapabilitySetReject &
  1546.       H323ControlPDU::BuildTerminalCapabilitySetReject(unsigned sequenceNumber,
  1547.                                                        unsigned cause)
  1548. {
  1549.   H245_TerminalCapabilitySetReject & cap = Build(H245_ResponseMessage::e_terminalCapabilitySetReject);
  1550.   cap.m_sequenceNumber = sequenceNumber;
  1551.   cap.m_cause.SetTag(cause);
  1552.  
  1553.   return cap;
  1554. }
  1555.  
  1556.  
  1557. H245_OpenLogicalChannel &
  1558.       H323ControlPDU::BuildOpenLogicalChannel(unsigned forwardLogicalChannelNumber)
  1559. {
  1560.   H245_OpenLogicalChannel & open = Build(H245_RequestMessage::e_openLogicalChannel);
  1561.   open.m_forwardLogicalChannelNumber = forwardLogicalChannelNumber;
  1562.   return open;
  1563. }
  1564.  
  1565.  
  1566. H245_RequestChannelClose &
  1567.       H323ControlPDU::BuildRequestChannelClose(unsigned channelNumber,
  1568.                                                unsigned reason)
  1569. {
  1570.   H245_RequestChannelClose & rcc = Build(H245_RequestMessage::e_requestChannelClose);
  1571.   rcc.m_forwardLogicalChannelNumber = channelNumber;
  1572.   rcc.IncludeOptionalField(H245_RequestChannelClose::e_reason);
  1573.   rcc.m_reason.SetTag(reason);
  1574.   return rcc;
  1575. }
  1576.  
  1577.  
  1578. H245_CloseLogicalChannel &
  1579.       H323ControlPDU::BuildCloseLogicalChannel(unsigned channelNumber)
  1580. {
  1581.   H245_CloseLogicalChannel & clc = Build(H245_RequestMessage::e_closeLogicalChannel);
  1582.   clc.m_forwardLogicalChannelNumber = channelNumber;
  1583.   clc.m_source.SetTag(H245_CloseLogicalChannel_source::e_lcse);
  1584.   return clc;
  1585. }
  1586.  
  1587.  
  1588. H245_OpenLogicalChannelAck &
  1589.       H323ControlPDU::BuildOpenLogicalChannelAck(unsigned channelNumber)
  1590. {
  1591.   H245_OpenLogicalChannelAck & ack = Build(H245_ResponseMessage::e_openLogicalChannelAck);
  1592.   ack.m_forwardLogicalChannelNumber = channelNumber;
  1593.   return ack;
  1594. }
  1595.  
  1596.  
  1597. H245_OpenLogicalChannelReject &
  1598.       H323ControlPDU::BuildOpenLogicalChannelReject(unsigned channelNumber,
  1599.                                                     unsigned cause)
  1600. {
  1601.   H245_OpenLogicalChannelReject & reject = Build(H245_ResponseMessage::e_openLogicalChannelReject);
  1602.   reject.m_forwardLogicalChannelNumber = channelNumber;
  1603.   reject.m_cause.SetTag(cause);
  1604.   return reject;
  1605. }
  1606.  
  1607.  
  1608. H245_OpenLogicalChannelConfirm &
  1609.       H323ControlPDU::BuildOpenLogicalChannelConfirm(unsigned channelNumber)
  1610. {
  1611.   H245_OpenLogicalChannelConfirm & chan = Build(H245_IndicationMessage::e_openLogicalChannelConfirm);
  1612.   chan.m_forwardLogicalChannelNumber = channelNumber;
  1613.   return chan;
  1614. }
  1615.  
  1616.  
  1617. H245_CloseLogicalChannelAck &
  1618.       H323ControlPDU::BuildCloseLogicalChannelAck(unsigned channelNumber)
  1619. {
  1620.   H245_CloseLogicalChannelAck & chan = Build(H245_ResponseMessage::e_closeLogicalChannelAck);
  1621.   chan.m_forwardLogicalChannelNumber = channelNumber;
  1622.   return chan;
  1623. }
  1624.  
  1625.  
  1626. H245_RequestChannelCloseAck &
  1627.       H323ControlPDU::BuildRequestChannelCloseAck(unsigned channelNumber)
  1628. {
  1629.   H245_RequestChannelCloseAck & rcca = Build(H245_ResponseMessage::e_requestChannelCloseAck);
  1630.   rcca.m_forwardLogicalChannelNumber = channelNumber;
  1631.   return rcca;
  1632. }
  1633.  
  1634.  
  1635. H245_RequestChannelCloseReject &
  1636.       H323ControlPDU::BuildRequestChannelCloseReject(unsigned channelNumber)
  1637. {
  1638.   H245_RequestChannelCloseReject & rccr = Build(H245_ResponseMessage::e_requestChannelCloseReject);
  1639.   rccr.m_forwardLogicalChannelNumber = channelNumber;
  1640.   return rccr;
  1641. }
  1642.  
  1643.  
  1644. H245_RequestChannelCloseRelease &
  1645.       H323ControlPDU::BuildRequestChannelCloseRelease(unsigned channelNumber)
  1646. {
  1647.   H245_RequestChannelCloseRelease & rccr = Build(H245_IndicationMessage::e_requestChannelCloseRelease);
  1648.   rccr.m_forwardLogicalChannelNumber = channelNumber;
  1649.   return rccr;
  1650. }
  1651.  
  1652.  
  1653. H245_RequestMode & H323ControlPDU::BuildRequestMode(unsigned sequenceNumber)
  1654. {
  1655.   H245_RequestMode & rm = Build(H245_RequestMessage::e_requestMode);
  1656.   rm.m_sequenceNumber = sequenceNumber;
  1657.  
  1658.   return rm;
  1659. }
  1660.  
  1661.  
  1662. H245_RequestModeAck & H323ControlPDU::BuildRequestModeAck(unsigned sequenceNumber,
  1663.                                                           unsigned response)
  1664. {
  1665.   H245_RequestModeAck & ack = Build(H245_ResponseMessage::e_requestModeAck);
  1666.   ack.m_sequenceNumber = sequenceNumber;
  1667.   ack.m_response.SetTag(response);
  1668.   return ack;
  1669. }
  1670.  
  1671.  
  1672. H245_RequestModeReject & H323ControlPDU::BuildRequestModeReject(unsigned sequenceNumber,
  1673.                                                                 unsigned cause)
  1674. {
  1675.   H245_RequestModeReject & reject = Build(H245_ResponseMessage::e_requestModeReject);
  1676.   reject.m_sequenceNumber = sequenceNumber;
  1677.   reject.m_cause.SetTag(cause);
  1678.   return reject;
  1679. }
  1680.  
  1681.  
  1682. H245_RoundTripDelayRequest &
  1683.       H323ControlPDU::BuildRoundTripDelayRequest(unsigned sequenceNumber)
  1684. {
  1685.   H245_RoundTripDelayRequest & req = Build(H245_RequestMessage::e_roundTripDelayRequest);
  1686.   req.m_sequenceNumber = sequenceNumber;
  1687.   return req;
  1688. }
  1689.  
  1690.  
  1691. H245_RoundTripDelayResponse &
  1692.       H323ControlPDU::BuildRoundTripDelayResponse(unsigned sequenceNumber)
  1693. {
  1694.   H245_RoundTripDelayResponse & resp = Build(H245_ResponseMessage::e_roundTripDelayResponse);
  1695.   resp.m_sequenceNumber = sequenceNumber;
  1696.   return resp;
  1697. }
  1698.  
  1699.  
  1700. H245_UserInputIndication &
  1701.       H323ControlPDU::BuildUserInputIndication(const PString & value)
  1702. {
  1703.   H245_UserInputIndication & ind = Build(H245_IndicationMessage::e_userInput);
  1704.   ind.SetTag(H245_UserInputIndication::e_alphanumeric);
  1705.   (PASN_GeneralString &)ind = value;
  1706.   return ind;
  1707. }
  1708.  
  1709.  
  1710. H245_UserInputIndication & H323ControlPDU::BuildUserInputIndication(char tone,
  1711.                                                                     unsigned duration,
  1712.                                                                     unsigned logicalChannel,
  1713.                                                                     unsigned rtpTimestamp)
  1714. {
  1715.   H245_UserInputIndication & ind = Build(H245_IndicationMessage::e_userInput);
  1716.  
  1717.   if (tone != ' ') {
  1718.     ind.SetTag(H245_UserInputIndication::e_signal);
  1719.     H245_UserInputIndication_signal & sig = ind;
  1720.  
  1721.     sig.m_signalType.SetValue(tone);
  1722.  
  1723.     if (duration > 0) {
  1724.       sig.IncludeOptionalField(H245_UserInputIndication_signal::e_duration);
  1725.       sig.m_duration = duration;
  1726.     }
  1727.  
  1728.     if (logicalChannel > 0) {
  1729.       sig.IncludeOptionalField(H245_UserInputIndication_signal::e_rtp);
  1730.       sig.m_rtp.m_logicalChannelNumber = logicalChannel;
  1731.       sig.m_rtp.m_timestamp = rtpTimestamp;
  1732.     }
  1733.   }
  1734.   else {
  1735.     ind.SetTag(H245_UserInputIndication::e_signalUpdate);
  1736.     H245_UserInputIndication_signalUpdate & sig = ind;
  1737.  
  1738.     sig.m_duration = duration;
  1739.     if (logicalChannel > 0) {
  1740.       sig.IncludeOptionalField(H245_UserInputIndication_signalUpdate::e_rtp);
  1741.       sig.m_rtp.m_logicalChannelNumber = logicalChannel;
  1742.     }
  1743.   }
  1744.  
  1745.   return ind;
  1746. }
  1747.  
  1748.  
  1749. H245_FunctionNotUnderstood &
  1750.       H323ControlPDU::BuildFunctionNotUnderstood(const H323ControlPDU & pdu)
  1751. {
  1752.   H245_FunctionNotUnderstood & fnu = Build(H245_IndicationMessage::e_functionNotUnderstood);
  1753.  
  1754.   switch (pdu.GetTag()) {
  1755.     case H245_MultimediaSystemControlMessage::e_request :
  1756.       fnu.SetTag(H245_FunctionNotUnderstood::e_request);
  1757.       (H245_RequestMessage &)fnu = (const H245_RequestMessage &)pdu;
  1758.       break;
  1759.  
  1760.     case H245_MultimediaSystemControlMessage::e_response :
  1761.       fnu.SetTag(H245_FunctionNotUnderstood::e_response);
  1762.       (H245_ResponseMessage &)fnu = (const H245_ResponseMessage &)pdu;
  1763.       break;
  1764.  
  1765.     case H245_MultimediaSystemControlMessage::e_command :
  1766.       fnu.SetTag(H245_FunctionNotUnderstood::e_command);
  1767.       (H245_CommandMessage &)fnu = (const H245_CommandMessage &)pdu;
  1768.       break;
  1769.   }
  1770.  
  1771.   return fnu;
  1772. }
  1773.  
  1774.  
  1775. H245_EndSessionCommand & H323ControlPDU::BuildEndSessionCommand(unsigned reason)
  1776. {
  1777.   H245_EndSessionCommand & end = Build(H245_CommandMessage::e_endSessionCommand);
  1778.   end.SetTag(reason);
  1779.   return end;
  1780. }
  1781.  
  1782.  
  1783. /////////////////////////////////////////////////////////////////////////////
  1784.  
  1785. H323RasPDU::H323RasPDU()
  1786. {
  1787. }
  1788.  
  1789.  
  1790. H323RasPDU::H323RasPDU(const H235Authenticators & auth)
  1791.   : H323TransactionPDU(auth)
  1792. {
  1793. }
  1794.  
  1795.  
  1796. PObject * H323RasPDU::Clone() const
  1797. {
  1798.   return new H323RasPDU(*this);
  1799. }
  1800.  
  1801.  
  1802. PASN_Object & H323RasPDU::GetPDU()
  1803. {
  1804.   return *this;
  1805. }
  1806.  
  1807.  
  1808. PASN_Choice & H323RasPDU::GetChoice()
  1809. {
  1810.   return *this;
  1811. }
  1812.  
  1813.  
  1814. const PASN_Object & H323RasPDU::GetPDU() const
  1815. {
  1816.   return *this;
  1817. }
  1818.  
  1819.  
  1820. const PASN_Choice & H323RasPDU::GetChoice() const
  1821. {
  1822.   return *this;
  1823. }
  1824.  
  1825.  
  1826. unsigned H323RasPDU::GetSequenceNumber() const
  1827. {
  1828.   switch (GetTag()) {
  1829.     case H225_RasMessage::e_gatekeeperRequest :
  1830.       return ((const H225_GatekeeperRequest &)*this).m_requestSeqNum;
  1831.  
  1832.     case H225_RasMessage::e_gatekeeperConfirm :
  1833.       return ((const H225_GatekeeperConfirm &)*this).m_requestSeqNum;
  1834.  
  1835.     case H225_RasMessage::e_gatekeeperReject :
  1836.       return ((const H225_GatekeeperReject &)*this).m_requestSeqNum;
  1837.  
  1838.     case H225_RasMessage::e_registrationRequest :
  1839.       return ((const H225_RegistrationRequest &)*this).m_requestSeqNum;
  1840.  
  1841.     case H225_RasMessage::e_registrationConfirm :
  1842.       return ((const H225_RegistrationConfirm &)*this).m_requestSeqNum;
  1843.  
  1844.     case H225_RasMessage::e_registrationReject :
  1845.       return ((const H225_RegistrationReject &)*this).m_requestSeqNum;
  1846.  
  1847.     case H225_RasMessage::e_unregistrationRequest :
  1848.       return ((const H225_UnregistrationRequest &)*this).m_requestSeqNum;
  1849.  
  1850.     case H225_RasMessage::e_unregistrationConfirm :
  1851.       return ((const H225_UnregistrationConfirm &)*this).m_requestSeqNum;
  1852.  
  1853.     case H225_RasMessage::e_unregistrationReject :
  1854.       return ((const H225_UnregistrationReject &)*this).m_requestSeqNum;
  1855.  
  1856.     case H225_RasMessage::e_admissionRequest :
  1857.       return ((const H225_AdmissionRequest &)*this).m_requestSeqNum;
  1858.  
  1859.     case H225_RasMessage::e_admissionConfirm :
  1860.       return ((const H225_AdmissionConfirm &)*this).m_requestSeqNum;
  1861.  
  1862.     case H225_RasMessage::e_admissionReject :
  1863.       return ((const H225_AdmissionReject &)*this).m_requestSeqNum;
  1864.  
  1865.     case H225_RasMessage::e_bandwidthRequest :
  1866.       return ((const H225_BandwidthRequest &)*this).m_requestSeqNum;
  1867.  
  1868.     case H225_RasMessage::e_bandwidthConfirm :
  1869.       return ((const H225_BandwidthConfirm &)*this).m_requestSeqNum;
  1870.  
  1871.     case H225_RasMessage::e_bandwidthReject :
  1872.       return ((const H225_BandwidthReject &)*this).m_requestSeqNum;
  1873.  
  1874.     case H225_RasMessage::e_disengageRequest :
  1875.       return ((const H225_DisengageRequest &)*this).m_requestSeqNum;
  1876.  
  1877.     case H225_RasMessage::e_disengageConfirm :
  1878.       return ((const H225_DisengageConfirm &)*this).m_requestSeqNum;
  1879.  
  1880.     case H225_RasMessage::e_disengageReject :
  1881.       return ((const H225_DisengageReject &)*this).m_requestSeqNum;
  1882.  
  1883.     case H225_RasMessage::e_locationRequest :
  1884.       return ((const H225_LocationRequest &)*this).m_requestSeqNum;
  1885.  
  1886.     case H225_RasMessage::e_locationConfirm :
  1887.       return ((const H225_LocationConfirm &)*this).m_requestSeqNum;
  1888.  
  1889.     case H225_RasMessage::e_locationReject :
  1890.       return ((const H225_LocationReject &)*this).m_requestSeqNum;
  1891.  
  1892.     case H225_RasMessage::e_infoRequest :
  1893.       return ((const H225_InfoRequest &)*this).m_requestSeqNum;
  1894.  
  1895.     case H225_RasMessage::e_infoRequestResponse :
  1896.       return ((const H225_InfoRequestResponse &)*this).m_requestSeqNum;
  1897.  
  1898.     case H225_RasMessage::e_nonStandardMessage :
  1899.       return ((const H225_NonStandardMessage &)*this).m_requestSeqNum;
  1900.  
  1901.     case H225_RasMessage::e_unknownMessageResponse :
  1902.       return ((const H225_UnknownMessageResponse &)*this).m_requestSeqNum;
  1903.  
  1904.     case H225_RasMessage::e_requestInProgress :
  1905.       return ((const H225_RequestInProgress &)*this).m_requestSeqNum;
  1906.  
  1907.     case H225_RasMessage::e_resourcesAvailableIndicate :
  1908.       return ((const H225_ResourcesAvailableIndicate &)*this).m_requestSeqNum;
  1909.  
  1910.     case H225_RasMessage::e_resourcesAvailableConfirm :
  1911.       return ((const H225_ResourcesAvailableConfirm &)*this).m_requestSeqNum;
  1912.  
  1913.     case H225_RasMessage::e_infoRequestAck :
  1914.       return ((const H225_InfoRequestAck &)*this).m_requestSeqNum;
  1915.  
  1916.     case H225_RasMessage::e_infoRequestNak :
  1917.       return ((const H225_InfoRequestNak &)*this).m_requestSeqNum;
  1918.  
  1919.     case H225_RasMessage::e_serviceControlIndication :
  1920.       return ((const H225_ServiceControlIndication &)*this).m_requestSeqNum;
  1921.  
  1922.     case H225_RasMessage::e_serviceControlResponse :
  1923.       return ((const H225_ServiceControlResponse &)*this).m_requestSeqNum;
  1924.  
  1925.     default :
  1926.       return 0;
  1927.   }
  1928. }
  1929.  
  1930.  
  1931. unsigned H323RasPDU::GetRequestInProgressDelay() const
  1932. {
  1933.   if (GetTag() != H225_RasMessage::e_requestInProgress)
  1934.     return 0;
  1935.  
  1936.   return ((const H225_RequestInProgress &)*this).m_delay;
  1937. }
  1938.  
  1939.  
  1940. #if PTRACING
  1941. const char * H323RasPDU::GetProtocolName() const
  1942. {
  1943.   return "H225RAS";
  1944. }
  1945. #endif
  1946.  
  1947.  
  1948. H323TransactionPDU * H323RasPDU::ClonePDU() const
  1949. {
  1950.   return new H323RasPDU(*this);
  1951. }
  1952.  
  1953.  
  1954. void H323RasPDU::DeletePDU()
  1955. {
  1956.   delete this;
  1957. }
  1958.  
  1959.  
  1960. H225_GatekeeperRequest & H323RasPDU::BuildGatekeeperRequest(unsigned seqNum)
  1961. {
  1962.   SetTag(e_gatekeeperRequest);
  1963.   H225_GatekeeperRequest & grq = *this;
  1964.   grq.m_requestSeqNum = seqNum;
  1965.   grq.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
  1966.   return grq;
  1967. }
  1968.  
  1969.  
  1970. H225_GatekeeperConfirm & H323RasPDU::BuildGatekeeperConfirm(unsigned seqNum)
  1971. {
  1972.   SetTag(e_gatekeeperConfirm);
  1973.   H225_GatekeeperConfirm & gcf = *this;
  1974.   gcf.m_requestSeqNum = seqNum;
  1975.   gcf.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
  1976.   return gcf;
  1977. }
  1978.  
  1979.  
  1980. H225_GatekeeperReject & H323RasPDU::BuildGatekeeperReject(unsigned seqNum, unsigned reason)
  1981. {
  1982.   SetTag(e_gatekeeperReject);
  1983.   H225_GatekeeperReject & grj = *this;
  1984.   grj.m_requestSeqNum = seqNum;
  1985.   grj.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
  1986.   grj.m_rejectReason.SetTag(reason);
  1987.   return grj;
  1988. }
  1989.  
  1990.  
  1991. H225_RegistrationRequest & H323RasPDU::BuildRegistrationRequest(unsigned seqNum)
  1992. {
  1993.   SetTag(e_registrationRequest);
  1994.   H225_RegistrationRequest & rrq = *this;
  1995.   rrq.m_requestSeqNum = seqNum;
  1996.   rrq.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
  1997.   return rrq;
  1998. }
  1999.  
  2000.  
  2001. H225_RegistrationConfirm & H323RasPDU::BuildRegistrationConfirm(unsigned seqNum)
  2002. {
  2003.   SetTag(e_registrationConfirm);
  2004.   H225_RegistrationConfirm & rcf = *this;
  2005.   rcf.m_requestSeqNum = seqNum;
  2006.   rcf.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
  2007.   return rcf;
  2008. }
  2009.  
  2010.  
  2011. H225_RegistrationReject & H323RasPDU::BuildRegistrationReject(unsigned seqNum, unsigned reason)
  2012. {
  2013.   SetTag(e_registrationReject);
  2014.   H225_RegistrationReject & rrj = *this;
  2015.   rrj.m_requestSeqNum = seqNum;
  2016.   rrj.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
  2017.   rrj.m_rejectReason.SetTag(reason);
  2018.   return rrj;
  2019. }
  2020.  
  2021.  
  2022. H225_UnregistrationRequest & H323RasPDU::BuildUnregistrationRequest(unsigned seqNum)
  2023. {
  2024.   SetTag(e_unregistrationRequest);
  2025.   H225_UnregistrationRequest & urq = *this;
  2026.   urq.m_requestSeqNum = seqNum;
  2027.   return urq;
  2028. }
  2029.  
  2030.  
  2031. H225_UnregistrationConfirm & H323RasPDU::BuildUnregistrationConfirm(unsigned seqNum)
  2032. {
  2033.   SetTag(e_unregistrationConfirm);
  2034.   H225_UnregistrationConfirm & ucf = *this;
  2035.   ucf.m_requestSeqNum = seqNum;
  2036.   return ucf;
  2037. }
  2038.  
  2039.  
  2040. H225_UnregistrationReject & H323RasPDU::BuildUnregistrationReject(unsigned seqNum, unsigned reason)
  2041. {
  2042.   SetTag(e_unregistrationReject);
  2043.   H225_UnregistrationReject & urj = *this;
  2044.   urj.m_requestSeqNum = seqNum;
  2045.   urj.m_rejectReason.SetTag(reason);
  2046.   return urj;
  2047. }
  2048.  
  2049.  
  2050. H225_LocationRequest & H323RasPDU::BuildLocationRequest(unsigned seqNum)
  2051. {
  2052.   SetTag(e_locationRequest);
  2053.   H225_LocationRequest & lrq = *this;
  2054.   lrq.m_requestSeqNum = seqNum;
  2055.   return lrq;
  2056. }
  2057.  
  2058.  
  2059. H225_LocationConfirm & H323RasPDU::BuildLocationConfirm(unsigned seqNum)
  2060. {
  2061.   SetTag(e_locationConfirm);
  2062.   H225_LocationConfirm & lcf = *this;
  2063.   lcf.m_requestSeqNum = seqNum;
  2064.   return lcf;
  2065. }
  2066.  
  2067.  
  2068. H225_LocationReject & H323RasPDU::BuildLocationReject(unsigned seqNum, unsigned reason)
  2069. {
  2070.   SetTag(e_locationReject);
  2071.   H225_LocationReject & lrj = *this;
  2072.   lrj.m_requestSeqNum = seqNum;
  2073.   lrj.m_rejectReason.SetTag(reason);
  2074.   return lrj;
  2075. }
  2076.  
  2077.  
  2078. H225_AdmissionRequest & H323RasPDU::BuildAdmissionRequest(unsigned seqNum)
  2079. {
  2080.   SetTag(e_admissionRequest);
  2081.   H225_AdmissionRequest & arq = *this;
  2082.   arq.m_requestSeqNum = seqNum;
  2083.   return arq;
  2084. }
  2085.  
  2086.  
  2087. H225_AdmissionConfirm & H323RasPDU::BuildAdmissionConfirm(unsigned seqNum)
  2088. {
  2089.   SetTag(e_admissionConfirm);
  2090.   H225_AdmissionConfirm & acf = *this;
  2091.   acf.m_requestSeqNum = seqNum;
  2092.   return acf;
  2093. }
  2094.  
  2095.  
  2096. H225_AdmissionReject & H323RasPDU::BuildAdmissionReject(unsigned seqNum, unsigned reason)
  2097. {
  2098.   SetTag(e_admissionReject);
  2099.   H225_AdmissionReject & arj = *this;
  2100.   arj.m_requestSeqNum = seqNum;
  2101.   arj.m_rejectReason.SetTag(reason);
  2102.   return arj;
  2103. }
  2104.  
  2105.  
  2106. H225_DisengageRequest & H323RasPDU::BuildDisengageRequest(unsigned seqNum)
  2107. {
  2108.   SetTag(e_disengageRequest);
  2109.   H225_DisengageRequest & drq = *this;
  2110.   drq.m_requestSeqNum = seqNum;
  2111.   return drq;
  2112. }
  2113.  
  2114.  
  2115. H225_DisengageConfirm & H323RasPDU::BuildDisengageConfirm(unsigned seqNum)
  2116. {
  2117.   SetTag(e_disengageConfirm);
  2118.   H225_DisengageConfirm & dcf = *this;
  2119.   dcf.m_requestSeqNum = seqNum;
  2120.   return dcf;
  2121. }
  2122.  
  2123.  
  2124. H225_DisengageReject & H323RasPDU::BuildDisengageReject(unsigned seqNum, unsigned reason)
  2125. {
  2126.   SetTag(e_disengageReject);
  2127.   H225_DisengageReject & drj = *this;
  2128.   drj.m_requestSeqNum = seqNum;
  2129.   drj.m_rejectReason.SetTag(reason);
  2130.   return drj;
  2131. }
  2132.  
  2133.  
  2134. H225_BandwidthRequest & H323RasPDU::BuildBandwidthRequest(unsigned seqNum)
  2135. {
  2136.   SetTag(e_bandwidthRequest);
  2137.   H225_BandwidthRequest & brq = *this;
  2138.   brq.m_requestSeqNum = seqNum;
  2139.   return brq;
  2140. }
  2141.  
  2142.  
  2143. H225_BandwidthConfirm & H323RasPDU::BuildBandwidthConfirm(unsigned seqNum, unsigned bandWidth)
  2144. {
  2145.   SetTag(e_bandwidthConfirm);
  2146.   H225_BandwidthConfirm & bcf = *this;
  2147.   bcf.m_requestSeqNum = seqNum;
  2148.   bcf.m_bandWidth = bandWidth;
  2149.   return bcf;
  2150. }
  2151.  
  2152.  
  2153. H225_BandwidthReject & H323RasPDU::BuildBandwidthReject(unsigned seqNum, unsigned reason)
  2154. {
  2155.   SetTag(e_bandwidthReject);
  2156.   H225_BandwidthReject & brj = *this;
  2157.   brj.m_requestSeqNum = seqNum;
  2158.   brj.m_rejectReason.SetTag(reason);
  2159.   return brj;
  2160. }
  2161.  
  2162.  
  2163. H225_InfoRequest & H323RasPDU::BuildInfoRequest(unsigned seqNum,
  2164.                                                 unsigned callRef,
  2165.                                                 const OpalGloballyUniqueID * id)
  2166. {
  2167.   SetTag(e_infoRequest);
  2168.   H225_InfoRequest & irq = *this;
  2169.   irq.m_requestSeqNum = seqNum;
  2170.   irq.m_callReferenceValue = callRef;
  2171.   if (callRef != 0 && id != NULL)
  2172.     irq.m_callIdentifier.m_guid = *id;
  2173.   return irq;
  2174. }
  2175.  
  2176.  
  2177. H225_InfoRequestResponse & H323RasPDU::BuildInfoRequestResponse(unsigned seqNum)
  2178. {
  2179.   SetTag(e_infoRequestResponse);
  2180.   H225_InfoRequestResponse & irr = *this;
  2181.   irr.m_requestSeqNum = seqNum;
  2182.   return irr;
  2183. }
  2184.  
  2185.  
  2186. H225_InfoRequestAck & H323RasPDU::BuildInfoRequestAck(unsigned seqNum)
  2187. {
  2188.   SetTag(e_infoRequestAck);
  2189.   H225_InfoRequestAck & iack = *this;
  2190.   iack.m_requestSeqNum = seqNum;
  2191.   return iack;
  2192. }
  2193.  
  2194.  
  2195. H225_InfoRequestNak & H323RasPDU::BuildInfoRequestNak(unsigned seqNum, unsigned reason)
  2196. {
  2197.   SetTag(e_infoRequestNak);
  2198.   H225_InfoRequestNak & inak = *this;
  2199.   inak.m_requestSeqNum = seqNum;
  2200.   inak.m_nakReason.SetTag(reason);
  2201.   return inak;
  2202. }
  2203.  
  2204.  
  2205. H225_UnknownMessageResponse & H323RasPDU::BuildUnknownMessageResponse(unsigned seqNum)
  2206. {
  2207.   SetTag(e_unknownMessageResponse);
  2208.   H225_UnknownMessageResponse & umr = *this;
  2209.   umr.m_requestSeqNum = seqNum;
  2210.   return umr;
  2211. }
  2212.  
  2213.  
  2214. H225_RequestInProgress & H323RasPDU::BuildRequestInProgress(unsigned seqNum, unsigned delay)
  2215. {
  2216.   SetTag(e_requestInProgress);
  2217.   H225_RequestInProgress & rip = *this;
  2218.   rip.m_requestSeqNum = seqNum;
  2219.   rip.m_delay = delay;
  2220.   return rip;
  2221. }
  2222.  
  2223.  
  2224. H225_ServiceControlIndication & H323RasPDU::BuildServiceControlIndication(unsigned seqNum, const OpalGloballyUniqueID * id)
  2225. {
  2226.   SetTag(e_serviceControlIndication);
  2227.   H225_ServiceControlIndication & sci = *this;
  2228.   sci.m_requestSeqNum = seqNum;
  2229.  
  2230.   if (id != NULL && !id->IsNULL()) {
  2231.     sci.IncludeOptionalField(H225_ServiceControlIndication::e_callSpecific);
  2232.     sci.m_callSpecific.m_callIdentifier.m_guid = *id;
  2233.   }
  2234.  
  2235.   return sci;
  2236. }
  2237.  
  2238.  
  2239. H225_ServiceControlResponse & H323RasPDU::BuildServiceControlResponse(unsigned seqNum)
  2240. {
  2241.   SetTag(e_serviceControlResponse);
  2242.   H225_ServiceControlResponse & scr = *this;
  2243.   scr.m_requestSeqNum = seqNum;
  2244.   return scr;
  2245. }
  2246.  
  2247.  
  2248. /////////////////////////////////////////////////////////////////////////////
  2249.