Utilise new MergeSym feature to no longer overwrite the source .DEF file when buildin...
[openh323.git] / src / h323pdu.cxx
blob97d4d07eacd3999f3d2a73b3573ad5ea88c3cf20
1 /*
2 * h323pdu.cxx
4 * H.323 PDU definitions
6 * Open H323 Library
8 * Copyright (c) 1998-2000 Equivalence Pty. Ltd.
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/
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.
20 * The Original Code is Open H323 Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions of this code were written with the assisance of funding from
25 * Vovida Networks, Inc. http://www.vovida.com.
27 * Contributor(s): ______________________________________.
29 * $Log$
30 * Revision 1.154 2006/07/17 09:52:57 shorne
31 * Added more support URL alias Addresses
33 * Revision 1.153 2006/06/23 20:19:39 shorne
34 * More H460 support
36 * Revision 1.152 2006/05/30 11:14:56 hfriederich
37 * Switch from DISABLE_H460 to H323_H460
39 * Revision 1.151 2006/05/17 03:36:52 shorne
40 * DISABLE_H460 default under linux
42 * Revision 1.150 2006/05/16 18:46:50 shorne
43 * Fixed H460 ReleaseComplete missing call
45 * Revision 1.149 2006/05/16 11:45:17 shorne
46 * more H460 support and non-call services
48 * Revision 1.148 2006/01/26 03:28:10 shorne
49 * Caller Authentication added
51 * Revision 1.147 2006/01/20 00:32:24 csoutheren
52 * First check-in of signalling aggregation code - incomplete and disabled by default
54 * Revision 1.146 2005/12/09 05:20:07 csoutheren
55 * Added ability to set explicit Q.931 cause code on call end
57 * Revision 1.145 2005/11/21 20:59:59 shorne
58 * Adjusted Call End Reasons
60 * Revision 1.144 2005/09/16 08:12:50 csoutheren
61 * Added ability to set timeout for connect
63 * Revision 1.143 2005/08/30 08:29:31 csoutheren
64 * Added new error code
66 * Revision 1.142 2005/03/04 03:21:21 csoutheren
67 * Added local and remote addresses to all PDU logs to assist in debugging
69 * Revision 1.141 2005/01/04 08:08:45 csoutheren
70 * More changes to implement the new configuration methodology, and also to
71 * attack the global static problem
73 * Revision 1.140 2005/01/03 06:26:09 csoutheren
74 * Added extensive support for disabling code modules at compile time
76 * Revision 1.139 2004/12/21 23:33:47 csoutheren
77 * Fixed #defines for H.460, thanks to Simon Horne
79 * Revision 1.138 2004/12/14 06:22:22 csoutheren
80 * More OSP implementation
82 * Revision 1.137 2004/12/08 01:59:23 csoutheren
83 * initial support for Transnexus OSP toolkit
85 * Revision 1.136 2004/09/03 01:06:10 csoutheren
86 * Added initial hooks for H.460 GEF
87 * Thanks to Simon Horne and ISVO (Asia) Pte Ltd. for this contribution
89 * Revision 1.135 2004/05/07 06:44:16 csoutheren
90 * Fixed problem with empty Q>931 DisplayName
92 * Revision 1.134 2004/04/20 05:24:54 csoutheren
93 * Added ability to specify Q.931 DisplayName
95 * Revision 1.133 2004/04/03 08:28:06 csoutheren
96 * Remove pseudo-RTTI and replaced with real RTTI
98 * Revision 1.132 2004/04/03 06:56:52 rjongbloed
99 * Many and various changes to support new Visual C++ 2003
101 * Revision 1.131 2004/02/26 08:32:47 csoutheren
102 * Added release complete codes for MCU
104 * Revision 1.130 2003/12/11 05:41:00 csoutheren
105 * Added storage of H.225 version in endpoint structure
106 * Disabled sending RIPs to endpoints that cannot handle them
108 * Revision 1.129 2003/05/29 09:19:52 rjongbloed
109 * Fixed minor problem with including DisplayName IE if localPartyName
110 * is blank, now does not include it, thanks Auri Vizgaitis
112 * Revision 1.128 2003/05/06 06:24:16 robertj
113 * Added continuous DTMF tone support (H.245 UserInputIndication - signalUpdate)
114 * as per header documentation, thanks Auri Vizgaitis
116 * Revision 1.127 2003/04/10 09:37:20 robertj
117 * Added some more functions for converting to alias addresses.
119 * Revision 1.126 2003/04/01 03:11:51 robertj
120 * Added function to get array of AliasAddress into PStringArray.
122 * Revision 1.125 2003/03/25 04:56:21 robertj
123 * Fixed issues to do with multiple inheritence in transaction reply cache.
125 * Revision 1.124 2003/03/20 01:51:12 robertj
126 * More abstraction of H.225 RAS and H.501 protocols transaction handling.
128 * Revision 1.123 2003/02/25 06:48:19 robertj
129 * More work on PDU transaction abstraction.
131 * Revision 1.122 2003/02/21 05:25:45 craigs
132 * Abstracted out underlying transports for use with peerelements
134 * Revision 1.121 2003/02/03 04:31:05 robertj
135 * Added special case for Cisco vendor field, they leave it rather incomplete,
137 * Revision 1.120 2003/01/26 02:57:58 craigs
138 * Fixed oops in last checkin
140 * Revision 1.119 2003/01/26 02:50:38 craigs
141 * Change so SETUP PDU uses conference and callIdentifier from H323Connection,
142 * rather than both doing seperately and then overwriting
144 * Revision 1.118 2002/11/28 04:41:48 robertj
145 * Added support for RAS ServiceControlIndication command.
147 * Revision 1.117 2002/11/27 06:54:57 robertj
148 * Added Service Control Session management as per Annex K/H.323 via RAS
149 * only at this stage.
150 * Added H.248 ASN and very primitive infrastructure for linking into the
151 * Service Control Session management system.
152 * Added basic infrastructure for Annex K/H.323 HTTP transport system.
153 * Added Call Credit Service Control to display account balances.
155 * Revision 1.116 2002/11/21 05:21:42 robertj
156 * Fixed bug where get lots of zeros at the end of some PDU's
158 * Revision 1.115 2002/11/21 04:15:36 robertj
159 * Added some changes to help interop with brain dead ASN decoders that do not
160 * know to ignore fields (eg greater than version 2) they do not understand.
162 * Revision 1.114 2002/11/13 04:38:17 robertj
163 * Added ability to get (and set) Q.931 release complete cause codes.
165 * Revision 1.113 2002/11/07 03:50:28 robertj
166 * Added extra "congested" Q.931 codes.
168 * Revision 1.112 2002/10/31 00:45:22 robertj
169 * Enhanced jitter buffer system so operates dynamically between minimum and
170 * maximum values. Altered API to assure app writers note the change!
172 * Revision 1.111 2002/10/08 13:08:21 robertj
173 * Changed for IPv6 support, thanks Sébastien Josset.
175 * Revision 1.110 2002/08/14 01:07:22 robertj
176 * Added translation of Q.931 unallocated number release complete code to
177 * OpenH323 EndedByNoUser which is the nearest match.
179 * Revision 1.109 2002/08/12 05:38:24 robertj
180 * Changes to the RAS subsystem to support ability to make requests to client
181 * from gkserver without causing bottlenecks and race conditions.
183 * Revision 1.108 2002/08/05 10:03:47 robertj
184 * Cosmetic changes to normalise the usage of pragma interface/implementation.
186 * Revision 1.107 2002/08/05 05:17:41 robertj
187 * Fairly major modifications to support different authentication credentials
188 * in ARQ to the logged in ones on RRQ. For both client and server.
189 * Various other H.235 authentication bugs and anomalies fixed on the way.
191 * Revision 1.106 2002/07/31 02:25:04 robertj
192 * Fixed translation of some call end reasons for to Q.931 codes.
194 * Revision 1.105 2002/07/25 10:55:44 robertj
195 * Changes to allow more granularity in PDU dumps, hex output increasing
196 * with increasing trace level.
198 * Revision 1.104 2002/07/11 07:04:12 robertj
199 * Added build InfoRequest pdu type to RAS.
201 * Revision 1.103 2002/06/13 03:59:56 craigs
202 * Added codes to progress messages to allow inband audio before connect
204 * Revision 1.102 2002/05/29 03:55:21 robertj
205 * Added protocol version number checking infrastructure, primarily to improve
206 * interoperability with stacks that are unforgiving of new features.
208 * Revision 1.101 2002/05/29 00:03:19 robertj
209 * Fixed unsolicited IRR support in gk client and server,
210 * including support for IACK and INAK.
212 * Revision 1.100 2002/05/21 09:32:49 robertj
213 * Added ability to set multiple alias names ona connection by connection
214 * basis, defaults to endpoint list, thanks Artis Kugevics
216 * Revision 1.99 2002/05/07 03:18:15 robertj
217 * Added application info (name/version etc) into registered endpoint data.
219 * Revision 1.98 2002/05/03 09:18:49 robertj
220 * Added automatic retransmission of RAS responses to retried requests.
222 * Revision 1.97 2002/04/24 01:08:09 robertj
223 * Added output of RAS pdu sequence number to level 3 trace output.
225 * Revision 1.96 2002/03/27 06:04:43 robertj
226 * Added Temporary Failure end code for connection, an application may
227 * immediately retry the call if this occurs.
229 * Revision 1.95 2002/03/14 07:56:48 robertj
230 * Added ability to specify alias type in H323SetAliasAddress, if not specified
231 * then defaults to previous behaviour, thanks Nils Bokerman.
233 * Revision 1.94 2002/02/13 07:52:30 robertj
234 * Fixed missing parameters on Q.931 calling number, thanks Markus Rydh
236 * Revision 1.93 2002/02/01 01:48:45 robertj
237 * Some more fixes for T.120 channel establishment, more to do!
239 * Revision 1.92 2002/01/18 06:01:23 robertj
240 * Added some H323v4 functions (fastConnectRefused & TCS in SETUP)
242 * Revision 1.91 2001/12/15 07:10:59 robertj
243 * Added functions to get E.164 address from alias address or addresses.
245 * Revision 1.90 2001/12/14 08:36:36 robertj
246 * More implementation of T.38, thanks Adam Lazur
248 * Revision 1.89 2001/12/14 06:38:35 robertj
249 * Broke out conversion of Q.850 and H.225 release complete codes to
250 * OpenH323 call end reasons enum.
252 * Revision 1.88 2001/12/13 10:56:28 robertj
253 * Added build of request in progress pdu.
255 * Revision 1.87 2001/10/18 00:58:51 robertj
256 * Fixed problem with GetDestinationAlias() adding source aliases instead
257 * of the destination from the setup PDU, thanks Mikael Stolt.
259 * Revision 1.86 2001/10/09 06:55:26 robertj
260 * Fixed separating destCallSignalAddress fields with tabs in
261 * GetDestinationAlias() function, thanks Lee Kirchhoff
263 * Revision 1.85 2001/09/26 07:05:29 robertj
264 * Fixed incorrect tags in building some PDU's, thanks Chris Purvis.
266 * Revision 1.84 2001/09/14 00:08:20 robertj
267 * Optimised H323SetAliasAddress to use IsE164 function.
269 * Revision 1.83 2001/09/12 07:48:05 robertj
270 * Fixed various problems with tracing.
272 * Revision 1.82 2001/08/16 07:49:19 robertj
273 * Changed the H.450 support to be more extensible. Protocol handlers
274 * are now in separate classes instead of all in H323Connection.
276 * Revision 1.81 2001/08/10 11:03:52 robertj
277 * Major changes to H.235 support in RAS to support server.
279 * Revision 1.80 2001/08/06 03:08:56 robertj
280 * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
282 * Revision 1.79 2001/06/14 06:25:16 robertj
283 * Added further H.225 PDU build functions.
284 * Moved some functionality from connection to PDU class.
286 * Revision 1.78 2001/06/14 00:45:21 robertj
287 * Added extra parameters for Q.931 fields, thanks Rani Assaf
289 * Revision 1.77 2001/06/05 03:14:41 robertj
290 * Upgraded H.225 ASN to v4 and H.245 ASN to v7.
292 * Revision 1.76 2001/05/30 23:34:54 robertj
293 * Added functions to send TCS=0 for transmitter side pause.
295 * Revision 1.75 2001/05/09 04:07:55 robertj
296 * Added more call end codes for busy and congested.
298 * Revision 1.74 2001/05/03 06:45:21 robertj
299 * Changed trace so dumps PDU if gets an error in decode.
301 * Revision 1.73 2001/04/11 03:01:29 robertj
302 * Added H.450.2 (call transfer), thanks a LOT to Graeme Reid & Norwood Systems
304 * Revision 1.72 2001/03/24 00:58:03 robertj
305 * Fixed MSVC warnings.
307 * Revision 1.71 2001/03/24 00:34:49 robertj
308 * Added read/write hook functions so don't have to duplicate code in
309 * H323RasH235PDU descendant class of H323RasPDU.
311 * Revision 1.70 2001/03/23 05:38:30 robertj
312 * Added PTRACE_IF to output trace if a conditional is TRUE.
314 * Revision 1.69 2001/03/02 06:59:59 robertj
315 * Enhanced the globally unique identifier class.
317 * Revision 1.68 2001/02/09 05:13:56 craigs
318 * Added pragma implementation to (hopefully) reduce the executable image size
319 * under Linux
321 * Revision 1.67 2001/01/18 06:04:46 robertj
322 * Bullet proofed code so local alias can not be empty string. This actually
323 * fixes an ASN PER encoding bug causing an assert.
325 * Revision 1.66 2000/10/12 05:11:54 robertj
326 * Added trace log if get transport error on writing PDU.
328 * Revision 1.65 2000/09/25 06:48:11 robertj
329 * Removed use of alias if there is no alias present, ie only have transport address.
331 * Revision 1.64 2000/09/22 01:35:51 robertj
332 * Added support for handling LID's that only do symmetric codecs.
334 * Revision 1.63 2000/09/20 01:50:22 craigs
335 * Added ability to set jitter buffer on a per-connection basis
337 * Revision 1.62 2000/09/05 01:16:20 robertj
338 * Added "security" call end reason code.
340 * Revision 1.61 2000/07/15 09:51:41 robertj
341 * Changed adding of Q.931 party numbers to only occur in SETUP.
343 * Revision 1.60 2000/07/13 12:29:49 robertj
344 * Added some more cause codes on release complete,
346 * Revision 1.59 2000/07/12 10:20:43 robertj
347 * Fixed incorrect tag code in H.245 ModeChange reject PDU.
349 * Revision 1.58 2000/07/09 15:21:11 robertj
350 * Changed reference to the word "field" to be more correct IE or "Information Element"
351 * Fixed return value of Q.931/H.225 PDU read so returns TRUE if no H.225 data in the
352 * User-User IE. Just flag it as empty and continue processing PDU's.
354 * Revision 1.57 2000/06/21 23:59:44 robertj
355 * Fixed copy/paste error setting Q.931 display name to incorrect value.
357 * Revision 1.56 2000/06/21 08:07:47 robertj
358 * Added cause/reason to release complete PDU, where relevent.
360 * Revision 1.55 2000/06/07 05:48:06 robertj
361 * Added call forwarding.
363 * Revision 1.54 2000/05/25 01:59:05 robertj
364 * Fixed bugs in calculation of GlLobally Uniqie ID according to DCE/H.225 rules.
366 * Revision 1.53 2000/05/23 11:32:37 robertj
367 * Rewrite of capability table to combine 2 structures into one and move functionality into that class
368 * allowing some normalisation of usage across several applications.
369 * Changed H323Connection so gets a copy of capabilities instead of using endponts, allows adjustments
370 * to be done depending on the remote client application.
372 * Revision 1.52 2000/05/15 08:38:59 robertj
373 * Removed addition of calling/called party number field in Q.931 if there isn't one.
375 * Revision 1.51 2000/05/09 12:19:31 robertj
376 * Added ability to get and set "distinctive ring" Q.931 functionality.
378 * Revision 1.50 2000/05/08 14:07:35 robertj
379 * Improved the provision and detection of calling and caller numbers, aliases and hostnames.
381 * Revision 1.49 2000/05/08 05:06:27 robertj
382 * Fixed bug in H.245 close logical channel timeout, thanks XuPeili.
384 * Revision 1.48 2000/05/02 04:32:27 robertj
385 * Fixed copyright notice comment.
387 * Revision 1.47 2000/04/14 17:29:43 robertj
388 * Fixed display of error message on timeout when timeouts are not errors.
390 * Revision 1.46 2000/04/10 20:39:18 robertj
391 * Added support for more sophisticated DTMF and hook flash user indication.
392 * Added function to extract E164 address from Q.931/H.225 PDU.
394 * Revision 1.45 2000/03/29 04:42:19 robertj
395 * Improved some trace logging messages.
397 * Revision 1.44 2000/03/25 02:01:07 robertj
398 * Added adjustable caller name on connection by connection basis.
400 * Revision 1.43 2000/03/21 01:08:10 robertj
401 * Fixed incorrect call reference code being used in originated call.
403 * Revision 1.42 2000/02/17 12:07:43 robertj
404 * Used ne wPWLib random number generator after finding major problem in MSVC rand().
406 * Revision 1.41 1999/12/23 22:47:09 robertj
407 * Added calling party number field.
409 * Revision 1.40 1999/12/11 02:21:00 robertj
410 * Added ability to have multiple aliases on local endpoint.
412 * Revision 1.39 1999/11/16 13:21:38 robertj
413 * Removed extraneous error trace when doing asynchronous answer call.
415 * Revision 1.38 1999/11/15 14:11:29 robertj
416 * Fixed trace output stream being put back after setting hex/fillchar modes.
418 * Revision 1.37 1999/11/10 23:30:20 robertj
419 * Fixed unexpected closing of transport on PDU read error.
421 * Revision 1.36 1999/11/01 00:48:31 robertj
422 * Added assert for illegal condition in capabilities, must have set if have table.
424 * Revision 1.35 1999/10/30 23:48:21 robertj
425 * Fixed incorrect PDU type for H225 RAS location request.
427 * Revision 1.34 1999/10/29 03:35:06 robertj
428 * Fixed setting of unique ID using fake MAC address from Win32 PPP device.
430 * Revision 1.33 1999/09/21 14:09:49 robertj
431 * Removed warnings when no tracing enabled.
433 * Revision 1.32 1999/09/10 09:03:01 robertj
434 * Used new GetInterfaceTable() function to get ethernet address for UniqueID
436 * Revision 1.31 1999/09/10 03:36:48 robertj
437 * Added simple Q.931 Status response to Q.931 Status Enquiry
439 * Revision 1.30 1999/08/31 12:34:19 robertj
440 * Added gatekeeper support.
442 * Revision 1.29 1999/08/31 11:37:30 robertj
443 * Fixed problem with apparently randomly losing signalling channel.
445 * Revision 1.28 1999/08/25 05:08:14 robertj
446 * File fission (critical mass reached).
448 * Revision 1.27 1999/08/13 06:34:38 robertj
449 * Fixed problem in CallPartyNumber Q.931 encoding.
450 * Added field name display to Q.931 protocol.
452 * Revision 1.26 1999/08/10 13:14:15 robertj
453 * Added Q.931 Called Number field if have "phone number" style destination addres.
455 * Revision 1.25 1999/08/10 11:38:03 robertj
456 * Changed population of setup UUIE destinationAddress if can be IA5 string.
458 * Revision 1.24 1999/07/26 05:10:30 robertj
459 * Fixed yet another race condition on connection termination.
461 * Revision 1.23 1999/07/16 14:03:52 robertj
462 * Fixed bug in Master/Slave negotiation that can cause looping.
464 * Revision 1.22 1999/07/16 06:15:59 robertj
465 * Corrected semantics for tunnelled master/slave determination in fast start.
467 * Revision 1.21 1999/07/16 02:15:30 robertj
468 * Fixed more tunneling problems.
470 * Revision 1.20 1999/07/15 14:45:36 robertj
471 * Added propagation of codec open error to shut down logical channel.
472 * Fixed control channel start up bug introduced with tunnelling.
474 * Revision 1.19 1999/07/15 09:08:04 robertj
475 * Added extra debugging for if have PDU decoding error.
477 * Revision 1.18 1999/07/15 09:04:31 robertj
478 * Fixed some fast start bugs
480 * Revision 1.17 1999/07/10 02:51:36 robertj
481 * Added mutexing in H245 procedures. Also fixed MSD state bug.
483 * Revision 1.16 1999/07/09 06:09:50 robertj
484 * Major implementation. An ENORMOUS amount of stuff added everywhere.
486 * Revision 1.15 1999/06/25 10:25:35 robertj
487 * Added maintentance of callIdentifier variable in H.225 channel.
489 * Revision 1.14 1999/06/22 13:45:40 robertj
490 * Fixed conferenceIdentifier generation algorithm to bas as in spec.
492 * Revision 1.13 1999/06/19 15:18:38 robertj
493 * Fixed bug in MasterSlaveDeterminationAck pdu has incorrect master/slave state.
495 * Revision 1.12 1999/06/14 15:08:40 robertj
496 * Added GSM codec class frame work (still no actual codec).
498 * Revision 1.11 1999/06/14 06:39:08 robertj
499 * Fixed problem with getting transmit flag to channel from PDU negotiator
501 * Revision 1.10 1999/06/14 05:15:56 robertj
502 * Changes for using RTP sessions correctly in H323 Logical Channel context
504 * Revision 1.9 1999/06/13 12:41:14 robertj
505 * Implement logical channel transmitter.
506 * Fixed H245 connect on receiving call.
508 * Revision 1.8 1999/06/09 05:26:19 robertj
509 * Major restructuring of classes.
511 * Revision 1.7 1999/06/06 06:06:36 robertj
512 * Changes for new ASN compiler and v2 protocol ASN files.
514 * Revision 1.6 1999/04/26 06:20:22 robertj
515 * Fixed bugs in protocol
517 * Revision 1.5 1999/04/26 06:14:47 craigs
518 * Initial implementation for RTP decoding and lots of stuff
519 * As a whole, these changes are called "First Noise"
521 * Revision 1.4 1999/02/23 11:04:28 robertj
522 * Added capability to make outgoing call.
524 * Revision 1.3 1999/02/06 09:23:39 robertj
525 * BeOS port
527 * Revision 1.2 1999/01/16 02:34:57 robertj
528 * GNU compiler compatibility.
530 * Revision 1.1 1999/01/16 01:30:54 robertj
531 * Initial revision
535 #include <ptlib.h>
537 #ifdef __GNUC__
538 #pragma implementation "h323pdu.h"
539 #endif
541 #include "h323pdu.h"
543 #include "h323ep.h"
544 #include "h225ras.h"
546 #ifdef H323_H460
547 #include "h460.h"
548 #endif
550 #ifdef _MSC_VER
551 #pragma warning(disable : 4100)
552 #endif
554 #define new PNEW
556 const unsigned H225_ProtocolID[] = { 0,0,8,2250,0,H225_PROTOCOL_VERSION };
557 const unsigned H245_ProtocolID[] = { 0,0,8,245 ,0,H245_PROTOCOL_VERSION };
559 static const char E164NumberPrefix[] = "E164:";
560 static const char PrivatePartyPrefix[] = "Private:";
561 static const char DataPartyPrefix[] = "Data:";
562 static const char TelexPartyPrefix[] = "Telex:";
563 static const char NSPNumberPrefix[] = "NSP:";
566 ///////////////////////////////////////////////////////////////////////////////
568 #if PTRACING
569 void H323TraceDumpPDU(const char * proto,
570 BOOL writing,
571 const PBYTEArray & rawData,
572 const PASN_Object & pdu,
573 const PASN_Choice & tags,
574 unsigned seqNum,
575 const H323TransportAddress & locAddr,
576 const H323TransportAddress & remAddr)
578 if (!PTrace::CanTrace(3))
579 return;
581 ostream & trace = PTrace::Begin(3, __FILE__, __LINE__);
582 trace << proto << '\t' << (writing ? "Send" : "Receiv") << "ing PDU [";
584 if (locAddr.IsEmpty())
585 trace << "(noaddr)";
586 else
587 trace << locAddr;
588 trace << "/";
589 if (remAddr.IsEmpty())
590 trace << "(noaddr)";
591 else
592 trace << remAddr;
594 trace << "] :";
596 if (PTrace::CanTrace(4)) {
597 trace << "\n "
598 << resetiosflags(ios::floatfield);
600 if (!PTrace::CanTrace(5))
601 trace << setiosflags(ios::fixed); // Will truncate hex dumps to 32 bytes
603 trace << setprecision(2) << pdu
604 << resetiosflags(ios::floatfield);
606 if (PTrace::CanTrace(6))
607 trace << "\nRaw PDU:\n"
608 << hex << setfill('0')
609 << setprecision(2) << rawData
610 << dec << setfill(' ');
612 else {
613 trace << ' ' << tags.GetTagName();
614 PASN_Object & next = tags.GetObject();
615 if (PIsDescendant(&next, PASN_Choice))
616 trace << ' ' << ((PASN_Choice &)next).GetTagName();
617 if (seqNum > 0)
618 trace << ' ' << seqNum;
621 trace << PTrace::End;
623 #endif
626 ///////////////////////////////////////////////////////////////////////////////
628 void H323SetAliasAddresses(const H323TransportAddressArray & addresses, H225_ArrayOf_AliasAddress & aliases)
630 aliases.SetSize(addresses.GetSize());
631 for (PINDEX i = 0; i < addresses.GetSize(); i++)
632 H323SetAliasAddress(addresses[i], aliases[i]);
636 void H323SetAliasAddresses(const PStringArray & names,
637 H225_ArrayOf_AliasAddress & aliases,
638 int tag)
640 aliases.SetSize(names.GetSize());
641 for (PINDEX i = 0; i < names.GetSize(); i++)
642 H323SetAliasAddress(names[i], aliases[i], tag);
646 void H323SetAliasAddresses(const PStringList & names,
647 H225_ArrayOf_AliasAddress & aliases,
648 int tag)
650 aliases.SetSize(names.GetSize());
651 for (PINDEX i = 0; i < names.GetSize(); i++)
652 H323SetAliasAddress(names[i], aliases[i], tag);
656 static BOOL IsE164(const PString & str)
658 return !str && strspn(str, "1234567890*#") == strlen(str);
661 static BOOL IsURL(const PString & str)
663 return !str && str.Find("@") != P_MAX_INDEX;
667 void H323SetAliasAddress(const H323TransportAddress & address, H225_AliasAddress & alias)
669 alias.SetTag(H225_AliasAddress::e_transportID);
670 address.SetPDU(alias);
673 static struct {
674 const char * name;
675 int tag;
676 } aliasAddressTypes[5] = {
677 { "e164", H225_AliasAddress::e_dialedDigits },
678 { "h323", H225_AliasAddress::e_h323_ID },
679 { "url", H225_AliasAddress::e_url_ID },
680 { "ip", H225_AliasAddress::e_transportID },
681 { "email", H225_AliasAddress::e_email_ID },
682 // { "???", H225_AliasAddresse_partyNumber },
683 // { "???", H225_AliasAddresse_mobileUIM }
686 void H323SetAliasAddress(const PString & _name, H225_AliasAddress & alias, int tag)
688 PString name = _name;
689 // See if alias type was explicitly specified
690 if (tag < 0) {
691 PINDEX colon = name.Find(':');
692 if (colon != P_MAX_INDEX && colon > 0) {
693 PString type = name.Left(colon);
694 for (PINDEX i = 0; tag < 0 && i < 5; i++) {
695 if (type == aliasAddressTypes[i].name) {
696 tag = aliasAddressTypes[i].tag;
697 name = name.Mid(colon+1);
703 // otherwise guess it from the string: if all digits then assume an e164 address, @ URL else H323_ID.
704 if (tag < 0) {
705 if (IsE164(name))
706 tag = H225_AliasAddress::e_dialedDigits;
707 else if (IsURL(name))
708 tag = H225_AliasAddress::e_url_ID;
709 else
710 tag =H225_AliasAddress::e_h323_ID;
713 alias.SetTag(tag);
714 switch (alias.GetTag()) {
715 case H225_AliasAddress::e_dialedDigits :
716 case H225_AliasAddress::e_url_ID :
717 case H225_AliasAddress::e_email_ID :
718 (PASN_IA5String &)alias = name;
719 break;
721 case H225_AliasAddress::e_h323_ID :
722 (PASN_BMPString &)alias = name;
723 break;
725 case H225_AliasAddress::e_transportID :
727 H323TransportAddress addr = name;
728 addr.SetPDU(alias);
729 break;
731 case H225_AliasAddress::e_partyNumber :
733 H225_PartyNumber & party = alias;
734 if (strncmp(name, E164NumberPrefix, sizeof(E164NumberPrefix)-1) == 0) {
735 party.SetTag(H225_PartyNumber::e_e164Number);
736 H225_PublicPartyNumber & number = party;
737 number.m_publicNumberDigits = name.Mid(sizeof(E164NumberPrefix)-1);
739 else if (strncmp(name, PrivatePartyPrefix, sizeof(PrivatePartyPrefix)-1) == 0) {
740 party.SetTag(H225_PartyNumber::e_privateNumber);
741 H225_PrivatePartyNumber & number = party;
742 number.m_privateNumberDigits = name.Mid(sizeof(PrivatePartyPrefix)-1);
744 else if (strncmp(name, DataPartyPrefix, sizeof(DataPartyPrefix)-1) == 0) {
745 party.SetTag(H225_PartyNumber::e_dataPartyNumber);
746 (H225_NumberDigits &)party = name.Mid(sizeof(DataPartyPrefix)-1);
748 else if (strncmp(name, TelexPartyPrefix, sizeof(TelexPartyPrefix)-1) == 0) {
749 party.SetTag(H225_PartyNumber::e_telexPartyNumber);
750 (H225_NumberDigits &)party = name.Mid(sizeof(TelexPartyPrefix)-1);
752 else if (strncmp(name, NSPNumberPrefix, sizeof(NSPNumberPrefix)-1) == 0) {
753 party.SetTag(H225_PartyNumber::e_nationalStandardPartyNumber);
754 (H225_NumberDigits &)party = name.Mid(sizeof(NSPNumberPrefix)-1);
758 default :
759 break;
764 /////////////////////////////////////////////////////////////////////////////
766 PStringArray H323GetAliasAddressStrings(const H225_ArrayOf_AliasAddress & aliases)
768 PStringArray strings(aliases.GetSize());
770 for (PINDEX i = 0; i < aliases.GetSize(); i++)
771 strings[i] = H323GetAliasAddressString(aliases[i]);
773 return strings;
777 PString H323GetAliasAddressString(const H225_AliasAddress & alias)
779 switch (alias.GetTag()) {
780 case H225_AliasAddress::e_dialedDigits :
781 case H225_AliasAddress::e_url_ID :
782 case H225_AliasAddress::e_email_ID :
783 return ((const PASN_IA5String &)alias).GetValue();
785 case H225_AliasAddress::e_h323_ID :
786 return ((const PASN_BMPString &)alias).GetValue();
788 case H225_AliasAddress::e_transportID :
789 return H323TransportAddress(alias);
791 case H225_AliasAddress::e_partyNumber :
793 const H225_PartyNumber & party = alias;
794 switch (party.GetTag()) {
795 case H225_PartyNumber::e_e164Number :
797 const H225_PublicPartyNumber & number = party;
798 return E164NumberPrefix + (PString)number.m_publicNumberDigits;
801 case H225_PartyNumber::e_privateNumber :
803 const H225_PrivatePartyNumber & number = party;
804 return PrivatePartyPrefix + (PString)number.m_privateNumberDigits;
807 case H225_PartyNumber::e_dataPartyNumber :
808 return DataPartyPrefix + (PString)(const H225_NumberDigits &)party;
810 case H225_PartyNumber::e_telexPartyNumber :
811 return TelexPartyPrefix + (PString)(const H225_NumberDigits &)party;
813 case H225_PartyNumber::e_nationalStandardPartyNumber :
814 return NSPNumberPrefix + (PString)(const H225_NumberDigits &)party;
816 break;
819 default :
820 break;
823 return PString();
827 PString H323GetAliasAddressE164(const H225_AliasAddress & alias)
829 PString str = H323GetAliasAddressString(alias);
830 if (IsE164(str))
831 return str;
833 return PString();
837 PString H323GetAliasAddressE164(const H225_ArrayOf_AliasAddress & aliases)
839 for (PINDEX i = 0; i < aliases.GetSize(); i++) {
840 PString alias = H323GetAliasAddressE164(aliases[i]);
841 if (!alias)
842 return alias;
845 return PString();
849 ///////////////////////////////////////////////////////////////////////////////
851 PString H323GetApplicationInfo(const H225_VendorIdentifier & vendor)
853 PStringStream str;
855 PString product = vendor.m_productId.AsString();
856 PString version = vendor.m_versionId.AsString();
858 // Special case, Cisco IOS does not put in the product and version fields
859 if (vendor.m_vendor.m_t35CountryCode == 181 &&
860 vendor.m_vendor.m_t35Extension == 0 &&
861 vendor.m_vendor.m_manufacturerCode == 18) {
862 if (product.IsEmpty())
863 product = "Cisco IOS";
864 if (version.IsEmpty())
865 version = "12.2";
868 str << product << '\t' << version << '\t' << vendor.m_vendor.m_t35CountryCode;
869 if (vendor.m_vendor.m_t35Extension != 0)
870 str << '.' << vendor.m_vendor.m_t35Extension;
871 str << '/' << vendor.m_vendor.m_manufacturerCode;
873 str.MakeMinimumSize();
874 return str;
877 ///////////////////////////////////////////////////////////////////////////////
878 #ifdef H323_H460
879 static void SendSetupFeatureSet(const H323Connection * connection, H225_Setup_UUIE & pdu)
882 H225_FeatureSet fs;
884 if (!connection->OnSendFeatureSet(H460_MessageType::e_setup, fs))
885 return;
887 if (fs.HasOptionalField(H225_FeatureSet::e_neededFeatures)) {
888 pdu.IncludeOptionalField(H225_Setup_UUIE::e_neededFeatures);
889 H225_ArrayOf_FeatureDescriptor & fsn = pdu.m_neededFeatures;
890 fsn = fs.m_neededFeatures;
893 if (fs.HasOptionalField(H225_FeatureSet::e_desiredFeatures)) {
894 pdu.IncludeOptionalField(H225_Setup_UUIE::e_desiredFeatures);
895 H225_ArrayOf_FeatureDescriptor & fsn = pdu.m_desiredFeatures;
896 fsn = fs.m_desiredFeatures;
899 if (fs.HasOptionalField(H225_FeatureSet::e_supportedFeatures)) {
900 pdu.IncludeOptionalField(H225_Setup_UUIE::e_supportedFeatures);
901 H225_ArrayOf_FeatureDescriptor & fsn = pdu.m_supportedFeatures;
902 fsn = fs.m_supportedFeatures;
907 template <typename PDUType>
908 static void SendFeatureSet(const H323Connection * connection, unsigned code, H225_H323_UU_PDU & msg, PDUType & pdu)
910 H225_FeatureSet fs;
911 if (!connection->OnSendFeatureSet(code,fs))
912 return;
914 if (code == H460_MessageType::e_callProceeding) {
915 pdu.IncludeOptionalField(PDUType::e_featureSet);
916 pdu.m_featureSet = fs;
917 } else {
918 if (fs.HasOptionalField(H225_FeatureSet::e_supportedFeatures)) {
919 msg.IncludeOptionalField(H225_H323_UU_PDU::e_genericData);
921 H225_ArrayOf_FeatureDescriptor & fsn = fs.m_supportedFeatures;
922 H225_ArrayOf_GenericData & data = msg.m_genericData;
924 for (PINDEX i=0; i < fsn.GetSize(); i++) {
925 PINDEX lastPos = data.GetSize();
926 data.SetSize(lastPos+1);
927 data[lastPos] = fsn[i];
932 #endif
935 #ifndef DISABLE_CALLAUTH
936 template <typename PDUType>
937 static void BuildAuthenticatorPDU(PDUType & pdu, unsigned code, const H323Connection * connection)
940 H235Authenticators authenticators = connection->GetEPAuthenticators();
942 if (!authenticators.IsEmpty()) {
943 connection->GetEPAuthenticators().PrepareSignalPDU(code,pdu.m_tokens,pdu.m_cryptoTokens);
945 if (pdu.m_tokens.GetSize() > 0)
946 pdu.IncludeOptionalField(PDUType::e_tokens);
948 if (pdu.m_cryptoTokens.GetSize() > 0)
949 pdu.IncludeOptionalField(PDUType::e_cryptoTokens);
952 #endif
953 ///////////////////////////////////////////////////////////////////////////////
955 H323SignalPDU::H323SignalPDU()
960 static unsigned SetH225Version(const H323Connection & connection,
961 H225_ProtocolIdentifier & protocolIdentifier)
963 unsigned version = connection.GetSignallingVersion();
964 protocolIdentifier.SetValue(psprintf("0.0.8.2250.0.%u", version));
965 return version;
968 H225_Setup_UUIE & H323SignalPDU::BuildSetup(const H323Connection & connection,
969 const H323TransportAddress & destAddr)
971 H323EndPoint & endpoint = connection.GetEndPoint();
973 q931pdu.BuildSetup(connection.GetCallReference());
974 SetQ931Fields(connection, TRUE);
976 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_setup);
977 H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
979 if (SetH225Version(connection, setup.m_protocolIdentifier) < 3) {
980 setup.RemoveOptionalField(H225_Setup_UUIE::e_multipleCalls);
981 setup.RemoveOptionalField(H225_Setup_UUIE::e_maintainConnection);
984 setup.IncludeOptionalField(H225_Setup_UUIE::e_sourceAddress);
985 H323SetAliasAddresses(connection.GetLocalAliasNames(), setup.m_sourceAddress);
987 setup.m_conferenceID = connection.GetConferenceIdentifier();
989 if (connection.GetEndPoint().OnSendCallIndependentSupplementaryService(&connection,*this))
990 setup.m_conferenceGoal.SetTag(H225_Setup_UUIE_conferenceGoal::e_callIndependentSupplementaryService);
991 else if (connection.GetEndPoint().OnConferenceInvite(TRUE,&connection,*this))
992 setup.m_conferenceGoal.SetTag(H225_Setup_UUIE_conferenceGoal::e_invite);
993 else
994 setup.m_conferenceGoal.SetTag(H225_Setup_UUIE_conferenceGoal::e_create);
996 setup.m_callType.SetTag(H225_CallType::e_pointToPoint);
998 setup.m_callIdentifier.m_guid = connection.GetCallIdentifier();
999 setup.m_mediaWaitForConnect = FALSE;
1000 setup.m_canOverlapSend = FALSE;
1002 if (!destAddr) {
1003 setup.IncludeOptionalField(H225_Setup_UUIE::e_destCallSignalAddress);
1004 destAddr.SetPDU(setup.m_destCallSignalAddress);
1007 PString destAlias = connection.GetRemotePartyName();
1008 if (!destAlias && destAlias != destAddr) {
1009 setup.IncludeOptionalField(H225_Setup_UUIE::e_destinationAddress);
1010 setup.m_destinationAddress.SetSize(1);
1012 // Try and encode it as a phone number
1013 H323SetAliasAddress(destAlias, setup.m_destinationAddress[0]);
1014 if (setup.m_destinationAddress[0].GetTag() == H225_AliasAddress::e_dialedDigits)
1015 q931pdu.SetCalledPartyNumber(destAlias);
1018 endpoint.SetEndpointTypeInfo(setup.m_sourceInfo);
1020 #ifdef H323_H460
1021 SendSetupFeatureSet(&connection,setup);
1022 #endif
1024 #ifndef DISABLE_CALLAUTH
1025 BuildAuthenticatorPDU<H225_Setup_UUIE>(setup,H225_H323_UU_PDU_h323_message_body::e_setup,
1026 &connection);
1027 #endif
1029 return setup;
1033 H225_CallProceeding_UUIE &
1034 H323SignalPDU::BuildCallProceeding(const H323Connection & connection)
1036 q931pdu.BuildCallProceeding(connection.GetCallReference());
1037 SetQ931Fields(connection);
1039 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_callProceeding);
1040 H225_CallProceeding_UUIE & proceeding = m_h323_uu_pdu.m_h323_message_body;
1042 if (SetH225Version(connection, proceeding.m_protocolIdentifier) < 3) {
1043 proceeding.RemoveOptionalField(H225_CallProceeding_UUIE::e_multipleCalls);
1044 proceeding.RemoveOptionalField(H225_CallProceeding_UUIE::e_maintainConnection);
1047 proceeding.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1049 connection.GetEndPoint().SetEndpointTypeInfo(proceeding.m_destinationInfo);
1051 #ifdef H323_H460
1052 SendFeatureSet<H225_CallProceeding_UUIE>(&connection,H460_MessageType::e_callProceeding, m_h323_uu_pdu, proceeding);
1053 #endif
1055 #ifndef DISABLE_CALLAUTH
1056 if (connection.HasAuthentication()) {
1057 BuildAuthenticatorPDU<H225_CallProceeding_UUIE>(proceeding,H225_H323_UU_PDU_h323_message_body::e_callProceeding,
1058 &connection);
1060 #endif
1062 return proceeding;
1066 H225_Connect_UUIE & H323SignalPDU::BuildConnect(const H323Connection & connection)
1068 q931pdu.BuildConnect(connection.GetCallReference());
1069 SetQ931Fields(connection);
1071 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_connect);
1072 H225_Connect_UUIE & connect = m_h323_uu_pdu.m_h323_message_body;
1074 if (SetH225Version(connection, connect.m_protocolIdentifier) < 3) {
1075 connect.RemoveOptionalField(H225_Connect_UUIE::e_multipleCalls);
1076 connect.RemoveOptionalField(H225_Connect_UUIE::e_maintainConnection);
1078 connect.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1079 connect.m_conferenceID = connection.GetConferenceIdentifier();
1081 connection.GetEndPoint().SetEndpointTypeInfo(connect.m_destinationInfo);
1083 #ifdef H323_H460
1084 SendFeatureSet<H225_Connect_UUIE>(&connection,H460_MessageType::e_connect, m_h323_uu_pdu,connect);
1085 #endif
1087 #ifndef DISABLE_CALLAUTH
1088 BuildAuthenticatorPDU<H225_Connect_UUIE>(connect,H225_H323_UU_PDU_h323_message_body::e_connect,
1089 &connection);
1090 #endif
1091 return connect;
1095 H225_Connect_UUIE & H323SignalPDU::BuildConnect(const H323Connection & connection,
1096 const PIPSocket::Address & h245Address,
1097 WORD port)
1099 H225_Connect_UUIE & connect = BuildConnect(connection);
1101 // indicate we are including the optional H245 address in the PDU
1102 connect.IncludeOptionalField(H225_Connect_UUIE::e_h245Address);
1104 // convert IP address into the correct H245 type
1105 H323TransportAddress transAddr(h245Address, port);
1106 transAddr.SetPDU(connect.m_h245Address);
1108 return connect;
1112 H225_Alerting_UUIE & H323SignalPDU::BuildAlerting(const H323Connection & connection)
1114 q931pdu.BuildAlerting(connection.GetCallReference());
1115 SetQ931Fields(connection);
1117 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_alerting);
1118 H225_Alerting_UUIE & alerting = m_h323_uu_pdu.m_h323_message_body;
1120 if (SetH225Version(connection, alerting.m_protocolIdentifier) < 3) {
1121 alerting.RemoveOptionalField(H225_Alerting_UUIE::e_multipleCalls);
1122 alerting.RemoveOptionalField(H225_Alerting_UUIE::e_maintainConnection);
1125 alerting.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1126 connection.GetEndPoint().SetEndpointTypeInfo(alerting.m_destinationInfo);
1128 #ifdef H323_H460
1129 SendFeatureSet<H225_Alerting_UUIE>(&connection,H460_MessageType::e_alerting, m_h323_uu_pdu,alerting);
1130 #endif
1132 #ifdef H323_H248
1133 if(connection.OnSendServiceControlSessions(alerting.m_serviceControl,
1134 H225_ServiceControlSession_reason::e_open))
1135 alerting.IncludeOptionalField(H225_Alerting_UUIE::e_serviceControl);
1136 #endif
1138 #ifndef DISABLE_CALLAUTH
1139 BuildAuthenticatorPDU<H225_Alerting_UUIE>(alerting,H225_H323_UU_PDU_h323_message_body::e_alerting,
1140 &connection);
1141 #endif
1143 return alerting;
1147 H225_Information_UUIE & H323SignalPDU::BuildInformation(const H323Connection & connection)
1149 q931pdu.BuildInformation(connection.GetCallReference(), connection.HadAnsweredCall());
1150 SetQ931Fields(connection);
1152 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_information);
1153 H225_Information_UUIE & information = m_h323_uu_pdu.m_h323_message_body;
1155 SetH225Version(connection, information.m_protocolIdentifier);
1156 information.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1158 return information;
1162 H323Connection::CallEndReason H323TranslateToCallEndReason(Q931::CauseValues cause,
1163 const H225_ReleaseCompleteReason & reason)
1165 PTRACE(4,"H225\tCall End Reason " << cause);
1167 switch (cause) {
1168 case Q931::ErrorInCauseIE :
1169 switch (reason.GetTag()) {
1170 case H225_ReleaseCompleteReason::e_noBandwidth :
1171 return H323Connection::EndedByNoBandwidth;
1173 case H225_ReleaseCompleteReason::e_gatekeeperResources :
1174 case H225_ReleaseCompleteReason::e_gatewayResources :
1175 case H225_ReleaseCompleteReason::e_adaptiveBusy :
1176 return H323Connection::EndedByRemoteCongestion;
1178 case H225_ReleaseCompleteReason::e_unreachableDestination :
1179 return H323Connection::EndedByUnreachable;
1181 case H225_ReleaseCompleteReason::e_calledPartyNotRegistered :
1182 return H323Connection::EndedByNoUser;
1184 case H225_ReleaseCompleteReason::e_callerNotRegistered:
1185 return H323Connection::EndedByGatekeeper;
1187 case H225_ReleaseCompleteReason::e_securityDenied:
1188 return H323Connection::EndedBySecurityDenial;
1190 case H225_ReleaseCompleteReason::e_newConnectionNeeded:
1191 return H323Connection::EndedByTemporaryFailure;
1193 // Do next case
1194 case Q931::UnknownCauseIE :
1195 case Q931::CallRejected :
1196 return H323Connection::EndedByRefusal;
1198 case Q931::NormalCallClearing :
1199 return H323Connection::EndedByRemoteUser;
1201 case Q931::UserBusy :
1202 return H323Connection::EndedByRemoteBusy;
1204 case Q931::Congestion :
1205 case Q931::ResourceUnavailable :
1206 return H323Connection::EndedByRemoteCongestion;
1208 case Q931::NoResponse :
1209 return H323Connection::EndedByHostOffline;
1211 case Q931::NoAnswer :
1212 return H323Connection::EndedByNoAnswer;
1214 case Q931::NoRouteToNetwork :
1215 case Q931::RequestedCircuitNotAvailable :
1216 case Q931::ChannelUnacceptable :
1217 return H323Connection::EndedByUnreachable;
1219 case Q931::UnallocatedNumber :
1220 case Q931::NoRouteToDestination :
1221 case Q931::SubscriberAbsent :
1222 return H323Connection::EndedByNoUser;
1224 case Q931::Redirection :
1225 return H323Connection::EndedByCallForwarded;
1227 case Q931::DestinationOutOfOrder :
1228 case Q931::NoCircuitChannelAvailable :
1229 return H323Connection::EndedByConnectFail;
1231 case Q931::TemporaryFailure :
1232 return H323Connection::EndedByTemporaryFailure;
1234 case Q931::InvalidNumberFormat :
1235 return H323Connection::EndedByInvalidNumberFormat;
1237 default:
1238 return H323Connection::EndedByQ931Cause;
1243 Q931::CauseValues H323TranslateFromCallEndReason(H323Connection::CallEndReason callEndReason,
1244 H225_ReleaseCompleteReason & reason)
1246 static int const ReasonCodes[H323Connection::NumCallEndReasons] = {
1247 Q931::NormalCallClearing, /// EndedByLocalUser, Local endpoint application cleared call
1248 Q931::UserBusy, /// EndedByNoAccept, Local endpoint did not accept call
1249 Q931::CallRejected, /// EndedByAnswerDenied, Local endpoint declined to answer call
1250 Q931::NormalCallClearing, /// EndedByRemoteUser, Remote endpoint application cleared call
1251 -H225_ReleaseCompleteReason::e_destinationRejection, /// EndedByRefusal, Remote endpoint refused call
1252 Q931::NoAnswer, /// EndedByNoAnswer, Remote endpoint did not answer in required time
1253 Q931::NormalCallClearing, /// EndedByCallerAbort, Remote endpoint stopped calling
1254 -H225_ReleaseCompleteReason::e_undefinedReason, /// EndedByTransportFail, Transport error cleared call
1255 -H225_ReleaseCompleteReason::e_unreachableDestination, /// EndedByConnectFail, Transport connection failed to establish call
1256 -H225_ReleaseCompleteReason::e_gatekeeperResources, /// EndedByGatekeeper, Gatekeeper has cleared call
1257 -H225_ReleaseCompleteReason::e_calledPartyNotRegistered,/// EndedByNoUser, Call failed as could not find user (in GK)
1258 -H225_ReleaseCompleteReason::e_noBandwidth, /// EndedByNoBandwidth, Call failed as could not get enough bandwidth
1259 -H225_ReleaseCompleteReason::e_undefinedReason, /// EndedByCapabilityExchange,Could not find common capabilities
1260 -H225_ReleaseCompleteReason::e_facilityCallDeflection, /// EndedByCallForwarded, Call was forwarded using FACILITY message
1261 -H225_ReleaseCompleteReason::e_securityDenied, /// EndedBySecurityDenial, Call failed a security check and was ended
1262 Q931::UserBusy, /// EndedByLocalBusy, Local endpoint busy
1263 Q931::Congestion, /// EndedByLocalCongestion, Local endpoint congested
1264 Q931::UserBusy, /// EndedByRemoteBusy, Remote endpoint busy
1265 Q931::Congestion, /// EndedByRemoteCongestion, Remote endpoint congested
1266 Q931::NoRouteToDestination, /// EndedByUnreachable, Could not reach the remote party
1267 Q931::InvalidCallReference, /// EndedByNoEndPoint, The remote party is not running an endpoint
1268 Q931::NoResponse, /// EndedByHostOffline, The remote party host off line
1269 Q931::TemporaryFailure, /// EndedByTemporaryFailure The remote failed temporarily app may retry
1270 Q931::UnknownCauseIE, /// EndedByQ931Cause, The remote ended the call with unmapped Q.931 cause code
1271 Q931::NormalUnspecified, /// EndedByDurationLimit, Call cleared due to an enforced duration limit
1272 -H225_ReleaseCompleteReason::e_invalidCID, /// EndedByInvalidConferenceID Call cleared due to invalid conference ID
1273 -H225_ReleaseCompleteReason::e_calledPartyNotRegistered, /// EndedByOSPRefusal Call cleared as OSP server unable or unwilling to route
1274 Q931::InvalidNumberFormat, /// EndedByInvalidNumberFormat Call cleared as number was invalid format
1275 Q931::ProtocolErrorUnspecified /// EndedByUnspecifiedProtocolError Call cleared due to unspecified protocol error
1278 int code = ReasonCodes[callEndReason];
1279 //if (code == Q931::UnknownCauseIE)
1280 // return (Q931::CauseValues)connection.GetCallEndReason();
1281 if (code >= 0)
1282 return (Q931::CauseValues)code;
1284 reason.SetTag(-code);
1285 return Q931::ErrorInCauseIE;
1288 Q931::CauseValues H323TranslateFromCallEndReason(const H323Connection & connection,
1289 H225_ReleaseCompleteReason & reason)
1291 return H323TranslateFromCallEndReason(connection.GetCallEndReason(), reason);
1294 H225_ReleaseComplete_UUIE &
1295 H323SignalPDU::BuildReleaseComplete(const H323Connection & connection)
1297 q931pdu.BuildReleaseComplete(connection.GetCallReference(), connection.HadAnsweredCall());
1299 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_releaseComplete);
1301 H225_ReleaseComplete_UUIE & release = m_h323_uu_pdu.m_h323_message_body;
1303 SetH225Version(connection, release.m_protocolIdentifier);
1304 release.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1306 Q931::CauseValues cause = (Q931::CauseValues)connection.GetQ931Cause();
1307 if (cause == Q931::ErrorInCauseIE)
1308 cause = H323TranslateFromCallEndReason(connection, release.m_reason);
1309 if (cause != Q931::ErrorInCauseIE)
1310 q931pdu.SetCause(cause);
1311 else
1312 release.IncludeOptionalField(H225_ReleaseComplete_UUIE::e_reason);
1314 #ifndef DISABLE_CALLAUTH
1315 BuildAuthenticatorPDU<H225_ReleaseComplete_UUIE>(release,H225_H323_UU_PDU_h323_message_body::e_releaseComplete,
1316 &connection);
1317 #endif
1319 #ifdef H323_H460
1320 SendFeatureSet<H225_ReleaseComplete_UUIE>(&connection,H460_MessageType::e_releaseComplete, m_h323_uu_pdu,release);
1321 #endif
1323 return release;
1327 H225_Facility_UUIE * H323SignalPDU::BuildFacility(const H323Connection & connection,
1328 BOOL empty)
1330 q931pdu.BuildFacility(connection.GetCallReference(), connection.HadAnsweredCall());
1331 if (empty) {
1332 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
1333 return NULL;
1336 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_facility);
1337 H225_Facility_UUIE & fac = m_h323_uu_pdu.m_h323_message_body;
1339 SetH225Version(connection, fac.m_protocolIdentifier);
1340 fac.IncludeOptionalField(H225_Facility_UUIE::e_callIdentifier);
1341 fac.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1343 #ifdef H323_H460
1344 SendFeatureSet<H225_Facility_UUIE>(&connection,H460_MessageType::e_facility, m_h323_uu_pdu,fac);
1345 #endif
1347 #ifndef DISABLE_CALLAUTH
1348 BuildAuthenticatorPDU<H225_Facility_UUIE>(fac,H225_H323_UU_PDU_h323_message_body::e_facility,
1349 &connection);
1350 #endif
1352 return &fac;
1356 H225_Progress_UUIE & H323SignalPDU::BuildProgress(const H323Connection & connection)
1358 q931pdu.BuildProgress(connection.GetCallReference(), connection.HadAnsweredCall(), Q931::ProgressInbandInformationAvailable);
1359 SetQ931Fields(connection);
1361 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_progress);
1362 H225_Progress_UUIE & progress = m_h323_uu_pdu.m_h323_message_body;
1364 SetH225Version(connection, progress.m_protocolIdentifier);
1365 progress.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1366 connection.GetEndPoint().SetEndpointTypeInfo(progress.m_destinationInfo);
1368 return progress;
1372 H225_Status_UUIE & H323SignalPDU::BuildStatus(const H323Connection & connection)
1374 q931pdu.BuildStatus(connection.GetCallReference(), connection.HadAnsweredCall());
1376 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_status);
1377 H225_Status_UUIE & status = m_h323_uu_pdu.m_h323_message_body;
1379 SetH225Version(connection, status.m_protocolIdentifier);
1380 status.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1382 return status;
1386 H225_StatusInquiry_UUIE & H323SignalPDU::BuildStatusInquiry(const H323Connection & connection)
1388 q931pdu.BuildStatusEnquiry(connection.GetCallReference(), connection.HadAnsweredCall());
1390 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_statusInquiry);
1391 H225_StatusInquiry_UUIE & inquiry = m_h323_uu_pdu.m_h323_message_body;
1393 SetH225Version(connection, inquiry.m_protocolIdentifier);
1394 inquiry.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1396 return inquiry;
1400 H225_SetupAcknowledge_UUIE & H323SignalPDU::BuildSetupAcknowledge(const H323Connection & connection)
1402 q931pdu.BuildSetupAcknowledge(connection.GetCallReference());
1404 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_setupAcknowledge);
1405 H225_SetupAcknowledge_UUIE & setupAck = m_h323_uu_pdu.m_h323_message_body;
1407 SetH225Version(connection, setupAck.m_protocolIdentifier);
1408 setupAck.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1410 return setupAck;
1414 H225_Notify_UUIE & H323SignalPDU::BuildNotify(const H323Connection & connection)
1416 q931pdu.BuildNotify(connection.GetCallReference(), connection.HadAnsweredCall());
1418 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_notify);
1419 H225_Notify_UUIE & notify = m_h323_uu_pdu.m_h323_message_body;
1421 SetH225Version(connection, notify.m_protocolIdentifier);
1422 notify.m_callIdentifier.m_guid = connection.GetCallIdentifier();
1424 return notify;
1428 void H323SignalPDU::BuildQ931()
1430 // Encode the H225 PDu into the Q931 PDU as User-User data
1431 PPER_Stream strm;
1432 Encode(strm);
1433 strm.CompleteEncoding();
1434 q931pdu.SetIE(Q931::UserUserIE, strm);
1438 void H323SignalPDU::PrintOn(ostream & strm) const
1440 int indent = strm.precision() + 2;
1441 strm << "{\n"
1442 << setw(indent+10) << "q931pdu = " << setprecision(indent) << q931pdu << '\n'
1443 << setw(indent+10) << "h225pdu = " << setprecision(indent);
1444 H225_H323_UserInformation::PrintOn(strm);
1445 strm << '\n'
1446 << setw(indent-1) << "}";
1450 BOOL H323SignalPDU::Read(H323Transport & transport)
1452 PBYTEArray rawData;
1453 if (!transport.ReadPDU(rawData)) {
1454 PTRACE_IF(1, transport.GetErrorCode(PChannel::LastReadError) != PChannel::Timeout,
1455 "H225\tRead error (" << transport.GetErrorNumber(PChannel::LastReadError)
1456 << "): " << transport.GetErrorText(PChannel::LastReadError));
1457 return FALSE;
1460 return ProcessReadData(transport, rawData);
1463 BOOL H323SignalPDU::ProcessReadData(H323Transport & transport, const PBYTEArray & rawData)
1465 if (!q931pdu.Decode(rawData)) {
1466 PTRACE(1, "H225\tParse error of Q931 PDU:\n" << hex << setfill('0')
1467 << setprecision(2) << rawData
1468 << dec << setfill(' '));
1469 return FALSE;
1472 if (!q931pdu.HasIE(Q931::UserUserIE)) {
1473 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
1474 PTRACE(1, "H225\tNo Q931 User-User Information Element,"
1475 "\nRaw PDU:\n" << hex << setfill('0')
1476 << setprecision(2) << rawData
1477 << dec << setfill(' ') <<
1478 "\nQ.931 PDU:\n " << setprecision(2) << q931pdu);
1479 return TRUE;
1482 PPER_Stream strm = q931pdu.GetIE(Q931::UserUserIE);
1483 if (!Decode(strm)) {
1484 PTRACE(1, "H225\tRead error: PER decode failure in Q.931 User-User Information Element,"
1485 "\nRaw PDU:\n" << hex << setfill('0')
1486 << setprecision(2) << rawData
1487 << dec << setfill(' ') <<
1488 "\nQ.931 PDU:\n " << setprecision(2) << q931pdu <<
1489 "\nPartial PDU:\n " << setprecision(2) << *this);
1490 m_h323_uu_pdu.m_h323_message_body.SetTag(H225_H323_UU_PDU_h323_message_body::e_empty);
1491 return TRUE;
1494 H323TraceDumpPDU("H225", FALSE, rawData, *this, m_h323_uu_pdu.m_h323_message_body, 0,
1495 transport.GetLocalAddress(), transport.GetRemoteAddress());
1496 return TRUE;
1500 BOOL H323SignalPDU::Write(H323Transport & transport, H323Connection & connection)
1502 if (!q931pdu.HasIE(Q931::UserUserIE) && m_h323_uu_pdu.m_h323_message_body.IsValid())
1503 BuildQ931();
1505 PBYTEArray rawData;
1506 if (!q931pdu.Encode(rawData))
1507 return FALSE;
1509 #ifndef DISABLE_CALLAUTH
1510 int tag = m_h323_uu_pdu.m_h323_message_body.GetTag();
1511 connection.OnAuthenticationFinalise(tag,rawData);
1512 #endif
1514 H323TraceDumpPDU("H225", TRUE, rawData, *this, m_h323_uu_pdu.m_h323_message_body, 0,
1515 transport.GetLocalAddress(), transport.GetRemoteAddress());
1517 if (transport.WritePDU(rawData))
1518 return TRUE;
1520 PTRACE(1, "H225\tWrite PDU failed ("
1521 << transport.GetErrorNumber(PChannel::LastWriteError)
1522 << "): " << transport.GetErrorText(PChannel::LastWriteError));
1523 return FALSE;
1526 PString H323SignalPDU::GetSourceURL() const
1529 PString url = PString();
1531 if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
1532 const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
1534 if (setup.HasOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress)) {
1535 const H225_ArrayOf_AliasAddress & aliases = setup.e_sourceCallSignalAddress;
1536 if (aliases.GetSize() > 0) {
1537 for (PINDEX i = 0; i < aliases.GetSize(); i++) {
1538 switch (aliases[i].GetTag()) {
1539 case H225_AliasAddress::e_url_ID :
1540 case H225_AliasAddress::e_email_ID:
1541 url = ((const PASN_IA5String &)aliases[i]).GetValue();
1542 default:
1543 break;
1550 return url;
1553 PString H323SignalPDU::GetSourceAliases(const H323Transport * transport) const
1555 PString remoteHostName;
1557 if (transport != NULL)
1558 remoteHostName = transport->GetRemoteAddress().GetHostName();
1560 PString displayName = GetQ931().GetDisplayName();
1562 PStringStream aliases;
1563 if (displayName != remoteHostName)
1564 aliases << displayName;
1566 if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
1567 const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
1569 if (remoteHostName.IsEmpty() &&
1570 setup.HasOptionalField(H225_Setup_UUIE::e_sourceCallSignalAddress)) {
1571 H323TransportAddress remoteAddress(setup.m_sourceCallSignalAddress);
1572 remoteHostName = remoteAddress.GetHostName();
1575 if (setup.m_sourceAddress.GetSize() > 0) {
1576 BOOL needParen = !aliases.IsEmpty();
1577 BOOL needComma = FALSE;
1578 for (PINDEX i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
1579 PString alias = H323GetAliasAddressString(setup.m_sourceAddress[i]);
1580 if (alias != displayName && alias != remoteHostName) {
1581 if (needComma)
1582 aliases << ", ";
1583 else if (needParen)
1584 aliases << " (";
1585 aliases << alias;
1586 needComma = TRUE;
1589 if (needParen && needComma)
1590 aliases << ')';
1594 if (aliases.IsEmpty())
1595 return remoteHostName;
1597 aliases << " [" << remoteHostName << ']';
1598 aliases.MakeMinimumSize();
1599 return aliases;
1603 PString H323SignalPDU::GetDestinationAlias(BOOL firstAliasOnly) const
1605 PStringStream aliases;
1607 PString number;
1608 if (GetQ931().GetCalledPartyNumber(number)) {
1609 if (firstAliasOnly)
1610 return number;
1611 aliases << number;
1614 if (m_h323_uu_pdu.m_h323_message_body.GetTag() == H225_H323_UU_PDU_h323_message_body::e_setup) {
1615 const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
1616 if (setup.m_destinationAddress.GetSize() > 0) {
1617 if (firstAliasOnly)
1618 return H323GetAliasAddressString(setup.m_destinationAddress[0]);
1620 for (PINDEX i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
1621 if (!aliases.IsEmpty())
1622 aliases << '\t';
1623 aliases << H323GetAliasAddressString(setup.m_destinationAddress[i]);
1627 if (setup.HasOptionalField(H225_Setup_UUIE::e_destCallSignalAddress)) {
1628 if (!aliases.IsEmpty())
1629 aliases << '\t';
1630 aliases << H323TransportAddress(setup.m_destCallSignalAddress);
1634 aliases.MakeMinimumSize();
1635 return aliases;
1639 BOOL H323SignalPDU::GetSourceE164(PString & number) const
1641 if (GetQ931().GetCallingPartyNumber(number))
1642 return TRUE;
1644 if (m_h323_uu_pdu.m_h323_message_body.GetTag() != H225_H323_UU_PDU_h323_message_body::e_setup)
1645 return FALSE;
1647 const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
1648 if (!setup.HasOptionalField(H225_Setup_UUIE::e_sourceAddress))
1649 return FALSE;
1651 PINDEX i;
1652 for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
1653 if (setup.m_sourceAddress[i].GetTag() == H225_AliasAddress::e_dialedDigits) {
1654 number = (PASN_IA5String &)setup.m_sourceAddress[i];
1655 return TRUE;
1659 for (i = 0; i < setup.m_sourceAddress.GetSize(); i++) {
1660 PString str = H323GetAliasAddressString(setup.m_sourceAddress[i]);
1661 if (IsE164(str)) {
1662 number = str;
1663 return TRUE;
1667 return FALSE;
1671 BOOL H323SignalPDU::GetDestinationE164(PString & number) const
1673 if (GetQ931().GetCalledPartyNumber(number))
1674 return TRUE;
1676 if (m_h323_uu_pdu.m_h323_message_body.GetTag() != H225_H323_UU_PDU_h323_message_body::e_setup)
1677 return FALSE;
1679 const H225_Setup_UUIE & setup = m_h323_uu_pdu.m_h323_message_body;
1680 if (!setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress))
1681 return FALSE;
1683 PINDEX i;
1684 for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
1685 if (setup.m_destinationAddress[i].GetTag() == H225_AliasAddress::e_dialedDigits) {
1686 number = (PASN_IA5String &)setup.m_destinationAddress[i];
1687 return TRUE;
1691 for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
1692 PString str = H323GetAliasAddressString(setup.m_destinationAddress[i]);
1693 if (IsE164(str)) {
1694 number = str;
1695 return TRUE;
1699 return FALSE;
1703 unsigned H323SignalPDU::GetDistinctiveRing() const
1705 Q931::SignalInfo sig = GetQ931().GetSignalInfo();
1706 if (sig < Q931::SignalAlertingPattern0 || sig > Q931::SignalAlertingPattern7)
1707 return 0;
1709 return sig - Q931::SignalAlertingPattern0;
1713 void H323SignalPDU::SetQ931Fields(const H323Connection & connection,
1714 BOOL insertPartyNumbers,
1715 unsigned plan,
1716 unsigned type,
1717 int presentation,
1718 int screening)
1720 PINDEX i;
1721 const PStringList & aliases = connection.GetLocalAliasNames();
1723 PString number;
1724 PString localName = connection.GetLocalPartyName();
1725 PString displayName;
1727 if (IsE164(localName)) {
1728 number = localName;
1729 for (i = 0; i < aliases.GetSize(); i++) {
1730 if (!IsE164(aliases[i])) {
1731 displayName = aliases[i];
1732 break;
1736 else {
1737 if (!localName)
1738 displayName = localName;
1739 for (i = 0; i < aliases.GetSize(); i++) {
1740 if (IsE164(aliases[i])) {
1741 number = aliases[i];
1742 break;
1747 if (!connection.GetDisplayName().IsEmpty())
1748 displayName = connection.GetDisplayName();
1749 if (displayName.IsEmpty())
1750 displayName = number;
1751 q931pdu.SetDisplayName(displayName);
1753 if (insertPartyNumbers) {
1754 PString otherNumber = connection.GetRemotePartyNumber();
1755 if (otherNumber.IsEmpty()) {
1756 PString otherName = connection.GetRemotePartyName();
1757 if (IsE164(otherName))
1758 otherNumber = otherName;
1761 if (connection.HadAnsweredCall()) {
1762 if (!number)
1763 q931pdu.SetCalledPartyNumber(number, plan, type);
1764 if (!otherNumber)
1765 q931pdu.SetCallingPartyNumber(otherNumber, plan, type, presentation, screening);
1767 else {
1768 if (!number)
1769 q931pdu.SetCallingPartyNumber(number, plan, type, presentation, screening);
1770 if (!otherNumber)
1771 q931pdu.SetCalledPartyNumber(otherNumber, plan, type);
1775 unsigned ring = connection.GetDistinctiveRing();
1776 if (ring != 0)
1777 q931pdu.SetSignalInfo((Q931::SignalInfo)(ring + Q931::SignalAlertingPattern0));
1781 /////////////////////////////////////////////////////////////////////////////
1783 H245_RequestMessage & H323ControlPDU::Build(H245_RequestMessage::Choices request)
1785 SetTag(e_request);
1786 H245_RequestMessage & msg = *this;
1787 msg.SetTag(request);
1788 return msg;
1792 H245_ResponseMessage & H323ControlPDU::Build(H245_ResponseMessage::Choices response)
1794 SetTag(e_response);
1795 H245_ResponseMessage & resp = *this;
1796 resp.SetTag(response);
1797 return resp;
1801 H245_CommandMessage & H323ControlPDU::Build(H245_CommandMessage::Choices command)
1803 SetTag(e_command);
1804 H245_CommandMessage & cmd = *this;
1805 cmd.SetTag(command);
1806 return cmd;
1810 H245_IndicationMessage & H323ControlPDU::Build(H245_IndicationMessage::Choices indication)
1812 SetTag(e_indication);
1813 H245_IndicationMessage & ind = *this;
1814 ind.SetTag(indication);
1815 return ind;
1819 H245_MasterSlaveDetermination &
1820 H323ControlPDU::BuildMasterSlaveDetermination(unsigned terminalType,
1821 unsigned statusDeterminationNumber)
1823 H245_MasterSlaveDetermination & msd = Build(H245_RequestMessage::e_masterSlaveDetermination);
1824 msd.m_terminalType = terminalType;
1825 msd.m_statusDeterminationNumber = statusDeterminationNumber;
1826 return msd;
1830 H245_MasterSlaveDeterminationAck &
1831 H323ControlPDU::BuildMasterSlaveDeterminationAck(BOOL isMaster)
1833 H245_MasterSlaveDeterminationAck & msda = Build(H245_ResponseMessage::e_masterSlaveDeterminationAck);
1834 msda.m_decision.SetTag(isMaster
1835 ? H245_MasterSlaveDeterminationAck_decision::e_slave
1836 : H245_MasterSlaveDeterminationAck_decision::e_master);
1837 return msda;
1841 H245_MasterSlaveDeterminationReject &
1842 H323ControlPDU::BuildMasterSlaveDeterminationReject(unsigned cause)
1844 H245_MasterSlaveDeterminationReject & msdr = Build(H245_ResponseMessage::e_masterSlaveDeterminationReject);
1845 msdr.m_cause.SetTag(cause);
1846 return msdr;
1850 H245_TerminalCapabilitySet &
1851 H323ControlPDU::BuildTerminalCapabilitySet(const H323Connection & connection,
1852 unsigned sequenceNumber,
1853 BOOL empty)
1855 H245_TerminalCapabilitySet & cap = Build(H245_RequestMessage::e_terminalCapabilitySet);
1857 cap.m_sequenceNumber = sequenceNumber;
1858 cap.m_protocolIdentifier.SetValue(H245_ProtocolID, PARRAYSIZE(H245_ProtocolID));
1860 if (empty)
1861 return cap;
1863 cap.IncludeOptionalField(H245_TerminalCapabilitySet::e_multiplexCapability);
1864 cap.m_multiplexCapability.SetTag(H245_MultiplexCapability::e_h2250Capability);
1865 H245_H2250Capability & h225_0 = cap.m_multiplexCapability;
1866 h225_0.m_maximumAudioDelayJitter = connection.GetMaxAudioJitterDelay();
1867 h225_0.m_receiveMultipointCapability.m_mediaDistributionCapability.SetSize(1);
1868 h225_0.m_transmitMultipointCapability.m_mediaDistributionCapability.SetSize(1);
1869 h225_0.m_receiveAndTransmitMultipointCapability.m_mediaDistributionCapability.SetSize(1);
1870 h225_0.m_t120DynamicPortCapability = TRUE;
1872 // Set the table of capabilities
1873 connection.GetLocalCapabilities().BuildPDU(connection, cap);
1875 return cap;
1879 H245_TerminalCapabilitySetAck &
1880 H323ControlPDU::BuildTerminalCapabilitySetAck(unsigned sequenceNumber)
1882 H245_TerminalCapabilitySetAck & cap = Build(H245_ResponseMessage::e_terminalCapabilitySetAck);
1883 cap.m_sequenceNumber = sequenceNumber;
1884 return cap;
1888 H245_TerminalCapabilitySetReject &
1889 H323ControlPDU::BuildTerminalCapabilitySetReject(unsigned sequenceNumber,
1890 unsigned cause)
1892 H245_TerminalCapabilitySetReject & cap = Build(H245_ResponseMessage::e_terminalCapabilitySetReject);
1893 cap.m_sequenceNumber = sequenceNumber;
1894 cap.m_cause.SetTag(cause);
1896 return cap;
1900 H245_OpenLogicalChannel &
1901 H323ControlPDU::BuildOpenLogicalChannel(unsigned forwardLogicalChannelNumber)
1903 H245_OpenLogicalChannel & open = Build(H245_RequestMessage::e_openLogicalChannel);
1904 open.m_forwardLogicalChannelNumber = forwardLogicalChannelNumber;
1905 return open;
1909 H245_RequestChannelClose &
1910 H323ControlPDU::BuildRequestChannelClose(unsigned channelNumber,
1911 unsigned reason)
1913 H245_RequestChannelClose & rcc = Build(H245_RequestMessage::e_requestChannelClose);
1914 rcc.m_forwardLogicalChannelNumber = channelNumber;
1915 rcc.IncludeOptionalField(H245_RequestChannelClose::e_reason);
1916 rcc.m_reason.SetTag(reason);
1917 return rcc;
1921 H245_CloseLogicalChannel &
1922 H323ControlPDU::BuildCloseLogicalChannel(unsigned channelNumber)
1924 H245_CloseLogicalChannel & clc = Build(H245_RequestMessage::e_closeLogicalChannel);
1925 clc.m_forwardLogicalChannelNumber = channelNumber;
1926 clc.m_source.SetTag(H245_CloseLogicalChannel_source::e_lcse);
1927 return clc;
1931 H245_OpenLogicalChannelAck &
1932 H323ControlPDU::BuildOpenLogicalChannelAck(unsigned channelNumber)
1934 H245_OpenLogicalChannelAck & ack = Build(H245_ResponseMessage::e_openLogicalChannelAck);
1935 ack.m_forwardLogicalChannelNumber = channelNumber;
1936 return ack;
1940 H245_OpenLogicalChannelReject &
1941 H323ControlPDU::BuildOpenLogicalChannelReject(unsigned channelNumber,
1942 unsigned cause)
1944 H245_OpenLogicalChannelReject & reject = Build(H245_ResponseMessage::e_openLogicalChannelReject);
1945 reject.m_forwardLogicalChannelNumber = channelNumber;
1946 reject.m_cause.SetTag(cause);
1947 return reject;
1951 H245_OpenLogicalChannelConfirm &
1952 H323ControlPDU::BuildOpenLogicalChannelConfirm(unsigned channelNumber)
1954 H245_OpenLogicalChannelConfirm & chan = Build(H245_IndicationMessage::e_openLogicalChannelConfirm);
1955 chan.m_forwardLogicalChannelNumber = channelNumber;
1956 return chan;
1960 H245_CloseLogicalChannelAck &
1961 H323ControlPDU::BuildCloseLogicalChannelAck(unsigned channelNumber)
1963 H245_CloseLogicalChannelAck & chan = Build(H245_ResponseMessage::e_closeLogicalChannelAck);
1964 chan.m_forwardLogicalChannelNumber = channelNumber;
1965 return chan;
1969 H245_RequestChannelCloseAck &
1970 H323ControlPDU::BuildRequestChannelCloseAck(unsigned channelNumber)
1972 H245_RequestChannelCloseAck & rcca = Build(H245_ResponseMessage::e_requestChannelCloseAck);
1973 rcca.m_forwardLogicalChannelNumber = channelNumber;
1974 return rcca;
1978 H245_RequestChannelCloseReject &
1979 H323ControlPDU::BuildRequestChannelCloseReject(unsigned channelNumber)
1981 H245_RequestChannelCloseReject & rccr = Build(H245_ResponseMessage::e_requestChannelCloseReject);
1982 rccr.m_forwardLogicalChannelNumber = channelNumber;
1983 return rccr;
1987 H245_RequestChannelCloseRelease &
1988 H323ControlPDU::BuildRequestChannelCloseRelease(unsigned channelNumber)
1990 H245_RequestChannelCloseRelease & rccr = Build(H245_IndicationMessage::e_requestChannelCloseRelease);
1991 rccr.m_forwardLogicalChannelNumber = channelNumber;
1992 return rccr;
1996 H245_RequestMode & H323ControlPDU::BuildRequestMode(unsigned sequenceNumber)
1998 H245_RequestMode & rm = Build(H245_RequestMessage::e_requestMode);
1999 rm.m_sequenceNumber = sequenceNumber;
2001 return rm;
2005 H245_RequestModeAck & H323ControlPDU::BuildRequestModeAck(unsigned sequenceNumber,
2006 unsigned response)
2008 H245_RequestModeAck & ack = Build(H245_ResponseMessage::e_requestModeAck);
2009 ack.m_sequenceNumber = sequenceNumber;
2010 ack.m_response.SetTag(response);
2011 return ack;
2015 H245_RequestModeReject & H323ControlPDU::BuildRequestModeReject(unsigned sequenceNumber,
2016 unsigned cause)
2018 H245_RequestModeReject & reject = Build(H245_ResponseMessage::e_requestModeReject);
2019 reject.m_sequenceNumber = sequenceNumber;
2020 reject.m_cause.SetTag(cause);
2021 return reject;
2025 H245_RoundTripDelayRequest &
2026 H323ControlPDU::BuildRoundTripDelayRequest(unsigned sequenceNumber)
2028 H245_RoundTripDelayRequest & req = Build(H245_RequestMessage::e_roundTripDelayRequest);
2029 req.m_sequenceNumber = sequenceNumber;
2030 return req;
2034 H245_RoundTripDelayResponse &
2035 H323ControlPDU::BuildRoundTripDelayResponse(unsigned sequenceNumber)
2037 H245_RoundTripDelayResponse & resp = Build(H245_ResponseMessage::e_roundTripDelayResponse);
2038 resp.m_sequenceNumber = sequenceNumber;
2039 return resp;
2043 H245_UserInputIndication &
2044 H323ControlPDU::BuildUserInputIndication(const PString & value)
2046 H245_UserInputIndication & ind = Build(H245_IndicationMessage::e_userInput);
2047 ind.SetTag(H245_UserInputIndication::e_alphanumeric);
2048 (PASN_GeneralString &)ind = value;
2049 return ind;
2053 H245_UserInputIndication & H323ControlPDU::BuildUserInputIndication(char tone,
2054 unsigned duration,
2055 unsigned logicalChannel,
2056 unsigned rtpTimestamp)
2058 H245_UserInputIndication & ind = Build(H245_IndicationMessage::e_userInput);
2060 if (tone != ' ') {
2061 ind.SetTag(H245_UserInputIndication::e_signal);
2062 H245_UserInputIndication_signal & sig = ind;
2064 sig.m_signalType.SetValue(tone);
2066 if (duration > 0) {
2067 sig.IncludeOptionalField(H245_UserInputIndication_signal::e_duration);
2068 sig.m_duration = duration;
2071 if (logicalChannel > 0) {
2072 sig.IncludeOptionalField(H245_UserInputIndication_signal::e_rtp);
2073 sig.m_rtp.m_logicalChannelNumber = logicalChannel;
2074 sig.m_rtp.m_timestamp = rtpTimestamp;
2077 else {
2078 ind.SetTag(H245_UserInputIndication::e_signalUpdate);
2079 H245_UserInputIndication_signalUpdate & sig = ind;
2081 sig.m_duration = duration;
2082 if (logicalChannel > 0) {
2083 sig.IncludeOptionalField(H245_UserInputIndication_signalUpdate::e_rtp);
2084 sig.m_rtp.m_logicalChannelNumber = logicalChannel;
2088 return ind;
2092 H245_FunctionNotUnderstood &
2093 H323ControlPDU::BuildFunctionNotUnderstood(const H323ControlPDU & pdu)
2095 H245_FunctionNotUnderstood & fnu = Build(H245_IndicationMessage::e_functionNotUnderstood);
2097 switch (pdu.GetTag()) {
2098 case H245_MultimediaSystemControlMessage::e_request :
2099 fnu.SetTag(H245_FunctionNotUnderstood::e_request);
2100 (H245_RequestMessage &)fnu = (const H245_RequestMessage &)pdu;
2101 break;
2103 case H245_MultimediaSystemControlMessage::e_response :
2104 fnu.SetTag(H245_FunctionNotUnderstood::e_response);
2105 (H245_ResponseMessage &)fnu = (const H245_ResponseMessage &)pdu;
2106 break;
2108 case H245_MultimediaSystemControlMessage::e_command :
2109 fnu.SetTag(H245_FunctionNotUnderstood::e_command);
2110 (H245_CommandMessage &)fnu = (const H245_CommandMessage &)pdu;
2111 break;
2114 return fnu;
2118 H245_EndSessionCommand & H323ControlPDU::BuildEndSessionCommand(unsigned reason)
2120 H245_EndSessionCommand & end = Build(H245_CommandMessage::e_endSessionCommand);
2121 end.SetTag(reason);
2122 return end;
2126 /////////////////////////////////////////////////////////////////////////////
2128 H323RasPDU::H323RasPDU()
2133 H323RasPDU::H323RasPDU(const H235Authenticators & auth)
2134 : H323TransactionPDU(auth)
2139 PObject * H323RasPDU::Clone() const
2141 return new H323RasPDU(*this);
2145 PASN_Object & H323RasPDU::GetPDU()
2147 return *this;
2151 PASN_Choice & H323RasPDU::GetChoice()
2153 return *this;
2157 const PASN_Object & H323RasPDU::GetPDU() const
2159 return *this;
2163 const PASN_Choice & H323RasPDU::GetChoice() const
2165 return *this;
2169 unsigned H323RasPDU::GetSequenceNumber() const
2171 switch (GetTag()) {
2172 case H225_RasMessage::e_gatekeeperRequest :
2173 return ((const H225_GatekeeperRequest &)*this).m_requestSeqNum;
2175 case H225_RasMessage::e_gatekeeperConfirm :
2176 return ((const H225_GatekeeperConfirm &)*this).m_requestSeqNum;
2178 case H225_RasMessage::e_gatekeeperReject :
2179 return ((const H225_GatekeeperReject &)*this).m_requestSeqNum;
2181 case H225_RasMessage::e_registrationRequest :
2182 return ((const H225_RegistrationRequest &)*this).m_requestSeqNum;
2184 case H225_RasMessage::e_registrationConfirm :
2185 return ((const H225_RegistrationConfirm &)*this).m_requestSeqNum;
2187 case H225_RasMessage::e_registrationReject :
2188 return ((const H225_RegistrationReject &)*this).m_requestSeqNum;
2190 case H225_RasMessage::e_unregistrationRequest :
2191 return ((const H225_UnregistrationRequest &)*this).m_requestSeqNum;
2193 case H225_RasMessage::e_unregistrationConfirm :
2194 return ((const H225_UnregistrationConfirm &)*this).m_requestSeqNum;
2196 case H225_RasMessage::e_unregistrationReject :
2197 return ((const H225_UnregistrationReject &)*this).m_requestSeqNum;
2199 case H225_RasMessage::e_admissionRequest :
2200 return ((const H225_AdmissionRequest &)*this).m_requestSeqNum;
2202 case H225_RasMessage::e_admissionConfirm :
2203 return ((const H225_AdmissionConfirm &)*this).m_requestSeqNum;
2205 case H225_RasMessage::e_admissionReject :
2206 return ((const H225_AdmissionReject &)*this).m_requestSeqNum;
2208 case H225_RasMessage::e_bandwidthRequest :
2209 return ((const H225_BandwidthRequest &)*this).m_requestSeqNum;
2211 case H225_RasMessage::e_bandwidthConfirm :
2212 return ((const H225_BandwidthConfirm &)*this).m_requestSeqNum;
2214 case H225_RasMessage::e_bandwidthReject :
2215 return ((const H225_BandwidthReject &)*this).m_requestSeqNum;
2217 case H225_RasMessage::e_disengageRequest :
2218 return ((const H225_DisengageRequest &)*this).m_requestSeqNum;
2220 case H225_RasMessage::e_disengageConfirm :
2221 return ((const H225_DisengageConfirm &)*this).m_requestSeqNum;
2223 case H225_RasMessage::e_disengageReject :
2224 return ((const H225_DisengageReject &)*this).m_requestSeqNum;
2226 case H225_RasMessage::e_locationRequest :
2227 return ((const H225_LocationRequest &)*this).m_requestSeqNum;
2229 case H225_RasMessage::e_locationConfirm :
2230 return ((const H225_LocationConfirm &)*this).m_requestSeqNum;
2232 case H225_RasMessage::e_locationReject :
2233 return ((const H225_LocationReject &)*this).m_requestSeqNum;
2235 case H225_RasMessage::e_infoRequest :
2236 return ((const H225_InfoRequest &)*this).m_requestSeqNum;
2238 case H225_RasMessage::e_infoRequestResponse :
2239 return ((const H225_InfoRequestResponse &)*this).m_requestSeqNum;
2241 case H225_RasMessage::e_nonStandardMessage :
2242 return ((const H225_NonStandardMessage &)*this).m_requestSeqNum;
2244 case H225_RasMessage::e_unknownMessageResponse :
2245 return ((const H225_UnknownMessageResponse &)*this).m_requestSeqNum;
2247 case H225_RasMessage::e_requestInProgress :
2248 return ((const H225_RequestInProgress &)*this).m_requestSeqNum;
2250 case H225_RasMessage::e_resourcesAvailableIndicate :
2251 return ((const H225_ResourcesAvailableIndicate &)*this).m_requestSeqNum;
2253 case H225_RasMessage::e_resourcesAvailableConfirm :
2254 return ((const H225_ResourcesAvailableConfirm &)*this).m_requestSeqNum;
2256 case H225_RasMessage::e_infoRequestAck :
2257 return ((const H225_InfoRequestAck &)*this).m_requestSeqNum;
2259 case H225_RasMessage::e_infoRequestNak :
2260 return ((const H225_InfoRequestNak &)*this).m_requestSeqNum;
2262 case H225_RasMessage::e_serviceControlIndication :
2263 return ((const H225_ServiceControlIndication &)*this).m_requestSeqNum;
2265 case H225_RasMessage::e_serviceControlResponse :
2266 return ((const H225_ServiceControlResponse &)*this).m_requestSeqNum;
2268 default :
2269 return 0;
2274 unsigned H323RasPDU::GetRequestInProgressDelay() const
2276 if (GetTag() != H225_RasMessage::e_requestInProgress)
2277 return 0;
2279 return ((const H225_RequestInProgress &)*this).m_delay;
2283 #if PTRACING
2284 const char * H323RasPDU::GetProtocolName() const
2286 return "H225RAS";
2288 #endif
2291 H323TransactionPDU * H323RasPDU::ClonePDU() const
2293 return new H323RasPDU(*this);
2297 void H323RasPDU::DeletePDU()
2299 delete this;
2303 H225_GatekeeperRequest & H323RasPDU::BuildGatekeeperRequest(unsigned seqNum)
2305 SetTag(e_gatekeeperRequest);
2306 H225_GatekeeperRequest & grq = *this;
2307 grq.m_requestSeqNum = seqNum;
2308 grq.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
2309 return grq;
2313 H225_GatekeeperConfirm & H323RasPDU::BuildGatekeeperConfirm(unsigned seqNum)
2315 SetTag(e_gatekeeperConfirm);
2316 H225_GatekeeperConfirm & gcf = *this;
2317 gcf.m_requestSeqNum = seqNum;
2318 gcf.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
2319 return gcf;
2323 H225_GatekeeperReject & H323RasPDU::BuildGatekeeperReject(unsigned seqNum, unsigned reason)
2325 SetTag(e_gatekeeperReject);
2326 H225_GatekeeperReject & grj = *this;
2327 grj.m_requestSeqNum = seqNum;
2328 grj.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
2329 grj.m_rejectReason.SetTag(reason);
2330 return grj;
2334 H225_RegistrationRequest & H323RasPDU::BuildRegistrationRequest(unsigned seqNum)
2336 SetTag(e_registrationRequest);
2337 H225_RegistrationRequest & rrq = *this;
2338 rrq.m_requestSeqNum = seqNum;
2339 rrq.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
2340 return rrq;
2344 H225_RegistrationConfirm & H323RasPDU::BuildRegistrationConfirm(unsigned seqNum)
2346 SetTag(e_registrationConfirm);
2347 H225_RegistrationConfirm & rcf = *this;
2348 rcf.m_requestSeqNum = seqNum;
2349 rcf.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
2350 return rcf;
2354 H225_RegistrationReject & H323RasPDU::BuildRegistrationReject(unsigned seqNum, unsigned reason)
2356 SetTag(e_registrationReject);
2357 H225_RegistrationReject & rrj = *this;
2358 rrj.m_requestSeqNum = seqNum;
2359 rrj.m_protocolIdentifier.SetValue(H225_ProtocolID, PARRAYSIZE(H225_ProtocolID));
2360 rrj.m_rejectReason.SetTag(reason);
2361 return rrj;
2365 H225_UnregistrationRequest & H323RasPDU::BuildUnregistrationRequest(unsigned seqNum)
2367 SetTag(e_unregistrationRequest);
2368 H225_UnregistrationRequest & urq = *this;
2369 urq.m_requestSeqNum = seqNum;
2370 return urq;
2374 H225_UnregistrationConfirm & H323RasPDU::BuildUnregistrationConfirm(unsigned seqNum)
2376 SetTag(e_unregistrationConfirm);
2377 H225_UnregistrationConfirm & ucf = *this;
2378 ucf.m_requestSeqNum = seqNum;
2379 return ucf;
2383 H225_UnregistrationReject & H323RasPDU::BuildUnregistrationReject(unsigned seqNum, unsigned reason)
2385 SetTag(e_unregistrationReject);
2386 H225_UnregistrationReject & urj = *this;
2387 urj.m_requestSeqNum = seqNum;
2388 urj.m_rejectReason.SetTag(reason);
2389 return urj;
2393 H225_LocationRequest & H323RasPDU::BuildLocationRequest(unsigned seqNum)
2395 SetTag(e_locationRequest);
2396 H225_LocationRequest & lrq = *this;
2397 lrq.m_requestSeqNum = seqNum;
2398 return lrq;
2402 H225_LocationConfirm & H323RasPDU::BuildLocationConfirm(unsigned seqNum)
2404 SetTag(e_locationConfirm);
2405 H225_LocationConfirm & lcf = *this;
2406 lcf.m_requestSeqNum = seqNum;
2407 return lcf;
2411 H225_LocationReject & H323RasPDU::BuildLocationReject(unsigned seqNum, unsigned reason)
2413 SetTag(e_locationReject);
2414 H225_LocationReject & lrj = *this;
2415 lrj.m_requestSeqNum = seqNum;
2416 lrj.m_rejectReason.SetTag(reason);
2417 return lrj;
2421 H225_AdmissionRequest & H323RasPDU::BuildAdmissionRequest(unsigned seqNum)
2423 SetTag(e_admissionRequest);
2424 H225_AdmissionRequest & arq = *this;
2425 arq.m_requestSeqNum = seqNum;
2426 return arq;
2430 H225_AdmissionConfirm & H323RasPDU::BuildAdmissionConfirm(unsigned seqNum)
2432 SetTag(e_admissionConfirm);
2433 H225_AdmissionConfirm & acf = *this;
2434 acf.m_requestSeqNum = seqNum;
2435 return acf;
2439 H225_AdmissionReject & H323RasPDU::BuildAdmissionReject(unsigned seqNum, unsigned reason)
2441 SetTag(e_admissionReject);
2442 H225_AdmissionReject & arj = *this;
2443 arj.m_requestSeqNum = seqNum;
2444 arj.m_rejectReason.SetTag(reason);
2445 return arj;
2449 H225_DisengageRequest & H323RasPDU::BuildDisengageRequest(unsigned seqNum)
2451 SetTag(e_disengageRequest);
2452 H225_DisengageRequest & drq = *this;
2453 drq.m_requestSeqNum = seqNum;
2454 return drq;
2458 H225_DisengageConfirm & H323RasPDU::BuildDisengageConfirm(unsigned seqNum)
2460 SetTag(e_disengageConfirm);
2461 H225_DisengageConfirm & dcf = *this;
2462 dcf.m_requestSeqNum = seqNum;
2463 return dcf;
2467 H225_DisengageReject & H323RasPDU::BuildDisengageReject(unsigned seqNum, unsigned reason)
2469 SetTag(e_disengageReject);
2470 H225_DisengageReject & drj = *this;
2471 drj.m_requestSeqNum = seqNum;
2472 drj.m_rejectReason.SetTag(reason);
2473 return drj;
2477 H225_BandwidthRequest & H323RasPDU::BuildBandwidthRequest(unsigned seqNum)
2479 SetTag(e_bandwidthRequest);
2480 H225_BandwidthRequest & brq = *this;
2481 brq.m_requestSeqNum = seqNum;
2482 return brq;
2486 H225_BandwidthConfirm & H323RasPDU::BuildBandwidthConfirm(unsigned seqNum, unsigned bandWidth)
2488 SetTag(e_bandwidthConfirm);
2489 H225_BandwidthConfirm & bcf = *this;
2490 bcf.m_requestSeqNum = seqNum;
2491 bcf.m_bandWidth = bandWidth;
2492 return bcf;
2496 H225_BandwidthReject & H323RasPDU::BuildBandwidthReject(unsigned seqNum, unsigned reason)
2498 SetTag(e_bandwidthReject);
2499 H225_BandwidthReject & brj = *this;
2500 brj.m_requestSeqNum = seqNum;
2501 brj.m_rejectReason.SetTag(reason);
2502 return brj;
2506 H225_InfoRequest & H323RasPDU::BuildInfoRequest(unsigned seqNum,
2507 unsigned callRef,
2508 const OpalGloballyUniqueID * id)
2510 SetTag(e_infoRequest);
2511 H225_InfoRequest & irq = *this;
2512 irq.m_requestSeqNum = seqNum;
2513 irq.m_callReferenceValue = callRef;
2514 if (callRef != 0 && id != NULL)
2515 irq.m_callIdentifier.m_guid = *id;
2516 return irq;
2520 H225_InfoRequestResponse & H323RasPDU::BuildInfoRequestResponse(unsigned seqNum)
2522 SetTag(e_infoRequestResponse);
2523 H225_InfoRequestResponse & irr = *this;
2524 irr.m_requestSeqNum = seqNum;
2525 return irr;
2529 H225_InfoRequestAck & H323RasPDU::BuildInfoRequestAck(unsigned seqNum)
2531 SetTag(e_infoRequestAck);
2532 H225_InfoRequestAck & iack = *this;
2533 iack.m_requestSeqNum = seqNum;
2534 return iack;
2538 H225_InfoRequestNak & H323RasPDU::BuildInfoRequestNak(unsigned seqNum, unsigned reason)
2540 SetTag(e_infoRequestNak);
2541 H225_InfoRequestNak & inak = *this;
2542 inak.m_requestSeqNum = seqNum;
2543 inak.m_nakReason.SetTag(reason);
2544 return inak;
2548 H225_UnknownMessageResponse & H323RasPDU::BuildUnknownMessageResponse(unsigned seqNum)
2550 SetTag(e_unknownMessageResponse);
2551 H225_UnknownMessageResponse & umr = *this;
2552 umr.m_requestSeqNum = seqNum;
2553 return umr;
2557 H225_RequestInProgress & H323RasPDU::BuildRequestInProgress(unsigned seqNum, unsigned delay)
2559 SetTag(e_requestInProgress);
2560 H225_RequestInProgress & rip = *this;
2561 rip.m_requestSeqNum = seqNum;
2562 rip.m_delay = delay;
2563 return rip;
2567 H225_ServiceControlIndication & H323RasPDU::BuildServiceControlIndication(unsigned seqNum, const OpalGloballyUniqueID * id)
2569 SetTag(e_serviceControlIndication);
2570 H225_ServiceControlIndication & sci = *this;
2571 sci.m_requestSeqNum = seqNum;
2573 if (id != NULL && !id->IsNULL()) {
2574 sci.IncludeOptionalField(H225_ServiceControlIndication::e_callSpecific);
2575 sci.m_callSpecific.m_callIdentifier.m_guid = *id;
2578 return sci;
2582 H225_ServiceControlResponse & H323RasPDU::BuildServiceControlResponse(unsigned seqNum)
2584 SetTag(e_serviceControlResponse);
2585 H225_ServiceControlResponse & scr = *this;
2586 scr.m_requestSeqNum = seqNum;
2587 return scr;
2590 #ifdef _MSC_VER
2591 #pragma warning(default : 4100)
2592 #endif
2594 /////////////////////////////////////////////////////////////////////////////